Skip to content

Commit 1854a69

Browse files
tglsfdcCommitfest Bot
authored andcommitted
Change the names generated for index partitions.
Instead of applying the default index-naming algorithm using the name of the child partition, use the name of the parent partitioned index, plus an underscore and some digit(s) as needed to make the name unique. This is similar to the rule adopted in commit 3db61db for child foreign-key constraints. As in that case, the immediate motivation is to reduce the risk of index name collisions; but it seems like this rule might be preferable from a user-experience standpoint anyway. Although these cases share code with CREATE TABLE LIKE ... INCLUDING INDEXES, I kept the old behavior for CREATE TABLE LIKE. It seems less obvious that changing that would be a user-experience improvement, since with CREATE TABLE LIKE there isn't any permanent connection of the parent and child tables. There is also a much larger race-condition window for name collisions if we try to do this in CREATE TABLE LIKE, since more time and indeed perhaps some other index creations could occur before the actual index creation happens. Finally, this is already a pretty big user-visible behavioral change; not changing the much-longer-standing CREATE TABLE LIKE behavior should reduce the blast radius a little bit. Bug: #18959 Reported-by: Maximilian Chrzan <[email protected]> Author: Tom Lane <[email protected]> Discussion: https://postgr.es/m/[email protected]
1 parent 5487058 commit 1854a69

File tree

25 files changed

+551
-506
lines changed

25 files changed

+551
-506
lines changed

contrib/btree_gist/expected/partitions.out

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ select * from parttmp_11_to_20 order by id, valid_at;
7474
-- make sure the excluson constraint excludes:
7575
insert into parttmp (id, valid_at) values
7676
(2, '[2000-01-15, 2000-02-01)');
77-
ERROR: conflicting key value violates exclusion constraint "parttmp_1_to_10_id_valid_at_excl"
77+
ERROR: conflicting key value violates exclusion constraint "parttmp_id_valid_at_excl_1"
7878
DETAIL: Key (id, valid_at)=(2, [01-15-2000,02-01-2000)) conflicts with existing key (id, valid_at)=(2, [01-01-2000,02-01-2000)).
7979
drop table parttmp;
8080
-- should fail with a good error message:

contrib/pg_overexplain/expected/pg_overexplain.out

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -388,8 +388,8 @@ SELECT explain_filter($$
388388
EXPLAIN (BUFFERS OFF, COSTS OFF, SUMMARY OFF, TIMING OFF, ANALYZE, DEBUG)
389389
SELECT * FROM vegetables v1, vegetables v2 WHERE v1.id = v2.id;
390390
$$);
391-
explain_filter
392-
------------------------------------------------------------------------------------------
391+
explain_filter
392+
----------------------------------------------------------------------------------------------
393393
Nested Loop (actual rows=N.NN loops=1)
394394
Disabled Nodes: 0
395395
Parallel Safe: true
@@ -398,12 +398,12 @@ $$);
398398
Disabled Nodes: 0
399399
Parallel Safe: true
400400
Plan Node ID: 1
401-
-> Index Scan using brassica_id_idx on brassica v1_1 (actual rows=N.NN loops=1)
401+
-> Index Scan using vegetables_id_idx_1 on brassica v1_1 (actual rows=N.NN loops=1)
402402
Index Searches: 1
403403
Disabled Nodes: 0
404404
Parallel Safe: true
405405
Plan Node ID: 2
406-
-> Index Scan using daucus_id_idx on daucus v1_2 (actual rows=N.NN loops=1)
406+
-> Index Scan using vegetables_id_idx_2 on daucus v1_2 (actual rows=N.NN loops=1)
407407
Index Searches: 1
408408
Disabled Nodes: 0
409409
Parallel Safe: true
@@ -414,15 +414,15 @@ $$);
414414
Plan Node ID: 4
415415
extParam: 0
416416
allParam: 0
417-
-> Index Scan using brassica_id_idx on brassica v2_1 (actual rows=N.NN loops=8)
417+
-> Index Scan using vegetables_id_idx_1 on brassica v2_1 (actual rows=N.NN loops=8)
418418
Index Cond: (id = v1.id)
419419
Index Searches: 8
420420
Disabled Nodes: 0
421421
Parallel Safe: true
422422
Plan Node ID: 5
423423
extParam: 0
424424
allParam: 0
425-
-> Index Scan using daucus_id_idx on daucus v2_2 (actual rows=N.NN loops=8)
425+
-> Index Scan using vegetables_id_idx_2 on daucus v2_2 (actual rows=N.NN loops=8)
426426
Index Cond: (id = v1.id)
427427
Index Searches: 8
428428
Disabled Nodes: 0

