//--------------------------------------------------------------------------- // @function: // CPhysicalComputeScalar::PrsDerive // // @doc: // Derive rewindability // //--------------------------------------------------------------------------- CRewindabilitySpec * CPhysicalComputeScalar::PrsDerive ( IMemoryPool *pmp, CExpressionHandle &exprhdl ) const { CDrvdPropScalar *pdpscalar = exprhdl.Pdpscalar(1 /*ulChildIndex*/); if (pdpscalar->FHasNonScalarFunction() || IMDFunction::EfsVolatile == pdpscalar->Pfp()->Efs()) { // ComputeScalar is not rewindable if it has non-scalar/volatile functions in project list return GPOS_NEW(pmp) CRewindabilitySpec(CRewindabilitySpec::ErtNone /*ert*/); } return PrsDerivePassThruOuter(exprhdl); }
//--------------------------------------------------------------------------- // @function: // CPhysicalComputeScalar::PdsRequired // // @doc: // Compute required distribution of the n-th child // //--------------------------------------------------------------------------- CDistributionSpec * CPhysicalComputeScalar::PdsRequired ( IMemoryPool *pmp, CExpressionHandle &exprhdl, CDistributionSpec *pdsRequired, ULONG ulChildIndex, DrgPdp *, // pdrgpdpCtxt ULONG ulOptReq ) const { GPOS_ASSERT(0 == ulChildIndex); GPOS_ASSERT(2 > ulOptReq); // check if master-only/replicated distribution needs to be requested CDistributionSpec *pds = PdsMasterOnlyOrReplicated(pmp, exprhdl, pdsRequired, ulChildIndex, ulOptReq); if (NULL != pds) { return pds; } CDrvdPropScalar *pdpscalar = exprhdl.Pdpscalar(1 /*ulChildIndex*/); // if a Project operator has a call to a set function, passing a Random distribution through this // Project may have the effect of not distributing the results of the set function to all nodes, // but only to the nodes on which first child of the Project is distributed. // to avoid that, we don't push the distribution requirement in this case and thus, for a random // distribution, the result of the set function is spread uniformly over all nodes if (pdpscalar->FHasNonScalarFunction()) { return GPOS_NEW(pmp) CDistributionSpecAny(); } // if required distribution uses any defined column, it has to be enforced on top of ComputeScalar, // in this case, we request Any distribution from the child CDistributionSpec::EDistributionType edtRequired = pdsRequired->Edt(); if (CDistributionSpec::EdtHashed == edtRequired) { CDistributionSpecHashed *pdshashed = CDistributionSpecHashed::PdsConvert(pdsRequired); CColRefSet *pcrs = pdshashed->PcrsUsed(m_pmp); BOOL fUsesDefinedCols = FUnaryUsesDefinedColumns(pcrs, exprhdl); pcrs->Release(); if (fUsesDefinedCols) { return GPOS_NEW(pmp) CDistributionSpecAny(); } } if (CDistributionSpec::EdtRouted == edtRequired) { CDistributionSpecRouted *pdsrouted = CDistributionSpecRouted::PdsConvert(pdsRequired); CColRefSet *pcrs = GPOS_NEW(m_pmp) CColRefSet(m_pmp); pcrs->Include(pdsrouted->Pcr()); BOOL fUsesDefinedCols = FUnaryUsesDefinedColumns(pcrs, exprhdl); pcrs->Release(); if (fUsesDefinedCols) { return GPOS_NEW(pmp) CDistributionSpecAny(); } } if (0 == ulOptReq) { // Req0: required distribution will be enforced on top of ComputeScalar return GPOS_NEW(pmp) CDistributionSpecAny(); } // Req1: required distribution will be enforced on top of ComputeScalar's child return PdsPassThru(pmp, exprhdl, pdsRequired, ulChildIndex); }