提交 04226b64 编写于 作者: T Tom Lane

Tweak planner so that index expressions and predicates are matched to

queries without regard to whether coercions are stated explicitly or
implicitly.  Per suggestion from Stephan Szabo.
上级 e1d08faf
......@@ -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 &&
......
......@@ -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);
......
......@@ -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);
......
......@@ -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;
/*
......
......@@ -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) (),
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册