@@ -731,71 +731,9 @@ logicalrep_partition_open(LogicalRepRelMapEntry *root,
731
731
return entry ;
732
732
}
733
733
734
- /*
735
- * Returns true if the given index consists only of expressions such as:
736
- * CREATE INDEX idx ON table(foo(col));
737
- *
738
- * Returns false even if there is one column reference:
739
- * CREATE INDEX idx ON table(foo(col), col_2);
740
- */
741
- static bool
742
- IsIndexOnlyOnExpression (IndexInfo * indexInfo )
743
- {
744
- for (int i = 0 ; i < indexInfo -> ii_NumIndexKeyAttrs ; i ++ )
745
- {
746
- AttrNumber attnum = indexInfo -> ii_IndexAttrNumbers [i ];
747
-
748
- if (AttributeNumberIsValid (attnum ))
749
- return false;
750
- }
751
-
752
- return true;
753
- }
754
-
755
- /*
756
- * Returns true if the attrmap contains the leftmost column of the index.
757
- * Otherwise returns false.
758
- *
759
- * attrmap is a map of local attributes to remote ones. We can consult this
760
- * map to check whether the local index attribute has a corresponding remote
761
- * attribute.
762
- */
763
- static bool
764
- RemoteRelContainsLeftMostColumnOnIdx (IndexInfo * indexInfo , AttrMap * attrmap )
765
- {
766
- AttrNumber keycol ;
767
-
768
- Assert (indexInfo -> ii_NumIndexAttrs >= 1 );
769
-
770
- keycol = indexInfo -> ii_IndexAttrNumbers [0 ];
771
- if (!AttributeNumberIsValid (keycol ))
772
- return false;
773
-
774
- if (attrmap -> maplen <= AttrNumberGetAttrOffset (keycol ))
775
- return false;
776
-
777
- return attrmap -> attnums [AttrNumberGetAttrOffset (keycol )] >= 0 ;
778
- }
779
-
780
734
/*
781
735
* Returns the oid of an index that can be used by the apply worker to scan
782
- * the relation. The index must be btree, non-partial, and the leftmost
783
- * field must be a column (not an expression) that references the remote
784
- * relation column. These limitations help to keep the index scan similar
785
- * to PK/RI index scans.
786
- *
787
- * Note that the limitations of index scans for replica identity full only
788
- * adheres to a subset of the limitations of PK/RI. For example, we support
789
- * columns that are marked as [NULL] or we are not interested in the [NOT
790
- * DEFERRABLE] aspect of constraints here. It works for us because we always
791
- * compare the tuples for non-PK/RI index scans. See
792
- * RelationFindReplTupleByIndex().
793
- *
794
- * XXX: There are no fundamental problems for supporting non-btree indexes.
795
- * We mostly need to relax the limitations in RelationFindReplTupleByIndex().
796
- * For partial indexes, the required changes are likely to be larger. If
797
- * none of the tuples satisfy the expression for the index scan, we fall-back
798
- * to sequential execution, which might not be a good idea in some cases.
736
+ * the relation.
799
737
*
800
738
* We expect to call this function when REPLICA IDENTITY FULL is defined for
801
739
* the remote relation.
@@ -812,37 +750,77 @@ FindUsableIndexForReplicaIdentityFull(Relation localrel, AttrMap *attrmap)
812
750
{
813
751
Oid idxoid = lfirst_oid (lc );
814
752
bool isUsableIdx ;
815
- bool containsLeftMostCol ;
816
753
Relation idxRel ;
817
754
IndexInfo * idxInfo ;
818
755
819
756
idxRel = index_open (idxoid , AccessShareLock );
820
757
idxInfo = BuildIndexInfo (idxRel );
821
- isUsableIdx = IsIndexUsableForReplicaIdentityFull (idxInfo );
822
- containsLeftMostCol =
823
- RemoteRelContainsLeftMostColumnOnIdx (idxInfo , attrmap );
758
+ isUsableIdx = IsIndexUsableForReplicaIdentityFull (idxInfo , attrmap );
824
759
index_close (idxRel , AccessShareLock );
825
760
826
761
/* Return the first eligible index found */
827
- if (isUsableIdx && containsLeftMostCol )
762
+ if (isUsableIdx )
828
763
return idxoid ;
829
764
}
830
765
831
766
return InvalidOid ;
832
767
}
833
768
834
769
/*
835
- * Returns true if the index is usable for replica identity full. For details,
836
- * see FindUsableIndexForReplicaIdentityFull.
770
+ * Returns true if the index is usable for replica identity full.
771
+ *
772
+ * The index must be btree, non-partial, and the leftmost field must be a
773
+ * column (not an expression) that references the remote relation column.
774
+ * These limitations help to keep the index scan similar to PK/RI index
775
+ * scans.
776
+ *
777
+ * attrmap is a map of local attributes to remote ones. We can consult this
778
+ * map to check whether the local index attribute has a corresponding remote
779
+ * attribute.
780
+ *
781
+ * Note that the limitations of index scans for replica identity full only
782
+ * adheres to a subset of the limitations of PK/RI. For example, we support
783
+ * columns that are marked as [NULL] or we are not interested in the [NOT
784
+ * DEFERRABLE] aspect of constraints here. It works for us because we always
785
+ * compare the tuples for non-PK/RI index scans. See
786
+ * RelationFindReplTupleByIndex().
787
+ *
788
+ * XXX: There are no fundamental problems for supporting non-btree indexes.
789
+ * We mostly need to relax the limitations in RelationFindReplTupleByIndex().
790
+ * For partial indexes, the required changes are likely to be larger. If
791
+ * none of the tuples satisfy the expression for the index scan, we fall-back
792
+ * to sequential execution, which might not be a good idea in some cases.
837
793
*/
838
794
bool
839
- IsIndexUsableForReplicaIdentityFull (IndexInfo * indexInfo )
795
+ IsIndexUsableForReplicaIdentityFull (IndexInfo * indexInfo , AttrMap * attrmap )
840
796
{
841
- bool is_btree = (indexInfo -> ii_Am == BTREE_AM_OID );
842
- bool is_partial = (indexInfo -> ii_Predicate != NIL );
843
- bool is_only_on_expression = IsIndexOnlyOnExpression (indexInfo );
797
+ AttrNumber keycol ;
798
+
799
+ /* The index must be a Btree index */
800
+ if (indexInfo -> ii_Am != BTREE_AM_OID )
801
+ return false;
802
+
803
+ /* The index must not be a partial index */
804
+ if (indexInfo -> ii_Predicate != NIL )
805
+ return false;
806
+
807
+ Assert (indexInfo -> ii_NumIndexAttrs >= 1 );
844
808
845
- return is_btree && !is_partial && !is_only_on_expression ;
809
+ /* The leftmost index field must not be an expression */
810
+ keycol = indexInfo -> ii_IndexAttrNumbers [0 ];
811
+ if (!AttributeNumberIsValid (keycol ))
812
+ return false;
813
+
814
+ /*
815
+ * And the leftmost index field must reference the remote relation column.
816
+ * This is because if it doesn't, the sequential scan is favorable over
817
+ * index scan in most cases.
818
+ */
819
+ if (attrmap -> maplen <= AttrNumberGetAttrOffset (keycol ) ||
820
+ attrmap -> attnums [AttrNumberGetAttrOffset (keycol )] < 0 )
821
+ return false;
822
+
823
+ return true;
846
824
}
847
825
848
826
/*
0 commit comments