//--------------------------------------------------------------------------- // @function: // CLogical::PpcDeriveConstraintFromPredicates // // @doc: // Derive constraint property when expression has relational children and // scalar children (predicates) // //--------------------------------------------------------------------------- CPropConstraint * CLogical::PpcDeriveConstraintFromPredicates ( IMemoryPool *pmp, CExpressionHandle &exprhdl ) { DrgPcrs *pdrgpcrs = GPOS_NEW(pmp) DrgPcrs(pmp); DrgPcnstr *pdrgpcnstr = GPOS_NEW(pmp) DrgPcnstr(pmp); // collect constraint properties from relational children // and predicates from scalar children const ULONG ulArity = exprhdl.UlArity(); for (ULONG ul = 0; ul < ulArity; ul++) { if (exprhdl.FScalarChild(ul)) { CExpression *pexprScalar = exprhdl.PexprScalarChild(ul); // make sure it is a predicate... boolop, cmp, nulltest if (NULL == pexprScalar || !CUtils::FPredicate(pexprScalar)) { continue; } DrgPcrs *pdrgpcrsChild = NULL; CConstraint *pcnstr = CConstraint::PcnstrFromScalarExpr(pmp, pexprScalar, &pdrgpcrsChild); if (NULL != pcnstr) { pdrgpcnstr->Append(pcnstr); // merge with the equivalence classes we have so far DrgPcrs *pdrgpcrsMerged = CUtils::PdrgpcrsMergeEquivClasses(pmp, pdrgpcrs, pdrgpcrsChild); pdrgpcrs->Release(); pdrgpcrs = pdrgpcrsMerged; } CRefCount::SafeRelease(pdrgpcrsChild); } else { CDrvdPropRelational *pdprel = exprhdl.Pdprel(ul); CPropConstraint *ppc = pdprel->Ppc(); // equivalence classes coming from child DrgPcrs *pdrgpcrsChild = ppc->PdrgpcrsEquivClasses(); // merge with the equivalence classes we have so far DrgPcrs *pdrgpcrsMerged = CUtils::PdrgpcrsMergeEquivClasses(pmp, pdrgpcrs, pdrgpcrsChild); pdrgpcrs->Release(); pdrgpcrs = pdrgpcrsMerged; // constraint coming from child CConstraint *pcnstr = ppc->Pcnstr(); if (NULL != pcnstr) { pcnstr->AddRef(); pdrgpcnstr->Append(pcnstr); } } } CConstraint *pcnstrNew = CConstraint::PcnstrConjunction(pmp, pdrgpcnstr); return GPOS_NEW(pmp) CPropConstraint(pmp, pdrgpcrs, pcnstrNew); }