Skip to content

Commit 071ab32

Browse files
committed
fixes and improvements in append_child_relation() & set_append_rel_pathlist(), add missing set_dummy_rel_pathlist() for PG 9.5
1 parent 2e6d2f8 commit 071ab32

File tree

4 files changed

+102
-36
lines changed

4 files changed

+102
-36
lines changed

src/hooks.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ pathman_rel_pathlist_hook(PlannerInfo *root,
218218
/* Proceed iff relation 'rel' is partitioned */
219219
if ((prel = get_pathman_relation_info(rte->relid)) != NULL)
220220
{
221-
Relation parent_rel; /* parent's relation (heap */
221+
Relation parent_rel; /* parent's relation (heap) */
222222
Oid *children; /* selected children oids */
223223
List *ranges, /* a list of IndexRanges */
224224
*wrappers, /* a list of WrapperNodes */

src/pg_compat.c

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,9 @@ set_append_rel_size_compat(PlannerInfo *root, RelOptInfo *rel, Index rti)
5858
#endif
5959
}
6060

61+
/* Set 'rows' for append relation */
6162
rel->rows = parent_rows;
63+
6264
#if PG_VERSION_NUM >= 90600
6365
rel->reltarget->width = rint(parent_size / parent_rows);
6466
#else
@@ -314,4 +316,37 @@ create_plain_partial_paths(PlannerInfo *root, RelOptInfo *rel)
314316
/* Add an unordered partial path based on a parallel sequential scan. */
315317
add_partial_path(rel, create_seqscan_path(root, rel, NULL, parallel_workers));
316318
}
317-
#endif
319+
320+
321+
#else /* PG_VERSION_NUM >= 90500 */
322+
323+
/*
324+
* set_dummy_rel_pathlist
325+
* Build a dummy path for a relation that's been excluded by constraints
326+
*
327+
* Rather than inventing a special "dummy" path type, we represent this as an
328+
* AppendPath with no members (see also IS_DUMMY_PATH/IS_DUMMY_REL macros).
329+
*/
330+
void
331+
set_dummy_rel_pathlist(RelOptInfo *rel)
332+
{
333+
/* Set dummy size estimates --- we leave attr_widths[] as zeroes */
334+
rel->rows = 0;
335+
rel->width = 0;
336+
337+
/* Discard any pre-existing paths; no further need for them */
338+
rel->pathlist = NIL;
339+
340+
add_path(rel, (Path *) create_append_path(rel, NIL, NULL));
341+
342+
/*
343+
* We set the cheapest path immediately, to ensure that IS_DUMMY_REL()
344+
* will recognize the relation as dummy if anyone asks. This is redundant
345+
* when we're called from set_rel_size(), but not when called from
346+
* elsewhere, and doing it twice is harmless anyway.
347+
*/
348+
set_cheapest(rel);
349+
}
350+
351+
352+
#endif /* PG_VERSION_NUM >= 90600 */

src/pg_compat.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,10 @@ void set_append_rel_size_compat(PlannerInfo *root, RelOptInfo *rel, Index rti);
2323
void adjust_targetlist_compat(PlannerInfo *root, RelOptInfo *dest,
2424
RelOptInfo *rel, AppendRelInfo *appinfo);
2525

26+
2627
#if PG_VERSION_NUM >= 90600
2728

29+
2830
#define get_parameterized_joinrel_size_compat(root, rel, outer_path, \
2931
inner_path, sjinfo, \
3032
restrict_clauses) \
@@ -54,8 +56,10 @@ extern Result *make_result(List *tlist, Node *resconstantqual, Plan *subplan);
5456
#define make_result_compat(root, tlist, resconstantqual, subplan) \
5557
make_result(tlist, resconstantqual, subplan)
5658

59+
5760
#else /* PG_VERSION_NUM >= 90500 */
5861

62+
5963
#define get_parameterized_joinrel_size_compat(root, rel, \
6064
outer_path, \
6165
inner_path, \
@@ -81,7 +85,10 @@ extern Result *make_result(List *tlist, Node *resconstantqual, Plan *subplan);
8185

8286
#define create_plain_partial_paths_compat(root, rel) ((void) true)
8387

84-
#endif
88+
void set_dummy_rel_pathlist(RelOptInfo *rel);
89+
90+
91+
#endif /* PG_VERSION_NUM */
8592

