Search in sources :

Example 1 with DrillFuncHolder

use of org.apache.drill.exec.expr.fn.DrillFuncHolder in project drill by apache.

the class DefaultFunctionResolver method getBestMatch.

@Override
public DrillFuncHolder getBestMatch(List<DrillFuncHolder> methods, FunctionCall call) {
    int bestcost = Integer.MAX_VALUE;
    int currcost = Integer.MAX_VALUE;
    DrillFuncHolder bestmatch = null;
    final List<DrillFuncHolder> bestMatchAlternatives = new LinkedList<>();
    for (DrillFuncHolder h : methods) {
        final List<TypeProtos.MajorType> argumentTypes = Lists.newArrayList();
        for (LogicalExpression expression : call.args) {
            argumentTypes.add(expression.getMajorType());
        }
        currcost = TypeCastRules.getCost(argumentTypes, h);
        // if cost is lower than 0, func implementation is not matched, either w/ or w/o implicit casts
        if (currcost < 0) {
            continue;
        }
        if (currcost < bestcost) {
            bestcost = currcost;
            bestmatch = h;
            bestMatchAlternatives.clear();
        } else if (currcost == bestcost) {
            // keep log of different function implementations that have the same best cost
            bestMatchAlternatives.add(h);
        }
    }
    if (bestcost < 0) {
        //TODO: raise exception here?
        return null;
    } else {
        if (AssertionUtil.isAssertionsEnabled() && bestMatchAlternatives.size() > 0) {
            /*
         * There are other alternatives to the best match function which could have been selected
         * Log the possible functions and the chose implementation and raise an exception
         */
            logger.error("Chosen function impl: " + bestmatch.toString());
            // printing the possible matches
            logger.error("Printing all the possible functions that could have matched: ");
            for (DrillFuncHolder holder : bestMatchAlternatives) {
                logger.error(holder.toString());
            }
            throw new AssertionError("Multiple functions with best cost found");
        }
        return bestmatch;
    }
}
Also used : LogicalExpression(org.apache.drill.common.expression.LogicalExpression) DrillFuncHolder(org.apache.drill.exec.expr.fn.DrillFuncHolder) LinkedList(java.util.LinkedList)

Example 2 with DrillFuncHolder

use of org.apache.drill.exec.expr.fn.DrillFuncHolder in project drill by apache.

the class ExactFunctionResolver method getBestMatch.

/*
   * This function resolves the input call to a func holder only if all
   * the input argument types match exactly with the func holder arguments. This is used when we
   * are trying to inject an implicit cast and do not want to inject another implicit
   * cast
   */
@Override
public DrillFuncHolder getBestMatch(List<DrillFuncHolder> methods, FunctionCall call) {
    int currcost;
    for (DrillFuncHolder h : methods) {
        final List<TypeProtos.MajorType> argumentTypes = Lists.newArrayList();
        for (LogicalExpression expression : call.args) {
            argumentTypes.add(expression.getMajorType());
        }
        currcost = TypeCastRules.getCost(argumentTypes, h);
        // Return if we found a function that has an exact match with the input arguments
        if (currcost == 0) {
            return h;
        }
    }
    // No match found
    return null;
}
Also used : LogicalExpression(org.apache.drill.common.expression.LogicalExpression) DrillFuncHolder(org.apache.drill.exec.expr.fn.DrillFuncHolder)

Example 3 with DrillFuncHolder

use of org.apache.drill.exec.expr.fn.DrillFuncHolder in project drill by apache.

the class TypeInferenceUtils method resolveDrillFuncHolder.

