Search in sources :

Example 31 with FunctionHandle

use of com.facebook.presto.spi.function.FunctionHandle in project presto by prestodb.

the class TestRowExpressionOptimizer method testIfConstantOptimization.

@Test
public void testIfConstantOptimization() {
    assertEquals(optimize(ifExpression(constant(true, BOOLEAN), 1L, 2L)), constant(1L, BIGINT));
    assertEquals(optimize(ifExpression(constant(false, BOOLEAN), 1L, 2L)), constant(2L, BIGINT));
    assertEquals(optimize(ifExpression(constant(null, BOOLEAN), 1L, 2L)), constant(2L, BIGINT));
    FunctionHandle bigintEquals = functionAndTypeManager.resolveOperator(EQUAL, fromTypes(BIGINT, BIGINT));
    RowExpression condition = new CallExpression(EQUAL.name(), bigintEquals, BOOLEAN, ImmutableList.of(constant(3L, BIGINT), constant(3L, BIGINT)));
    assertEquals(optimize(ifExpression(condition, 1L, 2L)), constant(1L, BIGINT));
}
Also used : RowExpression(com.facebook.presto.spi.relation.RowExpression) FunctionHandle(com.facebook.presto.spi.function.FunctionHandle) CallExpression(com.facebook.presto.spi.relation.CallExpression) Test(org.testng.annotations.Test)

Example 32 with FunctionHandle

use of com.facebook.presto.spi.function.FunctionHandle in project presto by prestodb.

the class TestDeterminismEvaluator method testDeterminismEvaluator.

@Test
public void testDeterminismEvaluator() {
    FunctionAndTypeManager functionAndTypeManager = createTestMetadataManager().getFunctionAndTypeManager();
    RowExpressionDeterminismEvaluator determinismEvaluator = new RowExpressionDeterminismEvaluator(functionAndTypeManager);
    CallExpression random = new CallExpression("random", functionAndTypeManager.lookupFunction("random", fromTypes(BIGINT)), BIGINT, singletonList(constant(10L, BIGINT)));
    assertFalse(determinismEvaluator.isDeterministic(random));
    InputReferenceExpression col0 = field(0, BIGINT);
    FunctionHandle lessThan = functionAndTypeManager.resolveOperator(LESS_THAN, fromTypes(BIGINT, BIGINT));
    CallExpression lessThanExpression = new CallExpression(LESS_THAN.name(), lessThan, BOOLEAN, ImmutableList.of(col0, constant(10L, BIGINT)));
    assertTrue(determinismEvaluator.isDeterministic(lessThanExpression));
    CallExpression lessThanRandomExpression = new CallExpression(LESS_THAN.name(), lessThan, BOOLEAN, ImmutableList.of(col0, random));
    assertFalse(determinismEvaluator.isDeterministic(lessThanRandomExpression));
}
Also used : InputReferenceExpression(com.facebook.presto.spi.relation.InputReferenceExpression) FunctionAndTypeManager(com.facebook.presto.metadata.FunctionAndTypeManager) CallExpression(com.facebook.presto.spi.relation.CallExpression) FunctionHandle(com.facebook.presto.spi.function.FunctionHandle) Test(org.testng.annotations.Test)

Example 33 with FunctionHandle

use of com.facebook.presto.spi.function.FunctionHandle in project presto by prestodb.

the class ArrayToArrayCast method specialize.

@Override
public BuiltInScalarFunctionImplementation specialize(BoundVariables boundVariables, int arity, FunctionAndTypeManager functionAndTypeManager) {
    checkArgument(arity == 1, "Expected arity to be 1");
    Type fromType = boundVariables.getTypeVariable("F");
    Type toType = boundVariables.getTypeVariable("T");
    FunctionHandle functionHandle = functionAndTypeManager.lookupCast(CastType.CAST, fromType.getTypeSignature(), toType.getTypeSignature());
    JavaScalarFunctionImplementation function = functionAndTypeManager.getJavaScalarFunctionImplementation(functionHandle);
    Class<?> castOperatorClass = generateArrayCast(functionAndTypeManager, functionAndTypeManager.getFunctionMetadata(functionHandle), function);
    MethodHandle methodHandle = methodHandle(castOperatorClass, "castArray", SqlFunctionProperties.class, Block.class);
    return new BuiltInScalarFunctionImplementation(false, ImmutableList.of(valueTypeArgumentProperty(RETURN_NULL_ON_NULL), valueTypeArgumentProperty(RETURN_NULL_ON_NULL)), methodHandle);
}
Also used : JavaScalarFunctionImplementation(com.facebook.presto.spi.function.JavaScalarFunctionImplementation) CastType(com.facebook.presto.metadata.CastType) Type(com.facebook.presto.common.type.Type) FunctionHandle(com.facebook.presto.spi.function.FunctionHandle) MethodHandle(java.lang.invoke.MethodHandle)