contrib/seg/expected/partition.out

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ Partitions: pt12 FOR VALUES IN (1, 2),
4848
Partition of: pt FOR VALUES IN (1, 2)
4949
Partition constraint: ((category IS NOT NULL) AND (category = ANY (ARRAY[1, 2])))
5050
Indexes:
51-
"pt12_expr_idx" btree ((mydouble(category) + 1))
52-
"pt12_sdata_idx" btree (sdata)
53-
"pt12_tdata_idx" btree (tdata COLLATE mycollation)
51+
"pti1_1" btree ((mydouble(category) + 1))
52+
"pti2_1" btree (sdata)
53+
"pti3_1" btree (tdata COLLATE mycollation)
5454

src/backend/commands/indexcmds.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1366,6 +1366,7 @@ DefineIndex(Oid tableId,
13661366
{
13671367
Oid childRelid = part_oids[i];
13681368
Relation childrel;
1369+
Oid childNamespace;
13691370
Oid child_save_userid;
13701371
int child_save_sec_context;
13711372
int child_save_nestlevel;
@@ -1375,6 +1376,7 @@ DefineIndex(Oid tableId,
13751376
bool found = false;
13761377

13771378
childrel = table_open(childRelid, lockmode);
1379+
childNamespace = RelationGetNamespace(childrel);
13781380

13791381
GetUserIdAndSecContext(&child_save_userid,
13801382
&child_save_sec_context);
@@ -1506,8 +1508,10 @@ DefineIndex(Oid tableId,
15061508
* original IndexStmt might not be.
15071509
*/
15081510
childStmt = generateClonedIndexStmt(NULL,
1511+
childNamespace,
15091512
parentIndex,
15101513
attmap,
1514+
true,
15111515
NULL);
15121516

15131517
/*
@@ -2583,6 +2587,8 @@ makeObjectName(const char *name1, const char *name2, const char *label)
25832587
* name1, name2, and label are used the same way as for makeObjectName(),
25842588
* except that the label can't be NULL; digits will be appended to the label
25852589
* if needed to create a name that is unique within the specified namespace.
2590+
* If the given label is empty, we only consider names that include at least
2591+
* one added digit.
25862592
*
25872593
* If isconstraint is true, we also avoid choosing a name matching any
25882594
* existing constraint in the same namespace. (This is stricter than what
@@ -2616,8 +2622,11 @@ ChooseRelationName(const char *name1, const char *name2,
26162622
InitDirtySnapshot(SnapshotDirty);
26172623
pgclassrel = table_open(RelationRelationId, AccessShareLock);
26182624

2619-
/* try the unmodified label first */
2620-
strlcpy(modlabel, label, sizeof(modlabel));
2625+
/* try the unmodified label first, unless it's empty */
2626+
if (label[0] != '\0')
2627+
strlcpy(modlabel, label, sizeof(modlabel));
2628+
else
2629+
snprintf(modlabel, sizeof(modlabel), "%s%d", label, ++pass);
26212630

26222631
for (;;)
26232632
{

src/backend/commands/tablecmds.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1295,8 +1295,12 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
12951295
RelationGetDescr(parent),
12961296
false);
12971297
idxstmt =
1298-
generateClonedIndexStmt(NULL, idxRel,
1299-
attmap, &constraintOid);
1298+
generateClonedIndexStmt(NULL,
1299+
RelationGetNamespace(rel),
1300+
idxRel,
1301+
attmap,
1302+
true,
1303+
&constraintOid);
13001304
DefineIndex(RelationGetRelid(rel),
13011305
idxstmt,
13021306
InvalidOid,
@@ -20676,7 +20680,10 @@ AttachPartitionEnsureIndexes(List **wqueue, Relation rel, Relation attachrel)
2067620680
Oid conOid;
2067720681

2067820682
stmt = generateClonedIndexStmt(NULL,
20679-
idxRel, attmap,
20683+
RelationGetNamespace(attachrel),
20684+
idxRel,
20685+
attmap,
20686+
true,
2068020687
&conOid);
2068120688
DefineIndex(RelationGetRelid(attachrel), stmt, InvalidOid,
2068220689
RelationGetRelid(idxRel),

src/backend/parser/parse_utilcmd.c

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1561,10 +1561,18 @@ expandTableLikeClause(RangeVar *heapRel, TableLikeClause *table_like_clause)
15611561

15621562
parent_index = index_open(parent_index_oid, AccessShareLock);
15631563

1564-
/* Build CREATE INDEX statement to recreate the parent_index */
1564+
/*
1565+
* Build CREATE INDEX statement to recreate the parent_index. But
1566+
* do not clone the parent index's name: that doesn't seem
1567+
* entirely appropriate in CREATE TABLE LIKE, and besides there's
1568+
* a race condition because we're some ways away from actually
1569+
* creating the new index.
1570+
*/
15651571
index_stmt = generateClonedIndexStmt(heapRel,
1572+
RelationGetNamespace(childrel),
15661573
parent_index,
15671574
attmap,
1575+
false,
15681576
NULL);
15691577

15701578
/* Copy comment on index, if requested */
@@ -1678,9 +1686,18 @@ transformOfType(CreateStmtContext *cxt, TypeName *ofTypename)
16781686
* heapRel is stored into the IndexStmt's relation field, but we don't use it
16791687
* otherwise; some callers pass NULL, if they don't need it to be valid.
16801688
* (The target relation might not exist yet, so we mustn't try to access it.)
1689+
* The namespace OID for the target relation must be provided, though.
16811690
*
16821691
* Attribute numbers in expression Vars are adjusted according to attmap.
16831692
*
1693+
* If clone_name is true, we copy the source index's name, with addition of
1694+
* an underscore and digit(s) to make a unique name. Otherwise we leave it
1695+
* to DefineIndex to pick a name derived from the target relation's name.
1696+
* (We typically use "true" for partitioned-index cases and "false" for
1697+
* CREATE TABLE LIKE. Note that it's a bit unsafe to use "true" if we're
1698+
* not immediately going to call DefineIndex, since a conflicting index
1699+
* could appear in the interim.)
1700+
*
16841701
* If constraintOid isn't NULL, we store the OID of any constraint associated
16851702
* with the index there.
16861703
*
@@ -1690,8 +1707,11 @@ transformOfType(CreateStmtContext *cxt, TypeName *ofTypename)
16901707
* complain if that fails to happen).
16911708
*/
16921709
IndexStmt *
1693-
generateClonedIndexStmt(RangeVar *heapRel, Relation source_idx,
1710+
generateClonedIndexStmt(RangeVar *heapRel,
1711+
Oid heapNamespace,
1712+
Relation source_idx,
16941713
const AttrMap *attmap,
1714+
bool clone_name,
16951715
Oid *constraintOid)
16961716
{
16971717
Oid source_relid = RelationGetRelid(source_idx);
@@ -1768,14 +1788,6 @@ generateClonedIndexStmt(RangeVar *heapRel, Relation source_idx,
17681788
index->if_not_exists = false;
17691789
index->reset_default_tblspc = false;
17701790

1771-
/*
1772-
* We don't try to preserve the name of the source index; instead, just
1773-
* let DefineIndex() choose a reasonable name. (If we tried to preserve
1774-
* the name, we'd get duplicate-relation-name failures unless the source
1775-
* table was in a different schema.)
1776-
*/
1777-
index->idxname = NULL;
1778-
17791791
/*
17801792
* If the index is marked PRIMARY or has an exclusion condition, it's
17811793
* certainly from a constraint; else, if it's not marked UNIQUE, it
@@ -1854,6 +1866,21 @@ generateClonedIndexStmt(RangeVar *heapRel, Relation source_idx,
18541866
else
18551867
index->isconstraint = false;
18561868

1869+
/*
1870+
* Choose a name for the new index. Ideally we'd preserve the name of the
1871+
* source index, but that leads to duplicate-relation-name failures if the
1872+
* new table is in the same schema. Instead use ChooseRelationName, which
1873+
* will append an underscore and digits as needed to make a unique name.
1874+
* Or, if we're told not to choose a name, just set idxname = NULL.
1875+
*/
1876+
if (clone_name)
1877+
index->idxname = ChooseRelationName(RelationGetRelationName(source_idx),
1878+
NULL, "",
1879+
heapNamespace,
1880+
index->isconstraint);
1881+
else
1882+
index->idxname = NULL;
1883+
18571884
/* Get the index expressions, if any */
18581885
datum = SysCacheGetAttr(INDEXRELID, ht_idx,
18591886
Anum_pg_index_indexprs, &isnull);

src/bin/pg_dump/t/002_pg_dump.pl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4271,7 +4271,7 @@
42714271
42724272
'CREATE INDEX ... ON measurement_y2006_m2' => {
42734273
regexp => qr/^
4274-
\QCREATE INDEX measurement_y2006m2_city_id_logdate_idx ON dump_test_second_schema.measurement_y2006m2 \E
4274+
\QCREATE INDEX measurement_city_id_logdate_idx_1 ON dump_test_second_schema.measurement_y2006m2 \E
42754275
/xm,
42764276
like => {
42774277
%full_runs,
@@ -4286,7 +4286,7 @@
42864286
42874287
'ALTER INDEX ... ATTACH PARTITION' => {
42884288
regexp => qr/^
4289-
\QALTER INDEX dump_test.measurement_city_id_logdate_idx ATTACH PARTITION dump_test_second_schema.measurement_y2006m2_city_id_logdate_idx\E
4289+
\QALTER INDEX dump_test.measurement_city_id_logdate_idx ATTACH PARTITION dump_test_second_schema.measurement_city_id_logdate_idx_1\E
42904290
/xm,
42914291
like => {
42924292
%full_runs,
@@ -4302,7 +4302,7 @@
43024302
'ALTER INDEX ... ATTACH PARTITION (primary key)' => {
43034303
catch_all => 'CREATE ... commands',
43044304
regexp => qr/^
4305-
\QALTER INDEX dump_test.measurement_pkey ATTACH PARTITION dump_test_second_schema.measurement_y2006m2_pkey\E
4305+
\QALTER INDEX dump_test.measurement_pkey ATTACH PARTITION dump_test_second_schema.measurement_pkey_1\E
43064306
/xm,
43074307
like => {
43084308
%full_runs,

src/include/parser/parse_utilcmd.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,10 @@ extern PartitionBoundSpec *transformPartitionBound(ParseState *pstate, Relation
3737
extern List *expandTableLikeClause(RangeVar *heapRel,
3838
TableLikeClause *table_like_clause);
3939
extern IndexStmt *generateClonedIndexStmt(RangeVar *heapRel,
40+
Oid heapNamespace,
4041
Relation source_idx,
4142
const struct AttrMap *attmap,
43+
bool clone_name,
4244
Oid *constraintOid);
4345

4446
#endif /* PARSE_UTILCMD_H */

src/test/isolation/expected/partition-drop-index-locking.out

Lines changed: 31 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,15 @@ step s3getlocks:
1818
WHERE c.relname LIKE 'part_drop_index_locking%'
1919
ORDER BY s.query, c.relname, l.mode, l.granted;
2020

21-
query |relname |mode |granted
22-
----------------------------------------------------+---------------------------------------------+-------------------+-------
23-
DROP INDEX part_drop_index_locking_idx; |part_drop_index_locking |AccessExclusiveLock|t
24-
DROP INDEX part_drop_index_locking_idx; |part_drop_index_locking_idx |AccessExclusiveLock|t
25-
DROP INDEX part_drop_index_locking_idx; |part_drop_index_locking_subpart |AccessExclusiveLock|t
26-
DROP INDEX part_drop_index_locking_idx; |part_drop_index_locking_subpart_child |AccessExclusiveLock|f
27-
SELECT * FROM part_drop_index_locking_subpart_child;|part_drop_index_locking_subpart_child |AccessShareLock |t
28-
SELECT * FROM part_drop_index_locking_subpart_child;|part_drop_index_locking_subpart_child_id_idx |AccessShareLock |t
29-
SELECT * FROM part_drop_index_locking_subpart_child;|part_drop_index_locking_subpart_child_id_idx1|AccessShareLock |t
21+
query |relname |mode |granted
22+
----------------------------------------------------+-------------------------------------+-------------------+-------
23+
DROP INDEX part_drop_index_locking_idx; |part_drop_index_locking |AccessExclusiveLock|t
24+
DROP INDEX part_drop_index_locking_idx; |part_drop_index_locking_idx |AccessExclusiveLock|t
25+
DROP INDEX part_drop_index_locking_idx; |part_drop_index_locking_subpart |AccessExclusiveLock|t
26+
DROP INDEX part_drop_index_locking_idx; |part_drop_index_locking_subpart_child|AccessExclusiveLock|f
27+
SELECT * FROM part_drop_index_locking_subpart_child;|part_drop_index_locking_idx_1_1 |AccessShareLock |t
28+
SELECT * FROM part_drop_index_locking_subpart_child;|part_drop_index_locking_subpart_child|AccessShareLock |t
29+
SELECT * FROM part_drop_index_locking_subpart_child;|part_drop_index_locking_subpart_idx_1|AccessShareLock |t
3030
(7 rows)
3131

3232
step s1commit: COMMIT;
@@ -39,14 +39,14 @@ step s3getlocks:
3939
WHERE c.relname LIKE 'part_drop_index_locking%'
4040
ORDER BY s.query, c.relname, l.mode, l.granted;
4141

42-
query |relname |mode |granted
43-
---------------------------------------+--------------------------------------------+-------------------+-------
44-
DROP INDEX part_drop_index_locking_idx;|part_drop_index_locking |AccessExclusiveLock|t
45-
DROP INDEX part_drop_index_locking_idx;|part_drop_index_locking_idx |AccessExclusiveLock|t
46-
DROP INDEX part_drop_index_locking_idx;|part_drop_index_locking_subpart |AccessExclusiveLock|t
47-
DROP INDEX part_drop_index_locking_idx;|part_drop_index_locking_subpart_child |AccessExclusiveLock|t
48-
DROP INDEX part_drop_index_locking_idx;|part_drop_index_locking_subpart_child_id_idx|AccessExclusiveLock|t
49-
DROP INDEX part_drop_index_locking_idx;|part_drop_index_locking_subpart_id_idx |AccessExclusiveLock|t
42+
query |relname |mode |granted
43+
---------------------------------------+-------------------------------------+-------------------+-------
44+
DROP INDEX part_drop_index_locking_idx;|part_drop_index_locking |AccessExclusiveLock|t
45+
DROP INDEX part_drop_index_locking_idx;|part_drop_index_locking_idx |AccessExclusiveLock|t
46+
DROP INDEX part_drop_index_locking_idx;|part_drop_index_locking_idx_1 |AccessExclusiveLock|t
47+
DROP INDEX part_drop_index_locking_idx;|part_drop_index_locking_idx_1_1 |AccessExclusiveLock|t
48+
DROP INDEX part_drop_index_locking_idx;|part_drop_index_locking_subpart |AccessExclusiveLock|t
49+
DROP INDEX part_drop_index_locking_idx;|part_drop_index_locking_subpart_child|AccessExclusiveLock|t
5050
(6 rows)
5151

5252
step s2commit: COMMIT;
@@ -69,14 +69,14 @@ step s3getlocks:
6969
WHERE c.relname LIKE 'part_drop_index_locking%'
7070
ORDER BY s.query, c.relname, l.mode, l.granted;
7171

72-
query |relname |mode |granted
73-
----------------------------------------------------+---------------------------------------------+-------------------+-------
74-
DROP INDEX part_drop_index_locking_subpart_idx; |part_drop_index_locking_subpart |AccessExclusiveLock|t
75-
DROP INDEX part_drop_index_locking_subpart_idx; |part_drop_index_locking_subpart_child |AccessExclusiveLock|f
76-
DROP INDEX part_drop_index_locking_subpart_idx; |part_drop_index_locking_subpart_idx |AccessExclusiveLock|t
77-
SELECT * FROM part_drop_index_locking_subpart_child;|part_drop_index_locking_subpart_child |AccessShareLock |t
78-
SELECT * FROM part_drop_index_locking_subpart_child;|part_drop_index_locking_subpart_child_id_idx |AccessShareLock |t
79-
SELECT * FROM part_drop_index_locking_subpart_child;|part_drop_index_locking_subpart_child_id_idx1|AccessShareLock |t
72+
query |relname |mode |granted
73+
----------------------------------------------------+-------------------------------------+-------------------+-------
74+
DROP INDEX part_drop_index_locking_subpart_idx; |part_drop_index_locking_subpart |AccessExclusiveLock|t
75+
DROP INDEX part_drop_index_locking_subpart_idx; |part_drop_index_locking_subpart_child|AccessExclusiveLock|f
76+
DROP INDEX part_drop_index_locking_subpart_idx; |part_drop_index_locking_subpart_idx |AccessExclusiveLock|t
77+
SELECT * FROM part_drop_index_locking_subpart_child;|part_drop_index_locking_idx_1_1 |AccessShareLock |t
78+
SELECT * FROM part_drop_index_locking_subpart_child;|part_drop_index_locking_subpart_child|AccessShareLock |t
79+
SELECT * FROM part_drop_index_locking_subpart_child;|part_drop_index_locking_subpart_idx_1|AccessShareLock |t
8080
(6 rows)
8181

8282
step s1commit: COMMIT;
@@ -89,12 +89,12 @@ step s3getlocks:
8989
WHERE c.relname LIKE 'part_drop_index_locking%'
9090
ORDER BY s.query, c.relname, l.mode, l.granted;
9191

92-
query |relname |mode |granted
93-
-----------------------------------------------+---------------------------------------------+-------------------+-------
94-
DROP INDEX part_drop_index_locking_subpart_idx;|part_drop_index_locking_subpart |AccessExclusiveLock|t
95-
DROP INDEX part_drop_index_locking_subpart_idx;|part_drop_index_locking_subpart_child |AccessExclusiveLock|t
96-
DROP INDEX part_drop_index_locking_subpart_idx;|part_drop_index_locking_subpart_child_id_idx1|AccessExclusiveLock|t
97-
DROP INDEX part_drop_index_locking_subpart_idx;|part_drop_index_locking_subpart_idx |AccessExclusiveLock|t
92+
query |relname |mode |granted
93+
-----------------------------------------------+-------------------------------------+-------------------+-------
94+
DROP INDEX part_drop_index_locking_subpart_idx;|part_drop_index_locking_subpart |AccessExclusiveLock|t
95+
DROP INDEX part_drop_index_locking_subpart_idx;|part_drop_index_locking_subpart_child|AccessExclusiveLock|t
96+
DROP INDEX part_drop_index_locking_subpart_idx;|part_drop_index_locking_subpart_idx |AccessExclusiveLock|t
97+
DROP INDEX part_drop_index_locking_subpart_idx;|part_drop_index_locking_subpart_idx_1|AccessExclusiveLock|t
9898
(4 rows)
9999

100100
step s2commit: COMMIT;

0 commit comments

Comments
 (0)