//--------------------------------------------------------------------------- // @function: // CXformDifferenceAll2LeftAntiSemiJoin::Transform // // @doc: // Actual transformation // //--------------------------------------------------------------------------- void CXformDifferenceAll2LeftAntiSemiJoin::Transform ( CXformContext *pxfctxt, CXformResult *pxfres, CExpression *pexpr ) const { GPOS_ASSERT(NULL != pxfctxt); GPOS_ASSERT(FPromising(pxfctxt->Pmp(), this, pexpr)); GPOS_ASSERT(FCheckPattern(pexpr)); IMemoryPool *pmp = pxfctxt->Pmp(); // TODO: , Jan 8th 2013, we currently only handle difference all // operators with two children GPOS_ASSERT(2 == pexpr->UlArity()); // extract components CExpression *pexprLeftChild = (*pexpr)[0]; CExpression *pexprRightChild = (*pexpr)[1]; CLogicalDifferenceAll *popDifferenceAll = CLogicalDifferenceAll::PopConvert(pexpr->Pop()); DrgDrgPcr *pdrgpdrgpcrInput = popDifferenceAll->PdrgpdrgpcrInput(); CExpression *pexprLeftWindow = CXformUtils::PexprWindowWithRowNumber(pmp, pexprLeftChild, (*pdrgpdrgpcrInput)[0]); CExpression *pexprRightWindow = CXformUtils::PexprWindowWithRowNumber(pmp, pexprRightChild, (*pdrgpdrgpcrInput)[1]); DrgDrgPcr *pdrgpdrgpcrInputNew = GPOS_NEW(pmp) DrgDrgPcr(pmp); DrgPcr *pdrgpcrLeftNew = CUtils::PdrgpcrExactCopy(pmp, (*pdrgpdrgpcrInput)[0]); pdrgpcrLeftNew->Append(CXformUtils::PcrProjectElement(pexprLeftWindow, 0 /* row_number window function*/)); DrgPcr *pdrgpcrRightNew = CUtils::PdrgpcrExactCopy(pmp, (*pdrgpdrgpcrInput)[1]); pdrgpcrRightNew->Append(CXformUtils::PcrProjectElement(pexprRightWindow, 0 /* row_number window function*/)); pdrgpdrgpcrInputNew->Append(pdrgpcrLeftNew); pdrgpdrgpcrInputNew->Append(pdrgpcrRightNew); // generate the scalar condition for the left anti-semi join CExpression *pexprScCond = CUtils::PexprConjINDFCond(pmp, pdrgpdrgpcrInputNew); // assemble the new left anti-semi join logical operator CExpression *pexprLASJ = GPOS_NEW(pmp) CExpression ( pmp, GPOS_NEW(pmp) CLogicalLeftAntiSemiJoin(pmp), pexprLeftWindow, pexprRightWindow, pexprScCond ); // clean up pdrgpdrgpcrInputNew->Release(); // add alternative to results pxfres->Add(pexprLASJ); }
//--------------------------------------------------------------------------- // @function: // CLogical::PdrgpcrCreateMapping // // @doc: // Create output column mapping given a list of column descriptors and // a pointer to the operator creating that column // //--------------------------------------------------------------------------- DrgPcr * CLogical::PdrgpcrCreateMapping ( IMemoryPool *pmp, const DrgPcoldesc *pdrgpcoldesc, ULONG ulOpSourceId ) const { // get column factory from optimizer context object CColumnFactory *pcf = COptCtxt::PoctxtFromTLS()->Pcf(); ULONG ulCols = pdrgpcoldesc->UlLength(); DrgPcr *pdrgpcr = GPOS_NEW(pmp) DrgPcr(pmp, ulCols); for(ULONG ul = 0; ul < ulCols; ul++) { CColumnDescriptor *pcoldesc = (*pdrgpcoldesc)[ul]; CName name(pmp, pcoldesc->Name()); CColRef *pcr = pcf->PcrCreate(pcoldesc, name, ulOpSourceId); pdrgpcr->Append(pcr); } return pdrgpcr; }
//--------------------------------------------------------------------------- // @function: // CLogical::PdrgpdrgpcrCreatePartCols // // @doc: // Initialize array of partition columns from the array with their indexes // //--------------------------------------------------------------------------- DrgDrgPcr * CLogical::PdrgpdrgpcrCreatePartCols ( IMemoryPool *pmp, DrgPcr *pdrgpcr, const DrgPul *pdrgpulPart ) { GPOS_ASSERT(NULL != pdrgpcr && "Output columns cannot be NULL"); GPOS_ASSERT(NULL != pdrgpulPart); DrgDrgPcr *pdrgpdrgpcrPart = GPOS_NEW(pmp) DrgDrgPcr(pmp); const ULONG ulPartCols = pdrgpulPart->UlLength(); GPOS_ASSERT(0 < ulPartCols); for (ULONG ul = 0; ul < ulPartCols; ul++) { ULONG ulCol = *((*pdrgpulPart)[ul]); CColRef *pcr = (*pdrgpcr)[ulCol]; DrgPcr * pdrgpcrCurr = GPOS_NEW(pmp) DrgPcr(pmp); pdrgpcrCurr->Append(pcr); pdrgpdrgpcrPart->Append(pdrgpcrCurr); } return pdrgpdrgpcrPart; }
//--------------------------------------------------------------------------- // @function: // CPhysicalAgg::PdsRequiredIntermediateAgg // // @doc: // Compute required distribution of the n-th child of an intermediate // aggregate operator // //--------------------------------------------------------------------------- CDistributionSpec * CPhysicalAgg::PdsRequiredIntermediateAgg ( IMemoryPool *pmp, ULONG ulOptReq ) const { GPOS_ASSERT(COperator::EgbaggtypeIntermediate == m_egbaggtype); if (0 == ulOptReq) { return PdsMaximalHashed(pmp, m_pdrgpcr); } DrgPcr *pdrgpcr = GPOS_NEW(pmp) DrgPcr(pmp); const ULONG ulLen = m_pdrgpcr->UlLength() - m_pdrgpcrArgDQA->UlLength(); for (ULONG ul = 0; ul < ulLen; ul++) { CColRef *pcr = (*m_pdrgpcr)[ul]; pdrgpcr->Append(pcr); } CDistributionSpec *pds = PdsMaximalHashed(pmp, pdrgpcr); pdrgpcr->Release(); return pds; }
//--------------------------------------------------------------------------- // @function: // CColRefSet::Pdrgpcr // // @doc: // Convert set into array // //--------------------------------------------------------------------------- DrgPcr * CColRefSet::Pdrgpcr ( IMemoryPool *pmp ) const { DrgPcr *pdrgpcr = GPOS_NEW(pmp) DrgPcr(pmp); CColRefSetIter crsi(*this); while(crsi.FAdvance()) { pdrgpcr->Append(crsi.Pcr()); } return pdrgpcr; }
//--------------------------------------------------------------------------- // @function: // CPartKeys::PpartkeysRemap // // @doc: // Create a new PartKeys object from the current one by remapping the // keys using the given hashmap // //--------------------------------------------------------------------------- CPartKeys * CPartKeys::PpartkeysRemap ( IMemoryPool *pmp, HMUlCr *phmulcr ) const { GPOS_ASSERT(NULL != phmulcr); DrgDrgPcr *pdrgpdrgpcr = GPOS_NEW(pmp) DrgDrgPcr(pmp); for (ULONG ul = 0; ul < m_ulLevels; ul++) { CColRef *pcr = CUtils::PcrRemap(PcrKey(ul), phmulcr, false /*fMustExist*/); DrgPcr *pdrgpcr = GPOS_NEW(pmp) DrgPcr(pmp); pdrgpcr->Append(pcr); pdrgpdrgpcr->Append(pdrgpcr); } return GPOS_NEW(pmp) CPartKeys(pdrgpdrgpcr); }
//--------------------------------------------------------------------------- // @function: // CPartKeys::PpartkeysCopy // // @doc: // Copy part key into the given memory pool // //--------------------------------------------------------------------------- CPartKeys * CPartKeys::PpartkeysCopy ( IMemoryPool *pmp ) { DrgDrgPcr *pdrgpdrgpcrCopy = GPOS_NEW(pmp) DrgDrgPcr(pmp); const ULONG ulLength = m_pdrgpdrgpcr->UlLength(); for (ULONG ul = 0; ul < ulLength; ul++) { DrgPcr *pdrgpcr = (*m_pdrgpdrgpcr)[ul]; DrgPcr *pdrgpcrCopy = GPOS_NEW(pmp) DrgPcr(pmp); const ULONG ulCols = pdrgpcr->UlLength(); for (ULONG ulCol = 0; ulCol < ulCols; ulCol++) { pdrgpcrCopy->Append((*pdrgpcr)[ulCol]); } pdrgpdrgpcrCopy->Append(pdrgpcrCopy); } return GPOS_NEW(pmp) CPartKeys(pdrgpdrgpcrCopy); }
//--------------------------------------------------------------------------- // @function: // CTranslatorDXLToExprUtils::Pdrgpcr // // @doc: // Construct a dynamic array of column references corresponding to the // given col ids // //--------------------------------------------------------------------------- DrgPcr * CTranslatorDXLToExprUtils::Pdrgpcr ( IMemoryPool *pmp, HMUlCr *phmulcr, const DrgPul *pdrgpulColIds ) { GPOS_ASSERT(NULL != pdrgpulColIds); DrgPcr *pdrgpcr = GPOS_NEW(pmp) DrgPcr(pmp); for (ULONG ul = 0; ul < pdrgpulColIds->UlLength(); ul++) { ULONG *pulColId = (*pdrgpulColIds)[ul]; const CColRef *pcr = phmulcr->PtLookup(pulColId); GPOS_ASSERT(NULL != pcr); pdrgpcr->Append(const_cast<CColRef*>(pcr)); } return pdrgpcr; }
//--------------------------------------------------------------------------- // @function: // CQueryContext::PqcGenerate // // @doc: // Generate the query context for the given expression and array of // output column ref ids // //--------------------------------------------------------------------------- CQueryContext * CQueryContext::PqcGenerate ( IMemoryPool *pmp, CExpression * pexpr, DrgPul *pdrgpulQueryOutputColRefId, DrgPmdname *pdrgpmdname, BOOL fDeriveStats ) { GPOS_ASSERT(NULL != pexpr && NULL != pdrgpulQueryOutputColRefId); CColRefSet *pcrs = GPOS_NEW(pmp) CColRefSet(pmp); DrgPcr *pdrgpcr = GPOS_NEW(pmp) DrgPcr(pmp); COptCtxt *poptctxt = COptCtxt::PoctxtFromTLS(); CColumnFactory *pcf = poptctxt->Pcf(); GPOS_ASSERT(NULL != pcf); const ULONG ulLen = pdrgpulQueryOutputColRefId->UlLength(); for (ULONG ul = 0; ul < ulLen; ul++) { ULONG *pul = (*pdrgpulQueryOutputColRefId)[ul]; GPOS_ASSERT(NULL != pul); CColRef *pcr = pcf->PcrLookup(*pul); GPOS_ASSERT(NULL != pcr); pcrs->Include(pcr); pdrgpcr->Append(pcr); } COrderSpec *pos = NULL; CExpression *pexprResult = pexpr; COperator *popTop = PopTop(pexpr); if (COperator::EopLogicalLimit == popTop->Eopid()) { // top level operator is a limit, copy order spec to query context pos = CLogicalLimit::PopConvert(popTop)->Pos(); pos->AddRef(); } else { // no order required pos = GPOS_NEW(pmp) COrderSpec(pmp); } CDistributionSpec *pds = NULL; BOOL fDML = CUtils::FLogicalDML(pexpr->Pop()); poptctxt->MarkDMLQuery(fDML); if (fDML) { pds = GPOS_NEW(pmp) CDistributionSpecAny(COperator::EopSentinel); } else { pds = GPOS_NEW(pmp) CDistributionSpecSingleton(CDistributionSpecSingleton::EstMaster); } CRewindabilitySpec *prs = GPOS_NEW(pmp) CRewindabilitySpec(CRewindabilitySpec::ErtNone /*ert*/); CEnfdOrder *peo = GPOS_NEW(pmp) CEnfdOrder(pos, CEnfdOrder::EomSatisfy); // we require satisfy matching on distribution since final query results must be sent to master CEnfdDistribution *ped = GPOS_NEW(pmp) CEnfdDistribution(pds, CEnfdDistribution::EdmSatisfy); CEnfdRewindability *per = GPOS_NEW(pmp) CEnfdRewindability(prs, CEnfdRewindability::ErmSatisfy); CCTEReq *pcter = poptctxt->Pcteinfo()->PcterProducers(pmp); CReqdPropPlan *prpp = GPOS_NEW(pmp) CReqdPropPlan(pcrs, peo, ped, per, pcter); pdrgpmdname->AddRef(); return GPOS_NEW(pmp) CQueryContext(pmp, pexprResult, prpp, pdrgpcr, pdrgpmdname, fDeriveStats); }
//--------------------------------------------------------------------------- // @function: // CLogical::PpcDeriveConstraintFromTable // // @doc: // Derive constraint property from a table/index get // //--------------------------------------------------------------------------- CPropConstraint * CLogical::PpcDeriveConstraintFromTable ( IMemoryPool *pmp, const CTableDescriptor *ptabdesc, const DrgPcr *pdrgpcrOutput ) { DrgPcrs *pdrgpcrs = GPOS_NEW(pmp) DrgPcrs(pmp); DrgPcnstr *pdrgpcnstr = GPOS_NEW(pmp) DrgPcnstr(pmp); const DrgPcoldesc *pdrgpcoldesc = ptabdesc->Pdrgpcoldesc(); const ULONG ulCols = pdrgpcoldesc->UlLength(); DrgPcr *pdrgpcrNonSystem = GPOS_NEW(pmp) DrgPcr(pmp); for (ULONG ul = 0; ul < ulCols; ul++) { CColumnDescriptor *pcoldesc = (*pdrgpcoldesc)[ul]; CColRef *pcr = (*pdrgpcrOutput)[ul]; // we are only interested in non-system columns that are defined as // being NOT NULL if (pcoldesc->FSystemColumn()) { continue; } pdrgpcrNonSystem->Append(pcr); if (pcoldesc->FNullable()) { continue; } // add a "not null" constraint and an equivalence class CConstraint * pcnstr = CConstraintInterval::PciUnbounded(pmp, pcr, false /*fIncludesNull*/); if (pcnstr == NULL) { continue; } pdrgpcnstr->Append(pcnstr); CColRefSet *pcrsEquiv = GPOS_NEW(pmp) CColRefSet(pmp); pcrsEquiv->Include(pcr); pdrgpcrs->Append(pcrsEquiv); } CMDAccessor *pmda = COptCtxt::PoctxtFromTLS()->Pmda(); const IMDRelation *pmdrel = pmda->Pmdrel(ptabdesc->Pmdid()); const ULONG ulCheckConstraint = pmdrel->UlCheckConstraints(); for (ULONG ul = 0; ul < ulCheckConstraint; ul++) { IMDId *pmdidCheckConstraint = pmdrel->PmdidCheckConstraint(ul); const IMDCheckConstraint *pmdCheckConstraint = pmda->Pmdcheckconstraint(pmdidCheckConstraint); // extract the check constraint expression CExpression *pexprCheckConstraint = pmdCheckConstraint->Pexpr(pmp, pmda, pdrgpcrNonSystem); GPOS_ASSERT(NULL != pexprCheckConstraint); GPOS_ASSERT(CUtils::FPredicate(pexprCheckConstraint)); DrgPcrs *pdrgpcrsChild = NULL; CConstraint *pcnstr = CConstraint::PcnstrFromScalarExpr(pmp, pexprCheckConstraint, &pdrgpcrsChild); if (NULL != pcnstr) { pdrgpcnstr->Append(pcnstr); // merge with the equivalence classes we have so far DrgPcrs *pdrgpcrsMerged = CUtils::PdrgpcrsMergeEquivClasses(pmp, pdrgpcrs, pdrgpcrsChild); pdrgpcrs->Release(); pdrgpcrs = pdrgpcrsMerged; } CRefCount::SafeRelease(pdrgpcrsChild); pexprCheckConstraint->Release(); } pdrgpcrNonSystem->Release(); return GPOS_NEW(pmp) CPropConstraint(pmp, pdrgpcrs, CConstraint::PcnstrConjunction(pmp, pdrgpcnstr)); }