Fix an oversight I made in a cleanup patch over a year ago:
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 1 Apr 2008 00:48:44 +0000 (00:48 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 1 Apr 2008 00:48:44 +0000 (00:48 +0000)
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.

src/backend/optimizer/path/allpaths.c
src/backend/optimizer/plan/initsplan.c
src/backend/optimizer/plan/planner.c
src/backend/optimizer/util/clauses.c
src/backend/optimizer/util/plancat.c
src/backend/utils/cache/relcache.c
src/include/optimizer/clauses.h
src/include/optimizer/plancat.h

index a199a001b6fe1b79b011121d780a20e0218e4586..c4c85a2a762d911cc3fc260b470163eb19beef6c 100644 (file)
@@ -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
index e60491a7cc5a32e025533a3b9290a4c443d19682..afc76fdc42453fb34a303e0c2dcd55ebc538a55a 100644 (file)
@@ -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))
index 2c22840fbdc74ade2f2dfd60890e841cce21e207..ef91030bde691ee3a2ef24e3184df0bed9cd5101 100644 (file)
@@ -496,7 +496,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.
index fb4ab8799c63cd40ee040ba868520b9a3f4f3b1f..99a0306146687df67ec2762e074cabb9d72ff6f8 100644 (file)
@@ -1675,16 +1675,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 */
index 1b3f44890a51f836f1e65d4f52f7b9ed50c3a527..d10843a7a2579787f62a5cff467cf4cd024bbe86 100644 (file)
@@ -47,7 +47,8 @@ get_relation_info_hook_type get_relation_info_hook = NULL;
 
 static void estimate_rel_size(Relation rel, int32 *attr_widths,
                                  BlockNumber *pages, double *tuples);
-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
index d88fa5478e80df06d46fa83a7f01162465359224..2ad90392496a1f0e4a122e16d8402c10e1c41577 100644 (file)
@@ -3078,7 +3078,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
@@ -3148,7 +3148,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);
 
index 33b678ffbc5e1444a358d18236481c1b99fae1d6..a6675979ca17e564b30daea1410aa232ff422206 100644 (file)
@@ -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);
 
index f6c169b7bbbae014ead6c2d1a3f72fa11904074d..9f8a5d1699f5dcb35692028acd92f516ef848208 100644 (file)
@@ -27,8 +27,8 @@ extern PGDLLIMPORT get_relation_info_hook_type get_relation_info_hook;
 extern void get_relation_info(PlannerInfo *root, Oid relationObjectId,
                                  bool inhparent, RelOptInfo *rel);
 
-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);