8693

8794
#endif /* PG_COMPAT_H */

src/pg_pathman.c

Lines changed: 57 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include "fmgr.h"
3434
#include "miscadmin.h"
3535
#include "optimizer/clauses.h"
36+
#include "optimizer/plancat.h"
3637
#include "optimizer/prep.h"
3738
#include "optimizer/restrictinfo.h"
3839
#include "optimizer/cost.h"
@@ -276,6 +277,8 @@ append_child_relation(PlannerInfo *root, Relation parent_relation,
276277
Index childRTindex;
277278
PlanRowMark *parent_rowmark,
278279
*child_rowmark;
280+
Node *childqual;
281+
List *childquals;
279282
ListCell *lc,
280283
*lc2;
281284

@@ -323,10 +326,9 @@ append_child_relation(PlannerInfo *root, Relation parent_relation,
323326
* Copy restrictions. If it's not the parent table, copy only
324327
* those restrictions that are related to this partition.
325328
*/
326-
child_rel->baserestrictinfo = NIL;
327329
if (parent_rte->relid != child_oid)
328330
{
329-
List *childquals = NIL;
331+
childquals = NIL;
330332

331333
forboth(lc, wrappers, lc2, parent_rel->baserestrictinfo)
332334
{
@@ -345,24 +347,39 @@ append_child_relation(PlannerInfo *root, Relation parent_relation,
345347
Assert(new_clause);
346348
childquals = lappend(childquals, new_clause);
347349
}
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;
354350
}
355351
/* 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)))
357363
{
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);
366383
}
367384

368385
/*
@@ -373,9 +390,6 @@ append_child_relation(PlannerInfo *root, Relation parent_relation,
373390
add_child_rel_equivalences(root, appinfo, parent_rel, child_rel);
374391
child_rel->has_eclass_joins = parent_rel->has_eclass_joins;
375392

376-
/* Recalc parent relation tuples count */
377-
parent_rel->tuples += child_rel->tuples;
378-
379393
/* Close child relations, but keep locks */
380394
heap_close(child_relation, NoLock);
381395

@@ -1666,8 +1680,8 @@ set_plain_rel_size(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte)
16661680
static void
16671681
set_plain_rel_pathlist(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte)
16681682
{
1669-
Relids required_outer;
1670-
Path *path;
1683+
Relids required_outer;
1684+
Path *path;
16711685

16721686
/*
16731687
* 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,
17531767
*/
17541768
foreach(l, root->append_rel_list)
17551769
{
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;
17611775

17621776
/* append_rel_list contains all append rels; ignore others */
17631777
if (appinfo->parent_relid != parentRTindex)
@@ -1780,24 +1794,34 @@ set_append_rel_pathlist(PlannerInfo *root, RelOptInfo *rel, Index rti,
17801794
set_rel_consider_parallel_compat(root, childrel, childRTE);
17811795
#endif
17821796

1783-
/*
1784-
* Compute the child's access paths.
1785-
*/
1797+
/* Compute child's access paths & sizes */
17861798
if (childRTE->relkind == RELKIND_FOREIGN_TABLE)
17871799
{
1800+
/* childrel->rows should be >= 1 */
17881801
set_foreign_size(root, childrel, childRTE);
1802+
1803+
/* If child IS dummy, ignore it */
1804+
if (IS_DUMMY_REL(childrel))
1805+
continue;
1806+
17891807
set_foreign_pathlist(root, childrel, childRTE);
17901808
}
17911809
else
17921810
{
1811+
/* childrel->rows should be >= 1 */
17931812
set_plain_rel_size(root, childrel, childRTE);
1813+
1814+
/* If child IS dummy, ignore it */
1815+
if (IS_DUMMY_REL(childrel))
1816+
continue;
1817+
17941818
set_plain_rel_pathlist(root, childrel, childRTE);
17951819
}
1820+
1821+
/* Set cheapest path for child */
17961822
set_cheapest(childrel);
17971823

1798-
/*
1799-
* If child is dummy, ignore it.
1800-
*/
1824+
/* If child BECAME dummy, ignore it */
18011825
if (IS_DUMMY_REL(childrel))
18021826
continue;
18031827

0 commit comments

Comments
 (0)