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