/* ---------------------------------------------------------------- * InitScanRelation * * This does the initialization for scan relations and * subplans of scans. * ---------------------------------------------------------------- */ static void InitScanRelation(SeqScanState *node, EState *estate) { Relation currentRelation; HeapScanDesc currentScanDesc; /* * get the relation object id from the relid'th entry in the range table, * open that relation and acquire appropriate lock on it. */ /*CHANGED BY YASIN*/ if (node->ps.ps_InAround) /*If this is in the around branch*/ /*currentRelation = ExecOpenScanRelationAround(estate,((SeqScan *) node->ps.plan)->scanrelid);*/ currentRelation = ExecOpenScanRelation(estate,((SeqScan *) node->ps.plan)->scanrelid); else /*Original code*/ currentRelation = ExecOpenScanRelation(estate,((SeqScan *) node->ps.plan)->scanrelid); currentScanDesc = heap_beginscan(currentRelation, estate->es_snapshot, 0, NULL); node->ss_currentRelation = currentRelation; node->ss_currentScanDesc = currentScanDesc; ExecAssignScanType(node, RelationGetDescr(currentRelation)); }
/* ---------------------------------------------------------------- * InitScanRelation * * Set up to access the scan relation. * ---------------------------------------------------------------- */ static void InitScanRelation(SeqScanState *node, EState *estate, int eflags) { Relation currentRelation; HeapScanDesc currentScanDesc; /* * get the relation object id from the relid'th entry in the range table, * open that relation and acquire appropriate lock on it. */ currentRelation = ExecOpenScanRelation(estate, ((SeqScan *) node->ps.plan)->scanrelid, eflags); /* initialize a heapscan */ currentScanDesc = heap_beginscan(currentRelation, estate->es_snapshot, 0, NULL); node->ss_currentRelation = currentRelation; node->ss_currentScanDesc = currentScanDesc; /* and report the scan tuple slot's rowtype */ ExecAssignScanType(node, RelationGetDescr(currentRelation)); }
/* ---------------------------------------------------------------- * InitScanRelation * * This does the initialization for scan relations and * subplans of scans. * ---------------------------------------------------------------- */ static void InitScanRelation(SeqScanState *node, EState *estate) { Relation currentRelation; HeapScanDesc currentScanDesc; //elog(WARNING, "InitScanRelation"); /* * get the relation object id from the relid'th entry in the range table, * open that relation and acquire appropriate lock on it. */ currentRelation = ExecOpenScanRelation(estate, ((SeqScan *) node->ps.plan)->scanrelid); //elog(WARNING, "Rel kind %c",currentRelation->rd_rel->relkind); if(currentRelation->rd_rel->relkind== RELKIND_ARRAY) currentScanDesc = heap_beginscan_ar(currentRelation, estate->es_snapshot, 0, NULL); else currentScanDesc = heap_beginscan(currentRelation, estate->es_snapshot, 0, NULL); node->ss_currentRelation = currentRelation; node->ss_currentScanDesc = currentScanDesc; ExecAssignScanType(node, RelationGetDescr(currentRelation)); }
/* ---------------------------------------------------------------- * ExecInitAppendOnlyScan * ---------------------------------------------------------------- */ AppendOnlyScanState * ExecInitAppendOnlyScan(AppendOnlyScan *node, EState *estate, int eflags) { AppendOnlyScanState *appendonlystate; Relation currentRelation; Assert(outerPlan(node) == NULL); Assert(innerPlan(node) == NULL); /* * create state structure */ appendonlystate = makeNode(AppendOnlyScanState); appendonlystate->ss.ps.plan = (Plan *) node; appendonlystate->ss.ps.state = estate; /* * Miscellaneous initialization * * create expression context for node */ ExecAssignExprContext(estate, &appendonlystate->ss.ps); /* * initialize child expressions */ appendonlystate->ss.ps.targetlist = (List *) ExecInitExpr((Expr *) node->scan.plan.targetlist, (PlanState *) appendonlystate); appendonlystate->ss.ps.qual = (List *) ExecInitExpr((Expr *) node->scan.plan.qual, (PlanState *) appendonlystate); #define AOSCAN_NSLOTS 2 /* * tuple table initialization */ ExecInitResultTupleSlot(estate, &appendonlystate->ss.ps); ExecInitScanTupleSlot(estate, &appendonlystate->ss); /* * get the relation object id from the relid'th entry in the range table * and open that relation. */ currentRelation = ExecOpenScanRelation(estate, node->scan.scanrelid); appendonlystate->ss.ss_currentRelation = currentRelation; ExecAssignScanType(&appendonlystate->ss, RelationGetDescr(currentRelation)); /* * Initialize result tuple type and projection info. */ ExecAssignResultTypeFromTL(&appendonlystate->ss.ps); ExecAssignScanProjectionInfo(&appendonlystate->ss); initGpmonPktForAppendOnlyScan((Plan *)node, &appendonlystate->ss.ps.gpmon_pkt, estate); return appendonlystate; }
/* ---------------------------------------------------------------- * InitScanRelation * * This does the initialization for scan relations and * subplans of scans. * ---------------------------------------------------------------- */ static void InitScanRelation(SeqScanState *node, EState *estate) { Relation currentRelation; /* * get the relation object id from the relid'th entry in the range table, * open that relation and acquire appropriate lock on it. */ currentRelation = ExecOpenScanRelation(estate, ((SeqScan *) node->ps.plan)->scanrelid); node->ss_currentRelation = currentRelation; ExecAssignScanType(node, RelationGetDescr(currentRelation)); }
/* ---------------------------------------------------------------- * InitScanRelation * * Set up to access the scan relation. * ---------------------------------------------------------------- */ static void InitScanRelation(SeqScanState *node, EState *estate, int eflags) { Relation currentRelation; /* * get the relation object id from the relid'th entry in the range table, * open that relation and acquire appropriate lock on it. */ currentRelation = ExecOpenScanRelation(estate, ((SeqScan *) node->ss.ps.plan)->scanrelid, eflags); node->ss.ss_currentRelation = currentRelation; /* and report the scan tuple slot's rowtype */ ExecAssignScanType(&node->ss, RelationGetDescr(currentRelation)); }
/* * InitScanStateRelationDetails * Opens a relation and sets various relation specific ScanState fields. */ void InitScanStateRelationDetails(ScanState *scanState, Plan *plan, EState *estate) { Assert(NULL != scanState); PlanState *planState = &scanState->ps; /* Initialize child expressions */ planState->targetlist = (List *)ExecInitExpr((Expr *)plan->targetlist, planState); planState->qual = (List *)ExecInitExpr((Expr *)plan->qual, planState); Relation currentRelation = ExecOpenScanRelation(estate, ((Scan *)plan)->scanrelid); scanState->ss_currentRelation = currentRelation; if (RelationIsAoRows(currentRelation) || RelationIsParquet(currentRelation)) { scanState->splits = GetFileSplitsOfSegment(estate->es_plannedstmt->scantable_splits, currentRelation->rd_id, GetQEIndex()); } ExecAssignScanType(scanState, RelationGetDescr(currentRelation)); ExecAssignScanProjectionInfo(scanState); scanState->tableType = getTableType(scanState->ss_currentRelation); }
/* ---------------------------------------------------------------- * ExecInitForeignScan * ---------------------------------------------------------------- */ ForeignScanState * ExecInitForeignScan(ForeignScan *node, EState *estate, int eflags) { ForeignScanState *scanstate; Relation currentRelation = NULL; Index scanrelid = node->scan.scanrelid; Index tlistvarno; FdwRoutine *fdwroutine; /* check for unsupported flags */ Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK))); /* * create state structure */ scanstate = makeNode(ForeignScanState); scanstate->ss.ps.plan = (Plan *) node; scanstate->ss.ps.state = estate; /* * Miscellaneous initialization * * create expression context for node */ ExecAssignExprContext(estate, &scanstate->ss.ps); scanstate->ss.ps.ps_TupFromTlist = false; /* * 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); scanstate->fdw_recheck_quals = (List *) ExecInitExpr((Expr *) node->fdw_recheck_quals, (PlanState *) scanstate); /* * tuple table initialization */ ExecInitResultTupleSlot(estate, &scanstate->ss.ps); ExecInitScanTupleSlot(estate, &scanstate->ss); /* * open the base relation, if any, and acquire an appropriate lock on it; * also acquire function pointers from the FDW's handler */ if (scanrelid > 0) { currentRelation = ExecOpenScanRelation(estate, scanrelid, eflags); scanstate->ss.ss_currentRelation = currentRelation; fdwroutine = GetFdwRoutineForRelation(currentRelation, true); } else { /* We can't use the relcache, so get fdwroutine the hard way */ fdwroutine = GetFdwRoutineByServerId(node->fs_server); } /* * Determine the scan tuple type. If the FDW provided a targetlist * describing the scan tuples, use that; else use base relation's rowtype. */ if (node->fdw_scan_tlist != NIL || currentRelation == NULL) { TupleDesc scan_tupdesc; scan_tupdesc = ExecTypeFromTL(node->fdw_scan_tlist, false); ExecAssignScanType(&scanstate->ss, scan_tupdesc); /* Node's targetlist will contain Vars with varno = INDEX_VAR */ tlistvarno = INDEX_VAR; } else { ExecAssignScanType(&scanstate->ss, RelationGetDescr(currentRelation)); /* Node's targetlist will contain Vars with varno = scanrelid */ tlistvarno = scanrelid; } /* * Initialize result tuple type and projection info. */ ExecAssignResultTypeFromTL(&scanstate->ss.ps); ExecAssignScanProjectionInfoWithVarno(&scanstate->ss, tlistvarno); /* * Initialize FDW-related state. */ scanstate->fdwroutine = fdwroutine; scanstate->fdw_state = NULL; /* Initialize any outer plan. */ if (outerPlan(node)) outerPlanState(scanstate) = ExecInitNode(outerPlan(node), estate, eflags); /* * Tell the FDW to initialize the scan. */ fdwroutine->BeginForeignScan(scanstate, eflags); return scanstate; }
/* ---------------------------------------------------------------- * ExecInitIndexScan * * Initializes the index scan's state information, creates * scan keys, and opens the base and index relations. * * Note: index scans have 2 sets of state information because * we have to keep track of the base relation and the * index relation. * ---------------------------------------------------------------- */ IndexScanState * ExecInitIndexScan(IndexScan *node, EState *estate, int eflags) { IndexScanState *indexstate; Relation currentRelation; bool relistarget; /* * create state structure */ indexstate = makeNode(IndexScanState); indexstate->ss.ps.plan = (Plan *) node; indexstate->ss.ps.state = estate; /* * Miscellaneous initialization * * create expression context for node */ ExecAssignExprContext(estate, &indexstate->ss.ps); indexstate->ss.ps.ps_TupFromTlist = false; /* * initialize child expressions * * Note: we don't initialize all of the indexqual expression, only the * sub-parts corresponding to runtime keys (see below). Likewise for * indexorderby, if any. But the indexqualorig expression is always * initialized even though it will only be used in some uncommon cases --- * would be nice to improve that. (Problem is that any SubPlans present * in the expression must be found now...) */ indexstate->ss.ps.targetlist = (List *) ExecInitExpr((Expr *) node->scan.plan.targetlist, (PlanState *) indexstate); indexstate->ss.ps.qual = (List *) ExecInitExpr((Expr *) node->scan.plan.qual, (PlanState *) indexstate); indexstate->indexqualorig = (List *) ExecInitExpr((Expr *) node->indexqualorig, (PlanState *) indexstate); /* * tuple table initialization */ ExecInitResultTupleSlot(estate, &indexstate->ss.ps); ExecInitScanTupleSlot(estate, &indexstate->ss); /* * open the base relation and acquire appropriate lock on it. */ currentRelation = ExecOpenScanRelation(estate, node->scan.scanrelid); indexstate->ss.ss_currentRelation = currentRelation; indexstate->ss.ss_currentScanDesc = NULL; /* no heap scan here */ /* * get the scan type from the relation descriptor. */ ExecAssignScanType(&indexstate->ss, RelationGetDescr(currentRelation)); /* * Initialize result tuple type and projection info. */ ExecAssignResultTypeFromTL(&indexstate->ss.ps); ExecAssignScanProjectionInfo(&indexstate->ss); /* * If we are just doing EXPLAIN (ie, aren't going to run the plan), stop * here. This allows an index-advisor plugin to EXPLAIN a plan containing * references to nonexistent indexes. */ if (eflags & EXEC_FLAG_EXPLAIN_ONLY) return indexstate; /* * Open the index relation. * * If the parent table is one of the target relations of the query, then * InitPlan already opened and write-locked the index, so we can avoid * taking another lock here. Otherwise we need a normal reader's lock. */ relistarget = ExecRelationIsTargetRelation(estate, node->scan.scanrelid); indexstate->iss_RelationDesc = index_open(node->indexid, relistarget ? NoLock : AccessShareLock); /* * Initialize index-specific scan state */ indexstate->iss_RuntimeKeysReady = false; indexstate->iss_RuntimeKeys = NULL; indexstate->iss_NumRuntimeKeys = 0; /* * build the index scan keys from the index qualification */ ExecIndexBuildScanKeys((PlanState *) indexstate, indexstate->iss_RelationDesc, node->scan.scanrelid, node->indexqual, false, &indexstate->iss_ScanKeys, &indexstate->iss_NumScanKeys, &indexstate->iss_RuntimeKeys, &indexstate->iss_NumRuntimeKeys, NULL, /* no ArrayKeys */ NULL); /* * any ORDER BY exprs have to be turned into scankeys in the same way */ ExecIndexBuildScanKeys((PlanState *) indexstate, indexstate->iss_RelationDesc, node->scan.scanrelid, node->indexorderby, true, &indexstate->iss_OrderByKeys, &indexstate->iss_NumOrderByKeys, &indexstate->iss_RuntimeKeys, &indexstate->iss_NumRuntimeKeys, NULL, /* no ArrayKeys */ NULL); /* * If we have runtime keys, we need an ExprContext to evaluate them. The * node's standard context won't do because we want to reset that context * for every tuple. So, build another context just like the other one... * -tgl 7/11/00 */ if (indexstate->iss_NumRuntimeKeys != 0) { ExprContext *stdecontext = indexstate->ss.ps.ps_ExprContext; ExecAssignExprContext(estate, &indexstate->ss.ps); indexstate->iss_RuntimeContext = indexstate->ss.ps.ps_ExprContext; indexstate->ss.ps.ps_ExprContext = stdecontext; } else { indexstate->iss_RuntimeContext = NULL; } /* * Initialize scan descriptor. */ indexstate->iss_ScanDesc = index_beginscan(currentRelation, indexstate->iss_RelationDesc, estate->es_snapshot, indexstate->iss_NumScanKeys, indexstate->iss_NumOrderByKeys); /* * If no run-time keys to calculate, go ahead and pass the scankeys to the * index AM. */ if (indexstate->iss_NumRuntimeKeys == 0) index_rescan(indexstate->iss_ScanDesc, indexstate->iss_ScanKeys, indexstate->iss_NumScanKeys, indexstate->iss_OrderByKeys, indexstate->iss_NumOrderByKeys); /* * all done. */ return indexstate; }
/* ---------------------------------------------------------------- * ExecInitIndexOnlyScan * * Initializes the index scan's state information, creates * scan keys, and opens the base and index relations. * * Note: index scans have 2 sets of state information because * we have to keep track of the base relation and the * index relation. * ---------------------------------------------------------------- */ IndexOnlyScanState * ExecInitIndexOnlyScan(IndexOnlyScan *node, EState *estate, int eflags) { IndexOnlyScanState *indexstate; Relation currentRelation; bool relistarget; TupleDesc tupDesc; /* * create state structure */ indexstate = makeNode(IndexOnlyScanState); indexstate->ss.ps.plan = (Plan *) node; indexstate->ss.ps.state = estate; indexstate->ioss_HeapFetches = 0; /* * Miscellaneous initialization * * create expression context for node */ ExecAssignExprContext(estate, &indexstate->ss.ps); indexstate->ss.ps.ps_TupFromTlist = false; /* * initialize child expressions * * Note: we don't initialize all of the indexorderby expression, only the * sub-parts corresponding to runtime keys (see below). */ indexstate->ss.ps.targetlist = (List *) ExecInitExpr((Expr *) node->scan.plan.targetlist, (PlanState *) indexstate); indexstate->ss.ps.qual = (List *) ExecInitExpr((Expr *) node->scan.plan.qual, (PlanState *) indexstate); indexstate->indexqual = (List *) ExecInitExpr((Expr *) node->indexqual, (PlanState *) indexstate); /* * tuple table initialization */ ExecInitResultTupleSlot(estate, &indexstate->ss.ps); ExecInitScanTupleSlot(estate, &indexstate->ss); /* * open the base relation and acquire appropriate lock on it. */ currentRelation = ExecOpenScanRelation(estate, node->scan.scanrelid, eflags); indexstate->ss.ss_currentRelation = currentRelation; indexstate->ss.ss_currentScanDesc = NULL; /* no heap scan here */ /* * Build the scan tuple type using the indextlist generated by the * planner. We use this, rather than the index's physical tuple * descriptor, because the latter contains storage column types not the * types of the original datums. (It's the AM's responsibility to return * suitable data anyway.) */ tupDesc = ExecTypeFromTL(node->indextlist, false); ExecAssignScanType(&indexstate->ss, tupDesc); /* * Initialize result tuple type and projection info. The node's * targetlist will contain Vars with varno = INDEX_VAR, referencing the * scan tuple. */ ExecAssignResultTypeFromTL(&indexstate->ss.ps); ExecAssignScanProjectionInfoWithVarno(&indexstate->ss, INDEX_VAR); /* * If we are just doing EXPLAIN (ie, aren't going to run the plan), stop * here. This allows an index-advisor plugin to EXPLAIN a plan containing * references to nonexistent indexes. */ if (eflags & EXEC_FLAG_EXPLAIN_ONLY) return indexstate; /* * Open the index relation. * * If the parent table is one of the target relations of the query, then * InitPlan already opened and write-locked the index, so we can avoid * taking another lock here. Otherwise we need a normal reader's lock. */ relistarget = ExecRelationIsTargetRelation(estate, node->scan.scanrelid); indexstate->ioss_RelationDesc = index_open(node->indexid, relistarget ? NoLock : AccessShareLock); /* * Initialize index-specific scan state */ indexstate->ioss_RuntimeKeysReady = false; indexstate->ioss_RuntimeKeys = NULL; indexstate->ioss_NumRuntimeKeys = 0; /* * build the index scan keys from the index qualification */ ExecIndexBuildScanKeys((PlanState *) indexstate, indexstate->ioss_RelationDesc, node->indexqual, false, &indexstate->ioss_ScanKeys, &indexstate->ioss_NumScanKeys, &indexstate->ioss_RuntimeKeys, &indexstate->ioss_NumRuntimeKeys, NULL, /* no ArrayKeys */ NULL); /* * any ORDER BY exprs have to be turned into scankeys in the same way */ ExecIndexBuildScanKeys((PlanState *) indexstate, indexstate->ioss_RelationDesc, node->indexorderby, true, &indexstate->ioss_OrderByKeys, &indexstate->ioss_NumOrderByKeys, &indexstate->ioss_RuntimeKeys, &indexstate->ioss_NumRuntimeKeys, NULL, /* no ArrayKeys */ NULL); /* * If we have runtime keys, we need an ExprContext to evaluate them. The * node's standard context won't do because we want to reset that context * for every tuple. So, build another context just like the other one... * -tgl 7/11/00 */ if (indexstate->ioss_NumRuntimeKeys != 0) { ExprContext *stdecontext = indexstate->ss.ps.ps_ExprContext; ExecAssignExprContext(estate, &indexstate->ss.ps); indexstate->ioss_RuntimeContext = indexstate->ss.ps.ps_ExprContext; indexstate->ss.ps.ps_ExprContext = stdecontext; } else { indexstate->ioss_RuntimeContext = NULL; } /* * Initialize scan descriptor. */ indexstate->ioss_ScanDesc = index_beginscan(currentRelation, indexstate->ioss_RelationDesc, estate->es_snapshot, indexstate->ioss_NumScanKeys, indexstate->ioss_NumOrderByKeys); /* Set it up for index-only scan */ indexstate->ioss_ScanDesc->xs_want_itup = true; indexstate->ioss_VMBuffer = InvalidBuffer; /* * If no run-time keys to calculate, go ahead and pass the scankeys to the * index AM. */ if (indexstate->ioss_NumRuntimeKeys == 0) index_rescan(indexstate->ioss_ScanDesc, indexstate->ioss_ScanKeys, indexstate->ioss_NumScanKeys, indexstate->ioss_OrderByKeys, indexstate->ioss_NumOrderByKeys); /* * all done. */ return indexstate; }
/* ---------------------------------------------------------------- * ExecInitForeignScan * ---------------------------------------------------------------- */ ForeignScanState * ExecInitForeignScan(ForeignScan *node, EState *estate, int eflags) { ForeignScanState *scanstate; Relation currentRelation; FdwRoutine *fdwroutine; /* check for unsupported flags */ Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK))); /* * create state structure */ scanstate = makeNode(ForeignScanState); scanstate->ss.ps.plan = (Plan *) node; scanstate->ss.ps.state = estate; /* * Miscellaneous initialization * * create expression context for node */ ExecAssignExprContext(estate, &scanstate->ss.ps); scanstate->ss.ps.ps_TupFromTlist = false; /* * 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); /* * tuple table initialization */ ExecInitResultTupleSlot(estate, &scanstate->ss.ps); ExecInitScanTupleSlot(estate, &scanstate->ss); /* * open the base relation and acquire appropriate lock on it. */ currentRelation = ExecOpenScanRelation(estate, node->scan.scanrelid); scanstate->ss.ss_currentRelation = currentRelation; /* * get the scan type from the relation descriptor. */ ExecAssignScanType(&scanstate->ss, RelationGetDescr(currentRelation)); /* * Initialize result tuple type and projection info. */ ExecAssignResultTypeFromTL(&scanstate->ss.ps); ExecAssignScanProjectionInfo(&scanstate->ss); /* * Acquire function pointers from the FDW's handler, and init fdw_state. */ fdwroutine = GetFdwRoutineByRelId(RelationGetRelid(currentRelation)); scanstate->fdwroutine = fdwroutine; scanstate->fdw_state = NULL; /* * Tell the FDW to initiate the scan. */ fdwroutine->BeginForeignScan(scanstate, eflags); return scanstate; }
/* ---------------------------------------------------------------- * ExecInitIndexScan * * Initializes the index scan's state information, creates * scan keys, and opens the base and index relations. * * Note: index scans have 2 sets of state information because * we have to keep track of the base relation and the * index relation. * ---------------------------------------------------------------- */ IndexScanState * ExecInitIndexScan(IndexScan *node, EState *estate, int eflags) { IndexScanState *indexstate; Relation currentRelation; bool relistarget; /* * create state structure */ indexstate = makeNode(IndexScanState); indexstate->ss.ps.plan = (Plan *) node; indexstate->ss.ps.state = estate; /* * Miscellaneous initialization * * create expression context for node */ ExecAssignExprContext(estate, &indexstate->ss.ps); /*indexstate->ss.ps.ps_TupFromTlist = false;*/ /* * initialize child expressions * * Note: we don't initialize all of the indexqual expression, only the * sub-parts corresponding to runtime keys (see below). The indexqualorig * expression is always initialized even though it will only be used in * some uncommon cases --- would be nice to improve that. (Problem is * that any SubPlans present in the expression must be found now...) */ indexstate->ss.ps.targetlist = (List *) ExecInitExpr((Expr *) node->scan.plan.targetlist, (PlanState *) indexstate); indexstate->ss.ps.qual = (List *) ExecInitExpr((Expr *) node->scan.plan.qual, (PlanState *) indexstate); indexstate->indexqualorig = (List *) ExecInitExpr((Expr *) node->indexqualorig, (PlanState *) indexstate); #define INDEXSCAN_NSLOTS 2 /* * tuple table initialization */ ExecInitResultTupleSlot(estate, &indexstate->ss.ps); ExecInitScanTupleSlot(estate, &indexstate->ss); /* * open the base relation and acquire appropriate lock on it. */ currentRelation = ExecOpenScanRelation(estate, node->scan.scanrelid); indexstate->ss.ss_currentRelation = currentRelation; /* * get the scan type from the relation descriptor. */ ExecAssignScanType(&indexstate->ss, RelationGetDescr(currentRelation)); /* * Open the index relation. * * If the parent table is one of the target relations of the query, then * InitPlan already opened and write-locked the index, so we can avoid * taking another lock here. Otherwise we need a normal reader's lock. */ relistarget = ExecRelationIsTargetRelation(estate, node->scan.scanrelid); indexstate->iss_RelationDesc = index_open(node->indexid, relistarget ? NoLock : AccessShareLock); /* * build the index scan keys from the index qualification */ ExecIndexBuildScanKeys((PlanState *) indexstate, indexstate->iss_RelationDesc, node->indexqual, node->indexstrategy, node->indexsubtype, &indexstate->iss_ScanKeys, &indexstate->iss_NumScanKeys, &indexstate->iss_RuntimeKeys, &indexstate->iss_NumRuntimeKeys, NULL, /* no ArrayKeys */ NULL); /* * If we have runtime keys, we need an ExprContext to evaluate them. The * node's standard context won't do because we want to reset that context * for every tuple. So, build another context just like the other one... * -tgl 7/11/00 */ if (indexstate->iss_NumRuntimeKeys != 0) { ExprContext *stdecontext = indexstate->ss.ps.ps_ExprContext; ExecAssignExprContext(estate, &indexstate->ss.ps); indexstate->iss_RuntimeContext = indexstate->ss.ps.ps_ExprContext; indexstate->ss.ps.ps_ExprContext = stdecontext; } else { indexstate->iss_RuntimeContext = NULL; } /* * Initialize index-specific scan state */ indexstate->iss_RuntimeKeysReady = false; /* * Initialize result tuple type and projection info. */ ExecAssignResultTypeFromTL(&indexstate->ss.ps); ExecAssignScanProjectionInfo(&indexstate->ss); initGpmonPktForIndexScan((Plan *)node, &indexstate->ss.ps.gpmon_pkt, estate); /* * If eflag contains EXEC_FLAG_REWIND or EXEC_FLAG_BACKWARD or EXEC_FLAG_MARK, * then this node is not eager free safe. */ indexstate->ss.ps.delayEagerFree = ((eflags & (EXEC_FLAG_REWIND | EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)) != 0); /* * all done. */ return indexstate; }
/* ---------------------------------------------------------------- * ExecInitBitmapHeapScan * * Initializes the scan's state information. * ---------------------------------------------------------------- */ BitmapHeapScanState * ExecInitBitmapHeapScan(BitmapHeapScan *node, EState *estate, int eflags) { BitmapHeapScanState *scanstate; Relation currentRelation; /* check for unsupported flags */ Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK))); /* * Assert caller didn't ask for an unsafe snapshot --- see comments at * head of file. */ Assert(IsMVCCSnapshot(estate->es_snapshot)); /* * create state structure */ scanstate = makeNode(BitmapHeapScanState); scanstate->ss.ps.plan = (Plan *) node; scanstate->ss.ps.state = estate; scanstate->tbm = NULL; scanstate->tbmres = NULL; /* * Miscellaneous initialization * * create expression context for node */ ExecAssignExprContext(estate, &scanstate->ss.ps); scanstate->ss.ps.ps_TupFromTlist = false; /* * 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); scanstate->bitmapqualorig = (List *) ExecInitExpr((Expr *) node->bitmapqualorig, (PlanState *) scanstate); #define BITMAPHEAPSCAN_NSLOTS 2 /* * tuple table initialization */ ExecInitResultTupleSlot(estate, &scanstate->ss.ps); ExecInitScanTupleSlot(estate, &scanstate->ss); /* * open the base relation and acquire appropriate lock on it. */ currentRelation = ExecOpenScanRelation(estate, node->scan.scanrelid); scanstate->ss.ss_currentRelation = currentRelation; /* * Even though we aren't going to do a conventional seqscan, it is useful * to create a HeapScanDesc --- this checks the relation size and sets up * statistical infrastructure for us. */ scanstate->ss.ss_currentScanDesc = heap_beginscan(currentRelation, estate->es_snapshot, 0, NULL); /* * One problem is that heap_beginscan counts a "sequential scan" start, * when we actually aren't doing any such thing. Reverse out the added * scan count. (Eventually we may want to count bitmap scans separately.) */ pgstat_discount_heap_scan(&scanstate->ss.ss_currentScanDesc->rs_pgstat_info); /* * get the scan type from the relation descriptor. */ ExecAssignScanType(&scanstate->ss, RelationGetDescr(currentRelation)); /* * Initialize result tuple type and projection info. */ ExecAssignResultTypeFromTL(&scanstate->ss.ps); ExecAssignScanProjectionInfo(&scanstate->ss); /* * initialize child nodes * * We do this last because the child nodes will open indexscans on our * relation's indexes, and we want to be sure we have acquired a lock on * the relation first. */ outerPlanState(scanstate) = ExecInitNode(outerPlan(node), estate, eflags); /* * all done. */ return scanstate; }
/* ---------------------------------------------------------------- * ExecInitForeignScan * ---------------------------------------------------------------- */ foreign_ss * ExecInitForeignScan(foreign_scan_sc *node, exec_state_n *estate, int eflags) { foreign_ss* scanstate; struct relation* currentRelation; FdwRoutine *fdwroutine; /* check for unsupported flags */ ASSERT(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK))); /* * create state structure */ scanstate = MK_N(ForeignScanState,foreign_ss); scanstate->ss.ps.plan = (plan_n *) node; scanstate->ss.ps.state = estate; /* * Miscellaneous initialization * * create expression context for node */ ExecAssignExprContext(estate, &scanstate->ss.ps); scanstate->ss.ps.ps_TupFromTlist = false; /* * initialize child expressions */ scanstate->ss.ps.targetlist = (struct list *) exec_init_expr( (expr_n *) node->scan.plan.targetlist, (plan_state_n *) scanstate); scanstate->ss.ps.qual = (struct list *) exec_init_expr( (expr_n *) node->scan.plan.qual, (plan_state_n *) scanstate); /* * tuple table initialization */ exec_init_result_tupslot(estate, &scanstate->ss.ps); exec_init_scan_tupslot(estate, &scanstate->ss); /* * open the base relation and acquire appropriate lock on it. */ currentRelation = ExecOpenScanRelation(estate, node->scan.scanrelid); scanstate->ss.ss_currentRelation = currentRelation; /* * get the scan type from the relation descriptor. */ ExecAssignScanType(&scanstate->ss, REL_DESC(currentRelation)); /* * Initialize result tuple type and projection info. */ ExecAssignResultTypeFromTL(&scanstate->ss.ps); ExecAssignScanProjectionInfo(&scanstate->ss); /* * Acquire function pointers from the FDW's handler, and init fdw_state. */ fdwroutine = GetFdwRoutineByRelId(REL_ID(currentRelation)); scanstate->fdwroutine = fdwroutine; scanstate->fdw_state = NULL; /* * Tell the FDW to initiate the scan. */ fdwroutine->BeginForeignScan(scanstate, eflags); return scanstate; }
/* ---------------------------------------------------------------- * ExecInitBitmapHeapScan * * Initializes the scan's state information. * ---------------------------------------------------------------- */ BitmapHeapScanState * ExecInitBitmapHeapScan(BitmapHeapScan *node, EState *estate, int eflags) { BitmapHeapScanState *scanstate; Relation currentRelation; /* check for unsupported flags */ Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK))); /* * Assert caller didn't ask for an unsafe snapshot --- see comments at * head of file. */ Assert(IsMVCCSnapshot(estate->es_snapshot)); /* * create state structure */ scanstate = makeNode(BitmapHeapScanState); scanstate->ss.ps.plan = (Plan *) node; scanstate->ss.ps.state = estate; scanstate->tbm = NULL; scanstate->tbmiterator = NULL; scanstate->tbmres = NULL; scanstate->prefetch_iterator = NULL; scanstate->prefetch_pages = 0; scanstate->prefetch_target = 0; /* * Miscellaneous initialization * * create expression context for node */ ExecAssignExprContext(estate, &scanstate->ss.ps); scanstate->ss.ps.ps_TupFromTlist = false; /* * 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); scanstate->bitmapqualorig = (List *) ExecInitExpr((Expr *) node->bitmapqualorig, (PlanState *) scanstate); /* * tuple table initialization */ ExecInitResultTupleSlot(estate, &scanstate->ss.ps); ExecInitScanTupleSlot(estate, &scanstate->ss); /* * open the base relation and acquire appropriate lock on it. */ currentRelation = ExecOpenScanRelation(estate, node->scan.scanrelid); scanstate->ss.ss_currentRelation = currentRelation; /* * Even though we aren't going to do a conventional seqscan, it is useful * to create a HeapScanDesc --- most of the fields in it are usable. */ scanstate->ss.ss_currentScanDesc = heap_beginscan_bm(currentRelation, estate->es_snapshot, 0, NULL); /* * get the scan type from the relation descriptor. */ ExecAssignScanType(&scanstate->ss, RelationGetDescr(currentRelation)); /* * Initialize result tuple type and projection info. */ ExecAssignResultTypeFromTL(&scanstate->ss.ps); ExecAssignScanProjectionInfo(&scanstate->ss); /* * initialize child nodes * * We do this last because the child nodes will open indexscans on our * relation's indexes, and we want to be sure we have acquired a lock on * the relation first. */ outerPlanState(scanstate) = ExecInitNode(outerPlan(node), estate, eflags); /* * all done. */ return scanstate; }
/* ---------------------------------------------------------------- * ExecInitBitmapHeapScan * * Initializes the scan's state information. * ---------------------------------------------------------------- */ BitmapHeapScanState * ExecInitBitmapHeapScan(BitmapHeapScan *node, EState *estate, int eflags) { BitmapHeapScanState *scanstate; Relation currentRelation; int io_concurrency; /* check for unsupported flags */ Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK))); /* * Assert caller didn't ask for an unsafe snapshot --- see comments at * head of file. */ Assert(IsMVCCSnapshot(estate->es_snapshot)); /* * create state structure */ scanstate = makeNode(BitmapHeapScanState); scanstate->ss.ps.plan = (Plan *) node; scanstate->ss.ps.state = estate; scanstate->ss.ps.ExecProcNode = ExecBitmapHeapScan; scanstate->tbm = NULL; scanstate->tbmiterator = NULL; scanstate->tbmres = NULL; scanstate->skip_fetch = false; scanstate->vmbuffer = InvalidBuffer; scanstate->pvmbuffer = InvalidBuffer; scanstate->exact_pages = 0; scanstate->lossy_pages = 0; scanstate->prefetch_iterator = NULL; scanstate->prefetch_pages = 0; scanstate->prefetch_target = 0; /* may be updated below */ scanstate->prefetch_maximum = target_prefetch_pages; scanstate->pscan_len = 0; scanstate->initialized = false; scanstate->shared_tbmiterator = NULL; scanstate->shared_prefetch_iterator = NULL; scanstate->pstate = NULL; /* * We can potentially skip fetching heap pages if we do not need any * columns of the table, either for checking non-indexable quals or for * returning data. This test is a bit simplistic, as it checks the * stronger condition that there's no qual or return tlist at all. But in * most cases it's probably not worth working harder than that. */ scanstate->can_skip_fetch = (node->scan.plan.qual == NIL && node->scan.plan.targetlist == NIL); /* * Miscellaneous initialization * * create expression context for node */ ExecAssignExprContext(estate, &scanstate->ss.ps); /* * open the scan relation */ currentRelation = ExecOpenScanRelation(estate, node->scan.scanrelid, eflags); /* * initialize child nodes */ outerPlanState(scanstate) = ExecInitNode(outerPlan(node), estate, eflags); /* * get the scan type from the relation descriptor. */ ExecInitScanTupleSlot(estate, &scanstate->ss, RelationGetDescr(currentRelation), &TTSOpsBufferHeapTuple); /* * Initialize result type and projection. */ ExecInitResultTypeTL(&scanstate->ss.ps); ExecAssignScanProjectionInfo(&scanstate->ss); /* * initialize child expressions */ scanstate->ss.ps.qual = ExecInitQual(node->scan.plan.qual, (PlanState *) scanstate); scanstate->bitmapqualorig = ExecInitQual(node->bitmapqualorig, (PlanState *) scanstate); /* * Determine the maximum for prefetch_target. If the tablespace has a * specific IO concurrency set, use that to compute the corresponding * maximum value; otherwise, we already initialized to the value computed * by the GUC machinery. */ io_concurrency = get_tablespace_io_concurrency(currentRelation->rd_rel->reltablespace); if (io_concurrency != effective_io_concurrency) { double maximum; if (ComputeIoConcurrency(io_concurrency, &maximum)) scanstate->prefetch_maximum = rint(maximum); } scanstate->ss.ss_currentRelation = currentRelation; /* * Even though we aren't going to do a conventional seqscan, it is useful * to create a HeapScanDesc --- most of the fields in it are usable. */ scanstate->ss.ss_currentScanDesc = heap_beginscan_bm(currentRelation, estate->es_snapshot, 0, NULL); /* * all done. */ return scanstate; }
/* ---------------------------------------------------------------- * ExecInitBitmapHeapScan * * Initializes the scan's state information. * ---------------------------------------------------------------- */ BitmapHeapScanState * ExecInitBitmapHeapScan(BitmapHeapScan *node, EState *estate, int eflags) { BitmapHeapScanState *scanstate; Relation currentRelation; int io_concurrency; /* check for unsupported flags */ Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK))); /* * Assert caller didn't ask for an unsafe snapshot --- see comments at * head of file. */ Assert(IsMVCCSnapshot(estate->es_snapshot)); /* * create state structure */ scanstate = makeNode(BitmapHeapScanState); scanstate->ss.ps.plan = (Plan *) node; scanstate->ss.ps.state = estate; scanstate->tbm = NULL; scanstate->tbmiterator = NULL; scanstate->tbmres = NULL; scanstate->exact_pages = 0; scanstate->lossy_pages = 0; scanstate->prefetch_iterator = NULL; scanstate->prefetch_pages = 0; scanstate->prefetch_target = 0; /* may be updated below */ scanstate->prefetch_maximum = target_prefetch_pages; /* * Miscellaneous initialization * * create expression context for node */ ExecAssignExprContext(estate, &scanstate->ss.ps); scanstate->ss.ps.ps_TupFromTlist = false; /* * 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); scanstate->bitmapqualorig = (List *) ExecInitExpr((Expr *) node->bitmapqualorig, (PlanState *) scanstate); /* * tuple table initialization */ ExecInitResultTupleSlot(estate, &scanstate->ss.ps); ExecInitScanTupleSlot(estate, &scanstate->ss); /* * open the base relation and acquire appropriate lock on it. */ currentRelation = ExecOpenScanRelation(estate, node->scan.scanrelid, eflags); /* * Determine the maximum for prefetch_target. If the tablespace has a * specific IO concurrency set, use that to compute the corresponding * maximum value; otherwise, we already initialized to the value computed * by the GUC machinery. */ io_concurrency = get_tablespace_io_concurrency(currentRelation->rd_rel->reltablespace); if (io_concurrency != effective_io_concurrency) { double maximum; if (ComputeIoConcurrency(io_concurrency, &maximum)) scanstate->prefetch_maximum = rint(maximum); } scanstate->ss.ss_currentRelation = currentRelation; /* * Even though we aren't going to do a conventional seqscan, it is useful * to create a HeapScanDesc --- most of the fields in it are usable. */ scanstate->ss.ss_currentScanDesc = heap_beginscan_bm(currentRelation, estate->es_snapshot, 0, NULL); /* * get the scan type from the relation descriptor. */ ExecAssignScanType(&scanstate->ss, RelationGetDescr(currentRelation)); /* * Initialize result tuple type and projection info. */ ExecAssignResultTypeFromTL(&scanstate->ss.ps); ExecAssignScanProjectionInfo(&scanstate->ss); /* * initialize child nodes * * We do this last because the child nodes will open indexscans on our * relation's indexes, and we want to be sure we have acquired a lock on * the relation first. */ outerPlanState(scanstate) = ExecInitNode(outerPlan(node), estate, eflags); /* * all done. */ return scanstate; }
CustomScanState * ExecInitCustomScan(CustomScan *cscan, EState *estate, int eflags) { CustomScanState *css; Relation scan_rel = NULL; Index scanrelid = cscan->scan.scanrelid; Index tlistvarno; /* * Allocate the CustomScanState object. We let the custom scan provider * do the palloc, in case it wants to make a larger object that embeds * CustomScanState as the first field. It must set the node tag and the * methods field correctly at this time. Other standard fields should be * set to zero. */ css = (CustomScanState *) cscan->methods->CreateCustomScanState(cscan); Assert(IsA(css, CustomScanState)); /* ensure flags is filled correctly */ css->flags = cscan->flags; /* fill up fields of ScanState */ css->ss.ps.plan = &cscan->scan.plan; css->ss.ps.state = estate; /* create expression context for node */ ExecAssignExprContext(estate, &css->ss.ps); #ifdef PG95 css->ss.ps.ps_TupFromTlist = false; #endif /* initialize child expressions */ css->ss.ps.targetlist = (List *) ExecInitExpr((Expr *) cscan->scan.plan.targetlist, (PlanState *) css); css->ss.ps.qual = (List *) ExecInitExpr((Expr *) cscan->scan.plan.qual, (PlanState *) css); /* tuple table initialization */ #ifndef PG95 if (((Scan*)css->ss.ps.plan)->scanrelid) { // For table scans ExecInitScanTupleSlot(estate, &css->ss); } else { // For tuple-table-slot scans (typically over Motion nodes) css->ss.ss_ScanTupleSlot = ExecAllocTableSlot(&estate->es_tupleTable); } #else ExecInitScanTupleSlot(estate, &css->ss); #endif ExecInitResultTupleSlot(estate, &css->ss.ps); /* * open the base relation, if any, and acquire an appropriate lock on it */ if (scanrelid > 0) { scan_rel = ExecOpenScanRelation(estate , scanrelid #ifdef PG95 , eflags #endif ); css->ss.ss_currentRelation = scan_rel; } /* * Determine the scan tuple type. If the custom scan provider provided a * targetlist describing the scan tuples, use that; else use base * relation's rowtype. */ if (cscan->custom_scan_tlist != NIL || scan_rel == NULL) { // index-only scan? GP doesn't define INDEX_VAR TupleDesc scan_tupdesc; scan_tupdesc = ExecTypeFromTL(cscan->custom_scan_tlist, false); ExecAssignScanType(&css->ss, scan_tupdesc); #ifdef PG95 /* Node's targetlist will contain Vars with varno = INDEX_VAR */ tlistvarno = INDEX_VAR; #endif } else { ExecAssignScanType(&css->ss, RelationGetDescr(scan_rel)); /* Node's targetlist will contain Vars with varno = scanrelid */ tlistvarno = scanrelid; } /* * Initialize result tuple type and projection info. */ ExecAssignResultTypeFromTL(&css->ss.ps); #ifdef PG95 ExecAssignScanProjectionInfoWithVarno(&css->ss, tlistvarno); #else ExecAssignScanProjectionInfo(&css->ss); #endif /* * The callback of custom-scan provider applies the final initialization * of the custom-scan-state node according to its logic. */ css->methods->BeginCustomScan(css, estate, eflags); return css; }