aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2002-11-15 02:36:53 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2002-11-15 02:36:53 +0000
commit3779f7fd9fed8e77cb02a3ef26ab4311906377ad (patch)
tree0d332a5b1e4e6604106ca47d29ce45c1fb884a94
parentc948a3f4b81788283e7a31f5056baa9cac7b3024 (diff)
downloadpostgresql-3779f7fd9fed8e77cb02a3ef26ab4311906377ad.tar.gz
postgresql-3779f7fd9fed8e77cb02a3ef26ab4311906377ad.zip
Push qual clauses containing subplans to the back of the qual list
at each plan node. Per gripe from Ross Reedstrom.
-rw-r--r--src/backend/optimizer/plan/createplan.c48
1 files changed, 46 insertions, 2 deletions
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c
index cba1b2027d3..717fcfa3cec 100644
--- a/src/backend/optimizer/plan/createplan.c
+++ b/src/backend/optimizer/plan/createplan.c
@@ -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;
}
@@ -1213,6 +1220,43 @@ switch_outer(List *clauses)
}
/*
+ * 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.
*/