summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane2008-04-01 00:48:44 +0000
committerTom Lane2008-04-01 00:48:44 +0000
commit5488a9e91acc9bf1db71cb7c7652a5594cf8dba3 (patch)
treedf94a1fad6d9456840c2879fa20ad8cb6820dfeb
parent0973c9a3a815ef191088eaacb6486b1f928db6ce (diff)
Fix an oversight I made in a cleanup patch over a year ago:
eval_const_expressions needs to be passed the PlannerInfo ("root") structure, because in some cases we want it to substitute values for Param nodes. (So "constant" is not so constant as all that ...) This mistake partially disabled optimization of unnamed extended-Query statements in 8.3: in particular the LIKE-to-indexscan optimization would never be applied if the LIKE pattern was passed as a parameter, and constraint exclusion depending on a parameter value didn't work either.
-rw-r--r--src/backend/optimizer/path/allpaths.c4
-rw-r--r--src/backend/optimizer/plan/initsplan.c2
-rw-r--r--src/backend/optimizer/plan/planner.c2
-rw-r--r--src/backend/optimizer/util/clauses.c10
-rw-r--r--src/backend/optimizer/util/plancat.c13
-rw-r--r--src/backend/utils/cache/relcache.c4
-rw-r--r--src/include/optimizer/clauses.h2
-rw-r--r--src/include/optimizer/plancat.h4
8 files changed, 25 insertions, 16 deletions
diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c
index a199a001b6..c4c85a2a76 100644
--- a/src/backend/optimizer/path/allpaths.c
+++ b/src/backend/optimizer/path/allpaths.c
@@ -205,7 +205,7 @@ set_plain_rel_pathlist(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte)
* set_append_rel_pathlist().
*/
if (rel->reloptkind == RELOPT_BASEREL &&
- relation_excluded_by_constraints(rel, rte))
+ relation_excluded_by_constraints(root, rel, rte))
{
set_dummy_rel_pathlist(rel);
return;
@@ -321,7 +321,7 @@ set_append_rel_pathlist(PlannerInfo *root, RelOptInfo *rel,
adjust_appendrel_attrs((Node *) rel->baserestrictinfo,
appinfo);
- if (relation_excluded_by_constraints(childrel, childRTE))
+ if (relation_excluded_by_constraints(root, childrel, childRTE))
{
/*
* This child need not be scanned, so we can omit it from the
diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c
index e60491a7cc..afc76fdc42 100644
--- a/src/backend/optimizer/plan/initsplan.c
+++ b/src/backend/optimizer/plan/initsplan.c
@@ -1219,7 +1219,7 @@ process_implied_equality(PlannerInfo *root,
/* If both constant, try to reduce to a boolean constant. */
if (both_const)
{
- clause = (Expr *) eval_const_expressions((Node *) clause);
+ clause = (Expr *) eval_const_expressions(root, (Node *) clause);
/* If we produced const TRUE, just drop the clause */
if (clause && IsA(clause, Const))
diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c
index 8a569d7cbd..41e06a9ec2 100644
--- a/src/backend/optimizer/plan/planner.c
+++ b/src/backend/optimizer/plan/planner.c
@@ -503,7 +503,7 @@ preprocess_expression(PlannerInfo *root, Node *expr, int kind)
(root->parse->jointree->fromlist != NIL ||
kind == EXPRKIND_QUAL ||
root->query_level > 1))
- expr = eval_const_expressions(expr);
+ expr = eval_const_expressions(root, expr);
/*
* If it's a qual or havingQual, canonicalize it.
diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c
index a5e6226a87..6935ec7ae8 100644
--- a/src/backend/optimizer/util/clauses.c
+++ b/src/backend/optimizer/util/clauses.c
@@ -1687,16 +1687,22 @@ rowtype_field_matches(Oid rowtypeid, int fieldnum,
* We assume that the tree has already been type-checked and contains
* only operators and functions that are reasonable to try to execute.
*
+ * NOTE: "root" can be passed as NULL if the caller never wants to do any
+ * Param substitutions.
+ *
* NOTE: the planner assumes that this will always flatten nested AND and
* OR clauses into N-argument form. See comments in prepqual.c.
*--------------------
*/
Node *
-eval_const_expressions(Node *node)
+eval_const_expressions(PlannerInfo *root, Node *node)
{
eval_const_expressions_context context;
- context.boundParams = NULL; /* don't use any bound params */
+ if (root)
+ context.boundParams = root->glob->boundParams; /* bound Params */
+ else
+ context.boundParams = NULL;
context.active_fns = NIL; /* nothing being recursively simplified */
context.case_val = NULL; /* no CASE being examined */
context.estimate = false; /* safe transformations only */
diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c
index 5e7c648d6e..d10ba4cae5 100644
--- a/src/backend/optimizer/util/plancat.c
+++ b/src/backend/optimizer/util/plancat.c
@@ -47,7 +47,8 @@ bool constraint_exclusion = false;
get_relation_info_hook_type get_relation_info_hook = NULL;
-static List *get_relation_constraints(Oid relationObjectId, RelOptInfo *rel,
+static List *get_relation_constraints(PlannerInfo *root,
+ Oid relationObjectId, RelOptInfo *rel,
bool include_notnull);
@@ -462,7 +463,8 @@ estimate_rel_size(Relation rel, int32 *attr_widths,
* point in caching the data in RelOptInfo.
*/
static List *
-get_relation_constraints(Oid relationObjectId, RelOptInfo *rel,
+get_relation_constraints(PlannerInfo *root,
+ Oid relationObjectId, RelOptInfo *rel,
bool include_notnull)
{
List *result = NIL;
@@ -497,7 +499,7 @@ get_relation_constraints(Oid relationObjectId, RelOptInfo *rel,
* stuff involving subqueries, however, since we don't allow any
* in check constraints.)
*/
- cexpr = eval_const_expressions(cexpr);
+ cexpr = eval_const_expressions(root, cexpr);
cexpr = (Node *) canonicalize_qual((Expr *) cexpr);
@@ -561,7 +563,8 @@ get_relation_constraints(Oid relationObjectId, RelOptInfo *rel,
* it can be called before filling in other fields of the RelOptInfo.
*/
bool
-relation_excluded_by_constraints(RelOptInfo *rel, RangeTblEntry *rte)
+relation_excluded_by_constraints(PlannerInfo *root,
+ RelOptInfo *rel, RangeTblEntry *rte)
{
List *safe_restrictions;
List *constraint_pred;
@@ -600,7 +603,7 @@ relation_excluded_by_constraints(RelOptInfo *rel, RangeTblEntry *rte)
* OK to fetch the constraint expressions. Include "col IS NOT NULL"
* expressions for attnotnull columns, in case we can refute those.
*/
- constraint_pred = get_relation_constraints(rte->relid, rel, true);
+ constraint_pred = get_relation_constraints(root, rte->relid, rel, true);
/*
* We do not currently enforce that CHECK constraints contain only
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 911a8ede7d..767afd4c96 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -3068,7 +3068,7 @@ RelationGetIndexExpressions(Relation relation)
* them to similarly-processed qual clauses, and may fail to detect valid
* matches without this. We don't bother with canonicalize_qual, however.
*/
- result = (List *) eval_const_expressions((Node *) result);
+ result = (List *) eval_const_expressions(NULL, (Node *) result);
/*
* Also mark any coercion format fields as "don't care", so that the
@@ -3138,7 +3138,7 @@ RelationGetIndexPredicate(Relation relation)
* stuff involving subqueries, however, since we don't allow any in index
* predicates.)
*/
- result = (List *) eval_const_expressions((Node *) result);
+ result = (List *) eval_const_expressions(NULL, (Node *) result);
result = (List *) canonicalize_qual((Expr *) result);
diff --git a/src/include/optimizer/clauses.h b/src/include/optimizer/clauses.h
index 797222d526..58c20d69a2 100644
--- a/src/include/optimizer/clauses.h
+++ b/src/include/optimizer/clauses.h
@@ -75,7 +75,7 @@ extern Node *strip_implicit_coercions(Node *node);
extern void set_coercionform_dontcare(Node *node);
-extern Node *eval_const_expressions(Node *node);
+extern Node *eval_const_expressions(PlannerInfo *root, Node *node);
extern Node *estimate_expression_value(PlannerInfo *root, Node *node);
diff --git a/src/include/optimizer/plancat.h b/src/include/optimizer/plancat.h
index 4e248604df..bd23b2f1c2 100644
--- a/src/include/optimizer/plancat.h
+++ b/src/include/optimizer/plancat.h
@@ -31,8 +31,8 @@ extern void get_relation_info(PlannerInfo *root, Oid relationObjectId,
extern void estimate_rel_size(Relation rel, int32 *attr_widths,
BlockNumber *pages, double *tuples);
-extern bool relation_excluded_by_constraints(RelOptInfo *rel,
- RangeTblEntry *rte);
+extern bool relation_excluded_by_constraints(PlannerInfo *root,
+ RelOptInfo *rel, RangeTblEntry *rte);
extern List *build_physical_tlist(PlannerInfo *root, RelOptInfo *rel);