retval = tinfo->f_le(query, key->upper, flinfo);
break;
case BtreeGistNotEqualStrategyNumber:
- retval = (!(tinfo->f_eq(query, key->lower, flinfo) &&
- tinfo->f_eq(query, key->upper, flinfo)));
+ if (is_leaf)
+ retval = !(tinfo->f_eq(query, key->lower, flinfo));
+ else
+ {
+ /*
+ * If the upper/lower bounds are equal, then all entries below
+ * this node must have exactly that value. So we can avoid
+ * descending if the query equals both bounds. In all other
+ * cases, we must descend.
+ */
+ retval = !(tinfo->f_eq(query, key->lower, flinfo) &&
+ tinfo->f_eq(query, key->upper, flinfo));
+ }
break;
default:
retval = false;
{
bool retval = false;
+ /*
+ * Remember that f_cmp is for internal pages, f_eq etc for leaf pages, and
+ * on internal pages we need to check gbt_var_node_pf_match too.
+ *
+ * The leaf-page tests use swapped operands (e.g., f_gt(query, lower)
+ * means "lower < query"), which is why they look reversed.
+ */
switch (strategy)
{
case BTLessEqualStrategyNumber:
|| gbt_var_node_pf_match(key, query, tinfo);
break;
case BtreeGistNotEqualStrategyNumber:
- retval = !(tinfo->f_eq(query, key->lower, collation, flinfo) &&
- tinfo->f_eq(query, key->upper, collation, flinfo));
+ if (is_leaf)
+ retval = !(tinfo->f_eq(query, key->lower, collation, flinfo));
+ else
+ {
+ /*
+ * If the upper/lower bounds are equal and not truncated, then
+ * all entries below this node must have exactly that value.
+ * So we can avoid descending if the query equals both bounds.
+ * In all other cases, we must descend.
+ */
+ retval = tinfo->trnc ||
+ !(tinfo->f_cmp(query, key->lower, collation, flinfo) == 0 &&
+ tinfo->f_cmp(query, key->upper, collation, flinfo) == 0);
+ }
break;
default:
retval = false;