33
33
#include "fmgr.h"
34
34
#include "miscadmin.h"
35
35
#include "optimizer/clauses.h"
36
+ #include "optimizer/plancat.h"
36
37
#include "optimizer/prep.h"
37
38
#include "optimizer/restrictinfo.h"
38
39
#include "optimizer/cost.h"
@@ -276,6 +277,8 @@ append_child_relation(PlannerInfo *root, Relation parent_relation,
276
277
Index childRTindex ;
277
278
PlanRowMark * parent_rowmark ,
278
279
* child_rowmark ;
280
+ Node * childqual ;
281
+ List * childquals ;
279
282
ListCell * lc ,
280
283
* lc2 ;
281
284
@@ -323,10 +326,9 @@ append_child_relation(PlannerInfo *root, Relation parent_relation,
323
326
* Copy restrictions. If it's not the parent table, copy only
324
327
* those restrictions that are related to this partition.
325
328
*/
326
- child_rel -> baserestrictinfo = NIL ;
327
329
if (parent_rte -> relid != child_oid )
328
330
{
329
- List * childquals = NIL ;
331
+ childquals = NIL ;
330
332
331
333
forboth (lc , wrappers , lc2 , parent_rel -> baserestrictinfo )
332
334
{
@@ -345,24 +347,39 @@ append_child_relation(PlannerInfo *root, Relation parent_relation,
345
347
Assert (new_clause );
346
348
childquals = lappend (childquals , new_clause );
347
349
}
348
-
349
- childquals = (List * ) adjust_appendrel_attrs (root ,
350
- (Node * ) childquals ,
351
- appinfo );
352
- childquals = make_restrictinfos_from_actual_clauses (root , childquals );
353
- child_rel -> baserestrictinfo = childquals ;
354
350
}
355
351
/* If it's the parent table, copy all restrictions */
356
- else
352
+ else childquals = get_all_actual_clauses (parent_rel -> baserestrictinfo );
353
+
354
+ /* Now it's time to change varnos and rebuld quals */
355
+ childquals = (List * ) adjust_appendrel_attrs (root ,
356
+ (Node * ) childquals ,
357
+ appinfo );
358
+ childqual = eval_const_expressions (root , (Node * )
359
+ make_ands_explicit (childquals ));
360
+ if (childqual && IsA (childqual , Const ) &&
361
+ (((Const * ) childqual )-> constisnull ||
362
+ !DatumGetBool (((Const * ) childqual )-> constvalue )))
357
363
{
358
- List * childquals = NIL ;
359
-
360
- childquals = get_all_actual_clauses (parent_rel -> baserestrictinfo );
361
- childquals = (List * ) adjust_appendrel_attrs (root ,
362
- (Node * ) childquals ,
363
- appinfo );
364
- childquals = make_restrictinfos_from_actual_clauses (root , childquals );
365
- child_rel -> baserestrictinfo = childquals ;
364
+ /*
365
+ * Restriction reduces to constant FALSE or constant NULL after
366
+ * substitution, so this child need not be scanned.
367
+ */
368
+ set_dummy_rel_pathlist (child_rel );
369
+ }
370
+ childquals = make_ands_implicit ((Expr * ) childqual );
371
+ childquals = make_restrictinfos_from_actual_clauses (root , childquals );
372
+
373
+ /* Set new shiny childquals */
374
+ child_rel -> baserestrictinfo = childquals ;
375
+
376
+ if (relation_excluded_by_constraints (root , child_rel , child_rte ))
377
+ {
378
+ /*
379
+ * This child need not be scanned, so we can omit it from the
380
+ * appendrel.
381
+ */
382
+ set_dummy_rel_pathlist (child_rel );
366
383
}
367
384
368
385
/*
@@ -373,9 +390,6 @@ append_child_relation(PlannerInfo *root, Relation parent_relation,
373
390
add_child_rel_equivalences (root , appinfo , parent_rel , child_rel );
374
391
child_rel -> has_eclass_joins = parent_rel -> has_eclass_joins ;
375
392
376
- /* Recalc parent relation tuples count */
377
- parent_rel -> tuples += child_rel -> tuples ;
378
-
379
393
/* Close child relations, but keep locks */
380
394
heap_close (child_relation , NoLock );
381
395
@@ -1666,8 +1680,8 @@ set_plain_rel_size(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte)
1666
1680
static void
1667
1681
set_plain_rel_pathlist (PlannerInfo * root , RelOptInfo * rel , RangeTblEntry * rte )
1668
1682
{
1669
- Relids required_outer ;
1670
- Path * path ;
1683
+ Relids required_outer ;
1684
+ Path * path ;
1671
1685
1672
1686
/*
1673
1687
* We don't support pushing join clauses into the quals of a seqscan, but
@@ -1753,11 +1767,11 @@ set_append_rel_pathlist(PlannerInfo *root, RelOptInfo *rel, Index rti,
1753
1767
*/
1754
1768
foreach (l , root -> append_rel_list )
1755
1769
{
1756
- AppendRelInfo * appinfo = (AppendRelInfo * ) lfirst (l );
1757
- Index childRTindex ;
1758
- RangeTblEntry * childRTE ;
1759
- RelOptInfo * childrel ;
1760
- ListCell * lcp ;
1770
+ AppendRelInfo * appinfo = (AppendRelInfo * ) lfirst (l );
1771
+ Index childRTindex ;
1772
+ RangeTblEntry * childRTE ;
1773
+ RelOptInfo * childrel ;
1774
+ ListCell * lcp ;
1761
1775
1762
1776
/* append_rel_list contains all append rels; ignore others */
1763
1777
if (appinfo -> parent_relid != parentRTindex )
@@ -1780,24 +1794,34 @@ set_append_rel_pathlist(PlannerInfo *root, RelOptInfo *rel, Index rti,
1780
1794
set_rel_consider_parallel_compat (root , childrel , childRTE );
1781
1795
#endif
1782
1796
1783
- /*
1784
- * Compute the child's access paths.
1785
- */
1797
+ /* Compute child's access paths & sizes */
1786
1798
if (childRTE -> relkind == RELKIND_FOREIGN_TABLE )
1787
1799
{
1800
+ /* childrel->rows should be >= 1 */
1788
1801
set_foreign_size (root , childrel , childRTE );
1802
+
1803
+ /* If child IS dummy, ignore it */
1804
+ if (IS_DUMMY_REL (childrel ))
1805
+ continue ;
1806
+
1789
1807
set_foreign_pathlist (root , childrel , childRTE );
1790
1808
}
1791
1809
else
1792
1810
{
1811
+ /* childrel->rows should be >= 1 */
1793
1812
set_plain_rel_size (root , childrel , childRTE );
1813
+
1814
+ /* If child IS dummy, ignore it */
1815
+ if (IS_DUMMY_REL (childrel ))
1816
+ continue ;
1817
+
1794
1818
set_plain_rel_pathlist (root , childrel , childRTE );
1795
1819
}
1820
+
1821
+ /* Set cheapest path for child */
1796
1822
set_cheapest (childrel );
1797
1823
1798
- /*
1799
- * If child is dummy, ignore it.
1800
- */
1824
+ /* If child BECAME dummy, ignore it */
1801
1825
if (IS_DUMMY_REL (childrel ))
1802
1826
continue ;
1803
1827
0 commit comments