From 649698b9f03a79a3d62d60e48b674c77dbbde269 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Wed, 4 Dec 2024 12:06:24 +0100 Subject: [PATCH v45.2 2/5] Replace get_equal_strategy_number_for_am() by get_equal_strategy_number() get_equal_strategy_number_for_am() gets the equal strategy number for an AM. This currently only supports btree and hash. In the more general case, this also depends on the operator class (see for example GistTranslateStratnum()). To support that, replace this function with get_equal_strategy_number() that takes an opclass and derives it from there. (This function already existed before as a static function, so the signature is kept for simplicity.) This patch is only a refactoring, it doesn't add support for other index AMs such as gist. This will be done separately. Discussion: https://www.postgresql.org/message-id/flat/CA+renyUApHgSZF9-nd-a0+OPGharLQLO=mDHcY4_qQ0+noCUVg@mail.gmail.com --- src/backend/executor/execReplication.c | 17 +++-------------- src/backend/replication/logical/relation.c | 17 ++++++++++++----- src/include/executor/executor.h | 2 +- 3 files changed, 16 insertions(+), 20 deletions(-) diff --git a/src/backend/executor/execReplication.c b/src/backend/executor/execReplication.c index 2ca8c5c50be..2b42c0ae524 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 71a1b7e01eb..f2fac57412e 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,15 @@ 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 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.1