fix_srf-v3.diff
text/x-patch
Filename: fix_srf-v3.diff
Type: text/x-patch
Part: 0
Patch
Format: unified
Series: patch v3
| File | + | − |
|---|---|---|
| src/backend/optimizer/plan/planner.c | 112 | 116 |
diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c
index 647baa3cf6..ec4a8fb9cc 100644
--- a/src/backend/optimizer/plan/planner.c
+++ b/src/backend/optimizer/plan/planner.c
@@ -6969,139 +6969,135 @@ apply_scanjoin_target_to_paths(PlannerInfo *root,
rel->nparts = 0;
rel->part_rels = NULL;
rel->boundinfo = NULL;
-
- /* Now fix things up if scan/join target contains SRFs */
- if (root->parse->hasTargetSRFs)
- adjust_paths_for_srfs(root, rel,
- scanjoin_targets,
- scanjoin_targets_contain_srfs);
-
- return;
}
-
- /*
- * Adjust each input path. If the tlist exprs are the same, we can just
- * inject the sortgroupref information into the existing pathtarget.
- * Otherwise, replace each path with a projection path that generates the
- * SRF-free scan/join target. This can't change the ordering of paths
- * within rel->pathlist, so we just modify the list in place.
- */
- foreach(lc, rel->pathlist)
+ else
{
- Path *subpath = (Path *) lfirst(lc);
- Path *newpath;
-
- Assert(subpath->param_info == NULL);
-
- if (tlist_same_exprs)
- subpath->pathtarget->sortgrouprefs =
- scanjoin_target->sortgrouprefs;
- else
+ /*
+ * Adjust each input path. If the tlist exprs are the same, we can
+ * just inject the sortgroupref information into the existing
+ * pathtarget. Otherwise, replace each path with a projection path
+ * that generates the SRF-free scan/join target. This can't change the
+ * ordering of paths within rel->pathlist, so we just modify the list
+ * in place.
+ */
+ foreach(lc, rel->pathlist)
{
- newpath = (Path *) create_projection_path(root, rel, subpath,
- scanjoin_target);
- lfirst(lc) = newpath;
- }
- }
+ Path *subpath = (Path *) lfirst(lc);
+ Path *newpath;
- /* Same for partial paths. */
- foreach(lc, rel->partial_pathlist)
- {
- Path *subpath = (Path *) lfirst(lc);
- Path *newpath;
+ Assert(subpath->param_info == NULL);
- /* Shouldn't have any parameterized paths anymore */
- Assert(subpath->param_info == NULL);
+ if (tlist_same_exprs)
+ subpath->pathtarget->sortgrouprefs =
+ scanjoin_target->sortgrouprefs;
+ else
+ {
+ newpath = (Path *) create_projection_path(root, rel, subpath,
+ scanjoin_target);
+ lfirst(lc) = newpath;
+ }
+ }
- if (tlist_same_exprs)
- subpath->pathtarget->sortgrouprefs =
- scanjoin_target->sortgrouprefs;
- else
+ /* Same for partial paths. */
+ foreach(lc, rel->partial_pathlist)
{
- newpath = (Path *) create_projection_path(root,
- rel,
- subpath,
- scanjoin_target);
- lfirst(lc) = newpath;
- }
- }
+ Path *subpath = (Path *) lfirst(lc);
+ Path *newpath;
- /* Now fix things up if scan/join target contains SRFs */
- if (root->parse->hasTargetSRFs)
- adjust_paths_for_srfs(root, rel,
- scanjoin_targets,
- scanjoin_targets_contain_srfs);
+ /* Shouldn't have any parameterized paths anymore */
+ Assert(subpath->param_info == NULL);
- /*
- * If the relation is partitioned, recursively apply the same changes to
- * all partitions and generate new Append paths. Since Append is not
- * projection-capable, that might save a separate Result node, and it also
- * is important for partitionwise aggregate.
- */
- if (rel->part_scheme && rel->part_rels)
- {
- int partition_idx;
- List *live_children = NIL;
+ if (tlist_same_exprs)
+ subpath->pathtarget->sortgrouprefs =
+ scanjoin_target->sortgrouprefs;
+ else
+ {
+ newpath = (Path *) create_projection_path(root,
+ rel,
+ subpath,
+ scanjoin_target);
+ lfirst(lc) = newpath;
+ }
+ }
- /* Adjust each partition. */
- for (partition_idx = 0; partition_idx < rel->nparts; partition_idx++)
+ /*
+ * If the relation is partitioned, recursively apply the same changes
+ * to all partitions and generate new Append paths. Since Append is
+ * not projection-capable, that might save a separate Result node, and
+ * it also is important for partitionwise aggregate.
+ */
+ if (rel->part_scheme && rel->part_rels)
{
- RelOptInfo *child_rel = rel->part_rels[partition_idx];
- ListCell *lc;
- AppendRelInfo **appinfos;
- int nappinfos;
- List *child_scanjoin_targets = NIL;
-
- /* Translate scan/join targets for this child. */
- appinfos = find_appinfos_by_relids(root, child_rel->relids,
- &nappinfos);
- foreach(lc, scanjoin_targets)
+ int part_idx;
+ List *live_children = NIL;
+
+ /* Adjust each partition. */
+ for (part_idx = 0; part_idx < rel->nparts; part_idx++)
{
- PathTarget *target = lfirst_node(PathTarget, lc);
-
- target = copy_pathtarget(target);
- target->exprs = (List *)
- adjust_appendrel_attrs(root,
- (Node *) target->exprs,
- nappinfos, appinfos);
- child_scanjoin_targets = lappend(child_scanjoin_targets,
- target);
+ RelOptInfo *child_rel = rel->part_rels[part_idx];
+ ListCell *lc;
+ AppendRelInfo **appinfos;
+ int nappinfos;
+ List *child_scanjoin_targets = NIL;
+
+ /* Translate scan/join targets for this child. */
+ appinfos = find_appinfos_by_relids(root, child_rel->relids,
+ &nappinfos);
+ foreach(lc, scanjoin_targets)
+ {
+ PathTarget *target = lfirst_node(PathTarget, lc);
+
+ target = copy_pathtarget(target);
+ target->exprs = (List *)
+ adjust_appendrel_attrs(root,
+ (Node *) target->exprs,
+ nappinfos, appinfos);
+ child_scanjoin_targets = lappend(child_scanjoin_targets,
+ target);
+ }
+ pfree(appinfos);
+
+ /* Recursion does the real work. */
+ apply_scanjoin_target_to_paths(root, child_rel,
+ child_scanjoin_targets,
+ scanjoin_targets_contain_srfs,
+ scanjoin_target_parallel_safe,
+ tlist_same_exprs);
+
+ /* Save non-dummy children for Append paths. */
+ if (!IS_DUMMY_REL(child_rel))
+ live_children = lappend(live_children, child_rel);
}
- pfree(appinfos);
-
- /* Recursion does the real work. */
- apply_scanjoin_target_to_paths(root, child_rel,
- child_scanjoin_targets,
- scanjoin_targets_contain_srfs,
- scanjoin_target_parallel_safe,
- tlist_same_exprs);
-
- /* Save non-dummy children for Append paths. */
- if (!IS_DUMMY_REL(child_rel))
- live_children = lappend(live_children, child_rel);
+
+ /* Build new paths for this relation by appending child paths. */
+ if (live_children != NIL)
+ add_paths_to_append_rel(root, rel, live_children);
}
- /* Build new paths for this relation by appending child paths. */
- if (live_children != NIL)
- add_paths_to_append_rel(root, rel, live_children);
- }
+ /*
+ * Consider generating Gather or Gather Merge paths. We must only do
+ * this if the relation is parallel safe, and we don't do it for child
+ * rels to avoid creating multiple Gather nodes within the same plan.
+ * We must do this after all paths have been generated and before
+ * set_cheapest, since one of the generated paths may turn out to be
+ * the cheapest one.
+ */
+ if (rel->consider_parallel && !IS_OTHER_REL(rel))
+ generate_gather_paths(root, rel, false);
- /*
- * Consider generating Gather or Gather Merge paths. We must only do this
- * if the relation is parallel safe, and we don't do it for child rels to
- * avoid creating multiple Gather nodes within the same plan. We must do
- * this after all paths have been generated and before set_cheapest, since
- * one of the generated paths may turn out to be the cheapest one.
- */
- if (rel->consider_parallel && !IS_OTHER_REL(rel))
- generate_gather_paths(root, rel, false);
+ /*
+ * Reassess which paths are the cheapest, now that we've potentially
+ * added new Gather (or Gather Merge) and/or Append (or MergeAppend)
+ * paths to this relation.
+ */
+ set_cheapest(rel);
+ }
- /*
- * Reassess which paths are the cheapest, now that we've potentially added
- * new Gather (or Gather Merge) and/or Append (or MergeAppend) paths to
- * this relation.
- */
- set_cheapest(rel);
+ /* Now fix things up if scan/join target contains SRFs */
+ if (root->parse->hasTargetSRFs)
+ adjust_paths_for_srfs(root, rel,
+ scanjoin_targets,
+ scanjoin_targets_contain_srfs);
}
/*