Esempio n. 1
0
//---------------------------------------------------------------------------
//	@function:
//		CBitSetTest::EresUnittest_Performance
//
//	@doc:
//		Simple perf test -- simulates xform candidate sets
//
//---------------------------------------------------------------------------
GPOS_RESULT
CBitSetTest::EresUnittest_Performance()
{
	// create memory pool
	CAutoMemoryPool amp;
	IMemoryPool *pmp = amp.Pmp();
	
	ULONG cSizeBits = 512;
	CBitSet *pbsBase = GPOS_NEW(pmp) CBitSet(pmp, cSizeBits);
	for (ULONG i = 0; i < cSizeBits; i++)
		{
			(void) pbsBase->FExchangeSet(i);
		}

	CBitSet *pbsTest = GPOS_NEW(pmp) CBitSet(pmp, cSizeBits);
	for (ULONG j = 0; j < 100000; j++)
	{
		ULONG cRandomBits = 16;
		for (ULONG i = 0; i < cRandomBits; i += ((cSizeBits - 1) / cRandomBits))
		{
			(void) pbsTest->FExchangeSet(i);
		}
			
		pbsTest->Intersection(pbsBase);		
	}	
	
	pbsTest->Release();
	pbsBase->Release();
	
	return GPOS_OK;
}	
Esempio n. 2
0
//---------------------------------------------------------------------------
//	@function:
//		CJoinOrderDP::GenerateSubsets
//
//	@doc:
//		Generate all subsets of given array of elements
//
//---------------------------------------------------------------------------
void
CJoinOrderDP::GenerateSubsets
	(
	IMemoryPool *pmp,
	CBitSet *pbsCurrent,
	ULONG *pulElems,
	ULONG ulSize,
	ULONG ulIndex,
	DrgPbs *pdrgpbsSubsets
	)
{
	GPOS_CHECK_STACK_SIZE;
	GPOS_CHECK_ABORT;

	GPOS_ASSERT(ulIndex <= ulSize);
	GPOS_ASSERT(NULL != pbsCurrent);
	GPOS_ASSERT(NULL != pulElems);
	GPOS_ASSERT(NULL != pdrgpbsSubsets);

	if (ulIndex == ulSize)
	{
		pdrgpbsSubsets->Append(pbsCurrent);
		return;
	}

	CBitSet *pbsCopy = GPOS_NEW(pmp) CBitSet(pmp, *pbsCurrent);
#ifdef GPOS_DEBUG
	BOOL fSet =
#endif // GPOS_DEBUG
		pbsCopy->FExchangeSet(pulElems[ulIndex]);
	GPOS_ASSERT(!fSet);

	GenerateSubsets(pmp, pbsCopy, pulElems, ulSize, ulIndex + 1, pdrgpbsSubsets);
	GenerateSubsets(pmp, pbsCurrent, pulElems, ulSize, ulIndex + 1, pdrgpbsSubsets);
}
Esempio n. 3
0
//---------------------------------------------------------------------------
//	@function:
//		CJoinOrderDP::PexprExpand
//
//	@doc:
//		Create join order
//
//---------------------------------------------------------------------------
CExpression *
CJoinOrderDP::PexprExpand()
{
	CBitSet *pbs = GPOS_NEW(m_pmp) CBitSet(m_pmp);
	for (ULONG ul = 0; ul < m_ulComps; ul++)
	{
		(void) pbs->FExchangeSet(ul);
	}

	if (GPOPT_DP_JOIN_ORDERING_SIZE_THRESHOLD < m_ulComps &&
		GPOPT_DP_JOIN_ORDERING_CONNECTEDNESS_THRESHOLD < DMaxConnectedness(pbs))
	{
		// terminate early if computation cost is expected to be large
		pbs->Release();

		return NULL;
	}

	CExpression *pexprResult = PexprBestJoinOrder(pbs);
	if (NULL != pexprResult)
	{
		pexprResult->AddRef();
	}
	pbs->Release();

	return pexprResult;
}
//---------------------------------------------------------------------------
//	@function:
//		CLogicalGbAggDeduplicate::PstatsDerive
//
//	@doc:
//		Derive statistics
//
//---------------------------------------------------------------------------
IStatistics *
CLogicalGbAggDeduplicate::PstatsDerive
	(
	IMemoryPool *pmp,
	CExpressionHandle &exprhdl,
	DrgPstat * // not used
	)
	const
{
	GPOS_ASSERT(Esp(exprhdl) > EspNone);
	IStatistics *pstatsChild = exprhdl.Pstats(0);

	// extract computed columns
	DrgPul *pdrgpulComputedCols = GPOS_NEW(pmp) DrgPul(pmp);
	exprhdl.Pdpscalar(1 /*ulChildIndex*/)->PcrsDefined()->ExtractColIds(pmp, pdrgpulComputedCols);

	// construct bitset with keys of join child
	CBitSet *pbsKeys = GPOS_NEW(pmp) CBitSet(pmp);
	const ULONG ulKeys = m_pdrgpcrKeys->UlLength();
	for (ULONG ul = 0; ul < ulKeys; ul++)
	{
		CColRef *pcr = (*m_pdrgpcrKeys)[ul];
		pbsKeys->FExchangeSet(pcr->UlId());
	}

	IStatistics *pstats = CLogicalGbAgg::PstatsDerive(pmp, pstatsChild, Pdrgpcr(), pdrgpulComputedCols, pbsKeys);
	pbsKeys->Release();
	pdrgpulComputedCols->Release();

	return pstats;
}
//---------------------------------------------------------------------------
//	@function:
//		CTranslatorDXLToExprUtils::AddKeySets
//
//	@doc:
// 		Add key sets info from the MD relation to the table descriptor
//
//---------------------------------------------------------------------------
void
CTranslatorDXLToExprUtils::AddKeySets
	(
	IMemoryPool *pmp,
	CTableDescriptor *ptabdesc,
	const IMDRelation *pmdrel,
	HMUlUl *phmululColMapping
	)
{
	GPOS_ASSERT(NULL != ptabdesc);
	GPOS_ASSERT(NULL != pmdrel);

	const ULONG ulKeySets = pmdrel->UlKeySets();
	for (ULONG ul = 0; ul < ulKeySets; ul++)
	{
		CBitSet *pbs = GPOS_NEW(pmp) CBitSet(pmp, ptabdesc->UlColumns());
		const DrgPul *pdrgpulKeys = pmdrel->PdrgpulKeyset(ul);
		const ULONG ulKeys = pdrgpulKeys->UlLength();

		for (ULONG ulKey = 0; ulKey < ulKeys; ulKey++)
		{
			// populate current keyset
			ULONG ulOriginalKey = *((*pdrgpulKeys)[ulKey]);
			ULONG *pulRemappedKey = phmululColMapping->PtLookup(&ulOriginalKey);
			GPOS_ASSERT(NULL != pulRemappedKey);
			
			pbs->FExchangeSet(*pulRemappedKey);
		}

		if (!ptabdesc->FAddKeySet(pbs))
		{
			pbs->Release();
		}
	}
}
Esempio n. 6
0
//---------------------------------------------------------------------------
//	@function:
//		CBitSetTest::EresUnittest_Basics
//
//	@doc:
//		Testing ctors/dtor
//
//---------------------------------------------------------------------------
GPOS_RESULT
CBitSetTest::EresUnittest_Basics()
{
	// create memory pool
	CAutoMemoryPool amp;
	IMemoryPool *pmp = amp.Pmp();

	ULONG cSizeBits = 32;
	CBitSet *pbs = GPOS_NEW(pmp) CBitSet(pmp, cSizeBits);

	ULONG cInserts = 10;
	for (ULONG i = 0; i < cInserts; i += 2)
	{
		// forces addition of new link
		pbs->FExchangeSet(i * cSizeBits);
	}
	GPOS_ASSERT(cInserts / 2 == pbs->CElements());

	for (ULONG i = 1; i < cInserts; i += 2)
	{
		// new link between existing links
		pbs->FExchangeSet(i * cSizeBits);
	}
	GPOS_ASSERT(cInserts == pbs->CElements());

	CBitSet *pbsCopy = GPOS_NEW(pmp) CBitSet(pmp, *pbs);
	GPOS_ASSERT(pbsCopy->FEqual(pbs));

	// delete old bitset to make sure we're not accidentally
	// using any of its memory
	pbs->Release();

	for (ULONG i = 0; i < cInserts; i++)
	{
		GPOS_ASSERT(pbsCopy->FBit(i * cSizeBits));
	}

	CWStringDynamic str(pmp);
	COstreamString os(&str);
	
	os << *pbsCopy << std::endl;
	GPOS_TRACE(str.Wsz());
	
	pbsCopy->Release();

	return GPOS_OK;
}
Esempio n. 7
0
//---------------------------------------------------------------------------
//	@function:
//		CJoinOrderDP::PexprJoin
//
//	@doc:
//		Join expressions in the given set
//
//---------------------------------------------------------------------------
CExpression *
CJoinOrderDP::PexprJoin
	(
	CBitSet *pbs
	)
{
	GPOS_ASSERT(2 == pbs->CElements());

	CBitSetIter bsi(*pbs);
	(void) bsi.FAdvance();
	ULONG ulCompFst = bsi.UlBit();
	(void) bsi.FAdvance();
	ULONG ulCompSnd = bsi.UlBit();
	GPOS_ASSERT(!bsi.FAdvance());

	CBitSet *pbsFst = GPOS_NEW(m_pmp) CBitSet(m_pmp);
	(void) pbsFst->FExchangeSet(ulCompFst);
	CBitSet *pbsSnd = GPOS_NEW(m_pmp) CBitSet(m_pmp);
	(void) pbsSnd->FExchangeSet(ulCompSnd);
	CExpression *pexprScalar = PexprPred(pbsFst, pbsSnd);
	pbsFst->Release();
	pbsSnd->Release();

	if (NULL == pexprScalar)
	{
		return NULL;
	}

	CExpression *pexprLeft = m_rgpcomp[ulCompFst]->m_pexpr;
	CExpression *pexprRight = m_rgpcomp[ulCompSnd]->m_pexpr;
	pexprLeft->AddRef();
	pexprRight->AddRef();
	pexprScalar->AddRef();
	CExpression *pexprJoin =
		CUtils::PexprLogicalJoin<CLogicalInnerJoin>(m_pmp, pexprLeft, pexprRight, pexprScalar);

	DeriveStats(pexprJoin);
	// store solution in DP table
	pbs->AddRef();
#ifdef GPOS_DEBUG
	BOOL fInserted =
#endif // GPOS_DEBUG
		m_phmbsexpr->FInsert(pbs, pexprJoin);
	GPOS_ASSERT(fInserted);

	return pexprJoin;
}
Esempio n. 8
0
//---------------------------------------------------------------------------
//	@function:
//		CJoinOrderDP::PexprBuildPred
//
//	@doc:
//		Build predicate connecting the two given sets
//
//---------------------------------------------------------------------------
CExpression *
CJoinOrderDP::PexprBuildPred
	(
	CBitSet *pbsFst,
	CBitSet *pbsSnd
	)
{
	// collect edges connecting the given sets
	CBitSet *pbsEdges = GPOS_NEW(m_pmp) CBitSet(m_pmp);
	CBitSet *pbs = GPOS_NEW(m_pmp) CBitSet(m_pmp, *pbsFst);
	pbs->Union(pbsSnd);

	for (ULONG ul = 0; ul < m_ulEdges; ul++)
	{
		SEdge *pedge = m_rgpedge[ul];
		if (
			pbs->FSubset(pedge->m_pbs) &&
			!pbsFst->FDisjoint(pedge->m_pbs) &&
			!pbsSnd->FDisjoint(pedge->m_pbs)
			)
		{
#ifdef GPOS_DEBUG
		BOOL fSet =
#endif // GPOS_DEBUG
			pbsEdges->FExchangeSet(ul);
			GPOS_ASSERT(!fSet);
		}
	}
	pbs->Release();

	CExpression *pexprPred = NULL;
	if (0 < pbsEdges->CElements())
	{
		DrgPexpr *pdrgpexpr = GPOS_NEW(m_pmp) DrgPexpr(m_pmp);
		CBitSetIter bsi(*pbsEdges);
		while (bsi.FAdvance())
		{
			ULONG ul = bsi.UlBit();
			SEdge *pedge = m_rgpedge[ul];
			pedge->m_pexpr->AddRef();
			pdrgpexpr->Append(pedge->m_pexpr);
		}

		pexprPred = CPredicateUtils::PexprConjunction(m_pmp, pdrgpexpr);
	}

	pbsEdges->Release();
	return pexprPred;
}
Esempio n. 9
0
//---------------------------------------------------------------------------
//	@function:
//		CTranslatorDXLToQuery::MarkUnusedColumns
//
//	@doc:
//		Mark unused target list entries in the setop child
//
//---------------------------------------------------------------------------
void
CTranslatorDXLToQuery::MarkUnusedColumns
	(
	Query *pquery,
	RangeTblRef *prtref,
	CStateDXLToQuery *pstatedxltoquery,
	const DrgPul *pdrgpulColids
	)
{
	const ULONG ulRTIndex = prtref->rtindex;
	RangeTblEntry *prte = (RangeTblEntry*) gpdb::PvListNth(pquery->rtable, ulRTIndex -1);

	GPOS_ASSERT(RTE_SUBQUERY == prte->rtekind);
	Query *pqueryDerTbl = prte->subquery;

	// maintain the list of used columns in a bit set
	CBitSet *pds = New(m_pmp) CBitSet(m_pmp);
	const ULONG ulLen = pdrgpulColids->UlLength();
	for (ULONG ul = 0; ul < ulLen; ul++)
	{
		ULONG ulValue = *((*pdrgpulColids)[ul]);
		(void) pds->FExchangeSet(ulValue);
	}

	// Mark all columns that are not in the list of required input columns as being unused
	const ULONG ulSize = pstatedxltoquery->UlLength();
	for (ULONG ul = 0; ul < ulSize; ul++)
	{
		ULONG ulColId = pstatedxltoquery->UlColId(ul);
		BOOL fSet = pds->FBit(ulColId);

		if (!fSet)
		{
			// mark the column as unused in the query
			TargetEntry *pte2 = (TargetEntry*) gpdb::PvListNth(pqueryDerTbl->targetList, ul);
			pte2->resjunk = true;

			// mark the column as unused in the state
			TargetEntry *pte = pstatedxltoquery->PteColumn(ul);
			pte->resjunk = true;
		}
	}

	pds->Release();
}
Esempio n. 10
0
//---------------------------------------------------------------------------
//	@function:
//		CBitSetTest::EresUnittest_Removal
//
//	@doc:
//		Cleanup test
//
//---------------------------------------------------------------------------
GPOS_RESULT
CBitSetTest::EresUnittest_Removal()
{
	// create memory pool
	CAutoMemoryPool amp;
	IMemoryPool *pmp = amp.Pmp();

	ULONG cSizeBits = 32;
	CBitSet *pbs = GPOS_NEW(pmp) CBitSet(pmp, cSizeBits);
	CBitSet *pbsEmpty = GPOS_NEW(pmp) CBitSet(pmp, cSizeBits);

	GPOS_ASSERT(pbs->FEqual(pbsEmpty));
	GPOS_ASSERT(pbsEmpty->FEqual(pbs));

	ULONG cInserts = 10;
	for (ULONG i = 0; i < cInserts; i++)
	{
		pbs->FExchangeSet(i * cSizeBits);

		GPOS_ASSERT(i + 1 == pbs->CElements());
	}

	for (ULONG i = 0; i < cInserts; i++)
	{
		// cleans up empty links
		pbs->FExchangeClear(i * cSizeBits);

		GPOS_ASSERT(cInserts - i - 1 == pbs->CElements());
	}

	GPOS_ASSERT(pbs->FEqual(pbsEmpty));
	GPOS_ASSERT(pbsEmpty->FEqual(pbs));

	pbs->Release();
	pbsEmpty->Release();

	return GPOS_OK;
}
//---------------------------------------------------------------------------
//	@function:
//		CConfigParamMapping::PbsPack
//
//	@doc:
//		Pack the GPDB config params into a bitset
//
//---------------------------------------------------------------------------
CBitSet *
CConfigParamMapping::PbsPack
	(
	IMemoryPool *pmp,
	ULONG ulXforms // number of available xforms
	)
{
	CBitSet *pbs = New(pmp) CBitSet(pmp, EopttraceSentinel);

	for (ULONG ul = 0; ul < GPOS_ARRAY_SIZE(m_elem); ul++)
	{
		SConfigMappingElem elem = m_elem[ul];
		GPOS_ASSERT(!pbs->FBit((ULONG) elem.m_etf) &&
					"trace flag already set");

		BOOL fVal = *elem.m_pfParam;
		if (elem.m_fNegate)
		{
			// negate the value of config param
			fVal = !fVal;
		}

		if (fVal)
		{
#ifdef GPOS_DEBUG
			BOOL fSet =
#endif // GPOS_DEBUG
				pbs->FExchangeSet((ULONG) elem.m_etf);
			GPOS_ASSERT(!fSet);
		}
	}

	// pack disable flags of xforms
	for (ULONG ul = 0; ul < ulXforms; ul++)
	{
		GPOS_ASSERT(!pbs->FBit(EopttraceDisableXformBase + ul) &&
					"xform trace flag already set");

		if (optimizer_xforms[ul])
		{
#ifdef GPOS_DEBUG
			BOOL fSet =
#endif // GPOS_DEBUG
				pbs->FExchangeSet(EopttraceDisableXformBase + ul);
			GPOS_ASSERT(!fSet);
		}
	}

	// disable index-join if the corresponding GUC is turned off
	if (!optimizer_enable_indexjoin)
	{
		CBitSet *pbsIndexJoin = CXform::PbsIndexJoinXforms(pmp);
		pbs->Union(pbsIndexJoin);
		pbsIndexJoin->Release();
	}

	// disable bitmap scan if the corresponding GUC is turned off
	if (!optimizer_enable_bitmapscan)
	{
		CBitSet *pbsBitmapScan = CXform::PbsBitmapIndexXforms(pmp);
		pbs->Union(pbsBitmapScan);
		pbsBitmapScan->Release();
	}

	// disable outerjoin to unionall transformation if GUC is turned off
	if (!optimizer_enable_outerjoin_to_unionall_rewrite)
	{
		 pbs->FExchangeSet(GPOPT_DISABLE_XFORM_TF(CXform::ExfLeftOuter2InnerUnionAllLeftAntiSemiJoin));
	}

	// disable Assert MaxOneRow plans if GUC is turned off
	if (!optimizer_enable_assert_maxonerow)
	{
		 pbs->FExchangeSet(GPOPT_DISABLE_XFORM_TF(CXform::ExfMaxOneRow2Assert));
	}

	if (!optimizer_enable_partial_index)
	{
		CBitSet *pbsHeterogeneousIndex = CXform::PbsHeterogeneousIndexXforms(pmp);
		pbs->Union(pbsHeterogeneousIndex);
		pbsHeterogeneousIndex->Release();
	}

	return pbs;
}