17
17
18
18
#include "postgres.h"
19
19
20
+ #ifdef USE_ASSERT_CHECKING
21
+ #include "access/amapi.h"
22
+ #endif
20
23
#include "access/genam.h"
21
24
#include "access/table.h"
22
25
#include "catalog/namespace.h"
@@ -779,7 +782,7 @@ RemoteRelContainsLeftMostColumnOnIdx(IndexInfo *indexInfo, AttrMap *attrmap)
779
782
780
783
/*
781
784
* 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
785
+ * the relation. The index must be btree or hash , non-partial, and the leftmost
783
786
* field must be a column (not an expression) that references the remote
784
787
* relation column. These limitations help to keep the index scan similar
785
788
* to PK/RI index scans.
@@ -791,11 +794,11 @@ RemoteRelContainsLeftMostColumnOnIdx(IndexInfo *indexInfo, AttrMap *attrmap)
791
794
* compare the tuples for non-PK/RI index scans. See
792
795
* RelationFindReplTupleByIndex().
793
796
*
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.
797
+ * XXX: See IsIndexUsableForReplicaIdentityFull() to know the challenges in
798
+ * supporting indexes other than btree and hash. For partial indexes, the
799
+ * required changes are likely to be larger. If none of the tuples satisfy
800
+ * the expression for the index scan, we fall-back to sequential execution,
801
+ * which might not be a good idea in some cases.
799
802
*
800
803
* We expect to call this function when REPLICA IDENTITY FULL is defined for
801
804
* the remote relation.
@@ -834,15 +837,43 @@ FindUsableIndexForReplicaIdentityFull(Relation localrel, AttrMap *attrmap)
834
837
/*
835
838
* Returns true if the index is usable for replica identity full. For details,
836
839
* see FindUsableIndexForReplicaIdentityFull.
840
+ *
841
+ * Currently, only Btree and Hash indexes can be returned as usable. This
842
+ * is due to following reasons:
843
+ *
844
+ * 1) Other index access methods don't have a fixed strategy for equality
845
+ * operation. Refer get_equal_strategy_number_for_am().
846
+ *
847
+ * 2) For indexes other than PK and REPLICA IDENTITY, we need to match the
848
+ * local and remote tuples. The equality routine tuples_equal() cannot accept
849
+ * a datatype (e.g. point or box) that does not have a default operator class
850
+ * for Btree or Hash.
851
+ *
852
+ * XXX: Note that BRIN and GIN indexes do not implement "amgettuple" which
853
+ * will be used later to fetch the tuples. See RelationFindReplTupleByIndex().
837
854
*/
838
855
bool
839
856
IsIndexUsableForReplicaIdentityFull (IndexInfo * indexInfo )
840
857
{
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 );
858
+ /* Ensure that the index access method has a valid equal strategy */
859
+ if (get_equal_strategy_number_for_am (indexInfo -> ii_Am ) == InvalidStrategy )
860
+ return false;
861
+ if (indexInfo -> ii_Predicate != NIL )
862
+ return false;
863
+ if (IsIndexOnlyOnExpression (indexInfo ))
864
+ return false;
865
+
866
+ #ifdef USE_ASSERT_CHECKING
867
+ {
868
+ IndexAmRoutine * amroutine ;
844
869
845
- return is_btree && !is_partial && !is_only_on_expression ;
870
+ /* The given index access method must implement amgettuple. */
871
+ amroutine = GetIndexAmRoutineByAmId (indexInfo -> ii_Am , false);
872
+ Assert (amroutine -> amgettuple != NULL );
873
+ }
874
+ #endif
875
+
876
+ return true;
846
877
}
847
878
848
879
/*
0 commit comments