mirror of
https://github.com/postgres/postgres.git
synced 2025-11-21 00:42:43 +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/path/clausesel.c,v 1.79 2006/03/07 01:00:15 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/path/clausesel.c,v 1.80 2006/07/01 18:38:32 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -117,10 +117,18 @@ clauselist_selectivity(PlannerInfo *root,
|
||||
|
||||
/*
|
||||
* Check for being passed a RestrictInfo.
|
||||
*
|
||||
* If it's a pseudoconstant RestrictInfo, then s2 is either 1.0 or
|
||||
* 0.0; just use that rather than looking for range pairs.
|
||||
*/
|
||||
if (IsA(clause, RestrictInfo))
|
||||
{
|
||||
rinfo = (RestrictInfo *) clause;
|
||||
if (rinfo->pseudoconstant)
|
||||
{
|
||||
s1 = s1 * s2;
|
||||
continue;
|
||||
}
|
||||
clause = (Node *) rinfo->clause;
|
||||
}
|
||||
else
|
||||
@@ -422,6 +430,20 @@ clause_selectivity(PlannerInfo *root,
|
||||
{
|
||||
rinfo = (RestrictInfo *) clause;
|
||||
|
||||
/*
|
||||
* If the clause is marked pseudoconstant, then it will be used as
|
||||
* a gating qual and should not affect selectivity estimates; hence
|
||||
* return 1.0. The only exception is that a constant FALSE may
|
||||
* be taken as having selectivity 0.0, since it will surely mean
|
||||
* no rows out of the plan. This case is simple enough that we
|
||||
* need not bother caching the result.
|
||||
*/
|
||||
if (rinfo->pseudoconstant)
|
||||
{
|
||||
if (! IsA(rinfo->clause, Const))
|
||||
return s1;
|
||||
}
|
||||
|
||||
/*
|
||||
* If possible, cache the result of the selectivity calculation for
|
||||
* the clause. We can cache if varRelid is zero or the clause
|
||||
@@ -509,7 +531,10 @@ clause_selectivity(PlannerInfo *root,
|
||||
else if (IsA(clause, Const))
|
||||
{
|
||||
/* bool constant is pretty easy... */
|
||||
s1 = ((bool) ((Const *) clause)->constvalue) ? 1.0 : 0.0;
|
||||
Const *con = (Const *) clause;
|
||||
|
||||
s1 = con->constisnull ? 0.0 :
|
||||
DatumGetBool(con->constvalue) ? 1.0 : 0.0;
|
||||
}
|
||||
else if (IsA(clause, Param))
|
||||
{
|
||||
@@ -519,7 +544,10 @@ clause_selectivity(PlannerInfo *root,
|
||||
if (IsA(subst, Const))
|
||||
{
|
||||
/* bool constant is pretty easy... */
|
||||
s1 = ((bool) ((Const *) subst)->constvalue) ? 1.0 : 0.0;
|
||||
Const *con = (Const *) subst;
|
||||
|
||||
s1 = con->constisnull ? 0.0 :
|
||||
DatumGetBool(con->constvalue) ? 1.0 : 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user