#include "postgres.h"
#include "executor/execdebug.h"
#include "executor/nodeBitmapIndexscan.h"
#include "executor/nodeIndexscan.h"
#include "miscadmin.h"
#include "utils/memutils.h"
Go to the source code of this file.
Functions | |
Node * | MultiExecBitmapIndexScan (BitmapIndexScanState *node) |
void | ExecReScanBitmapIndexScan (BitmapIndexScanState *node) |
void | ExecEndBitmapIndexScan (BitmapIndexScanState *node) |
BitmapIndexScanState * | ExecInitBitmapIndexScan (BitmapIndexScan *node, EState *estate, int eflags) |
void ExecEndBitmapIndexScan | ( | BitmapIndexScanState * | node | ) |
Definition at line 160 of file nodeBitmapIndexscan.c.
References BitmapIndexScanState::biss_RelationDesc, BitmapIndexScanState::biss_RuntimeContext, BitmapIndexScanState::biss_ScanDesc, FreeExprContext(), index_close(), index_endscan(), and NoLock.
Referenced by ExecEndNode().
{ Relation indexRelationDesc; IndexScanDesc indexScanDesc; /* * extract information from the node */ indexRelationDesc = node->biss_RelationDesc; indexScanDesc = node->biss_ScanDesc; /* * Free the exprcontext ... now dead code, see ExecFreeExprContext */ #ifdef NOT_USED if (node->biss_RuntimeContext) FreeExprContext(node->biss_RuntimeContext, true); #endif /* * close the index relation (no-op if we didn't open it) */ if (indexScanDesc) index_endscan(indexScanDesc); if (indexRelationDesc) index_close(indexRelationDesc, NoLock); }
BitmapIndexScanState* ExecInitBitmapIndexScan | ( | BitmapIndexScan * | node, | |
EState * | estate, | |||
int | eflags | |||
) |
Definition at line 195 of file nodeBitmapIndexscan.c.
References AccessShareLock, Assert, BitmapIndexScanState::biss_NumRuntimeKeys, BitmapIndexScanState::biss_RelationDesc, BitmapIndexScanState::biss_result, BitmapIndexScanState::biss_RuntimeKeys, BitmapIndexScanState::biss_RuntimeKeysReady, EState::es_snapshot, EXEC_FLAG_BACKWARD, EXEC_FLAG_EXPLAIN_ONLY, EXEC_FLAG_MARK, ExecAssignExprContext(), ExecIndexBuildScanKeys(), ExecRelationIsTargetRelation(), index_beginscan_bitmap(), index_open(), index_rescan(), BitmapIndexScan::indexid, BitmapIndexScan::indexqual, makeNode, NoLock, NULL, PlanState::plan, ScanState::ps, PlanState::ps_ExprContext, BitmapIndexScan::scan, Scan::scanrelid, BitmapIndexScanState::ss, ScanState::ss_currentRelation, ScanState::ss_currentScanDesc, and PlanState::state.
Referenced by ExecInitNode().
{ 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). */ /* * 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; indexstate->biss_RuntimeKeys = NULL; indexstate->biss_NumRuntimeKeys = 0; /* * build the index scan keys from the index qualification */ ExecIndexBuildScanKeys((PlanState *) indexstate, indexstate->biss_RelationDesc, node->indexqual, false, &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_bitmap(indexstate->biss_RelationDesc, estate->es_snapshot, indexstate->biss_NumScanKeys); /* * If no run-time keys to calculate, go ahead and pass the scankeys to the * index AM. */ if (indexstate->biss_NumRuntimeKeys == 0 && indexstate->biss_NumArrayKeys == 0) index_rescan(indexstate->biss_ScanDesc, indexstate->biss_ScanKeys, indexstate->biss_NumScanKeys, NULL, 0); /* * all done. */ return indexstate; }
void ExecReScanBitmapIndexScan | ( | BitmapIndexScanState * | node | ) |
Definition at line 116 of file nodeBitmapIndexscan.c.
References BitmapIndexScanState::biss_ArrayKeys, BitmapIndexScanState::biss_NumArrayKeys, BitmapIndexScanState::biss_NumRuntimeKeys, BitmapIndexScanState::biss_NumScanKeys, BitmapIndexScanState::biss_RuntimeContext, BitmapIndexScanState::biss_RuntimeKeys, BitmapIndexScanState::biss_RuntimeKeysReady, BitmapIndexScanState::biss_ScanDesc, BitmapIndexScanState::biss_ScanKeys, ExecIndexEvalArrayKeys(), ExecIndexEvalRuntimeKeys(), index_rescan(), NULL, and ResetExprContext.
Referenced by ExecReScan().
{ ExprContext *econtext = node->biss_RuntimeContext; /* * Reset the runtime-key context so we don't leak memory as each outer * tuple is scanned. Note this assumes that we will recalculate *all* * runtime keys on each call. */ if (econtext) ResetExprContext(econtext); /* * If we are doing runtime key calculations (ie, any of the index key * values weren't simple Consts), compute the new key values. * * Array keys are also treated as runtime keys; note that if we return * with biss_RuntimeKeysReady still false, then there is an empty array * key so no index scan is needed. */ if (node->biss_NumRuntimeKeys != 0) ExecIndexEvalRuntimeKeys(econtext, node->biss_RuntimeKeys, node->biss_NumRuntimeKeys); if (node->biss_NumArrayKeys != 0) node->biss_RuntimeKeysReady = ExecIndexEvalArrayKeys(econtext, node->biss_ArrayKeys, node->biss_NumArrayKeys); else node->biss_RuntimeKeysReady = true; /* reset index scan */ if (node->biss_RuntimeKeysReady) index_rescan(node->biss_ScanDesc, node->biss_ScanKeys, node->biss_NumScanKeys, NULL, 0); }
Node* MultiExecBitmapIndexScan | ( | BitmapIndexScanState * | node | ) |
Definition at line 36 of file nodeBitmapIndexscan.c.
References BitmapIndexScanState::biss_ArrayKeys, BitmapIndexScanState::biss_NumArrayKeys, BitmapIndexScanState::biss_NumRuntimeKeys, BitmapIndexScanState::biss_NumScanKeys, BitmapIndexScanState::biss_result, BitmapIndexScanState::biss_RuntimeKeysReady, BitmapIndexScanState::biss_ScanDesc, BitmapIndexScanState::biss_ScanKeys, CHECK_FOR_INTERRUPTS, ExecIndexAdvanceArrayKeys(), ExecReScan(), index_getbitmap(), index_rescan(), InstrStartNode(), InstrStopNode(), PlanState::instrument, NULL, ScanState::ps, BitmapIndexScanState::ss, tbm_create(), and work_mem.
Referenced by MultiExecProcNode().
{ TIDBitmap *tbm; IndexScanDesc scandesc; double nTuples = 0; bool doscan; /* must provide our own instrumentation support */ if (node->ss.ps.instrument) InstrStartNode(node->ss.ps.instrument); /* * extract necessary information from index scan node */ scandesc = node->biss_ScanDesc; /* * If we have runtime keys and they've not already been set up, do it now. * Array keys are also treated as runtime keys; note that if ExecReScan * returns with biss_RuntimeKeysReady still false, then there is an empty * array key so we should do nothing. */ if (!node->biss_RuntimeKeysReady && (node->biss_NumRuntimeKeys != 0 || node->biss_NumArrayKeys != 0)) { ExecReScan((PlanState *) node); doscan = node->biss_RuntimeKeysReady; } else doscan = true; /* * Prepare the result bitmap. Normally we just create a new one to pass * back; however, our parent node is allowed to store a pre-made one into * node->biss_result, in which case we just OR our tuple IDs into the * existing bitmap. (This saves needing explicit UNION steps.) */ if (node->biss_result) { tbm = node->biss_result; node->biss_result = NULL; /* reset for next time */ } else { /* XXX should we use less than work_mem for this? */ tbm = tbm_create(work_mem * 1024L); } /* * Get TIDs from index and insert into bitmap */ while (doscan) { nTuples += (double) index_getbitmap(scandesc, tbm); CHECK_FOR_INTERRUPTS(); doscan = ExecIndexAdvanceArrayKeys(node->biss_ArrayKeys, node->biss_NumArrayKeys); if (doscan) /* reset index scan */ index_rescan(node->biss_ScanDesc, node->biss_ScanKeys, node->biss_NumScanKeys, NULL, 0); } /* must provide our own instrumentation support */ if (node->ss.ps.instrument) InstrStopNode(node->ss.ps.instrument, nTuples); return (Node *) tbm; }