Skip to content

Commit 7e7c57b

Browse files
committed
Fix dependency recording bug for partitioned PKs
When DefineIndex recurses to create constraints on partitions, it needs to use the value returned by index_constraint_create to set up partition dependencies. However, in the course of fixing the DEPENDENCY_INTERNAL_AUTO mess, commit 1d92a0c introduced some code to that function that clobbered the return value, causing the recorded OID to be of the wrong object. Close examination of pg_depend after creating the tables leads to indescribable objects :-( My sin (in commit bdc3d7f, while preparing for DDL deparsing in event triggers) was to use a variable name for the return value that's typically used for throwaway objects in dependency-setting calls ("referenced"). Fix by changing the variable names to match extended practice (the return value is "myself" rather than "referenced".) The pg_upgrade test notices the problem (in an indirect way: the pg_dump outputs are in different order), but only if you create the objects in a specific way that wasn't being used in the existing tests. Add a stanza to leave some objects around that shows the bug. Catversion bump because preexisting databases might have bogus pg_depend entries. Discussion: https://postgr.es/m/[email protected]
1 parent bfb456c commit 7e7c57b

File tree

3 files changed

+44
-12
lines changed

3 files changed

+44
-12
lines changed

src/backend/catalog/index.c

+7-12
Original file line numberDiff line numberDiff line change
@@ -1247,7 +1247,7 @@ index_constraint_create(Relation heapRelation,
12471247
{
12481248
Oid namespaceId = RelationGetNamespace(heapRelation);
12491249
ObjectAddress myself,
1250-
referenced;
1250+
idxaddr;
12511251
Oid conOid;
12521252
bool deferrable;
12531253
bool initdeferred;
@@ -1341,23 +1341,18 @@ index_constraint_create(Relation heapRelation,
13411341
* Note that the constraint has a dependency on the table, so we don't
13421342
* need (or want) any direct dependency from the index to the table.
13431343
*/
1344-
myself.classId = RelationRelationId;
1345-
myself.objectId = indexRelationId;
1346-
myself.objectSubId = 0;
1347-
1348-
referenced.classId = ConstraintRelationId;
1349-
referenced.objectId = conOid;
1350-
referenced.objectSubId = 0;
1351-
1352-
recordDependencyOn(&myself, &referenced, DEPENDENCY_INTERNAL);
1344+
ObjectAddressSet(myself, ConstraintRelationId, conOid);
1345+
ObjectAddressSet(idxaddr, RelationRelationId, indexRelationId);
1346+
recordDependencyOn(&idxaddr, &myself, DEPENDENCY_INTERNAL);
13531347

13541348
/*
13551349
* Also, if this is a constraint on a partition, give it partition-type
13561350
* dependencies on the parent constraint as well as the table.
13571351
*/
13581352
if (OidIsValid(parentConstraintId))
13591353
{
1360-
ObjectAddressSet(myself, ConstraintRelationId, conOid);
1354+
ObjectAddress referenced;
1355+
13611356
ObjectAddressSet(referenced, ConstraintRelationId, parentConstraintId);
13621357
recordDependencyOn(&myself, &referenced, DEPENDENCY_PARTITION_PRI);
13631358
ObjectAddressSet(referenced, RelationRelationId,
@@ -1444,7 +1439,7 @@ index_constraint_create(Relation heapRelation,
14441439
table_close(pg_index, RowExclusiveLock);
14451440
}
14461441

1447-
return referenced;
1442+
return myself;
14481443
}
14491444

14501445
/*

src/test/regress/expected/indexing.out

+18
Original file line numberDiff line numberDiff line change
@@ -1411,6 +1411,24 @@ alter index idxpart2_a_idx attach partition idxpart22_a_idx;
14111411
create index on idxpart (a);
14121412
create table idxpart_another (a int, b int, primary key (a, b)) partition by range (a);
14131413
create table idxpart_another_1 partition of idxpart_another for values from (0) to (100);
1414+
-- More objects intentionally left behind, to verify some pg_dump/pg_upgrade
1415+
-- behavior; see https://postgr.es/m/[email protected]
1416+
create schema regress_indexing;
1417+
set search_path to regress_indexing;
1418+
create table pk (a int primary key) partition by range (a);
1419+
create table pk1 partition of pk for values from (0) to (1000);
1420+
create table pk2 (b int, a int);
1421+
alter table pk2 drop column b;
1422+
alter table pk2 alter a set not null;
1423+
alter table pk attach partition pk2 for values from (1000) to (2000);
1424+
create table pk3 partition of pk for values from (2000) to (3000);
1425+
create table pk4 (like pk);
1426+
alter table pk attach partition pk4 for values from (3000) to (4000);
1427+
create table pk5 (like pk) partition by range (a);
1428+
create table pk51 partition of pk5 for values from (4000) to (4500);
1429+
create table pk52 partition of pk5 for values from (4500) to (5000);
1430+
alter table pk attach partition pk5 for values from (4000) to (5000);
1431+
reset search_path;
14141432
-- Test that covering partitioned indexes work in various cases
14151433
create table covidxpart (a int, b int) partition by list (a);
14161434
create unique index on covidxpart (a) include (b);

src/test/regress/sql/indexing.sql

+19
Original file line numberDiff line numberDiff line change
@@ -748,6 +748,25 @@ create index on idxpart (a);
748748
create table idxpart_another (a int, b int, primary key (a, b)) partition by range (a);
749749
create table idxpart_another_1 partition of idxpart_another for values from (0) to (100);
750750

751+
-- More objects intentionally left behind, to verify some pg_dump/pg_upgrade
752+
-- behavior; see https://postgr.es/m/[email protected]
753+
create schema regress_indexing;
754+
set search_path to regress_indexing;
755+
create table pk (a int primary key) partition by range (a);
756+
create table pk1 partition of pk for values from (0) to (1000);
757+
create table pk2 (b int, a int);
758+
alter table pk2 drop column b;
759+
alter table pk2 alter a set not null;
760+
alter table pk attach partition pk2 for values from (1000) to (2000);
761+
create table pk3 partition of pk for values from (2000) to (3000);
762+
create table pk4 (like pk);
763+
alter table pk attach partition pk4 for values from (3000) to (4000);
764+
create table pk5 (like pk) partition by range (a);
765+
create table pk51 partition of pk5 for values from (4000) to (4500);
766+
create table pk52 partition of pk5 for values from (4500) to (5000);
767+
alter table pk attach partition pk5 for values from (4000) to (5000);
768+
reset search_path;
769+
751770
-- Test that covering partitioned indexes work in various cases
752771
create table covidxpart (a int, b int) partition by list (a);
753772
create unique index on covidxpart (a) include (b);

0 commit comments

Comments
 (0)