summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2020-09-13 12:51:21 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2020-09-13 12:51:21 -0400
commit783a21eff37ec2cbe44b6e88aa4edb15a151155e (patch)
tree35c60e08f6f9062c2b67e3a26fba254a9d53ca4f
parent1a7c5b6f7b5a18ace8199aba35b25ffd37053450 (diff)
Use the properly transformed RangeVar for expandTableLikeClause().
transformCreateStmt() adjusts the transformed statement's RangeVar to specify the target schema explicitly, for the express reason of making sure that auxiliary statements derived by parse transformation operate on the right table. But the refactoring I did in commit 502898192 got this wrong and passed the untransformed RangeVar to expandTableLikeClause(). This could lead to assertion failures or weird misbehavior if the wrong table was accessed. Per report from Alexander Lakhin. Like the previous patch, back-patch to all supported branches. Discussion: https://postgr.es/m/05051f9d-b32b-cb35-6735-0e9f2ab86b5f@gmail.com
-rw-r--r--src/backend/tcop/utility.c23
-rw-r--r--src/test/regress/expected/create_table_like.out18
-rw-r--r--src/test/regress/sql/create_table_like.sql5
3 files changed, 40 insertions, 6 deletions
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index df11869863b..445e0bab42f 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -999,6 +999,7 @@ ProcessUtilitySlow(ParseState *pstate,
{
List *stmts;
ListCell *l;
+ RangeVar *table_rv = NULL;
/* Run parse analysis ... */
stmts = transformCreateStmt((CreateStmt *) parsetree,
@@ -1011,11 +1012,15 @@ ProcessUtilitySlow(ParseState *pstate,
if (IsA(stmt, CreateStmt))
{
+ CreateStmt *cstmt = (CreateStmt *) stmt;
Datum toast_options;
static char *validnsps[] = HEAP_RELOPT_NAMESPACES;
+ /* Remember transformed RangeVar for LIKE */
+ table_rv = cstmt->relation;
+
/* Create the table itself */
- address = DefineRelation((CreateStmt *) stmt,
+ address = DefineRelation(cstmt,
RELKIND_RELATION,
InvalidOid, NULL,
queryString);
@@ -1034,7 +1039,7 @@ ProcessUtilitySlow(ParseState *pstate,
* table
*/
toast_options = transformRelOptions((Datum) 0,
- ((CreateStmt *) stmt)->options,
+ cstmt->options,
"toast",
validnsps,
true,
@@ -1048,12 +1053,17 @@ ProcessUtilitySlow(ParseState *pstate,
}
else if (IsA(stmt, CreateForeignTableStmt))
{
+ CreateForeignTableStmt *cstmt = (CreateForeignTableStmt *) stmt;
+
+ /* Remember transformed RangeVar for LIKE */
+ table_rv = cstmt->base.relation;
+
/* Create the table itself */
- address = DefineRelation((CreateStmt *) stmt,
+ address = DefineRelation(&cstmt->base,
RELKIND_FOREIGN_TABLE,
InvalidOid, NULL,
queryString);
- CreateForeignTable((CreateForeignTableStmt *) stmt,
+ CreateForeignTable(cstmt,
address.objectId);
EventTriggerCollectSimpleCommand(address,
secondaryObject,
@@ -1068,10 +1078,11 @@ ProcessUtilitySlow(ParseState *pstate,
* to-do list.
*/
TableLikeClause *like = (TableLikeClause *) stmt;
- RangeVar *rv = ((CreateStmt *) parsetree)->relation;
List *morestmts;
- morestmts = expandTableLikeClause(rv, like);
+ Assert(table_rv != NULL);
+
+ morestmts = expandTableLikeClause(table_rv, like);
stmts = list_concat(stmts, morestmts);
/*
diff --git a/src/test/regress/expected/create_table_like.out b/src/test/regress/expected/create_table_like.out
index a9a78922cef..f6356efd5c8 100644
--- a/src/test/regress/expected/create_table_like.out
+++ b/src/test/regress/expected/create_table_like.out
@@ -299,6 +299,24 @@ CREATE TABLE inh_error2 (LIKE ctlt4 INCLUDING STORAGE) INHERITS (ctlt1);
NOTICE: merging column "a" with inherited definition
ERROR: column "a" has a storage parameter conflict
DETAIL: MAIN versus EXTENDED
+-- Check that LIKE isn't confused by a system catalog of the same name
+CREATE TABLE pg_attrdef (LIKE ctlt1 INCLUDING ALL);
+\d+ public.pg_attrdef
+ Table "public.pg_attrdef"
+ Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
+--------+------+-----------+----------+---------+----------+--------------+-------------
+ a | text | | not null | | main | | A
+ b | text | | | | extended | | B
+Indexes:
+ "pg_attrdef_pkey" PRIMARY KEY, btree (a)
+ "pg_attrdef_b_idx" btree (b)
+ "pg_attrdef_expr_idx" btree ((a || b))
+Check constraints:
+ "ctlt1_a_check" CHECK (length(a) > 2)
+Statistics objects:
+ "public"."pg_attrdef_a_b_stat" (ndistinct, dependencies) ON a, b FROM public.pg_attrdef
+
+DROP TABLE public.pg_attrdef;
DROP TABLE ctlt1, ctlt2, ctlt3, ctlt4, ctlt12_storage, ctlt12_comments, ctlt1_inh, ctlt13_inh, ctlt13_like, ctlt_all, ctla, ctlb CASCADE;
NOTICE: drop cascades to table inhe
/* LIKE with other relation kinds */
diff --git a/src/test/regress/sql/create_table_like.sql b/src/test/regress/sql/create_table_like.sql
index e4b5571ca82..79658b1ce67 100644
--- a/src/test/regress/sql/create_table_like.sql
+++ b/src/test/regress/sql/create_table_like.sql
@@ -129,6 +129,11 @@ SELECT s.stxname, objsubid, description FROM pg_description, pg_statistic_ext s
CREATE TABLE inh_error1 () INHERITS (ctlt1, ctlt4);
CREATE TABLE inh_error2 (LIKE ctlt4 INCLUDING STORAGE) INHERITS (ctlt1);
+-- Check that LIKE isn't confused by a system catalog of the same name
+CREATE TABLE pg_attrdef (LIKE ctlt1 INCLUDING ALL);
+\d+ public.pg_attrdef
+DROP TABLE public.pg_attrdef;
+
DROP TABLE ctlt1, ctlt2, ctlt3, ctlt4, ctlt12_storage, ctlt12_comments, ctlt1_inh, ctlt13_inh, ctlt13_like, ctlt_all, ctla, ctlb CASCADE;