//--------------------------------------------------------------------------- // @function: // CLogical::PcrsDeriveOuter // // @doc: // Derive outer references // //--------------------------------------------------------------------------- CColRefSet * CLogical::PcrsDeriveOuter ( IMemoryPool *pmp, CExpressionHandle &exprhdl, CColRefSet *pcrsUsedAdditional ) { ULONG ulArity = exprhdl.UlArity(); CColRefSet *pcrsOuter = GPOS_NEW(pmp) CColRefSet(pmp); // collect output columns from relational children // and used columns from scalar children CColRefSet *pcrsOutput = GPOS_NEW(pmp) CColRefSet(pmp); CColRefSet *pcrsUsed = GPOS_NEW(pmp) CColRefSet(pmp); for (ULONG i = 0; i < ulArity; i++) { if (exprhdl.FScalarChild(i)) { CDrvdPropScalar *pdpscalar = exprhdl.Pdpscalar(i); pcrsUsed->Union(pdpscalar->PcrsUsed()); } else { CDrvdPropRelational *pdprel = exprhdl.Pdprel(i); pcrsOutput->Union(pdprel->PcrsOutput()); // add outer references from relational children pcrsOuter->Union(pdprel->PcrsOuter()); } } if (NULL != pcrsUsedAdditional) { pcrsUsed->Include(pcrsUsedAdditional); } // outer references are columns used by scalar child // but are not included in the output columns of relational children pcrsOuter->Union(pcrsUsed); pcrsOuter->Exclude(pcrsOutput); pcrsOutput->Release(); pcrsUsed->Release(); return pcrsOuter; }
//--------------------------------------------------------------------------- // @function: // CDecorrelator::FProcess // // @doc: // Main driver for decorrelation of expression // //--------------------------------------------------------------------------- BOOL CDecorrelator::FProcess ( IMemoryPool *pmp, CExpression *pexpr, BOOL fEqualityOnly, CExpression **ppexprDecorrelated, DrgPexpr *pdrgpexprCorrelations ) { GPOS_CHECK_STACK_SIZE; // only correlated Apply can be encountered here GPOS_ASSERT_IMP(CUtils::FApply(pexpr->Pop()), CUtils::FCorrelatedApply(pexpr->Pop()) && "Apply expression is encountered by decorrelator"); CDrvdPropRelational *pdprel = CDrvdPropRelational::Pdprel(pexpr->PdpDerive()); // no outer references? if (0 == pdprel->PcrsOuter()->CElements()) { pexpr->AddRef(); *ppexprDecorrelated = pexpr; return true; } BOOL fSuccess = FProcessOperator(pmp, pexpr, fEqualityOnly, ppexprDecorrelated, pdrgpexprCorrelations); // in case of success make sure there are no outer references left GPOS_ASSERT_IMP ( fSuccess, 0 == CDrvdPropRelational::Pdprel((*ppexprDecorrelated)->PdpDerive())->PcrsOuter()->CElements() ); return fSuccess; }