From: Tom Lane Date: Fri, 15 Nov 2002 02:37:08 +0000 (+0000) Subject: Push qual clauses containing subplans to the back of the qual list X-Git-Tag: REL7_3~37 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=779eb541425568e038a0149483be7d4a45934b61;p=postgresql Push qual clauses containing subplans to the back of the qual list at each plan node. Per gripe from Ross Reedstrom. --- diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c index 9cdbcc2e5e..44b116ce94 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.119 2002/09/18 21:35:21 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.119.2.1 2002/11/15 02:37:08 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -69,6 +69,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); @@ -177,6 +178,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: @@ -1178,6 +1182,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.