From e24695c4a912eeefe0cfc2fbfa5369a0374e6223 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Tue, 26 Nov 2024 11:47:24 +0100 Subject: [PATCH 2/3] Replace get_equal_strategy_number_for_am() by get_equal_strategy_number() --- src/backend/executor/execReplication.c | 17 +++-------------- src/backend/replication/logical/relation.c | 15 +++++++++++---- src/include/executor/executor.h | 2 +- 3 files changed, 15 insertions(+), 19 deletions(-) diff --git a/src/backend/executor/execReplication.c b/src/backend/executor/execReplication.c index 54025c9f150..8313ccdb46b 100644 --- a/src/backend/executor/execReplication.c +++ b/src/backend/executor/execReplication.c @@ -39,7 +39,7 @@ static bool tuples_equal(TupleTableSlot *slot1, TupleTableSlot *slot2, /* * Returns the fixed strategy number, if any, of the equality operator for the - * given index access method, otherwise, InvalidStrategy. + * given operator class, otherwise, InvalidStrategy. * * Currently, only Btree and Hash indexes are supported. The other index access * methods don't have a fixed strategy for equality operation - instead, the @@ -47,8 +47,9 @@ static bool tuples_equal(TupleTableSlot *slot1, TupleTableSlot *slot2, * according to the operator class's definition. */ StrategyNumber -get_equal_strategy_number_for_am(Oid am) +get_equal_strategy_number(Oid opclass) { + Oid am = get_opclass_method(opclass); int ret; switch (am) @@ -68,18 +69,6 @@ get_equal_strategy_number_for_am(Oid am) return ret; } -/* - * Return the appropriate strategy number which corresponds to the equality - * operator. - */ -static StrategyNumber -get_equal_strategy_number(Oid opclass) -{ - Oid am = get_opclass_method(opclass); - - return get_equal_strategy_number_for_am(am); -} - /* * Setup a ScanKey for a search in the relation 'rel' for a tuple 'key' that * is setup to match 'rel' (*NOT* idxrel!). diff --git a/src/backend/replication/logical/relation.c b/src/backend/replication/logical/relation.c index 1b426f43fd7..7cda6a792a2 100644 --- a/src/backend/replication/logical/relation.c +++ b/src/backend/replication/logical/relation.c @@ -29,6 +29,7 @@ #include "replication/logicalrelation.h" #include "replication/worker_internal.h" #include "utils/inval.h" +#include "utils/syscache.h" static MemoryContext LogicalRepRelMapContext = NULL; @@ -784,7 +785,7 @@ FindUsableIndexForReplicaIdentityFull(Relation localrel, AttrMap *attrmap) * The reasons why only Btree and Hash indexes can be considered as usable are: * * 1) Other index access methods don't have a fixed strategy for equality - * operation. Refer get_equal_strategy_number_for_am(). + * operation. Refer get_equal_strategy_number(). * * 2) For indexes other than PK and REPLICA IDENTITY, we need to match the * local and remote tuples. The equality routine tuples_equal() cannot accept @@ -802,10 +803,9 @@ bool IsIndexUsableForReplicaIdentityFull(Relation idxrel, AttrMap *attrmap) { AttrNumber keycol; + oidvector *indclass; - /* Ensure that the index access method has a valid equal strategy */ - if (get_equal_strategy_number_for_am(idxrel->rd_rel->relam) == InvalidStrategy) - return false; + indclass = (oidvector *) DatumGetPointer(SysCacheGetAttrNotNull(INDEXRELID, idxrel->rd_indextuple, Anum_pg_index_indclass)); /* The index must not be a partial index */ if (!heap_attisnull(idxrel->rd_indextuple, Anum_pg_index_indpred, NULL)) @@ -813,6 +813,13 @@ IsIndexUsableForReplicaIdentityFull(Relation idxrel, AttrMap *attrmap) Assert(idxrel->rd_index->indnatts >= 1); + /* Ensure that the index has a valid equal strategy for each column */ + for (int i = 0; i < idxrel->rd_index->indnatts; i++) + { + if (get_equal_strategy_number(indclass->values[i]) == InvalidStrategy) + return false; + } + /* The leftmost index field must not be an expression */ keycol = idxrel->rd_index->indkey.values[0]; if (!AttributeNumberIsValid(keycol)) diff --git a/src/include/executor/executor.h b/src/include/executor/executor.h index 69c3ebff00a..e949cce7d98 100644 --- a/src/include/executor/executor.h +++ b/src/include/executor/executor.h @@ -658,7 +658,7 @@ extern void check_exclusion_constraint(Relation heap, Relation index, /* * prototypes from functions in execReplication.c */ -extern StrategyNumber get_equal_strategy_number_for_am(Oid am); +extern StrategyNumber get_equal_strategy_number(Oid opclass); extern bool RelationFindReplTupleByIndex(Relation rel, Oid idxoid, LockTupleMode lockmode, TupleTableSlot *searchslot, -- 2.47.0