v41-0003-Allow-match_orclause_to_indexcol-for-joins.patch
application/octet-stream
Filename: v41-0003-Allow-match_orclause_to_indexcol-for-joins.patch
Type: application/octet-stream
Part: 1
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 v41-0003
Subject: Allow match_orclause_to_indexcol() for joins
| File | + | − |
|---|---|---|
| src/backend/optimizer/path/indxpath.c | 10 | 9 |
| src/test/regress/expected/join.out | 5 | 5 |
From d26c4a0408cf6af783216540cb189a64e8fa5579 Mon Sep 17 00:00:00 2001
From: Alexander Korotkov <akorotkov@postgresql.org>
Date: Wed, 9 Oct 2024 18:44:25 +0300
Subject: [PATCH v41 3/3] Allow match_orclause_to_indexcol() for joins
---
src/backend/optimizer/path/indxpath.c | 19 ++++++++++---------
src/test/regress/expected/join.out | 10 +++++-----
2 files changed, 15 insertions(+), 14 deletions(-)
diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c
index 5c8b64a5b1e..ed3f8ff9991 100644
--- a/src/backend/optimizer/path/indxpath.c
+++ b/src/backend/optimizer/path/indxpath.c
@@ -2418,8 +2418,8 @@ match_join_clauses_to_index(PlannerInfo *root,
/* Potentially usable, so see if it matches the index or is an OR */
if (restriction_is_or_clause(rinfo))
*joinorclauses = lappend(*joinorclauses, rinfo);
- else
- match_clause_to_index(root, rinfo, index, clauseset);
+
+ match_clause_to_index(root, rinfo, index, clauseset);
}
}
@@ -3229,6 +3229,7 @@ match_orclause_to_indexcol(PlannerInfo *root,
Oid inputcollid = InvalidOid;
bool firstTime = true;
bool have_param = false;
+ Index index_relid = index->rel->relid;
Assert(IsA(orclause, BoolExpr));
Assert(orclause->boolop == OR_EXPR);
@@ -3295,12 +3296,16 @@ match_orclause_to_indexcol(PlannerInfo *root,
*/
leftop = (Node *) linitial(subClause->args);
rightop = (Node *) lsecond(subClause->args);
- if (match_index_to_operand(leftop, indexcol, index))
+ if (match_index_to_operand(leftop, indexcol, index) &&
+ !bms_is_member(index_relid, rinfo->right_relids) &&
+ !contain_volatile_functions(rightop))
{
indexExpr = leftop;
constExpr = rightop;
}
- else if (match_index_to_operand(rightop, indexcol, index))
+ else if (match_index_to_operand(rightop, indexcol, index) &&
+ !bms_is_member(index_relid, rinfo->left_relids) &&
+ !contain_volatile_functions(leftop))
{
opno = get_commutator(opno);
if (!OidIsValid(opno))
@@ -3327,10 +3332,6 @@ match_orclause_to_indexcol(PlannerInfo *root,
if (IsA(indexExpr, RelabelType))
indexExpr = (Node *) ((RelabelType *) indexExpr)->arg;
- /* We allow constant to be Const or Param */
- if (!IsA(constExpr, Const) && !IsA(constExpr, Param))
- break;
-
/* Forbid transformation for composite types, records. */
if (type_is_rowtype(exprType(constExpr)) ||
type_is_rowtype(exprType(indexExpr)))
@@ -3367,7 +3368,7 @@ match_orclause_to_indexcol(PlannerInfo *root,
break;
}
- if (IsA(constExpr, Param))
+ if (!IsA(constExpr, Const))
have_param = true;
consts = lappend(consts, constExpr);
}
diff --git a/src/test/regress/expected/join.out b/src/test/regress/expected/join.out
index 198b9168045..b4354c12079 100644
--- a/src/test/regress/expected/join.out
+++ b/src/test/regress/expected/join.out
@@ -3729,8 +3729,8 @@ select * from
tenk1 join int4_tbl on f1 = twothousand,
q1, q2
where q1 = thousand or q2 = thousand;
- QUERY PLAN
-------------------------------------------------------------------------
+ QUERY PLAN
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Hash Join
Hash Cond: (tenk1.twothousand = int4_tbl.f1)
-> Nested Loop
@@ -3738,12 +3738,12 @@ where q1 = thousand or q2 = thousand;
-> Seq Scan on q1
-> Seq Scan on q2
-> Bitmap Heap Scan on tenk1
- Recheck Cond: ((q1.q1 = thousand) OR (q2.q2 = thousand))
+ Recheck Cond: (((q1.q1 = thousand) AND ((q1.q1 = thousand) OR (q2.q2 = thousand))) OR ((q2.q2 = thousand) AND ((q1.q1 = thousand) OR (q2.q2 = thousand))))
-> BitmapOr
-> Bitmap Index Scan on tenk1_thous_tenthous
- Index Cond: (thousand = q1.q1)
+ Index Cond: ((thousand = q1.q1) AND (thousand = ANY (ARRAY[q1.q1, q2.q2])))
-> Bitmap Index Scan on tenk1_thous_tenthous
- Index Cond: (thousand = q2.q2)
+ Index Cond: ((thousand = q2.q2) AND (thousand = ANY (ARRAY[q1.q1, q2.q2])))
-> Hash
-> Seq Scan on int4_tbl
(15 rows)
--
2.39.5 (Apple Git-154)