diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c index b23002ff9477c1796fc5cc62f4c8e7cfb74e42e8..fadd02c935708768a0f6142b6a0cee24d98051b0 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 a767eda803cfd34a33c3f5092752e178a5285afc..1f3a8afc7f44fa46059e503490b43c6aabe18d57 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 ac0ee1a5e518930a4a45833c4ed6289c2e76da97..4900cfa527642323957c22fd72137f2c645c2931 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 6a9312b73fe309f6fb0deff64699164bd12a7ef9..065ca656a7f5ae91237786397512db7147abdd64 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 947c4467e7b4285913122aa563e6fc08c13b49f1..09f0822f468389cf9fd8ae8dccb809f315bfa03c 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) (),