v2-restore-partitioned-tables-with-exclude-constraints.patch

application/octet-stream

Filename: v2-restore-partitioned-tables-with-exclude-constraints.patch
Type: application/octet-stream
Part: 0
Message: 回复: pg_restore error with partitioned table having exclude constraint

Patch

Same data as JSON: GET /api/v1/attachments/:id/patch the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes. API reference →
Format: unified
Series: patch v2
File+
src/backend/catalog/index.c 14 2
src/test/regress/expected/indexing.out 21 0
src/test/regress/sql/indexing.sql 20 0
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 739a92bdcc1..5fba4355d76 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -2645,9 +2645,21 @@ CompareIndexInfo(const IndexInfo *info1, const IndexInfo *info2,
 			return false;
 	}
 
-	/* No support currently for comparing exclusion indexes. */
-	if (info1->ii_ExclusionOps != NULL || info2->ii_ExclusionOps != NULL)
+	/* Exclusion index must be identical, if they exist */
+	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;
 }
diff --git a/src/test/regress/expected/indexing.out b/src/test/regress/expected/indexing.out
index bcf1db11d73..30c35b8784f 100644
--- a/src/test/regress/expected/indexing.out
+++ b/src/test/regress/expected/indexing.out
@@ -1669,3 +1669,24 @@ reindex index test_pg_index_toast_index;
 drop index test_pg_index_toast_index;
 drop function test_pg_index_toast_func;
 drop table test_pg_index_toast_table;
+-- test that attaching exclusion index on partition table
+create schema regress_excl_indexing;
+set search_path to regress_excl_indexing;
+create table idxpart (a int4range, b int4range) partition by list (a);
+create table idxpart_1 (a int4range, b int4range);
+alter table only idxpart attach partition idxpart_1 for values in ('[0,1)'::int4range);
+alter table only idxpart add constraint idxpart_id_data_excl exclude USING GIST (a with =, b with &&);
+alter table only idxpart_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;
+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.
+drop table idxpart, idxpart_1;
+-- More objects intentionally left behind, to verify some pg_dump/pg_upgrade
+-- behavior.
+create table exclpart (a int4range, b int4range) partition by list (a);
+create table exclpart_1 (a int4range, b int4range);
+alter table only exclpart attach partition exclpart_1 for values in ('[0,1)'::int4range);
+alter table only exclpart add constraint exclpart_id_data_excl exclude USING GIST (a with =, b with &&);
+alter table only exclpart_1 add constraint exclpart_1_id_data_excl exclude USING GIST (a with =, b with &&);
+alter index exclpart_id_data_excl attach partition exclpart_1_id_data_excl;
+reset search_path;
diff --git a/src/test/regress/sql/indexing.sql b/src/test/regress/sql/indexing.sql
index b5cb01c2d70..aae277aab03 100644
--- a/src/test/regress/sql/indexing.sql
+++ b/src/test/regress/sql/indexing.sql
@@ -934,3 +934,23 @@ reindex index test_pg_index_toast_index;
 drop index test_pg_index_toast_index;
 drop function test_pg_index_toast_func;
 drop table test_pg_index_toast_table;
+
+-- test that attaching exclusion index on partition table
+create schema regress_excl_indexing;
+set search_path to regress_excl_indexing;
+create table idxpart (a int4range, b int4range) partition by list (a);
+create table idxpart_1 (a int4range, b int4range);
+alter table only idxpart attach partition idxpart_1 for values in ('[0,1)'::int4range);
+alter table only idxpart add constraint idxpart_id_data_excl exclude USING GIST (a with =, b with &&);
+alter table only idxpart_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;
+drop table idxpart, idxpart_1;
+-- More objects intentionally left behind, to verify some pg_dump/pg_upgrade
+-- behavior.
+create table exclpart (a int4range, b int4range) partition by list (a);
+create table exclpart_1 (a int4range, b int4range);
+alter table only exclpart attach partition exclpart_1 for values in ('[0,1)'::int4range);
+alter table only exclpart add constraint exclpart_id_data_excl exclude USING GIST (a with =, b with &&);
+alter table only exclpart_1 add constraint exclpart_1_id_data_excl exclude USING GIST (a with =, b with &&);
+alter index exclpart_id_data_excl attach partition exclpart_1_id_data_excl;
+reset search_path;