Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit5f9b05a

Browse files
committed
Ensure that expandTableLikeClause() re-examines the same table.
As it stood, expandTableLikeClause() re-did the same relation_openrvcall that transformTableLikeClause() had done. However there arescenarios where this would not find the same table as expected.We hold lock on the LIKE source table, so it can't be renamed ordropped, but another table could appear before it in the search path.This explains the odd behavior reported in bug #16758 when cloning atable as a temp table of the same name. This case worked as expectedbefore commit5028981 introduced the need to open the source tabletwice, so we should fix it.To make really sure we get the same table, let's re-open it by OID notname. That requires adding an OID field to struct TableLikeClause,which is a little nervous-making from an ABI standpoint, but as longas it's at the end I don't think there's any serious risk.Per bug #16758 from Marc Boeren. Like the previous patch,back-patch to all supported branches.Discussion:https://postgr.es/m/16758-840e84a6cfab276d@postgresql.org
1 parentf0ff52f commit5f9b05a

File tree

8 files changed

+45
-3
lines changed

8 files changed

+45
-3
lines changed

‎src/backend/nodes/copyfuncs.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3368,6 +3368,7 @@ _copyTableLikeClause(const TableLikeClause *from)
33683368

33693369
COPY_NODE_FIELD(relation);
33703370
COPY_SCALAR_FIELD(options);
3371+
COPY_SCALAR_FIELD(relationOid);
33713372

33723373
returnnewnode;
33733374
}

‎src/backend/nodes/equalfuncs.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1252,6 +1252,7 @@ _equalTableLikeClause(const TableLikeClause *a, const TableLikeClause *b)
12521252
{
12531253
COMPARE_NODE_FIELD(relation);
12541254
COMPARE_SCALAR_FIELD(options);
1255+
COMPARE_SCALAR_FIELD(relationOid);
12551256

12561257
return true;
12571258
}

‎src/backend/nodes/outfuncs.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2746,6 +2746,7 @@ _outTableLikeClause(StringInfo str, const TableLikeClause *node)
27462746

27472747
WRITE_NODE_FIELD(relation);
27482748
WRITE_UINT_FIELD(options);
2749+
WRITE_OID_FIELD(relationOid);
27492750
}
27502751

27512752
staticvoid

‎src/backend/parser/gram.y

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3595,6 +3595,7 @@ TableLikeClause:
35953595
TableLikeClause *n = makeNode(TableLikeClause);
35963596
n->relation =$2;
35973597
n->options =$3;
3598+
n->relationOid = InvalidOid;
35983599
$$ = (Node *)n;
35993600
}
36003601
;

‎src/backend/parser/parse_utilcmd.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1091,14 +1091,18 @@ transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla
10911091
* we don't yet know what column numbers the copied columns will have in
10921092
* the finished table. If any of those options are specified, add the
10931093
* LIKE clause to cxt->likeclauses so that expandTableLikeClause will be
1094-
* called after we do know that.
1094+
* called after we do know that. Also, remember the relation OID so that
1095+
* expandTableLikeClause is certain to open the same table.
10951096
*/
10961097
if (table_like_clause->options&
10971098
(CREATE_TABLE_LIKE_DEFAULTS |
10981099
CREATE_TABLE_LIKE_GENERATED |
10991100
CREATE_TABLE_LIKE_CONSTRAINTS |
11001101
CREATE_TABLE_LIKE_INDEXES))
1102+
{
1103+
table_like_clause->relationOid=RelationGetRelid(relation);
11011104
cxt->likeclauses=lappend(cxt->likeclauses,table_like_clause);
1105+
}
11021106

11031107
/*
11041108
* We may copy extended statistics if requested, since the representation
@@ -1171,9 +1175,13 @@ expandTableLikeClause(RangeVar *heapRel, TableLikeClause *table_like_clause)
11711175
* Open the relation referenced by the LIKE clause. We should still have
11721176
* the table lock obtained by transformTableLikeClause (and this'll throw
11731177
* an assertion failure if not). Hence, no need to recheck privileges
1174-
* etc.
1178+
* etc. We must open the rel by OID not name, to be sure we get the same
1179+
* table.
11751180
*/
1176-
relation=relation_openrv(table_like_clause->relation,NoLock);
1181+
if (!OidIsValid(table_like_clause->relationOid))
1182+
elog(ERROR,"expandTableLikeClause called on untransformed LIKE clause");
1183+
1184+
relation=relation_open(table_like_clause->relationOid,NoLock);
11771185

11781186
tupleDesc=RelationGetDescr(relation);
11791187
constr=tupleDesc->constr;

‎src/include/nodes/parsenodes.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -671,6 +671,7 @@ typedef struct TableLikeClause
671671
NodeTagtype;
672672
RangeVar*relation;
673673
bits32options;/* OR of TableLikeOption flags */
674+
OidrelationOid;/* If table has been looked up, its OID */
674675
}TableLikeClause;
675676

676677
typedefenumTableLikeOption

‎src/test/regress/expected/create_table_like.out

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,27 @@ Statistics objects:
455455
"public"."pg_attrdef_a_b_stat" (ndistinct, dependencies, mcv) ON a, b FROM public.pg_attrdef
456456

457457
DROP TABLE public.pg_attrdef;
458+
-- Check that LIKE isn't confused when new table masks the old, either
459+
BEGIN;
460+
CREATE SCHEMA ctl_schema;
461+
SET LOCAL search_path = ctl_schema, public;
462+
CREATE TABLE ctlt1 (LIKE ctlt1 INCLUDING ALL);
463+
\d+ ctlt1
464+
Table "ctl_schema.ctlt1"
465+
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
466+
--------+------+-----------+----------+---------+----------+--------------+-------------
467+
a | text | | not null | | main | | A
468+
b | text | | | | extended | | B
469+
Indexes:
470+
"ctlt1_pkey" PRIMARY KEY, btree (a)
471+
"ctlt1_b_idx" btree (b)
472+
"ctlt1_expr_idx" btree ((a || b))
473+
Check constraints:
474+
"ctlt1_a_check" CHECK (length(a) > 2)
475+
Statistics objects:
476+
"ctl_schema"."ctlt1_a_b_stat" (ndistinct, dependencies, mcv) ON a, b FROM ctlt1
477+
478+
ROLLBACK;
458479
DROP TABLE ctlt1, ctlt2, ctlt3, ctlt4, ctlt12_storage, ctlt12_comments, ctlt1_inh, ctlt13_inh, ctlt13_like, ctlt_all, ctla, ctlb CASCADE;
459480
NOTICE: drop cascades to table inhe
460481
/* LIKE with other relation kinds */

‎src/test/regress/sql/create_table_like.sql

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,14 @@ CREATE TABLE pg_attrdef (LIKE ctlt1 INCLUDING ALL);
173173
\d+public.pg_attrdef
174174
DROPTABLEpublic.pg_attrdef;
175175

176+
-- Check that LIKE isn't confused when new table masks the old, either
177+
BEGIN;
178+
CREATESCHEMActl_schema;
179+
SET LOCAL search_path= ctl_schema, public;
180+
CREATETABLEctlt1 (LIKE ctlt1 INCLUDING ALL);
181+
\d+ ctlt1
182+
ROLLBACK;
183+
176184
DROPTABLE ctlt1, ctlt2, ctlt3, ctlt4, ctlt12_storage, ctlt12_comments, ctlt1_inh, ctlt13_inh, ctlt13_like, ctlt_all, ctla, ctlb CASCADE;
177185

178186

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp