postgres.git / summary / log / commit / refs
commit 79b575d3bc09cc67a7b5c2da454aeb35f4beccc5
Author: Peter Eisentraut <peter@eisentraut.org>
Date: Thu Nov 21 12:50:18 2024 +0000
First released in: 18.0
Fix ALTER TABLE / REPLICA IDENTITY for temporal tables
REPLICA IDENTITY USING INDEX did not accept a GiST index. This should
be allowed when used as a temporal primary key.
Author: Paul Jungwirth <pj@illuminatedcomputing.com>
Discussion: https://www.postgresql.org/message-id/04579cbf-b134-45e1-8f2d-8c54c849c1ee@illuminatedcomputing.com
src/backend/commands/tablecmds.c | 11 ++++++++---
src/test/regress/expected/without_overlaps.out | 20 ++++++++++++++++++--
src/test/regress/sql/without_overlaps.sql | 3 ++-
3 files changed, 28 insertions(+), 6 deletions(-)
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index c632d1e8245..f53129a1c48 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -17296,9 +17296,14 @@ ATExecReplicaIdentity(Relation rel, ReplicaIdentityStmt *stmt, LOCKMODE lockmode
errmsg("\"%s\" is not an index for table \"%s\"",
RelationGetRelationName(indexRel),
RelationGetRelationName(rel))));
- /* The AM must support uniqueness, and the index must in fact be unique. */
- if (!indexRel->rd_indam->amcanunique ||
- !indexRel->rd_index->indisunique)
+ /*
+ * The AM must support uniqueness, and the index must in fact be unique.
+ * If we have a WITHOUT OVERLAPS constraint (identified by uniqueness +
+ * exclusion), we can use that too.
+ */
+ if ((!indexRel->rd_indam->amcanunique ||
+ !indexRel->rd_index->indisunique) &&
+ !(indexRel->rd_index->indisunique && indexRel->rd_index->indisexclusion))
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("cannot use non-unique index \"%s\" as replica identity",
diff --git a/src/test/regress/expected/without_overlaps.out b/src/test/regress/expected/without_overlaps.out
index d6cb65e9a63..8b5ecab6fd8 100644
--- a/src/test/regress/expected/without_overlaps.out
+++ b/src/test/regress/expected/without_overlaps.out
@@ -978,9 +978,25 @@ SELECT * FROM tp2 ORDER BY id, valid_at;
DROP TABLE temporal_partitioned;
-- ALTER TABLE REPLICA IDENTITY
--- (should fail)
+\d temporal_rng
+ Table "public.temporal_rng"
+ Column | Type | Collation | Nullable | Default
+----------+-----------+-----------+----------+---------
+ id | int4range | | not null |
+ valid_at | daterange | | not null |
+Indexes:
+ "temporal_rng_pk" PRIMARY KEY (id, valid_at WITHOUT OVERLAPS)
+
ALTER TABLE temporal_rng REPLICA IDENTITY USING INDEX temporal_rng_pk;
-ERROR: cannot use non-unique index "temporal_rng_pk" as replica identity
+\d temporal_rng
+ Table "public.temporal_rng"
+ Column | Type | Collation | Nullable | Default
+----------+-----------+-----------+----------+---------
+ id | int4range | | not null |
+ valid_at | daterange | | not null |
+Indexes:
+ "temporal_rng_pk" PRIMARY KEY (id, valid_at WITHOUT OVERLAPS) REPLICA IDENTITY
+
--
-- ON CONFLICT: ranges
--
diff --git a/src/test/regress/sql/without_overlaps.sql b/src/test/regress/sql/without_overlaps.sql
index 943edf3da63..ce58171bc35 100644
--- a/src/test/regress/sql/without_overlaps.sql
+++ b/src/test/regress/sql/without_overlaps.sql
@@ -691,8 +691,9 @@ SELECT * FROM tp2 ORDER BY id, valid_at;
DROP TABLE temporal_partitioned;
-- ALTER TABLE REPLICA IDENTITY
--- (should fail)
+\d temporal_rng
ALTER TABLE temporal_rng REPLICA IDENTITY USING INDEX temporal_rng_pk;
+\d temporal_rng
--
-- ON CONFLICT: ranges
[parent: da94e871e887]