Commit
8c852ba9a4 allowed exclusion constraints to be added to
partitioned tables, but wasn't careful to verify that pg_restore worked
correctly for them. Fix that by making CompareIndexInfo() more
selective about what needs to be rejected.
Author: Japin Li <japinli@hotmail.com>
Reported-by: Keith Paskett <keith.paskett@logansw.com>
Discussion: https://postgr.es/m/
2A40921D-83AB-411E-ADA6-
7E509A46F1E4@logansw.com
return false;
}
- /* No support currently for comparing exclusion indexes. */
- if (info1->ii_ExclusionOps != NULL || info2->ii_ExclusionOps != NULL)
+ /* If they're exclusion indexes, their properties must be identical */
+ if ((info1->ii_ExclusionOps == NULL) != (info2->ii_ExclusionOps == NULL))
return false;
+ if (info1->ii_ExclusionOps != NULL)
+ {
+ for (i = 0; i < info1->ii_NumIndexKeyAttrs; i++)
+ {
+ if (info1->ii_ExclusionOps[i] != info2->ii_ExclusionOps[i])
+ return false;
+ if (info1->ii_ExclusionProcs[i] != info2->ii_ExclusionProcs[i])
+ return false;
+ if (info1->ii_ExclusionStrats[i] != info2->ii_ExclusionStrats[i])
+ return false;
+ }
+ }
return true;
}
drop index row_image_index;
drop function row_image(test_pg_wholerow_index);
drop table test_pg_wholerow_index;
+-- Test of a partitioned index attach, when there are exclusion constraints.
+create table idx_excl_part (a int4range, b int4range) partition by list (a);
+create table idx_excl_part_1 (a int4range, b int4range);
+alter table only idx_excl_part attach partition idx_excl_part_1 for values in ('[0,1)'::int4range);
+alter table only idx_excl_part add constraint idxpart_id_data_excl exclude using gist (a with =, b with &&);
+alter table idx_excl_part_1 add constraint idxpart_1_id_data_excl exclude using gist (a with &&, b with &&);
+-- This should be disallowed, because the constraints don't match.
+alter index idxpart_id_data_excl attach partition idxpart_1_id_data_excl;
+ERROR: cannot attach index "idxpart_1_id_data_excl" as a partition of index "idxpart_id_data_excl"
+DETAIL: The index definitions do not match.
+-- but if we recreate the constraint differently, it's allowed:
+alter table idx_excl_part_1 drop constraint idxpart_1_id_data_excl;
+alter table idx_excl_part_1 add constraint idxpart_1_id_data_excl exclude using gist (a with =, b with &&);
+alter index idxpart_id_data_excl attach partition idxpart_1_id_data_excl;
+-- leave these tables around, for pg_upgrade testing
drop index row_image_index;
drop function row_image(test_pg_wholerow_index);
drop table test_pg_wholerow_index;
+
+-- Test of a partitioned index attach, when there are exclusion constraints.
+create table idx_excl_part (a int4range, b int4range) partition by list (a);
+create table idx_excl_part_1 (a int4range, b int4range);
+alter table only idx_excl_part attach partition idx_excl_part_1 for values in ('[0,1)'::int4range);
+alter table only idx_excl_part add constraint idxpart_id_data_excl exclude using gist (a with =, b with &&);
+alter table idx_excl_part_1 add constraint idxpart_1_id_data_excl exclude using gist (a with &&, b with &&);
+-- This should be disallowed, because the constraints don't match.
+alter index idxpart_id_data_excl attach partition idxpart_1_id_data_excl;
+-- but if we recreate the constraint differently, it's allowed:
+alter table idx_excl_part_1 drop constraint idxpart_1_id_data_excl;
+alter table idx_excl_part_1 add constraint idxpart_1_id_data_excl exclude using gist (a with =, b with &&);
+alter index idxpart_id_data_excl attach partition idxpart_1_id_data_excl;
+-- leave these tables around, for pg_upgrade testing