[
https://issues.apache.org/jira/browse/DRILL-4726?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15468944#comment-15468944
]
ASF GitHub Bot commented on DRILL-4726:
---------------------------------------
Github user paul-rogers commented on a diff in the pull request:
https://github.com/apache/drill/pull/574#discussion_r77737314
--- Diff:
exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/DrillFunctionRegistry.java
---
@@ -64,62 +76,134 @@
.put("CONVERT_FROM", Pair.of(2, 2))
.put("FLATTEN", Pair.of(1, 1)).build();
+ /** Registers all functions present in Drill classpath on start-up. All
functions will be marked as built-in.*/
public DrillFunctionRegistry(ScanResult classpathScan) {
+ validate(BUILT_IN, classpathScan);
+ register(BUILT_IN, classpathScan, this.getClass().getClassLoader());
+ if (logger.isTraceEnabled()) {
+ StringBuilder allFunctions = new StringBuilder();
+ for (DrillFuncHolder method:
registryHolder.getAllFunctionsWithHolders().values()) {
+ allFunctions.append(method.toString()).append("\n");
+ }
+ logger.trace("Registered functions: [\n{}]", allFunctions);
+ }
+ }
+
+ /**
+ * Validates all functions, present in jars.
+ * Will throw {@link FunctionValidationException} if:
+ * 1. Jar with the same name has been already registered.
+ * 2. Conflicting function with the similar signature is found.
+ * 3. Aggregating function is not deterministic.
+ *
+ * @return list of validated functions
+ */
+ public List<Func> validate(String jarName, ScanResult classpathScan) {
+ List<Func> functions = Lists.newArrayList();
FunctionConverter converter = new FunctionConverter();
List<AnnotatedClassDescriptor> providerClasses =
classpathScan.getAnnotatedClasses();
- // Hash map to prevent registering functions with exactly matching
signatures
- // key: Function Name + Input's Major Type
- // value: Class name where function is implemented
- //
- final Map<String, String> functionSignatureMap = new HashMap<>();
+ if (registryHolder.containsJar(jarName)) {
+ throw new FunctionValidationException(String.format("Jar %s is
already registered", jarName));
+ }
+
+ final ListMultimap<String, String> allFuncWithSignatures =
registryHolder.getAllFunctionsWithSignatures();
+
for (AnnotatedClassDescriptor func : providerClasses) {
- DrillFuncHolder holder = converter.getHolder(func);
+ DrillFuncHolder holder = converter.getHolder(func,
ClassLoader.getSystemClassLoader());
if (holder != null) {
- // register handle for each name the function can be referred to
- String[] names = holder.getRegisteredNames();
- // Create the string for input types
String functionInput = "";
+ List<MajorType> types = Lists.newArrayList();
for (DrillFuncHolder.ValueReference ref : holder.parameters) {
functionInput += ref.getType().toString();
+ types.add(ref.getType());
}
+
+ String[] names = holder.getRegisteredNames();
for (String name : names) {
String functionName = name.toLowerCase();
- registeredFunctions.put(functionName, holder);
String functionSignature = functionName + functionInput;
- String existingImplementation;
- if ((existingImplementation =
functionSignatureMap.get(functionSignature)) != null) {
- throw new AssertionError(
- String.format(
- "Conflicting functions with similar signature found.
Func Name: %s, Class name: %s " +
- " Class name: %s", functionName, func.getClassName(),
existingImplementation));
- } else if (holder.isAggregating() && !holder.isDeterministic() )
{
- logger.warn("Aggregate functions must be deterministic, did
not register function {}", func.getClassName());
+
+ if
(allFuncWithSignatures.get(functionName).contains(functionSignature)) {
--- End diff --
Similar race condition. Getting the list of function names & signatures is
thread-safe. But, iterating though the list is not: two threads may do the same
functions at the same time, resulting in conflicts.
> Dynamic UDFs support
> --------------------
>
> Key: DRILL-4726
> URL: https://issues.apache.org/jira/browse/DRILL-4726
> Project: Apache Drill
> Issue Type: New Feature
> Affects Versions: 1.6.0
> Reporter: Arina Ielchiieva
> Assignee: Arina Ielchiieva
> Fix For: Future
>
>
> Allow register UDFs without restart of Drillbits.
> Design is described in document below:
> https://docs.google.com/document/d/1FfyJtWae5TLuyheHCfldYUpCdeIezR2RlNsrOTYyAB4/edit?usp=sharing
>
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)