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 isSTDistance(Expression expression) { if (expression instanceof FunctionCall) { return ((FunctionCall) expression).getName().toString().equalsIgnoreCase(ST_DISTANCE); } return false; }
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); }
@Override protected Void visitFunctionCall(FunctionCall node, Integer indentLevel) { String name = Joiner.on('.').join(node.getName().getParts()); print(indentLevel, "FunctionCall[" + name + "]"); super.visitFunctionCall(node, indentLevel + 1); return null; }
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 node, AtomicBoolean deterministic) { // TODO: total hack to figure out if a function is deterministic. martint should fix this when he refactors the planning code if (node.getName().equals(QualifiedName.of("rand")) || node.getName().equals(QualifiedName.of("random")) || node.getName().equals(QualifiedName.of("shuffle"))) { deterministic.set(false); } return super.visitFunctionCall(node, deterministic); } }
@Override protected RowExpression visitFunctionCall(FunctionCall node, Void context) { List<RowExpression> arguments = node.getArguments().stream() .map(value -> process(value, context)) .collect(toImmutableList()); List<TypeSignature> argumentTypes = arguments.stream() .map(RowExpression::getType) .map(Type::getTypeSignature) .collect(toImmutableList()); Signature signature = new Signature(node.getName().getSuffix(), functionKind, getType(node).getTypeSignature(), argumentTypes); return call(signature, getType(node), arguments); }
@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(); }
private SpatialPredicate spatialTest(FunctionCall functionCall, boolean probeFirst, Optional<ComparisonExpression.Operator> comparisonOperator) switch (functionCall.getName().toString().toLowerCase(Locale.ENGLISH)) { case ST_CONTAINS: if (probeFirst) { throw new UnsupportedOperationException("Unsupported spatial function: " + functionCall.getName());
@Override public PlanNode visitWindow(WindowNode node, RewriteContext<Context> context) { if (!node.getWindowFunctions().values().stream() .map(function -> function.getFunctionCall().getName()) .allMatch(metadata.getFunctionRegistry()::isAggregationFunction)) { return node; } // Don't need this restriction if we can prove that all order by symbols are deterministically produced if (node.getOrderingScheme().isPresent()) { return node; } // Only RANGE frame type currently supported for aggregation functions because it guarantees the // same value for each peer group. // ROWS frame type requires the ordering to be fully deterministic (e.g. deterministically sorted on all columns) if (node.getFrames().stream().map(WindowNode.Frame::getType).anyMatch(type -> type != WindowFrame.Type.RANGE)) { // TODO: extract frames of type RANGE and allow optimization on them return node; } // Lookup symbols can only be passed through if they are part of the partitioning Set<Symbol> partitionByLookupSymbols = context.get().getLookupSymbols().stream() .filter(node.getPartitionBy()::contains) .collect(toImmutableSet()); if (partitionByLookupSymbols.isEmpty()) { return node; } return context.defaultRewrite(node, new Context(partitionByLookupSymbols, context.get().getSuccess())); }
public Symbol newSymbol(Expression expression, Type type, String suffix) { String nameHint = "expr"; if (expression instanceof Identifier) { nameHint = ((Identifier) expression).getValue(); } else if (expression instanceof FunctionCall) { nameHint = ((FunctionCall) expression).getName().getSuffix(); } else if (expression instanceof SymbolReference) { nameHint = ((SymbolReference) expression).getName(); } else if (expression instanceof GroupingOperation) { nameHint = "grouping"; } return newSymbol(nameHint, type, suffix); }
@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); }
FunctionCall call = entry.getValue().getCall(); Symbol symbol = entry.getKey(); if (call.getName().equals(COUNT)) { List<TypeSignature> scalarAggregationSourceTypeSignatures = ImmutableList.of( symbolAllocator.getTypes().get(nonNullableAggregationSourceSymbol).getTypeSignature());
@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()); }
@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 AggregationBuilder addAggregation(Symbol output, Expression expression, List<Type> inputTypes, Optional<Symbol> mask) { checkArgument(expression instanceof FunctionCall); FunctionCall aggregation = (FunctionCall) expression; Signature signature = metadata.getFunctionRegistry().resolveFunction(aggregation.getName(), TypeSignatureProvider.fromTypes(inputTypes)); return addAggregation(output, new Aggregation(aggregation, signature, mask)); }
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()); } }
public static Signature resolveFunction(FunctionCall node, List<TypeSignatureProvider> argumentTypes, FunctionRegistry functionRegistry) { try { return functionRegistry.resolveFunction(node.getName(), argumentTypes); } catch (PrestoException e) { if (e.getErrorCode().getCode() == StandardErrorCode.FUNCTION_NOT_FOUND.toErrorCode().getCode()) { throw new SemanticException(SemanticErrorCode.FUNCTION_NOT_FOUND, node, e.getMessage()); } if (e.getErrorCode().getCode() == StandardErrorCode.AMBIGUOUS_FUNCTION_CALL.toErrorCode().getCode()) { throw new SemanticException(SemanticErrorCode.AMBIGUOUS_FUNCTION_CALL, node, e.getMessage()); } throw e; } }
@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; }