/* ---------------------------------------------------------------- * MultiExecBitmapIndexScan(node) * ---------------------------------------------------------------- */ Node * MultiExecBitmapIndexScan(BitmapIndexScanState *node) { IndexScanState *scanState = (IndexScanState*)node; Node *bitmap = NULL; /* must provide our own instrumentation support */ if (scanState->ss.ps.instrument) { InstrStartNode(scanState->ss.ps.instrument); } bool partitionIsReady = DynamicScan_BeginIndexPartition(scanState, false /* initQual */, false /* initTargetList */, true /* supportsArrayKeys */, true /* isMultiScan */); Assert(partitionIsReady); if (!partitionIsReady) { DynamicScan_EndIndexPartition(scanState); return NULL; } bool doscan = node->indexScanState.iss_RuntimeKeysReady; IndexScanDesc scandesc = scanState->iss_ScanDesc; /* Get bitmap from index */ while (doscan) { bitmap = index_getmulti(scandesc, node->bitmap); if ((NULL != bitmap) && !(IsA(bitmap, HashBitmap) || IsA(bitmap, StreamBitmap))) { elog(ERROR, "unrecognized result from bitmap index scan"); } CHECK_FOR_INTERRUPTS(); /* CDB: If EXPLAIN ANALYZE, let bitmap share our Instrumentation. */ if (scanState->ss.ps.instrument) { tbm_bitmap_set_instrument(bitmap, scanState->ss.ps.instrument); } if(node->bitmap == NULL) { node->bitmap = (Node *)bitmap; } doscan = ExecIndexAdvanceArrayKeys(scanState->iss_ArrayKeys, scanState->iss_NumArrayKeys); if (doscan) { /* reset index scan */ index_rescan(scanState->iss_ScanDesc, scanState->iss_ScanKeys); } } DynamicScan_EndIndexPartition(scanState); /* must provide our own instrumentation support */ if (scanState->ss.ps.instrument) { InstrStopNode(scanState->ss.ps.instrument, 1 /* nTuples */); } return (Node *) bitmap; }
/* ---------------------------------------------------------------- * MultiExecBitmapIndexScan(node) * ---------------------------------------------------------------- */ Node * MultiExecBitmapIndexScan(BitmapIndexScanState *node) { 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, ((BitmapIndexScan *) node->ss.ps.plan)->isshared ? node->ss.ps.state->es_query_dsa : NULL); } /* * 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; }