Skip to content

Commit eaf1d28

Browse files
committed
Allow duplicate function signatures when matching with generic candidates
1 parent e366be1 commit eaf1d28

File tree

2 files changed

+44
-2
lines changed

2 files changed

+44
-2
lines changed

presto-main-base/src/main/java/com/facebook/presto/metadata/FunctionSignatureMatcher.java

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ public Optional<Signature> match(Collection<? extends SqlFunction> candidates, L
7171
.filter(function -> !function.getSignature().getTypeVariableConstraints().isEmpty())
7272
.collect(Collectors.toList());
7373

74-
match = matchFunctionExact(genericCandidates, parameterTypes);
74+
match = matchFunctionGeneric(genericCandidates, parameterTypes);
7575
if (match.isPresent()) {
7676
return match;
7777
}
@@ -91,6 +91,28 @@ private Optional<Signature> matchFunctionExact(List<SqlFunction> candidates, Lis
9191
return matchFunction(candidates, actualParameters, false);
9292
}
9393

94+
private Optional<Signature> matchFunctionGeneric(List<SqlFunction> candidates, List<TypeSignatureProvider> actualParameters)
95+
{
96+
List<ApplicableFunction> applicableFunctions = identifyApplicableFunctions(candidates, actualParameters, false);
97+
if (applicableFunctions.isEmpty()) {
98+
return Optional.empty();
99+
}
100+
101+
if (applicableFunctions.size() == 1) {
102+
return Optional.of(getOnlyElement(applicableFunctions).getBoundSignature());
103+
}
104+
105+
List<Signature> deduplicatedSignatures = applicableFunctions.stream()
106+
.map(applicableFunction -> applicableFunction.boundSignature)
107+
.distinct()
108+
.collect(toImmutableList());
109+
if (deduplicatedSignatures.size() == 1) {
110+
return Optional.of(getOnlyElement(deduplicatedSignatures));
111+
}
112+
113+
throw new PrestoException(AMBIGUOUS_FUNCTION_CALL, getErrorMessage(applicableFunctions));
114+
}
115+
94116
private Optional<Signature> matchFunctionWithCoercion(Collection<? extends SqlFunction> candidates, List<TypeSignatureProvider> actualParameters)
95117
{
96118
return matchFunction(candidates, actualParameters, true);
@@ -112,6 +134,11 @@ private Optional<Signature> matchFunction(Collection<? extends SqlFunction> cand
112134
return Optional.of(getOnlyElement(applicableFunctions).getBoundSignature());
113135
}
114136

137+
throw new PrestoException(AMBIGUOUS_FUNCTION_CALL, getErrorMessage(applicableFunctions));
138+
}
139+
140+
private String getErrorMessage(List<ApplicableFunction> applicableFunctions)
141+
{
115142
StringBuilder errorMessageBuilder = new StringBuilder();
116143
errorMessageBuilder.append("Could not choose a best candidate operator. Explicit type casts must be added.\n");
117144
errorMessageBuilder.append("Candidates are:\n");
@@ -120,7 +147,8 @@ private Optional<Signature> matchFunction(Collection<? extends SqlFunction> cand
120147
errorMessageBuilder.append(function.getBoundSignature().toString());
121148
errorMessageBuilder.append("\n");
122149
}
123-
throw new PrestoException(AMBIGUOUS_FUNCTION_CALL, errorMessageBuilder.toString());
150+
151+
return errorMessageBuilder.toString();
124152
}
125153

126154
private List<ApplicableFunction> identifyApplicableFunctions(Collection<? extends SqlFunction> candidates, List<TypeSignatureProvider> actualParameters, boolean allowCoercion)

presto-native-sidecar-plugin/src/test/java/com/facebook/presto/sidecar/TestNativeSidecarPlugin.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,20 @@ public void testApproxPercentile()
334334
}
335335
}
336336

337+
@Test
338+
public void testMapSubset()
339+
{
340+
assertQuery("select m[1], m[3] from (select map_subset(map(array[1,2,3,4], array['a', 'b', 'c', 'd']), array[1,3,10]) m)", "select 'a', 'c'");
341+
assertQuery("select m['p'], m['r'] from (select map_subset(map(array['p', 'q', 'r', 's'], array['a', 'b', 'c', 'd']), array['p', 'r', 'z']) m)", "select 'a', 'c'");
342+
assertQuery("select m[true], m[false] from (select map_subset(map(array[false, true], array['a', 'z']), array[true, false]) m)", "select 'z', 'a'");
343+
assertQuery("select m[DATE '2015-01-01'], m[DATE '2015-01-13'] from (select map_subset(" +
344+
"map(array[DATE '2015-01-01', DATE '2015-02-13', DATE '2015-01-13', DATE '2015-05-15'], array['a', 'b', 'c', 'd']), " +
345+
"array[DATE '2015-01-01', DATE '2015-01-13', DATE '2015-06-15']) m)", "select 'a', 'c'");
346+
assertQuery("select m[TIMESTAMP '2021-01-02 09:04:05.321'] from (select map_subset(" +
347+
"map(array[TIMESTAMP '2021-01-02 09:04:05.321', TIMESTAMP '2022-12-22 10:07:08.456'], array['a', 'b']), " +
348+
"array[TIMESTAMP '2021-01-02 09:04:05.321', TIMESTAMP '2022-12-22 10:07:09.246']) m)", "select 'a'");
349+
}
350+
337351
@Test
338352
public void testInformationSchemaTables()
339353
{

0 commit comments

Comments
 (0)