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; }
private static boolean hasNoDistinctWithFilterOrMask(AggregationNode aggregation) { return aggregation.getAggregations() .values().stream() .noneMatch(e -> e.getCall().isDistinct() && (e.getCall().getFilter().isPresent() || e.getMask().isPresent())); }
@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 call = aggregation.getCall(); if (call.isDistinct() && !call.getFilter().isPresent() && !aggregation.getMask().isPresent()) { Set<Symbol> inputs = call.getArguments().stream() .map(Symbol::from)
if (!ALLOWED_FUNCTIONS.contains(aggregation.getCall().getName().toString()) && !aggregation.getCall().isDistinct()) { return context.defaultRewrite(node);
.map(SortItem::getSortKey) .collect(toImmutableList()); if (node.isDistinct()) { List<FieldId> fieldIds = node.getArguments().stream() .map(NodeRef::of)
sortOrders, pagesIndexFactory, aggregation.getCall().isDistinct(), joinCompiler, lambdaProviders,
if (windowFunction.isDistinct()) { throw new SemanticException(NOT_SUPPORTED, node, "DISTINCT in window function parameters not yet supported: %s", windowFunction);
@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); }
.entrySet() .stream() .filter(entry -> entry.getValue().getCall().isDistinct()) .map(entry -> entry.getKey()) .collect(Collectors.toList());
FunctionCall rewritten = new FunctionCall( aggregation.getCall().getName(), aggregation.getCall().isDistinct(), aggregation.getCall().getArguments(), aggregation.getCall().getFilter());
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));
Type expectedType = typeManager.getType(function.getArgumentTypes().get(i)); requireNonNull(expectedType, format("Type %s not found", function.getArgumentTypes().get(i))); if (node.isDistinct() && !expectedType.isComparable()) { throw new SemanticException(TYPE_MISMATCH, node, "DISTINCT can only be applied to comparable types (actual: %s)", expectedType);
@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 String visitFunctionCall(FunctionCall node, Boolean unmangleNames) { StringBuilder builder = new StringBuilder(); String arguments = joinExpressions(node.getArguments(), unmangleNames); if (node.getArguments().isEmpty() && "count".equalsIgnoreCase(node.getName().getSuffix())) { arguments = "*"; } if (node.isDistinct()) { arguments = "DISTINCT " + arguments; } if (unmangleNames && node.getName().toString().startsWith(QueryUtil.FIELD_REFERENCE_PREFIX)) { checkState(node.getArguments().size() == 1, "Expected only one argument to field reference"); QualifiedName name = QualifiedName.of(QueryUtil.unmangleFieldReference(node.getName().toString())); builder.append(arguments).append(".").append(name); } else { builder.append(formatQualifiedName(node.getName())) .append('(').append(arguments).append(')'); } if (node.getWindow().isPresent()) { builder.append(" OVER ").append(visitWindow(node.getWindow().get(), unmangleNames)); } return builder.toString(); }
@Override protected String visitFunctionCall(FunctionCall node, Boolean unmangleNames) { StringBuilder builder = new StringBuilder(); String arguments = joinExpressions(node.getArguments(), unmangleNames); if (node.getArguments().isEmpty() && "count".equalsIgnoreCase(node.getName().getSuffix())) { arguments = "*"; } if (node.isDistinct()) { arguments = "DISTINCT " + arguments; } if (unmangleNames && node.getName().toString().startsWith(QueryUtil.FIELD_REFERENCE_PREFIX)) { checkState(node.getArguments().size() == 1, "Expected only one argument to field reference"); QualifiedName name = QualifiedName.of(QueryUtil.unmangleFieldReference(node.getName().toString())); builder.append(arguments).append(".").append(name); } else { builder.append(formatQualifiedName(node.getName())) .append('(').append(arguments).append(')'); } if (node.getWindow().isPresent()) { builder.append(" OVER ").append(visitWindow(node.getWindow().get(), unmangleNames)); } return builder.toString(); }
@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 = expressionTypes.get(expression); argumentValues.add(value); argumentTypes.add(type); } Signature functionSignature = metadata.getFunctionRegistry().resolveFunction(node.getName(), Lists.transform(argumentTypes, Type::getTypeSignature), false); ScalarFunctionImplementation function = metadata.getFunctionRegistry().getScalarFunctionImplementation(functionSignature); for (int i = 0; i < argumentValues.size(); i++) { Object value = argumentValues.get(i); if (value == null && !function.getNullableArguments().get(i)) { return null; } } // do not optimize non-deterministic functions if (optimize && (!function.isDeterministic() || hasUnresolvedValue(argumentValues))) { return new FunctionCall(node.getName(), node.getWindow(), node.isDistinct(), toExpressions(argumentValues, argumentTypes)); } return invoke(session, function, argumentValues); }