//--------------------------------------------------------------------------- // @function: // CLogicalSetOp::PcnstrColumn // // @doc: // Get constraint for a given output column from a given children // //--------------------------------------------------------------------------- CConstraint * CLogicalSetOp::PcnstrColumn ( IMemoryPool *pmp, CExpressionHandle &exprhdl, ULONG ulColIndex, ULONG ulChild ) const { GPOS_ASSERT(ulChild < exprhdl.UlArity()); // constraint from child CConstraint *pcnstrChild = exprhdl.Pdprel(ulChild)->Ppc()->Pcnstr(); if (NULL == pcnstrChild) { return NULL; } // part of constraint on the current input column CConstraint *pcnstrCol = pcnstrChild->Pcnstr(pmp, (*(*m_pdrgpdrgpcrInput)[ulChild])[ulColIndex]); if (NULL == pcnstrCol) { return NULL; } // make a copy of this constraint but for the output column instead CConstraint *pcnstrOutput = pcnstrCol->PcnstrRemapForColumn(pmp, (*m_pdrgpcrOutput)[ulColIndex]); pcnstrCol->Release(); return pcnstrOutput; }
//--------------------------------------------------------------------------- // @function: // CConstraintConjunction::Pcnstr // // @doc: // Return constraint on a given column set // //--------------------------------------------------------------------------- CConstraint * CConstraintConjunction::Pcnstr ( IMemoryPool *mp, CColRefSet *pcrs ) { const ULONG length = m_pdrgpcnstr->Size(); CConstraintArray *pdrgpcnstr = GPOS_NEW(mp) CConstraintArray(mp); for (ULONG ul = 0; ul < length; ul++) { CConstraint *pcnstr = (*m_pdrgpcnstr)[ul]; if (pcnstr->PcrsUsed()->IsDisjoint(pcrs)) { continue; } // the part of the child that references these columns CConstraint *pcnstrCol = pcnstr->Pcnstr(mp, pcrs); if (NULL != pcnstrCol) { pdrgpcnstr->Append(pcnstrCol); } } return CConstraint::PcnstrConjunction(mp, pdrgpcnstr); }
//--------------------------------------------------------------------------- // @function: // CLogical::PpcDeriveConstraintRestrict // // @doc: // Derive constraint property only on the given columns // //--------------------------------------------------------------------------- CPropConstraint * CLogical::PpcDeriveConstraintRestrict ( IMemoryPool *pmp, CExpressionHandle &exprhdl, CColRefSet *pcrsOutput ) { // constraint property from relational child CPropConstraint *ppc = exprhdl.Pdprel(0)->Ppc(); DrgPcrs *pdrgpcrs = ppc->PdrgpcrsEquivClasses(); // construct new array of equivalence classes DrgPcrs *pdrgpcrsNew = GPOS_NEW(pmp) DrgPcrs(pmp); const ULONG ulLen = pdrgpcrs->UlLength(); for (ULONG ul = 0; ul < ulLen; ul++) { CColRefSet *pcrsEquiv = GPOS_NEW(pmp) CColRefSet(pmp); pcrsEquiv->Include((*pdrgpcrs)[ul]); pcrsEquiv->Intersection(pcrsOutput); if (0 < pcrsEquiv->CElements()) { pdrgpcrsNew->Append(pcrsEquiv); } else { pcrsEquiv->Release(); } } CConstraint *pcnstrChild = ppc->Pcnstr(); if (NULL == pcnstrChild) { return GPOS_NEW(pmp) CPropConstraint(pmp, pdrgpcrsNew, NULL); } DrgPcnstr *pdrgpcnstr = GPOS_NEW(pmp) DrgPcnstr(pmp); // include only constraints on given columns CColRefSetIter crsi(*pcrsOutput); while (crsi.FAdvance()) { CColRef *pcr = crsi.Pcr(); CConstraint *pcnstrCol = pcnstrChild->Pcnstr(pmp, pcr); if (NULL == pcnstrCol) { continue; } if (pcnstrCol->FUnbounded()) { pcnstrCol->Release(); continue; } pdrgpcnstr->Append(pcnstrCol); } CConstraint *pcnstr = CConstraint::PcnstrConjunction(pmp, pdrgpcnstr); return GPOS_NEW(pmp) CPropConstraint(pmp, pdrgpcrsNew, pcnstr); }