Example 34 with FunctionHandle

use of com.facebook.presto.spi.function.FunctionHandle in project presto by prestodb.

the class DruidFilterExpressionConverter method visitCall.

@Override
public DruidExpression visitCall(CallExpression call, Function<VariableReferenceExpression, Selection> context) {
    FunctionHandle functionHandle = call.getFunctionHandle();
    if (standardFunctionResolution.isNotFunction(functionHandle)) {
        return handleNot(call, context);
    }
    if (standardFunctionResolution.isCastFunction(functionHandle)) {
        return handleCast(call, context);
    }
    if (standardFunctionResolution.isBetweenFunction(functionHandle)) {
        return handleBetween(call, context);
    }
    FunctionMetadata functionMetadata = functionMetadataManager.getFunctionMetadata(call.getFunctionHandle());
    Optional<OperatorType> operatorTypeOptional = functionMetadata.getOperatorType();
    if (operatorTypeOptional.isPresent()) {
        OperatorType operatorType = operatorTypeOptional.get();
        if (operatorType.isArithmeticOperator()) {
            throw new PrestoException(DRUID_PUSHDOWN_UNSUPPORTED_EXPRESSION, "Arithmetic expressions are not supported in Druid filter: " + call);
        }
        if (operatorType.isComparisonOperator()) {
            return handleLogicalBinary(operatorType.getOperator(), call, context);
        }
    }
    throw new PrestoException(DRUID_PUSHDOWN_UNSUPPORTED_EXPRESSION, "Function " + call + " not supported in Druid filter");
}
Also used : FunctionMetadata(com.facebook.presto.spi.function.FunctionMetadata) PrestoException(com.facebook.presto.spi.PrestoException) FunctionHandle(com.facebook.presto.spi.function.FunctionHandle) OperatorType(com.facebook.presto.common.function.OperatorType)

Example 35 with FunctionHandle

use of com.facebook.presto.spi.function.FunctionHandle in project presto by prestodb.

the class SwitchCodeGenerator method generateExpression.

