private void checkFunctionSignature(Map<Symbol, Aggregation> aggregations) { for (Map.Entry<Symbol, Aggregation> entry : aggregations.entrySet()) { checkSignature(entry.getKey(), entry.getValue().getSignature()); } }
private void checkFunctionSignature(Map<Symbol, Aggregation> aggregations) { for (Map.Entry<Symbol, Aggregation> entry : aggregations.entrySet()) { checkSignature(entry.getKey(), entry.getValue().getSignature()); } }
/** * Rewrite assignments so that inputs are in terms of the output symbols. * <p> * Example: * 'a' := sum('b') => 'a' := sum('a') * 'a' := count(*) => 'a' := count('a') */ private static Map<Symbol, AggregationNode.Aggregation> outputsAsInputs(Map<Symbol, AggregationNode.Aggregation> assignments) { ImmutableMap.Builder<Symbol, AggregationNode.Aggregation> builder = ImmutableMap.builder(); for (Map.Entry<Symbol, AggregationNode.Aggregation> entry : assignments.entrySet()) { Symbol output = entry.getKey(); AggregationNode.Aggregation aggregation = entry.getValue(); checkState(!aggregation.getCall().getOrderBy().isPresent(), "Intermediate aggregation does not support ORDER BY"); builder.put( output, new AggregationNode.Aggregation( new FunctionCall(QualifiedName.of(aggregation.getSignature().getName()), ImmutableList.of(output.toSymbolReference())), aggregation.getSignature(), Optional.empty())); // No mask for INTERMEDIATE } return builder.build(); }
aggregations.put(newSymbol, new Aggregation(functionCall, entry.getValue().getSignature(), Optional.empty()));
aggregations.put(newSymbol, new Aggregation(functionCall, entry.getValue().getSignature(), Optional.empty()));
else if (functionRegistry.getAggregateFunctionImplementation(aggregation.getSignature()).isOrderSensitive()) { aggregations.put(entry); aggregation.getCall().getFilter()); aggregations.put(entry.getKey(), new Aggregation(rewritten, aggregation.getSignature(), aggregation.getMask()));
else if (functionRegistry.getAggregateFunctionImplementation(aggregation.getSignature()).isOrderSensitive()) { aggregations.put(entry); aggregation.getCall().getFilter()); aggregations.put(entry.getKey(), new Aggregation(rewritten, aggregation.getSignature(), aggregation.getMask()));
@Override public Result apply(AggregationNode aggregationNode, Captures captures, Context context) { boolean anyRewritten = false; ImmutableMap.Builder<Symbol, Aggregation> aggregations = ImmutableMap.builder(); for (Map.Entry<Symbol, Aggregation> entry : aggregationNode.getAggregations().entrySet()) { Aggregation aggregation = entry.getValue(); FunctionCall call = (FunctionCall) rewriter.rewrite(aggregation.getCall(), context); aggregations.put( entry.getKey(), new Aggregation(call, aggregation.getSignature(), aggregation.getMask())); if (!aggregation.getCall().equals(call)) { anyRewritten = true; } } if (anyRewritten) { return Result.ofPlanNode(new AggregationNode( aggregationNode.getId(), aggregationNode.getSource(), aggregations.build(), aggregationNode.getGroupingSets(), aggregationNode.getPreGroupedSymbols(), aggregationNode.getStep(), aggregationNode.getHashSymbol(), aggregationNode.getGroupIdSymbol())); } return Result.empty(); } }
@Override public Result apply(AggregationNode aggregationNode, Captures captures, Context context) { boolean anyRewritten = false; ImmutableMap.Builder<Symbol, Aggregation> aggregations = ImmutableMap.builder(); for (Map.Entry<Symbol, Aggregation> entry : aggregationNode.getAggregations().entrySet()) { Aggregation aggregation = entry.getValue(); FunctionCall call = (FunctionCall) rewriter.rewrite(aggregation.getCall(), context); aggregations.put( entry.getKey(), new Aggregation(call, aggregation.getSignature(), aggregation.getMask())); if (!aggregation.getCall().equals(call)) { anyRewritten = true; } } if (anyRewritten) { return Result.ofPlanNode(new AggregationNode( aggregationNode.getId(), aggregationNode.getSource(), aggregations.build(), aggregationNode.getGroupingSets(), aggregationNode.getPreGroupedSymbols(), aggregationNode.getStep(), aggregationNode.getHashSymbol(), aggregationNode.getGroupIdSymbol())); } return Result.empty(); } }
public Parts createPartialAggregations(SymbolAllocator symbolAllocator, FunctionRegistry functionRegistry) { ImmutableMap.Builder<Symbol, Aggregation> partialAggregation = ImmutableMap.builder(); ImmutableMap.Builder<Symbol, Aggregation> finalAggregation = ImmutableMap.builder(); ImmutableMap.Builder<Symbol, Symbol> mappings = ImmutableMap.builder(); for (Map.Entry<Symbol, Aggregation> entry : aggregations.entrySet()) { Aggregation originalAggregation = entry.getValue(); Signature signature = originalAggregation.getSignature(); InternalAggregationFunction function = functionRegistry.getAggregateFunctionImplementation(signature); Symbol partialSymbol = symbolAllocator.newSymbol(signature.getName(), function.getIntermediateType()); mappings.put(entry.getKey(), partialSymbol); partialAggregation.put(partialSymbol, new Aggregation(originalAggregation.getCall(), signature, originalAggregation.getMask())); finalAggregation.put(entry.getKey(), new Aggregation( new FunctionCall(QualifiedName.of(signature.getName()), ImmutableList.of(partialSymbol.toSymbolReference())), signature, Optional.empty())); } groupingSymbols.forEach(symbol -> mappings.put(symbol, symbol)); return new Parts( new StatisticAggregations(partialAggregation.build(), groupingSymbols), new StatisticAggregations(finalAggregation.build(), groupingSymbols), mappings.build()); }
public Parts createPartialAggregations(SymbolAllocator symbolAllocator, FunctionRegistry functionRegistry) { ImmutableMap.Builder<Symbol, Aggregation> partialAggregation = ImmutableMap.builder(); ImmutableMap.Builder<Symbol, Aggregation> finalAggregation = ImmutableMap.builder(); ImmutableMap.Builder<Symbol, Symbol> mappings = ImmutableMap.builder(); for (Map.Entry<Symbol, Aggregation> entry : aggregations.entrySet()) { Aggregation originalAggregation = entry.getValue(); Signature signature = originalAggregation.getSignature(); InternalAggregationFunction function = functionRegistry.getAggregateFunctionImplementation(signature); Symbol partialSymbol = symbolAllocator.newSymbol(signature.getName(), function.getIntermediateType()); mappings.put(entry.getKey(), partialSymbol); partialAggregation.put(partialSymbol, new Aggregation(originalAggregation.getCall(), signature, originalAggregation.getMask())); finalAggregation.put(entry.getKey(), new Aggregation( new FunctionCall(QualifiedName.of(signature.getName()), ImmutableList.of(partialSymbol.toSymbolReference())), signature, Optional.empty())); } groupingSymbols.forEach(symbol -> mappings.put(symbol, symbol)); return new Parts( new StatisticAggregations(partialAggregation.build(), groupingSymbols), new StatisticAggregations(finalAggregation.build(), groupingSymbols), mappings.build()); }
/** * Rewrite assignments so that inputs are in terms of the output symbols. * <p> * Example: * 'a' := sum('b') => 'a' := sum('a') * 'a' := count(*) => 'a' := count('a') */ private static Map<Symbol, AggregationNode.Aggregation> outputsAsInputs(Map<Symbol, AggregationNode.Aggregation> assignments) { ImmutableMap.Builder<Symbol, AggregationNode.Aggregation> builder = ImmutableMap.builder(); for (Map.Entry<Symbol, AggregationNode.Aggregation> entry : assignments.entrySet()) { Symbol output = entry.getKey(); AggregationNode.Aggregation aggregation = entry.getValue(); checkState(!aggregation.getCall().getOrderBy().isPresent(), "Intermediate aggregation does not support ORDER BY"); builder.put( output, new AggregationNode.Aggregation( new FunctionCall(QualifiedName.of(aggregation.getSignature().getName()), ImmutableList.of(output.toSymbolReference())), aggregation.getSignature(), Optional.empty())); // No mask for INTERMEDIATE } return builder.build(); }
@Override public Result apply(AggregationNode parent, Captures captures, Context context) { if (!parent.hasDefaultOutput() || parent.getOutputSymbols().size() != 1) { return Result.empty(); } Map<Symbol, AggregationNode.Aggregation> assignments = parent.getAggregations(); for (Map.Entry<Symbol, AggregationNode.Aggregation> entry : assignments.entrySet()) { AggregationNode.Aggregation aggregation = entry.getValue(); requireNonNull(aggregation, "aggregation is null"); Signature signature = aggregation.getSignature(); FunctionCall functionCall = aggregation.getCall(); if (!"count".equals(signature.getName()) || !functionCall.getArguments().isEmpty()) { return Result.empty(); } } if (!assignments.isEmpty() && isScalar(parent.getSource(), context.getLookup())) { return Result.ofPlanNode(new ValuesNode(parent.getId(), parent.getOutputSymbols(), ImmutableList.of(ImmutableList.of(new LongLiteral("1"))))); } return Result.empty(); } }
@Override public Result apply(AggregationNode parent, Captures captures, Context context) { if (!parent.hasDefaultOutput() || parent.getOutputSymbols().size() != 1) { return Result.empty(); } Map<Symbol, AggregationNode.Aggregation> assignments = parent.getAggregations(); for (Map.Entry<Symbol, AggregationNode.Aggregation> entry : assignments.entrySet()) { AggregationNode.Aggregation aggregation = entry.getValue(); requireNonNull(aggregation, "aggregation is null"); Signature signature = aggregation.getSignature(); FunctionCall functionCall = aggregation.getCall(); if (!"count".equals(signature.getName()) || !functionCall.getArguments().isEmpty()) { return Result.empty(); } } if (!assignments.isEmpty() && isScalar(parent.getSource(), context.getLookup())) { return Result.ofPlanNode(new ValuesNode(parent.getId(), parent.getOutputSymbols(), ImmutableList.of(ImmutableList.of(new LongLiteral("1"))))); } return Result.empty(); } }
private static AggregationNode.Aggregation removeDistinct(AggregationNode.Aggregation aggregation) { checkArgument(aggregation.getCall().isDistinct(), "Expected aggregation to have DISTINCT input"); FunctionCall call = aggregation.getCall(); return new AggregationNode.Aggregation( new FunctionCall( call.getName(), call.getWindow(), call.getFilter(), call.getOrderBy(), false, call.getArguments()), aggregation.getSignature(), aggregation.getMask()); } }
private static AggregationNode.Aggregation removeDistinct(AggregationNode.Aggregation aggregation) { checkArgument(aggregation.getCall().isDistinct(), "Expected aggregation to have DISTINCT input"); FunctionCall call = aggregation.getCall(); return new AggregationNode.Aggregation( new FunctionCall( call.getName(), call.getWindow(), call.getFilter(), call.getOrderBy(), false, call.getArguments()), aggregation.getSignature(), aggregation.getMask()); } }
private static boolean isCountOverConstant(AggregationNode.Aggregation aggregation, Assignments inputs) { Signature signature = aggregation.getSignature(); if (!signature.getName().equals("count") || signature.getArgumentTypes().size() != 1) { return false; } Expression argument = aggregation.getCall().getArguments().get(0); if (argument instanceof SymbolReference) { argument = inputs.get(Symbol.from(argument)); } return argument instanceof Literal && !(argument instanceof NullLiteral); } }
private static boolean isCountOverConstant(AggregationNode.Aggregation aggregation, Assignments inputs) { Signature signature = aggregation.getSignature(); if (!signature.getName().equals("count") || signature.getArgumentTypes().size() != 1) { return false; } Expression argument = aggregation.getCall().getArguments().get(0); if (argument instanceof SymbolReference) { argument = inputs.get(Symbol.from(argument)); } return argument instanceof Literal && !(argument instanceof NullLiteral); } }
private Aggregation map(Aggregation aggregation) { return new Aggregation( (FunctionCall) map(aggregation.getCall()), aggregation.getSignature(), aggregation.getMask().map(this::map)); }
private Aggregation map(Aggregation aggregation) { return new Aggregation( (FunctionCall) map(aggregation.getCall()), aggregation.getSignature(), aggregation.getMask().map(this::map)); }