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 );
7272static List * switch_outer (List * clauses );
73+ static List * order_qual_clauses (Query * root , List * clauses );
7374static void copy_path_costsize (Plan * dest , Path * src );
7475static void copy_plan_costsize (Plan * dest , Plan * src );
7576static 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