//--------------------------------------------------------------------------- // @function: // CLogicalAssert::Maxcard // // @doc: // Derive max card // //--------------------------------------------------------------------------- CMaxCard CLogicalAssert::Maxcard ( IMemoryPool *, // pmp CExpressionHandle &exprhdl ) const { // in case of a false condition or a contradiction, maxcard should be 1 CExpression *pexprScalar = exprhdl.PexprScalarChild(1); GPOS_ASSERT(NULL != pexprScalar); if (CUtils::FScalarConstFalse(pexprScalar) || CDrvdPropRelational::Pdprel(exprhdl.Pdp())->Ppc()->FContradiction()) { return CMaxCard(1 /*ull*/); } // if Assert operator was generated from MaxOneRow operator, // then a max cardinality of 1 is expected if (NULL != exprhdl.Pgexpr() && CXform::ExfMaxOneRow2Assert == exprhdl.Pgexpr()->ExfidOrigin()) { return CMaxCard(1 /*ull*/); } // pass on max card of first child return exprhdl.Pdprel(0)->Maxcard(); }
//--------------------------------------------------------------------------- // @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: // CPhysicalJoin::FProvidesReqdCols // // @doc: // Helper for checking if required columns are included in output columns // //--------------------------------------------------------------------------- BOOL CPhysicalJoin::FProvidesReqdCols ( CExpressionHandle &exprhdl, CColRefSet *pcrsRequired, ULONG // ulOptReq ) const { GPOS_ASSERT(NULL != pcrsRequired); GPOS_ASSERT(3 == exprhdl.UlArity()); // union columns from relational children CColRefSet *pcrs = GPOS_NEW(m_pmp) CColRefSet(m_pmp); ULONG ulArity = exprhdl.UlArity(); for (ULONG i = 0; i < ulArity - 1; i++) { CColRefSet *pcrsChild = exprhdl.Pdprel(i)->PcrsOutput(); pcrs->Union(pcrsChild); } BOOL fProvidesCols = pcrs->FSubset(pcrsRequired); pcrs->Release(); return fProvidesCols; }
//--------------------------------------------------------------------------- // @function: // CXformInnerApplyWithOuterKey2InnerJoin::Exfp // // @doc: // Compute xform promise for a given expression handle; // //--------------------------------------------------------------------------- CXform::EXformPromise CXformInnerApplyWithOuterKey2InnerJoin::Exfp ( CExpressionHandle &exprhdl ) const { // check if outer child has key and inner child has outer references if (NULL == exprhdl.Pdprel(0)->Pkc() || 0 == exprhdl.Pdprel(1)->PcrsOuter()->CElements()) { return ExfpNone; } return ExfpHigh; }
//--------------------------------------------------------------------------- // @function: // CLogicalUnion::Maxcard // // @doc: // Derive max card // //--------------------------------------------------------------------------- CMaxCard CLogicalUnion::Maxcard ( IMemoryPool *, // pmp CExpressionHandle &exprhdl ) const { const ULONG ulArity = exprhdl.UlArity(); CMaxCard maxcard = exprhdl.Pdprel(0)->Maxcard(); for (ULONG ul = 1; ul < ulArity; ul++) { maxcard += exprhdl.Pdprel(ul)->Maxcard(); } return maxcard; }
//--------------------------------------------------------------------------- // @function: // CLogical::MaxcardDef // // @doc: // Default max card for join and apply operators // //--------------------------------------------------------------------------- CMaxCard CLogical::MaxcardDef ( CExpressionHandle &exprhdl ) { const ULONG ulArity = exprhdl.UlArity(); CMaxCard maxcard = exprhdl.Pdprel(0)->Maxcard(); for (ULONG ul = 1; ul < ulArity - 1; ul++) { if (!exprhdl.FScalarChild(ul)) { maxcard *= exprhdl.Pdprel(ul)->Maxcard(); } } return maxcard; }
//--------------------------------------------------------------------------- // @function: // CLogicalLeftSemiApply::Maxcard // // @doc: // Derive max card // //--------------------------------------------------------------------------- CMaxCard CLogicalLeftSemiApply::Maxcard ( IMemoryPool *, // pmp CExpressionHandle &exprhdl ) const { return CLogical::Maxcard(exprhdl, 2 /*ulScalarIndex*/, exprhdl.Pdprel(0)->Maxcard()); }
//--------------------------------------------------------------------------- // @function: // CLogicalCTEAnchor::Maxcard // // @doc: // Derive max card // //--------------------------------------------------------------------------- CMaxCard CLogicalCTEAnchor::Maxcard ( IMemoryPool *, // pmp CExpressionHandle &exprhdl ) const { // pass on max card of first child return exprhdl.Pdprel(0)->Maxcard(); }
//--------------------------------------------------------------------------- // @function: // CXformJoinAssociativity::Exfp // // @doc: // Compute xform promise for a given expression handle // //--------------------------------------------------------------------------- CXform::EXformPromise CXformJoinAssociativity::Exfp ( CExpressionHandle &exprhdl ) const { if ( GPOPT_MAX_JOIN_DEPTH_FOR_ASSOCIATIVITY < exprhdl.Pdprel()->UlJoinDepth() || // disallow xform beyond max join depth GPOPT_MAX_JOIN_RIGHT_CHILD_DEPTH_FOR_ASSOCIATIVITY < exprhdl.Pdprel(1)->UlJoinDepth() // disallow xform if input is not a left deep tree ) { // restrict associativity to left-deep trees by prohibiting the // transformation when right child's join depth is above threshold return CXform::ExfpNone; } return CXform::ExfpHigh; }
//--------------------------------------------------------------------------- // @function: // CPhysicalCTEConsumer::FProvidesReqdCols // // @doc: // Check if required columns are included in output columns // //--------------------------------------------------------------------------- BOOL CPhysicalCTEConsumer::FProvidesReqdCols ( CExpressionHandle &exprhdl, CColRefSet *pcrsRequired, ULONG // ulOptReq ) const { GPOS_ASSERT(NULL != pcrsRequired); CColRefSet *pcrsOutput = exprhdl.Pdprel()->PcrsOutput(); return pcrsOutput->FSubset(pcrsRequired); }
//--------------------------------------------------------------------------- // @function: // CPhysicalJoin::FOuterProvidesReqdCols // // @doc: // Helper for checking if the outer input of a binary join operator // includes the required columns // //--------------------------------------------------------------------------- BOOL CPhysicalJoin::FOuterProvidesReqdCols ( CExpressionHandle &exprhdl, CColRefSet *pcrsRequired ) { GPOS_ASSERT(NULL != pcrsRequired); GPOS_ASSERT(3 == exprhdl.UlArity() && "expected binary join"); CColRefSet *pcrsOutput = exprhdl.Pdprel(0 /*ulChildIndex*/)->PcrsOutput(); return pcrsOutput->FSubset(pcrsRequired); }
//--------------------------------------------------------------------------- // @function: // CLogicalDifferenceAll::Maxcard // // @doc: // Derive max card // //--------------------------------------------------------------------------- CMaxCard CLogicalDifferenceAll::Maxcard ( IMemoryPool *, // pmp CExpressionHandle &exprhdl ) const { // contradictions produce no rows if (CDrvdPropRelational::Pdprel(exprhdl.Pdp())->Ppc()->FContradiction()) { return CMaxCard(0 /*ull*/); } return exprhdl.Pdprel(0)->Maxcard(); }
//--------------------------------------------------------------------------- // @function: // CPhysicalJoin::FSortColsInOuterChild // // @doc: // Helper for checking if required sort columns come from outer child // //---------------------------------------------------------------------------- BOOL CPhysicalJoin::FSortColsInOuterChild ( IMemoryPool *pmp, CExpressionHandle &exprhdl, COrderSpec *pos ) { GPOS_ASSERT(NULL != pos); CColRefSet *pcrsSort = pos->PcrsUsed(pmp); CColRefSet *pcrsOuterChild = exprhdl.Pdprel(0 /*ulChildIndex*/)->PcrsOutput(); BOOL fSortColsInOuter = pcrsOuterChild->FSubset(pcrsSort); pcrsSort->Release(); return fSortColsInOuter; }
//--------------------------------------------------------------------------- // @function: // CXformInnerJoinWithInnerSelect2PartialDynamicIndexGetApply::Exfp // // @doc: // Compute xform promise for a given expression handle // //--------------------------------------------------------------------------- CXform::EXformPromise CXformInnerJoinWithInnerSelect2PartialDynamicIndexGetApply::Exfp ( CExpressionHandle &exprhdl ) const { if (CXform::ExfpNone == CXformInnerJoin2IndexApply::Exfp(exprhdl)) { return CXform::ExfpNone; } if (exprhdl.Pdprel(1 /*ulChildIndex*/)->FHasPartialIndexes()) { return CXform::ExfpHigh; } return CXform::ExfpNone; }
//--------------------------------------------------------------------------- // @function: // CLogicalSelect::Maxcard // // @doc: // Derive max card // //--------------------------------------------------------------------------- CMaxCard CLogicalSelect::Maxcard ( IMemoryPool *, // pmp CExpressionHandle &exprhdl ) const { // in case of a false condition or a contradiction, maxcard should be zero CExpression *pexprScalar = exprhdl.PexprScalarChild(1); if ((NULL != pexprScalar && CUtils::FScalarConstFalse(pexprScalar)) || CDrvdPropRelational::Pdprel(exprhdl.Pdp())->Ppc()->FContradiction()) { return CMaxCard(0 /*ull*/); } // pass on max card of first child return exprhdl.Pdprel(0)->Maxcard(); }
//--------------------------------------------------------------------------- // @function: // CPhysicalSequence::FProvidesReqdCols // // @doc: // Helper for checking if required columns are included in output columns // //--------------------------------------------------------------------------- BOOL CPhysicalSequence::FProvidesReqdCols ( CExpressionHandle &exprhdl, CColRefSet *pcrsRequired, ULONG // ulOptReq ) const { GPOS_ASSERT(NULL != pcrsRequired); // last child must provide required columns ULONG ulArity = exprhdl.UlArity(); GPOS_ASSERT(0 < ulArity); CColRefSet *pcrsChild = exprhdl.Pdprel(ulArity - 1)->PcrsOutput(); return pcrsChild->FSubset(pcrsRequired); }
//--------------------------------------------------------------------------- // @function: // CLogicalLimit::Maxcard // // @doc: // Derive max card // //--------------------------------------------------------------------------- CMaxCard CLogicalLimit::Maxcard ( IMemoryPool *, // pmp CExpressionHandle &exprhdl ) const { CExpression *pexprCount = exprhdl.PexprScalarChild(2 /*ulChildIndex*/); if (CUtils::FScalarConstInt<IMDTypeInt8>(pexprCount)) { CScalarConst *popScalarConst = CScalarConst::PopConvert(pexprCount->Pop()); IDatumInt8 *pdatumInt8 = dynamic_cast<IDatumInt8 *>(popScalarConst->Pdatum()); return CMaxCard(pdatumInt8->LValue()); } // pass on max card of first child return exprhdl.Pdprel(0)->Maxcard(); }
//--------------------------------------------------------------------------- // @function: // CLogical::UlJoinDepth // // @doc: // Derive join depth // //--------------------------------------------------------------------------- ULONG CLogical::UlJoinDepth ( IMemoryPool *, // pmp CExpressionHandle &exprhdl ) const { const ULONG ulArity = exprhdl.UlArity(); // sum-up join depth of all relational children ULONG ulDepth = 0; for (ULONG ul = 0; ul < ulArity; ul++) { if (!exprhdl.FScalarChild(ul)) { ulDepth = ulDepth + exprhdl.Pdprel(ul)->UlJoinDepth(); } } return ulDepth; }
//--------------------------------------------------------------------------- // @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: // CPhysicalUnionAll::EpetPartitionPropagation // // @doc: // Compute the enforcing type for the operator // //--------------------------------------------------------------------------- CEnfdProp::EPropEnforcingType CPhysicalUnionAll::EpetPartitionPropagation ( CExpressionHandle &exprhdl, const CEnfdPartitionPropagation *pepp ) const { CPartIndexMap *ppimReqd = pepp->PppsRequired()->Ppim(); if (!ppimReqd->FContainsUnresolved()) { // no unresolved partition consumers left return CEnfdProp::EpetUnnecessary; } CPartIndexMap *ppimDrvd = CDrvdPropPlan::Pdpplan(exprhdl.Pdp())->Ppim(); GPOS_ASSERT(NULL != ppimDrvd); BOOL fInScope = pepp->FInScope(m_pmp, ppimDrvd); BOOL fResolved = pepp->FResolved(m_pmp, ppimDrvd); if (fResolved) { // all required partition consumers are resolved return CEnfdProp::EpetUnnecessary; } if (!fInScope) { // some partition consumers are not covered downstream return CEnfdProp::EpetRequired; } DrgPul *pdrgpul = ppimReqd->PdrgpulScanIds(m_pmp); const ULONG ulScanIds = pdrgpul->UlLength(); const ULONG ulArity = exprhdl.UlNonScalarChildren(); for (ULONG ul = 0; ul < ulScanIds; ul++) { ULONG ulScanId = *((*pdrgpul)[ul]); ULONG ulChildrenWithConsumers = 0; for (ULONG ulChildIdx = 0; ulChildIdx < ulArity; ulChildIdx++) { if (exprhdl.Pdprel(ulChildIdx)->Ppartinfo()->FContainsScanId(ulScanId)) { ulChildrenWithConsumers++; } } if (1 < ulChildrenWithConsumers) { // partition consumer exists in more than one child, so enforce it here pdrgpul->Release(); return CEnfdProp::EpetRequired; } } pdrgpul->Release(); // required part propagation can be enforced here or passed to the children return CEnfdProp::EpetOptional; }
//--------------------------------------------------------------------------- // @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()); } } }