v22-0008-WIP-Support-row-compare-index-scans-with-non-btr.patch
text/plain
Filename: v22-0008-WIP-Support-row-compare-index-scans-with-non-btr.patch
Type: text/plain
Part: 7
Message:
Re: Index AM API cleanup
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: format-patch
Series: patch v22-0008
Subject: WIP: Support row compare index scans with non-btree indexes
| File | + | − |
|---|---|---|
| src/backend/executor/nodeIndexscan.c | 7 | 2 |
| src/backend/optimizer/path/indxpath.c | 20 | 21 |
| src/backend/parser/parse_expr.c | 1 | 1 |
| src/test/regress/expected/rowtypes.out | 1 | 1 |
From dc31e865fed00cc79daa964762b5dfa8d9ef89bb Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter@eisentraut.org>
Date: Wed, 19 Mar 2025 19:51:54 +0100
Subject: [PATCH v22 08/10] WIP: Support row compare index scans with non-btree
indexes
---
src/backend/executor/nodeIndexscan.c | 9 ++++--
src/backend/optimizer/path/indxpath.c | 41 +++++++++++++-------------
src/backend/parser/parse_expr.c | 2 +-
src/test/regress/expected/rowtypes.out | 2 +-
4 files changed, 29 insertions(+), 25 deletions(-)
diff --git a/src/backend/executor/nodeIndexscan.c b/src/backend/executor/nodeIndexscan.c
index c04fe461083..39f55052759 100644
--- a/src/backend/executor/nodeIndexscan.c
+++ b/src/backend/executor/nodeIndexscan.c
@@ -1334,6 +1334,7 @@ ExecIndexBuildScanKeys(PlanState *planstate, Relation index,
int flags = SK_ROW_MEMBER;
Datum scanvalue;
Oid inputcollation;
+ CompareType op_cmptype;
leftop = (Expr *) lfirst(largs_cell);
rightop = (Expr *) lfirst(rargs_cell);
@@ -1365,10 +1366,11 @@ ExecIndexBuildScanKeys(PlanState *planstate, Relation index,
get_op_opfamily_properties(opno, opfamily, isorderby,
&op_strategy,
+ &op_cmptype,
&op_lefttype,
&op_righttype);
- if (op_strategy != rc->cmptype)
+ if (op_cmptype != rc->cmptype)
elog(ERROR, "RowCompare index qualification contains wrong operator");
opfuncid = get_opfamily_proc(opfamily,
@@ -1445,7 +1447,10 @@ ExecIndexBuildScanKeys(PlanState *planstate, Relation index,
MemSet(this_scan_key, 0, sizeof(ScanKeyData));
this_scan_key->sk_flags = SK_ROW_HEADER;
this_scan_key->sk_attno = first_sub_key->sk_attno;
- this_scan_key->sk_strategy = rc->cmptype;
+ this_scan_key->sk_strategy = IndexAmTranslateCompareType(rc->cmptype,
+ index->rd_rel->relam,
+ 0, // FIXME
+ false);
/* sk_subtype, sk_collation, sk_func not used in a header */
this_scan_key->sk_argument = PointerGetDatum(first_sub_key);
}
diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c
index e81cd8e1f45..14447e56e2b 100644
--- a/src/backend/optimizer/path/indxpath.c
+++ b/src/backend/optimizer/path/indxpath.c
@@ -3158,8 +3158,9 @@ match_rowcompare_to_indexcol(PlannerInfo *root,
bool var_on_left;
Oid expr_op;
Oid expr_coll;
+ StrategyNumber opstrategy;
- /* Forget it if we're not dealing with a btree index */
+ /* Forget it if we're not dealing with a btree index FIXME */
if (index->relam != BTREE_AM_OID)
return NULL;
@@ -3210,18 +3211,21 @@ match_rowcompare_to_indexcol(PlannerInfo *root,
return NULL;
/* We're good if the operator is the right type of opfamily member */
- switch (get_op_opfamily_strategy(expr_op, opfamily))
+ opstrategy = get_op_opfamily_strategy(expr_op, opfamily);
+ switch (IndexAmTranslateStrategy(opstrategy, index->relam, opfamily, true))
{
- case BTLessStrategyNumber:
- case BTLessEqualStrategyNumber:
- case BTGreaterEqualStrategyNumber:
- case BTGreaterStrategyNumber:
+ case COMPARE_LT:
+ case COMPARE_LE:
+ case COMPARE_GE:
+ case COMPARE_GT:
return expand_indexqual_rowcompare(root,
rinfo,
indexcol,
index,
expr_op,
var_on_left);
+ default:
+ break;
}
return NULL;
@@ -3650,8 +3654,7 @@ expand_indexqual_rowcompare(PlannerInfo *root,
/* very easy, just use the commuted operators */
new_ops = expr_ops;
}
- else if (op_strategy == BTLessEqualStrategyNumber ||
- op_strategy == BTGreaterEqualStrategyNumber)
+ else if (op_cmptype == COMPARE_LE || op_cmptype == COMPARE_GE)
{
/* easy, just use the same (possibly commuted) operators */
new_ops = list_truncate(expr_ops, matching_cols);
@@ -3662,12 +3665,12 @@ expand_indexqual_rowcompare(PlannerInfo *root,
ListCell *lefttypes_cell;
ListCell *righttypes_cell;
- if (op_strategy == BTLessStrategyNumber)
- op_strategy = BTLessEqualStrategyNumber;
- else if (op_strategy == BTGreaterStrategyNumber)
- op_strategy = BTGreaterEqualStrategyNumber;
+ if (op_cmptype == COMPARE_LT)
+ op_cmptype = COMPARE_LE;
+ else if (op_cmptype == COMPARE_GT)
+ op_cmptype = COMPARE_GE;
else
- elog(ERROR, "unexpected strategy number %d", op_strategy);
+ elog(ERROR, "unexpected compare type %d", op_cmptype);
new_ops = NIL;
forthree(opfamilies_cell, opfamilies,
lefttypes_cell, lefttypes,
@@ -3677,11 +3680,11 @@ expand_indexqual_rowcompare(PlannerInfo *root,
Oid lefttype = lfirst_oid(lefttypes_cell);
Oid righttype = lfirst_oid(righttypes_cell);
- expr_op = get_opfamily_member(opfam, lefttype, righttype,
- op_strategy);
+ expr_op = get_opfamily_member_for_cmptype(opfam, lefttype, righttype,
+ op_cmptype);
if (!OidIsValid(expr_op)) /* should not happen */
elog(ERROR, "missing operator %d(%u,%u) in opfamily %u",
- op_strategy, lefttype, righttype, opfam);
+ op_cmptype, lefttype, righttype, opfam);
new_ops = lappend_oid(new_ops, expr_op);
}
}
@@ -3691,11 +3694,7 @@ expand_indexqual_rowcompare(PlannerInfo *root,
{
RowCompareExpr *rc = makeNode(RowCompareExpr);
- /*
- * XXX This assumes that CompareType values match btree strategy
- * numbers; see cmptype.h.
- */
- rc->cmptype = (CompareType) op_strategy;
+ rc->cmptype = op_cmptype;
rc->opnos = new_ops;
rc->opfamilies = list_copy_head(clause->opfamilies,
matching_cols);
diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c
index 806ccb97537..b83dfc759d8 100644
--- a/src/backend/parser/parse_expr.c
+++ b/src/backend/parser/parse_expr.c
@@ -2943,7 +2943,7 @@ make_row_comparison_op(ParseState *pstate, List *opname,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("could not determine interpretation of row comparison operator %s",
strVal(llast(opname))),
- errhint("Row comparison operators must be associated with btree operator families."),
+ errhint("Row comparison operators must be associated with btree-compatible operator families."),
parser_errposition(pstate, location)));
}
cmptype = (CompareType) i;
diff --git a/src/test/regress/expected/rowtypes.out b/src/test/regress/expected/rowtypes.out
index 9168979a620..025afa2c628 100644
--- a/src/test/regress/expected/rowtypes.out
+++ b/src/test/regress/expected/rowtypes.out
@@ -266,7 +266,7 @@ select ROW('ABC','DEF') ~~ ROW('DEF','ABC') as fail;
ERROR: could not determine interpretation of row comparison operator ~~
LINE 1: select ROW('ABC','DEF') ~~ ROW('DEF','ABC') as fail;
^
-HINT: Row comparison operators must be associated with btree operator families.
+HINT: Row comparison operators must be associated with btree-compatible operator families.
-- Comparisons of ROW() expressions can cope with some type mismatches
select ROW(1,2) = ROW(1,2::int8);
?column?
--
2.49.0