10
10
*
11
11
*
12
12
* 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 $
14
14
*
15
15
*-------------------------------------------------------------------------
16
16
*/
@@ -70,6 +70,7 @@ static Node *fix_indxqual_operand(Node *node, int baserelid,
70
70
IndexOptInfo * index ,
71
71
Oid * opclass );
72
72
static List * switch_outer (List * clauses );
73
+ static List * order_qual_clauses (Query * root , List * clauses );
73
74
static void copy_path_costsize (Plan * dest , Path * src );
74
75
static void copy_plan_costsize (Plan * dest , Plan * src );
75
76
static SeqScan * make_seqscan (List * qptlist , List * qpqual , Index scanrelid );
@@ -182,6 +183,9 @@ create_scan_plan(Query *root, Path *best_path)
182
183
*/
183
184
scan_clauses = get_actual_clauses (best_path -> parent -> baserestrictinfo );
184
185
186
+ /* Sort clauses into best execution order */
187
+ scan_clauses = order_qual_clauses (root , scan_clauses );
188
+
185
189
switch (best_path -> pathtype )
186
190
{
187
191
case T_SeqScan :
@@ -359,6 +363,7 @@ create_result_plan(Query *root, ResultPath *best_path)
359
363
{
360
364
Result * plan ;
361
365
List * tlist ;
366
+ List * constclauses ;
362
367
Plan * subplan ;
363
368
364
369
if (best_path -> path .parent )
@@ -371,7 +376,9 @@ create_result_plan(Query *root, ResultPath *best_path)
371
376
else
372
377
subplan = NULL ;
373
378
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 );
375
382
376
383
return plan ;
377
384
}
@@ -1212,6 +1219,43 @@ switch_outer(List *clauses)
1212
1219
return t_list ;
1213
1220
}
1214
1221
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
+
1215
1259
/*
1216
1260
* Copy cost and size info from a Path node to the Plan node created from it.
1217
1261
* The executor won't use this info, but it's needed by EXPLAIN.
0 commit comments