//--------------------------------------------------------------------------- // @function: // CXformSelect2PartialDynamicIndexGet::Transform // // @doc: // Actual transformation // //--------------------------------------------------------------------------- void CXformSelect2PartialDynamicIndexGet::Transform ( CXformContext *pxfctxt, CXformResult *pxfres, CExpression *pexpr ) const { GPOS_ASSERT(NULL != pxfctxt); GPOS_ASSERT(FPromising(pxfctxt->Pmp(), this, pexpr)); GPOS_ASSERT(FCheckPattern(pexpr)); IMemoryPool *pmp = pxfctxt->Pmp(); // extract components CExpression *pexprRelational = (*pexpr)[0]; CExpression *pexprScalar = (*pexpr)[1]; // get the indexes on this relation CLogicalDynamicGet *popGet = CLogicalDynamicGet::PopConvert(pexprRelational->Pop()); if (popGet->FPartial()) { // already a partial dynamic get; do not try to split further return; } CTableDescriptor *ptabdesc = popGet->Ptabdesc(); CMDAccessor *pmda = COptCtxt::PoctxtFromTLS()->Pmda(); const IMDRelation *pmdrel = pmda->Pmdrel(ptabdesc->Pmdid()); const ULONG ulIndices = pmdrel->UlIndices(); if (0 == ulIndices) { // no indexes on the table return; } // array of expressions in the scalar expression DrgPexpr *pdrgpexpr = CPredicateUtils::PdrgpexprConjuncts(pmp, pexprScalar); GPOS_ASSERT(0 < pdrgpexpr->UlLength()); // derive the scalar and relational properties to build set of required columns CColRefSet *pcrsOutput = CDrvdPropRelational::Pdprel(pexpr->PdpDerive())->PcrsOutput(); CColRefSet *pcrsScalarExpr = CDrvdPropScalar::Pdpscalar(pexprScalar->PdpDerive())->PcrsUsed(); CColRefSet *pcrsReqd = GPOS_NEW(pmp) CColRefSet(pmp); pcrsReqd->Include(pcrsOutput); pcrsReqd->Include(pcrsScalarExpr); CPartConstraint *ppartcnstr = popGet->Ppartcnstr(); ppartcnstr->AddRef(); // find a candidate set of partial index combinations DrgPdrgPpartdig *pdrgpdrgppartdig = CXformUtils::PdrgpdrgppartdigCandidates ( pmp, pmda, pdrgpexpr, popGet->PdrgpdrgpcrPart(), pmdrel, ppartcnstr, popGet->PdrgpcrOutput(), pcrsReqd, pcrsScalarExpr, NULL // pcrsAcceptedOuterRefs ); // construct alternative partial index scan plans const ULONG ulCandidates = pdrgpdrgppartdig->UlLength(); for (ULONG ul = 0; ul < ulCandidates; ul++) { DrgPpartdig *pdrgppartdig = (*pdrgpdrgppartdig)[ul]; CreatePartialIndexGetPlan(pmp, pexpr, pdrgppartdig, pmdrel, pxfres); } ppartcnstr->Release(); pcrsReqd->Release(); pdrgpexpr->Release(); pdrgpdrgppartdig->Release(); }