Commit 19f5a37b authored by Tom Lane's avatar Tom Lane

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 50289819 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
parent 03c7f1f3
......@@ -1139,6 +1139,7 @@ ProcessUtilitySlow(ParseState *pstate,
{
List *stmts;
ListCell *l;
RangeVar *table_rv = NULL;
/* Run parse analysis ... */
stmts = transformCreateStmt((CreateStmt *) parsetree,
......@@ -1151,11 +1152,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);
......@@ -1174,7 +1179,7 @@ ProcessUtilitySlow(ParseState *pstate,
* table
*/
toast_options = transformRelOptions((Datum) 0,
((CreateStmt *) stmt)->options,
cstmt->options,
"toast",
validnsps,
true,
......@@ -1188,12 +1193,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,
......@@ -1208,10 +1218,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);
/*
......
......@@ -421,6 +421,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, mcv) 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 must respect NO INHERIT property of constraints
......
......@@ -163,6 +163,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;
-- LIKE must respect NO INHERIT property of constraints
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment