From 038061bce7edfa228df57e1a9e1ce6abeed40015 Mon Sep 17 00:00:00 2001 From: Alexander Korotkov Date: Wed, 9 Oct 2024 18:44:25 +0300 Subject: [PATCH v42 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)