Improve ruleutils' printout of LATERAL references within subplans.

Commit 1cc29fe7c, which taught EXPLAIN to print PARAM_EXEC Params as
the referenced expressions, included some checks to prevent matching
Params found in SubPlans or InitPlans to NestLoopParams of upper query
levels.  At the time, this seemed possibly necessary to avoid false
matches because of the planner's habit of re-using the same PARAM_EXEC
slot in multiple places in a plan.  Furthermore, in the absence of
LATERAL no such reference could be valid anyway.  But it's possible
now that we have LATERAL, and in the wake of 46c508fbc and 1db5667ba
I believe the false-match hazard is gone.  Hence, remove the
in_same_plan_level checks.  As shown in the regression test changes,
this provides a useful improvement in readability for EXPLAIN of
LATERAL-using subplans.

Richard Guo, reviewed by Greg Stark and myself

Discussion: https://postgr.es/m/CAMbWs4-YSOcQXAagJetP95cAeZPqzOy5kM5yijG0PVW5ztRb4w@mail.gmail.com
This commit is contained in:
Tom Lane 2022-11-16 20:06:09 -05:00
parent 5db195f76f
commit adaf34241a
3 changed files with 9 additions and 34 deletions

View File

@ -7896,12 +7896,10 @@ find_param_referent(Param *param, deparse_context *context,
{
deparse_namespace *dpns;
Plan *child_plan;
bool in_same_plan_level;
ListCell *lc;
dpns = (deparse_namespace *) linitial(context->namespaces);
child_plan = dpns->plan;
in_same_plan_level = true;
foreach(lc, dpns->ancestors)
{
@ -7909,13 +7907,10 @@ find_param_referent(Param *param, deparse_context *context,
ListCell *lc2;
/*
* NestLoops transmit params to their inner child only; also, once
* we've crawled up out of a subplan, this couldn't possibly be
* the right match.
* NestLoops transmit params to their inner child only.
*/
if (IsA(ancestor, NestLoop) &&
child_plan == innerPlan(ancestor) &&
in_same_plan_level)
child_plan == innerPlan(ancestor))
{
NestLoop *nl = (NestLoop *) ancestor;
@ -7973,34 +7968,14 @@ find_param_referent(Param *param, deparse_context *context,
}
}
/* We have emerged from a subplan. */
in_same_plan_level = false;
/* SubPlan isn't a kind of Plan, so skip the rest */
continue;
}
/*
* Check to see if we're emerging from an initplan of the current
* ancestor plan. Initplans never have any parParams, so no need
* to search that list, but we need to know if we should reset
* in_same_plan_level.
* We need not consider the ancestor's initPlan list, since
* initplans never have any parParams.
*/
foreach(lc2, ((Plan *) ancestor)->initPlan)
{
SubPlan *subplan = lfirst_node(SubPlan, lc2);
if (child_plan != (Plan *) list_nth(dpns->subplans,
subplan->plan_id - 1))
continue;
/* No parameters to be had here. */
Assert(subplan->parParam == NIL);
/* We have emerged from an initplan. */
in_same_plan_level = false;
break;
}
/* No luck, crawl up to next ancestor */
child_plan = (Plan *) ancestor;

View File

@ -6074,8 +6074,8 @@ lateral (select * from int8_tbl t1,
where q2 = (select greatest(t1.q1,t2.q2))
and (select v.id=0)) offset 0) ss2) ss
where t1.q1 = ss.q2) ss0;
QUERY PLAN
-----------------------------------------------------------------
QUERY PLAN
----------------------------------------------------------------------
Nested Loop
Output: "*VALUES*".column1, t1.q1, t1.q2, ss2.q1, ss2.q2
-> Seq Scan on public.int8_tbl t1
@ -6096,10 +6096,10 @@ lateral (select * from int8_tbl t1,
One-Time Filter: $4
InitPlan 1 (returns $2)
-> Result
Output: GREATEST($0, t2.q2)
Output: GREATEST(t1.q1, t2.q2)
InitPlan 2 (returns $4)
-> Result
Output: ($3 = 0)
Output: ("*VALUES*".column1 = 0)
-> Seq Scan on public.int8_tbl t3
Output: t3.q1, t3.q2
Filter: (t3.q2 = $2)

View File

@ -1155,7 +1155,7 @@ where o.ten = 0;
SubPlan 1
-> Seq Scan on public.int4_tbl
Output: int4_tbl.f1
Filter: (int4_tbl.f1 <= $0)
Filter: (int4_tbl.f1 <= o.hundred)
(14 rows)
select sum(ss.tst::int) from