//--------------------------------------------------------------------------- // @function: // CPhysical::PosDerivePassThruOuter // // @doc: // Helper for common case of sort order derivation // //--------------------------------------------------------------------------- COrderSpec * CPhysical::PosDerivePassThruOuter ( CExpressionHandle &exprhdl ) { COrderSpec *pos = exprhdl.Pdpplan(0 /*child_index*/)->Pos(); pos->AddRef(); return pos; }
//--------------------------------------------------------------------------- // @function: // CPhysicalSequence::PosDerive // // @doc: // Derive sort order // //--------------------------------------------------------------------------- COrderSpec * CPhysicalSequence::PosDerive ( IMemoryPool *, // pmp, CExpressionHandle &exprhdl ) const { // pass through sort order from last child const ULONG ulArity = exprhdl.UlArity(); GPOS_ASSERT(1 <= ulArity); COrderSpec *pos = exprhdl.Pdpplan(ulArity - 1 /*ulChildIndex*/)->Pos(); pos->AddRef(); return pos; }
//--------------------------------------------------------------------------- // @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: // CQueryContext::PqcGenerate // // @doc: // Generate the query context for the given expression and array of // output column ref ids // //--------------------------------------------------------------------------- CQueryContext * CQueryContext::PqcGenerate ( IMemoryPool *mp, CExpression * pexpr, ULongPtrArray *pdrgpulQueryOutputColRefId, CMDNameArray *pdrgpmdname, BOOL fDeriveStats ) { GPOS_ASSERT(NULL != pexpr && NULL != pdrgpulQueryOutputColRefId); CColRefSet *pcrs = GPOS_NEW(mp) CColRefSet(mp); CColRefArray *colref_array = GPOS_NEW(mp) CColRefArray(mp); COptCtxt *poptctxt = COptCtxt::PoctxtFromTLS(); CColumnFactory *col_factory = poptctxt->Pcf(); GPOS_ASSERT(NULL != col_factory); // Collect required column references (colref_array) const ULONG length = pdrgpulQueryOutputColRefId->Size(); for (ULONG ul = 0; ul < length; ul++) { ULONG *pul = (*pdrgpulQueryOutputColRefId)[ul]; GPOS_ASSERT(NULL != pul); CColRef *colref = col_factory->LookupColRef(*pul); GPOS_ASSERT(NULL != colref); pcrs->Include(colref); colref_array->Append(colref); } // Collect required properties (prpp) at the top level: // By default no sort order requirement is added, unless the root operator in // the input logical expression is a LIMIT. This is because Orca always // attaches top level Sort to a LIMIT node. 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(mp) COrderSpec(mp); } CDistributionSpec *pds = NULL; BOOL fDML = CUtils::FLogicalDML(pexpr->Pop()); poptctxt->MarkDMLQuery(fDML); // DML commands do not have distribution requirement. Otherwise the // distribution requirement is Singleton. if (fDML) { pds = GPOS_NEW(mp) CDistributionSpecAny(COperator::EopSentinel); } else { pds = GPOS_NEW(mp) CDistributionSpecSingleton(CDistributionSpecSingleton::EstMaster); } // By default, no rewindability requirement needs to be satisfied at the top level CRewindabilitySpec *prs = GPOS_NEW(mp) CRewindabilitySpec(CRewindabilitySpec::ErtNotRewindable, CRewindabilitySpec::EmhtNoMotion); // Ensure order, distribution and rewindability meet 'satisfy' matching at the top level CEnfdOrder *peo = GPOS_NEW(mp) CEnfdOrder(pos, CEnfdOrder::EomSatisfy); CEnfdDistribution *ped = GPOS_NEW(mp) CEnfdDistribution(pds, CEnfdDistribution::EdmSatisfy); CEnfdRewindability *per = GPOS_NEW(mp) CEnfdRewindability(prs, CEnfdRewindability::ErmSatisfy); // Required CTEs are obtained from the CTEInfo global information in the optimizer context CCTEReq *pcter = poptctxt->Pcteinfo()->PcterProducers(mp); // NB: Partition propagation requirements are not initialized here. They are // constructed later based on derived relation properties (CPartInfo) by // CReqdPropPlan::InitReqdPartitionPropagation(). CReqdPropPlan *prpp = GPOS_NEW(mp) CReqdPropPlan(pcrs, peo, ped, per, pcter); // Finally, create the CQueryContext pdrgpmdname->AddRef(); return GPOS_NEW(mp) CQueryContext(mp, pexprResult, prpp, colref_array, pdrgpmdname, fDeriveStats); }