aboutsummaryrefslogtreecommitdiff
path: root/src/backend/parser/parse_utilcmd.c
diff options
context:
space:
mode:
authorPeter Eisentraut <peter@eisentraut.org>2020-04-09 16:17:55 +0200
committerPeter Eisentraut <peter@eisentraut.org>2020-04-09 16:36:45 +0200
commite92e4a2b68fe877677278c1300db1780956c984e (patch)
tree9e651c181857cd6eeefa18a2c2a4f2768aacc7b7 /src/backend/parser/parse_utilcmd.c
parentc4f82a779d2676bfca1694a6f9b5499e6cc5f60f (diff)
downloadpostgresql-e92e4a2b68fe877677278c1300db1780956c984e.tar.gz
postgresql-e92e4a2b68fe877677278c1300db1780956c984e.zip
Fix CREATE TABLE LIKE INCLUDING GENERATED column order issue
CREATE TABLE LIKE INCLUDING GENERATED would fail if a generated column referred to a column with a higher attribute number. This is because the column mapping mechanism created the mapping incrementally as columns are added. This was sufficient for previous uses of that mechanism (omitting dropped columns), and it also happened to work if generated columns only referred to columns with lower attribute numbers, but here it failed. This fix is to build the attribute mapping in a separate loop before processing the columns in detail. Bug: #16342 Reported-by: Ethan Waldo <ewaldo@healthetechs.com> Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Diffstat (limited to 'src/backend/parser/parse_utilcmd.c')
-rw-r--r--src/backend/parser/parse_utilcmd.c25
1 files changed, 22 insertions, 3 deletions
diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c
index 350959a5e0b..75c122fe348 100644
--- a/src/backend/parser/parse_utilcmd.c
+++ b/src/backend/parser/parse_utilcmd.c
@@ -924,6 +924,7 @@ static void
transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_clause)
{
AttrNumber parent_attno;
+ AttrNumber new_attno;
Relation relation;
TupleDesc tupleDesc;
TupleConstr *constr;
@@ -987,6 +988,26 @@ transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla
attmap = make_attrmap(tupleDesc->natts);
/*
+ * We must fill the attmap now so that it can be used to process generated
+ * column default expressions in the per-column loop below.
+ */
+ new_attno = 1;
+ for (parent_attno = 1; parent_attno <= tupleDesc->natts;
+ parent_attno++)
+ {
+ Form_pg_attribute attribute = TupleDescAttr(tupleDesc,
+ parent_attno - 1);
+
+ /*
+ * Ignore dropped columns in the parent. attmap entry is left zero.
+ */
+ if (attribute->attisdropped)
+ continue;
+
+ attmap->attnums[parent_attno - 1] = list_length(cxt->columns) + (new_attno++);
+ }
+
+ /*
* Insert the copied attributes into the cxt for the new table definition.
*/
for (parent_attno = 1; parent_attno <= tupleDesc->natts;
@@ -998,7 +1019,7 @@ transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla
ColumnDef *def;
/*
- * Ignore dropped columns in the parent. attmap entry is left zero.
+ * Ignore dropped columns in the parent.
*/
if (attribute->attisdropped)
continue;
@@ -1030,8 +1051,6 @@ transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla
*/
cxt->columns = lappend(cxt->columns, def);
- attmap->attnums[parent_attno - 1] = list_length(cxt->columns);
-
/*
* Copy default, if present and it should be copied. We have separate
* options for plain default expressions and GENERATED defaults.