summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/nodes/equalfuncs.c8
-rw-r--r--src/backend/optimizer/util/clauses.c38
-rw-r--r--src/backend/utils/cache/relcache.c14
-rw-r--r--src/include/nodes/primnodes.h4
-rw-r--r--src/include/optimizer/clauses.h4
5 files changed, 58 insertions, 10 deletions
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index b23002ff947..fadd02c9357 100644
--- a/src/backend/nodes/equalfuncs.c
+++ b/src/backend/nodes/equalfuncs.c
@@ -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 &&
diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c
index a767eda803c..1f3a8afc7f4 100644
--- a/src/backend/optimizer/util/clauses.c
+++ b/src/backend/optimizer/util/clauses.c
@@ -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);
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index ac0ee1a5e51..4900cfa5276 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -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);
diff --git a/src/include/nodes/primnodes.h b/src/include/nodes/primnodes.h
index 6a9312b73fe..065ca656a7f 100644
--- a/src/include/nodes/primnodes.h
+++ b/src/include/nodes/primnodes.h
@@ -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;
/*
diff --git a/src/include/optimizer/clauses.h b/src/include/optimizer/clauses.h
index 947c4467e7b..09f0822f468 100644
--- a/src/include/optimizer/clauses.h
+++ b/src/include/optimizer/clauses.h
@@ -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) (),