Commit 3779f7fd authored by Tom Lane's avatar Tom Lane

Push qual clauses containing subplans to the back of the qual list

at each plan node.  Per gripe from Ross Reedstrom.
parent c948a3f4
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
* *
* *
* IDENTIFICATION * 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, ...@@ -70,6 +70,7 @@ static Node *fix_indxqual_operand(Node *node, int baserelid,
IndexOptInfo *index, IndexOptInfo *index,
Oid *opclass); Oid *opclass);
static List *switch_outer(List *clauses); 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_path_costsize(Plan *dest, Path *src);
static void copy_plan_costsize(Plan *dest, Plan *src); static void copy_plan_costsize(Plan *dest, Plan *src);
static SeqScan *make_seqscan(List *qptlist, List *qpqual, Index scanrelid); static SeqScan *make_seqscan(List *qptlist, List *qpqual, Index scanrelid);
...@@ -182,6 +183,9 @@ create_scan_plan(Query *root, Path *best_path) ...@@ -182,6 +183,9 @@ create_scan_plan(Query *root, Path *best_path)
*/ */
scan_clauses = get_actual_clauses(best_path->parent->baserestrictinfo); 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) switch (best_path->pathtype)
{ {
case T_SeqScan: case T_SeqScan:
...@@ -359,6 +363,7 @@ create_result_plan(Query *root, ResultPath *best_path) ...@@ -359,6 +363,7 @@ create_result_plan(Query *root, ResultPath *best_path)
{ {
Result *plan; Result *plan;
List *tlist; List *tlist;
List *constclauses;
Plan *subplan; Plan *subplan;
if (best_path->path.parent) if (best_path->path.parent)
...@@ -371,7 +376,9 @@ create_result_plan(Query *root, ResultPath *best_path) ...@@ -371,7 +376,9 @@ create_result_plan(Query *root, ResultPath *best_path)
else else
subplan = NULL; 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; return plan;
} }
...@@ -1212,6 +1219,43 @@ switch_outer(List *clauses) ...@@ -1212,6 +1219,43 @@ switch_outer(List *clauses)
return t_list; 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. * 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. * The executor won't use this info, but it's needed by EXPLAIN.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment