Search in sources :

Example 1 with ScalarFunctionImplementation

use of com.facebook.presto.operator.scalar.ScalarFunctionImplementation in project presto by prestodb.

the class FunctionRegistry method parameterIsNullable.

private boolean parameterIsNullable(Signature boundSignature, int parameterIndex) {
    FunctionKind functionKind = boundSignature.getKind();
    // Window and Aggregation functions have fixed semantic where NULL values are always skipped
    if (functionKind != SCALAR) {
        return false;
    }
    // TODO: Move information about nullable arguments to FunctionSignature. Remove this hack.
    ScalarFunctionImplementation implementation = getScalarFunctionImplementation(boundSignature);
    return implementation.getNullableArguments().get(parameterIndex);
}
Also used : ScalarFunctionImplementation(com.facebook.presto.operator.scalar.ScalarFunctionImplementation)

Example 2 with ScalarFunctionImplementation

use of com.facebook.presto.operator.scalar.ScalarFunctionImplementation in project presto by prestodb.

the class PolymorphicScalarFunction method specialize.

@Override
public ScalarFunctionImplementation specialize(BoundVariables boundVariables, int arity, TypeManager typeManager, FunctionRegistry functionRegistry) {
    List<TypeSignature> resolvedParameterTypeSignatures = applyBoundVariables(getSignature().getArgumentTypes(), boundVariables);
    List<Type> resolvedParameterTypes = resolveTypes(resolvedParameterTypeSignatures, typeManager);
    TypeSignature resolvedReturnTypeSignature = applyBoundVariables(getSignature().getReturnType(), boundVariables);
    Type resolvedReturnType = typeManager.getType(resolvedReturnTypeSignature);
    SpecializeContext context = new SpecializeContext(boundVariables, resolvedParameterTypes, resolvedReturnType, typeManager, functionRegistry);
    Optional<Method> matchingMethod = Optional.empty();
    Optional<MethodsGroup> matchingMethodsGroup = Optional.empty();
    for (MethodsGroup candidateMethodsGroup : methodsGroups) {
        for (Method candidateMethod : candidateMethodsGroup.getMethods()) {
            if (matchesParameterAndReturnTypes(candidateMethod, resolvedParameterTypes, resolvedReturnType) && predicateIsTrue(candidateMethodsGroup, context)) {
                if (matchingMethod.isPresent()) {
                    if (onlyFirstMatchedMethodHasPredicate(matchingMethodsGroup.get(), candidateMethodsGroup)) {
                        continue;
                    }
                    throw new IllegalStateException("two matching methods (" + matchingMethod.get().getName() + " and " + candidateMethod.getName() + ") for parameter types " + resolvedParameterTypeSignatures);
                }
                matchingMethod = Optional.of(candidateMethod);
                matchingMethodsGroup = Optional.of(candidateMethodsGroup);
            }
        }
    }
    checkState(matchingMethod.isPresent(), "no matching method for parameter types %s", resolvedParameterTypes);
    List<Object> extraParameters = computeExtraParameters(matchingMethodsGroup.get(), context);
    MethodHandle matchingMethodHandle = applyExtraParameters(matchingMethod.get(), extraParameters);
    return new ScalarFunctionImplementation(nullableResult, nullableArguments, nullFlags, matchingMethodHandle, deterministic);
}
Also used : ScalarFunctionImplementation(com.facebook.presto.operator.scalar.ScalarFunctionImplementation) MethodsGroup(com.facebook.presto.metadata.SqlScalarFunctionBuilder.MethodsGroup) Method(java.lang.reflect.Method) SpecializeContext(com.facebook.presto.metadata.SqlScalarFunctionBuilder.SpecializeContext) TypeSignature(com.facebook.presto.spi.type.TypeSignature) Type(com.facebook.presto.spi.type.Type) MethodHandle(java.lang.invoke.MethodHandle)

Example 3 with ScalarFunctionImplementation

use of com.facebook.presto.operator.scalar.ScalarFunctionImplementation in project presto by prestodb.

the class FunctionInvoker method invoke.

/**
     * Arguments must be the native container type for the corresponding SQL types.
     *
     * Returns a value in the native container type corresponding to the declared SQL return type
     */
