//--------------------------------------------------------------------------- // @function: // CXformCollapseGbAgg::Transform // // @doc: // Actual transformation to collapse two cascaded group by operators; // if the top Gb grouping columns are subset of bottom Gb grouping // columns AND both Gb operators do not define agg functions, we can // remove the bottom group by operator // // //--------------------------------------------------------------------------- void CXformCollapseGbAgg::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(); // extract components CLogicalGbAgg *popTopGbAgg = CLogicalGbAgg::PopConvert(pexpr->Pop()); GPOS_ASSERT(0 < popTopGbAgg->Pdrgpcr()->UlLength()); GPOS_ASSERT(popTopGbAgg->FGlobal()); CExpression *pexprRelational = (*pexpr)[0]; CExpression *pexprTopProjectList = (*pexpr)[1]; CLogicalGbAgg *popBottomGbAgg = CLogicalGbAgg::PopConvert(pexprRelational->Pop()); CExpression *pexprChild = (*pexprRelational)[0]; CExpression *pexprBottomProjectList = (*pexprRelational)[1]; if (!popBottomGbAgg->FGlobal()) { // bottom GbAgg must be global to prevent xform from getting applied to splitted GbAggs return; } if (0 < pexprTopProjectList->UlArity() || 0 < pexprBottomProjectList->UlArity()) { // exit if any of the Gb operators has an aggregate function return; } #ifdef GPOS_DEBUG // for two cascaded GbAgg ops with no agg functions, top grouping // columns must be a subset of bottom grouping columns CColRefSet *pcrsTopGrpCols = GPOS_NEW(pmp) CColRefSet(pmp, popTopGbAgg->Pdrgpcr()); CColRefSet *pcrsBottomGrpCols = GPOS_NEW(pmp) CColRefSet(pmp, popBottomGbAgg->Pdrgpcr()); GPOS_ASSERT(pcrsBottomGrpCols->FSubset(pcrsTopGrpCols)); pcrsTopGrpCols->Release(); pcrsBottomGrpCols->Release(); #endif // GPOS_DEBUG pexprChild->AddRef(); CExpression *pexprSelect = CUtils::PexprLogicalSelect(pmp, pexprChild, CPredicateUtils::PexprConjunction(pmp, NULL /*pdrgpexpr*/)); popTopGbAgg->AddRef(); pexprTopProjectList->AddRef(); CExpression *pexprGbAggNew = GPOS_NEW(pmp) CExpression(pmp, popTopGbAgg, pexprSelect, pexprTopProjectList); pxfres->Add(pexprGbAggNew); }
//--------------------------------------------------------------------------- // @function: // CXformPushGbWithHavingBelowJoin::Transform // // @doc: // Actual transformation // //--------------------------------------------------------------------------- void CXformPushGbWithHavingBelowJoin::Transform ( CXformContext *pxfctxt, CXformResult *pxfres, CExpression *pexpr ) const { GPOS_ASSERT(NULL != pxfctxt); GPOS_ASSERT(FPromising(pxfctxt->Pmp(), this, pexpr)); GPOS_ASSERT(FCheckPattern(pexpr)); IMemoryPool *mp = pxfctxt->Pmp(); CExpression *pexprGb = (*pexpr)[0]; CLogicalGbAgg *popGbAgg = CLogicalGbAgg::PopConvert(pexprGb->Pop()); if (!popGbAgg->FGlobal()) { // xform only applies to global aggs return; } CExpression *pexprResult = CXformUtils::PexprPushGbBelowJoin(mp, pexpr); if (NULL != pexprResult) { // add alternative to results pxfres->Add(pexprResult); } }
//--------------------------------------------------------------------------- // @function: // CXformCollapseGbAgg::Exfp // // @doc: // Compute xform promise for a given expression handle; // GbAgg must be global and have non empty grouping columns // //--------------------------------------------------------------------------- CXform::EXformPromise CXformCollapseGbAgg::Exfp ( CExpressionHandle &exprhdl ) const { CLogicalGbAgg *popAgg = CLogicalGbAgg::PopConvert(exprhdl.Pop()); if (!popAgg->FGlobal() || 0 == popAgg->Pdrgpcr()->UlLength()) { return CXform::ExfpNone; } return CXform::ExfpHigh; }
//--------------------------------------------------------------------------- // @function: // CXformPushGbBelowJoin::Exfp // // @doc: // Compute xform promise for a given expression handle; // we only push down global aggregates // //--------------------------------------------------------------------------- CXform::EXformPromise CXformPushGbBelowJoin::Exfp ( CExpressionHandle &exprhdl ) const { CLogicalGbAgg *popGbAgg = CLogicalGbAgg::PopConvert(exprhdl.Pop()); if (!popGbAgg->FGlobal()) { return CXform::ExfpNone; } return CXform::ExfpHigh; }
//--------------------------------------------------------------------------- // @function: // CXformGbAgg2Apply::Exfp // // @doc: // Compute xform promise for a given expression handle; // scalar child must have subquery // //--------------------------------------------------------------------------- CXform::EXformPromise CXformGbAgg2Apply::Exfp ( CExpressionHandle &exprhdl ) const { CLogicalGbAgg *popGbAgg = CLogicalGbAgg::PopConvert(exprhdl.Pop()); if (popGbAgg->FGlobal() && exprhdl.Pdpscalar(1)->FHasSubquery()) { return CXform::ExfpHigh; } return CXform::ExfpNone; }