//--------------------------------------------------------------------------- // @function: // CXformDynamicGet2DynamicTableScan::Transform // // @doc: // Actual transformation // //--------------------------------------------------------------------------- void CXformDynamicGet2DynamicTableScan::Transform ( CXformContext *pxfctxt, CXformResult *pxfres, CExpression *pexpr ) const { GPOS_ASSERT(NULL != pxfctxt); GPOS_ASSERT(FPromising(pxfctxt->Pmp(), this, pexpr)); GPOS_ASSERT(FCheckPattern(pexpr)); CLogicalDynamicGet *popGet = CLogicalDynamicGet::PopConvert(pexpr->Pop()); IMemoryPool *pmp = pxfctxt->Pmp(); // create/extract components for alternative CName *pname = GPOS_NEW(pmp) CName(pmp, popGet->Name()); CTableDescriptor *ptabdesc = popGet->Ptabdesc(); ptabdesc->AddRef(); DrgPcr *pdrgpcrOutput = popGet->PdrgpcrOutput(); GPOS_ASSERT(NULL != pdrgpcrOutput); pdrgpcrOutput->AddRef(); DrgDrgPcr *pdrgpdrgpcrPart = popGet->PdrgpdrgpcrPart(); pdrgpdrgpcrPart->AddRef(); popGet->Ppartcnstr()->AddRef(); popGet->PpartcnstrRel()->AddRef(); // create alternative expression CExpression *pexprAlt = GPOS_NEW(pmp) CExpression ( pmp, GPOS_NEW(pmp) CPhysicalDynamicTableScan ( pmp, popGet->FPartial(), pname, ptabdesc, popGet->UlOpId(), popGet->UlScanId(), pdrgpcrOutput, pdrgpdrgpcrPart, popGet->UlSecondaryScanId(), popGet->Ppartcnstr(), popGet->PpartcnstrRel() ) ); // add alternative to transformation result pxfres->Add(pexprAlt); }
//--------------------------------------------------------------------------- // @function: // CXformSelect2PartialDynamicIndexGet::CreatePartialIndexGetPlan // // @doc: // Create a plan as a union of the given partial index get candidates and // possibly a dynamic table scan // //--------------------------------------------------------------------------- void CXformSelect2PartialDynamicIndexGet::CreatePartialIndexGetPlan ( IMemoryPool *pmp, CExpression *pexpr, DrgPpartdig *pdrgppartdig, const IMDRelation *pmdrel, CXformResult *pxfres ) const { CExpression *pexprRelational = (*pexpr)[0]; CExpression *pexprScalar = (*pexpr)[1]; CLogicalDynamicGet *popGet = CLogicalDynamicGet::PopConvert(pexprRelational->Pop()); DrgPcr *pdrgpcrGet = popGet->PdrgpcrOutput(); const ULONG ulPartialIndexes = pdrgppartdig->UlLength(); DrgDrgPcr *pdrgpdrgpcrInput = GPOS_NEW(pmp) DrgDrgPcr(pmp); DrgPexpr *pdrgpexprInput = GPOS_NEW(pmp) DrgPexpr(pmp); for (ULONG ul = 0; ul < ulPartialIndexes; ul++) { SPartDynamicIndexGetInfo *ppartdig = (*pdrgppartdig)[ul]; const IMDIndex *pmdindex = ppartdig->m_pmdindex; CPartConstraint *ppartcnstr = ppartdig->m_ppartcnstr; DrgPexpr *pdrgpexprIndex = ppartdig->m_pdrgpexprIndex; DrgPexpr *pdrgpexprResidual = ppartdig->m_pdrgpexprResidual; DrgPcr *pdrgpcrNew = pdrgpcrGet; if (0 < ul) { pdrgpcrNew = CUtils::PdrgpcrCopy(pmp, pdrgpcrGet); } else { pdrgpcrNew->AddRef(); } CExpression *pexprDynamicScan = NULL; if (NULL != pmdindex) { pexprDynamicScan = CXformUtils::PexprPartialDynamicIndexGet ( pmp, popGet, pexpr->Pop()->UlOpId(), pdrgpexprIndex, pdrgpexprResidual, pdrgpcrNew, pmdindex, pmdrel, ppartcnstr, NULL, // pcrsAcceptedOuterRefs NULL, // pdrgpcrOuter NULL // pdrgpcrNewOuter ); } else { pexprDynamicScan = PexprSelectOverDynamicGet ( pmp, popGet, pexprScalar, pdrgpcrNew, ppartcnstr ); } GPOS_ASSERT(NULL != pexprDynamicScan); pdrgpdrgpcrInput->Append(pdrgpcrNew); pdrgpexprInput->Append(pexprDynamicScan); } ULONG ulInput = pdrgpexprInput->UlLength(); if (0 < ulInput) { CExpression *pexprResult = NULL; if (1 < ulInput) { pdrgpcrGet->AddRef(); DrgPcr *pdrgpcrOuter = pdrgpcrGet; // construct a new union all operator pexprResult = GPOS_NEW(pmp) CExpression ( pmp, GPOS_NEW(pmp) CLogicalUnionAll(pmp, pdrgpcrOuter, pdrgpdrgpcrInput, popGet->UlScanId()), pdrgpexprInput ); } else { pexprResult = (*pdrgpexprInput)[0]; pexprResult->AddRef(); // clean up pdrgpexprInput->Release(); pdrgpdrgpcrInput->Release(); } // if scalar expression involves the partitioning key, keep a SELECT node // on top for the purposes of partition selection DrgDrgPcr *pdrgpdrgpcrPartKeys = popGet->PdrgpdrgpcrPart(); CExpression *pexprPredOnPartKey = CPredicateUtils::PexprExtractPredicatesOnPartKeys ( pmp, pexprScalar, pdrgpdrgpcrPartKeys, NULL, /*pcrsAllowedRefs*/ true /*fUseConstraints*/ ); if (NULL != pexprPredOnPartKey) { pexprResult = GPOS_NEW(pmp) CExpression(pmp, GPOS_NEW(pmp) CLogicalSelect(pmp), pexprResult, pexprPredOnPartKey); } pxfres->Add(pexprResult); return; } // clean up pdrgpdrgpcrInput->Release(); pdrgpexprInput->Release(); }