From fa5550937c15c2da9b302aaebef24458d93b532b Mon Sep 17 00:00:00 2001 From: Richard Guo Date: Wed, 2 Nov 2022 15:06:46 +0800 Subject: [PATCH v3] constant folding for indexquals in bitmap scan --- contrib/btree_gin/expected/bool.out | 2 +- src/backend/optimizer/plan/createplan.c | 31 +++++++++++++++++++++++-- src/backend/optimizer/util/clauses.c | 13 ++++++----- src/include/optimizer/optimizer.h | 2 ++ 4 files changed, 39 insertions(+), 9 deletions(-) diff --git a/contrib/btree_gin/expected/bool.out b/contrib/btree_gin/expected/bool.out index 207a3f2328..51a70eb530 100644 --- a/contrib/btree_gin/expected/bool.out +++ b/contrib/btree_gin/expected/bool.out @@ -92,7 +92,7 @@ EXPLAIN (COSTS OFF) SELECT * FROM test_bool WHERE i=true ORDER BY i; Sort Sort Key: i -> Bitmap Heap Scan on test_bool - Filter: i + Recheck Cond: i -> Bitmap Index Scan on idx_bool Index Cond: (i = true) (6 rows) diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c index ac86ce9003..10705cb210 100644 --- a/src/backend/optimizer/plan/createplan.c +++ b/src/backend/optimizer/plan/createplan.c @@ -20,6 +20,7 @@ #include "access/sysattr.h" #include "catalog/pg_class.h" +#include "catalog/pg_operator.h" #include "foreign/fdwapi.h" #include "miscadmin.h" #include "nodes/extensible.h" @@ -3480,11 +3481,37 @@ create_bitmap_subplan(PlannerInfo *root, Path *bitmapqual, { IndexClause *iclause = (IndexClause *) lfirst(l); RestrictInfo *rinfo = iclause->rinfo; + ListCell *l2; Assert(!rinfo->pseudoconstant); subquals = lappend(subquals, rinfo->clause); - subindexquals = list_concat(subindexquals, - get_actual_clauses(iclause->indexquals)); + + /* + * The indexquals may have been transformed into form "indexkey = + * true/false" in match_boolean_index_clause(). We need to + * re-simplify them in order to compare them to scan_clauses in + * create_bitmap_scan_plan(). + */ + foreach(l2, iclause->indexquals) + { + RestrictInfo *restrictinfo = lfirst_node(RestrictInfo, l2); + OpExpr *clause = (OpExpr *) restrictinfo->clause; + + Assert(!restrictinfo->pseudoconstant); + + if (is_opclause(clause) && + clause->opno == BooleanEqualOperator) + { + Node *simple; + + simple = simplify_boolean_equality(clause->opno, + clause->args); + if (simple) /* successfully simplified it */ + clause = (OpExpr *) simple; + } + + subindexquals = lappend(subindexquals, (Node *) clause); + } if (rinfo->parent_ec) subindexECs = lappend(subindexECs, rinfo->parent_ec); } diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c index 7fb32a0710..50cd0cbe79 100644 --- a/src/backend/optimizer/util/clauses.c +++ b/src/backend/optimizer/util/clauses.c @@ -119,7 +119,6 @@ static List *simplify_or_arguments(List *args, static List *simplify_and_arguments(List *args, eval_const_expressions_context *context, bool *haveNull, bool *forceFalse); -static Node *simplify_boolean_equality(Oid opno, List *args); static Expr *simplify_function(Oid funcid, Oid result_type, int32 result_typmod, Oid result_collid, Oid input_collid, List **args_p, @@ -3774,8 +3773,8 @@ simplify_and_arguments(List *args, } /* - * Subroutine for eval_const_expressions: try to simplify boolean equality - * or inequality condition + * simplify_boolean_equality: try to simplify boolean equality or inequality + * condition * * Inputs are the operator OID and the simplified arguments to the operator. * Returns a simplified expression if successful, or NULL if cannot @@ -3787,10 +3786,12 @@ simplify_and_arguments(List *args, * ensures that we will recognize these forms as being equivalent in, for * example, partial index matching. * - * We come here only if simplify_function has failed; therefore we cannot - * see two constant inputs, nor a constant-NULL input. + * We come here only if simplify_function has failed in + * eval_const_expressions_mutator, or we need to re-simplify the boolean + * equality expression in create_bitmap_subplan; therefore we cannot see two + * constant inputs, nor a constant-NULL input. */ -static Node * +Node * simplify_boolean_equality(Oid opno, List *args) { Node *leftop; diff --git a/src/include/optimizer/optimizer.h b/src/include/optimizer/optimizer.h index 409005bae9..e5d110744b 100644 --- a/src/include/optimizer/optimizer.h +++ b/src/include/optimizer/optimizer.h @@ -150,6 +150,8 @@ extern Node *estimate_expression_value(PlannerInfo *root, Node *node); extern Expr *evaluate_expr(Expr *expr, Oid result_type, int32 result_typmod, Oid result_collation); +extern Node *simplify_boolean_equality(Oid opno, List *args); + extern List *expand_function_arguments(List *args, bool include_out_arguments, Oid result_type, struct HeapTupleData *func_tuple); -- 2.31.0