1 | /* | |
2 | * Copyright OpenSearch Contributors | |
3 | * SPDX-License-Identifier: Apache-2.0 | |
4 | */ | |
5 | ||
6 | package org.opensearch.sql.expression.function; | |
7 | ||
8 | import java.util.AbstractMap; | |
9 | import java.util.Map; | |
10 | import java.util.PriorityQueue; | |
11 | import java.util.Set; | |
12 | import java.util.stream.Collectors; | |
13 | import lombok.Builder; | |
14 | import lombok.Getter; | |
15 | import lombok.RequiredArgsConstructor; | |
16 | import lombok.Singular; | |
17 | import org.apache.commons.lang3.tuple.Pair; | |
18 | import org.opensearch.sql.exception.ExpressionEvaluationException; | |
19 | ||
20 | /** | |
21 | * The Function Resolver hold the overload {@link FunctionBuilder} implementation. | |
22 | * is composed by {@link FunctionName} which identified the function name | |
23 | * and a map of {@link FunctionSignature} and {@link FunctionBuilder} | |
24 | * to represent the overloaded implementation | |
25 | */ | |
26 | @Builder | |
27 | @RequiredArgsConstructor | |
28 | public class DefaultFunctionResolver implements FunctionResolver { | |
29 | @Getter | |
30 | private final FunctionName functionName; | |
31 | @Singular("functionBundle") | |
32 | private final Map<FunctionSignature, FunctionBuilder> functionBundle; | |
33 | ||
34 | /** | |
35 | * Resolve the {@link FunctionBuilder} by using input {@link FunctionSignature}. | |
36 | * If the {@link FunctionBuilder} exactly match the input {@link FunctionSignature}, return it. | |
37 | * If applying the widening rule, found the most match one, return it. | |
38 | * If nothing found, throw {@link ExpressionEvaluationException} | |
39 | * | |
40 | * @return function signature and its builder | |
41 | */ | |
42 | @Override | |
43 | public Pair<FunctionSignature, FunctionBuilder> resolve(FunctionSignature unresolvedSignature) { | |
44 | PriorityQueue<Map.Entry<Integer, FunctionSignature>> functionMatchQueue = new PriorityQueue<>( | |
45 | Map.Entry.comparingByKey()); | |
46 | ||
47 | for (FunctionSignature functionSignature : functionBundle.keySet()) { | |
48 | functionMatchQueue.add( | |
49 | new AbstractMap.SimpleEntry<>(unresolvedSignature.match(functionSignature), | |
50 | functionSignature)); | |
51 | } | |
52 | Map.Entry<Integer, FunctionSignature> bestMatchEntry = functionMatchQueue.peek(); | |
53 |
1
1. resolve : negated conditional → KILLED |
if (FunctionSignature.NOT_MATCH.equals(bestMatchEntry.getKey())) { |
54 | throw new ExpressionEvaluationException( | |
55 | String.format("%s function expected %s, but get %s", functionName, | |
56 | formatFunctions(functionBundle.keySet()), | |
57 | unresolvedSignature.formatTypes() | |
58 | )); | |
59 | } else { | |
60 | FunctionSignature resolvedSignature = bestMatchEntry.getValue(); | |
61 |
1
1. resolve : replaced return value with null for org/opensearch/sql/expression/function/DefaultFunctionResolver::resolve → KILLED |
return Pair.of(resolvedSignature, functionBundle.get(resolvedSignature)); |
62 | } | |
63 | } | |
64 | ||
65 | private String formatFunctions(Set<FunctionSignature> functionSignatures) { | |
66 |
1
1. formatFunctions : replaced return value with "" for org/opensearch/sql/expression/function/DefaultFunctionResolver::formatFunctions → KILLED |
return functionSignatures.stream().map(FunctionSignature::formatTypes) |
67 | .collect(Collectors.joining(",", "{", "}")); | |
68 | } | |
69 | } | |
Mutations | ||
53 |
1.1 |
|
61 |
1.1 |
|
66 |
1.1 |