private static boolean isWindowFunction(FunctionCall functionCall) { return functionCall.getWindow().isPresent(); }
private static Predicate<FunctionCall> isAggregationPredicate(FunctionRegistry functionRegistry) { return ((functionCall) -> (functionRegistry.isAggregationFunction(functionCall.getName()) || functionCall.getFilter().isPresent()) && !functionCall.getWindow().isPresent() || functionCall.getOrderBy().isPresent()); }
@Override protected Void visitFunctionCall(FunctionCall functionCall, Analysis analysis) { requireNonNull(analysis, "analysis is null"); Signature signature = analysis.getFunctionSignature(functionCall); if (signature != null && signature.getKind() == WINDOW && !functionCall.getWindow().isPresent()) { throw new SemanticException(WINDOW_REQUIRES_OVER, functionCall, "Window function %s requires an OVER clause", signature.getName()); } return super.visitFunctionCall(functionCall, analysis); } }
@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; }
@Override protected String visitFunctionCall(FunctionCall node, Void context) { StringBuilder builder = new StringBuilder(); String arguments = joinExpressions(node.getArguments()); if (node.getArguments().isEmpty() && "count".equalsIgnoreCase(node.getName().getSuffix())) { arguments = "*"; } if (node.isDistinct()) { arguments = "DISTINCT " + arguments; } builder.append(formatQualifiedName(node.getName())) .append('(').append(arguments); if (node.getOrderBy().isPresent()) { builder.append(' ').append(formatOrderBy(node.getOrderBy().get(), parameters)); } builder.append(')'); if (node.getFilter().isPresent()) { builder.append(" FILTER ").append(visitFilter(node.getFilter().get(), context)); } if (node.getWindow().isPresent()) { builder.append(" OVER ").append(visitWindow(node.getWindow().get(), context)); } return builder.toString(); }
@Override public boolean equals(Object object) { if (this == object) { return true; } if (object == null || !(object instanceof FunctionCall)) { return false; } FunctionCall other = (FunctionCall) object; return Objects.equals(name, other.getName()) && other.getWindow().isPresent() && Objects.equals(frame, other.getWindow().get().getFrame()) && Objects.equals(distinct, other.isDistinct()) && Objects.equals(getArguments(), other.getArguments()); }
functionCall = new FunctionCall(functionCall.getName(), functionCall.getWindow(), false, arguments.build());
if (!node.getWindow().isPresent()) { List<FunctionCall> aggregateFunctions = extractAggregateFunctions(node.getArguments(), metadata.getFunctionRegistry()); List<FunctionCall> windowFunctions = extractWindowFunctions(node.getArguments()); if (node.getWindow().isPresent() && !process(node.getWindow().get(), context)) { return false;
new FunctionCall( call.getName(), call.getWindow(), call.getFilter(), call.getOrderBy(),
new FunctionCall( functionCall.getName(), functionCall.getWindow(), false, ImmutableList.of(aggregateInfo.getNewDistinctAggregateSymbol().toSymbolReference())), String signatureName = entry.getValue().getSignature().getName(); Aggregation aggregation = new Aggregation( new FunctionCall(functionName, functionCall.getWindow(), false, ImmutableList.of(argument.toSymbolReference())), getFunctionSignature(functionName, argument), Optional.empty());
Window window = windowFunction.getWindow().get();
Window window = windowFunction.getWindow().get();
@Override protected Object visitFunctionCall(FunctionCall node, Object context) { List<Type> argumentTypes = new ArrayList<>(); List<Object> argumentValues = new ArrayList<>(); for (Expression expression : node.getArguments()) { Object value = process(expression, context); Type type = type(expression); argumentValues.add(value); argumentTypes.add(type); } Signature functionSignature = metadata.getFunctionRegistry().resolveFunction(node.getName(), fromTypes(argumentTypes)); ScalarFunctionImplementation function = metadata.getFunctionRegistry().getScalarFunctionImplementation(functionSignature); for (int i = 0; i < argumentValues.size(); i++) { Object value = argumentValues.get(i); if (value == null && function.getArgumentProperty(i).getNullConvention() == RETURN_NULL_ON_NULL) { return null; } } // do not optimize non-deterministic functions if (optimize && (!function.isDeterministic() || hasUnresolvedValue(argumentValues) || node.getName().equals(QualifiedName.of("fail")))) { return new FunctionCall(node.getName(), node.getWindow(), node.isDistinct(), toExpressions(argumentValues, argumentTypes)); } return functionInvoker.invoke(functionSignature, session, argumentValues); }
@Override protected Type visitFunctionCall(FunctionCall node, StackableAstVisitorContext<Context> context) if (node.getWindow().isPresent()) { for (Expression expression : node.getWindow().get().getPartitionBy()) { process(expression, context); Type type = getExpressionType(expression); for (SortItem sortItem : getSortItemsFromOrderBy(node.getWindow().get().getOrderBy())) { process(sortItem.getSortKey(), context); Type type = getExpressionType(sortItem.getSortKey()); if (node.getWindow().get().getFrame().isPresent()) { WindowFrame frame = node.getWindow().get().getFrame().get();
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()); } }
new FunctionCall(call.getName(), call.getWindow(), Optional.empty(), call.getOrderBy(), call.isDistinct(), call.getArguments()), entry.getValue().getSignature(), mask));
@Override protected Boolean visitFunctionCall(FunctionCall actual, Node expected) { if (!(expected instanceof FunctionCall)) { return false; } FunctionCall expectedFunction = (FunctionCall) expected; if (actual.isDistinct() != expectedFunction.isDistinct()) { return false; } if (!actual.getName().equals(expectedFunction.getName())) { return false; } if (!process(actual.getArguments(), expectedFunction.getArguments())) { return false; } if (!process(actual.getFilter(), expectedFunction.getFilter())) { return false; } if (!process(actual.getWindow(), expectedFunction.getWindow())) { return false; } return true; }
@Override protected String visitFunctionCall(FunctionCall node, Void context) { StringBuilder builder = new StringBuilder(); String arguments = joinExpressions(node.getArguments()); if (node.getArguments().isEmpty() && "count".equalsIgnoreCase(node.getName().getSuffix())) { arguments = "*"; } if (node.isDistinct()) { arguments = "DISTINCT " + arguments; } String name; if (node.getName().getParts().size() > 1) { name = formatQualifiedName(node.getName(), escape); } else { // for Mysql - > SELECT `count`(1) doesn't work name = node.getName().getSuffix(); } builder.append(name).append('(').append(arguments).append(')'); if (node.getFilter().isPresent()) { builder.append(" FILTER ").append(visitFilter(node.getFilter().get(), context)); } if (node.getWindow().isPresent()) { builder.append(" OVER ").append(visitWindow(node.getWindow().get(), context)); } return builder.toString(); }
@Override protected Void visitFunctionCall(FunctionCall node, Void context) { if (node.getWindow().isPresent()) { windowFunctions.add(node); return null; } return super.visitFunctionCall(node, null); }
@Override protected Void visitFunctionCall(FunctionCall node, Void context) { if (metadata.isAggregationFunction(node.getName()) && !node.getWindow().isPresent()) { aggregates.add(node); return null; } return super.visitFunctionCall(node, null); }