summaryrefslogtreecommitdiff
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.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c
index 358bb2aed6f..028d9e16808 100644
--- a/src/backend/optimizer/path/allpaths.c
+++ b/src/backend/optimizer/path/allpaths.c
@@ -2451,6 +2451,7 @@ set_subquery_pathlist(PlannerInfo *root, RelOptInfo *rel,
{
Query *parse = root->parse;
Query *subquery = rte->subquery;
+ bool trivial_pathtarget;
Relids required_outer;
pushdown_safety_info safetyInfo;
double tuple_fraction;
@@ -2614,6 +2615,36 @@ set_subquery_pathlist(PlannerInfo *root, RelOptInfo *rel,
set_subquery_size_estimates(root, rel);
/*
+ * Also detect whether the reltarget is trivial, so that we can pass that
+ * info to cost_subqueryscan (rather than re-deriving it multiple times).
+ * It's trivial if it fetches all the subplan output columns in order.
+ */
+ if (list_length(rel->reltarget->exprs) != list_length(subquery->targetList))
+ trivial_pathtarget = false;
+ else
+ {
+ trivial_pathtarget = true;
+ foreach(lc, rel->reltarget->exprs)
+ {
+ Node *node = (Node *) lfirst(lc);
+ Var *var;
+
+ if (!IsA(node, Var))
+ {
+ trivial_pathtarget = false;
+ break;
+ }
+ var = (Var *) node;
+ if (var->varno != rti ||
+ var->varattno != foreach_current_index(lc) + 1)
+ {
+ trivial_pathtarget = false;
+ break;
+ }
+ }
+ }
+
+ /*
* For each Path that subquery_planner produced, make a SubqueryScanPath
* in the outer query.
*/
@@ -2631,6 +2662,7 @@ set_subquery_pathlist(PlannerInfo *root, RelOptInfo *rel,
/* Generate outer path using this subpath */
add_path(rel, (Path *)
create_subqueryscan_path(root, rel, subpath,
+ trivial_pathtarget,
pathkeys, required_outer));
}
@@ -2656,6 +2688,7 @@ set_subquery_pathlist(PlannerInfo *root, RelOptInfo *rel,
/* Generate outer path using this subpath */
add_partial_path(rel, (Path *)
create_subqueryscan_path(root, rel, subpath,
+ trivial_pathtarget,
pathkeys,
required_outer));
}