/* ---------------------------------------------------------------- * ExecReScanMaterial * * Rescans the materialized relation. * ---------------------------------------------------------------- */ void ExecReScanMaterial(MaterialState *node) { PlanState *outerPlan = outerPlanState(node); ExecClearTuple(node->ss.ps.ps_ResultTupleSlot); if (node->eflags != 0) { /* * If we haven't materialized yet, just return. If outerplan's * chgParam is not NULL then it will be re-scanned by ExecProcNode, * else no reason to re-scan it at all. */ if (!node->tuplestorestate) return; /* * If subnode is to be rescanned then we forget previous stored * results; we have to re-read the subplan and re-store. Also, if we * told tuplestore it needn't support rescan, we lose and must * re-read. (This last should not happen in common cases; else our * caller lied by not passing EXEC_FLAG_REWIND to us.) * * Otherwise we can just rewind and rescan the stored output. The * state of the subnode does not change. */ if (outerPlan->chgParam != NULL || (node->eflags & EXEC_FLAG_REWIND) == 0) { tuplestore_end(node->tuplestorestate); node->tuplestorestate = NULL; if (outerPlan->chgParam == NULL) ExecReScan(outerPlan); node->eof_underlying = false; } else tuplestore_rescan(node->tuplestorestate); } else { /* In this case we are just passing on the subquery's output */ /* * if chgParam of subnode is not null then plan will be re-scanned by * first ExecProcNode. */ if (outerPlan->chgParam == NULL) ExecReScan(outerPlan); node->eof_underlying = false; } }
/* ---------------------------------------------------------------- * ExecSubqueryReScan * * Rescans the relation. * ---------------------------------------------------------------- */ void ExecSubqueryReScan(SubqueryScanState *node, ExprContext *exprCtxt) { EState *estate; estate = node->ss.ps.state; ItemPointerSet(&node->cdb_fake_ctid, 0, 0); /* * ExecReScan doesn't know about my subplan, so I have to do * changed-parameter signaling myself. This is just as well, because the * subplan has its own memory context in which its chgParam state lives. */ if (node->ss.ps.chgParam != NULL) UpdateChangedParamSet(node->subplan, node->ss.ps.chgParam); /* * if chgParam of subnode is not null then plan will be re-scanned by * first ExecProcNode. */ if (node->subplan->chgParam == NULL) ExecReScan(node->subplan, NULL); node->ss.ss_ScanTupleSlot = NULL; /*node->ss.ps.ps_TupFromTlist = false;*/ Gpmon_M_Incr(GpmonPktFromSubqueryScanState(node), GPMON_SUBQUERYSCAN_RESCAN); CheckSendPlanStateGpmonPkt(&node->ss.ps); }
/* ---------------------------------------------------------------- * ExecReScanBitmapHeapScan(node) * ---------------------------------------------------------------- */ void ExecReScanBitmapHeapScan(BitmapHeapScanState *node) { PlanState *outerPlan = outerPlanState(node); /* rescan to release any page pin */ heap_rescan(node->ss.ss_currentScanDesc, NULL); if (node->tbmiterator) tbm_end_iterate(node->tbmiterator); if (node->prefetch_iterator) tbm_end_iterate(node->prefetch_iterator); if (node->shared_tbmiterator) tbm_end_shared_iterate(node->shared_tbmiterator); if (node->shared_prefetch_iterator) tbm_end_shared_iterate(node->shared_prefetch_iterator); if (node->tbm) tbm_free(node->tbm); node->tbm = NULL; node->tbmiterator = NULL; node->tbmres = NULL; node->prefetch_iterator = NULL; node->initialized = false; node->shared_tbmiterator = NULL; node->shared_prefetch_iterator = NULL; ExecScanReScan(&node->ss); /* * if chgParam of subnode is not null then plan will be re-scanned by * first ExecProcNode. */ if (outerPlan->chgParam == NULL) ExecReScan(outerPlan); }
/* ---------------------------------------------------------------- * ExecSubqueryReScan * * Rescans the relation. * ---------------------------------------------------------------- */ void ExecSubqueryReScan(SubqueryScanState *node, ExprContext *exprCtxt) { EState *estate; MemoryContext oldcontext; estate = node->ss.ps.state; oldcontext = MemoryContextSwitchTo(node->sss_SubEState->es_query_cxt); /* * ExecReScan doesn't know about my subplan, so I have to do * changed-parameter signaling myself. This is just as well, because the * subplan has its own memory context in which its chgParam state lives. */ if (node->ss.ps.chgParam != NULL) UpdateChangedParamSet(node->subplan, node->ss.ps.chgParam); /* * if chgParam of subnode is not null then plan will be re-scanned by * first ExecProcNode. */ if (node->subplan->chgParam == NULL) ExecReScan(node->subplan, NULL); MemoryContextSwitchTo(oldcontext); node->ss.ss_ScanTupleSlot = NULL; node->ss.ps.ps_TupFromTlist = false; }
/* ---------------------------------------------------------------- * ExecReScanRecursiveUnion * * Rescans the relation. * ---------------------------------------------------------------- */ void ExecReScanRecursiveUnion(RecursiveUnionState *node) { PlanState *outerPlan = outerPlanState(node); PlanState *innerPlan = innerPlanState(node); RecursiveUnion *plan = (RecursiveUnion *) node->ps.plan; /* * Set recursive term's chgParam to tell it that we'll modify the working * table and therefore it has to rescan. */ innerPlan->chgParam = bms_add_member(innerPlan->chgParam, plan->wtParam); /* * if chgParam of subnode is not null then plan will be re-scanned by * first ExecProcNode. Because of above, we only have to do this to the * non-recursive term. */ if (outerPlan->chgParam == NULL) ExecReScan(outerPlan); /* Release any hashtable storage */ if (node->tableContext) MemoryContextResetAndDeleteChildren(node->tableContext); /* And rebuild empty hashtable if needed */ if (plan->numCols > 0) build_hash_table(node); /* reset processing state */ node->recursing = false; node->intermediate_empty = true; tuplestore_clear(node->working_table); tuplestore_clear(node->intermediate_table); }
/* * Prepares for scanning of a new partition/relation. */ void BitmapTableScanBeginPartition(ScanState *node, bool initExpressions) { Assert(node != NULL); BitmapTableScanState *scanState = (BitmapTableScanState *)node; Assert(SCAN_NEXT == scanState->ss.scan_state); initBitmapState(scanState); if (scanState->bitmapqualorig == NULL || initExpressions) { /* TODO rahmaf2 [JIRA: MPP-23293]: remap columns per-partition to handle dropped columns */ scanState->bitmapqualorig = (List *) ExecInitExpr((Expr *) ((BitmapTableScan*)(node->ps.plan))->bitmapqualorig, (PlanState *) scanState); } scanState->needNewBitmapPage = true; scanState->recheckTuples = true; getBitmapTableScanMethod(node->tableType)->beginScanMethod(node); /* * Prepare child node to produce new bitmaps for the new partition (and cleanup * any leftover state from old partition). */ ExecReScan(outerPlanState(node), NULL); }
void ExecReScanAppend(AppendState *node, ExprContext *exprCtxt) { int i; for (i = node->as_firstplan; i <= node->as_lastplan; i++) { PlanState *subnode = node->appendplans[i]; /* * ExecReScan doesn't know about my subplans, so I have to do * changed-parameter signaling myself. */ if (node->ps.chgParam != NULL) UpdateChangedParamSet(subnode, node->ps.chgParam); /* * if chgParam of subnode is not null then plan will be re-scanned * by first ExecProcNode. */ if (subnode->chgParam == NULL) { /* make sure estate is correct for this subnode (needed??) */ node->as_whichplan = i; exec_append_initialize_next(node); ExecReScan(subnode, exprCtxt); } } node->as_whichplan = node->as_firstplan; exec_append_initialize_next(node); }
/* * Prepares for a rescan. */ void BitmapTableScanReScan(BitmapTableScanState *node, ExprContext *exprCtxt) { ScanState *scanState = &node->ss; Assert(scanState->tableType >= 0 && scanState->tableType < TableTypeInvalid); /* * If we are being passed an outer tuple, link it into the "regular" * per-tuple econtext for possible qual eval. */ if (exprCtxt != NULL) { ExprContext *stdecontext = node->ss.ps.ps_ExprContext; stdecontext->ecxt_outertuple = exprCtxt->ecxt_outertuple; } EState *estate = node->ss.ps.state; Index scanrelid = ((Scan *)(scanState->ps.plan))->scanrelid; /* If this is re-scanning of PlanQual ... */ if (estate->es_evTuple != NULL && estate->es_evTuple[scanrelid - 1] != NULL) { estate->es_evTupleNull[scanrelid - 1] = false; } DynamicScan_ReScan((ScanState *)node, BitmapTableScanEndPartition, exprCtxt); ExecReScan(outerPlanState(node), exprCtxt); }
/* ---------------------------------------------------------------- * ExecReScanBitmapHeapScan(node) * ---------------------------------------------------------------- */ void ExecReScanBitmapHeapScan(BitmapHeapScanState *node) { /* rescan to release any page pin */ heap_rescan(node->ss.ss_currentScanDesc, NULL); if (node->tbmiterator) tbm_end_iterate(node->tbmiterator); if (node->prefetch_iterator) tbm_end_iterate(node->prefetch_iterator); if (node->tbm) tbm_free(node->tbm); node->tbm = NULL; node->tbmiterator = NULL; node->tbmres = NULL; node->prefetch_iterator = NULL; ExecScanReScan(&node->ss); /* * if chgParam of subnode is not null then plan will be re-scanned by * first ExecProcNode. */ if (node->ss.ps.lefttree->chgParam == NULL) ExecReScan(node->ss.ps.lefttree); }
void ExecReScanAppend(AppendState *node, ExprContext *exprCtxt) { int i; for (i = node->as_firstplan; i <= node->as_lastplan; i++) { PlanState *subnode = node->appendplans[i]; /* * ExecReScan doesn't know about my subplans, so I have to do * changed-parameter signaling myself. */ if (node->ps.chgParam != NULL) UpdateChangedParamSet(subnode, node->ps.chgParam); /* * If chgParam of subnode is not null then plan will be re-scanned by * first ExecProcNode. However, if caller is passing us an exprCtxt * then forcibly rescan all the subnodes now, so that we can pass the * exprCtxt down to the subnodes (needed for appendrel indexscan). */ if (subnode->chgParam == NULL || exprCtxt != NULL) { /* make sure estate is correct for this subnode (needed??) */ node->as_whichplan = i; exec_append_initialize_next(node); ExecReScan(subnode, exprCtxt); } } node->as_whichplan = node->as_firstplan; exec_append_initialize_next(node); }
void ExecReScanSort(SortState *node, ExprContext *exprCtxt) { /* * If we haven't sorted yet, just return. If outerplan' chgParam is not * NULL then it will be re-scanned by ExecProcNode, else - no reason to * re-scan it at all. */ if (!node->sort_Done) return; /* must drop pointer to sort result tuple */ ExecClearTuple(node->ss.ps.ps_ResultTupleSlot); /* * If subnode is to be rescanned then we forget previous sort results; we * have to re-read the subplan and re-sort. * * Otherwise we can just rewind and rescan the sorted output. */ if (((PlanState *) node)->lefttree->chgParam != NULL || !node->randomAccess || (NULL == node->tuplesortstate->sortstore_mk && NULL == node->tuplesortstate->sortstore)) { node->sort_Done = false; if (gp_enable_mk_sort && NULL != node->tuplesortstate->sortstore_mk) { tuplesort_end_mk(node->tuplesortstate->sortstore_mk); } if (!gp_enable_mk_sort && NULL != node->tuplesortstate->sortstore) { tuplesort_end(node->tuplesortstate->sortstore); } /* * if chgParam of subnode is not null then plan will be re-scanned by * first ExecProcNode. */ if (((PlanState *) node)->lefttree->chgParam == NULL) { ExecReScan(((PlanState *) node)->lefttree, exprCtxt); } } else { if(gp_enable_mk_sort) { tuplesort_rescan_mk(node->tuplesortstate->sortstore_mk); } else { tuplesort_rescan(node->tuplesortstate->sortstore); } } }
void ExecReScanSetOp(SetOpState *node) { ExecClearTuple(node->ps.ps_ResultTupleSlot); node->setop_done = false; node->numOutput = 0; if (((SetOp *) node->ps.plan)->strategy == SETOP_HASHED) { /* * In the hashed case, if we haven't yet built the hash table then we * can just return; nothing done yet, so nothing to undo. If subnode's * chgParam is not NULL then it will be re-scanned by ExecProcNode, * else no reason to re-scan it at all. */ if (!node->table_filled) return; /* * If we do have the hash table and the subplan does not have any * parameter changes, then we can just rescan the existing hash table; * no need to build it again. */ if (node->ps.lefttree->chgParam == NULL) { ResetTupleHashIterator(node->hashtable, &node->hashiter); return; } } /* Release first tuple of group, if we have made a copy */ if (node->grp_firstTuple != NULL) { heap_freetuple(node->grp_firstTuple); node->grp_firstTuple = NULL; } /* Release any hashtable storage */ if (node->tableContext) MemoryContextResetAndDeleteChildren(node->tableContext); /* And rebuild empty hashtable if needed */ if (((SetOp *) node->ps.plan)->strategy == SETOP_HASHED) { build_hash_table(node); node->table_filled = false; } /* * if chgParam of subnode is not null then plan will be re-scanned by * first ExecProcNode. */ if (node->ps.lefttree->chgParam == NULL) ExecReScan(node->ps.lefttree); }
void ExecReScanGroup(GroupState *node, ExprContext *exprCtxt) { node->grp_done = FALSE; /* must clear first tuple */ ExecClearTuple(node->ss.ss_ScanTupleSlot); if (((PlanState *) node)->lefttree && ((PlanState *) node)->lefttree->chgParam == NULL) ExecReScan(((PlanState *) node)->lefttree, exprCtxt); }
/* * Prepares the BitmapTableScanState for a re-scan. */ void ExecBitmapTableReScan(BitmapTableScanState *node, ExprContext *exprCtxt) { BitmapTableScanReScan(node, exprCtxt); /* * Always rescan the input immediately, to ensure we can pass down any * outer tuple that might be used in index quals. */ CheckSendPlanStateGpmonPkt(&node->ss.ps); ExecReScan(outerPlanState(node), exprCtxt); }
/* ---------------------------------------------------------------- * ExecReScanBitmapHeapScan(node) * ---------------------------------------------------------------- */ void ExecReScanBitmapHeapScan(BitmapHeapScanState *node) { PlanState *outerPlan = outerPlanState(node); /* rescan to release any page pin */ heap_rescan(node->ss.ss_currentScanDesc, NULL); if (node->tbmiterator) tbm_end_iterate(node->tbmiterator); if (node->prefetch_iterator) tbm_end_iterate(node->prefetch_iterator); if (node->shared_tbmiterator) tbm_end_shared_iterate(node->shared_tbmiterator); if (node->shared_prefetch_iterator) tbm_end_shared_iterate(node->shared_prefetch_iterator); if (node->tbm) tbm_free(node->tbm); node->tbm = NULL; node->tbmiterator = NULL; node->tbmres = NULL; node->prefetch_iterator = NULL; node->initialized = false; node->shared_tbmiterator = NULL; node->shared_prefetch_iterator = NULL; /* Reset parallel bitmap state, if present */ if (node->pstate) { dsa_area *dsa = node->ss.ps.state->es_query_dsa; node->pstate->state = BM_INITIAL; if (DsaPointerIsValid(node->pstate->tbmiterator)) tbm_free_shared_area(dsa, node->pstate->tbmiterator); if (DsaPointerIsValid(node->pstate->prefetch_iterator)) tbm_free_shared_area(dsa, node->pstate->prefetch_iterator); node->pstate->tbmiterator = InvalidDsaPointer; node->pstate->prefetch_iterator = InvalidDsaPointer; } ExecScanReScan(&node->ss); /* * if chgParam of subnode is not null then plan will be re-scanned by * first ExecProcNode. */ if (outerPlan->chgParam == NULL) ExecReScan(outerPlan); }
/* ---------------------------------------------------------------- * ExecIndexScan(node) * ---------------------------------------------------------------- */ TupleTableSlot * ExecIndexScan(IndexScanState *node) { /* * If we have runtime keys and they've not already been set up, do it now. */ if (node->iss_NumRuntimeKeys != 0 && !node->iss_RuntimeKeysReady) ExecReScan((PlanState *) node); return ExecScan(&node->ss, (ExecScanAccessMtd) IndexNext, (ExecScanRecheckMtd) IndexRecheck); }
void ExecReScanLimit(LimitState *node, ExprContext *exprCtxt) { /* resetting lstate will force offset/limit recalculation */ node->lstate = LIMIT_INITIAL; /* * if chgParam of subnode is not null then plan will be re-scanned by * first ExecProcNode. */ if (((PlanState *) node)->lefttree->chgParam == NULL) ExecReScan(((PlanState *) node)->lefttree, exprCtxt); }
void ExecReScanUnique(UniqueState *node) { /* must clear result tuple so first input tuple is returned */ ExecClearTuple(node->ps.ps_ResultTupleSlot); /* * if chgParam of subnode is not null then plan will be re-scanned by * first ExecProcNode. */ if (node->ps.lefttree->chgParam == NULL) ExecReScan(node->ps.lefttree); }
void ExecReScanResult(ResultState *node) { node->rs_done = false; node->rs_checkqual = (node->resconstantqual == NULL) ? false : true; /* * If chgParam of subnode is not null then plan will be re-scanned by * first ExecProcNode. */ if (node->ps.lefttree && node->ps.lefttree->chgParam == NULL) ExecReScan(node->ps.lefttree); }
void ExecReScanGroup(GroupState *node, ExprContext *exprCtxt) { node->grp_done = FALSE; if (node->grp_firstTuple != NULL) { heap_freetuple(node->grp_firstTuple); node->grp_firstTuple = NULL; } if (((PlanState *) node)->lefttree && ((PlanState *) node)->lefttree->chgParam == NULL) ExecReScan(((PlanState *) node)->lefttree, exprCtxt); }
/* ---------------------------------------------------------------- * ExecIndexScan(node) * ---------------------------------------------------------------- */ struct tupslot * ExecIndexScan(index_ss *node) { /* * If we have runtime keys and they've not already been set up, do it now. */ if (node->iss_NumRuntimeKeys != 0 && !node->iss_RuntimeKeysReady) ExecReScan((plan_state_n *) node); return ExecScan(&node->ss, (exec_scan_access_mtd_f*) IndexNext, (exec_scan_recheck_mtd_f*) IndexRecheck); }
/* ---------------------------------------------------------------- * ExecIndexScan(node) * ---------------------------------------------------------------- */ TupleTableSlot * ExecIndexScan(IndexScanState *node) { /* * If we have runtime keys and they've not already been set up, do it now. */ if (node->iss_NumRuntimeKeys != 0 && !node->iss_RuntimeKeysReady) ExecReScan((PlanState *) node, NULL); /* * use IndexNext as access method */ return ExecScan(&node->ss, (ExecScanAccessMtd) IndexNext); }
/* ---------------------------------------------------------------- * ExecBitmapHeapReScan(node) * ---------------------------------------------------------------- */ void ExecBitmapHeapReScan(BitmapHeapScanState *node, ExprContext *exprCtxt) { EState *estate; Index scanrelid; estate = node->ss.ps.state; scanrelid = ((BitmapHeapScan *) node->ss.ps.plan)->scan.scanrelid; /* * If we are being passed an outer tuple, link it into the "regular" * per-tuple econtext for possible qual eval. */ if (exprCtxt != NULL) { ExprContext *stdecontext; stdecontext = node->ss.ps.ps_ExprContext; stdecontext->ecxt_outertuple = exprCtxt->ecxt_outertuple; } /* If this is re-scanning of PlanQual ... */ if (estate->es_evTuple != NULL && estate->es_evTuple[scanrelid - 1] != NULL) { estate->es_evTupleNull[scanrelid - 1] = false; } /* rescan to release any page pin */ heap_rescan(node->ss.ss_currentScanDesc, NULL); /* undo bogus "seq scan" count (see notes in ExecInitBitmapHeapScan) */ pgstat_discount_heap_scan(&node->ss.ss_currentScanDesc->rs_pgstat_info); if (node->tbm) tbm_free(node->tbm); node->tbm = NULL; node->tbmres = NULL; if (node->odbm) odbm_free(node->odbm); node->odbm = NULL; /* * Always rescan the input immediately, to ensure we can pass down any * outer tuple that might be used in index quals. */ ExecReScan(outerPlanState(node), exprCtxt); }
/* ---------------------------------------------------------------- * ExecIndexOnlyScan(node) * ---------------------------------------------------------------- */ static TupleTableSlot * ExecIndexOnlyScan(PlanState *pstate) { IndexOnlyScanState *node = castNode(IndexOnlyScanState, pstate); /* * If we have runtime keys and they've not already been set up, do it now. */ if (node->ioss_NumRuntimeKeys != 0 && !node->ioss_RuntimeKeysReady) ExecReScan((PlanState *) node); return ExecScan(&node->ss, (ExecScanAccessMtd) IndexOnlyNext, (ExecScanRecheckMtd) IndexOnlyRecheck); }
void ExecReScanResult(ResultState *node, ExprContext *exprCtxt) { node->rs_done = false; node->ps.ps_TupFromTlist = false; node->rs_checkqual = (node->resconstantqual == NULL) ? false : true; /* * if chgParam of subnode is not null then plan will be re-scanned by * first ExecProcNode. */ if (((PlanState *) node)->lefttree && ((PlanState *) node)->lefttree->chgParam == NULL) ExecReScan(((PlanState *) node)->lefttree, exprCtxt); }
void ExecReScanRepeat(RepeatState *node, ExprContext *exprCtxt) { /* Clean out the tuple table */ ExecClearTuple(node->ps.ps_ResultTupleSlot); init_RepeatState(node); /* * if chgParam of subnode is not null then plan will be re-scanned by * first ExecProcNode. */ if (((PlanState *) node)->lefttree->chgParam == NULL) ExecReScan(((PlanState *) node)->lefttree, exprCtxt); }
void ExecReScanSetOp(SetOpState *node, ExprContext *exprCtxt) { ExecClearTuple(node->ps.ps_ResultTupleSlot); node->ps.ps_OuterTupleSlot = NULL; node->subplan_done = false; node->numOutput = 0; /* * if chgParam of subnode is not null then plan will be re-scanned by * first ExecProcNode. */ if (((PlanState *) node)->lefttree->chgParam == NULL) ExecReScan(((PlanState *) node)->lefttree, exprCtxt); }
/* * ExecChildRescan * Helper function for rescanning child of materialize node */ void ExecChildRescan(MaterialState *node, ExprContext *exprCtxt) { Assert(node); /* * if parameters of subplan have changed, then subplan will be rescanned by * first ExecProcNode. Otherwise, we need to rescan subplan here */ if (((PlanState *) node)->lefttree->chgParam == NULL) { Gpmon_M_Incr(GpmonPktFromMaterialState(node), GPMON_MATERIAL_RESCAN); CheckSendPlanStateGpmonPkt(&node->ss.ps); ExecReScan(((PlanState *) node)->lefttree, exprCtxt); } node->eof_underlying = false; }
void ExecReScanGroup(GroupState *node) { PlanState *outerPlan = outerPlanState(node); node->grp_done = false; /* must clear first tuple */ ExecClearTuple(node->ss.ss_ScanTupleSlot); /* * if chgParam of subnode is not null then plan will be re-scanned by * first ExecProcNode. */ if (outerPlan->chgParam == NULL) ExecReScan(outerPlan); }
void ExecReScanGroup(GroupState *node) { node->grp_done = FALSE; node->ss.ps.ps_TupFromTlist = false; /* must clear first tuple */ ExecClearTuple(node->ss.ss_ScanTupleSlot); /* * if chgParam of subnode is not null then plan will be re-scanned by * first ExecProcNode. */ if (node->ss.ps.lefttree && node->ss.ps.lefttree->chgParam == NULL) ExecReScan(node->ss.ps.lefttree); }