//--------------------------------------------------------------------------- // @function: // CPhysicalJoin::PrsDerive // // @doc: // Derive rewindability // //--------------------------------------------------------------------------- CRewindabilitySpec * CPhysicalJoin::PrsDerive ( IMemoryPool *pmp, CExpressionHandle &exprhdl ) const { CRewindabilitySpec *prsOuter = exprhdl.Pdpplan(0 /*ulChildIndex*/)->Prs(); GPOS_ASSERT(NULL != prsOuter); CRewindabilitySpec *prsInner = exprhdl.Pdpplan(1 /*ulChildIndex*/)->Prs(); GPOS_ASSERT(NULL != prsInner); if (CUtils::FCorrelatedNLJoin(exprhdl.Pop())) { // rewindability is not established if correlated join return GPOS_NEW(pmp) CRewindabilitySpec(CRewindabilitySpec::ErtNone /*ert*/); } if (CRewindabilitySpec::ErtNone == prsOuter->Ert() || CRewindabilitySpec::ErtNone == prsInner->Ert()) { // rewindability is not established if any child is non-rewindable return GPOS_NEW(pmp) CRewindabilitySpec(CRewindabilitySpec::ErtNone /*ert*/); } // check if both children have the same rewindability spec if (prsOuter->Ert() == prsInner->Ert()) { prsOuter->AddRef(); return prsOuter; } // one of the two children has general rewindability while the other child has // mark-restore rewindability return GPOS_NEW(pmp) CRewindabilitySpec(CRewindabilitySpec::ErtGeneral /*ert*/); }