#define IsBooleanOpfamily(opfamily) \
((opfamily) == BOOL_BTREE_FAM_OID || (opfamily) == BOOL_HASH_FAM_OID)
+#define IndexCollMatchesExprColl(idxcollation, exprcollation) \
+ ((idxcollation) == InvalidOid || (idxcollation) == (exprcollation))
+
/* Whether to use ScalarArrayOpExpr to build index qualifications */
typedef enum
{
* We do not actually do the commuting here, but we check whether a
* suitable commutator operator is available.
*
+ * If the index has a collation, the clause must have the same collation.
+ * For collation-less indexes, we assume it doesn't matter; this is
+ * necessary for cases like "hstore ? text", wherein hstore's operators
+ * don't care about collation but the clause will get marked with a
+ * collation anyway because of the text argument. (This logic is
+ * embodied in the macro IndexCollMatchesExprColl.)
+ *
* It is also possible to match RowCompareExpr clauses to indexes (but
* currently, only btree indexes handle this). In this routine we will
* report a match if the first column of the row comparison matches the
bms_is_subset(right_relids, outer_relids) &&
!contain_volatile_functions(rightop))
{
- if (idxcollation == expr_coll &&
+ if (IndexCollMatchesExprColl(idxcollation, expr_coll) &&
is_indexable_operator(expr_op, opfamily, true))
return true;
bms_is_subset(left_relids, outer_relids) &&
!contain_volatile_functions(leftop))
{
- if (idxcollation == expr_coll &&
+ if (IndexCollMatchesExprColl(idxcollation, expr_coll) &&
is_indexable_operator(expr_op, opfamily, false))
return true;
expr_op = linitial_oid(clause->opnos);
expr_coll = linitial_oid(clause->inputcollids);
- /* Collations must match */
- if (expr_coll != idxcollation)
+ /* Collations must match, if relevant */
+ if (!IndexCollMatchesExprColl(idxcollation, expr_coll))
return false;
/*
/*
* We can forget the whole thing right away if wrong collation.
*/
- if (expr_coll != idxcollation)
+ if (!IndexCollMatchesExprColl(idxcollation, expr_coll))
return NULL;
/*
*/
if ((index->relam != BTREE_AM_OID ||
list_member_oid(ec->ec_opfamilies, curFamily)) &&
- ec->ec_collation == curCollation &&
+ IndexCollMatchesExprColl(curCollation, ec->ec_collation) &&
match_index_to_operand((Node *) em->em_expr, indexcol, index))
return true;
}
break;
/* Does collation match? */
- if (lfirst_oid(collids_cell) != index->indexcollations[i])
+ if (!IndexCollMatchesExprColl(index->indexcollations[i],
+ lfirst_oid(collids_cell)))
break;
/* Add opfamily and datatypes to lists */