public static Aggregation translateAggregateCall ( final PlannerContext plannerContext , final DruidQuerySignature querySignature , final RexBuilder rexBuilder , final Project project , final List < Aggregation > existingAggregations , final String name , final AggregateCall call , final boolean finalizeAggregations ) { final DimFilter filter ; if ( call . filterArg >= 0 ) { // AGG(xxx) FILTER(WHERE yyy) if ( project == null ) { // We need some kind of projection to support filtered aggregations. return null ; } final RexNode expression = project . getChildExps ( ) . get ( call . filterArg ) ; final DimFilter nonOptimizedFilter = Expressions . toFilter ( plannerContext , querySignature , expression ) ; if ( nonOptimizedFilter == null ) { return null ; } else { filter = Filtration . create ( nonOptimizedFilter ) . optimizeFilterOnly ( querySignature ) . getDimFilter ( ) ; } } else { filter = null ; } final SqlAggregator sqlAggregator = plannerContext . getOperatorTable ( ) . lookupAggregator ( call . getAggregation ( ) ) ; if ( sqlAggregator == null ) { return null ; } // Compute existingAggregations for SqlAggregator impls that want it. final List < Aggregation > existingAggregationsWithSameFilter = new ArrayList <> ( ) ; for ( Aggregation existingAggregation : existingAggregations ) { if ( filter == null ) { final boolean doesMatch = existingAggregation . getAggregatorFactories ( ) . stream ( ) . noneMatch ( factory -> factory instanceof FilteredAggregatorFactory ) ; if ( doesMatch ) { existingAggregationsWithSameFilter . add ( existingAggregation ) ; } } else { final boolean doesMatch = existingAggregation . getAggregatorFactories ( ) . stream ( ) . allMatch ( factory -> factory instanceof FilteredAggregatorFactory && ( ( FilteredAggregatorFactory ) factory ) . getFilter ( ) . equals ( filter ) ) ; if ( doesMatch ) { existingAggregationsWithSameFilter . add ( Aggregation . create ( existingAggregation . getVirtualColumns ( ) , existingAggregation . getAggregatorFactories ( ) . stream ( ) . map ( factory -> ( ( FilteredAggregatorFactory ) factory ) . getAggregator ( ) ) . collect ( Collectors . toList ( ) ) , existingAggregation . getPostAggregator ( ) ) ) ; } } } final Aggregation retVal = sqlAggregator . toDruidAggregation ( plannerContext , querySignature , rexBuilder , name , call , project , existingAggregationsWithSameFilter , finalizeAggregations ) ; if ( retVal == null ) { return null ; } else { // Check if this refers to the existingAggregationsWithSameFilter. If so, no need to apply the filter. if ( isUsingExistingAggregation ( retVal , existingAggregationsWithSameFilter ) ) { return retVal ; } else { return retVal . filter ( querySignature , filter ) ; } } }
Translate an AggregateCall to Druid equivalents .