]> granicus.if.org Git - postgresql/commitdiff
Tweak planner so that index expressions and predicates are matched to
authorTom Lane <tgl@sss.pgh.pa.us>
Sun, 14 Mar 2004 23:41:27 +0000 (23:41 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Sun, 14 Mar 2004 23:41:27 +0000 (23:41 +0000)
queries without regard to whether coercions are stated explicitly or
implicitly.  Per suggestion from Stephan Szabo.

src/backend/nodes/equalfuncs.c
src/backend/optimizer/util/clauses.c
src/backend/utils/cache/relcache.c
src/include/nodes/primnodes.h
src/include/optimizer/clauses.h

index b23002ff9477c1796fc5cc62f4c8e7cfb74e42e8..fadd02c935708768a0f6142b6a0cee24d98051b0 100644 (file)
@@ -18,7 +18,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.216 2004/03/11 01:47:35 ishii Exp $
+ *       $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.217 2004/03/14 23:41:26 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -231,7 +231,7 @@ _equalFuncExpr(FuncExpr *a, FuncExpr *b)
        COMPARE_SCALAR_FIELD(funcretset);
 
        /*
-        * Special-case COERCE_DONTCARE, so that pathkeys can build coercion
+        * Special-case COERCE_DONTCARE, so that planner can build coercion
         * nodes that are equal() to both explicit and implicit coercions.
         */
        if (a->funcformat != b->funcformat &&
@@ -372,7 +372,7 @@ _equalRelabelType(RelabelType *a, RelabelType *b)
        COMPARE_SCALAR_FIELD(resulttypmod);
 
        /*
-        * Special-case COERCE_DONTCARE, so that pathkeys can build coercion
+        * Special-case COERCE_DONTCARE, so that planner can build coercion
         * nodes that are equal() to both explicit and implicit coercions.
         */
        if (a->relabelformat != b->relabelformat &&
@@ -472,7 +472,7 @@ _equalCoerceToDomain(CoerceToDomain *a, CoerceToDomain *b)
        COMPARE_SCALAR_FIELD(resulttypmod);
 
        /*
-        * Special-case COERCE_DONTCARE, so that pathkeys can build coercion
+        * Special-case COERCE_DONTCARE, so that planner can build coercion
         * nodes that are equal() to both explicit and implicit coercions.
         */
        if (a->coercionformat != b->coercionformat &&
index a767eda803cfd34a33c3f5092752e178a5285afc..1f3a8afc7f44fa46059e503490b43c6aabe18d57 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.163 2004/01/28 00:05:04 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.164 2004/03/14 23:41:27 tgl Exp $
  *
  * HISTORY
  *       AUTHOR                        DATE                    MAJOR EVENT
@@ -60,6 +60,7 @@ static bool contain_subplans_walker(Node *node, void *context);
 static bool contain_mutable_functions_walker(Node *node, void *context);
 static bool contain_volatile_functions_walker(Node *node, void *context);
 static bool contain_nonstrict_functions_walker(Node *node, void *context);
+static bool set_coercionform_dontcare_walker(Node *node, void *context);
 static Node *eval_const_expressions_mutator(Node *node, List *active_fns);
 static List *simplify_or_arguments(List *args,
                                                                   bool *haveNull, bool *forceTrue);
@@ -1002,6 +1003,39 @@ CommuteClause(OpExpr *clause)
        lsecond(clause->args) = temp;
 }
 
+/*
+ * set_coercionform_dontcare: set all CoercionForm fields to COERCE_DONTCARE
+ *
+ * This is used to make index expressions and index predicates more easily
+ * comparable to clauses of queries.  CoercionForm is not semantically
+ * significant (for cases where it does matter, the significant info is
+ * coded into the coercion function arguments) so we can ignore it during
+ * comparisons.  Thus, for example, an index on "foo::int4" can match an
+ * implicit coercion to int4.
+ *
+ * Caution: the passed expression tree is modified in-place.
+ */
+void
+set_coercionform_dontcare(Node *node)
+{
+       (void) set_coercionform_dontcare_walker(node, NULL);
+}
+
+static bool
+set_coercionform_dontcare_walker(Node *node, void *context)
+{
+       if (node == NULL)
+               return false;
+       if (IsA(node, FuncExpr))
+               ((FuncExpr *) node)->funcformat = COERCE_DONTCARE;
+       if (IsA(node, RelabelType))
+               ((RelabelType *) node)->relabelformat = COERCE_DONTCARE;
+       if (IsA(node, CoerceToDomain))
+               ((CoerceToDomain *) node)->coercionformat = COERCE_DONTCARE;
+       return expression_tree_walker(node, set_coercionform_dontcare_walker,
+                                                                 context);
+}
+
 
 /*--------------------
  * eval_const_expressions
@@ -1766,7 +1800,7 @@ evaluate_function(Oid funcid, Oid result_type, List *args,
        newexpr->funcid = funcid;
        newexpr->funcresulttype = result_type;
        newexpr->funcretset = false;
-       newexpr->funcformat = COERCE_EXPLICIT_CALL; /* doesn't matter */
+       newexpr->funcformat = COERCE_DONTCARE;          /* doesn't matter */
        newexpr->args = args;
 
        return evaluate_expr((Expr *) newexpr, result_type);
index ac0ee1a5e518930a4a45833c4ed6289c2e76da97..4900cfa527642323957c22fd72137f2c645c2931 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/utils/cache/relcache.c,v 1.198 2004/02/25 19:41:23 momjian Exp $
+ *       $PostgreSQL: pgsql/src/backend/utils/cache/relcache.c,v 1.199 2004/03/14 23:41:27 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -2687,6 +2687,12 @@ RelationGetIndexExpressions(Relation relation)
 
        result = (List *) eval_const_expressions((Node *) result);
 
+       /*
+        * Also mark any coercion format fields as "don't care", so that the
+        * planner can match to both explicit and implicit coercions.
+        */
+       set_coercionform_dontcare((Node *) result);
+
        /* May as well fix opfuncids too */
        fix_opfuncids((Node *) result);
 
@@ -2755,6 +2761,12 @@ RelationGetIndexPredicate(Relation relation)
 
        result = (List *) eval_const_expressions((Node *) result);
 
+       /*
+        * Also mark any coercion format fields as "don't care", so that the
+        * planner can match to both explicit and implicit coercions.
+        */
+       set_coercionform_dontcare((Node *) result);
+
        /* Also convert to implicit-AND format */
        result = make_ands_implicit((Expr *) result);
 
index 6a9312b73fe309f6fb0deff64699164bd12a7ef9..065ca656a7f5ae91237786397512db7147abdd64 100644 (file)
@@ -10,7 +10,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/nodes/primnodes.h,v 1.94 2004/01/07 18:43:36 neilc Exp $
+ * $PostgreSQL: pgsql/src/include/nodes/primnodes.h,v 1.95 2004/03/14 23:41:27 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -307,7 +307,7 @@ typedef enum CoercionForm
        COERCE_EXPLICIT_CALL,           /* display as a function call */
        COERCE_EXPLICIT_CAST,           /* display as an explicit cast */
        COERCE_IMPLICIT_CAST,           /* implicit cast, so hide it */
-       COERCE_DONTCARE                         /* special case for pathkeys */
+       COERCE_DONTCARE                         /* special case for planner */
 } CoercionForm;
 
 /*
index 947c4467e7b4285913122aa563e6fc08c13b49f1..09f0822f468389cf9fd8ae8dccb809f315bfa03c 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/optimizer/clauses.h,v 1.72 2004/01/05 18:04:39 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/optimizer/clauses.h,v 1.73 2004/03/14 23:41:27 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -63,6 +63,8 @@ extern bool has_distinct_on_clause(Query *query);
 extern int     NumRelids(Node *clause);
 extern void CommuteClause(OpExpr *clause);
 
+extern void set_coercionform_dontcare(Node *node);
+
 extern Node *eval_const_expressions(Node *node);
 
 extern bool expression_tree_walker(Node *node, bool (*walker) (),