* ExecScanSubPlan: default case where we have to rescan subplan each time */
| 232 | * ExecScanSubPlan: default case where we have to rescan subplan each time |
| 233 | */ |
| 234 | static Datum |
| 235 | ExecScanSubPlan(SubPlanState *node, |
| 236 | ExprContext *econtext, |
| 237 | bool *isNull) |
| 238 | { |
| 239 | SubPlan *subplan = node->subplan; |
| 240 | PlanState *planstate = node->planstate; |
| 241 | SubLinkType subLinkType = subplan->subLinkType; |
| 242 | MemoryContext oldcontext; |
| 243 | TupleTableSlot *slot; |
| 244 | Datum result; |
| 245 | bool found = false; /* true if got at least one subplan tuple */ |
| 246 | ListCell *pvar; |
| 247 | ListCell *l; |
| 248 | ArrayBuildStateAny *astate = NULL; |
| 249 | |
| 250 | /* |
| 251 | * MULTIEXPR subplans, when "executed", just return NULL; but first we |
| 252 | * mark the subplan's output parameters as needing recalculation. (This |
| 253 | * is a bit of a hack: it relies on the subplan appearing later in its |
| 254 | * targetlist than any of the referencing Params, so that all the Params |
| 255 | * have been evaluated before we re-mark them for the next evaluation |
| 256 | * cycle. But in general resjunk tlist items appear after non-resjunk |
| 257 | * ones, so this should be safe.) Unlike ExecReScanSetParamPlan, we do |
| 258 | * *not* set bits in the parent plan node's chgParam, because we don't |
| 259 | * want to cause a rescan of the parent. |
| 260 | */ |
| 261 | if (subLinkType == MULTIEXPR_SUBLINK) |
| 262 | { |
| 263 | EState *estate = node->parent->state; |
| 264 | |
| 265 | foreach(l, subplan->setParam) |
| 266 | { |
| 267 | int paramid = lfirst_int(l); |
| 268 | ParamExecData *prm = &(estate->es_param_exec_vals[paramid]); |
| 269 | |
| 270 | prm->execPlan = node; |
| 271 | } |
| 272 | *isNull = true; |
| 273 | return (Datum) 0; |
| 274 | } |
| 275 | |
| 276 | /* Initialize ArrayBuildStateAny in caller's context, if needed */ |
| 277 | if (subLinkType == ARRAY_SUBLINK) |
| 278 | astate = initArrayResultAny(subplan->firstColType, |
| 279 | CurrentMemoryContext, true); |
| 280 | |
| 281 | /* |
| 282 | * We are probably in a short-lived expression-evaluation context. Switch |
| 283 | * to the per-query context for manipulating the child plan's chgParam, |
| 284 | * calling ExecProcNode on it, etc. |
| 285 | */ |
| 286 | oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_query_memory); |
| 287 | |
| 288 | /* |
| 289 | * Set Params of this plan from parent plan correlation values. (Any |
| 290 | * calculation we have to do is done in the parent econtext, since the |
| 291 | * Param values don't need to have per-query lifetime.) |
no test coverage detected