//--------------------------------------------------------------------------- // @function: // CLogical::PosFromIndex // // @doc: // Compute an order spec based on an index // //--------------------------------------------------------------------------- COrderSpec * CLogical::PosFromIndex ( IMemoryPool *pmp, const IMDIndex *pmdindex, DrgPcr *pdrgpcr ) { // compute the order spec COrderSpec *pos = GPOS_NEW(pmp) COrderSpec(pmp); const ULONG ulLenIncludeCols = pmdindex->UlKeys(); for (ULONG ul = 0; ul < ulLenIncludeCols; ul++) { ULONG ulPos = pmdindex->UlKey(ul); CColRef *pcr = (*pdrgpcr)[ulPos]; IMDId *pmdid = pcr->Pmdtype()->PmdidCmp(IMDType::EcmptL); pmdid->AddRef(); // TODO: March 27th 2012; we hard-code NULL treatment // need to revisit pos->Append(pmdid, pcr, COrderSpec::EntLast); } return pos; }
//--------------------------------------------------------------------------- // @function: // CLogicalSetOp::PdrgpcnstrColumn // // @doc: // Get constraints for a given output column from all children // //--------------------------------------------------------------------------- DrgPcnstr * CLogicalSetOp::PdrgpcnstrColumn ( IMemoryPool *pmp, CExpressionHandle &exprhdl, ULONG ulColIndex, ULONG ulStart ) const { DrgPcnstr *pdrgpcnstr = GPOS_NEW(pmp) DrgPcnstr(pmp); CColRef *pcr = (*m_pdrgpcrOutput)[ulColIndex]; if (!CUtils::FConstrainableType(pcr->Pmdtype()->Pmdid())) { return pdrgpcnstr; } const ULONG ulChildren = exprhdl.UlArity(); for (ULONG ul = ulStart; ul < ulChildren; ul++) { CConstraint *pcnstr = PcnstrColumn(pmp, exprhdl, ulColIndex, ul); if (NULL == pcnstr) { pcnstr = CConstraintInterval::PciUnbounded(pmp, pcr, true /*fIsNull*/); } GPOS_ASSERT (NULL != pcnstr); pdrgpcnstr->Append(pcnstr); } return pdrgpcnstr; }
//--------------------------------------------------------------------------- // @function: // CLogicalConstTableGet::PdrgpcoldescMapping // // @doc: // Construct column descriptors from column references // //--------------------------------------------------------------------------- DrgPcoldesc * CLogicalConstTableGet::PdrgpcoldescMapping ( IMemoryPool *pmp, DrgPcr *pdrgpcr ) const { GPOS_ASSERT(NULL != pdrgpcr); DrgPcoldesc *pdrgpcoldesc = GPOS_NEW(pmp) DrgPcoldesc(pmp); const ULONG ulLen = pdrgpcr->UlLength(); for (ULONG ul = 0; ul < ulLen; ul++) { CColRef *pcr = (*pdrgpcr)[ul]; ULONG ulLength = ULONG_MAX; if (CColRef::EcrtTable == pcr->Ecrt()) { CColRefTable *pcrTable = CColRefTable::PcrConvert(pcr); ulLength = pcrTable->UlWidth(); } CColumnDescriptor *pcoldesc = GPOS_NEW(pmp) CColumnDescriptor ( pmp, pcr->Pmdtype(), pcr->Name(), ul + 1, //iAttno true, // FNullable ulLength ); pdrgpcoldesc->Append(pcoldesc); } return pdrgpcoldesc; }
//--------------------------------------------------------------------------- // @function: // CConstraint::PcnstrFromScalarExpr // // @doc: // Create constraint from scalar expression and pass back any discovered // equivalence classes // //--------------------------------------------------------------------------- CConstraint * CConstraint::PcnstrFromScalarExpr ( IMemoryPool *pmp, CExpression *pexpr, DrgPcrs **ppdrgpcrs // output equivalence classes ) { GPOS_ASSERT(NULL != pexpr); GPOS_ASSERT(pexpr->Pop()->FScalar()); GPOS_ASSERT(NULL != ppdrgpcrs); GPOS_ASSERT(NULL == *ppdrgpcrs); (void) pexpr->PdpDerive(); CDrvdPropScalar *pdpScalar = CDrvdPropScalar::Pdpscalar(pexpr->Pdp(CDrvdProp::EptScalar)); CColRefSet *pcrs = pdpScalar->PcrsUsed(); ULONG ulCols = pcrs->CElements(); if (0 == ulCols) { // TODO: - May 29, 2012: in case of an expr with no columns (e.g. 1 < 2), // possibly evaluate the expression, and return a "TRUE" or "FALSE" constraint return NULL; } if (1 == ulCols) { CColRef *pcr = pcrs->PcrFirst(); if (!CUtils::FConstrainableType(pcr->Pmdtype()->Pmdid())) { return NULL; } CConstraint *pcnstr = NULL; *ppdrgpcrs = GPOS_NEW(pmp) DrgPcrs(pmp); // first, try creating a single interval constraint from the expression pcnstr = CConstraintInterval::PciIntervalFromScalarExpr(pmp, pexpr, pcr); if (NULL == pcnstr && CUtils::FScalarArrayCmp(pexpr)) { // if the interval creation failed, try creating a disjunction or conjunction // of several interval constraints in the array case pcnstr = PcnstrFromScalarArrayCmp(pmp, pexpr, pcr); } if (NULL != pcnstr) { AddColumnToEquivClasses(pmp, pcr, ppdrgpcrs); } return pcnstr; } switch (pexpr->Pop()->Eopid()) { case COperator::EopScalarBoolOp: return PcnstrFromScalarBoolOp(pmp, pexpr, ppdrgpcrs); case COperator::EopScalarCmp: return PcnstrFromScalarCmp(pmp, pexpr, ppdrgpcrs); default: return NULL; } }