Skip to content

Commit 1371a1e

Browse files
committed
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 5028981 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
1 parent 6a8f6ae commit 1371a1e

File tree

3 files changed

+40
-6
lines changed

3 files changed

+40
-6
lines changed

src/backend/tcop/utility.c

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -995,6 +995,7 @@ ProcessUtilitySlow(ParseState *pstate,
995995
{
996996
List *stmts;
997997
ListCell *l;
998+
RangeVar *table_rv = NULL;
998999

9991000
/* Run parse analysis ... */
10001001
stmts = transformCreateStmt((CreateStmt *) parsetree,
@@ -1007,11 +1008,15 @@ ProcessUtilitySlow(ParseState *pstate,
10071008

10081009
if (IsA(stmt, CreateStmt))
10091010
{
1011+
CreateStmt *cstmt = (CreateStmt *) stmt;
10101012
Datum toast_options;
10111013
static char *validnsps[] = HEAP_RELOPT_NAMESPACES;
10121014

1015+
/* Remember transformed RangeVar for LIKE */
1016+
table_rv = cstmt->relation;
1017+
10131018
/* Create the table itself */
1014-
address = DefineRelation((CreateStmt *) stmt,
1019+
address = DefineRelation(cstmt,
10151020
RELKIND_RELATION,
10161021
InvalidOid, NULL,
10171022
queryString);
@@ -1030,7 +1035,7 @@ ProcessUtilitySlow(ParseState *pstate,
10301035
* table
10311036
*/
10321037
toast_options = transformRelOptions((Datum) 0,
1033-
((CreateStmt *) stmt)->options,
1038+
cstmt->options,
10341039
"toast",
10351040
validnsps,
10361041
true,
@@ -1044,12 +1049,17 @@ ProcessUtilitySlow(ParseState *pstate,
10441049
}
10451050
else if (IsA(stmt, CreateForeignTableStmt))
10461051
{
1052+
CreateForeignTableStmt *cstmt = (CreateForeignTableStmt *) stmt;
1053+
1054+
/* Remember transformed RangeVar for LIKE */
1055+
table_rv = cstmt->base.relation;
1056+
10471057
/* Create the table itself */
1048-
address = DefineRelation((CreateStmt *) stmt,
1058+
address = DefineRelation(&cstmt->base,
10491059
RELKIND_FOREIGN_TABLE,
10501060
InvalidOid, NULL,
10511061
queryString);
1052-
CreateForeignTable((CreateForeignTableStmt *) stmt,
1062+
CreateForeignTable(cstmt,
10531063
address.objectId);
10541064
EventTriggerCollectSimpleCommand(address,
10551065
secondaryObject,
@@ -1064,10 +1074,11 @@ ProcessUtilitySlow(ParseState *pstate,
10641074
* to-do list.
10651075
*/
10661076
TableLikeClause *like = (TableLikeClause *) stmt;
1067-
RangeVar *rv = ((CreateStmt *) parsetree)->relation;
10681077
List *morestmts;
10691078

1070-
morestmts = expandTableLikeClause(rv, like);
1079+
Assert(table_rv != NULL);
1080+
1081+
morestmts = expandTableLikeClause(table_rv, like);
10711082
stmts = list_concat(stmts, morestmts);
10721083

10731084
/*

src/test/regress/expected/create_table_like.out

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,24 @@ CREATE TABLE inh_error2 (LIKE ctlt4 INCLUDING STORAGE) INHERITS (ctlt1);
421421
NOTICE: merging column "a" with inherited definition
422422
ERROR: column "a" has a storage parameter conflict
423423
DETAIL: MAIN versus EXTENDED
424+
-- Check that LIKE isn't confused by a system catalog of the same name
425+
CREATE TABLE pg_attrdef (LIKE ctlt1 INCLUDING ALL);
426+
\d+ public.pg_attrdef
427+
Table "public.pg_attrdef"
428+
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
429+
--------+------+-----------+----------+---------+----------+--------------+-------------
430+
a | text | | not null | | main | | A
431+
b | text | | | | extended | | B
432+
Indexes:
433+
"pg_attrdef_pkey" PRIMARY KEY, btree (a)
434+
"pg_attrdef_b_idx" btree (b)
435+
"pg_attrdef_expr_idx" btree ((a || b))
436+
Check constraints:
437+
"ctlt1_a_check" CHECK (length(a) > 2)
438+
Statistics objects:
439+
"public"."pg_attrdef_a_b_stat" (ndistinct, dependencies, mcv) ON a, b FROM public.pg_attrdef
440+
441+
DROP TABLE public.pg_attrdef;
424442
DROP TABLE ctlt1, ctlt2, ctlt3, ctlt4, ctlt12_storage, ctlt12_comments, ctlt1_inh, ctlt13_inh, ctlt13_like, ctlt_all, ctla, ctlb CASCADE;
425443
NOTICE: drop cascades to table inhe
426444
/* LIKE with other relation kinds */

src/test/regress/sql/create_table_like.sql

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,11 @@ SELECT s.stxname, objsubid, description FROM pg_description, pg_statistic_ext s
163163
CREATE TABLE inh_error1 () INHERITS (ctlt1, ctlt4);
164164
CREATE TABLE inh_error2 (LIKE ctlt4 INCLUDING STORAGE) INHERITS (ctlt1);
165165

166+
-- Check that LIKE isn't confused by a system catalog of the same name
167+
CREATE TABLE pg_attrdef (LIKE ctlt1 INCLUDING ALL);
168+
\d+ public.pg_attrdef
169+
DROP TABLE public.pg_attrdef;
170+
166171
DROP TABLE ctlt1, ctlt2, ctlt3, ctlt4, ctlt12_storage, ctlt12_comments, ctlt1_inh, ctlt13_inh, ctlt13_like, ctlt_all, ctla, ctlb CASCADE;
167172

168173

0 commit comments

Comments
 (0)