Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 3779f7f

Browse files
committed
Push qual clauses containing subplans to the back of the qual list
at each plan node. Per gripe from Ross Reedstrom.
1 parent c948a3f commit 3779f7f

File tree

1 file changed

+46
-2
lines changed

1 file changed

+46
-2
lines changed

src/backend/optimizer/plan/createplan.c

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
*
1111
*
1212
* IDENTIFICATION
13-
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.121 2002/11/06 22:31:24 tgl Exp $
13+
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.122 2002/11/15 02:36:53 tgl Exp $
1414
*
1515
*-------------------------------------------------------------------------
1616
*/
@@ -70,6 +70,7 @@ static Node *fix_indxqual_operand(Node *node, int baserelid,
7070
IndexOptInfo *index,
7171
Oid *opclass);
7272
static List *switch_outer(List *clauses);
73+
static List *order_qual_clauses(Query *root, List *clauses);
7374
static void copy_path_costsize(Plan *dest, Path *src);
7475
static void copy_plan_costsize(Plan *dest, Plan *src);
7576
static SeqScan *make_seqscan(List *qptlist, List *qpqual, Index scanrelid);
@@ -182,6 +183,9 @@ create_scan_plan(Query *root, Path *best_path)
182183
*/
183184
scan_clauses = get_actual_clauses(best_path->parent->baserestrictinfo);
184185

186+
/* Sort clauses into best execution order */
187+
scan_clauses = order_qual_clauses(root, scan_clauses);
188+
185189
switch (best_path->pathtype)
186190
{
187191
case T_SeqScan:
@@ -359,6 +363,7 @@ create_result_plan(Query *root, ResultPath *best_path)
359363
{
360364
Result *plan;
361365
List *tlist;
366+
List *constclauses;
362367
Plan *subplan;
363368

364369
if (best_path->path.parent)
@@ -371,7 +376,9 @@ create_result_plan(Query *root, ResultPath *best_path)
371376
else
372377
subplan = NULL;
373378

374-
plan = make_result(tlist, (Node *) best_path->constantqual, subplan);
379+
constclauses = order_qual_clauses(root, best_path->constantqual);
380+
381+
plan = make_result(tlist, (Node *) constclauses, subplan);
375382

376383
return plan;
377384
}
@@ -1212,6 +1219,43 @@ switch_outer(List *clauses)
12121219
return t_list;
12131220
}
12141221

1222+
/*
1223+
* order_qual_clauses
1224+
* Given a list of qual clauses that will all be evaluated at the same
1225+
* plan node, sort the list into the order we want to check the quals
1226+
* in at runtime.
1227+
*
1228+
* Ideally the order should be driven by a combination of execution cost and
1229+
* selectivity, but unfortunately we have so little information about
1230+
* execution cost of operators that it's really hard to do anything smart.
1231+
* For now, we just move any quals that contain SubPlan references (but not
1232+
* InitPlan references) to the end of the list.
1233+
*/
1234+
static List *
1235+
order_qual_clauses(Query *root, List *clauses)
1236+
{
1237+
List *nosubplans;
1238+
List *withsubplans;
1239+
List *l;
1240+
1241+
/* No need to work hard if the query is subselect-free */
1242+
if (!root->hasSubLinks)
1243+
return clauses;
1244+
1245+
nosubplans = withsubplans = NIL;
1246+
foreach(l, clauses)
1247+
{
1248+
Node *clause = lfirst(l);
1249+
1250+
if (contain_subplans(clause))
1251+
withsubplans = lappend(withsubplans, clause);
1252+
else
1253+
nosubplans = lappend(nosubplans, clause);
1254+
}
1255+
1256+
return nconc(nosubplans, withsubplans);
1257+
}
1258+
12151259
/*
12161260
* Copy cost and size info from a Path node to the Plan node created from it.
12171261
* The executor won't use this info, but it's needed by EXPLAIN.

0 commit comments

Comments
 (0)