196
* Select a PARAM_EXEC number to identify the given PlaceHolderVar.
197
* If the PlaceHolderVar already has a param slot, return that one.
199
* This is just like assign_param_for_var, except for PlaceHolderVars.
202
assign_param_for_placeholdervar(PlannerInfo *root, PlaceHolderVar *phv)
205
PlannerParamItem *pitem;
209
abslevel = root->query_level - phv->phlevelsup;
211
/* If there's already a paramlist entry for this same PHV, just use it */
213
foreach(ppl, root->glob->paramlist)
215
pitem = (PlannerParamItem *) lfirst(ppl);
216
if (pitem->abslevel == abslevel && IsA(pitem->item, PlaceHolderVar))
218
PlaceHolderVar *pphv = (PlaceHolderVar *) pitem->item;
220
/* We assume comparing the PHIDs is sufficient */
221
if (pphv->phid == phv->phid)
227
/* Nope, so make a new one */
228
phv = (PlaceHolderVar *) copyObject(phv);
229
if (phv->phlevelsup != 0)
231
IncrementVarSublevelsUp((Node *) phv, -((int) phv->phlevelsup), 0);
232
Assert(phv->phlevelsup == 0);
235
pitem = makeNode(PlannerParamItem);
236
pitem->item = (Node *) phv;
237
pitem->abslevel = abslevel;
239
root->glob->paramlist = lappend(root->glob->paramlist, pitem);
241
/* i is already the correct list index for the new item */
246
* Generate a Param node to replace the given PlaceHolderVar,
247
* which is expected to have phlevelsup > 0 (ie, it is not local).
249
* This is just like replace_outer_var, except for PlaceHolderVars.
252
replace_outer_placeholdervar(PlannerInfo *root, PlaceHolderVar *phv)
257
Assert(phv->phlevelsup > 0 && phv->phlevelsup < root->query_level);
260
* Find the PlaceHolderVar in root->glob->paramlist, or add it if not
263
i = assign_param_for_placeholdervar(root, phv);
265
retval = makeNode(Param);
266
retval->paramkind = PARAM_EXEC;
268
retval->paramtype = exprType((Node *) phv->phexpr);
269
retval->paramtypmod = exprTypmod((Node *) phv->phexpr);
270
retval->paramcollid = exprCollation((Node *) phv->phexpr);
271
retval->location = -1;
196
277
* Generate a Param node to replace the given PlaceHolderVar, which will be
197
278
* supplied from an upper NestLoop join node.
202
283
assign_nestloop_param_placeholdervar(PlannerInfo *root, PlaceHolderVar *phv)
206
PlannerParamItem *pitem;
210
288
Assert(phv->phlevelsup == 0);
211
abslevel = root->query_level;
213
/* If there's already a paramlist entry for this same PHV, just use it */
214
/* We assume comparing the PHIDs is sufficient */
216
foreach(ppl, root->glob->paramlist)
218
pitem = (PlannerParamItem *) lfirst(ppl);
219
if (pitem->abslevel == abslevel && IsA(pitem->item, PlaceHolderVar))
221
PlaceHolderVar *pphv = (PlaceHolderVar *) pitem->item;
223
if (pphv->phid == phv->phid)
231
/* Nope, so make a new one */
232
phv = (PlaceHolderVar *) copyObject(phv);
234
pitem = makeNode(PlannerParamItem);
235
pitem->item = (Node *) phv;
236
pitem->abslevel = abslevel;
238
root->glob->paramlist = lappend(root->glob->paramlist, pitem);
240
/* i is already the correct list index for the new item */
290
i = assign_param_for_placeholdervar(root, phv);
243
292
retval = makeNode(Param);
244
293
retval->paramkind = PARAM_EXEC;
563
* The Var or Aggref has already been adjusted to have the correct
564
* varlevelsup or agglevelsup. We probably don't even need to
565
* copy it again, but be safe.
612
* The Var, PlaceHolderVar, or Aggref has already been adjusted to
613
* have the correct varlevelsup, phlevelsup, or agglevelsup. We
614
* probably don't even need to copy it again, but be safe.
567
616
arg = copyObject(pitem->item);
570
* If it's an Aggref, its arguments might contain SubLinks, which
571
* have not yet been processed. Do that now.
619
* If it's a PlaceHolderVar or Aggref, its arguments might contain
620
* SubLinks, which have not yet been processed (see the comments
621
* for SS_replace_correlation_vars). Do that now.
573
if (IsA(arg, Aggref))
623
if (IsA(arg, PlaceHolderVar) ||
574
625
arg = SS_process_sublinks(root, arg, false);
576
627
splan->parParam = lappend_int(splan->parParam, paramid);
1679
1730
* Replace correlation vars (uplevel vars) with Params.
1681
* Uplevel aggregates are replaced, too.
1732
* Uplevel PlaceHolderVars and aggregates are replaced, too.
1683
1734
* Note: it is critical that this runs immediately after SS_process_sublinks.
1684
* Since we do not recurse into the arguments of uplevel aggregates, they will
1685
* get copied to the appropriate subplan args list in the parent query with
1686
* uplevel vars not replaced by Params, but only adjusted in level (see
1687
* replace_outer_agg). That's exactly what we want for the vars of the parent
1688
* level --- but if an aggregate's argument contains any further-up variables,
1689
* they have to be replaced with Params in their turn. That will happen when
1690
* the parent level runs SS_replace_correlation_vars. Therefore it must do
1691
* so after expanding its sublinks to subplans. And we don't want any steps
1692
* in between, else those steps would never get applied to the aggregate
1693
* argument expressions, either in the parent or the child level.
1735
* Since we do not recurse into the arguments of uplevel PHVs and aggregates,
1736
* they will get copied to the appropriate subplan args list in the parent
1737
* query with uplevel vars not replaced by Params, but only adjusted in level
1738
* (see replace_outer_placeholdervar and replace_outer_agg). That's exactly
1739
* what we want for the vars of the parent level --- but if a PHV's or
1740
* aggregate's argument contains any further-up variables, they have to be
1741
* replaced with Params in their turn. That will happen when the parent level
1742
* runs SS_replace_correlation_vars. Therefore it must do so after expanding
1743
* its sublinks to subplans. And we don't want any steps in between, else
1744
* those steps would never get applied to the argument expressions, either in
1745
* the parent or the child level.
1695
1747
* Another fairly tricky thing going on here is the handling of SubLinks in
1696
* the arguments of uplevel aggregates. Those are not touched inside the
1697
* intermediate query level, either. Instead, SS_process_sublinks recurses
1698
* on them after copying the Aggref expression into the parent plan level
1748
* the arguments of uplevel PHVs/aggregates. Those are not touched inside the
1749
* intermediate query level, either. Instead, SS_process_sublinks recurses on
1750
* them after copying the PHV or Aggref expression into the parent plan level
1699
1751
* (this is actually taken care of in build_subplan).
1715
1767
if (((Var *) node)->varlevelsup > 0)
1716
1768
return (Node *) replace_outer_var(root, (Var *) node);
1770
if (IsA(node, PlaceHolderVar))
1772
if (((PlaceHolderVar *) node)->phlevelsup > 0)
1773
return (Node *) replace_outer_placeholdervar(root,
1774
(PlaceHolderVar *) node);
1718
1776
if (IsA(node, Aggref))
1720
1778
if (((Aggref *) node)->agglevelsup > 0)
1777
* Don't recurse into the arguments of an outer aggregate here. Any
1778
* SubLinks in the arguments have to be dealt with at the outer query
1779
* level; they'll be handled when build_subplan collects the Aggref into
1780
* the arguments to be passed down to the current subplan.
1835
* Don't recurse into the arguments of an outer PHV or aggregate here.
1836
* Any SubLinks in the arguments have to be dealt with at the outer query
1837
* level; they'll be handled when build_subplan collects the PHV or Aggref
1838
* into the arguments to be passed down to the current subplan.
1782
if (IsA(node, Aggref))
1840
if (IsA(node, PlaceHolderVar))
1842
if (((PlaceHolderVar *) node)->phlevelsup > 0)
1845
else if (IsA(node, Aggref))
1784
1847
if (((Aggref *) node)->agglevelsup > 0)