diff options
-rw-r--r-- | src/backend/executor/execReplication.c | 17 | ||||
-rw-r--r-- | src/backend/replication/logical/relation.c | 19 | ||||
-rw-r--r-- | src/include/executor/executor.h | 2 |
3 files changed, 18 insertions, 20 deletions
diff --git a/src/backend/executor/execReplication.c b/src/backend/executor/execReplication.c index c8b79f42c24..4431f6b9ecf 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) @@ -69,18 +70,6 @@ get_equal_strategy_number_for_am(Oid am) } /* - * 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 71a1b7e01eb..c3799a6185e 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; @@ -815,7 +816,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 @@ -833,10 +834,7 @@ bool IsIndexUsableForReplicaIdentityFull(Relation idxrel, AttrMap *attrmap) { AttrNumber keycol; - - /* 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; + oidvector *indclass; /* The index must not be a partial index */ if (!heap_attisnull(idxrel->rd_indextuple, Anum_pg_index_indpred, NULL)) @@ -844,6 +842,17 @@ IsIndexUsableForReplicaIdentityFull(Relation idxrel, AttrMap *attrmap) Assert(idxrel->rd_index->indnatts >= 1); + indclass = (oidvector *) DatumGetPointer(SysCacheGetAttrNotNull(INDEXRELID, + idxrel->rd_indextuple, + Anum_pg_index_indclass)); + + /* Ensure that the index has a valid equal strategy for each key column */ + for (int i = 0; i < idxrel->rd_index->indnkeyatts; 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 892cf055cdf..b8433eabc1f 100644 --- a/src/include/executor/executor.h +++ b/src/include/executor/executor.h @@ -657,7 +657,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, |