@Override
public BytecodeNode generateExpression(BytecodeGeneratorContext generatorContext, Type returnType, List<RowExpression> arguments, Optional<Variable> outputBlockVariable) {
    Scope scope = generatorContext.getScope();
    BytecodeNode elseValue;
    List<RowExpression> whenClauses;
    RowExpression last = arguments.get(arguments.size() - 1);
    if (last instanceof SpecialFormExpression && ((SpecialFormExpression) last).getForm().equals(WHEN)) {
        whenClauses = arguments.subList(1, arguments.size());
        elseValue = new BytecodeBlock().append(generatorContext.wasNull().set(constantTrue())).pushJavaDefault(returnType.getJavaType());
    } else {
        whenClauses = arguments.subList(1, arguments.size() - 1);
        elseValue = generatorContext.generate(last, Optional.empty());
    }
    // determine the type of the value and result
    RowExpression value = arguments.get(0);
    Class<?> valueType = value.getType().getJavaType();
    // We generate SearchedCase as CASE TRUE WHEN p1 THEN v1 WHEN p2 THEN p2...
    boolean searchedCase = (value instanceof ConstantExpression && ((ConstantExpression) value).getType() == BOOLEAN && ((ConstantExpression) value).getValue() == Boolean.TRUE);
    // evaluate the value and store it in a variable
    LabelNode elseLabel = new LabelNode("else");
    LabelNode endLabel = new LabelNode("end");
    BytecodeBlock block = new BytecodeBlock();
    Optional<BytecodeNode> getTempVariableNode;
    if (!searchedCase) {
        BytecodeNode valueBytecode = generatorContext.generate(value, Optional.empty());
        Variable tempVariable = scope.createTempVariable(valueType);
        block.append(valueBytecode).append(BytecodeUtils.ifWasNullClearPopAndGoto(scope, elseLabel, void.class, valueType)).putVariable(tempVariable);
        getTempVariableNode = Optional.of(VariableInstruction.loadVariable(tempVariable));
    } else {
        getTempVariableNode = Optional.empty();
    }
    Variable wasNull = generatorContext.wasNull();
    block.putVariable(wasNull, false);
    Map<RowExpression, LabelNode> resultLabels = new HashMap<>();
    // We already know the P1 .. Pn are all boolean just call them and search for true (false/null don't matter).
    for (RowExpression clause : whenClauses) {
        checkArgument(clause instanceof SpecialFormExpression && ((SpecialFormExpression) clause).getForm().equals(WHEN));
        RowExpression operand = ((SpecialFormExpression) clause).getArguments().get(0);
        BytecodeNode operandBytecode;
        if (searchedCase) {
            operandBytecode = generatorContext.generate(operand, Optional.empty());
        } else {
            // call equals(value, operandBytecode)
            FunctionHandle equalsFunction = generatorContext.getFunctionManager().resolveOperator(EQUAL, fromTypes(value.getType(), operand.getType()));
            operandBytecode = generatorContext.generateCall(EQUAL.name(), generatorContext.getFunctionManager().getJavaScalarFunctionImplementation(equalsFunction), ImmutableList.of(generatorContext.generate(operand, Optional.empty()), getTempVariableNode.get()));
        }
        block.append(operandBytecode);
        IfStatement ifWasNull = new IfStatement().condition(wasNull);
        ifWasNull.ifTrue().putVariable(wasNull, false).pop(// pop the result of the predicate eval
        Boolean.class);
        // Here the TOS  is the result of the predicate.
        RowExpression result = ((SpecialFormExpression) clause).getArguments().get(1);
        LabelNode target = resultLabels.get(result);
        if (target == null) {
            target = new LabelNode(RESULT_LABEL_PREFIX + resultLabels.size());
            resultLabels.put(result, target);
        }
        ifWasNull.ifFalse().ifTrueGoto(target);
        block.append(ifWasNull);
    }
    // Here we evaluate the else result.
    block.visitLabel(elseLabel).append(elseValue).gotoLabel(endLabel);
    // Now generate the result expression code.
    for (Map.Entry<RowExpression, LabelNode> resultLabel : resultLabels.entrySet()) {
        block.visitLabel(resultLabel.getValue()).append(generatorContext.generate(resultLabel.getKey(), Optional.empty())).gotoLabel(endLabel);
    }
    block.visitLabel(endLabel);
    outputBlockVariable.ifPresent(output -> block.append(generateWrite(generatorContext, returnType, output)));
    return block;
}
Also used : LabelNode(com.facebook.presto.bytecode.instruction.LabelNode) Variable(com.facebook.presto.bytecode.Variable) HashMap(java.util.HashMap) ConstantExpression(com.facebook.presto.spi.relation.ConstantExpression) BytecodeBlock(com.facebook.presto.bytecode.BytecodeBlock) RowExpression(com.facebook.presto.spi.relation.RowExpression) IfStatement(com.facebook.presto.bytecode.control.IfStatement) Scope(com.facebook.presto.bytecode.Scope) BytecodeNode(com.facebook.presto.bytecode.BytecodeNode) SpecialFormExpression(com.facebook.presto.spi.relation.SpecialFormExpression) FunctionHandle(com.facebook.presto.spi.function.FunctionHandle) HashMap(java.util.HashMap) Map(java.util.Map)

Aggregations

FunctionHandle (com.facebook.presto.spi.function.FunctionHandle)44 Test (org.testng.annotations.Test)20 CallExpression (com.facebook.presto.spi.relation.CallExpression)16 Type (com.facebook.presto.common.type.Type)14 RowExpression (com.facebook.presto.spi.relation.RowExpression)13 FunctionAndTypeManager (com.facebook.presto.metadata.FunctionAndTypeManager)9 VariableReferenceExpression (com.facebook.presto.spi.relation.VariableReferenceExpression)9 ImmutableList (com.google.common.collect.ImmutableList)8 Variable (com.facebook.presto.bytecode.Variable)7 JavaScalarFunctionImplementation (com.facebook.presto.spi.function.JavaScalarFunctionImplementation)7 BytecodeBlock (com.facebook.presto.bytecode.BytecodeBlock)6 IfStatement (com.facebook.presto.bytecode.control.IfStatement)6 Page (com.facebook.presto.common.Page)6 ArrayType (com.facebook.presto.common.type.ArrayType)6 Map (java.util.Map)6 BytecodeNode (com.facebook.presto.bytecode.BytecodeNode)5 Scope (com.facebook.presto.bytecode.Scope)5 FunctionMetadata (com.facebook.presto.spi.function.FunctionMetadata)5 LabelNode (com.facebook.presto.bytecode.instruction.LabelNode)4 MapType (com.facebook.presto.common.type.MapType)4