/* ---------------- * ExecConditionalAssignProjectionInfo * * as ExecAssignProjectionInfo, but store NULL rather than building projection * info if no projection is required * ---------------- */ void ExecConditionalAssignProjectionInfo(PlanState *planstate, TupleDesc inputDesc, Index varno) { if (tlist_matches_tupdesc(planstate, planstate->plan->targetlist, varno, inputDesc)) { planstate->ps_ProjInfo = NULL; planstate->resultopsset = planstate->scanopsset; planstate->resultopsfixed = planstate->scanopsfixed; planstate->resultops = planstate->scanops; } else { if (!planstate->ps_ResultTupleSlot) { ExecInitResultSlot(planstate, &TTSOpsVirtual); planstate->resultops = &TTSOpsVirtual; planstate->resultopsfixed = true; planstate->resultopsset = true; } ExecAssignProjectionInfo(planstate, inputDesc); } }
/* ---------------------------------------------------------------- * ExecInitResult * * Creates the run-time state information for the result node * produced by the planner and initailizes outer relations * (child nodes). * ---------------------------------------------------------------- */ ResultState * ExecInitResult(Result *node, EState *estate) { ResultState *resstate; /* * create state structure */ resstate = makeNode(ResultState); resstate->ps.plan = (Plan *) node; resstate->ps.state = estate; resstate->rs_done = false; resstate->rs_checkqual = (node->resconstantqual == NULL) ? false : true; /* * Miscellaneous initialization * * create expression context for node */ ExecAssignExprContext(estate, &resstate->ps); #define RESULT_NSLOTS 1 /* * tuple table initialization */ ExecInitResultTupleSlot(estate, &resstate->ps); /* * initialize child expressions */ resstate->ps.targetlist = (List *) ExecInitExpr((Expr *) node->plan.targetlist, (PlanState *) resstate); resstate->ps.qual = (List *) ExecInitExpr((Expr *) node->plan.qual, (PlanState *) resstate); resstate->resconstantqual = ExecInitExpr((Expr *) node->resconstantqual, (PlanState *) resstate); /* * initialize child nodes */ outerPlanState(resstate) = ExecInitNode(outerPlan(node), estate); /* * we don't use inner plan */ Assert(innerPlan(node) == NULL); /* * initialize tuple type and projection info */ ExecAssignResultTypeFromTL(&resstate->ps); ExecAssignProjectionInfo(&resstate->ps); return resstate; }
/* ----------------- * ExecInitGroup * * Creates the run-time information for the group node produced by the * planner and initializes its outer subtree * ----------------- */ GroupState * ExecInitGroup(Group *node, EState *estate, int eflags) { GroupState *grpstate; /* check for unsupported flags */ Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK))); /* * create state structure */ grpstate = makeNode(GroupState); grpstate->ss.ps.plan = (Plan *) node; grpstate->ss.ps.state = estate; grpstate->ss.ps.ExecProcNode = ExecGroup; grpstate->grp_done = false; /* * create expression context */ ExecAssignExprContext(estate, &grpstate->ss.ps); /* * tuple table initialization */ ExecInitScanTupleSlot(estate, &grpstate->ss); ExecInitResultTupleSlot(estate, &grpstate->ss.ps); /* * initialize child expressions */ grpstate->ss.ps.qual = ExecInitQual(node->plan.qual, (PlanState *) grpstate); /* * initialize child nodes */ outerPlanState(grpstate) = ExecInitNode(outerPlan(node), estate, eflags); /* * initialize tuple type. */ ExecAssignScanTypeFromOuterPlan(&grpstate->ss); /* * Initialize result tuple type and projection info. */ ExecAssignResultTypeFromTL(&grpstate->ss.ps); ExecAssignProjectionInfo(&grpstate->ss.ps, NULL); /* * Precompute fmgr lookup data for inner loop */ grpstate->eqfunctions = execTuplesMatchPrepare(node->numCols, node->grpOperators); return grpstate; }
/** * Init nodeDML, which initializes the insert TupleTableSlot. * */ DMLState* ExecInitDML(DML *node, EState *estate, int eflags) { /* check for unsupported flags */ Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK | EXEC_FLAG_REWIND))); DMLState *dmlstate = makeNode(DMLState); dmlstate->ps.plan = (Plan *)node; dmlstate->ps.state = estate; ExecInitResultTupleSlot(estate, &dmlstate->ps); dmlstate->ps.targetlist = (List *) ExecInitExpr((Expr *) node->plan.targetlist, (PlanState *) dmlstate); Plan *outerPlan = outerPlan(node); outerPlanState(dmlstate) = ExecInitNode(outerPlan, estate, eflags); ExecAssignResultTypeFromTL(&dmlstate->ps); /* Create expression evaluation context. This will be used for projections */ ExecAssignExprContext(estate, &dmlstate->ps); /* * Create projection info from the child tuple descriptor and our target list * Projection will be placed in the ResultSlot */ TupleTableSlot *childResultSlot = outerPlanState(dmlstate)->ps_ResultTupleSlot; ExecAssignProjectionInfo(&dmlstate->ps, childResultSlot->tts_tupleDescriptor); /* * Initialize slot to insert/delete using output relation descriptor. */ dmlstate->cleanedUpSlot = ExecInitExtraTupleSlot(estate); /* * Both input and output of the junk filter include dropped attributes, so * the junk filter doesn't need to do anything special there about them */ TupleDesc cleanTupType = CreateTupleDescCopy(dmlstate->ps.state->es_result_relation_info->ri_RelationDesc->rd_att); dmlstate->junkfilter = ExecInitJunkFilter(node->plan.targetlist, cleanTupType, dmlstate->cleanedUpSlot); if (estate->es_instrument) { dmlstate->ps.cdbexplainbuf = makeStringInfo(); /* Request a callback at end of query. */ dmlstate->ps.cdbexplainfun = ExecDMLExplainEnd; } initGpmonPktForDML((Plan *)node, &dmlstate->ps.gpmon_pkt, estate); return dmlstate; }
/* ---------------------------------------------------------------- * ExecInitResult * * Creates the run-time state information for the result node * produced by the planner and initializes outer relations * (child nodes). * ---------------------------------------------------------------- */ ResultState * ExecInitResult(Result *node, EState *estate, int eflags) { ResultState *resstate; /* check for unsupported flags */ Assert(!(eflags & (EXEC_FLAG_MARK | EXEC_FLAG_BACKWARD)) || outerPlan(node) != NULL); /* * create state structure */ resstate = makeNode(ResultState); resstate->ps.plan = (Plan *) node; resstate->ps.state = estate; resstate->ps.ExecProcNode = ExecResult; resstate->rs_done = false; resstate->rs_checkqual = (node->resconstantqual == NULL) ? false : true; /* * Miscellaneous initialization * * create expression context for node */ ExecAssignExprContext(estate, &resstate->ps); /* * initialize child nodes */ outerPlanState(resstate) = ExecInitNode(outerPlan(node), estate, eflags); /* * we don't use inner plan */ Assert(innerPlan(node) == NULL); /* * Initialize result slot, type and projection. */ ExecInitResultTupleSlotTL(&resstate->ps); ExecAssignProjectionInfo(&resstate->ps, NULL); /* * initialize child expressions */ resstate->ps.qual = ExecInitQual(node->plan.qual, (PlanState *) resstate); resstate->resconstantqual = ExecInitQual((List *) node->resconstantqual, (PlanState *) resstate); return resstate; }
/* * ExecAssignScanProjectionInfo * Set up projection info for a scan node, if necessary. * * We can avoid a projection step if the requested tlist exactly matches * the underlying tuple type. If so, we just set ps_ProjInfo to NULL. * Note that this case occurs not only for simple "SELECT * FROM ...", but * also in most cases where there are joins or other processing nodes above * the scan node, because the planner will preferentially generate a matching * tlist. * * ExecAssignScanType must have been called already. */ void ExecAssignScanProjectionInfo(ScanState *node) { Scan *scan = (Scan *) node->ps.plan; if (tlist_matches_tupdesc(&node->ps, scan->plan.targetlist, scan->scanrelid, node->ss_ScanTupleSlot->tts_tupleDescriptor)) node->ps.ps_ProjInfo = NULL; else ExecAssignProjectionInfo(&node->ps, node->ss_ScanTupleSlot->tts_tupleDescriptor); }
RepeatState * ExecInitRepeat(Repeat *node, EState *estate, int eflags) { RepeatState *repeatstate; /* Check for unsupported flag */ Assert(!(eflags & (EXEC_FLAG_MARK | EXEC_FLAG_BACKWARD)) || outerPlan(node) != NULL); /* * Create state structure. */ repeatstate = makeNode(RepeatState); repeatstate->ps.plan = (Plan *)node; repeatstate->ps.state = estate; /* Create expression context for the node. */ ExecAssignExprContext(estate, &repeatstate->ps); ExecInitResultTupleSlot(estate, &repeatstate->ps); /* Initialize child expressions */ repeatstate->ps.targetlist = (List *) ExecInitExpr((Expr *)node->plan.targetlist, (PlanState *)repeatstate); repeatstate->ps.qual = (List *) ExecInitExpr((Expr *)node->plan.qual, (PlanState *)repeatstate); repeatstate->expr_state = ExecInitExpr(node->repeatCountExpr, (PlanState *)repeatstate); /* Initialize child nodes */ outerPlanState(repeatstate) = ExecInitNode(outerPlan(node), estate, eflags); /* Inner plan is not used. */ Assert(innerPlan(node) == NULL); /* Initialize tuple type and projection info */ ExecAssignResultTypeFromTL(&repeatstate->ps); ExecAssignProjectionInfo(&repeatstate->ps, NULL); init_RepeatState(repeatstate); initGpmonPktForRepeat((Plan *)node, &repeatstate->ps.gpmon_pkt, estate); return repeatstate; }
/* ---------------------------------------------------------------- * ExecInitPartitionSelector * * Create the run-time state information for PartitionSelector node * produced by Orca and initializes outer child if exists. * * ---------------------------------------------------------------- */ PartitionSelectorState * ExecInitPartitionSelector(PartitionSelector *node, EState *estate, int eflags) { /* check for unsupported flags */ Assert (!(eflags & (EXEC_FLAG_MARK | EXEC_FLAG_BACKWARD))); PartitionSelectorState *psstate = initPartitionSelection(node, estate); /* tuple table initialization */ ExecInitResultTupleSlot(estate, &psstate->ps); ExecAssignResultTypeFromTL(&psstate->ps); ExecAssignProjectionInfo(&psstate->ps, NULL); /* initialize child nodes */ /* No inner plan for PartitionSelector */ Assert(NULL == innerPlan(node)); if (NULL != outerPlan(node)) { outerPlanState(psstate) = ExecInitNode(outerPlan(node), estate, eflags); } /* * Initialize projection, to produce a tuple that has the partitioning key * columns at the same positions as in the partitioned table. */ if (node->partTabTargetlist) { List *exprStates; exprStates = (List *) ExecInitExpr((Expr *) node->partTabTargetlist, (PlanState *) psstate); psstate->partTabDesc = ExecTypeFromTL(node->partTabTargetlist, false); psstate->partTabSlot = MakeSingleTupleTableSlot(psstate->partTabDesc); psstate->partTabProj = ExecBuildProjectionInfo(exprStates, psstate->ps.ps_ExprContext, psstate->partTabSlot, ExecGetResultType(&psstate->ps)); } initGpmonPktForPartitionSelector((Plan *)node, &psstate->ps.gpmon_pkt, estate); return psstate; }
/* * ExecAssignScanProjectionInfo * Set up projection info for a scan node, if necessary. * * We can avoid a projection step if the requested tlist exactly matches * the underlying tuple type. If so, we just set ps_ProjInfo to NULL. * Note that this case occurs not only for simple "SELECT * FROM ...", but * also in most cases where there are joins or other processing nodes above * the scan node, because the planner will preferentially generate a matching * tlist. * * ExecAssignScanType must have been called already. */ void ExecAssignScanProjectionInfo(ScanState *node) { Scan *scan = (Scan *) node->ps.plan; Index varno; /* Vars in an index-only scan's tlist should be INDEX_VAR */ if (IsA(scan, IndexOnlyScan)) varno = INDEX_VAR; else varno = scan->scanrelid; if (tlist_matches_tupdesc(&node->ps, scan->plan.targetlist, varno, node->ss_ScanTupleSlot->tts_tupleDescriptor)) node->ps.ps_ProjInfo = NULL; else ExecAssignProjectionInfo(&node->ps, node->ss_ScanTupleSlot->tts_tupleDescriptor); }
/* ---------------------------------------------------------------- * ExecInitFunctionScan * ---------------------------------------------------------------- */ FunctionScanState * ExecInitFunctionScan(FunctionScan *node, EState *estate) { FunctionScanState *scanstate; RangeTblEntry *rte; Oid funcrettype; TypeFuncClass functypclass; TupleDesc tupdesc = NULL; /* * FunctionScan should not have any children. */ Assert(outerPlan(node) == NULL); Assert(innerPlan(node) == NULL); /* * create new ScanState for node */ scanstate = makeNode(FunctionScanState); scanstate->ss.ps.plan = (Plan *) node; scanstate->ss.ps.state = estate; /* * Miscellaneous initialization * * create expression context for node */ ExecAssignExprContext(estate, &scanstate->ss.ps); #define FUNCTIONSCAN_NSLOTS 2 /* * tuple table initialization */ ExecInitResultTupleSlot(estate, &scanstate->ss.ps); ExecInitScanTupleSlot(estate, &scanstate->ss); /* * initialize child expressions */ scanstate->ss.ps.targetlist = (List *) ExecInitExpr((Expr *) node->scan.plan.targetlist, (PlanState *) scanstate); scanstate->ss.ps.qual = (List *) ExecInitExpr((Expr *) node->scan.plan.qual, (PlanState *) scanstate); /* * get info about function */ rte = rt_fetch(node->scan.scanrelid, estate->es_range_table); Assert(rte->rtekind == RTE_FUNCTION); funcrettype = exprType(rte->funcexpr); /* * Now determine if the function returns a simple or composite type, * and build an appropriate tupdesc. */ functypclass = get_type_func_class(funcrettype); if (functypclass == TYPEFUNC_COMPOSITE) { /* Composite data type, e.g. a table's row type */ tupdesc = CreateTupleDescCopy(lookup_rowtype_tupdesc(funcrettype, -1)); } else if (functypclass == TYPEFUNC_SCALAR) { /* Base data type, i.e. scalar */ char *attname = strVal(linitial(rte->eref->colnames)); tupdesc = CreateTemplateTupleDesc(1, false); TupleDescInitEntry(tupdesc, (AttrNumber) 1, attname, funcrettype, -1, 0); } else if (functypclass == TYPEFUNC_RECORD) { tupdesc = BuildDescForRelation(rte->coldeflist); } else { /* crummy error message, but parser should have caught this */ elog(ERROR, "function in FROM has unsupported return type"); } /* * For RECORD results, make sure a typmod has been assigned. (The * function should do this for itself, but let's cover things in case * it doesn't.) */ if (tupdesc->tdtypeid == RECORDOID && tupdesc->tdtypmod < 0) assign_record_type_typmod(tupdesc); scanstate->tupdesc = tupdesc; ExecSetSlotDescriptor(scanstate->ss.ss_ScanTupleSlot, tupdesc, false); /* * Other node-specific setup */ scanstate->tuplestorestate = NULL; scanstate->funcexpr = ExecInitExpr((Expr *) rte->funcexpr, (PlanState *) scanstate); scanstate->ss.ps.ps_TupFromTlist = false; /* * Initialize result tuple type and projection info. */ ExecAssignResultTypeFromTL(&scanstate->ss.ps); ExecAssignProjectionInfo(&scanstate->ss.ps); return scanstate; }
/* ----------------- * ExecInitGroup * * Creates the run-time information for the group node produced by the * planner and initializes its outer subtree * ----------------- */ GroupState * ExecInitGroup(Group *node, EState *estate) { GroupState *grpstate; /* * create state structure */ grpstate = makeNode(GroupState); grpstate->ss.ps.plan = (Plan *) node; grpstate->ss.ps.state = estate; grpstate->grp_done = FALSE; /* * create expression context */ ExecAssignExprContext(estate, &grpstate->ss.ps); #define GROUP_NSLOTS 2 /* * tuple table initialization */ ExecInitScanTupleSlot(estate, &grpstate->ss); ExecInitResultTupleSlot(estate, &grpstate->ss.ps); /* * initialize child expressions */ grpstate->ss.ps.targetlist = (List *) ExecInitExpr((Expr *) node->plan.targetlist, (PlanState *) grpstate); grpstate->ss.ps.qual = (List *) ExecInitExpr((Expr *) node->plan.qual, (PlanState *) grpstate); /* * initialize child nodes */ outerPlanState(grpstate) = ExecInitNode(outerPlan(node), estate); /* * initialize tuple type. */ ExecAssignScanTypeFromOuterPlan(&grpstate->ss); /* * Initialize result tuple type and projection info. */ ExecAssignResultTypeFromTL(&grpstate->ss.ps); ExecAssignProjectionInfo(&grpstate->ss.ps, NULL); /* * Precompute fmgr lookup data for inner loop */ grpstate->eqfunctions = execTuplesMatchPrepare(ExecGetScanType(&grpstate->ss), node->numCols, node->grpColIdx); return grpstate; }
/* ---------------------------------------------------------------- * ExecInitNestLoop * * Creates the run-time state information for the nestloop node * produced by the planner and initailizes inner and outer relations * (child nodes). * ---------------------------------------------------------------- */ bool ExecInitNestLoop(NestLoop *node, EState *estate, Plan *parent) { NestLoopState *nlstate; NL1_printf("ExecInitNestLoop: %s\n", "initializing node"); /* ---------------- * assign execution state to node * ---------------- */ node->join.state = estate; /* ---------------- * create new nest loop state * ---------------- */ nlstate = makeNode(NestLoopState); nlstate->nl_PortalFlag = false; node->nlstate = nlstate; /* ---------------- * Miscellanious initialization * * + assign node's base_id * + assign debugging hooks and * + create expression context for node * ---------------- */ ExecAssignNodeBaseInfo(estate, &nlstate->jstate, parent); ExecAssignExprContext(estate, &nlstate->jstate); #define NESTLOOP_NSLOTS 1 /* ---------------- * tuple table initialization * ---------------- */ ExecInitResultTupleSlot(estate, &nlstate->jstate); /* ---------------- * now initialize children * ---------------- */ ExecInitNode(outerPlan((Plan*)node), estate, (Plan*)node); ExecInitNode(innerPlan((Plan*)node), estate, (Plan*)node); /* ---------------- * initialize tuple type and projection info * ---------------- */ ExecAssignResultTypeFromTL((Plan *) node, &nlstate->jstate); ExecAssignProjectionInfo((Plan *) node, &nlstate->jstate); /* ---------------- * finally, wipe the current outer tuple clean. * ---------------- */ nlstate->jstate.cs_OuterTupleSlot = NULL; nlstate->jstate.cs_TupFromTlist = false; NL1_printf("ExecInitNestLoop: %s\n", "node initialized"); return TRUE; }
/* ---------------------------------------------------------------- * ExecInitGather * ---------------------------------------------------------------- */ GatherState * ExecInitGather(Gather *node, EState *estate, int eflags) { GatherState *gatherstate; Plan *outerNode; bool hasoid; TupleDesc tupDesc; /* Gather node doesn't have innerPlan node. */ Assert(innerPlan(node) == NULL); /* * create state structure */ gatherstate = makeNode(GatherState); gatherstate->ps.plan = (Plan *) node; gatherstate->ps.state = estate; gatherstate->need_to_scan_locally = !node->single_copy; /* * Miscellaneous initialization * * create expression context for node */ ExecAssignExprContext(estate, &gatherstate->ps); /* * initialize child expressions */ gatherstate->ps.targetlist = (List *) ExecInitExpr((Expr *) node->plan.targetlist, (PlanState *) gatherstate); gatherstate->ps.qual = (List *) ExecInitExpr((Expr *) node->plan.qual, (PlanState *) gatherstate); /* * tuple table initialization */ gatherstate->funnel_slot = ExecInitExtraTupleSlot(estate); ExecInitResultTupleSlot(estate, &gatherstate->ps); /* * now initialize outer plan */ outerNode = outerPlan(node); outerPlanState(gatherstate) = ExecInitNode(outerNode, estate, eflags); gatherstate->ps.ps_TupFromTlist = false; /* * Initialize result tuple type and projection info. */ ExecAssignResultTypeFromTL(&gatherstate->ps); ExecAssignProjectionInfo(&gatherstate->ps, NULL); /* * Initialize funnel slot to same tuple descriptor as outer plan. */ if (!ExecContextForcesOids(&gatherstate->ps, &hasoid)) hasoid = false; tupDesc = ExecTypeFromTL(outerNode->targetlist, hasoid); ExecSetSlotDescriptor(gatherstate->funnel_slot, tupDesc); return gatherstate; }
/* ----------------- * ExecInitGroup * * Creates the run-time information for the group node produced by the * planner and initializes its outer subtree * ----------------- */ group_ss* ExecInitGroup(group_pl *node, exec_state_n *estate, int eflags) { group_ss *grpstate; /* check for unsupported flags */ ASSERT(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK))); /* * create state structure */ grpstate = MK_N(GroupState,group_ss); grpstate->ss.ps.plan = (plan_n *) node; grpstate->ss.ps.state = estate; grpstate->grp_done = FALSE; /* * create expression context */ ExecAssignExprContext(estate, &grpstate->ss.ps); /* * tuple table initialization */ exec_init_scan_tupslot(estate, &grpstate->ss); exec_init_result_tupslot(estate, &grpstate->ss.ps); /* * initialize child expressions */ grpstate->ss.ps.targetlist = (struct list*) exec_init_expr( (expr_n*) node->plan.targetlist, (plan_state_n*) grpstate); grpstate->ss.ps.qual = (struct list*) exec_init_expr( (expr_n*) node->plan.qual, (plan_state_n*) grpstate); /* * initialize child nodes */ OUTER_PLAN_STATE(grpstate) = exec_init_node(OUTER_PLAN(node), estate, eflags); /* * initialize tuple type. */ ExecAssignScanTypeFromOuterPlan(&grpstate->ss); /* * Initialize result tuple type and projection info. */ ExecAssignResultTypeFromTL(&grpstate->ss.ps); ExecAssignProjectionInfo(&grpstate->ss.ps, NULL); grpstate->ss.ps.ps_TupFromTlist = false; /* * Precompute fmgr lookup data for inner loop */ grpstate->eqfunctions = execTuplesMatchPrepare(node->numCols, node->grpOperators); return grpstate; }
/* ---------------------------------------------------------------- * ExecInitSubqueryScan * ---------------------------------------------------------------- */ SubqueryScanState * ExecInitSubqueryScan(SubqueryScan *node, EState *estate) { SubqueryScanState *subquerystate; RangeTblEntry *rte; EState *sp_estate; MemoryContext oldcontext; /* * SubqueryScan should not have any "normal" children. */ Assert(outerPlan(node) == NULL); Assert(innerPlan(node) == NULL); /* * create state structure */ subquerystate = makeNode(SubqueryScanState); subquerystate->ss.ps.plan = (Plan *) node; subquerystate->ss.ps.state = estate; /* * Miscellaneous initialization * * create expression context for node */ ExecAssignExprContext(estate, &subquerystate->ss.ps); /* * initialize child expressions */ subquerystate->ss.ps.targetlist = (List *) ExecInitExpr((Expr *) node->scan.plan.targetlist, (PlanState *) subquerystate); subquerystate->ss.ps.qual = (List *) ExecInitExpr((Expr *) node->scan.plan.qual, (PlanState *) subquerystate); #define SUBQUERYSCAN_NSLOTS 1 /* * tuple table initialization */ ExecInitResultTupleSlot(estate, &subquerystate->ss.ps); /* * initialize subquery * * This should agree with ExecInitSubPlan */ rte = rt_fetch(node->scan.scanrelid, estate->es_range_table); Assert(rte->rtekind == RTE_SUBQUERY); /* * The subquery needs its own EState because it has its own * rangetable. It shares our Param ID space, however. XXX if * rangetable access were done differently, the subquery could share * our EState, which would eliminate some thrashing about in this * module... */ sp_estate = CreateExecutorState(); subquerystate->sss_SubEState = sp_estate; oldcontext = MemoryContextSwitchTo(sp_estate->es_query_cxt); sp_estate->es_range_table = rte->subquery->rtable; sp_estate->es_param_list_info = estate->es_param_list_info; sp_estate->es_param_exec_vals = estate->es_param_exec_vals; sp_estate->es_tupleTable = ExecCreateTupleTable(ExecCountSlotsNode(node->subplan) + 10); sp_estate->es_snapshot = estate->es_snapshot; sp_estate->es_crosscheck_snapshot = estate->es_crosscheck_snapshot; sp_estate->es_instrument = estate->es_instrument; /* * Start up the subplan (this is a very cut-down form of InitPlan()) */ subquerystate->subplan = ExecInitNode(node->subplan, sp_estate); MemoryContextSwitchTo(oldcontext); subquerystate->ss.ss_ScanTupleSlot = NULL; subquerystate->ss.ps.ps_TupFromTlist = false; /* * Initialize result tuple type and projection info. */ ExecAssignResultTypeFromTL(&subquerystate->ss.ps); ExecAssignProjectionInfo(&subquerystate->ss.ps); return subquerystate; }
/* ---------------------------------------------------------------- * ExecInitGather * ---------------------------------------------------------------- */ GatherMergeState * ExecInitGatherMerge(GatherMerge *node, EState *estate, int eflags) { GatherMergeState *gm_state; Plan *outerNode; bool hasoid; TupleDesc tupDesc; /* Gather merge node doesn't have innerPlan node. */ Assert(innerPlan(node) == NULL); /* * create state structure */ gm_state = makeNode(GatherMergeState); gm_state->ps.plan = (Plan *) node; gm_state->ps.state = estate; gm_state->ps.ExecProcNode = ExecGatherMerge; /* * Miscellaneous initialization * * create expression context for node */ ExecAssignExprContext(estate, &gm_state->ps); /* * initialize child expressions */ gm_state->ps.qual = ExecInitQual(node->plan.qual, &gm_state->ps); /* * tuple table initialization */ ExecInitResultTupleSlot(estate, &gm_state->ps); /* * now initialize outer plan */ outerNode = outerPlan(node); outerPlanState(gm_state) = ExecInitNode(outerNode, estate, eflags); /* * Initialize result tuple type and projection info. */ ExecAssignResultTypeFromTL(&gm_state->ps); ExecAssignProjectionInfo(&gm_state->ps, NULL); gm_state->gm_initialized = false; /* * initialize sort-key information */ if (node->numCols) { int i; gm_state->gm_nkeys = node->numCols; gm_state->gm_sortkeys = palloc0(sizeof(SortSupportData) * node->numCols); for (i = 0; i < node->numCols; i++) { SortSupport sortKey = gm_state->gm_sortkeys + i; sortKey->ssup_cxt = CurrentMemoryContext; sortKey->ssup_collation = node->collations[i]; sortKey->ssup_nulls_first = node->nullsFirst[i]; sortKey->ssup_attno = node->sortColIdx[i]; /* * We don't perform abbreviated key conversion here, for the same * reasons that it isn't used in MergeAppend */ sortKey->abbreviate = false; PrepareSortSupportFromOrderingOp(node->sortOperators[i], sortKey); } } /* * store the tuple descriptor into gather merge state, so we can use it * later while initializing the gather merge slots. */ if (!ExecContextForcesOids(&gm_state->ps, &hasoid)) hasoid = false; tupDesc = ExecTypeFromTL(outerNode->targetlist, hasoid); gm_state->tupDesc = tupDesc; return gm_state; }
/* ---------------------------------------------------------------- * ExecInitNestLoop * ---------------------------------------------------------------- */ NestLoopState * ExecInitNestLoop(NestLoop *node, EState *estate, int eflags) { NestLoopState *nlstate; /* check for unsupported flags */ Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK))); NL1_printf("ExecInitNestLoop: %s\n", "initializing node"); /* * create state structure */ nlstate = makeNode(NestLoopState); nlstate->js.ps.plan = (Plan *) node; nlstate->js.ps.state = estate; /* * Miscellaneous initialization * * create expression context for node */ ExecAssignExprContext(estate, &nlstate->js.ps); /* * initialize child expressions */ nlstate->js.ps.targetlist = (List *) ExecInitExpr((Expr *) node->join.plan.targetlist, (PlanState *) nlstate); nlstate->js.ps.qual = (List *) ExecInitExpr((Expr *) node->join.plan.qual, (PlanState *) nlstate); nlstate->js.jointype = node->join.jointype; nlstate->js.joinqual = (List *) ExecInitExpr((Expr *) node->join.joinqual, (PlanState *) nlstate); /* * initialize child nodes * * Tell the inner child that cheap rescans would be good. (This is * unnecessary if we are doing nestloop with inner indexscan, because the * rescan will always be with a fresh parameter --- but since * nodeIndexscan doesn't actually care about REWIND, there's no point in * dealing with that refinement.) */ outerPlanState(nlstate) = ExecInitNode(outerPlan(node), estate, eflags); innerPlanState(nlstate) = ExecInitNode(innerPlan(node), estate, eflags | EXEC_FLAG_REWIND); #define NESTLOOP_NSLOTS 2 /* * tuple table initialization */ ExecInitResultTupleSlot(estate, &nlstate->js.ps); switch (node->join.jointype) { case JOIN_INNER: case JOIN_IN: break; case JOIN_LEFT: nlstate->nl_NullInnerTupleSlot = ExecInitNullTupleSlot(estate, ExecGetResultType(innerPlanState(nlstate))); break; default: elog(ERROR, "unrecognized join type: %d", (int) node->join.jointype); } /* * initialize tuple type and projection info */ ExecAssignResultTypeFromTL(&nlstate->js.ps); ExecAssignProjectionInfo(&nlstate->js.ps); /* * finally, wipe the current outer tuple clean. */ nlstate->js.ps.ps_OuterTupleSlot = NULL; nlstate->js.ps.ps_TupFromTlist = false; nlstate->nl_NeedNewOuter = true; nlstate->nl_MatchedOuter = false; NL1_printf("ExecInitNestLoop: %s\n", "node initialized"); return nlstate; }
/* ---------------------------------------------------------------- * ExecInitNestLoop * ---------------------------------------------------------------- */ NestLoopState * ExecInitNestLoop(NestLoop *node, EState *estate) { NestLoopState *nlstate; NL1_printf("ExecInitNestLoop: %s\n", "initializing node"); /* * create state structure */ nlstate = makeNode(NestLoopState); nlstate->js.ps.plan = (Plan *) node; nlstate->js.ps.state = estate; /* * Miscellaneous initialization * * create expression context for node */ ExecAssignExprContext(estate, &nlstate->js.ps); /* * initialize child expressions */ nlstate->js.ps.targetlist = (List *) ExecInitExpr((Expr *) node->join.plan.targetlist, (PlanState *) nlstate); nlstate->js.ps.qual = (List *) ExecInitExpr((Expr *) node->join.plan.qual, (PlanState *) nlstate); nlstate->js.jointype = node->join.jointype; nlstate->js.joinqual = (List *) ExecInitExpr((Expr *) node->join.joinqual, (PlanState *) nlstate); /* * initialize child nodes */ outerPlanState(nlstate) = ExecInitNode(outerPlan(node), estate); innerPlanState(nlstate) = ExecInitNode(innerPlan(node), estate); #define NESTLOOP_NSLOTS 2 /* * tuple table initialization */ ExecInitResultTupleSlot(estate, &nlstate->js.ps); switch (node->join.jointype) { case JOIN_INNER: case JOIN_IN: break; case JOIN_LEFT: nlstate->nl_NullInnerTupleSlot = ExecInitNullTupleSlot(estate, ExecGetResultType(innerPlanState(nlstate))); break; default: elog(ERROR, "unrecognized join type: %d", (int) node->join.jointype); } /* * initialize tuple type and projection info */ ExecAssignResultTypeFromTL(&nlstate->js.ps); ExecAssignProjectionInfo(&nlstate->js.ps); /* * finally, wipe the current outer tuple clean. */ nlstate->js.ps.ps_OuterTupleSlot = NULL; nlstate->js.ps.ps_TupFromTlist = false; nlstate->nl_NeedNewOuter = true; nlstate->nl_MatchedOuter = false; NL1_printf("ExecInitNestLoop: %s\n", "node initialized"); return nlstate; }