#include "postgres.h"
-#ifdef USE_ASSERT_CHECKING
#include "access/amapi.h"
-#endif
#include "access/genam.h"
#include "access/table.h"
#include "catalog/namespace.h"
/*
* Returns true if the index is usable for replica identity full.
*
- * The index must be btree or hash, non-partial, and the leftmost field must be
- * a column (not an expression) that references the remote relation column. These
- * limitations help to keep the index scan similar to PK/RI index scans.
+ * The index must have an equal strategy for each key column, be non-partial,
+ * and the leftmost field must be a column (not an expression) that references
+ * the remote relation column. These limitations help to keep the index scan
+ * similar to PK/RI index scans.
*
* 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
* compare the tuples for non-PK/RI index scans. See
* RelationFindReplTupleByIndex().
*
- * 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().
- *
- * 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
- * a datatype (e.g. point or box) that does not have a default operator class
- * for Btree or Hash.
- *
- * XXX: Note that BRIN and GIN indexes do not implement "amgettuple" which
- * will be used later to fetch the tuples. See RelationFindReplTupleByIndex().
- *
* XXX: To support partial indexes, the required changes are likely to be larger.
* If none of the tuples satisfy the expression for the index scan, we fall-back
* to sequential execution, which might not be a good idea in some cases.
return false;
}
+ /*
+ * For indexes other than PK and REPLICA IDENTITY, we need to match the
+ * local and remote tuples. The equality routine tuples_equal() cannot
+ * accept a data type where the type cache cannot provide an equality
+ * operator.
+ */
+ for (int i = 0; i < idxrel->rd_att->natts; i++)
+ {
+ TypeCacheEntry *typentry;
+
+ typentry = lookup_type_cache(TupleDescAttr(idxrel->rd_att, i)->atttypid, TYPECACHE_EQ_OPR_FINFO);
+ if (!OidIsValid(typentry->eq_opr_finfo.fn_oid))
+ return false;
+ }
+
/* The leftmost index field must not be an expression */
keycol = idxrel->rd_index->indkey.values[0];
if (!AttributeNumberIsValid(keycol))
attrmap->attnums[AttrNumberGetAttrOffset(keycol)] < 0)
return false;
-#ifdef USE_ASSERT_CHECKING
- {
- IndexAmRoutine *amroutine;
-
- /* The given index access method must implement amgettuple. */
- amroutine = GetIndexAmRoutineByAmId(idxrel->rd_rel->relam, false);
- Assert(amroutine->amgettuple != NULL);
- }
-#endif
+ /*
+ * The given index access method must implement "amgettuple", which will
+ * be used later to fetch the tuples. See RelationFindReplTupleByIndex().
+ */
+ if (GetIndexAmRoutineByAmId(idxrel->rd_rel->relam, false)->amgettuple == NULL)
+ return false;
return true;
}