aboutsummaryrefslogtreecommitdiff
path: root/src/backend/optimizer/path/allpaths.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer/path/allpaths.c')
-rw-r--r--src/backend/optimizer/path/allpaths.c180
1 files changed, 11 insertions, 169 deletions
diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c
index 3c9d84f665a..727da333388 100644
--- a/src/backend/optimizer/path/allpaths.c
+++ b/src/backend/optimizer/path/allpaths.c
@@ -139,9 +139,6 @@ static void subquery_push_qual(Query *subquery,
static void recurse_push_qual(Node *setOp, Query *topquery,
RangeTblEntry *rte, Index rti, Node *qual);
static void remove_unused_subquery_outputs(Query *subquery, RelOptInfo *rel);
-static bool apply_child_basequals(PlannerInfo *root, RelOptInfo *rel,
- RelOptInfo *childrel,
- RangeTblEntry *childRTE, AppendRelInfo *appinfo);
/*
@@ -396,8 +393,9 @@ set_rel_size(PlannerInfo *root, RelOptInfo *rel,
else if (rte->relkind == RELKIND_PARTITIONED_TABLE)
{
/*
- * A partitioned table without any partitions is marked as
- * a dummy rel.
+ * We could get here if asked to scan a partitioned table
+ * with ONLY. In that case we shouldn't scan any of the
+ * partitions, so mark it as a dummy rel.
*/
set_dummy_rel_pathlist(rel);
}
@@ -946,8 +944,6 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel,
double *parent_attrsizes;
int nattrs;
ListCell *l;
- Relids live_children = NULL;
- bool did_pruning = false;
/* Guard against stack overflow due to overly deep inheritance tree. */
check_stack_depth();
@@ -966,21 +962,6 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel,
rel->partitioned_child_rels = list_make1_int(rti);
/*
- * If the partitioned relation has any baserestrictinfo quals then we
- * attempt to use these quals to prune away partitions that cannot
- * possibly contain any tuples matching these quals. In this case we'll
- * store the relids of all partitions which could possibly contain a
- * matching tuple, and skip anything else in the loop below.
- */
- if (enable_partition_pruning &&
- rte->relkind == RELKIND_PARTITIONED_TABLE &&
- rel->baserestrictinfo != NIL)
- {
- live_children = prune_append_rel_partitions(rel);
- did_pruning = true;
- }
-
- /*
* If this is a partitioned baserel, set the consider_partitionwise_join
* flag; currently, we only consider partitionwise joins with the baserel
* if its targetlist doesn't contain a whole-row Var.
@@ -1034,30 +1015,17 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel,
childrel = find_base_rel(root, childRTindex);
Assert(childrel->reloptkind == RELOPT_OTHER_MEMBER_REL);
- if (did_pruning && !bms_is_member(appinfo->child_relid, live_children))
- {
- /* This partition was pruned; skip it. */
- set_dummy_rel_pathlist(childrel);
+ /* We may have already proven the child to be dummy. */
+ if (IS_DUMMY_REL(childrel))
continue;
- }
/*
* We have to copy the parent's targetlist and quals to the child,
- * with appropriate substitution of variables. If any constant false
- * or NULL clauses turn up, we can disregard the child right away. If
- * not, we can apply constraint exclusion with just the
- * baserestrictinfo quals.
+ * with appropriate substitution of variables. However, the
+ * baserestrictinfo quals were already copied/substituted when the
+ * child RelOptInfo was built. So we don't need any additional setup
+ * before applying constraint exclusion.
*/
- if (!apply_child_basequals(root, rel, childrel, childRTE, appinfo))
- {
- /*
- * Some restriction clause reduced to constant FALSE or NULL after
- * substitution, so this child need not be scanned.
- */
- set_dummy_rel_pathlist(childrel);
- continue;
- }
-
if (relation_excluded_by_constraints(root, childrel, childRTE))
{
/*
@@ -1069,7 +1037,8 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel,
}
/*
- * CE failed, so finish copying/modifying targetlist and join quals.
+ * Constraint exclusion failed, so copy the parent's join quals and
+ * targetlist to the child, with appropriate variable substitutions.
*
* NB: the resulting childrel->reltarget->exprs may contain arbitrary
* expressions, which otherwise would not occur in a rel's targetlist.
@@ -3596,133 +3565,6 @@ generate_partitionwise_join_paths(PlannerInfo *root, RelOptInfo *rel)
list_free(live_children);
}
-/*
- * apply_child_basequals
- * Populate childrel's quals based on rel's quals, translating them using
- * appinfo.
- *
- * If any of the resulting clauses evaluate to false or NULL, we return false
- * and don't apply any quals. Caller can mark the relation as a dummy rel in
- * this case, since it needn't be scanned.
- *
- * If any resulting clauses evaluate to true, they're unnecessary and we don't
- * apply then.
- */
-static bool
-apply_child_basequals(PlannerInfo *root, RelOptInfo *rel,
- RelOptInfo *childrel, RangeTblEntry *childRTE,
- AppendRelInfo *appinfo)
-{
- List *childquals;
- Index cq_min_security;
- ListCell *lc;
-
- /*
- * The child rel's targetlist might contain non-Var expressions, which
- * means that substitution into the quals could produce opportunities for
- * const-simplification, and perhaps even pseudoconstant quals. Therefore,
- * transform each RestrictInfo separately to see if it reduces to a
- * constant or pseudoconstant. (We must process them separately to keep
- * track of the security level of each qual.)
- */
- childquals = NIL;
- cq_min_security = UINT_MAX;
- foreach(lc, rel->baserestrictinfo)
- {
- RestrictInfo *rinfo = (RestrictInfo *) lfirst(lc);
- Node *childqual;
- ListCell *lc2;
-
- Assert(IsA(rinfo, RestrictInfo));
- childqual = adjust_appendrel_attrs(root,
- (Node *) rinfo->clause,
- 1, &appinfo);
- childqual = eval_const_expressions(root, childqual);
- /* check for flat-out constant */
- if (childqual && IsA(childqual, Const))
- {
- if (((Const *) childqual)->constisnull ||
- !DatumGetBool(((Const *) childqual)->constvalue))
- {
- /* Restriction reduces to constant FALSE or NULL */
- return false;
- }
- /* Restriction reduces to constant TRUE, so drop it */
- continue;
- }
- /* might have gotten an AND clause, if so flatten it */
- foreach(lc2, make_ands_implicit((Expr *) childqual))
- {
- Node *onecq = (Node *) lfirst(lc2);
- bool pseudoconstant;
-
- /* check for pseudoconstant (no Vars or volatile functions) */
- pseudoconstant =
- !contain_vars_of_level(onecq, 0) &&
- !contain_volatile_functions(onecq);
- if (pseudoconstant)
- {
- /* tell createplan.c to check for gating quals */
- root->hasPseudoConstantQuals = true;
- }
- /* reconstitute RestrictInfo with appropriate properties */
- childquals = lappend(childquals,
- make_restrictinfo((Expr *) onecq,
- rinfo->is_pushed_down,
- rinfo->outerjoin_delayed,
- pseudoconstant,
- rinfo->security_level,
- NULL, NULL, NULL));
- /* track minimum security level among child quals */
- cq_min_security = Min(cq_min_security, rinfo->security_level);
- }
- }
-
- /*
- * In addition to the quals inherited from the parent, we might have
- * securityQuals associated with this particular child node. (Currently
- * this can only happen in appendrels originating from UNION ALL;
- * inheritance child tables don't have their own securityQuals, see
- * expand_inherited_rtentry().) Pull any such securityQuals up into the
- * baserestrictinfo for the child. This is similar to
- * process_security_barrier_quals() for the parent rel, except that we
- * can't make any general deductions from such quals, since they don't
- * hold for the whole appendrel.
- */
- if (childRTE->securityQuals)
- {
- Index security_level = 0;
-
- foreach(lc, childRTE->securityQuals)
- {
- List *qualset = (List *) lfirst(lc);
- ListCell *lc2;
-
- foreach(lc2, qualset)
- {
- Expr *qual = (Expr *) lfirst(lc2);
-
- /* not likely that we'd see constants here, so no check */
- childquals = lappend(childquals,
- make_restrictinfo(qual,
- true, false, false,
- security_level,
- NULL, NULL, NULL));
- cq_min_security = Min(cq_min_security, security_level);
- }
- security_level++;
- }
- Assert(security_level <= root->qual_security_level);
- }
-
- /*
- * OK, we've got all the baserestrictinfo quals for this child.
- */
- childrel->baserestrictinfo = childquals;
- childrel->baserestrict_min_security = cq_min_security;
-
- return true;
-}
/*****************************************************************************
* DEBUG SUPPORT