summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/parser/parse_utilcmd.c25
-rw-r--r--src/test/regress/expected/create_table_like.out29
-rw-r--r--src/test/regress/sql/create_table_like.sql19
3 files changed, 47 insertions, 26 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.
diff --git a/src/test/regress/expected/create_table_like.out b/src/test/regress/expected/create_table_like.out
index f686606e423..655e8e41dd9 100644
--- a/src/test/regress/expected/create_table_like.out
+++ b/src/test/regress/expected/create_table_like.out
@@ -159,14 +159,15 @@ SELECT * FROM test_like_gen_3;
(1 row)
DROP TABLE test_like_gen_1, test_like_gen_2, test_like_gen_3;
-CREATE TABLE test_like_4 (a int, b int DEFAULT 42, c int GENERATED ALWAYS AS (a * 2) STORED);
+-- also test generated column with a "forward" reference (bug #16342)
+CREATE TABLE test_like_4 (b int DEFAULT 42, c int GENERATED ALWAYS AS (a * 2) STORED, a int);
\d test_like_4
Table "public.test_like_4"
Column | Type | Collation | Nullable | Default
--------+---------+-----------+----------+------------------------------------
- a | integer | | |
b | integer | | | 42
c | integer | | | generated always as (a * 2) stored
+ a | integer | | |
CREATE TABLE test_like_4a (LIKE test_like_4);
CREATE TABLE test_like_4b (LIKE test_like_4 INCLUDING DEFAULTS);
@@ -176,12 +177,12 @@ CREATE TABLE test_like_4d (LIKE test_like_4 INCLUDING DEFAULTS INCLUDING GENERAT
Table "public.test_like_4a"
Column | Type | Collation | Nullable | Default
--------+---------+-----------+----------+---------
- a | integer | | |
b | integer | | |
c | integer | | |
+ a | integer | | |
-INSERT INTO test_like_4a VALUES(11);
-TABLE test_like_4a;
+INSERT INTO test_like_4a (a) VALUES(11);
+SELECT a, b, c FROM test_like_4a;
a | b | c
----+---+---
11 | |
@@ -191,12 +192,12 @@ TABLE test_like_4a;
Table "public.test_like_4b"
Column | Type | Collation | Nullable | Default
--------+---------+-----------+----------+---------
- a | integer | | |
b | integer | | | 42
c | integer | | |
+ a | integer | | |
-INSERT INTO test_like_4b VALUES(11);
-TABLE test_like_4b;
+INSERT INTO test_like_4b (a) VALUES(11);
+SELECT a, b, c FROM test_like_4b;
a | b | c
----+----+---
11 | 42 |
@@ -206,12 +207,12 @@ TABLE test_like_4b;
Table "public.test_like_4c"
Column | Type | Collation | Nullable | Default
--------+---------+-----------+----------+------------------------------------
- a | integer | | |
b | integer | | |
c | integer | | | generated always as (a * 2) stored
+ a | integer | | |
-INSERT INTO test_like_4c VALUES(11);
-TABLE test_like_4c;
+INSERT INTO test_like_4c (a) VALUES(11);
+SELECT a, b, c FROM test_like_4c;
a | b | c
----+---+----
11 | | 22
@@ -221,12 +222,12 @@ TABLE test_like_4c;
Table "public.test_like_4d"
Column | Type | Collation | Nullable | Default
--------+---------+-----------+----------+------------------------------------
- a | integer | | |
b | integer | | | 42
c | integer | | | generated always as (a * 2) stored
+ a | integer | | |
-INSERT INTO test_like_4d VALUES(11);
-TABLE test_like_4d;
+INSERT INTO test_like_4d (a) VALUES(11);
+SELECT a, b, c FROM test_like_4d;
a | b | c
----+----+----
11 | 42 | 22
diff --git a/src/test/regress/sql/create_table_like.sql b/src/test/regress/sql/create_table_like.sql
index afcb59b8970..6981ac0cbee 100644
--- a/src/test/regress/sql/create_table_like.sql
+++ b/src/test/regress/sql/create_table_like.sql
@@ -65,24 +65,25 @@ INSERT INTO test_like_gen_3 (a) VALUES (1);
SELECT * FROM test_like_gen_3;
DROP TABLE test_like_gen_1, test_like_gen_2, test_like_gen_3;
-CREATE TABLE test_like_4 (a int, b int DEFAULT 42, c int GENERATED ALWAYS AS (a * 2) STORED);
+-- also test generated column with a "forward" reference (bug #16342)
+CREATE TABLE test_like_4 (b int DEFAULT 42, c int GENERATED ALWAYS AS (a * 2) STORED, a int);
\d test_like_4
CREATE TABLE test_like_4a (LIKE test_like_4);
CREATE TABLE test_like_4b (LIKE test_like_4 INCLUDING DEFAULTS);
CREATE TABLE test_like_4c (LIKE test_like_4 INCLUDING GENERATED);
CREATE TABLE test_like_4d (LIKE test_like_4 INCLUDING DEFAULTS INCLUDING GENERATED);
\d test_like_4a
-INSERT INTO test_like_4a VALUES(11);
-TABLE test_like_4a;
+INSERT INTO test_like_4a (a) VALUES(11);
+SELECT a, b, c FROM test_like_4a;
\d test_like_4b
-INSERT INTO test_like_4b VALUES(11);
-TABLE test_like_4b;
+INSERT INTO test_like_4b (a) VALUES(11);
+SELECT a, b, c FROM test_like_4b;
\d test_like_4c
-INSERT INTO test_like_4c VALUES(11);
-TABLE test_like_4c;
+INSERT INTO test_like_4c (a) VALUES(11);
+SELECT a, b, c FROM test_like_4c;
\d test_like_4d
-INSERT INTO test_like_4d VALUES(11);
-TABLE test_like_4d;
+INSERT INTO test_like_4d (a) VALUES(11);
+SELECT a, b, c FROM test_like_4d;
DROP TABLE test_like_4, test_like_4a, test_like_4b, test_like_4c, test_like_4d;
CREATE TABLE inhg (x text, LIKE inhx INCLUDING INDEXES, y text); /* copies indexes */