diff --git a/src/backend/executor/execReplication.c b/src/backend/executor/execReplication.c index af09342881..25d2868744 100644 --- a/src/backend/executor/execReplication.c +++ b/src/backend/executor/execReplication.c @@ -175,16 +175,7 @@ retry: if (!isIdxSafeToSkipDuplicates) { if (eq == NULL) - { -#ifdef USE_ASSERT_CHECKING - /* apply assertions only once for the input idxoid */ - IndexInfo *indexInfo = BuildIndexInfo(idxrel); - - Assert(IsIndexUsableForReplicaIdentityFull(indexInfo)); -#endif - eq = palloc0(sizeof(*eq) * outslot->tts_tupleDescriptor->natts); - } if (!tuples_equal(outslot, searchslot, eq)) continue; diff --git a/src/backend/replication/logical/relation.c b/src/backend/replication/logical/relation.c index fe940335a3..39aedf24c8 100644 --- a/src/backend/replication/logical/relation.c +++ b/src/backend/replication/logical/relation.c @@ -731,52 +731,6 @@ logicalrep_partition_open(LogicalRepRelMapEntry *root, return entry; } -/* - * Returns true if the given index consists only of expressions such as: - * CREATE INDEX idx ON table(foo(col)); - * - * Returns false even if there is one column reference: - * CREATE INDEX idx ON table(foo(col), col_2); - */ -static bool -IsIndexOnlyOnExpression(IndexInfo *indexInfo) -{ - for (int i = 0; i < indexInfo->ii_NumIndexKeyAttrs; i++) - { - AttrNumber attnum = indexInfo->ii_IndexAttrNumbers[i]; - - if (AttributeNumberIsValid(attnum)) - return false; - } - - return true; -} - -/* - * Returns true if the attrmap contains the leftmost column of the index. - * Otherwise returns false. - * - * attrmap is a map of local attributes to remote ones. We can consult this - * map to check whether the local index attribute has a corresponding remote - * attribute. - */ -static bool -RemoteRelContainsLeftMostColumnOnIdx(IndexInfo *indexInfo, AttrMap *attrmap) -{ - AttrNumber keycol; - - Assert(indexInfo->ii_NumIndexAttrs >= 1); - - keycol = indexInfo->ii_IndexAttrNumbers[0]; - if (!AttributeNumberIsValid(keycol)) - return false; - - if (attrmap->maplen <= AttrNumberGetAttrOffset(keycol)) - return false; - - return attrmap->attnums[AttrNumberGetAttrOffset(keycol)] >= 0; -} - /* * Returns the oid of an index that can be used by the apply worker to scan * the relation. The index must be btree, non-partial, and the leftmost @@ -791,6 +745,10 @@ RemoteRelContainsLeftMostColumnOnIdx(IndexInfo *indexInfo, AttrMap *attrmap) * compare the tuples for non-PK/RI index scans. See * RelationFindReplTupleByIndex(). * + * attrmap is a map of local attributes to remote ones. We can consult this + * map to check whether the local index attribute has a corresponding remote + * attribute. + * * XXX: There are no fundamental problems for supporting non-btree indexes. * We mostly need to relax the limitations in RelationFindReplTupleByIndex(). * For partial indexes, the required changes are likely to be larger. If @@ -811,40 +769,44 @@ FindUsableIndexForReplicaIdentityFull(Relation localrel, AttrMap *attrmap) foreach(lc, idxlist) { Oid idxoid = lfirst_oid(lc); - bool isUsableIdx; - bool containsLeftMostCol; Relation idxRel; IndexInfo *idxInfo; + AttrNumber keycol; idxRel = index_open(idxoid, AccessShareLock); idxInfo = BuildIndexInfo(idxRel); - isUsableIdx = IsIndexUsableForReplicaIdentityFull(idxInfo); - containsLeftMostCol = - RemoteRelContainsLeftMostColumnOnIdx(idxInfo, attrmap); index_close(idxRel, AccessShareLock); + /* Must be a btree index */ + if (idxInfo->ii_Am != BTREE_AM_OID) + continue; + + /* Must be non-partial index */ + if (idxInfo->ii_Predicate != NIL) + continue; + + Assert(idxInfo->ii_NumIndexAttrs >= 1); + + /* The left most index field must not be an expression */ + keycol = idxInfo->ii_IndexAttrNumbers[0]; + if (!AttributeNumberIsValid(keycol)) + continue; + + /* + * The lest most index field must have a reference to a remote + * relation column. + */ + if (attrmap->maplen <= AttrNumberGetAttrOffset(keycol) || + (attrmap->attnums[AttrNumberGetAttrOffset(keycol)] < 0)) + continue; + /* Return the first eligible index found */ - if (isUsableIdx && containsLeftMostCol) - return idxoid; + return idxoid; } return InvalidOid; } -/* - * Returns true if the index is usable for replica identity full. For details, - * see FindUsableIndexForReplicaIdentityFull. - */ -bool -IsIndexUsableForReplicaIdentityFull(IndexInfo *indexInfo) -{ - bool is_btree = (indexInfo->ii_Am == BTREE_AM_OID); - bool is_partial = (indexInfo->ii_Predicate != NIL); - bool is_only_on_expression = IsIndexOnlyOnExpression(indexInfo); - - return is_btree && !is_partial && !is_only_on_expression; -} - /* * Get replica identity index or if it is not defined a primary key. *