//--------------------------------------------------------------------------- // @function: // CXformGbAgg2StreamAgg::Transform // // @doc: // Actual transformation // //--------------------------------------------------------------------------- void CXformGbAgg2StreamAgg::Transform ( CXformContext *pxfctxt, CXformResult *pxfres, CExpression *pexpr ) const { GPOS_ASSERT(NULL != pxfctxt); GPOS_ASSERT(FPromising(pxfctxt->Pmp(), this, pexpr)); GPOS_ASSERT(FCheckPattern(pexpr)); CLogicalGbAgg *popAgg = CLogicalGbAgg::PopConvert(pexpr->Pop()); IMemoryPool *pmp = pxfctxt->Pmp(); DrgPcr *pdrgpcr = popAgg->Pdrgpcr(); pdrgpcr->AddRef(); // extract components CExpression *pexprRel = (*pexpr)[0]; CExpression *pexprScalar = (*pexpr)[1]; // addref children pexprRel->AddRef(); pexprScalar->AddRef(); DrgPcr *pdrgpcrArgDQA = popAgg->PdrgpcrArgDQA(); if (0 != pdrgpcrArgDQA->UlSafeLength()) { GPOS_ASSERT(NULL != pdrgpcrArgDQA); pdrgpcrArgDQA->AddRef(); } // create alternative expression CExpression *pexprAlt = GPOS_NEW(pmp) CExpression ( pmp, GPOS_NEW(pmp) CPhysicalStreamAgg ( pmp, pdrgpcr, popAgg->PdrgpcrMinimal(), popAgg->Egbaggtype(), popAgg->FGeneratesDuplicates(), pdrgpcrArgDQA, CXformUtils::FMultiStageAgg(pexpr) ), pexprRel, pexprScalar ); // add alternative to transformation result pxfres->Add(pexprAlt); }
//--------------------------------------------------------------------------- // @function: // CXformGbAggDedup2HashAggDedup::Transform // // @doc: // Actual transformation // //--------------------------------------------------------------------------- void CXformGbAggDedup2HashAggDedup::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(); CLogicalGbAggDeduplicate *popAggDedup = CLogicalGbAggDeduplicate::PopConvert(pexpr->Pop()); DrgPcr *pdrgpcr = popAggDedup->Pdrgpcr(); pdrgpcr->AddRef(); DrgPcr *pdrgpcrKeys = popAggDedup->PdrgpcrKeys(); pdrgpcrKeys->AddRef(); // extract components CExpression *pexprRel = (*pexpr)[0]; CExpression *pexprScalar = (*pexpr)[1]; GPOS_ASSERT(0 == pexprScalar->UlArity()); // addref children pexprRel->AddRef(); pexprScalar->AddRef(); // create alternative expression CExpression *pexprAlt = GPOS_NEW(pmp) CExpression ( pmp, GPOS_NEW(pmp) CPhysicalHashAggDeduplicate ( pmp, pdrgpcr, popAggDedup->PdrgpcrMinimal(), popAggDedup->Egbaggtype(), pdrgpcrKeys, popAggDedup->FGeneratesDuplicates(), CXformUtils::FMultiStageAgg(pexpr) ), pexprRel, pexprScalar ); // add alternative to transformation result pxfres->Add(pexprAlt); }
//--------------------------------------------------------------------------- // @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: // CXformImplementSplit::Transform // // @doc: // Actual transformation // //--------------------------------------------------------------------------- void CXformImplementSplit::Transform ( CXformContext *pxfctxt, CXformResult *pxfres, CExpression *pexpr ) const { GPOS_ASSERT(NULL != pxfctxt); GPOS_ASSERT(FPromising(pxfctxt->Pmp(), this, pexpr)); GPOS_ASSERT(FCheckPattern(pexpr)); CLogicalSplit *popSplit = CLogicalSplit::PopConvert(pexpr->Pop()); IMemoryPool *pmp = pxfctxt->Pmp(); // extract components for alternative DrgPcr *pdrgpcrDelete = popSplit->PdrgpcrDelete(); pdrgpcrDelete->AddRef(); DrgPcr *pdrgpcrInsert = popSplit->PdrgpcrInsert(); pdrgpcrInsert->AddRef(); CColRef *pcrAction = popSplit->PcrAction(); CColRef *pcrCtid = popSplit->PcrCtid(); CColRef *pcrSegmentId = popSplit->PcrSegmentId(); CColRef *pcrTupleOid = popSplit->PcrTupleOid(); // child of Split operator CExpression *pexprChild = (*pexpr)[0]; CExpression *pexprProjList = (*pexpr)[1]; pexprChild->AddRef(); pexprProjList->AddRef(); // create physical Split CExpression *pexprAlt = GPOS_NEW(pmp) CExpression ( pmp, GPOS_NEW(pmp) CPhysicalSplit(pmp, pdrgpcrDelete, pdrgpcrInsert, pcrCtid, pcrSegmentId, pcrAction, pcrTupleOid), pexprChild, pexprProjList ); // add alternative to transformation result pxfres->Add(pexprAlt); }
//--------------------------------------------------------------------------- // @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: // CXformDelete2DML::Transform // // @doc: // Actual transformation // //--------------------------------------------------------------------------- void CXformDelete2DML::Transform ( CXformContext *pxfctxt, CXformResult *pxfres, CExpression *pexpr ) const { GPOS_ASSERT(NULL != pxfctxt); GPOS_ASSERT(FPromising(pxfctxt->Pmp(), this, pexpr)); GPOS_ASSERT(FCheckPattern(pexpr)); CLogicalDelete *popDelete = CLogicalDelete::PopConvert(pexpr->Pop()); IMemoryPool *pmp = pxfctxt->Pmp(); // extract components for alternative CTableDescriptor *ptabdesc = popDelete->Ptabdesc(); ptabdesc->AddRef(); DrgPcr *pdrgpcr = popDelete->Pdrgpcr(); pdrgpcr->AddRef(); CColRef *pcrCtid = popDelete->PcrCtid(); CColRef *pcrSegmentId = popDelete->PcrSegmentId(); // child of delete operator CExpression *pexprChild = (*pexpr)[0]; pexprChild->AddRef(); // create logical DML CExpression *pexprAlt = CXformUtils::PexprLogicalDMLOverProject ( pmp, pexprChild, CLogicalDML::EdmlDelete, ptabdesc, pdrgpcr, pcrCtid, pcrSegmentId ); // add alternative to transformation result pxfres->Add(pexprAlt); }
//--------------------------------------------------------------------------- // @function: // CXformImplementInnerIndexApply::Transform // // @doc: // Actual transformation // //--------------------------------------------------------------------------- void CXformImplementInnerIndexApply::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 *pexprOuter = (*pexpr)[0]; CExpression *pexprInner = (*pexpr)[1]; CExpression *pexprScalar = (*pexpr)[2]; DrgPcr *pdrgpcr = CLogicalInnerIndexApply::PopConvert(pexpr->Pop())->PdrgPcrOuterRefs(); pdrgpcr->AddRef(); // addref all components pexprOuter->AddRef(); pexprInner->AddRef(); pexprScalar->AddRef(); // assemble physical operator CExpression *pexprResult = GPOS_NEW(pmp) CExpression ( pmp, GPOS_NEW(pmp) CPhysicalInnerIndexNLJoin(pmp, pdrgpcr), pexprOuter, pexprInner, pexprScalar ); // add alternative to results pxfres->Add(pexprResult); }
//--------------------------------------------------------------------------- // @function: // CXformImplementConstTableGet::Transform // // @doc: // Actual transformation // //--------------------------------------------------------------------------- void CXformImplementConstTableGet::Transform ( CXformContext *pxfctxt, CXformResult *pxfres, CExpression *pexpr ) const { GPOS_ASSERT(NULL != pxfctxt); GPOS_ASSERT(FPromising(pxfctxt->Pmp(), this, pexpr)); GPOS_ASSERT(FCheckPattern(pexpr)); CLogicalConstTableGet *popConstTableGet = CLogicalConstTableGet::PopConvert(pexpr->Pop()); IMemoryPool *pmp = pxfctxt->Pmp(); // create/extract components for alternative DrgPcoldesc *pdrgpcoldesc = popConstTableGet->Pdrgpcoldesc(); pdrgpcoldesc->AddRef(); DrgPdrgPdatum *pdrgpdrgpdatum = popConstTableGet->Pdrgpdrgpdatum(); pdrgpdrgpdatum->AddRef(); DrgPcr *pdrgpcrOutput = popConstTableGet->PdrgpcrOutput(); pdrgpcrOutput->AddRef(); // create alternative expression CExpression *pexprAlt = GPOS_NEW(pmp) CExpression ( pmp, GPOS_NEW(pmp) CPhysicalConstTableGet(pmp, pdrgpcoldesc, pdrgpdrgpdatum, pdrgpcrOutput) ); // 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(); }
//--------------------------------------------------------------------------- // @function: // CXformSimplifyGbAgg::Transform // // @doc: // Actual transformation to simplify a aggregate expression // //--------------------------------------------------------------------------- void CXformSimplifyGbAgg::Transform ( CXformContext *pxfctxt, CXformResult *pxfres, CExpression *pexpr ) const { GPOS_ASSERT(NULL != pxfctxt); GPOS_ASSERT(NULL != pxfres); GPOS_ASSERT(FPromising(pxfctxt->Pmp(), this, pexpr)); GPOS_ASSERT(FCheckPattern(pexpr)); IMemoryPool *pmp = pxfctxt->Pmp(); if (FDropGbAgg(pmp, pexpr,pxfres)) { // grouping columns could be dropped, GbAgg is transformed to a Select return; } // extract components CLogicalGbAgg *popAgg = CLogicalGbAgg::PopConvert(pexpr->Pop()); CExpression *pexprRelational = (*pexpr)[0]; CExpression *pexprProjectList = (*pexpr)[1]; DrgPcr *pdrgpcr = popAgg->Pdrgpcr(); CColRefSet *pcrsGrpCols = GPOS_NEW(pmp) CColRefSet(pmp); pcrsGrpCols->Include(pdrgpcr); CColRefSet *pcrsCovered = GPOS_NEW(pmp) CColRefSet(pmp); // set of grouping columns covered by FD's CColRefSet *pcrsMinimal = GPOS_NEW(pmp) CColRefSet(pmp); // a set of minimal grouping columns based on FD's DrgPfd *pdrgpfd = CDrvdPropRelational::Pdprel(pexpr->PdpDerive())->Pdrgpfd(); // collect grouping columns FD's const ULONG ulSize = pdrgpfd->UlSafeLength(); for (ULONG ul = 0; ul < ulSize; ul++) { CFunctionalDependency *pfd = (*pdrgpfd)[ul]; if (pfd->FIncluded(pcrsGrpCols)) { pcrsCovered->Include(pfd->PcrsDetermined()); pcrsCovered->Include(pfd->PcrsKey()); pcrsMinimal->Include(pfd->PcrsKey()); } } BOOL fCovered = pcrsCovered->FEqual(pcrsGrpCols); pcrsGrpCols->Release(); pcrsCovered->Release(); if (!fCovered) { // the union of RHS of collected FD's does not cover all grouping columns pcrsMinimal->Release(); return; } // create a new Agg with minimal grouping columns pdrgpcr->AddRef(); CLogicalGbAgg *popAggNew = GPOS_NEW(pmp) CLogicalGbAgg(pmp, pdrgpcr, pcrsMinimal->Pdrgpcr(pmp), popAgg->Egbaggtype()); pcrsMinimal->Release(); GPOS_ASSERT(!popAgg->FMatch(popAggNew) && "Simplified aggregate matches original aggregate"); pexprRelational->AddRef(); pexprProjectList->AddRef(); CExpression *pexprResult = GPOS_NEW(pmp) CExpression(pmp, popAggNew, pexprRelational, pexprProjectList); pxfres->Add(pexprResult); }
//--------------------------------------------------------------------------- // @function: // CXformSplitGbAggDedup::Transform // // @doc: // Actual transformation to expand a global aggregate into a pair of // local and global aggregate // //--------------------------------------------------------------------------- void CXformSplitGbAggDedup::Transform ( CXformContext *pxfctxt, CXformResult *pxfres, CExpression *pexpr ) const { GPOS_ASSERT(NULL != pxfctxt); GPOS_ASSERT(NULL != pxfres); GPOS_ASSERT(FPromising(pxfctxt->Pmp(), this, pexpr)); GPOS_ASSERT(FCheckPattern(pexpr)); IMemoryPool *pmp = pxfctxt->Pmp(); CLogicalGbAggDeduplicate *popAggDedup = CLogicalGbAggDeduplicate::PopConvert(pexpr->Pop()); // extract components CExpression *pexprRelational = (*pexpr)[0]; CExpression *pexprProjectList = (*pexpr)[1]; // check if the transformation is applicable if (!FApplicable(pexprProjectList)) { return; } pexprRelational->AddRef(); CExpression *pexprProjectListLocal = NULL; CExpression *pexprProjectListGlobal = NULL; (void) PopulateLocalGlobalProjectList(pmp, pexprProjectList, &pexprProjectListLocal, &pexprProjectListGlobal); GPOS_ASSERT(NULL != pexprProjectListLocal && NULL != pexprProjectListLocal); DrgPcr *pdrgpcr = popAggDedup->Pdrgpcr(); pdrgpcr->AddRef(); pdrgpcr->AddRef(); DrgPcr *pdrgpcrMinimal = popAggDedup->PdrgpcrMinimal(); if (NULL != pdrgpcrMinimal) { pdrgpcrMinimal->AddRef(); pdrgpcrMinimal->AddRef(); } DrgPcr *pdrgpcrKeys = popAggDedup->PdrgpcrKeys(); pdrgpcrKeys->AddRef(); pdrgpcrKeys->AddRef(); CExpression *pexprLocal = GPOS_NEW(pmp) CExpression ( pmp, GPOS_NEW(pmp) CLogicalGbAggDeduplicate(pmp, pdrgpcr, pdrgpcrMinimal, COperator::EgbaggtypeLocal /*egbaggtype*/, pdrgpcrKeys), pexprRelational, pexprProjectListLocal ); CExpression *pexprGlobal = GPOS_NEW(pmp) CExpression ( pmp, GPOS_NEW(pmp) CLogicalGbAggDeduplicate(pmp, pdrgpcr, pdrgpcrMinimal, COperator::EgbaggtypeGlobal /*egbaggtype*/, pdrgpcrKeys), pexprLocal, pexprProjectListGlobal ); pxfres->Add(pexprGlobal); }