Push qual clauses containing subplans to the back of the qual list
at each plan node. Per gripe from Ross Reedstrom.
This commit is contained in:
parent
c948a3f4b8
commit
3779f7fd9f
@ -10,7 +10,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.121 2002/11/06 22:31:24 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.122 2002/11/15 02:36:53 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -70,6 +70,7 @@ static Node *fix_indxqual_operand(Node *node, int baserelid,
|
||||
IndexOptInfo *index,
|
||||
Oid *opclass);
|
||||
static List *switch_outer(List *clauses);
|
||||
static List *order_qual_clauses(Query *root, List *clauses);
|
||||
static void copy_path_costsize(Plan *dest, Path *src);
|
||||
static void copy_plan_costsize(Plan *dest, Plan *src);
|
||||
static SeqScan *make_seqscan(List *qptlist, List *qpqual, Index scanrelid);
|
||||
@ -182,6 +183,9 @@ create_scan_plan(Query *root, Path *best_path)
|
||||
*/
|
||||
scan_clauses = get_actual_clauses(best_path->parent->baserestrictinfo);
|
||||
|
||||
/* Sort clauses into best execution order */
|
||||
scan_clauses = order_qual_clauses(root, scan_clauses);
|
||||
|
||||
switch (best_path->pathtype)
|
||||
{
|
||||
case T_SeqScan:
|
||||
@ -359,6 +363,7 @@ create_result_plan(Query *root, ResultPath *best_path)
|
||||
{
|
||||
Result *plan;
|
||||
List *tlist;
|
||||
List *constclauses;
|
||||
Plan *subplan;
|
||||
|
||||
if (best_path->path.parent)
|
||||
@ -371,7 +376,9 @@ create_result_plan(Query *root, ResultPath *best_path)
|
||||
else
|
||||
subplan = NULL;
|
||||
|
||||
plan = make_result(tlist, (Node *) best_path->constantqual, subplan);
|
||||
constclauses = order_qual_clauses(root, best_path->constantqual);
|
||||
|
||||
plan = make_result(tlist, (Node *) constclauses, subplan);
|
||||
|
||||
return plan;
|
||||
}
|
||||
@ -1212,6 +1219,43 @@ switch_outer(List *clauses)
|
||||
return t_list;
|
||||
}
|
||||
|
||||
/*
|
||||
* order_qual_clauses
|
||||
* Given a list of qual clauses that will all be evaluated at the same
|
||||
* plan node, sort the list into the order we want to check the quals
|
||||
* in at runtime.
|
||||
*
|
||||
* Ideally the order should be driven by a combination of execution cost and
|
||||
* selectivity, but unfortunately we have so little information about
|
||||
* execution cost of operators that it's really hard to do anything smart.
|
||||
* For now, we just move any quals that contain SubPlan references (but not
|
||||
* InitPlan references) to the end of the list.
|
||||
*/
|
||||
static List *
|
||||
order_qual_clauses(Query *root, List *clauses)
|
||||
{
|
||||
List *nosubplans;
|
||||
List *withsubplans;
|
||||
List *l;
|
||||
|
||||
/* No need to work hard if the query is subselect-free */
|
||||
if (!root->hasSubLinks)
|
||||
return clauses;
|
||||
|
||||
nosubplans = withsubplans = NIL;
|
||||
foreach(l, clauses)
|
||||
{
|
||||
Node *clause = lfirst(l);
|
||||
|
||||
if (contain_subplans(clause))
|
||||
withsubplans = lappend(withsubplans, clause);
|
||||
else
|
||||
nosubplans = lappend(nosubplans, clause);
|
||||
}
|
||||
|
||||
return nconc(nosubplans, withsubplans);
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy cost and size info from a Path node to the Plan node created from it.
|
||||
* The executor won't use this info, but it's needed by EXPLAIN.
|
||||
|
Loading…
Reference in New Issue
Block a user