Обсуждение: Apparent bug in _make_subplan
I have been looking at the planner's handling of subplans, and I see
something that I think is wrong, but I'm not quite certain. In
_make_subplan() in backend/optimizer/plan/subselect.c, there is the
code
/* make parParam list */ foreach(lst, plan->extParam) { Var *var = nth(lfirsti(lst),
PlannerParamVar);
if (var->varlevelsup == PlannerQueryLevel) node->parParam = lappendi(node->parParam, lfirsti(lst));
}
It looks to me like this code is supposed to find parameters that
reference the immediate parent plan level, as opposed to higher levels.
So, shouldn't it be looking for varlevelsup == 1, not PlannerQueryLevel?
For a first-level subplan, PlannerQueryLevel will be 1 at the time
this code runs, so the result is the same anyway. But I think it
does the wrong thing for more deeply nested subplans. Am I right?
regards, tom lane
Tom Lane wrote:
>
> /* make parParam list */
> foreach(lst, plan->extParam)
> {
> Var *var = nth(lfirsti(lst), PlannerParamVar);
>
> if (var->varlevelsup == PlannerQueryLevel)
> node->parParam = lappendi(node->parParam, lfirsti(lst));
> }
>
> It looks to me like this code is supposed to find parameters that
> reference the immediate parent plan level, as opposed to higher levels.
> So, shouldn't it be looking for varlevelsup == 1, not PlannerQueryLevel?
>
> For a first-level subplan, PlannerQueryLevel will be 1 at the time
> this code runs, so the result is the same anyway. But I think it
PlannerQueryLevel will be 0 here - subselect.c:140
/* and now we are parent again */ PlannerInitPlan = saved_ip; PlannerQueryLevel--;
> does the wrong thing for more deeply nested subplans. Am I right?
I'm not sure. Seems that I made assumption here that
varlevelsup is _absolute_ level number and seems that
_replace_var() and _new_param() replace parser' varlevelsup
with absolute level value.
Vadim
Vadim Mikheev <vadim@krs.ru> writes:
>> For a first-level subplan, PlannerQueryLevel will be 1 at the time
>> this code runs, so the result is the same anyway. But I think it
> PlannerQueryLevel will be 0 here - subselect.c:140
No, it's never 0. It starts out 1 in planner(), and _make_subplan
increments it at line 116 before recursing, then decrements again at
line 142. So it's at least one when we arrive at the parParam code.
> I'm not sure. Seems that I made assumption here that
> varlevelsup is _absolute_ level number and seems that
> _replace_var() and _new_param() replace parser' varlevelsup
> with absolute level value.
After looking through all the references to varlevelsup, it's clear
that all pieces of the system *except* subselect.c treat varlevelsup
as a relative level number, so-many-levels-out-from-current-subplan.
subselect.c has a couple of places that think nonzero varlevelsup
is an absolute level number, with 1 as the top plan. This is certainly
a source of bugs --- it happens to work for two-level plans, but will
fail for anything more deeply nested. I will work on fixing subselect.c
to bring it in line with the rest of the world...
regards, tom lane
> After looking through all the references to varlevelsup, it's clear > that all pieces of the system *except* subselect.c treat varlevelsup > as a relative level number, so-many-levels-out-from-current-subplan. > subselect.c has a couple of places that think nonzero varlevelsup > is an absolute level number, with 1 as the top plan. This is certainly > a source of bugs --- it happens to work for two-level plans, but will > fail for anything more deeply nested. I will work on fixing subselect.c > to bring it in line with the rest of the world... varlevelsup was always intended to be relative. -- Bruce Momjian | http://www.op.net/~candle maillist@candle.pha.pa.us | (610) 853-3000+ If your life is a hard drive, | 830 Blythe Avenue + Christ can be your backup. | Drexel Hill, Pennsylvania19026
Tom Lane wrote: > > > I'm not sure. Seems that I made assumption here that > > varlevelsup is _absolute_ level number and seems that > > _replace_var() and _new_param() replace parser' varlevelsup > > with absolute level value. > > After looking through all the references to varlevelsup, it's clear > that all pieces of the system *except* subselect.c treat varlevelsup > as a relative level number, so-many-levels-out-from-current-subplan. > subselect.c has a couple of places that think nonzero varlevelsup > is an absolute level number, with 1 as the top plan. This is certainly > a source of bugs --- it happens to work for two-level plans, but will > fail for anything more deeply nested. I will work on fixing subselect.c > to bring it in line with the rest of the world... subselect.c uses varlevelsup as absolute level number only for correlation vars <--> params mapping, so why should it be source of bugs? SS_replace_correlation_vars replaces all correlation vars with parameters. Vars with absolute varlevelsup are in PlannerParamVar only. To identify correlation vars and to know is parameter already assigned to a var we obviously need in absolute level number. Vadim
> subselect.c uses varlevelsup as absolute level number only > for correlation vars <--> params mapping, so why should it be > source of bugs? SS_replace_correlation_vars replaces all > correlation vars with parameters. Vars with absolute varlevelsup > are in PlannerParamVar only. To identify correlation vars and > to know is parameter already assigned to a var we obviously > need in absolute level number. But the varlevelsup I pass in from the parser are relative to the current level, not absolute. -- Bruce Momjian | http://www.op.net/~candle maillist@candle.pha.pa.us | (610) 853-3000+ If your life is a hard drive, | 830 Blythe Avenue + Christ can be your backup. | Drexel Hill, Pennsylvania19026
Bruce Momjian wrote: > > > subselect.c uses varlevelsup as absolute level number only > > for correlation vars <--> params mapping, so why should it be > > source of bugs? SS_replace_correlation_vars replaces all > > correlation vars with parameters. Vars with absolute varlevelsup > > are in PlannerParamVar only. To identify correlation vars and > > to know is parameter already assigned to a var we obviously > > need in absolute level number. > > But the varlevelsup I pass in from the parser are relative to the > current level, not absolute. subselect.c takes it into account, computes absolute numbers and stores them in PlannerParamVar only... Vadim
Vadim Mikheev <vadim@krs.ru> writes:
>> But the varlevelsup I pass in from the parser are relative to the
>> current level, not absolute.
> subselect.c takes it into account, computes absolute numbers
> and stores them in PlannerParamVar only...
Right, I eventually figured that out, and I see that it's probably the
best way. I have added the following documentation to subselect.c:
/*--------------------* PlannerParamVar is a list of Var nodes, wherein the n'th entry* (n counts from 0) corresponds
toParam->paramid = n. The Var nodes* are ordinary except for one thing: their varlevelsup field does NOT* have the
usualinterpretation of "subplan levels out from current".* Instead, it contains the absolute plan level, with the
outermost*plan being level 1 and nested plans having higher level numbers.* This nonstandardness is useful because we
don'thave to run around* and update the list elements when we enter or exit a subplan* recursion level. But we must
payattention not to confuse this* meaning with the normal meaning of varlevelsup.*--------------------*/
along with other changes that I will commit once I get subselects in
HAVING working right ...
regards, tom lane
> Bruce Momjian wrote: > > > > > subselect.c uses varlevelsup as absolute level number only > > > for correlation vars <--> params mapping, so why should it be > > > source of bugs? SS_replace_correlation_vars replaces all > > > correlation vars with parameters. Vars with absolute varlevelsup > > > are in PlannerParamVar only. To identify correlation vars and > > > to know is parameter already assigned to a var we obviously > > > need in absolute level number. > > > > But the varlevelsup I pass in from the parser are relative to the > > current level, not absolute. > > subselect.c takes it into account, computes absolute numbers > and stores them in PlannerParamVar only... Oh. -- Bruce Momjian | http://www.op.net/~candle maillist@candle.pha.pa.us | (610) 853-3000+ If your life is a hard drive, | 830 Blythe Avenue + Christ can be your backup. | Drexel Hill, Pennsylvania19026