diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index fd144d783d9..ec3b374f6fa 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -1685,6 +1685,17 @@ RemoveRelations(DropStmt *drop) continue; } + /* + * An explicitly selected replica identity must remain available until + * the table's replica identity is changed. + */ + if (drop->removeType == OBJECT_INDEX && get_index_isreplident(relOid)) + ereport(ERROR, + errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST), + errmsg("cannot drop index \"%s\" because it is used as replica identity", + rel->relname), + errhint("Use ALTER TABLE ... REPLICA IDENTITY to change the table's replica identity first.")); + /* * Decide if concurrent mode needs to be used here or not. The * callback retrieved the rel's persistence for us. diff --git a/src/test/regress/expected/replica_identity.out b/src/test/regress/expected/replica_identity.out index 1560cd04125..bcfcf1a1b4b 100644 --- a/src/test/regress/expected/replica_identity.out +++ b/src/test/regress/expected/replica_identity.out @@ -133,6 +133,10 @@ SELECT count(*) FROM pg_index WHERE indrelid = 'test_replica_identity'::regclass 1 (1 row) +-- An explicitly selected replica identity index cannot be dropped. +DROP INDEX test_replica_identity_keyab_key; +ERROR: cannot drop index "test_replica_identity_keyab_key" because it is used as replica identity +HINT: Use ALTER TABLE ... REPLICA IDENTITY to change the table's replica identity first. ---- -- Make sure non index cases work ---- @@ -143,6 +147,7 @@ SELECT relreplident FROM pg_class WHERE oid = 'test_replica_identity'::regclass; d (1 row) +DROP INDEX test_replica_identity_keyab_key; SELECT count(*) FROM pg_index WHERE indrelid = 'test_replica_identity'::regclass AND indisreplident; count ------- @@ -169,7 +174,6 @@ Indexes: "test_replica_identity_expr" UNIQUE, btree (keya, keyb, (3)) "test_replica_identity_hash" hash (nonkey) "test_replica_identity_keyab" btree (keya, keyb) - "test_replica_identity_keyab_key" UNIQUE, btree (keya, keyb) "test_replica_identity_nonkey" UNIQUE, btree (keya, nonkey) "test_replica_identity_partial" UNIQUE, btree (keya, keyb) WHERE keyb <> '3'::text "test_replica_identity_unique_defer" UNIQUE CONSTRAINT, btree (keya, keyb) DEFERRABLE @@ -200,7 +204,6 @@ Indexes: "test_replica_identity_expr" UNIQUE, btree (keya, keyb, (3)) "test_replica_identity_hash" hash (nonkey) "test_replica_identity_keyab" btree (keya, keyb) - "test_replica_identity_keyab_key" UNIQUE, btree (keya, keyb) "test_replica_identity_nonkey" UNIQUE, btree (keya, nonkey) "test_replica_identity_partial" UNIQUE, btree (keya, keyb) WHERE keyb <> '3'::text "test_replica_identity_unique_defer" UNIQUE CONSTRAINT, btree (keya, keyb) DEFERRABLE diff --git a/src/test/regress/sql/replica_identity.sql b/src/test/regress/sql/replica_identity.sql index 4ebb097f282..b8d29ca8fa5 100644 --- a/src/test/regress/sql/replica_identity.sql +++ b/src/test/regress/sql/replica_identity.sql @@ -65,11 +65,15 @@ SELECT relreplident FROM pg_class WHERE oid = 'test_replica_identity'::regclass; \d test_replica_identity SELECT count(*) FROM pg_index WHERE indrelid = 'test_replica_identity'::regclass AND indisreplident; +-- An explicitly selected replica identity index cannot be dropped. +DROP INDEX test_replica_identity_keyab_key; + ---- -- Make sure non index cases work ---- ALTER TABLE test_replica_identity REPLICA IDENTITY DEFAULT; SELECT relreplident FROM pg_class WHERE oid = 'test_replica_identity'::regclass; +DROP INDEX test_replica_identity_keyab_key; SELECT count(*) FROM pg_index WHERE indrelid = 'test_replica_identity'::regclass AND indisreplident; ALTER TABLE test_replica_identity REPLICA IDENTITY FULL;