Skip to content

Commit 783a21e

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 1a7c5b6 commit 783a21e

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
@@ -999,6 +999,7 @@ ProcessUtilitySlow(ParseState *pstate,
999999
{
10001000
List *stmts;
10011001
ListCell *l;
1002+
RangeVar *table_rv = NULL;
10021003

10031004
/* Run parse analysis ... */
10041005
stmts = transformCreateStmt((CreateStmt *) parsetree,
@@ -1011,11 +1012,15 @@ ProcessUtilitySlow(ParseState *pstate,
10111012

10121013
if (IsA(stmt, CreateStmt))
10131014
{
1015+
CreateStmt *cstmt = (CreateStmt *) stmt;
10141016
Datum toast_options;
10151017
static char *validnsps[] = HEAP_RELOPT_NAMESPACES;
10161018

1019+
/* Remember transformed RangeVar for LIKE */
1020+
table_rv = cstmt->relation;
1021+
10171022
/* Create the table itself */
1018-
address = DefineRelation((CreateStmt *) stmt,
1023+
address = DefineRelation(cstmt,
10191024
RELKIND_RELATION,
10201025
InvalidOid, NULL,
10211026
queryString);
@@ -1034,7 +1039,7 @@ ProcessUtilitySlow(ParseState *pstate,
10341039
* table
10351040
*/
10361041
toast_options = transformRelOptions((Datum) 0,
1037-
((CreateStmt *) stmt)->options,
1042+
cstmt->options,
10381043
"toast",
10391044
validnsps,
10401045
true,
@@ -1048,12 +1053,17 @@ ProcessUtilitySlow(ParseState *pstate,
10481053
}
10491054
else if (IsA(stmt, CreateForeignTableStmt))
10501055
{
1056+
CreateForeignTableStmt *cstmt = (CreateForeignTableStmt *) stmt;
1057+
1058+
/* Remember transformed RangeVar for LIKE */
1059+
table_rv = cstmt->base.relation;
1060+
10511061
/* Create the table itself */
1052-
address = DefineRelation((CreateStmt *) stmt,
1062+
address = DefineRelation(&cstmt->base,
10531063
RELKIND_FOREIGN_TABLE,
10541064
InvalidOid, NULL,
10551065
queryString);
1056-
CreateForeignTable((CreateForeignTableStmt *) stmt,
1066+
CreateForeignTable(cstmt,
10571067
address.objectId);
10581068
EventTriggerCollectSimpleCommand(address,
10591069
secondaryObject,
@@ -1068,10 +1078,11 @@ ProcessUtilitySlow(ParseState *pstate,
10681078
* to-do list.
10691079
*/
10701080
TableLikeClause *like = (TableLikeClause *) stmt;
1071-
RangeVar *rv = ((CreateStmt *) parsetree)->relation;
10721081
List *morestmts;
10731082

1074-
morestmts = expandTableLikeClause(rv, like);
1083+
Assert(table_rv != NULL);
1084+
1085+
morestmts = expandTableLikeClause(table_rv, like);
10751086
stmts = list_concat(stmts, morestmts);
10761087

10771088
/*

src/test/regress/expected/create_table_like.out

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