diff options
Diffstat (limited to 'src/backend/optimizer/path/costsize.c')
-rw-r--r-- | src/backend/optimizer/path/costsize.c | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/src/backend/optimizer/path/costsize.c b/src/backend/optimizer/path/costsize.c index 5e5732f6e12..fb28e6411aa 100644 --- a/src/backend/optimizer/path/costsize.c +++ b/src/backend/optimizer/path/costsize.c @@ -1415,10 +1415,12 @@ cost_tidrangescan(Path *path, PlannerInfo *root, * * 'baserel' is the relation to be scanned * 'param_info' is the ParamPathInfo if this is a parameterized path, else NULL + * 'trivial_pathtarget' is true if the pathtarget is believed to be trivial. */ void cost_subqueryscan(SubqueryScanPath *path, PlannerInfo *root, - RelOptInfo *baserel, ParamPathInfo *param_info) + RelOptInfo *baserel, ParamPathInfo *param_info, + bool trivial_pathtarget) { Cost startup_cost; Cost run_cost; @@ -1458,6 +1460,22 @@ cost_subqueryscan(SubqueryScanPath *path, PlannerInfo *root, path->path.startup_cost = path->subpath->startup_cost; path->path.total_cost = path->subpath->total_cost; + /* + * However, if there are no relevant restriction clauses and the + * pathtarget is trivial, then we expect that setrefs.c will optimize away + * the SubqueryScan plan node altogether, so we should just make its cost + * and rowcount equal to the input path's. + * + * Note: there are some edge cases where createplan.c will apply a + * different targetlist to the SubqueryScan node, thus falsifying our + * current estimate of whether the target is trivial, and making the cost + * estimate (though not the rowcount) wrong. It does not seem worth the + * extra complication to try to account for that exactly, especially since + * that behavior falsifies other cost estimates as well. + */ + if (qpquals == NIL && trivial_pathtarget) + return; + get_restriction_qual_cost(root, baserel, param_info, &qpqual_cost); startup_cost = qpqual_cost.startup; |