/* ----------------------------------------------------------------
 *		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)
{
#define MAX_TIDS	1024
	TIDBitmap  *tbm;
	IndexScanDesc scandesc;
	ItemPointerData tids[MAX_TIDS];
	int32		ntids;
	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, NULL);
		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)
	{
		bool		more = index_getmulti(scandesc, tids, MAX_TIDS, &ntids);

		if (ntids > 0)
		{
			tbm_add_tuples(tbm, tids, ntids);
			nTuples += ntids;
		}

		CHECK_FOR_INTERRUPTS();

		if (!more)
		{
			doscan = ExecIndexAdvanceArrayKeys(node->biss_ArrayKeys,
											   node->biss_NumArrayKeys);
			if (doscan)			/* reset index scan */
				index_rescan(node->biss_ScanDesc, node->biss_ScanKeys);
		}
	}

	/* must provide our own instrumentation support */
	if (node->ss.ps.instrument)
		InstrStopNode(node->ss.ps.instrument, nTuples);

	return (Node *) tbm;
}
Esempio n. 3
0
/* ----------------------------------------------------------------
 *		MultiExecBitmapIndexScan(node)
 * ----------------------------------------------------------------
 */
Node *
MultiExecBitmapIndexScan(BitmapIndexScanState *node)
{
#define MAX_TIDS	1024
	TIDBitmap  *tbm = NULL;
	IndexScanDesc scandesc;
	IndexScanDesc odScanDesc;
	ItemPointerData tids[MAX_TIDS];
	int32		ntids;
	double		nTuples = 0;

	OnDiskBitmapWords *odbm = NULL;
	bool	inmem = false;

	/* 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;
	odScanDesc = node->odbiss_ScanDesc;

	/*
	 * If we have runtime keys and they've not already been set up, do it
	 * now.
	 */
	if (node->biss_RuntimeKeyInfo && !node->biss_RuntimeKeysReady)
		ExecReScan((PlanState *) node, NULL);

	inmem = ((BitmapIndexScan*)((PlanState*)node)->plan)->inmem;

	if (inmem) {

		node->odbiss_result = NULL;

		/*
		 * 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
	 	*/
		for (;;)
		{
			bool	more = index_getmulti(scandesc, tids, MAX_TIDS, &ntids);

			if (ntids > 0)
			{
				tbm_add_tuples(tbm, tids, ntids);
				nTuples += ntids;
			}

			if (!more)
				break;

			CHECK_FOR_INTERRUPTS();
		}
	}

	else {
		node->biss_result = NULL;

		if (node->odbiss_result == NULL)
			node->odbiss_result = odbm_create(ODBM_MAX_WORDS);

		odbm = node->odbiss_result;

		index_getbitmapwords(odScanDesc, odbm->maxNumOfWords,
							&(odbm->numOfWords), 
							odbm->bitmapHeaderWords,
							odbm->bitmapContentWords);
	}

	/* must provide our own instrumentation support */
	if (node->ss.ps.instrument)
		InstrStopNodeMulti(node->ss.ps.instrument, nTuples);

	if (tbm != NULL)
		return (Node *) tbm;
	else
		return (Node *) odbm;
}