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
This commit is contained in:
parent
03c7f1f37a
commit
19f5a37b9f
@ -1139,6 +1139,7 @@ ProcessUtilitySlow(ParseState *pstate,
|
|||||||
{
|
{
|
||||||
List *stmts;
|
List *stmts;
|
||||||
ListCell *l;
|
ListCell *l;
|
||||||
|
RangeVar *table_rv = NULL;
|
||||||
|
|
||||||
/* Run parse analysis ... */
|
/* Run parse analysis ... */
|
||||||
stmts = transformCreateStmt((CreateStmt *) parsetree,
|
stmts = transformCreateStmt((CreateStmt *) parsetree,
|
||||||
@ -1151,11 +1152,15 @@ ProcessUtilitySlow(ParseState *pstate,
|
|||||||
|
|
||||||
if (IsA(stmt, CreateStmt))
|
if (IsA(stmt, CreateStmt))
|
||||||
{
|
{
|
||||||
|
CreateStmt *cstmt = (CreateStmt *) stmt;
|
||||||
Datum toast_options;
|
Datum toast_options;
|
||||||
static char *validnsps[] = HEAP_RELOPT_NAMESPACES;
|
static char *validnsps[] = HEAP_RELOPT_NAMESPACES;
|
||||||
|
|
||||||
|
/* Remember transformed RangeVar for LIKE */
|
||||||
|
table_rv = cstmt->relation;
|
||||||
|
|
||||||
/* Create the table itself */
|
/* Create the table itself */
|
||||||
address = DefineRelation((CreateStmt *) stmt,
|
address = DefineRelation(cstmt,
|
||||||
RELKIND_RELATION,
|
RELKIND_RELATION,
|
||||||
InvalidOid, NULL,
|
InvalidOid, NULL,
|
||||||
queryString);
|
queryString);
|
||||||
@ -1174,7 +1179,7 @@ ProcessUtilitySlow(ParseState *pstate,
|
|||||||
* table
|
* table
|
||||||
*/
|
*/
|
||||||
toast_options = transformRelOptions((Datum) 0,
|
toast_options = transformRelOptions((Datum) 0,
|
||||||
((CreateStmt *) stmt)->options,
|
cstmt->options,
|
||||||
"toast",
|
"toast",
|
||||||
validnsps,
|
validnsps,
|
||||||
true,
|
true,
|
||||||
@ -1188,12 +1193,17 @@ ProcessUtilitySlow(ParseState *pstate,
|
|||||||
}
|
}
|
||||||
else if (IsA(stmt, CreateForeignTableStmt))
|
else if (IsA(stmt, CreateForeignTableStmt))
|
||||||
{
|
{
|
||||||
|
CreateForeignTableStmt *cstmt = (CreateForeignTableStmt *) stmt;
|
||||||
|
|
||||||
|
/* Remember transformed RangeVar for LIKE */
|
||||||
|
table_rv = cstmt->base.relation;
|
||||||
|
|
||||||
/* Create the table itself */
|
/* Create the table itself */
|
||||||
address = DefineRelation((CreateStmt *) stmt,
|
address = DefineRelation(&cstmt->base,
|
||||||
RELKIND_FOREIGN_TABLE,
|
RELKIND_FOREIGN_TABLE,
|
||||||
InvalidOid, NULL,
|
InvalidOid, NULL,
|
||||||
queryString);
|
queryString);
|
||||||
CreateForeignTable((CreateForeignTableStmt *) stmt,
|
CreateForeignTable(cstmt,
|
||||||
address.objectId);
|
address.objectId);
|
||||||
EventTriggerCollectSimpleCommand(address,
|
EventTriggerCollectSimpleCommand(address,
|
||||||
secondaryObject,
|
secondaryObject,
|
||||||
@ -1208,10 +1218,11 @@ ProcessUtilitySlow(ParseState *pstate,
|
|||||||
* to-do list.
|
* to-do list.
|
||||||
*/
|
*/
|
||||||
TableLikeClause *like = (TableLikeClause *) stmt;
|
TableLikeClause *like = (TableLikeClause *) stmt;
|
||||||
RangeVar *rv = ((CreateStmt *) parsetree)->relation;
|
|
||||||
List *morestmts;
|
List *morestmts;
|
||||||
|
|
||||||
morestmts = expandTableLikeClause(rv, like);
|
Assert(table_rv != NULL);
|
||||||
|
|
||||||
|
morestmts = expandTableLikeClause(table_rv, like);
|
||||||
stmts = list_concat(stmts, morestmts);
|
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
|
NOTICE: merging column "a" with inherited definition
|
||||||
ERROR: column "a" has a storage parameter conflict
|
ERROR: column "a" has a storage parameter conflict
|
||||||
DETAIL: MAIN versus EXTENDED
|
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;
|
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
|
NOTICE: drop cascades to table inhe
|
||||||
-- LIKE must respect NO INHERIT property of constraints
|
-- 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_error1 () INHERITS (ctlt1, ctlt4);
|
||||||
CREATE TABLE inh_error2 (LIKE ctlt4 INCLUDING STORAGE) INHERITS (ctlt1);
|
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;
|
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
|
-- LIKE must respect NO INHERIT property of constraints
|
||||||
|
Loading…
x
Reference in New Issue
Block a user