diff options
| author | Tom Lane | 2006-07-01 18:38:33 +0000 |
|---|---|---|
| committer | Tom Lane | 2006-07-01 18:38:33 +0000 |
| commit | cffd89ca736e485309cd51ae056f837bd7e683ad (patch) | |
| tree | 7ebf13ae5d921d074382d80be66a8d97e7a822e1 /src/include/nodes | |
| parent | 68628fc38ea7a3c72f6a813b0193d836731d9c10 (diff) | |
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.
Diffstat (limited to 'src/include/nodes')
| -rw-r--r-- | src/include/nodes/relation.h | 52 |
1 files changed, 28 insertions, 24 deletions
diff --git a/src/include/nodes/relation.h b/src/include/nodes/relation.h index 1f971118f5b..d7a93f0f650 100644 --- a/src/include/nodes/relation.h +++ b/src/include/nodes/relation.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/nodes/relation.h,v 1.125 2006/06/06 17:59:58 tgl Exp $ + * $PostgreSQL: pgsql/src/include/nodes/relation.h,v 1.126 2006/07/01 18:38:33 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -114,6 +114,8 @@ typedef struct PlannerInfo bool hasJoinRTEs; /* true if any RTEs are RTE_JOIN kind */ bool hasOuterJoins; /* true if any RTEs are outer joins */ bool hasHavingQual; /* true if havingQual was non-null */ + bool hasPseudoConstantQuals; /* true if any RestrictInfo has + * pseudoconstant = true */ } PlannerInfo; @@ -524,25 +526,16 @@ typedef struct AppendPath } AppendPath; /* - * ResultPath represents use of a Result plan node. There are several - * applications for this: - * * To compute a variable-free targetlist (a "SELECT expressions" query). - * In this case subpath and path.parent will both be NULL. constantqual - * might or might not be empty ("SELECT expressions WHERE something"). - * * To gate execution of a subplan with a one-time (variable-free) qual - * condition. path.parent is copied from the subpath. - * * To substitute for a scan plan when we have proven that no rows in - * a table will satisfy the query. subpath is NULL but path.parent - * references the not-to-be-scanned relation, and constantqual is - * a constant FALSE. - * - * Note that constantqual is a list of bare clauses, not RestrictInfos. + * ResultPath represents use of a Result plan node to compute a variable-free + * targetlist with no underlying tables (a "SELECT expressions" query). + * The query could have a WHERE clause, too, represented by "quals". + * + * Note that quals is a list of bare clauses, not RestrictInfos. */ typedef struct ResultPath { Path path; - Path *subpath; - List *constantqual; + List *quals; } ResultPath; /* @@ -732,6 +725,22 @@ typedef struct HashPath * OR/AND structure. This is a convenience for OR indexscan processing: * indexquals taken from either the top level or an OR subclause will have * associated RestrictInfo nodes. + * + * The can_join flag is set true if the clause looks potentially useful as + * a merge or hash join clause, that is if it is a binary opclause with + * nonoverlapping sets of relids referenced in the left and right sides. + * (Whether the operator is actually merge or hash joinable isn't checked, + * however.) + * + * The pseudoconstant flag is set true if the clause contains no Vars of + * the current query level and no volatile functions. Such a clause can be + * pulled out and used as a one-time qual in a gating Result node. We keep + * pseudoconstant clauses in the same lists as other RestrictInfos so that + * the regular clause-pushing machinery can assign them to the correct join + * level, but they need to be treated specially for cost and selectivity + * estimates. Note that a pseudoconstant clause can never be an indexqual + * or merge or hash join clause, so it's of no interest to large parts of + * the planner. */ typedef struct RestrictInfo @@ -744,14 +753,9 @@ typedef struct RestrictInfo bool outerjoin_delayed; /* TRUE if delayed by outer join */ - /* - * This flag is set true if the clause looks potentially useful as a merge - * or hash join clause, that is if it is a binary opclause with - * nonoverlapping sets of relids referenced in the left and right sides. - * (Whether the operator is actually merge or hash joinable isn't checked, - * however.) - */ - bool can_join; + bool can_join; /* see comment above */ + + bool pseudoconstant; /* see comment above */ /* The set of relids (varnos) actually referenced in the clause: */ Relids clause_relids; |
