Avoid creating PlaceHolderVars immediately within PlaceHolderVars.

Such a construction is useless since the lower PlaceHolderVar is already
nullable; no need to make it more so.  Noted while pursuing bug #6154.

This is just a minor planner efficiency improvement, since the final plan
will come out the same anyway after PHVs are flattened.  So not worth the
risk of back-patching.
This commit is contained in:
Tom Lane 2011-08-09 11:33:46 -04:00
parent f4a9da0a15
commit cff60f2dfa

View File

@ -1411,6 +1411,12 @@ pullup_replace_vars_callback(Var *var,
/* Simple Vars always escape being wrapped */ /* Simple Vars always escape being wrapped */
wrap = false; wrap = false;
} }
else if (newnode && IsA(newnode, PlaceHolderVar) &&
((PlaceHolderVar *) newnode)->phlevelsup == 0)
{
/* No need to wrap a PlaceHolderVar with another one, either */
wrap = false;
}
else if (rcon->wrap_non_vars) else if (rcon->wrap_non_vars)
{ {
/* Wrap all non-Vars in a PlaceHolderVar */ /* Wrap all non-Vars in a PlaceHolderVar */
@ -1420,10 +1426,16 @@ pullup_replace_vars_callback(Var *var,
{ {
/* /*
* If it contains a Var of current level, and does not contain * If it contains a Var of current level, and does not contain
* any non-strict constructs, then it's certainly nullable and * any non-strict constructs, then it's certainly nullable so
* we don't need to insert a PlaceHolderVar. (Note: in future * we don't need to insert a PlaceHolderVar.
* maybe we should insert PlaceHolderVars anyway, when a tlist *
* item is expensive to evaluate? * This analysis could be tighter: in particular, a non-strict
* construct hidden within a lower-level PlaceHolderVar is not
* reason to add another PHV. But for now it doesn't seem
* worth the code to be more exact.
*
* Note: in future maybe we should insert a PlaceHolderVar
* anyway, if the tlist item is expensive to evaluate?
*/ */
if (contain_vars_of_level((Node *) newnode, 0) && if (contain_vars_of_level((Node *) newnode, 0) &&
!contain_nonstrict_functions((Node *) newnode)) !contain_nonstrict_functions((Node *) newnode))