private static DrillFuncHolder resolveDrillFuncHolder(final SqlOperatorBinding opBinding, final List<DrillFuncHolder> functions) {
    final FunctionCall functionCall = convertSqlOperatorBindingToFunctionCall(opBinding);
    final FunctionResolver functionResolver = FunctionResolverFactory.getResolver(functionCall);
    final DrillFuncHolder func = functionResolver.getBestMatch(functions, functionCall);
    // if no DrillFuncHolder matched for the given list of operand types
    if (func == null) {
        String operandTypes = "";
        for (int i = 0; i < opBinding.getOperandCount(); ++i) {
            operandTypes += opBinding.getOperandType(i).getSqlTypeName();
            if (i < opBinding.getOperandCount() - 1) {
                operandTypes += ",";
            }
        }
        throw UserException.functionError().message(String.format("%s does not support operand types (%s)", opBinding.getOperator().getName(), operandTypes)).build(logger);
    }
    return func;
}
Also used : DrillFuncHolder(org.apache.drill.exec.expr.fn.DrillFuncHolder) FunctionCall(org.apache.drill.common.expression.FunctionCall) FunctionResolver(org.apache.drill.exec.resolver.FunctionResolver)

Example 4 with DrillFuncHolder

use of org.apache.drill.exec.expr.fn.DrillFuncHolder in project drill by apache.

the class LocalFunctionRegistry method registerOperatorsWithoutInference.

private void registerOperatorsWithoutInference(DrillOperatorTable operatorTable, Map<String, Collection<DrillFuncHolder>> registeredFunctions) {
    SqlOperator op;
    for (Entry<String, Collection<DrillFuncHolder>> function : registeredFunctions.entrySet()) {
        Set<Integer> argCounts = Sets.newHashSet();
        String name = function.getKey().toUpperCase();
        for (DrillFuncHolder func : function.getValue()) {
            if (argCounts.add(func.getParamCount())) {
                if (func.isAggregating()) {
                    op = new DrillSqlAggOperatorWithoutInference(name, func.getParamCount());
                } else {
                    boolean isDeterministic;
                    // into literals
                    if (DrillConstExecutor.NON_REDUCIBLE_TYPES.contains(func.getReturnType().getMinorType())) {
                        isDeterministic = false;
                    } else {
                        isDeterministic = func.isDeterministic();
                    }
                    op = new DrillSqlOperatorWithoutInference(name, func.getParamCount(), func.getReturnType(), isDeterministic, func.isNiladic());
                }
                operatorTable.addOperatorWithoutInference(function.getKey(), op);
            }
        }
    }
}
Also used : DrillFuncHolder(org.apache.drill.exec.expr.fn.DrillFuncHolder) DrillSqlAggOperatorWithoutInference(org.apache.drill.exec.planner.sql.DrillSqlAggOperatorWithoutInference) DrillSqlOperator(org.apache.drill.exec.planner.sql.DrillSqlOperator) SqlOperator(org.apache.calcite.sql.SqlOperator) DrillSqlOperatorWithoutInference(org.apache.drill.exec.planner.sql.DrillSqlOperatorWithoutInference) Collection(java.util.Collection)

Example 5 with DrillFuncHolder

use of org.apache.drill.exec.expr.fn.DrillFuncHolder in project drill by apache.

the class LocalFunctionRegistry method registerOperatorsWithInference.

