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 Predicate<FunctionCall> isAggregationPredicate(FunctionRegistry functionRegistry) { return ((functionCall) -> (functionRegistry.isAggregationFunction(functionCall.getName()) || functionCall.getFilter().isPresent()) && !functionCall.getWindow().isPresent() || functionCall.getOrderBy().isPresent()); }
@Override protected R visitFunctionCall(FunctionCall node, C context) { for (Expression argument : node.getArguments()) { process(argument, context); } if (node.getOrderBy().isPresent()) { process(node.getOrderBy().get(), context); } if (node.getWindow().isPresent()) { process(node.getWindow().get(), context); } if (node.getFilter().isPresent()) { process(node.getFilter().get(), context); } return null; }
public static FunctionCall getCall(CurrentPath node) { return new FunctionCall(QualifiedName.of("$current_path"), ImmutableList.of()); } }
Symbol intermediateSymbol = context.getSymbolAllocator().newSymbol(signature.getName(), function.getIntermediateType()); checkState(!originalAggregation.getCall().getOrderBy().isPresent(), "Aggregate with ORDER BY does not support partial aggregation"); intermediateAggregation.put(intermediateSymbol, new AggregationNode.Aggregation(originalAggregation.getCall(), signature, originalAggregation.getMask())); new FunctionCall( QualifiedName.of(signature.getName()), ImmutableList.<Expression>builder() .add(intermediateSymbol.toSymbolReference()) .addAll(originalAggregation.getCall().getArguments().stream() .filter(LambdaExpression.class::isInstance) .collect(toImmutableList()))
@Override public Expression rewriteFunctionCall(FunctionCall node, Object context, ExpressionTreeRewriter<Object> treeRewriter) { if (node.getName().equals(QualifiedName.of("fail"))) { return new FunctionCall(QualifiedName.of("fail"), ImmutableList.of()); } return node; } }
private static boolean hasSpatialPartitioningAggregation(AggregationNode aggregation) { return aggregation.getAggregations().values().stream() .map(Aggregation::getCall) .anyMatch(call -> call.getName().toString().equals(NAME) && call.getArguments().size() == 1); }
/** * 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(); }
private static boolean isSupportedSpatialFunction(FunctionCall functionCall) { String functionName = functionCall.getName().toString(); return functionName.equalsIgnoreCase(ST_CONTAINS) || functionName.equalsIgnoreCase(ST_WITHIN) || functionName.equalsIgnoreCase(ST_INTERSECTS); }
private static boolean isUsingSymbols(AggregationNode.Aggregation aggregation, Set<Symbol> sourceSymbols) { List<Expression> functionArguments = aggregation.getCall().getArguments(); return sourceSymbols.stream() .map(Symbol::toSymbolReference) .anyMatch(functionArguments::contains); }
private static boolean hasNoDistinctWithFilterOrMask(AggregationNode aggregation) { return aggregation.getAggregations() .values().stream() .noneMatch(e -> e.getCall().isDistinct() && (e.getCall().getFilter().isPresent() || e.getMask().isPresent())); }
private static boolean noFilters(AggregationNode aggregation) { return aggregation.getAggregations() .values().stream() .map(Aggregation::getCall) .noneMatch(call -> call.getFilter().isPresent()); }
private static boolean isWindowFunction(FunctionCall functionCall) { return functionCall.getWindow().isPresent(); }
private static boolean hasMultipleDistincts(AggregationNode aggregation) { return aggregation.getAggregations() .values().stream() .filter(e -> e.getCall().isDistinct()) .map(Aggregation::getCall) .map(FunctionCall::getArguments) .map(HashSet::new) .distinct() .count() > 1; }
@Override public Optional<Symbol> getAssignedSymbol(PlanNode node, Session session, Metadata metadata, SymbolAliases symbolAliases) { Optional<Symbol> result = Optional.empty(); if (!(node instanceof AggregationNode)) { return result; } AggregationNode aggregationNode = (AggregationNode) node; FunctionCall expectedCall = callMaker.getExpectedValue(symbolAliases); for (Map.Entry<Symbol, Aggregation> assignment : aggregationNode.getAggregations().entrySet()) { if (expectedCall.equals(assignment.getValue().getCall())) { checkState(!result.isPresent(), "Ambiguous function calls in %s", aggregationNode); result = Optional.of(assignment.getKey()); } } return result; }
public static FunctionCall getCall(CurrentUser node) { return new FunctionCall(QualifiedName.of("$current_user"), ImmutableList.of()); } }
private static Predicate<FunctionCall> isAggregationPredicate(FunctionRegistry functionRegistry) { return ((functionCall) -> (functionRegistry.isAggregationFunction(functionCall.getName()) || functionCall.getFilter().isPresent()) && !functionCall.getWindow().isPresent() || functionCall.getOrderBy().isPresent()); }
@Override protected R visitFunctionCall(FunctionCall node, C context) { for (Expression argument : node.getArguments()) { process(argument, context); } if (node.getOrderBy().isPresent()) { process(node.getOrderBy().get(), context); } if (node.getWindow().isPresent()) { process(node.getWindow().get(), context); } if (node.getFilter().isPresent()) { process(node.getFilter().get(), context); } return null; }
Symbol intermediateSymbol = context.getSymbolAllocator().newSymbol(signature.getName(), function.getIntermediateType()); checkState(!originalAggregation.getCall().getOrderBy().isPresent(), "Aggregate with ORDER BY does not support partial aggregation"); intermediateAggregation.put(intermediateSymbol, new AggregationNode.Aggregation(originalAggregation.getCall(), signature, originalAggregation.getMask())); new FunctionCall( QualifiedName.of(signature.getName()), ImmutableList.<Expression>builder() .add(intermediateSymbol.toSymbolReference()) .addAll(originalAggregation.getCall().getArguments().stream() .filter(LambdaExpression.class::isInstance) .collect(toImmutableList()))
@Override public Expression rewriteFunctionCall(FunctionCall node, Object context, ExpressionTreeRewriter<Object> treeRewriter) { if (node.getName().equals(QualifiedName.of("fail"))) { return new FunctionCall(QualifiedName.of("fail"), ImmutableList.of()); } return node; } }