/* ---------------------------------------------------------------- * ExecInitBitmapIndexScan * * Initializes the index scan's state information. * ---------------------------------------------------------------- */ BitmapIndexScanState * ExecInitBitmapIndexScan(BitmapIndexScan *node, EState *estate, int eflags) { BitmapIndexScanState *indexstate; bool relistarget; /* check for unsupported flags */ Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK))); /* * create state structure */ indexstate = makeNode(BitmapIndexScanState); indexstate->ss.ps.plan = (Plan *) node; indexstate->ss.ps.state = estate; /* normally we don't make the result bitmap till runtime */ indexstate->biss_result = NULL; /* * Miscellaneous initialization * * We do not need a standard exprcontext for this node, though we may * decide below to create a runtime-key exprcontext */ /* * initialize child expressions * * We don't need to initialize targetlist or qual since neither are used. * * Note: we don't initialize all of the indexqual expression, only the * sub-parts corresponding to runtime keys (see below). */ #define BITMAPINDEXSCAN_NSLOTS 0 /* * We do not open or lock the base relation here. We assume that an * ancestor BitmapHeapScan node is holding AccessShareLock (or better) on * the heap relation throughout the execution of the plan tree. */ indexstate->ss.ss_currentRelation = NULL; indexstate->ss.ss_currentScanDesc = NULL; /* * 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->biss_RelationDesc = index_open(node->indexid, relistarget ? NoLock : AccessShareLock); /* * Initialize index-specific scan state */ indexstate->biss_RuntimeKeysReady = false; /* * build the index scan keys from the index qualification */ ExecIndexBuildScanKeys((PlanState *) indexstate, indexstate->biss_RelationDesc, node->indexqual, node->indexstrategy, node->indexsubtype, &indexstate->biss_ScanKeys, &indexstate->biss_NumScanKeys, &indexstate->biss_RuntimeKeys, &indexstate->biss_NumRuntimeKeys, &indexstate->biss_ArrayKeys, &indexstate->biss_NumArrayKeys); /* * If we have runtime keys or array keys, we need an ExprContext to * evaluate them. We could just create a "standard" plan node exprcontext, * but to keep the code looking similar to nodeIndexscan.c, it seems * better to stick with the approach of using a separate ExprContext. */ if (indexstate->biss_NumRuntimeKeys != 0 || indexstate->biss_NumArrayKeys != 0) { ExprContext *stdecontext = indexstate->ss.ps.ps_ExprContext; ExecAssignExprContext(estate, &indexstate->ss.ps); indexstate->biss_RuntimeContext = indexstate->ss.ps.ps_ExprContext; indexstate->ss.ps.ps_ExprContext = stdecontext; } else { indexstate->biss_RuntimeContext = NULL; } /* * Initialize scan descriptor. */ indexstate->biss_ScanDesc = index_beginscan_multi(indexstate->biss_RelationDesc, estate->es_snapshot, indexstate->biss_NumScanKeys, indexstate->biss_ScanKeys); /* * all done. */ return indexstate; }
/* ---------------------------------------------------------------- * ExecInitBitmapIndexScan * * Initializes the index scan's state information. * ---------------------------------------------------------------- */ BitmapIndexScanState * ExecInitBitmapIndexScan(BitmapIndexScan *node, EState *estate, int eflags) { BitmapIndexScanState *indexstate; ScanKey scanKeys; int numScanKeys; ExprState **runtimeKeyInfo; bool have_runtime_keys; /* check for unsupported flags */ Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK))); /* * create state structure */ indexstate = makeNode(BitmapIndexScanState); indexstate->ss.ps.plan = (Plan *) node; indexstate->ss.ps.state = estate; /* normally we don't make the result bitmap till runtime */ indexstate->biss_result = NULL; indexstate->odbiss_result = NULL; /* * Miscellaneous initialization * * We do not need a standard exprcontext for this node, though we may * decide below to create a runtime-key exprcontext */ /* * initialize child expressions * * We don't need to initialize targetlist or qual since neither are used. * * Note: we don't initialize all of the indexqual expression, only the * sub-parts corresponding to runtime keys (see below). */ #define BITMAPINDEXSCAN_NSLOTS 0 /* * Initialize index-specific scan state */ indexstate->biss_RuntimeKeysReady = false; CXT1_printf("ExecInitBitmapIndexScan: context is %d\n", CurrentMemoryContext); /* * build the index scan keys from the index qualification */ have_runtime_keys = ExecIndexBuildScanKeys((PlanState *) indexstate, node->indexqual, node->indexstrategy, node->indexsubtype, &runtimeKeyInfo, &scanKeys, &numScanKeys); indexstate->biss_RuntimeKeyInfo = runtimeKeyInfo; indexstate->biss_ScanKeys = scanKeys; indexstate->biss_NumScanKeys = numScanKeys; /* * If we have runtime keys, we need an ExprContext to evaluate them. We * could just create a "standard" plan node exprcontext, but to keep the * code looking similar to nodeIndexscan.c, it seems better to stick with * the approach of using a separate ExprContext. */ if (have_runtime_keys) { ExprContext *stdecontext = indexstate->ss.ps.ps_ExprContext; ExecAssignExprContext(estate, &indexstate->ss.ps); indexstate->biss_RuntimeContext = indexstate->ss.ps.ps_ExprContext; indexstate->ss.ps.ps_ExprContext = stdecontext; } else { indexstate->biss_RuntimeContext = NULL; } /* * We do not open or lock the base relation here. We assume that an * ancestor BitmapHeapScan node is holding AccessShareLock on the heap * relation throughout the execution of the plan tree. */ indexstate->ss.ss_currentRelation = NULL; indexstate->ss.ss_currentScanDesc = NULL; /* * open the index relation and initialize relation and scan descriptors. * Note we acquire no locks here; the index machinery does its own locks * and unlocks. */ indexstate->biss_RelationDesc = index_open(node->indexid); indexstate->biss_ScanDesc = index_beginscan_multi(indexstate->biss_RelationDesc, estate->es_snapshot, numScanKeys, scanKeys); if (node->indexam == BITMAP_AM_OID) { indexstate->odbiss_ScanDesc = index_beginscan_bitmapwords(indexstate->biss_RelationDesc, estate->es_snapshot, numScanKeys, scanKeys); node->inmem = false; } else { indexstate->odbiss_ScanDesc = NULL; node->inmem = true; } /* * all done. */ return indexstate; }