use of org.apache.drill.exec.expr.fn.DrillFuncHolder in project drill by apache.
the class LocalFunctionRegistry method validate.
/**
* Validates all functions, present in jars.
* Will throw {@link FunctionValidationException} if:
* <ol>
* <li>Jar with the same name has been already registered.</li>
* <li>Conflicting function with the similar signature is found.</li>
* <li>Aggregating function is not deterministic.</li>
*</ol>
* @param jarName jar name to be validated
* @param scanResult scan of all classes present in jar
* @return list of validated function signatures
*/
public List<String> validate(String jarName, ScanResult scanResult) {
List<String> functions = Lists.newArrayList();
FunctionConverter converter = new FunctionConverter();
List<AnnotatedClassDescriptor> providerClasses = scanResult.getAnnotatedClasses();
if (registryHolder.containsJar(jarName)) {
throw new JarValidationException(String.format("Jar with %s name has been already registered", jarName));
}
final ListMultimap<String, String> allFuncWithSignatures = registryHolder.getAllFunctionsWithSignatures();
for (AnnotatedClassDescriptor func : providerClasses) {
DrillFuncHolder holder = converter.getHolder(func, ClassLoader.getSystemClassLoader());
if (holder != null) {
String functionInput = holder.getInputParameters();
String[] names = holder.getRegisteredNames();
for (String name : names) {
String functionName = name.toLowerCase();
String functionSignature = String.format(functionSignaturePattern, functionName, functionInput);
if (allFuncWithSignatures.get(functionName).contains(functionSignature)) {
throw new FunctionValidationException(String.format("Found duplicated function in %s: %s", registryHolder.getJarNameByFunctionSignature(functionName, functionSignature), functionSignature));
} else if (holder.isAggregating() && !holder.isDeterministic()) {
throw new FunctionValidationException(String.format("Aggregate functions must be deterministic: %s", func.getClassName()));
} else {
functions.add(functionSignature);
allFuncWithSignatures.put(functionName, functionSignature);
}
}
} else {
logger.warn("Unable to initialize function for class {}", func.getClassName());
}
}
return functions;
}
use of org.apache.drill.exec.expr.fn.DrillFuncHolder in project drill by apache.
the class ExpressionTreeMaterializer method addCastExpression.
public static LogicalExpression addCastExpression(LogicalExpression fromExpr, MajorType toType, FunctionLookupContext functionLookupContext, ErrorCollector errorCollector, boolean exactResolver) {
String castFuncName = CastFunctions.getCastFunc(toType.getMinorType());
List<LogicalExpression> castArgs = Lists.newArrayList();
//input_expr
castArgs.add(fromExpr);
if (fromExpr.getMajorType().getMinorType() == MinorType.UNION && toType.getMinorType() == MinorType.UNION) {
return fromExpr;
}
if (!Types.isFixedWidthType(toType) && !Types.isUnion(toType)) {
/* We are implicitly casting to VARCHAR so we don't have a max length,
* using an arbitrary value. We trim down the size of the stored bytes
* to the actual size so this size doesn't really matter.
*/
castArgs.add(new ValueExpressions.LongExpression(Types.MAX_VARCHAR_LENGTH, null));
} else if (CoreDecimalUtility.isDecimalType(toType)) {
// Add the scale and precision to the arguments of the implicit cast
castArgs.add(new ValueExpressions.LongExpression(toType.getPrecision(), null));
castArgs.add(new ValueExpressions.LongExpression(toType.getScale(), null));
}
FunctionCall castCall = new FunctionCall(castFuncName, castArgs, ExpressionPosition.UNKNOWN);
FunctionResolver resolver;
if (exactResolver) {
resolver = FunctionResolverFactory.getExactResolver(castCall);
} else {
resolver = FunctionResolverFactory.getResolver(castCall);
}
DrillFuncHolder matchedCastFuncHolder = functionLookupContext.findDrillFunction(resolver, castCall);
if (matchedCastFuncHolder == null) {
logFunctionResolutionError(errorCollector, castCall);
return NullExpression.INSTANCE;
}
return matchedCastFuncHolder.getExpr(castFuncName, castArgs, ExpressionPosition.UNKNOWN);
}
use of org.apache.drill.exec.expr.fn.DrillFuncHolder in project drill by apache.
the class LocalFunctionRegistry method register.
/**
* Registers all functions present in jar and updates registry version.
* If jar name is already registered, all jar related functions will be overridden.
* To prevent classpath collisions during loading and unloading jars,
* each jar is shipped with its own class loader.
*
* @param jars list of jars to be registered
* @param version remote function registry version number with which local function registry is synced
*/
public void register(List<JarScan> jars, long version) {
Map<String, List<FunctionHolder>> newJars = Maps.newHashMap();
for (JarScan jarScan : jars) {
FunctionConverter converter = new FunctionConverter();
List<AnnotatedClassDescriptor> providerClasses = jarScan.getScanResult().getAnnotatedClasses();
List<FunctionHolder> functions = Lists.newArrayList();
newJars.put(jarScan.getJarName(), functions);
for (AnnotatedClassDescriptor func : providerClasses) {
DrillFuncHolder holder = converter.getHolder(func, jarScan.getClassLoader());
if (holder != null) {
String functionInput = holder.getInputParameters();
String[] names = holder.getRegisteredNames();
for (String name : names) {
String functionName = name.toLowerCase();
String functionSignature = String.format(functionSignaturePattern, functionName, functionInput);
functions.add(new FunctionHolder(functionName, functionSignature, holder));
}
}
}
}
registryHolder.addJars(newJars, version);
}
use of org.apache.drill.exec.expr.fn.DrillFuncHolder in project drill by apache.
the class ExpressionTreeMaterializer method convertToNullableType.
public static LogicalExpression convertToNullableType(LogicalExpression fromExpr, MinorType toType, FunctionLookupContext functionLookupContext, ErrorCollector errorCollector) {
String funcName = "convertToNullable" + toType.toString();
List<LogicalExpression> args = Lists.newArrayList();
args.add(fromExpr);
FunctionCall funcCall = new FunctionCall(funcName, args, ExpressionPosition.UNKNOWN);
FunctionResolver resolver = FunctionResolverFactory.getResolver(funcCall);
DrillFuncHolder matchedConvertToNullableFuncHolder = functionLookupContext.findDrillFunction(resolver, funcCall);
if (matchedConvertToNullableFuncHolder == null) {
logFunctionResolutionError(errorCollector, funcCall);
return NullExpression.INSTANCE;
}
return matchedConvertToNullableFuncHolder.getExpr(funcName, args, ExpressionPosition.UNKNOWN);
}
use of org.apache.drill.exec.expr.fn.DrillFuncHolder in project drill by apache.
the class TestSimpleFunctions method resolveHash.
public void resolveHash(DrillConfig config, LogicalExpression arg, TypeProtos.MajorType expectedArg, TypeProtos.MajorType expectedOut, TypeProtos.DataMode expectedBestInputMode, FunctionImplementationRegistry registry) throws JClassAlreadyExistsException, IOException {
final List<LogicalExpression> args = new ArrayList<>();
args.add(arg);
FunctionCall call = new FunctionCall("hash", args, ExpressionPosition.UNKNOWN);
final FunctionResolver resolver = FunctionResolverFactory.getResolver(call);
final DrillFuncHolder matchedFuncHolder = registry.findDrillFunction(resolver, call);
assertEquals(expectedBestInputMode, matchedFuncHolder.getParmMajorType(0).getMode());
}
Aggregations