1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-25 12:03:53 +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:
Peter Eisentraut
2025-11-06 11:52:47 +01:00
parent b8b37f0ee2
commit ccfe28eb42
3 changed files with 47 additions and 0 deletions

View File

@@ -128,6 +128,9 @@ DoCopy(ParseState *pstate, const CopyStmt *stmt,
if (stmt->whereClause)
{
Bitmapset *expr_attrs = NULL;
int i;
/* add nsitem to query namespace */
addNSItemToQuery(pstate, nsitem, false, true, true);
@@ -140,6 +143,40 @@ DoCopy(ParseState *pstate, const CopyStmt *stmt,
/* we have to fix its collations too */
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 = (Node *) canonicalize_qual((Expr *) whereClause, false);

View File

@@ -415,6 +415,12 @@ COPY gtest1 FROM stdin;
COPY gtest1 (a, b) FROM stdin;
ERROR: column "b" is a generated column
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;
a | b
---+---

View File

@@ -189,6 +189,10 @@ COPY gtest1 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;
TRUNCATE gtest3;