private void registerOperatorsWithInference(DrillOperatorTable operatorTable, Map<String, Collection<DrillFuncHolder>> registeredFunctions) {
    final Map<String, DrillSqlOperator.DrillSqlOperatorBuilder> map = Maps.newHashMap();
    final Map<String, DrillSqlAggOperator.DrillSqlAggOperatorBuilder> mapAgg = Maps.newHashMap();
    for (Entry<String, Collection<DrillFuncHolder>> function : registeredFunctions.entrySet()) {
        final ArrayListMultimap<Pair<Integer, Integer>, DrillFuncHolder> functions = ArrayListMultimap.create();
        final ArrayListMultimap<Integer, DrillFuncHolder> aggregateFunctions = ArrayListMultimap.create();
        final String name = function.getKey().toUpperCase();
        boolean isDeterministic = true;
        boolean isNiladic = false;
        for (DrillFuncHolder func : function.getValue()) {
            final int paramCount = func.getParamCount();
            if (func.isAggregating()) {
                aggregateFunctions.put(paramCount, func);
            } else {
                final Pair<Integer, Integer> argNumberRange;
                if (registeredFuncNameToArgRange.containsKey(name)) {
                    argNumberRange = registeredFuncNameToArgRange.get(name);
                } else {
                    argNumberRange = Pair.of(func.getParamCount(), func.getParamCount());
                }
                functions.put(argNumberRange, func);
            }
            if (!func.isDeterministic()) {
                isDeterministic = false;
            }
            if (func.isNiladic()) {
                isNiladic = true;
            }
        }
        for (Entry<Pair<Integer, Integer>, Collection<DrillFuncHolder>> entry : functions.asMap().entrySet()) {
            final Pair<Integer, Integer> range = entry.getKey();
            final int max = range.getRight();
            final int min = range.getLeft();
            if (!map.containsKey(name)) {
                map.put(name, new DrillSqlOperator.DrillSqlOperatorBuilder().setName(name));
            }
            final DrillSqlOperator.DrillSqlOperatorBuilder drillSqlOperatorBuilder = map.get(name);
            drillSqlOperatorBuilder.addFunctions(entry.getValue()).setArgumentCount(min, max).setDeterministic(isDeterministic).setNiladic(isNiladic);
        }
        for (Entry<Integer, Collection<DrillFuncHolder>> entry : aggregateFunctions.asMap().entrySet()) {
            if (!mapAgg.containsKey(name)) {
                mapAgg.put(name, new DrillSqlAggOperator.DrillSqlAggOperatorBuilder().setName(name));
            }
            final DrillSqlAggOperator.DrillSqlAggOperatorBuilder drillSqlAggOperatorBuilder = mapAgg.get(name);
            drillSqlAggOperatorBuilder.addFunctions(entry.getValue()).setArgumentCount(entry.getKey(), entry.getKey());
        }
    }
    for (final Entry<String, DrillSqlOperator.DrillSqlOperatorBuilder> entry : map.entrySet()) {
        operatorTable.addOperatorWithInference(entry.getKey(), entry.getValue().build());
    }
    for (final Entry<String, DrillSqlAggOperator.DrillSqlAggOperatorBuilder> entry : mapAgg.entrySet()) {
        operatorTable.addOperatorWithInference(entry.getKey(), entry.getValue().build());
    }
}
Also used : DrillFuncHolder(org.apache.drill.exec.expr.fn.DrillFuncHolder) DrillSqlAggOperator(org.apache.drill.exec.planner.sql.DrillSqlAggOperator) DrillSqlOperator(org.apache.drill.exec.planner.sql.DrillSqlOperator) Collection(java.util.Collection) Pair(org.apache.commons.lang3.tuple.Pair)

Aggregations

DrillFuncHolder (org.apache.drill.exec.expr.fn.DrillFuncHolder)12 LogicalExpression (org.apache.drill.common.expression.LogicalExpression)5 FunctionCall (org.apache.drill.common.expression.FunctionCall)4 FunctionResolver (org.apache.drill.exec.resolver.FunctionResolver)4 Collection (java.util.Collection)2 AtomicLong (java.util.concurrent.atomic.AtomicLong)2 QuotedString (org.apache.drill.common.expression.ValueExpressions.QuotedString)2 AnnotatedClassDescriptor (org.apache.drill.common.scanner.persistence.AnnotatedClassDescriptor)2 FunctionConverter (org.apache.drill.exec.expr.fn.FunctionConverter)2 DrillSqlOperator (org.apache.drill.exec.planner.sql.DrillSqlOperator)2 Test (org.junit.Test)2 ArrayList (java.util.ArrayList)1 LinkedList (java.util.LinkedList)1 List (java.util.List)1 SqlOperator (org.apache.calcite.sql.SqlOperator)1 Pair (org.apache.commons.lang3.tuple.Pair)1 ValueExpressions (org.apache.drill.common.expression.ValueExpressions)1 LongExpression (org.apache.drill.common.expression.ValueExpressions.LongExpression)1 FunctionValidationException (org.apache.drill.exec.exception.FunctionValidationException)1 JarValidationException (org.apache.drill.exec.exception.JarValidationException)1