]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Use the properly transformed RangeVar for expandTableLikeClause().
authorTom Lane <tgl@sss.pgh.pa.us>
Sun, 13 Sep 2020 16:51:21 +0000 (12:51 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Sun, 13 Sep 2020 16:51:21 +0000 (12:51 -0400)
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

src/backend/tcop/utility.c
src/test/regress/expected/create_table_like.out
src/test/regress/sql/create_table_like.sql

index 47a7825d8165307543d59edf5f5718a6c66796e2..042feb962805c499343e25fd626ce6d12a99a449 100644 (file)
@@ -964,6 +964,7 @@ ProcessUtilitySlow(Node *parsetree,
                                {
                                        List       *stmts;
                                        ListCell   *l;
+                                       RangeVar   *table_rv = NULL;
 
                                        /* Run parse analysis ... */
                                        stmts = transformCreateStmt((CreateStmt *) parsetree,
@@ -976,11 +977,15 @@ ProcessUtilitySlow(Node *parsetree,
 
                                                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);
                                                        EventTriggerCollectSimpleCommand(address,
@@ -998,7 +1003,7 @@ ProcessUtilitySlow(Node *parsetree,
                                                         * table
                                                         */
                                                        toast_options = transformRelOptions((Datum) 0,
-                                                                                         ((CreateStmt *) stmt)->options,
+                                                                                                                               cstmt->options,
                                                                                                                                "toast",
                                                                                                                                validnsps,
                                                                                                                                true,
@@ -1012,11 +1017,16 @@ ProcessUtilitySlow(Node *parsetree,
                                                }
                                                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);
-                                                       CreateForeignTable((CreateForeignTableStmt *) stmt,
+                                                       CreateForeignTable(cstmt,
                                                                                           address.objectId);
                                                        EventTriggerCollectSimpleCommand(address,
                                                                                                                         secondaryObject,
@@ -1031,10 +1041,11 @@ ProcessUtilitySlow(Node *parsetree,
                                                         * 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);
 
                                                        /*
index 1a5e4078904ae1d9384388b6258d40f9cc5891c9..49e1c8066d6397d929508ea2d9e8aaaf3074316d 100644 (file)
@@ -243,6 +243,22 @@ 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 | Modifiers | 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)
+
+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 with other relation kinds */
index d70407615bcc0682f0627e6c67d66fae9f2f1c9b..92b03c3d4e4346ed436a0af5c84acb8145b11e04 100644 (file)
@@ -112,6 +112,11 @@ SELECT c.relname, objsubid, description FROM pg_description, pg_index i, pg_clas
 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;