//--------------------------------------------------------------------------- // @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; }
//--------------------------------------------------------------------------- // @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); }
//--------------------------------------------------------------------------- // @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(); } } }
//--------------------------------------------------------------------------- // @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; }
//--------------------------------------------------------------------------- // @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; }
//--------------------------------------------------------------------------- // @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; }
//--------------------------------------------------------------------------- // @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(); }
//--------------------------------------------------------------------------- // @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; }