8
8
*
9
9
*
10
10
* IDENTIFICATION
11
- * $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.162 2007/04/2106:18:52 tgl Exp $
11
+ * $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.163 2007/04/2121:01:44 tgl Exp $
12
12
*
13
13
*-------------------------------------------------------------------------
14
14
*/
@@ -39,7 +39,8 @@ intgeqo_threshold;
39
39
40
40
41
41
static void set_base_rel_pathlists (PlannerInfo * root );
42
- static void set_rel_pathlist (PlannerInfo * root ,RelOptInfo * rel ,Index rti );
42
+ static void set_rel_pathlist (PlannerInfo * root ,RelOptInfo * rel ,
43
+ Index rti ,RangeTblEntry * rte );
43
44
static void set_plain_rel_pathlist (PlannerInfo * root ,RelOptInfo * rel ,
44
45
RangeTblEntry * rte );
45
46
static void set_append_rel_pathlist (PlannerInfo * root ,RelOptInfo * rel ,
@@ -144,7 +145,7 @@ set_base_rel_pathlists(PlannerInfo *root)
144
145
if (rel -> reloptkind != RELOPT_BASEREL )
145
146
continue ;
146
147
147
- set_rel_pathlist (root ,rel ,rti );
148
+ set_rel_pathlist (root ,rel ,rti , root -> simple_rte_array [ rti ] );
148
149
}
149
150
}
150
151
@@ -153,10 +154,9 @@ set_base_rel_pathlists(PlannerInfo *root)
153
154
* Build access paths for a base relation
154
155
*/
155
156
static void
156
- set_rel_pathlist (PlannerInfo * root ,RelOptInfo * rel ,Index rti )
157
+ set_rel_pathlist (PlannerInfo * root ,RelOptInfo * rel ,
158
+ Index rti ,RangeTblEntry * rte )
157
159
{
158
- RangeTblEntry * rte = rt_fetch (rti ,root -> parse -> rtable );
159
-
160
160
if (rte -> inh )
161
161
{
162
162
/* It's an "append relation", process accordingly */
@@ -200,8 +200,11 @@ set_plain_rel_pathlist(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte)
200
200
* If we can prove we don't need to scan the rel via constraint exclusion,
201
201
* set up a single dummy path for it. (Rather than inventing a special
202
202
* "dummy" path type, we represent this as an AppendPath with no members.)
203
+ * We only need to check for regular baserels; if it's an otherrel, CE
204
+ * was already checked in set_append_rel_pathlist().
203
205
*/
204
- if (relation_excluded_by_constraints (rel ,rte ))
206
+ if (rel -> reloptkind == RELOPT_BASEREL &&
207
+ relation_excluded_by_constraints (rel ,rte ))
205
208
{
206
209
/* Set dummy size estimates --- we leave attr_widths[] as zeroes */
207
210
rel -> rows = 0 ;
@@ -294,6 +297,7 @@ set_append_rel_pathlist(PlannerInfo *root, RelOptInfo *rel,
294
297
{
295
298
AppendRelInfo * appinfo = (AppendRelInfo * )lfirst (l );
296
299
int childRTindex ;
300
+ RangeTblEntry * childRTE ;
297
301
RelOptInfo * childrel ;
298
302
Path * childpath ;
299
303
ListCell * parentvars ;
@@ -304,6 +308,7 @@ set_append_rel_pathlist(PlannerInfo *root, RelOptInfo *rel,
304
308
continue ;
305
309
306
310
childRTindex = appinfo -> child_relid ;
311
+ childRTE = root -> simple_rte_array [childRTindex ];
307
312
308
313
/*
309
314
* The child rel's RelOptInfo was already created during
@@ -313,18 +318,29 @@ set_append_rel_pathlist(PlannerInfo *root, RelOptInfo *rel,
313
318
Assert (childrel -> reloptkind == RELOPT_OTHER_MEMBER_REL );
314
319
315
320
/*
316
- * Copy the parent's targetlist and quals to the child, with
317
- * appropriate substitution of variables.
321
+ * We have to copy the parent's targetlist and quals to the child,
322
+ * with appropriate substitution of variables. However, only the
323
+ * baserestrictinfo quals are needed before we can check for
324
+ * constraint exclusion; so do that first and then check to see
325
+ * if we can disregard this child.
318
326
*/
319
- childrel -> reltargetlist = (List * )
320
- adjust_appendrel_attrs ((Node * )rel -> reltargetlist ,
321
- appinfo );
322
327
childrel -> baserestrictinfo = (List * )
323
328
adjust_appendrel_attrs ((Node * )rel -> baserestrictinfo ,
324
329
appinfo );
330
+
331
+ if (relation_excluded_by_constraints (childrel ,childRTE ))
332
+ {
333
+ /* this child need not be scanned, so just disregard it */
334
+ continue ;
335
+ }
336
+
337
+ /* CE failed, so finish copying targetlist and join quals */
325
338
childrel -> joininfo = (List * )
326
339
adjust_appendrel_attrs ((Node * )rel -> joininfo ,
327
340
appinfo );
341
+ childrel -> reltargetlist = (List * )
342
+ adjust_appendrel_attrs ((Node * )rel -> reltargetlist ,
343
+ appinfo );
328
344
329
345
/*
330
346
* We have to make child entries in the EquivalenceClass data
@@ -353,12 +369,9 @@ set_append_rel_pathlist(PlannerInfo *root, RelOptInfo *rel,
353
369
* It's possible that the child is itself an appendrel, in which case
354
370
* we can "cut out the middleman" and just add its child paths to our
355
371
* own list. (We don't try to do this earlier because we need to
356
- * apply both levels of transformation to the quals.) This test also
357
- * handles the case where the child rel need not be scanned because of
358
- * constraint exclusion: it'll have an Append path with no subpaths,
359
- * and will vanish from our list.
372
+ * apply both levels of transformation to the quals.)
360
373
*/
361
- set_rel_pathlist (root ,childrel ,childRTindex );
374
+ set_rel_pathlist (root ,childrel ,childRTindex , childRTE );
362
375
363
376
childpath = childrel -> cheapest_total_path ;
364
377
if (IsA (childpath ,AppendPath ))