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.
This commit is contained in:
parent
e1d08faf04
commit
04226b6404
@ -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);
|
||||
|
14
src/backend/utils/cache/relcache.c
vendored
14
src/backend/utils/cache/relcache.c
vendored
@ -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) (),
|
||||
|
Loading…
Reference in New Issue
Block a user