8
8
*
9
9
*
10
10
* IDENTIFICATION
11
- * $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.141 2006/02/03 21:08:49 tgl Exp $
11
+ * $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.142 2006/02/04 23:03:20 tgl Exp $
12
12
*
13
13
*-------------------------------------------------------------------------
14
14
*/
26
26
#include "optimizer/paths.h"
27
27
#include "optimizer/plancat.h"
28
28
#include "optimizer/planner.h"
29
- #include "optimizer/predtest.h"
30
29
#include "optimizer/prep.h"
31
30
#include "optimizer/var.h"
32
31
#include "parser/parsetree.h"
36
35
37
36
38
37
/* These parameters are set by GUC */
39
- bool constraint_exclusion = false;
40
38
bool enable_geqo = false; /* just in case GUC doesn't set it */
41
39
int geqo_threshold ;
42
40
43
41
44
42
static void set_base_rel_pathlists (PlannerInfo * root );
45
- static void set_rel_pathlist (PlannerInfo * root , RelOptInfo * rel ,
46
- Index rti , RangeTblEntry * rte );
43
+ static void set_rel_pathlist (PlannerInfo * root , RelOptInfo * rel , Index rti );
47
44
static void set_plain_rel_pathlist (PlannerInfo * root , RelOptInfo * rel ,
48
45
RangeTblEntry * rte );
49
46
static void set_append_rel_pathlist (PlannerInfo * root , RelOptInfo * rel ,
@@ -146,8 +143,7 @@ set_base_rel_pathlists(PlannerInfo *root)
146
143
if (rel -> reloptkind != RELOPT_BASEREL )
147
144
continue ;
148
145
149
- set_rel_pathlist (root , rel , rti ,
150
- rt_fetch (rti , root -> parse -> rtable ));
146
+ set_rel_pathlist (root , rel , rti );
151
147
}
152
148
}
153
149
@@ -156,9 +152,10 @@ set_base_rel_pathlists(PlannerInfo *root)
156
152
* Build access paths for a base relation
157
153
*/
158
154
static void
159
- set_rel_pathlist (PlannerInfo * root , RelOptInfo * rel ,
160
- Index rti , RangeTblEntry * rte )
155
+ set_rel_pathlist (PlannerInfo * root , RelOptInfo * rel , Index rti )
161
156
{
157
+ RangeTblEntry * rte = rt_fetch (rti , root -> parse -> rtable );
158
+
162
159
if (rte -> inh )
163
160
{
164
161
/* It's an "append relation", process accordingly */
@@ -207,6 +204,24 @@ set_plain_rel_pathlist(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte)
207
204
if (create_or_index_quals (root , rel ))
208
205
set_baserel_size_estimates (root , rel );
209
206
207
+ /*
208
+ * If we can prove we don't need to scan the rel via constraint exclusion,
209
+ * set up a single dummy path for it. (Rather than inventing a special
210
+ * "dummy" path type, we represent this as an AppendPath with no members.)
211
+ */
212
+ if (relation_excluded_by_constraints (rel , rte ))
213
+ {
214
+ /* Reset output-rows estimate to 0 */
215
+ rel -> rows = 0 ;
216
+
217
+ add_path (rel , (Path * ) create_append_path (rel , NIL ));
218
+
219
+ /* Select cheapest path (pretty easy in this case...) */
220
+ set_cheapest (rel );
221
+
222
+ return ;
223
+ }
224
+
210
225
/*
211
226
* Generate paths and add them to the rel's pathlist.
212
227
*
@@ -273,7 +288,6 @@ set_append_rel_pathlist(PlannerInfo *root, RelOptInfo *rel,
273
288
AppendRelInfo * appinfo = (AppendRelInfo * ) lfirst (l );
274
289
int childRTindex ;
275
290
RelOptInfo * childrel ;
276
- RangeTblEntry * childrte ;
277
291
Path * childpath ;
278
292
ListCell * parentvars ;
279
293
ListCell * childvars ;
@@ -316,53 +330,18 @@ set_append_rel_pathlist(PlannerInfo *root, RelOptInfo *rel,
316
330
childrel -> max_attr );
317
331
318
332
/*
319
- * If we can prove we don't need to scan this child via constraint
320
- * exclusion, just ignore it. (We have to have converted the
321
- * baserestrictinfo Vars before we can make the test.)
322
- *
323
- * XXX it'd probably be better to give the child some kind of dummy
324
- * cheapest path, or otherwise explicitly mark it as ignorable.
325
- * Currently there is an ugly check in join_before_append() to handle
326
- * excluded children.
327
- */
328
- childrte = rt_fetch (childRTindex , root -> parse -> rtable );
329
- if (constraint_exclusion &&
330
- childrte -> rtekind == RTE_RELATION )
331
- {
332
- List * constraint_pred ;
333
-
334
- constraint_pred = get_relation_constraints (childrte -> relid ,
335
- childrel );
336
-
337
- /*
338
- * We do not currently enforce that CHECK constraints contain only
339
- * immutable functions, so it's necessary to check here. We
340
- * daren't draw conclusions from plan-time evaluation of
341
- * non-immutable functions.
342
- */
343
- if (!contain_mutable_functions ((Node * ) constraint_pred ))
344
- {
345
- /*
346
- * The constraints are effectively ANDed together, so we can
347
- * just try to refute the entire collection at once. This may
348
- * allow us to make proofs that would fail if we took them
349
- * individually.
350
- */
351
- if (predicate_refuted_by (constraint_pred ,
352
- childrel -> baserestrictinfo ))
353
- continue ;
354
- }
355
- }
356
-
357
- /*
358
- * Compute the child's access paths, and save the cheapest.
333
+ * Compute the child's access paths, and add the cheapest one
334
+ * to the Append path we are constructing for the parent.
359
335
*
360
336
* It's possible that the child is itself an appendrel, in which
361
337
* case we can "cut out the middleman" and just add its child
362
338
* paths to our own list. (We don't try to do this earlier because
363
339
* we need to apply both levels of transformation to the quals.)
340
+ * This test also handles the case where the child rel need not
341
+ * be scanned because of constraint exclusion: it'll have an
342
+ * Append path with no subpaths, and will vanish from our list.
364
343
*/
365
- set_rel_pathlist (root , childrel , childRTindex , childrte );
344
+ set_rel_pathlist (root , childrel , childRTindex );
366
345
367
346
childpath = childrel -> cheapest_total_path ;
368
347
if (IsA (childpath , AppendPath ))
0 commit comments