//--------------------------------------------------------------------------- // @function: // CLogical::PdrgpdrgpcrCreatePartCols // // @doc: // Initialize array of partition columns from the array with their indexes // //--------------------------------------------------------------------------- DrgDrgPcr * CLogical::PdrgpdrgpcrCreatePartCols ( IMemoryPool *pmp, DrgPcr *pdrgpcr, const DrgPul *pdrgpulPart ) { GPOS_ASSERT(NULL != pdrgpcr && "Output columns cannot be NULL"); GPOS_ASSERT(NULL != pdrgpulPart); DrgDrgPcr *pdrgpdrgpcrPart = GPOS_NEW(pmp) DrgDrgPcr(pmp); const ULONG ulPartCols = pdrgpulPart->UlLength(); GPOS_ASSERT(0 < ulPartCols); for (ULONG ul = 0; ul < ulPartCols; ul++) { ULONG ulCol = *((*pdrgpulPart)[ul]); CColRef *pcr = (*pdrgpcr)[ulCol]; DrgPcr * pdrgpcrCurr = GPOS_NEW(pmp) DrgPcr(pmp); pdrgpcrCurr->Append(pcr); pdrgpdrgpcrPart->Append(pdrgpcrCurr); } return pdrgpdrgpcrPart; }
//--------------------------------------------------------------------------- // @function: // CXformImplementDynamicBitmapTableGet::Transform // // @doc: // Actual transformation // //--------------------------------------------------------------------------- void CXformImplementDynamicBitmapTableGet::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(); CLogicalDynamicBitmapTableGet *popLogical = CLogicalDynamicBitmapTableGet::PopConvert(pexpr->Pop()); CTableDescriptor *ptabdesc = popLogical->Ptabdesc(); ptabdesc->AddRef(); CName *pname = GPOS_NEW(pmp) CName(pmp, popLogical->Name()); DrgPcr *pdrgpcrOutput = popLogical->PdrgpcrOutput(); GPOS_ASSERT(NULL != pdrgpcrOutput); pdrgpcrOutput->AddRef(); DrgDrgPcr *pdrgpdrgpcrPart = popLogical->PdrgpdrgpcrPart(); pdrgpdrgpcrPart->AddRef(); CPartConstraint *ppartcnstr = popLogical->Ppartcnstr(); ppartcnstr->AddRef(); CPartConstraint *ppartcnstrRel = popLogical->PpartcnstrRel(); ppartcnstrRel->AddRef(); CPhysicalDynamicBitmapTableScan *popPhysical = GPOS_NEW(pmp) CPhysicalDynamicBitmapTableScan ( pmp, popLogical->FPartial(), ptabdesc, pexpr->Pop()->UlOpId(), pname, popLogical->UlScanId(), pdrgpcrOutput, pdrgpdrgpcrPart, popLogical->UlSecondaryScanId(), ppartcnstr, ppartcnstrRel ); CExpression *pexprCondition = (*pexpr)[0]; CExpression *pexprIndexPath = (*pexpr)[1]; pexprCondition->AddRef(); pexprIndexPath->AddRef(); CExpression *pexprPhysical = GPOS_NEW(pmp) CExpression(pmp, popPhysical, pexprCondition, pexprIndexPath); pxfres->Add(pexprPhysical); }
//--------------------------------------------------------------------------- // @function: // CLogicalSetOp::FMatch // // @doc: // Match function on operator level // //--------------------------------------------------------------------------- BOOL CLogicalSetOp::FMatch ( COperator *pop ) const { if (pop->Eopid() != Eopid()) { return false; } CLogicalSetOp *popSetOp = CLogicalSetOp::PopConvert(pop); DrgDrgPcr *pdrgpdrgpcrInput = popSetOp->PdrgpdrgpcrInput(); const ULONG ulArity = pdrgpdrgpcrInput->UlLength(); if (ulArity != m_pdrgpdrgpcrInput->UlLength() || !m_pdrgpcrOutput->FEqual(popSetOp->PdrgpcrOutput())) { return false; } for (ULONG ul = 0; ul < ulArity; ul++) { if (!(*m_pdrgpdrgpcrInput)[ul]->FEqual((*pdrgpdrgpcrInput)[ul])) { return false; } } return true; }
//--------------------------------------------------------------------------- // @function: // CXformDifferenceAll2LeftAntiSemiJoin::Transform // // @doc: // Actual transformation // //--------------------------------------------------------------------------- void CXformDifferenceAll2LeftAntiSemiJoin::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(); // TODO: , Jan 8th 2013, we currently only handle difference all // operators with two children GPOS_ASSERT(2 == pexpr->UlArity()); // extract components CExpression *pexprLeftChild = (*pexpr)[0]; CExpression *pexprRightChild = (*pexpr)[1]; CLogicalDifferenceAll *popDifferenceAll = CLogicalDifferenceAll::PopConvert(pexpr->Pop()); DrgDrgPcr *pdrgpdrgpcrInput = popDifferenceAll->PdrgpdrgpcrInput(); CExpression *pexprLeftWindow = CXformUtils::PexprWindowWithRowNumber(pmp, pexprLeftChild, (*pdrgpdrgpcrInput)[0]); CExpression *pexprRightWindow = CXformUtils::PexprWindowWithRowNumber(pmp, pexprRightChild, (*pdrgpdrgpcrInput)[1]); DrgDrgPcr *pdrgpdrgpcrInputNew = GPOS_NEW(pmp) DrgDrgPcr(pmp); DrgPcr *pdrgpcrLeftNew = CUtils::PdrgpcrExactCopy(pmp, (*pdrgpdrgpcrInput)[0]); pdrgpcrLeftNew->Append(CXformUtils::PcrProjectElement(pexprLeftWindow, 0 /* row_number window function*/)); DrgPcr *pdrgpcrRightNew = CUtils::PdrgpcrExactCopy(pmp, (*pdrgpdrgpcrInput)[1]); pdrgpcrRightNew->Append(CXformUtils::PcrProjectElement(pexprRightWindow, 0 /* row_number window function*/)); pdrgpdrgpcrInputNew->Append(pdrgpcrLeftNew); pdrgpdrgpcrInputNew->Append(pdrgpcrRightNew); // generate the scalar condition for the left anti-semi join CExpression *pexprScCond = CUtils::PexprConjINDFCond(pmp, pdrgpdrgpcrInputNew); // assemble the new left anti-semi join logical operator CExpression *pexprLASJ = GPOS_NEW(pmp) CExpression ( pmp, GPOS_NEW(pmp) CLogicalLeftAntiSemiJoin(pmp), pexprLeftWindow, pexprRightWindow, pexprScCond ); // clean up pdrgpdrgpcrInputNew->Release(); // add alternative to results pxfres->Add(pexprLASJ); }
//--------------------------------------------------------------------------- // @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: // CPartKeys::PpartkeysRemap // // @doc: // Create a new PartKeys object from the current one by remapping the // keys using the given hashmap // //--------------------------------------------------------------------------- CPartKeys * CPartKeys::PpartkeysRemap ( IMemoryPool *pmp, HMUlCr *phmulcr ) const { GPOS_ASSERT(NULL != phmulcr); DrgDrgPcr *pdrgpdrgpcr = GPOS_NEW(pmp) DrgDrgPcr(pmp); for (ULONG ul = 0; ul < m_ulLevels; ul++) { CColRef *pcr = CUtils::PcrRemap(PcrKey(ul), phmulcr, false /*fMustExist*/); DrgPcr *pdrgpcr = GPOS_NEW(pmp) DrgPcr(pmp); pdrgpcr->Append(pcr); pdrgpdrgpcr->Append(pdrgpcr); } return GPOS_NEW(pmp) CPartKeys(pdrgpdrgpcr); }
//--------------------------------------------------------------------------- // @function: // CPartKeys::PpartkeysCopy // // @doc: // Copy part key into the given memory pool // //--------------------------------------------------------------------------- CPartKeys * CPartKeys::PpartkeysCopy ( IMemoryPool *pmp ) { DrgDrgPcr *pdrgpdrgpcrCopy = GPOS_NEW(pmp) DrgDrgPcr(pmp); const ULONG ulLength = m_pdrgpdrgpcr->UlLength(); for (ULONG ul = 0; ul < ulLength; ul++) { DrgPcr *pdrgpcr = (*m_pdrgpdrgpcr)[ul]; DrgPcr *pdrgpcrCopy = GPOS_NEW(pmp) DrgPcr(pmp); const ULONG ulCols = pdrgpcr->UlLength(); for (ULONG ulCol = 0; ulCol < ulCols; ulCol++) { pdrgpcrCopy->Append((*pdrgpcr)[ulCol]); } pdrgpdrgpcrCopy->Append(pdrgpcrCopy); } return GPOS_NEW(pmp) CPartKeys(pdrgpdrgpcrCopy); }
//--------------------------------------------------------------------------- // @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(); }
//--------------------------------------------------------------------------- // @function: // CPartitionPropagationSpec::AppendEnforcers // // @doc: // Add required enforcers to dynamic array // //--------------------------------------------------------------------------- void CPartitionPropagationSpec::AppendEnforcers ( IMemoryPool *pmp, CExpressionHandle &exprhdl, CReqdPropPlan * #ifdef GPOS_DEBUG prpp #endif // GPOS_DEBUG , DrgPexpr *pdrgpexpr, CExpression *pexpr ) { GPOS_ASSERT(NULL != prpp); GPOS_ASSERT(NULL != pmp); GPOS_ASSERT(NULL != pdrgpexpr); GPOS_ASSERT(NULL != pexpr); DrgPul *pdrgpul = m_ppim->PdrgpulScanIds(pmp); const ULONG ulSize = pdrgpul->UlLength(); for (ULONG ul = 0; ul < ulSize; ul++) { ULONG ulScanId = *((*pdrgpul)[ul]); GPOS_ASSERT(m_ppim->FContains(ulScanId)); if (CPartIndexMap::EpimConsumer != m_ppim->Epim(ulScanId) || 0 < m_ppim->UlExpectedPropagators(ulScanId)) { continue; } if (!FRequiresPartitionPropagation(pmp, pexpr, exprhdl, ulScanId)) { continue; } CExpression *pexprResolver = NULL; IMDId *pmdid = m_ppim->PmdidRel(ulScanId); DrgDrgPcr *pdrgpdrgpcrKeys = NULL; DrgPpartkeys *pdrgppartkeys = m_ppim->Pdrgppartkeys(ulScanId); CPartConstraint *ppartcnstr = m_ppim->PpartcnstrRel(ulScanId); PartCnstrMap *ppartcnstrmap = m_ppim->Ppartcnstrmap(ulScanId); pmdid->AddRef(); ppartcnstr->AddRef(); ppartcnstrmap->AddRef(); pexpr->AddRef(); // check if there is a predicate on this part index id HMUlExpr *phmulexprEqFilter = GPOS_NEW(pmp) HMUlExpr(pmp); HMUlExpr *phmulexprFilter = GPOS_NEW(pmp) HMUlExpr(pmp); CExpression *pexprResidual = NULL; if (m_ppfm->FContainsScanId(ulScanId)) { CExpression *pexprScalar = PexprFilter(pmp, ulScanId); // find out which keys are used in the predicate, in case there are multiple // keys at this point (e.g. from a union of multiple CTE consumers) CColRefSet *pcrsUsed = CDrvdPropScalar::Pdpscalar(pexprScalar->PdpDerive())->PcrsUsed(); const ULONG ulKeysets = pdrgppartkeys->UlLength(); for (ULONG ulKey = 0; NULL == pdrgpdrgpcrKeys && ulKey < ulKeysets; ulKey++) { // get partition key CPartKeys *ppartkeys = (*pdrgppartkeys)[ulKey]; if (ppartkeys->FOverlap(pcrsUsed)) { pdrgpdrgpcrKeys = ppartkeys->Pdrgpdrgpcr(); } } // if we cannot find partition keys mapping the partition predicates, fall back to planner if (NULL == pdrgpdrgpcrKeys) { GPOS_RAISE(gpopt::ExmaGPOPT, gpopt::ExmiUnsatisfiedRequiredProperties); } pdrgpdrgpcrKeys->AddRef(); // split predicates and put them in the appropriate hashmaps SplitPartPredicates(pmp, pexprScalar, pdrgpdrgpcrKeys, phmulexprEqFilter, phmulexprFilter, &pexprResidual); pexprScalar->Release(); } else { // doesn't matter which keys we use here since there is no filter GPOS_ASSERT(1 <= pdrgppartkeys->UlLength()); pdrgpdrgpcrKeys = (*pdrgppartkeys)[0]->Pdrgpdrgpcr(); pdrgpdrgpcrKeys->AddRef(); } pexprResolver = GPOS_NEW(pmp) CExpression ( pmp, GPOS_NEW(pmp) CPhysicalPartitionSelector ( pmp, ulScanId, pmdid, pdrgpdrgpcrKeys, ppartcnstrmap, ppartcnstr, phmulexprEqFilter, phmulexprFilter, pexprResidual ), pexpr ); pdrgpexpr->Append(pexprResolver); } pdrgpul->Release(); }