Skip to content

Commit df7df56

Browse files
kevintang2022facebook-github-bot
authored andcommitted
Native built in functions demo 1 (prestodb#25661)
Summary: This PR includes changes for Built in functions for different use cases - Register SQL invoked function in built in namespace when they come from plugins (prestodb#25597) - Register Native functions in built in namespace when they come from sidecar (prestodb/rfcs#41) Since these use cases have a lot of overlap, we can introduce an abstract class in order to reduce duplicate logic. ## Description ## Motivation and Context ## Impact Pull Request resolved: prestodb#25661 Test Plan: <!---Please fill in how you tested your change--> ## Contributor checklist - [ ] Please make sure your submission complies with our [contributing guide](https://github.com/prestodb/presto/blob/master/CONTRIBUTING.md), in particular [code style](https://github.com/prestodb/presto/blob/master/CONTRIBUTING.md#code-style) and [commit standards](https://github.com/prestodb/presto/blob/master/CONTRIBUTING.md#commit-standards). - [ ] PR description addresses the issue accurately and concisely. If the change is non-trivial, a GitHub Issue is referenced. - [ ] Documented new properties (with its default value), SQL syntax, functions, or other functionality. - [ ] If release notes are required, they follow the [release notes guidelines](https://github.com/prestodb/presto/wiki/Release-Notes-Guidelines). - [ ] Adequate tests were added if applicable. - [ ] CI passed. ## Release Notes Please follow [release notes guidelines](https://github.com/prestodb/presto/wiki/Release-Notes-Guidelines) and fill in the release notes below. ``` == RELEASE NOTES == General Changes * ... * ... Hive Connector Changes * ... * ... ``` If release note is NOT required, use: ``` == NO RELEASE NOTE == ``` Rollback Plan: Differential Revision: D79301760 Pulled By: kevintang2022
1 parent 84ae840 commit df7df56

File tree

37 files changed

+1241
-253
lines changed

37 files changed

+1241
-253
lines changed

presto-main-base/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,11 @@
9191
<artifactId>bootstrap</artifactId>
9292
</dependency>
9393

94+
<dependency>
95+
<groupId>com.facebook.airlift</groupId>
96+
<artifactId>http-client</artifactId>
97+
</dependency>
98+
9499
<dependency>
95100
<groupId>io.airlift</groupId>
96101
<artifactId>aircompressor</artifactId>

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

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
import com.facebook.presto.common.CatalogSchemaName;
1717
import com.facebook.presto.common.type.TypeSignature;
18+
import com.facebook.presto.spi.function.BuiltInKind;
1819
import com.facebook.presto.spi.function.FunctionHandle;
1920
import com.facebook.presto.spi.function.FunctionKind;
2021
import com.facebook.presto.spi.function.Signature;
@@ -30,12 +31,16 @@ public class BuiltInFunctionHandle
3031
implements FunctionHandle
3132
{
3233
private final Signature signature;
34+
private final BuiltInKind builtInKind;
3335

3436
@JsonCreator
35-
public BuiltInFunctionHandle(@JsonProperty("signature") Signature signature)
37+
public BuiltInFunctionHandle(
38+
@JsonProperty("signature") Signature signature,
39+
@JsonProperty("builtInKind") BuiltInKind builtInKind)
3640
{
3741
this.signature = requireNonNull(signature, "signature is null");
3842
checkArgument(signature.getTypeVariableConstraints().isEmpty(), "%s has unbound type parameters", signature);
43+
this.builtInKind = builtInKind;
3944
}
4045

4146
@JsonProperty
@@ -62,6 +67,13 @@ public List<TypeSignature> getArgumentTypes()
6267
return signature.getArgumentTypes();
6368
}
6469

70+
@JsonProperty
71+
@Override
72+
public BuiltInKind getBuiltInKind()
73+
{
74+
return builtInKind;
75+
}
76+
6577
@Override
6678
public CatalogSchemaName getCatalogSchemaName()
6779
{
@@ -78,13 +90,14 @@ public boolean equals(Object o)
7890
return false;
7991
}
8092
BuiltInFunctionHandle that = (BuiltInFunctionHandle) o;
81-
return Objects.equals(signature, that.signature);
93+
return Objects.equals(signature, that.signature)
94+
&& Objects.equals(builtInKind, that.builtInKind);
8295
}
8396

8497
@Override
8598
public int hashCode()
8699
{
87-
return Objects.hash(signature);
100+
return Objects.hash(signature, builtInKind);
88101
}
89102

90103
@Override
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
/*
2+
* Licensed under the Apache License, Version 2.0 (the "License");
3+
* you may not use this file except in compliance with the License.
4+
* You may obtain a copy of the License at
5+
*
6+
* http://www.apache.org/licenses/LICENSE-2.0
7+
*
8+
* Unless required by applicable law or agreed to in writing, software
9+
* distributed under the License is distributed on an "AS IS" BASIS,
10+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
* See the License for the specific language governing permissions and
12+
* limitations under the License.
13+
*/
14+
package com.facebook.presto.metadata;
15+
16+
import com.facebook.airlift.log.Logger;
17+
import com.facebook.presto.spi.PrestoException;
18+
import com.facebook.presto.spi.function.BuiltInKind;
19+
import com.facebook.presto.spi.function.FunctionHandle;
20+
import com.facebook.presto.spi.function.FunctionMetadata;
21+
import com.facebook.presto.spi.function.Parameter;
22+
import com.facebook.presto.spi.function.Signature;
23+
import com.facebook.presto.spi.function.SqlFunction;
24+
import com.facebook.presto.spi.function.SqlInvokedFunction;
25+
import com.google.common.util.concurrent.UncheckedExecutionException;
26+
27+
import javax.inject.Provider;
28+
29+
import java.util.Collection;
30+
import java.util.List;
31+
import java.util.stream.Collectors;
32+
33+
import static com.facebook.presto.spi.function.FunctionImplementationType.CPP;
34+
import static com.google.common.base.Preconditions.checkArgument;
35+
import static com.google.common.base.Throwables.throwIfInstanceOf;
36+
import static com.google.common.collect.ImmutableList.toImmutableList;
37+
import static java.util.Objects.requireNonNull;
38+
39+
public class BuiltInNativeFunctionNamespaceManager
40+
extends BuiltInSpecialFunctionNamespaceManager
41+
{
42+
private static final Logger log = Logger.get(BuiltInNativeFunctionNamespaceManager.class);
43+
44+
private final Provider<NativeFunctionRegistryTool> nativeFunctionRegistryToolProvider;
45+
46+
public BuiltInNativeFunctionNamespaceManager(FunctionAndTypeManager functionAndTypeManager, Provider<NativeFunctionRegistryTool> nativeFunctionRegistryToolProvider)
47+
{
48+
super(functionAndTypeManager);
49+
this.nativeFunctionRegistryToolProvider = requireNonNull(nativeFunctionRegistryToolProvider, "nativeFunctionRegistryToolProvider is null");
50+
}
51+
52+
public synchronized void registerNativeFunctions()
53+
{
54+
// only register functions once
55+
if (!this.functions.list().isEmpty()) {
56+
return;
57+
}
58+
59+
List<SqlFunction> allNativeFunctions = nativeFunctionRegistryToolProvider
60+
.get()
61+
.getNativeFunctionSignatureMap()
62+
.getUDFSignatureMap()
63+
.entrySet()
64+
.stream()
65+
.flatMap(entry -> entry.getValue().stream()
66+
.map(metaInfo -> NativeSidecarFunctionUtil.createSqlInvokedFunction(entry.getKey(), metaInfo)))
67+
.collect(Collectors.toList());
68+
this.functions = new FunctionMap(this.functions, allNativeFunctions);
69+
}
70+
71+
@Override
72+
public FunctionHandle getFunctionHandle(Signature signature)
73+
{
74+
return new BuiltInFunctionHandle(signature, BuiltInKind.NATIVE);
75+
}
76+
77+
@Override
78+
public FunctionMetadata getFunctionMetadata(FunctionHandle functionHandle)
79+
{
80+
checkArgument(functionHandle instanceof BuiltInFunctionHandle, "Expect BuiltInFunctionHandle");
81+
Signature signature = ((BuiltInFunctionHandle) functionHandle).getSignature();
82+
SpecializedFunctionKey functionKey;
83+
try {
84+
functionKey = specializedFunctionKeyCache.getUnchecked(signature);
85+
}
86+
catch (UncheckedExecutionException e) {
87+
throwIfInstanceOf(e.getCause(), PrestoException.class);
88+
throw e;
89+
}
90+
SqlFunction function = functionKey.getFunction();
91+
checkArgument(function instanceof SqlInvokedFunction, "BuiltInPluginFunctionNamespaceManager only support SqlInvokedFunctions");
92+
SqlInvokedFunction sqlFunction = (SqlInvokedFunction) function;
93+
List<String> argumentNames = sqlFunction.getParameters().stream().map(Parameter::getName).collect(toImmutableList());
94+
return new FunctionMetadata(
95+
signature.getName(),
96+
signature.getArgumentTypes(),
97+
argumentNames,
98+
signature.getReturnType(),
99+
signature.getKind(),
100+
sqlFunction.getRoutineCharacteristics().getLanguage(),
101+
CPP,
102+
function.isDeterministic(),
103+
function.isCalledOnNullInput(),
104+
sqlFunction.getVersion(),
105+
sqlFunction.getComplexTypeFunctionDescriptor());
106+
}
107+
108+
@Override
109+
protected synchronized void checkForNamingConflicts(Collection<? extends SqlFunction> functions)
110+
{
111+
}
112+
}
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/*
2+
* Licensed under the Apache License, Version 2.0 (the "License");
3+
* you may not use this file except in compliance with the License.
4+
* You may obtain a copy of the License at
5+
*
6+
* http://www.apache.org/licenses/LICENSE-2.0
7+
*
8+
* Unless required by applicable law or agreed to in writing, software
9+
* distributed under the License is distributed on an "AS IS" BASIS,
10+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
* See the License for the specific language governing permissions and
12+
* limitations under the License.
13+
*/
14+
package com.facebook.presto.metadata;
15+
16+
import com.facebook.presto.spi.PrestoException;
17+
import com.facebook.presto.spi.function.BuiltInKind;
18+
import com.facebook.presto.spi.function.FunctionHandle;
19+
import com.facebook.presto.spi.function.FunctionMetadata;
20+
import com.facebook.presto.spi.function.Parameter;
21+
import com.facebook.presto.spi.function.Signature;
22+
import com.facebook.presto.spi.function.SqlFunction;
23+
import com.facebook.presto.spi.function.SqlInvokedFunction;
24+
import com.google.common.util.concurrent.UncheckedExecutionException;
25+
26+
import java.util.Collection;
27+
import java.util.List;
28+
29+
import static com.facebook.presto.spi.function.FunctionImplementationType.SQL;
30+
import static com.google.common.base.Preconditions.checkArgument;
31+
import static com.google.common.base.Throwables.throwIfInstanceOf;
32+
import static com.google.common.collect.ImmutableList.toImmutableList;
33+
34+
public class BuiltInPluginFunctionNamespaceManager
35+
extends BuiltInSpecialFunctionNamespaceManager
36+
{
37+
public BuiltInPluginFunctionNamespaceManager(FunctionAndTypeManager functionAndTypeManager)
38+
{
39+
super(functionAndTypeManager);
40+
}
41+
42+
public synchronized void registerPluginFunctions(List<? extends SqlFunction> functions)
43+
{
44+
checkForNamingConflicts(functions);
45+
this.functions = new FunctionMap(this.functions, functions);
46+
}
47+
48+
@Override
49+
public FunctionMetadata getFunctionMetadata(FunctionHandle functionHandle)
50+
{
51+
checkArgument(functionHandle instanceof BuiltInFunctionHandle, "Expect BuiltInFunctionHandle");
52+
Signature signature = ((BuiltInFunctionHandle) functionHandle).getSignature();
53+
SpecializedFunctionKey functionKey;
54+
try {
55+
functionKey = specializedFunctionKeyCache.getUnchecked(signature);
56+
}
57+
catch (UncheckedExecutionException e) {
58+
throwIfInstanceOf(e.getCause(), PrestoException.class);
59+
throw e;
60+
}
61+
SqlFunction function = functionKey.getFunction();
62+
checkArgument(function instanceof SqlInvokedFunction, "BuiltInPluginFunctionNamespaceManager only support SqlInvokedFunctions");
63+
SqlInvokedFunction sqlFunction = (SqlInvokedFunction) function;
64+
List<String> argumentNames = sqlFunction.getParameters().stream().map(Parameter::getName).collect(toImmutableList());
65+
return new FunctionMetadata(
66+
signature.getName(),
67+
signature.getArgumentTypes(),
68+
argumentNames,
69+
signature.getReturnType(),
70+
signature.getKind(),
71+
sqlFunction.getRoutineCharacteristics().getLanguage(),
72+
SQL,
73+
function.isDeterministic(),
74+
function.isCalledOnNullInput(),
75+
sqlFunction.getVersion(),
76+
sqlFunction.getComplexTypeFunctionDescriptor());
77+
}
78+
79+
@Override
80+
public FunctionHandle getFunctionHandle(Signature signature)
81+
{
82+
return new BuiltInFunctionHandle(signature, BuiltInKind.PLUGIN);
83+
}
84+
85+
@Override
86+
protected synchronized void checkForNamingConflicts(Collection<? extends SqlFunction> functions)
87+
{
88+
for (SqlFunction function : functions) {
89+
for (SqlFunction existingFunction : this.functions.list()) {
90+
checkArgument(!function.getSignature().equals(existingFunction.getSignature()), "Function already registered: %s", function.getSignature());
91+
}
92+
}
93+
}
94+
}

0 commit comments

Comments
 (0)