public Object invoke(Signature function, ConnectorSession session, List<Object> arguments) {
    ScalarFunctionImplementation implementation = registry.getScalarFunctionImplementation(function);
    MethodHandle method = implementation.getMethodHandle();
    List<Object> actualArguments = new ArrayList<>(arguments.size() + 1);
    Iterator<Object> iterator = arguments.iterator();
    for (int i = 0; i < method.type().parameterCount(); i++) {
        Class<?> parameterType = method.type().parameterType(i);
        if (parameterType == ConnectorSession.class) {
            actualArguments.add(session);
        } else {
            checkArgument(iterator.hasNext(), "Not enough arguments provided for method: %s", method.type());
            Object argument = iterator.next();
            if (implementation.getNullFlags().get(i)) {
                boolean isNull = argument == null;
                if (isNull) {
                    argument = Defaults.defaultValue(parameterType);
                }
                actualArguments.add(argument);
                actualArguments.add(isNull);
                // Skip the next method parameter which is marked @IsNull
                i++;
            } else {
                actualArguments.add(argument);
            }
        }
    }
    checkArgument(!iterator.hasNext(), "Too many arguments provided for method: %s", method.type());
    try {
        return method.invokeWithArguments(actualArguments);
    } catch (Throwable throwable) {
        throw Throwables.propagate(throwable);
    }
}
Also used : ScalarFunctionImplementation(com.facebook.presto.operator.scalar.ScalarFunctionImplementation) ArrayList(java.util.ArrayList) MethodHandle(java.lang.invoke.MethodHandle)

Example 4 with ScalarFunctionImplementation

use of com.facebook.presto.operator.scalar.ScalarFunctionImplementation in project presto by prestodb.

the class NullIfCodeGenerator method generateExpression.

@Override
public BytecodeNode generateExpression(Signature signature, BytecodeGeneratorContext generatorContext, Type returnType, List<RowExpression> arguments) {
    Scope scope = generatorContext.getScope();
    RowExpression first = arguments.get(0);
    RowExpression second = arguments.get(1);
    LabelNode notMatch = new LabelNode("notMatch");
    // push first arg on the stack
    BytecodeBlock block = new BytecodeBlock().comment("check if first arg is null").append(generatorContext.generate(first)).append(BytecodeUtils.ifWasNullPopAndGoto(scope, notMatch, void.class));
    Type firstType = first.getType();
    Type secondType = second.getType();
    // if (equal(cast(first as <common type>), cast(second as <common type>))
    Signature equalsSignature = generatorContext.getRegistry().resolveOperator(OperatorType.EQUAL, ImmutableList.of(firstType, secondType));
    ScalarFunctionImplementation equalsFunction = generatorContext.getRegistry().getScalarFunctionImplementation(equalsSignature);
    BytecodeNode equalsCall = generatorContext.generateCall(equalsSignature.getName(), equalsFunction, ImmutableList.of(cast(generatorContext, new BytecodeBlock().dup(firstType.getJavaType()), firstType, equalsSignature.getArgumentTypes().get(0)), cast(generatorContext, generatorContext.generate(second), secondType, equalsSignature.getArgumentTypes().get(1))));
    BytecodeBlock conditionBlock = new BytecodeBlock().append(equalsCall).append(BytecodeUtils.ifWasNullClearPopAndGoto(scope, notMatch, void.class, boolean.class));
    // if first and second are equal, return null
    BytecodeBlock trueBlock = new BytecodeBlock().append(generatorContext.wasNull().set(constantTrue())).pop(first.getType().getJavaType()).pushJavaDefault(first.getType().getJavaType());
    // else return first (which is still on the stack
    block.append(new IfStatement().condition(conditionBlock).ifTrue(trueBlock).ifFalse(notMatch));
    return block;
}
Also used : LabelNode(com.facebook.presto.bytecode.instruction.LabelNode) ScalarFunctionImplementation(com.facebook.presto.operator.scalar.ScalarFunctionImplementation) IfStatement(com.facebook.presto.bytecode.control.IfStatement) OperatorType(com.facebook.presto.spi.function.OperatorType) Type(com.facebook.presto.spi.type.Type) Scope(com.facebook.presto.bytecode.Scope) TypeSignature(com.facebook.presto.spi.type.TypeSignature) Signature(com.facebook.presto.metadata.Signature) BytecodeBlock(com.facebook.presto.bytecode.BytecodeBlock) RowExpression(com.facebook.presto.sql.relational.RowExpression) BytecodeNode(com.facebook.presto.bytecode.BytecodeNode)

Example 5 with ScalarFunctionImplementation

use of com.facebook.presto.operator.scalar.ScalarFunctionImplementation in project presto by prestodb.

the class TestPolymorphicScalarFunction method testSetsHiddenToTrueForOperators.

