diff options
author | Etsuro Fujita <efujita@postgresql.org> | 2022-06-09 19:30:00 +0900 |
---|---|---|
committer | Etsuro Fujita <efujita@postgresql.org> | 2022-06-09 19:30:00 +0900 |
commit | 4a8a5dd7f59cd8dd9969cef1969cb5f7c5124eec (patch) | |
tree | d4e69a83e9f13eb608f5a3b4b49a9079fd0cbf98 | |
parent | e77de23fbb0f4ef27090c144edcfa889bb2a06d5 (diff) | |
download | postgresql-4a8a5dd7f59cd8dd9969cef1969cb5f7c5124eec.tar.gz postgresql-4a8a5dd7f59cd8dd9969cef1969cb5f7c5124eec.zip |
Improve comments for trivial_subqueryscan().
This function can be called from mark_async_capable_plan(), a helper
function for create_append_plan(), before set_subqueryscan_references(),
to determine the triviality of a SubqueryScan that is a child of an
Append plan node, which is done before doing finalize_plan() on the
SubqueryScan (if necessary) and set_plan_references() on the subplan,
unlike when called from set_subqueryscan_references(). The reason why
this is safe wouldn't be that obvious, so add comments explaining this.
Follow-up for commit c2bb02bc2.
Reviewed by Zhihong Yu.
Discussion: https://postgr.es/m/CAPmGK17%2BGiJBthC6va7%2B9n6t75e-M1N0U18YB2G1B%2BE5OdrNTA%40mail.gmail.com
-rw-r--r-- | src/backend/optimizer/plan/setrefs.c | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/src/backend/optimizer/plan/setrefs.c b/src/backend/optimizer/plan/setrefs.c index d95fd898077..9cef92cab24 100644 --- a/src/backend/optimizer/plan/setrefs.c +++ b/src/backend/optimizer/plan/setrefs.c @@ -1349,8 +1349,23 @@ set_subqueryscan_references(PlannerInfo *root, * We can delete it if it has no qual to check and the targetlist just * regurgitates the output of the child plan. * - * This might be called repeatedly on a SubqueryScan node, so we cache the - * result in the SubqueryScan node to avoid repeated computation. + * This can be called from mark_async_capable_plan(), a helper function for + * create_append_plan(), before set_subqueryscan_references(), to determine + * triviality of a SubqueryScan that is a child of an Append node. So we + * cache the result in the SubqueryScan node to avoid repeated computation. + * + * Note: when called from mark_async_capable_plan(), we determine the result + * before running finalize_plan() on the SubqueryScan node (if needed) and + * set_plan_references() on the subplan tree, but this would be safe, because + * 1) finalize_plan() doesn't modify the tlist or quals for the SubqueryScan + * node (or that for any plan node in the subplan tree), and + * 2) set_plan_references() modifies the tlist for every plan node in the + * subplan tree, but keeps const/resjunk columns as const/resjunk ones and + * preserves the length and order of the tlist, and + * 3) set_plan_references() might delete the topmost plan node like an Append + * or MergeAppend from the subplan tree and pull up the child plan node, + * but in that case, the tlist for the child plan node exactly matches the + * parent. */ bool trivial_subqueryscan(SubqueryScan *plan) @@ -1359,7 +1374,7 @@ trivial_subqueryscan(SubqueryScan *plan) ListCell *lp, *lc; - /* We might have detected this already (see mark_async_capable_plan) */ + /* We might have detected this already; in which case reuse the result */ if (plan->scanstatus == SUBQUERY_SCAN_TRIVIAL) return true; if (plan->scanstatus == SUBQUERY_SCAN_NONTRIVIAL) |