Replace get_equal_strategy_number_for_am() by get_equal_strategy_number()
authorPeter Eisentraut <[email protected]>
Tue, 10 Dec 2024 11:53:27 +0000 (12:53 +0100)
committerPeter Eisentraut <[email protected]>
Tue, 10 Dec 2024 11:53:27 +0000 (12:53 +0100)
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  is only a refactoring, it doesn't add support for other
index AMs such as gist.  This will be done separately.

Reviewed-by: Paul Jungwirth <[email protected]>
Reviewed-by: vignesh C <[email protected]>
Discussion: https://www.postgresql.org/message-id/flat/CA+renyUApHgSZF9-nd-a0+OPGharLQLO=mDHcY4_qQ0+noCUVg@mail.gmail.com

src/backend/executor/execReplication.c
src/backend/replication/logical/relation.c
src/include/executor/executor.h

index c8b79f42c24a81075664d462cdff61f999e04122..4431f6b9ecf6cac54a041732c1a9922144a0f19a 100644 (file)
@@ -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!).
index 71a1b7e01eb00b50f9ffe2b26bfd052a1d88264b..c3799a6185e8159b72366aae1977b229c6476c70 100644 (file)
@@ -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))
index 892cf055cdfa9008d6a6a4fe6affa47e9c4d98af..b8433eabc1ff3846985913868c7489a798e827a3 100644 (file)
@@ -657,7 +657,7 @@ extern void check_exclusion_constraint(Relation heap, Relation index,
 /*
  * s 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,