summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/nodes/copyfuncs.c1
-rw-r--r--src/backend/nodes/equalfuncs.c1
-rw-r--r--src/backend/nodes/outfuncs.c1
-rw-r--r--src/backend/parser/gram.y1
-rw-r--r--src/backend/parser/parse_utilcmd.c14
-rw-r--r--src/include/nodes/parsenodes.h1
-rw-r--r--src/test/regress/expected/create_table_like.out19
-rw-r--r--src/test/regress/sql/create_table_like.sql8
8 files changed, 43 insertions, 3 deletions
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index c2b1ccf99f1..fcdb7d2cdb2 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -3025,6 +3025,7 @@ _copyTableLikeClause(const TableLikeClause *from)
COPY_NODE_FIELD(relation);
COPY_SCALAR_FIELD(options);
+ COPY_SCALAR_FIELD(relationOid);
return newnode;
}
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index a7e1694e23b..1d9475965a1 100644
--- a/src/backend/nodes/equalfuncs.c
+++ b/src/backend/nodes/equalfuncs.c
@@ -1172,6 +1172,7 @@ _equalTableLikeClause(const TableLikeClause *a, const TableLikeClause *b)
{
COMPARE_NODE_FIELD(relation);
COMPARE_SCALAR_FIELD(options);
+ COMPARE_SCALAR_FIELD(relationOid);
return true;
}
diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c
index 96cefabb8f8..b89251586bc 100644
--- a/src/backend/nodes/outfuncs.c
+++ b/src/backend/nodes/outfuncs.c
@@ -2541,6 +2541,7 @@ _outTableLikeClause(StringInfo str, const TableLikeClause *node)
WRITE_NODE_FIELD(relation);
WRITE_UINT_FIELD(options);
+ WRITE_OID_FIELD(relationOid);
}
static void
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 6e15df231fa..31ec7d196f2 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -3174,6 +3174,7 @@ TableLikeClause:
TableLikeClause *n = makeNode(TableLikeClause);
n->relation = $2;
n->options = $3;
+ n->relationOid = InvalidOid;
$$ = (Node *)n;
}
;
diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c
index 57ea3fa1163..ebf9d19b874 100644
--- a/src/backend/parser/parse_utilcmd.c
+++ b/src/backend/parser/parse_utilcmd.c
@@ -909,12 +909,16 @@ transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla
* yet know what column numbers the copied columns will have in the
* finished table. If any of those options are specified, add the LIKE
* clause to cxt->likeclauses so that expandTableLikeClause will be called
- * after we do know that.
+ * after we do know that. Also, remember the relation OID so that
+ * expandTableLikeClause is certain to open the same table.
*/
if (table_like_clause->options &
(CREATE_TABLE_LIKE_CONSTRAINTS |
CREATE_TABLE_LIKE_INDEXES))
+ {
+ table_like_clause->relationOid = RelationGetRelid(relation);
cxt->likeclauses = lappend(cxt->likeclauses, table_like_clause);
+ }
/*
* Close the parent rel, but keep our AccessShareLock on it until xact
@@ -948,9 +952,13 @@ expandTableLikeClause(RangeVar *heapRel, TableLikeClause *table_like_clause)
* Open the relation referenced by the LIKE clause. We should still have
* the table lock obtained by transformTableLikeClause (and this'll throw
* an assertion failure if not). Hence, no need to recheck privileges
- * etc.
+ * etc. We must open the rel by OID not name, to be sure we get the same
+ * table.
*/
- relation = relation_openrv(table_like_clause->relation, NoLock);
+ if (!OidIsValid(table_like_clause->relationOid))
+ elog(ERROR, "expandTableLikeClause called on untransformed LIKE clause");
+
+ relation = relation_open(table_like_clause->relationOid, NoLock);
tupleDesc = RelationGetDescr(relation);
constr = tupleDesc->constr;
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index e6e11142a84..4dd2d4ecfb7 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -610,6 +610,7 @@ typedef struct TableLikeClause
NodeTag type;
RangeVar *relation;
bits32 options; /* OR of TableLikeOption flags */
+ Oid relationOid; /* If table has been looked up, its OID */
} TableLikeClause;
typedef enum TableLikeOption
diff --git a/src/test/regress/expected/create_table_like.out b/src/test/regress/expected/create_table_like.out
index 4739cd5ee3c..734319ef023 100644
--- a/src/test/regress/expected/create_table_like.out
+++ b/src/test/regress/expected/create_table_like.out
@@ -275,6 +275,25 @@ Check constraints:
"ctlt1_a_check" CHECK (length(a) > 2)
DROP TABLE public.pg_attrdef;
+-- Check that LIKE isn't confused when new table masks the old, either
+BEGIN;
+CREATE SCHEMA ctl_schema;
+SET LOCAL search_path = ctl_schema, public;
+CREATE TABLE ctlt1 (LIKE ctlt1 INCLUDING ALL);
+\d+ ctlt1
+ Table "ctl_schema.ctlt1"
+ Column | Type | Modifiers | Storage | Stats target | Description
+--------+------+-----------+----------+--------------+-------------
+ a | text | not null | main | | A
+ b | text | | extended | | B
+Indexes:
+ "ctlt1_pkey" PRIMARY KEY, btree (a)
+ "ctlt1_b_idx" btree (b)
+ "ctlt1_expr_idx" btree ((a || b))
+Check constraints:
+ "ctlt1_a_check" CHECK (length(a) > 2)
+
+ROLLBACK;
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 */
diff --git a/src/test/regress/sql/create_table_like.sql b/src/test/regress/sql/create_table_like.sql
index 86fa43415ed..dd0b212661f 100644
--- a/src/test/regress/sql/create_table_like.sql
+++ b/src/test/regress/sql/create_table_like.sql
@@ -122,6 +122,14 @@ CREATE TABLE pg_attrdef (LIKE ctlt1 INCLUDING ALL);
\d+ public.pg_attrdef
DROP TABLE public.pg_attrdef;
+-- Check that LIKE isn't confused when new table masks the old, either
+BEGIN;
+CREATE SCHEMA ctl_schema;
+SET LOCAL search_path = ctl_schema, public;
+CREATE TABLE ctlt1 (LIKE ctlt1 INCLUDING ALL);
+\d+ ctlt1
+ROLLBACK;
+
DROP TABLE ctlt1, ctlt2, ctlt3, ctlt4, ctlt12_storage, ctlt12_comments, ctlt1_inh, ctlt13_inh, ctlt13_like, ctlt_all, ctla, ctlb CASCADE;