Skip to content

Commit f112100

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 a089aa1 commit f112100

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
@@ -991,6 +991,7 @@ ProcessUtilitySlow(ParseState *pstate,
991991
{
992992
List *stmts;
993993
ListCell *l;
994+
RangeVar *table_rv = NULL;
994995

995996
/* Run parse analysis ... */
996997
stmts = transformCreateStmt((CreateStmt *) parsetree,
@@ -1003,11 +1004,15 @@ ProcessUtilitySlow(ParseState *pstate,
10031004

10041005
if (IsA(stmt, CreateStmt))
10051006
{
1007+
CreateStmt *cstmt = (CreateStmt *) stmt;
10061008
Datum toast_options;
10071009
static char *validnsps[] = HEAP_RELOPT_NAMESPACES;
10081010

1011+
/* Remember transformed RangeVar for LIKE */
1012+
table_rv = cstmt->relation;
1013+
10091014
/* Create the table itself */
1010-
address = DefineRelation((CreateStmt *) stmt,
1015+
address = DefineRelation(cstmt,
10111016
RELKIND_RELATION,
10121017
InvalidOid, NULL,
10131018
queryString);
@@ -1026,7 +1031,7 @@ ProcessUtilitySlow(ParseState *pstate,
10261031
* table
10271032
*/
10281033
toast_options = transformRelOptions((Datum) 0,
1029-
((CreateStmt *) stmt)->options,
1034+
cstmt->options,
10301035
"toast",
10311036
validnsps,
10321037
true,
@@ -1040,12 +1045,17 @@ ProcessUtilitySlow(ParseState *pstate,
10401045
}
10411046
else if (IsA(stmt, CreateForeignTableStmt))
10421047
{
1048+
CreateForeignTableStmt *cstmt = (CreateForeignTableStmt *) stmt;
1049+
1050+
/* Remember transformed RangeVar for LIKE */
1051+
table_rv = cstmt->base.relation;
1052+
10431053
/* Create the table itself */
1044-
address = DefineRelation((CreateStmt *) stmt,
1054+
address = DefineRelation(&cstmt->base,
10451055
RELKIND_FOREIGN_TABLE,
10461056
InvalidOid, NULL,
10471057
queryString);
1048-
CreateForeignTable((CreateForeignTableStmt *) stmt,
1058+
CreateForeignTable(cstmt,
10491059
address.objectId);
10501060
EventTriggerCollectSimpleCommand(address,
10511061
secondaryObject,
@@ -1060,10 +1070,11 @@ ProcessUtilitySlow(ParseState *pstate,
10601070
* to-do list.
10611071
*/
10621072
TableLikeClause *like = (TableLikeClause *) stmt;
1063-
RangeVar *rv = ((CreateStmt *) parsetree)->relation;
10641073
List *morestmts;
10651074

1066-
morestmts = expandTableLikeClause(rv, like);
1075+
Assert(table_rv != NULL);
1076+
1077+
morestmts = expandTableLikeClause(table_rv, like);
10671078
stmts = list_concat(stmts, morestmts);
10681079

10691080
/*

src/test/regress/expected/create_table_like.out

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,24 @@ CREATE TABLE inh_error2 (LIKE ctlt4 INCLUDING STORAGE) INHERITS (ctlt1);
300300
NOTICE: merging column "a" with inherited definition
301301
ERROR: column "a" has a storage parameter conflict
302302
DETAIL: MAIN versus EXTENDED
303+
-- Check that LIKE isn't confused by a system catalog of the same name
304+
CREATE TABLE pg_attrdef (LIKE ctlt1 INCLUDING ALL);
305+
\d+ public.pg_attrdef
306+
Table "public.pg_attrdef"
307+
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
308+
--------+------+-----------+----------+---------+----------+--------------+-------------
309+
a | text | | not null | | main | | A
310+
b | text | | | | extended | | B
311+
Indexes:
312+
"pg_attrdef_pkey" PRIMARY KEY, btree (a)
313+
"pg_attrdef_b_idx" btree (b)
314+
"pg_attrdef_expr_idx" btree ((a || b))
315+
Check constraints:
316+
"ctlt1_a_check" CHECK (length(a) > 2)
317+
Statistics objects:
318+
"public"."pg_attrdef_a_b_stat" (ndistinct, dependencies) ON a, b FROM public.pg_attrdef
319+
320+
DROP TABLE public.pg_attrdef;
303321
DROP TABLE ctlt1, ctlt2, ctlt3, ctlt4, ctlt12_storage, ctlt12_comments, ctlt1_inh, ctlt13_inh, ctlt13_like, ctlt_all, ctla, ctlb CASCADE;
304322
NOTICE: drop cascades to table inhe
305323
/* 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
@@ -129,6 +129,11 @@ SELECT s.stxname, objsubid, description FROM pg_description, pg_statistic_ext s
129129
CREATE TABLE inh_error1 () INHERITS (ctlt1, ctlt4);
130130
CREATE TABLE inh_error2 (LIKE ctlt4 INCLUDING STORAGE) INHERITS (ctlt1);
131131

132+
-- Check that LIKE isn't confused by a system catalog of the same name
133+
CREATE TABLE pg_attrdef (LIKE ctlt1 INCLUDING ALL);
134+
\d+ public.pg_attrdef
135+
DROP TABLE public.pg_attrdef;
136+
132137
DROP TABLE ctlt1, ctlt2, ctlt3, ctlt4, ctlt12_storage, ctlt12_comments, ctlt1_inh, ctlt13_inh, ctlt13_like, ctlt_all, ctla, ctlb CASCADE;
133138

134139

0 commit comments

Comments
 (0)