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
|
* 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,
|
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)
|
|||||||
*/
|
*/
|
||||||
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)
|
|||||||
{
|
{
|
||||||
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)
|
|||||||
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)
|
|||||||
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.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user