------------------------------------------------------------------------ * ExecInitNode * * Recursively initializes all the nodes in the plan tree rooted * at 'node'. * * Inputs: * 'node' is the current node of the plan produced by the query planner * 'estate' is the shared execution state for the plan tree * 'eflags' is a bitwise OR of flag bits described in executor.h * *
| 187 | * ------------------------------------------------------------------------ |
| 188 | */ |
| 189 | PlanState * |
| 190 | ExecInitNode(Plan *node, EState *estate, int eflags) |
| 191 | { |
| 192 | PlanState *result; |
| 193 | List *subps; |
| 194 | ListCell *l; |
| 195 | MemoryContext nodecxt = NULL; |
| 196 | MemoryContext oldcxt = NULL; |
| 197 | |
| 198 | /* |
| 199 | * do nothing when we get to the end of a leaf on tree. |
| 200 | */ |
| 201 | if (node == NULL) |
| 202 | return NULL; |
| 203 | |
| 204 | /* |
| 205 | * Make sure there's enough stack available. Need to check here, in |
| 206 | * addition to ExecProcNode() (via ExecProcNodeFirst()), to ensure the |
| 207 | * stack isn't overrun while initializing the node tree. |
| 208 | */ |
| 209 | check_stack_depth(); |
| 210 | |
| 211 | /* |
| 212 | * If per-node memory usage was requested |
| 213 | * (explain_memory_verbosity=detail), create a separate memory context |
| 214 | * for every node, so that we can attribute memory usage to each node. |
| 215 | * Otherwise, everything is allocated in the per-query ExecutorState |
| 216 | * context. The extra memory contexts consume some memory on their |
| 217 | * own, and prevent reusing memory allocated in one node in another |
| 218 | * node, so we only want to do this if the level of detail is needed. |
| 219 | */ |
| 220 | if ((estate->es_instrument & INSTRUMENT_MEMORY_DETAIL) != 0) |
| 221 | { |
| 222 | nodecxt = AllocSetContextCreate(CurrentMemoryContext, |
| 223 | "executor node", |
| 224 | ALLOCSET_SMALL_SIZES); |
| 225 | MemoryContextDeclareAccountingRoot(nodecxt); |
| 226 | oldcxt = MemoryContextSwitchTo(nodecxt); |
| 227 | } |
| 228 | |
| 229 | switch (nodeTag(node)) |
| 230 | { |
| 231 | /* |
| 232 | * control nodes |
| 233 | */ |
| 234 | case T_Result: |
| 235 | result = (PlanState *) ExecInitResult((Result *) node, |
| 236 | estate, eflags); |
| 237 | break; |
| 238 | |
| 239 | case T_ProjectSet: |
| 240 | result = (PlanState *) ExecInitProjectSet((ProjectSet *) node, |
| 241 | estate, eflags); |
| 242 | break; |
| 243 | |
| 244 | case T_ModifyTable: |
| 245 | result = (PlanState *) ExecInitModifyTable((ModifyTable *) node, |
| 246 | estate, eflags); |
no test coverage detected