//--------------------------------------------------------------------------- // @function: // CPhysicalComputeScalar::EpetRewindability // // @doc: // Return the enforcing type for rewindability property based on this operator // //--------------------------------------------------------------------------- CEnfdProp::EPropEnforcingType CPhysicalComputeScalar::EpetRewindability ( CExpressionHandle &exprhdl, const CEnfdRewindability *per ) const { CColRefSet *pcrsUsed = exprhdl.Pdpscalar(1 /*ulChidIndex*/)->PcrsUsed(); CColRefSet *pcrsCorrelatedApply = exprhdl.Pdprel()->PcrsCorrelatedApply(); if (!pcrsUsed->FDisjoint(pcrsCorrelatedApply)) { // columns are used from inner children of correlated-apply expressions, // this means that a subplan occurs below the Project operator, // in this case, rewindability needs to be enforced on operator's output return CEnfdProp::EpetRequired; } CRewindabilitySpec *prs = CDrvdPropPlan::Pdpplan(exprhdl.Pdp())->Prs(); if (per->FCompatible(prs)) { // required distribution is already provided return CEnfdProp::EpetUnnecessary; } // rewindability is enforced on operator's output return CEnfdProp::EpetRequired; }
//--------------------------------------------------------------------------- // @function: // CXformImplementAssert::Exfp // // @doc: // Compute xform promise level for a given expression handle; // //--------------------------------------------------------------------------- CXform::EXformPromise CXformImplementAssert::Exfp ( CExpressionHandle &exprhdl ) const { if(exprhdl.Pdpscalar(1)->FHasSubquery()) { return CXform::ExfpNone; } return CXform::ExfpHigh; }
//--------------------------------------------------------------------------- // @function: // CXformSelect2PartialDynamicIndexGet::Exfp // // @doc: // Compute xform promise for a given expression handle // //--------------------------------------------------------------------------- CXform::EXformPromise CXformSelect2PartialDynamicIndexGet::Exfp ( CExpressionHandle &exprhdl ) const { if (exprhdl.Pdpscalar(1)->FHasSubquery()) { return CXform::ExfpNone; } return CXform::ExfpHigh; }
//--------------------------------------------------------------------------- // @function: // CXformSelect2Filter::Exfp // // @doc: // Compute xform promise level for a given expression handle; // if scalar predicate has a subquery, then we must have an // equivalent logical Apply expression created during exploration; // no need for generating a Filter expression here // //--------------------------------------------------------------------------- CXform::EXformPromise CXformSelect2Filter::Exfp ( CExpressionHandle &exprhdl ) const { if (exprhdl.Pdpscalar(1)->FHasSubquery()) { return CXform::ExfpNone; } return CXform::ExfpHigh; }
//--------------------------------------------------------------------------- // @function: // CXformGbAgg2Apply::Exfp // // @doc: // Compute xform promise for a given expression handle; // scalar child must have subquery // //--------------------------------------------------------------------------- CXform::EXformPromise CXformGbAgg2Apply::Exfp ( CExpressionHandle &exprhdl ) const { CLogicalGbAgg *popGbAgg = CLogicalGbAgg::PopConvert(exprhdl.Pop()); if (popGbAgg->FGlobal() && exprhdl.Pdpscalar(1)->FHasSubquery()) { return CXform::ExfpHigh; } return CXform::ExfpNone; }
//--------------------------------------------------------------------------- // @function: // CXformGbAggWithMDQA2Join::Exfp // // @doc: // Compute xform promise for a given expression handle; // //--------------------------------------------------------------------------- CXform::EXformPromise CXformGbAggWithMDQA2Join::Exfp ( CExpressionHandle &exprhdl ) const { CAutoMemoryPool amp; CLogicalGbAgg *popAgg = CLogicalGbAgg::PopConvert(exprhdl.Pop()); if (COperator::EgbaggtypeGlobal == popAgg->Egbaggtype() && exprhdl.Pdpscalar(1 /*ulChildIndex*/)->FHasMultipleDistinctAggs()) { return CXform::ExfpHigh; } return CXform::ExfpNone; }
//--------------------------------------------------------------------------- // @function: // CXformGbAgg2StreamAgg::Exfp // // @doc: // Compute xform promise for a given expression handle; // grouping columns must be non-empty // //--------------------------------------------------------------------------- CXform::EXformPromise CXformGbAgg2StreamAgg::Exfp ( CExpressionHandle &exprhdl ) const { CLogicalGbAgg *popAgg = CLogicalGbAgg::PopConvert(exprhdl.Pop()); if (0 == popAgg->Pdrgpcr()->UlLength() || !CUtils::FComparisonPossible(popAgg->Pdrgpcr(), IMDType::EcmptL) || exprhdl.Pdpscalar(1 /*ulChildIndex*/)->FHasSubquery()) { // no grouping columns, or no sort operators are available for grouping columns, or // agg functions use subquery arguments return CXform::ExfpNone; } return CXform::ExfpHigh; }
//--------------------------------------------------------------------------- // @function: // CXformExpandNAryJoin::Exfp // // @doc: // Compute xform promise for a given expression handle // //--------------------------------------------------------------------------- CXform::EXformPromise CXformExpandNAryJoin::Exfp ( CExpressionHandle &exprhdl ) const { if (exprhdl.Pdpscalar(exprhdl.UlArity() - 1)->FHasSubquery()) { // subqueries must be unnested before applying xform return CXform::ExfpNone; } #ifdef GPOS_DEBUG CAutoMemoryPool amp; GPOS_ASSERT(!CXformUtils::FJoinPredOnSingleChild(amp.Pmp(), exprhdl) && "join predicates are not pushed down"); #endif // GPOS_DEBUG return CXform::ExfpHigh; }
//--------------------------------------------------------------------------- // @function: // CPhysicalComputeScalar::FProvidesReqdCols // // @doc: // Check if required columns are included in output columns // //--------------------------------------------------------------------------- BOOL CPhysicalComputeScalar::FProvidesReqdCols ( CExpressionHandle &exprhdl, CColRefSet *pcrsRequired, ULONG // ulOptReq ) const { GPOS_ASSERT(NULL != pcrsRequired); GPOS_ASSERT(2 == exprhdl.UlArity()); CColRefSet *pcrs = GPOS_NEW(m_pmp) CColRefSet(m_pmp); // include defined columns by scalar project list pcrs->Union(exprhdl.Pdpscalar(1 /*ulChildIndex*/)->PcrsDefined()); // include output columns of the relational child pcrs->Union(exprhdl.Pdprel(0 /*ulChildIndex*/)->PcrsOutput()); BOOL fProvidesCols = pcrs->FSubset(pcrsRequired); pcrs->Release(); return fProvidesCols; }
//--------------------------------------------------------------------------- // @function: // CPhysicalAgg::FProvidesReqdCols // // @doc: // Check if required columns are included in output columns // //--------------------------------------------------------------------------- BOOL CPhysicalAgg::FProvidesReqdCols ( CExpressionHandle &exprhdl, CColRefSet *pcrsRequired, ULONG // ulOptReq ) const { GPOS_ASSERT(NULL != pcrsRequired); GPOS_ASSERT(2 == exprhdl.UlArity()); CColRefSet *pcrs = GPOS_NEW(m_pmp) CColRefSet(m_pmp); // include grouping columns pcrs->Include(PdrgpcrGroupingCols()); // include defined columns by scalar child pcrs->Union(exprhdl.Pdpscalar(1 /*ulChildIndex*/)->PcrsDefined()); BOOL fProvidesCols = pcrs->FSubset(pcrsRequired); pcrs->Release(); return fProvidesCols; }
//--------------------------------------------------------------------------- // @function: // CDrvdPropScalar::Derive // // @doc: // Derive scalar props // //--------------------------------------------------------------------------- void CDrvdPropScalar::Derive ( IMemoryPool *pmp, CExpressionHandle &exprhdl, CDrvdPropCtxt * // pdpctxt ) { CScalar *popScalar = CScalar::PopConvert(exprhdl.Pop()); // call derivation functions on the operator GPOS_ASSERT(NULL == m_pcrsDefined); m_pcrsDefined = popScalar->PcrsDefined(pmp, exprhdl); GPOS_ASSERT(NULL == m_pcrsSetReturningFunction); m_pcrsSetReturningFunction = popScalar->PcrsSetReturningFunction(pmp, exprhdl); GPOS_ASSERT(NULL == m_pcrsUsed); m_pcrsUsed = popScalar->PcrsUsed(pmp, exprhdl); // derive function properties m_pfp = popScalar->PfpDerive(pmp, exprhdl); // add defined and used columns of children const ULONG ulArity = exprhdl.UlArity(); for (ULONG i = 0; i < ulArity; i++) { // only propagate properties from scalar children if (exprhdl.FScalarChild(i)) { m_pcrsDefined->Union(exprhdl.Pdpscalar(i)->PcrsDefined()); m_pcrsUsed->Union(exprhdl.Pdpscalar(i)->PcrsUsed()); m_pcrsSetReturningFunction->Union(exprhdl.Pdpscalar(i)->PcrsSetReturningFunction()); } else { GPOS_ASSERT(CUtils::FSubquery(popScalar)); // parent operator is a subquery, add outer references // from its relational child as used columns m_pcrsUsed->Union(exprhdl.Pdprel(0)->PcrsOuter()); } } // derive existence of subqueries GPOS_ASSERT(!m_fHasSubquery); m_fHasSubquery = popScalar->FHasSubquery(exprhdl); if (m_fHasSubquery) { m_ppartinfo = popScalar->PpartinfoDerive(pmp, exprhdl); } else { m_ppartinfo = GPOS_NEW(pmp) CPartInfo(pmp); } m_fHasNonScalarFunction = popScalar->FHasNonScalarFunction(exprhdl); if (COperator::EopScalarProjectList == exprhdl.Pop()->Eopid()) { m_ulDistinctAggs = CScalarProjectList::UlDistinctAggs(exprhdl); m_fHasMultipleDistinctAggs = CScalarProjectList::FHasMultipleDistinctAggs(exprhdl); } if (COperator::EopScalarProjectElement == exprhdl.Pop()->Eopid()) { if (m_fHasNonScalarFunction) { CScalarProjectElement *pspeProject = (CScalarProjectElement *)(exprhdl.Pop()); m_pcrsSetReturningFunction->Include(pspeProject->Pcr()); } } }