@Test
public void testSetsHiddenToTrueForOperators() {
    Signature signature = Signature.builder().operatorType(ADD).kind(SCALAR).returnType(parseTypeSignature("varchar(x)", ImmutableSet.of("x"))).argumentTypes(parseTypeSignature("varchar(x)", ImmutableSet.of("x"))).build();
    SqlScalarFunction function = SqlScalarFunction.builder(TestMethods.class).signature(signature).implementation(b -> b.methods("varcharToVarchar")).build();
    ScalarFunctionImplementation functionImplementation = function.specialize(BOUND_VARIABLES, 1, TYPE_REGISTRY, REGISTRY);
}
Also used : TypeSignature(com.facebook.presto.spi.type.TypeSignature) ImmutableSet(com.google.common.collect.ImmutableSet) Slice(io.airlift.slice.Slice) ImmutableMap(com.google.common.collect.ImmutableMap) TypeRegistry(com.facebook.presto.type.TypeRegistry) Assert.assertEquals(org.testng.Assert.assertEquals) ScalarFunctionImplementation(com.facebook.presto.operator.scalar.ScalarFunctionImplementation) Test(org.testng.annotations.Test) Signature.comparableWithVariadicBound(com.facebook.presto.metadata.Signature.comparableWithVariadicBound) FeaturesConfig(com.facebook.presto.sql.analyzer.FeaturesConfig) SCALAR(com.facebook.presto.metadata.FunctionKind.SCALAR) VARCHAR(com.facebook.presto.spi.type.StandardTypes.VARCHAR) ImmutableList(com.google.common.collect.ImmutableList) VARCHAR_TO_BIGINT_RETURN_VALUE(com.facebook.presto.metadata.TestPolymorphicScalarFunction.TestMethods.VARCHAR_TO_BIGINT_RETURN_VALUE) Slices(io.airlift.slice.Slices) TypeSignature.parseTypeSignature(com.facebook.presto.spi.type.TypeSignature.parseTypeSignature) StandardTypes(com.facebook.presto.spi.type.StandardTypes) Math.toIntExact(java.lang.Math.toIntExact) VARCHAR_TO_VARCHAR_RETURN_VALUE(com.facebook.presto.metadata.TestPolymorphicScalarFunction.TestMethods.VARCHAR_TO_VARCHAR_RETURN_VALUE) BlockEncodingManager(com.facebook.presto.block.BlockEncodingManager) ADD(com.facebook.presto.spi.function.OperatorType.ADD) ScalarFunctionImplementation(com.facebook.presto.operator.scalar.ScalarFunctionImplementation) TypeSignature(com.facebook.presto.spi.type.TypeSignature) TypeSignature.parseTypeSignature(com.facebook.presto.spi.type.TypeSignature.parseTypeSignature) Test(org.testng.annotations.Test)

Aggregations

ScalarFunctionImplementation (com.facebook.presto.operator.scalar.ScalarFunctionImplementation)13 TypeSignature (com.facebook.presto.spi.type.TypeSignature)9 BlockEncodingManager (com.facebook.presto.block.BlockEncodingManager)7 SCALAR (com.facebook.presto.metadata.FunctionKind.SCALAR)7 Signature.comparableWithVariadicBound (com.facebook.presto.metadata.Signature.comparableWithVariadicBound)7 VARCHAR_TO_BIGINT_RETURN_VALUE (com.facebook.presto.metadata.TestPolymorphicScalarFunction.TestMethods.VARCHAR_TO_BIGINT_RETURN_VALUE)7 VARCHAR_TO_VARCHAR_RETURN_VALUE (com.facebook.presto.metadata.TestPolymorphicScalarFunction.TestMethods.VARCHAR_TO_VARCHAR_RETURN_VALUE)7 ADD (com.facebook.presto.spi.function.OperatorType.ADD)7 StandardTypes (com.facebook.presto.spi.type.StandardTypes)7 VARCHAR (com.facebook.presto.spi.type.StandardTypes.VARCHAR)7 TypeSignature.parseTypeSignature (com.facebook.presto.spi.type.TypeSignature.parseTypeSignature)7 FeaturesConfig (com.facebook.presto.sql.analyzer.FeaturesConfig)7 TypeRegistry (com.facebook.presto.type.TypeRegistry)7 ImmutableList (com.google.common.collect.ImmutableList)7 ImmutableMap (com.google.common.collect.ImmutableMap)7 ImmutableSet (com.google.common.collect.ImmutableSet)7 Slice (io.airlift.slice.Slice)7 Slices (io.airlift.slice.Slices)7 Math.toIntExact (java.lang.Math.toIntExact)7 Assert.assertEquals (org.testng.Assert.assertEquals)7