//--------------------------------------------------------------------------- // @function: // CLogical::PosFromIndex // // @doc: // Compute an order spec based on an index // //--------------------------------------------------------------------------- COrderSpec * CLogical::PosFromIndex ( IMemoryPool *pmp, const IMDIndex *pmdindex, DrgPcr *pdrgpcr ) { // compute the order spec COrderSpec *pos = GPOS_NEW(pmp) COrderSpec(pmp); const ULONG ulLenIncludeCols = pmdindex->UlKeys(); for (ULONG ul = 0; ul < ulLenIncludeCols; ul++) { ULONG ulPos = pmdindex->UlKey(ul); CColRef *pcr = (*pdrgpcr)[ulPos]; IMDId *pmdid = pcr->Pmdtype()->PmdidCmp(IMDType::EcmptL); pmdid->AddRef(); // TODO: March 27th 2012; we hard-code NULL treatment // need to revisit pos->Append(pmdid, pcr, COrderSpec::EntLast); } return pos; }
//--------------------------------------------------------------------------- // @function: // CColumnFactoryTest::EresUnittest_Basic // // @doc: // Basic array allocation test // //--------------------------------------------------------------------------- GPOS_RESULT CColumnFactoryTest::EresUnittest_Basic() { CAutoMemoryPool amp; IMemoryPool *pmp = amp.Pmp(); CMDProviderMemory *pmdp = CTestUtils::m_pmdpf; pmdp->AddRef(); CMDAccessor mda(pmp, CMDCache::Pcache()); mda.RegisterProvider(CTestUtils::m_sysidDefault, pmdp); const IMDTypeInt4 *pmdtypeint4 = mda.PtMDType<IMDTypeInt4>(); CColumnFactory cf; // typed colref CColRef *pcrOne = cf.PcrCreate(pmdtypeint4); GPOS_ASSERT(pcrOne == cf.PcrLookup(pcrOne->m_ulId)); cf.Destroy(pcrOne); // typed/named colref CWStringConst strName(GPOS_WSZ_LIT("C_CustKey")); CColRef *pcrTwo = cf.PcrCreate(pmdtypeint4, CName(&strName)); GPOS_ASSERT(pcrTwo == cf.PcrLookup(pcrTwo->m_ulId)); // clone previous colref CColRef *pcrThree = cf.PcrCreate(pcrTwo); GPOS_ASSERT(pcrThree != cf.PcrLookup(pcrTwo->m_ulId)); GPOS_ASSERT(!pcrThree->Name().FEquals(pcrTwo->Name())); cf.Destroy(pcrThree); cf.Destroy(pcrTwo); return GPOS_OK; }
//--------------------------------------------------------------------------- // @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: // CLogicalSetOp::PdrgpcnstrColumn // // @doc: // Get constraints for a given output column from all children // //--------------------------------------------------------------------------- DrgPcnstr * CLogicalSetOp::PdrgpcnstrColumn ( IMemoryPool *pmp, CExpressionHandle &exprhdl, ULONG ulColIndex, ULONG ulStart ) const { DrgPcnstr *pdrgpcnstr = GPOS_NEW(pmp) DrgPcnstr(pmp); CColRef *pcr = (*m_pdrgpcrOutput)[ulColIndex]; if (!CUtils::FConstrainableType(pcr->Pmdtype()->Pmdid())) { return pdrgpcnstr; } const ULONG ulChildren = exprhdl.UlArity(); for (ULONG ul = ulStart; ul < ulChildren; ul++) { CConstraint *pcnstr = PcnstrColumn(pmp, exprhdl, ulColIndex, ul); if (NULL == pcnstr) { pcnstr = CConstraintInterval::PciUnbounded(pmp, pcr, true /*fIsNull*/); } GPOS_ASSERT (NULL != pcnstr); pdrgpcnstr->Append(pcnstr); } return pdrgpcnstr; }
//--------------------------------------------------------------------------- // @function: // CColRefSet::OsPrint // // @doc: // Helper function to print a colref set // //--------------------------------------------------------------------------- IOstream & CColRefSet::OsPrint ( IOstream &os, ULONG ulLenMax ) const { ULONG ulLen = CElements(); ULONG ul = 0; CColRefSetIter crsi(*this); while(crsi.FAdvance() && ul < std::min(ulLen, ulLenMax)) { CColRef *pcr = crsi.Pcr(); pcr->OsPrint(os); if (ul < ulLen - 1) { os << ", "; } ul++; } if (ulLenMax < ulLen) { os << "..."; } return os; }
//--------------------------------------------------------------------------- // @function: // CPhysicalStreamAgg::PosCovering // // @doc: // Construct order spec on grouping column so that it covers required // order spec, the function returns NULL if no covering order spec // can be created // //--------------------------------------------------------------------------- COrderSpec * CPhysicalStreamAgg::PosCovering ( IMemoryPool *mp, COrderSpec *posRequired, CColRefArray *pdrgpcrGrp ) const { GPOS_ASSERT(NULL != posRequired); if (0 == posRequired->UlSortColumns()) { // required order must be non-empty return NULL; } // create a set of required sort columns CColRefSet *pcrsReqd = posRequired->PcrsUsed(mp); COrderSpec *pos = NULL; CColRefSet *pcrsGrpCols = GPOS_NEW(mp) CColRefSet(mp, pdrgpcrGrp); if (pcrsGrpCols->ContainsAll(pcrsReqd)) { // required order columns are included in grouping columns, we can // construct a covering order spec pos = GPOS_NEW(mp) COrderSpec(mp); // extract order expressions from required order const ULONG ulReqdSortCols = posRequired->UlSortColumns(); for (ULONG ul = 0; ul < ulReqdSortCols; ul++) { CColRef *colref = const_cast<CColRef *>(posRequired->Pcr(ul)); IMDId *mdid = posRequired->GetMdIdSortOp(ul); COrderSpec::ENullTreatment ent = posRequired->Ent(ul); mdid->AddRef(); pos->Append(mdid, colref, ent); } // augment order with remaining grouping columns const ULONG size = pdrgpcrGrp->Size(); for (ULONG ul = 0; ul < size; ul++) { CColRef *colref = (*pdrgpcrGrp)[ul]; if (!pcrsReqd->FMember(colref)) { IMDId *mdid = colref->RetrieveType()->GetMdidForCmpType(IMDType::EcmptL); mdid->AddRef(); pos->Append(mdid, colref, COrderSpec::EntLast); } } } pcrsGrpCols->Release(); pcrsReqd->Release(); return pos; }
//--------------------------------------------------------------------------- // @function: // CColRefSet::ExtractColIds // // @doc: // Extract array of column ids from colrefset // //--------------------------------------------------------------------------- void CColRefSet::ExtractColIds ( IMemoryPool *pmp, DrgPul *pdrgpulColIds ) const { CColRefSetIter crsi(*this); while (crsi.FAdvance()) { CColRef *pcr = crsi.Pcr(); ULONG ulColId = pcr->UlId(); pdrgpulColIds->Append(GPOS_NEW(pmp) ULONG(ulColId)); } }
//--------------------------------------------------------------------------- // @function: // CColRef::Pdrgpul // // @doc: // Extract array of colids from array of colrefs // //--------------------------------------------------------------------------- DrgPul * CColRef::Pdrgpul ( IMemoryPool *pmp, DrgPcr *pdrgpcr ) { DrgPul *pdrgpul = GPOS_NEW(pmp) DrgPul(pmp); const ULONG ulLen = pdrgpcr->UlLength(); for (ULONG ul = 0; ul < ulLen; ul++) { CColRef *pcr = (*pdrgpcr)[ul]; pdrgpul->Append(GPOS_NEW(pmp) ULONG(pcr->UlId())); } return pdrgpul; }
//--------------------------------------------------------------------------- // @function: // CQueryContext::SetReqdSystemCols // // @doc: // Collect system columns from output columns // //--------------------------------------------------------------------------- void CQueryContext::SetSystemCols ( IMemoryPool *pmp ) { GPOS_ASSERT(NULL == m_pdrgpcrSystemCols); GPOS_ASSERT(NULL != m_pdrgpcr); m_pdrgpcrSystemCols = GPOS_NEW(pmp) DrgPcr(pmp); const ULONG ulReqdCols = m_pdrgpcr->UlLength(); for (ULONG ul = 0; ul < ulReqdCols; ul++) { CColRef *pcr = (*m_pdrgpcr)[ul]; if (pcr->FSystemCol()) { m_pdrgpcrSystemCols->Append(pcr); } } }
//--------------------------------------------------------------------------- // @function: // CQueryContext::SetReqdSystemCols // // @doc: // Collect system columns from output columns // //--------------------------------------------------------------------------- void CQueryContext::SetSystemCols ( IMemoryPool *mp ) { GPOS_ASSERT(NULL == m_pdrgpcrSystemCols); GPOS_ASSERT(NULL != m_pdrgpcr); m_pdrgpcrSystemCols = GPOS_NEW(mp) CColRefArray(mp); const ULONG ulReqdCols = m_pdrgpcr->Size(); for (ULONG ul = 0; ul < ulReqdCols; ul++) { CColRef *colref = (*m_pdrgpcr)[ul]; if (colref->FSystemCol()) { m_pdrgpcrSystemCols->Append(colref); } } }
//--------------------------------------------------------------------------- // @function: // CLogicalConstTableGet::PdrgpcoldescMapping // // @doc: // Construct column descriptors from column references // //--------------------------------------------------------------------------- DrgPcoldesc * CLogicalConstTableGet::PdrgpcoldescMapping ( IMemoryPool *pmp, DrgPcr *pdrgpcr ) const { GPOS_ASSERT(NULL != pdrgpcr); DrgPcoldesc *pdrgpcoldesc = GPOS_NEW(pmp) DrgPcoldesc(pmp); const ULONG ulLen = pdrgpcr->UlLength(); for (ULONG ul = 0; ul < ulLen; ul++) { CColRef *pcr = (*pdrgpcr)[ul]; ULONG ulLength = ULONG_MAX; if (CColRef::EcrtTable == pcr->Ecrt()) { CColRefTable *pcrTable = CColRefTable::PcrConvert(pcr); ulLength = pcrTable->UlWidth(); } CColumnDescriptor *pcoldesc = GPOS_NEW(pmp) CColumnDescriptor ( pmp, pcr->Pmdtype(), pcr->Name(), ul + 1, //iAttno true, // FNullable ulLength ); pdrgpcoldesc->Append(pcoldesc); } return pdrgpcoldesc; }
//--------------------------------------------------------------------------- // @function: // CPhysicalStreamAgg::InitOrderSpec // // @doc: // Initialize the order spec using the given array of columns // //--------------------------------------------------------------------------- void CPhysicalStreamAgg::InitOrderSpec ( IMemoryPool *mp, CColRefArray *pdrgpcrOrder ) { GPOS_ASSERT(NULL != pdrgpcrOrder); CRefCount::SafeRelease(m_pos); m_pos = GPOS_NEW(mp) COrderSpec(mp); const ULONG size = pdrgpcrOrder->Size(); for (ULONG ul = 0; ul < size; ul++) { CColRef *colref = (*pdrgpcrOrder)[ul]; // TODO: 12/21/2011 - ; this seems broken: a colref must not embed // a pointer to a cached object gpmd::IMDId *mdid = colref->RetrieveType()->GetMdidForCmpType(IMDType::EcmptL); mdid->AddRef(); m_pos->Append(mdid, colref, COrderSpec::EntLast); } }
//--------------------------------------------------------------------------- // @function: // CConstraint::PcnstrFromScalarExpr // // @doc: // Create constraint from scalar expression and pass back any discovered // equivalence classes // //--------------------------------------------------------------------------- CConstraint * CConstraint::PcnstrFromScalarExpr ( IMemoryPool *pmp, CExpression *pexpr, DrgPcrs **ppdrgpcrs // output equivalence classes ) { GPOS_ASSERT(NULL != pexpr); GPOS_ASSERT(pexpr->Pop()->FScalar()); GPOS_ASSERT(NULL != ppdrgpcrs); GPOS_ASSERT(NULL == *ppdrgpcrs); (void) pexpr->PdpDerive(); CDrvdPropScalar *pdpScalar = CDrvdPropScalar::Pdpscalar(pexpr->Pdp(CDrvdProp::EptScalar)); CColRefSet *pcrs = pdpScalar->PcrsUsed(); ULONG ulCols = pcrs->CElements(); if (0 == ulCols) { // TODO: - May 29, 2012: in case of an expr with no columns (e.g. 1 < 2), // possibly evaluate the expression, and return a "TRUE" or "FALSE" constraint return NULL; } if (1 == ulCols) { CColRef *pcr = pcrs->PcrFirst(); if (!CUtils::FConstrainableType(pcr->Pmdtype()->Pmdid())) { return NULL; } CConstraint *pcnstr = NULL; *ppdrgpcrs = GPOS_NEW(pmp) DrgPcrs(pmp); // first, try creating a single interval constraint from the expression pcnstr = CConstraintInterval::PciIntervalFromScalarExpr(pmp, pexpr, pcr); if (NULL == pcnstr && CUtils::FScalarArrayCmp(pexpr)) { // if the interval creation failed, try creating a disjunction or conjunction // of several interval constraints in the array case pcnstr = PcnstrFromScalarArrayCmp(pmp, pexpr, pcr); } if (NULL != pcnstr) { AddColumnToEquivClasses(pmp, pcr, ppdrgpcrs); } return pcnstr; } switch (pexpr->Pop()->Eopid()) { case COperator::EopScalarBoolOp: return PcnstrFromScalarBoolOp(pmp, pexpr, ppdrgpcrs); case COperator::EopScalarCmp: return PcnstrFromScalarCmp(pmp, pexpr, ppdrgpcrs); default: return NULL; } }
//--------------------------------------------------------------------------- // @function: // CColRefSetIterTest::EresUnittest_Basics // // @doc: // Testing ctors/dtor; and pcr decoding; // Other functionality already tested in vanilla CBitSetIter; // //--------------------------------------------------------------------------- GPOS_RESULT CColRefSetIterTest::EresUnittest_Basics() { CAutoMemoryPool amp; IMemoryPool *pmp = amp.Pmp(); // Setup an MD cache with a file-based provider CMDProviderMemory *pmdp = CTestUtils::m_pmdpf; pmdp->AddRef(); CMDAccessor mda(pmp, CMDCache::Pcache()); mda.RegisterProvider(CTestUtils::m_sysidDefault, pmdp); // install opt context in TLS CAutoOptCtxt aoc ( pmp, &mda, NULL /* pceeval */, CTestUtils::Pcm(pmp) ); // get column factory from optimizer context object CColumnFactory *pcf = COptCtxt::PoctxtFromTLS()->Pcf(); CColRefSet *pcrs = GPOS_NEW(pmp) CColRefSet(pmp); CWStringConst strName(GPOS_WSZ_LIT("Test Column")); CName name(&strName); // create a int4 datum const IMDTypeInt4 *pmdtypeint4 = mda.PtMDType<IMDTypeInt4>(); ULONG ulCols = 10; for(ULONG i = 0; i < ulCols; i++) { CColRef *pcr = pcf->PcrCreate(pmdtypeint4, name); pcrs->Include(pcr); GPOS_ASSERT(pcrs->FMember(pcr)); } GPOS_ASSERT(pcrs->CElements() == ulCols); ULONG ulCount = 0; CColRefSetIter crsi(*pcrs); while(crsi.FAdvance()) { GPOS_ASSERT((BOOL)crsi); CColRef *pcr = crsi.Pcr(); GPOS_ASSERT(pcr->Name().FEquals(name)); // to avoid unused variable warnings (void) pcr->UlId(); ulCount++; } GPOS_ASSERT(ulCols == ulCount); GPOS_ASSERT(!((BOOL)crsi)); pcrs->Release(); return GPOS_OK; }