mirror of
https://github.com/postgres/postgres.git
synced 2025-07-03 20:02:46 +03:00
Revise the planner's handling of "pseudoconstant" WHERE clauses, that is
clauses containing no variables and no volatile functions. Such a clause can be used as a one-time qual in a gating Result plan node, to suppress plan execution entirely when it is false. Even when the clause is true, putting it in a gating node wins by avoiding repeated evaluation of the clause. In previous PG releases, query_planner() would do this for pseudoconstant clauses appearing at the top level of the jointree, but there was no ability to generate a gating Result deeper in the plan tree. To fix it, get rid of the special case in query_planner(), and instead process pseudoconstant clauses through the normal RestrictInfo qual distribution mechanism. When a pseudoconstant clause is found attached to a path node in create_plan(), pull it out and generate a gating Result at that point. This requires special-casing pseudoconstants in selectivity estimation and cost_qual_eval, but on the whole it's pretty clean. It probably even makes the planner a bit faster than before for the normal case of no pseudoconstants, since removing pull_constant_clauses saves one useless traversal of the qual tree. Per gripe from Phil Frost.
This commit is contained in:
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/util/pathnode.c,v 1.128 2006/06/06 17:59:57 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/util/pathnode.c,v 1.129 2006/07/01 18:38:33 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -667,36 +667,29 @@ create_append_path(RelOptInfo *rel, List *subpaths)
|
||||
|
||||
/*
|
||||
* create_result_path
|
||||
* Creates a path corresponding to a Result plan, returning the
|
||||
* pathnode.
|
||||
* Creates a path representing a Result-and-nothing-else plan.
|
||||
* This is only used for the case of a query with an empty jointree.
|
||||
*/
|
||||
ResultPath *
|
||||
create_result_path(RelOptInfo *rel, Path *subpath, List *constantqual)
|
||||
create_result_path(List *quals)
|
||||
{
|
||||
ResultPath *pathnode = makeNode(ResultPath);
|
||||
|
||||
pathnode->path.pathtype = T_Result;
|
||||
pathnode->path.parent = rel; /* may be NULL */
|
||||
|
||||
if (subpath)
|
||||
pathnode->path.pathkeys = subpath->pathkeys;
|
||||
else
|
||||
pathnode->path.pathkeys = NIL;
|
||||
|
||||
pathnode->subpath = subpath;
|
||||
pathnode->constantqual = constantqual;
|
||||
pathnode->path.parent = NULL;
|
||||
pathnode->path.pathkeys = NIL;
|
||||
pathnode->quals = quals;
|
||||
|
||||
/* Ideally should define cost_result(), but I'm too lazy */
|
||||
if (subpath)
|
||||
{
|
||||
pathnode->path.startup_cost = subpath->startup_cost;
|
||||
pathnode->path.total_cost = subpath->total_cost;
|
||||
}
|
||||
else
|
||||
{
|
||||
pathnode->path.startup_cost = 0;
|
||||
pathnode->path.total_cost = cpu_tuple_cost;
|
||||
}
|
||||
pathnode->path.startup_cost = 0;
|
||||
pathnode->path.total_cost = cpu_tuple_cost;
|
||||
/*
|
||||
* In theory we should include the qual eval cost as well, but
|
||||
* at present that doesn't accomplish much except duplicate work that
|
||||
* will be done again in make_result; since this is only used for
|
||||
* degenerate cases, nothing interesting will be done with the path
|
||||
* cost values...
|
||||
*/
|
||||
|
||||
return pathnode;
|
||||
}
|
||||
|
Reference in New Issue
Block a user