mirror of
https://github.com/postgres/postgres.git
synced 2025-11-26 23:43:30 +03:00
Disallow generated columns in COPY WHERE clause
Stored generated columns are not yet computed when the filtering happens, so we need to prohibit them to avoid incorrect behavior. Co-authored-by: jian he <jian.universality@gmail.com> Reviewed-by: Kirill Reshke <reshkekirill@gmail.com> Reviewed-by: Masahiko Sawada <sawada.mshk@gmail.com> Discussion: https://www.postgresql.org/message-id/flat/CACJufxHb8YPQ095R_pYDr77W9XKNaXg5Rzy-WP525mkq+hRM3g@mail.gmail.com
This commit is contained in:
@@ -903,6 +903,9 @@ DoCopy(ParseState *pstate, const CopyStmt *stmt,
|
|||||||
|
|
||||||
if (stmt->whereClause)
|
if (stmt->whereClause)
|
||||||
{
|
{
|
||||||
|
Bitmapset *expr_attrs = NULL;
|
||||||
|
int i;
|
||||||
|
|
||||||
/* add nsitem to query namespace */
|
/* add nsitem to query namespace */
|
||||||
addNSItemToQuery(pstate, nsitem, false, true, true);
|
addNSItemToQuery(pstate, nsitem, false, true, true);
|
||||||
|
|
||||||
@@ -915,6 +918,40 @@ DoCopy(ParseState *pstate, const CopyStmt *stmt,
|
|||||||
/* we have to fix its collations too */
|
/* we have to fix its collations too */
|
||||||
assign_expr_collations(pstate, whereClause);
|
assign_expr_collations(pstate, whereClause);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Examine all the columns in the WHERE clause expression. When
|
||||||
|
* the whole-row reference is present, examine all the columns of
|
||||||
|
* the table.
|
||||||
|
*/
|
||||||
|
pull_varattnos(whereClause, 1, &expr_attrs);
|
||||||
|
if (bms_is_member(0 - FirstLowInvalidHeapAttributeNumber, expr_attrs))
|
||||||
|
{
|
||||||
|
expr_attrs = bms_add_range(expr_attrs,
|
||||||
|
1 - FirstLowInvalidHeapAttributeNumber,
|
||||||
|
RelationGetNumberOfAttributes(rel) - FirstLowInvalidHeapAttributeNumber);
|
||||||
|
expr_attrs = bms_del_member(expr_attrs, 0 - FirstLowInvalidHeapAttributeNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
i = -1;
|
||||||
|
while ((i = bms_next_member(expr_attrs, i)) >= 0)
|
||||||
|
{
|
||||||
|
AttrNumber attno = i + FirstLowInvalidHeapAttributeNumber;
|
||||||
|
|
||||||
|
Assert(attno != 0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Prohibit generated columns in the WHERE clause. Stored
|
||||||
|
* generated columns are not yet computed when the filtering
|
||||||
|
* happens.
|
||||||
|
*/
|
||||||
|
if (TupleDescAttr(RelationGetDescr(rel), attno - 1)->attgenerated)
|
||||||
|
ereport(ERROR,
|
||||||
|
errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
|
||||||
|
errmsg("generated columns are not supported in COPY FROM WHERE conditions"),
|
||||||
|
errdetail("Column \"%s\" is a generated column.",
|
||||||
|
get_attname(RelationGetRelid(rel), attno, false)));
|
||||||
|
}
|
||||||
|
|
||||||
whereClause = eval_const_expressions(NULL, whereClause);
|
whereClause = eval_const_expressions(NULL, whereClause);
|
||||||
|
|
||||||
whereClause = (Node *) canonicalize_qual((Expr *) whereClause, false);
|
whereClause = (Node *) canonicalize_qual((Expr *) whereClause, false);
|
||||||
|
|||||||
@@ -374,6 +374,12 @@ COPY gtest1 FROM stdin;
|
|||||||
COPY gtest1 (a, b) FROM stdin;
|
COPY gtest1 (a, b) FROM stdin;
|
||||||
ERROR: column "b" is a generated column
|
ERROR: column "b" is a generated column
|
||||||
DETAIL: Generated columns cannot be used in COPY.
|
DETAIL: Generated columns cannot be used in COPY.
|
||||||
|
COPY gtest1 FROM stdin WHERE b <> 10;
|
||||||
|
ERROR: generated columns are not supported in COPY FROM WHERE conditions
|
||||||
|
DETAIL: Column "b" is a generated column.
|
||||||
|
COPY gtest1 FROM stdin WHERE gtest1 IS NULL;
|
||||||
|
ERROR: generated columns are not supported in COPY FROM WHERE conditions
|
||||||
|
DETAIL: Column "b" is a generated column.
|
||||||
SELECT * FROM gtest1 ORDER BY a;
|
SELECT * FROM gtest1 ORDER BY a;
|
||||||
a | b
|
a | b
|
||||||
---+---
|
---+---
|
||||||
|
|||||||
@@ -172,6 +172,10 @@ COPY gtest1 FROM stdin;
|
|||||||
|
|
||||||
COPY gtest1 (a, b) FROM stdin;
|
COPY gtest1 (a, b) FROM stdin;
|
||||||
|
|
||||||
|
COPY gtest1 FROM stdin WHERE b <> 10;
|
||||||
|
|
||||||
|
COPY gtest1 FROM stdin WHERE gtest1 IS NULL;
|
||||||
|
|
||||||
SELECT * FROM gtest1 ORDER BY a;
|
SELECT * FROM gtest1 ORDER BY a;
|
||||||
|
|
||||||
TRUNCATE gtest3;
|
TRUNCATE gtest3;
|
||||||
|
|||||||
Reference in New Issue
Block a user