Search in sources :

Example 26 with IfStatement

use of com.facebook.presto.bytecode.control.IfStatement in project presto by prestodb.

the class JoinFilterFunctionCompiler method generateFilterMethod.

private void generateFilterMethod(SqlFunctionProperties sqlFunctionProperties, Map<SqlFunctionId, SqlInvokedFunction> sessionFunctions, ClassDefinition classDefinition, CallSiteBinder callSiteBinder, CachedInstanceBinder cachedInstanceBinder, Map<LambdaDefinitionExpression, CompiledLambda> compiledLambdaMap, RowExpression filter, int leftBlocksSize, FieldDefinition propertiesField) {
    // int leftPosition, Page leftPage, int rightPosition, Page rightPage
    Parameter leftPosition = arg("leftPosition", int.class);
    Parameter leftPage = arg("leftPage", Page.class);
    Parameter rightPosition = arg("rightPosition", int.class);
    Parameter rightPage = arg("rightPage", Page.class);
    MethodDefinition method = classDefinition.declareMethod(a(PUBLIC), "filter", type(boolean.class), ImmutableList.<Parameter>builder().add(leftPosition).add(leftPage).add(rightPosition).add(rightPage).build());
    method.comment("filter: %s", filter.toString());
    BytecodeBlock body = method.getBody();
    Scope scope = method.getScope();
    Variable wasNullVariable = scope.declareVariable("wasNull", body, constantFalse());
    scope.declareVariable("properties", body, method.getThis().getField(propertiesField));
    RowExpressionCompiler compiler = new RowExpressionCompiler(classDefinition, callSiteBinder, cachedInstanceBinder, fieldReferenceCompiler(callSiteBinder, leftPosition, leftPage, rightPosition, rightPage, leftBlocksSize), metadata, sqlFunctionProperties, sessionFunctions, compiledLambdaMap);
    BytecodeNode visitorBody = compiler.compile(filter, scope, Optional.empty());
    Variable result = scope.declareVariable(boolean.class, "result");
    body.append(visitorBody).putVariable(result).append(new IfStatement().condition(wasNullVariable).ifTrue(constantFalse().ret()).ifFalse(result.ret()));
}
Also used : IfStatement(com.facebook.presto.bytecode.control.IfStatement) Variable(com.facebook.presto.bytecode.Variable) Scope(com.facebook.presto.bytecode.Scope) MethodDefinition(com.facebook.presto.bytecode.MethodDefinition) BytecodeBlock(com.facebook.presto.bytecode.BytecodeBlock) Parameter(com.facebook.presto.bytecode.Parameter) BytecodeNode(com.facebook.presto.bytecode.BytecodeNode)

Example 27 with IfStatement

use of com.facebook.presto.bytecode.control.IfStatement in project presto by prestodb.

the class NullIfCodeGenerator method generateExpression.

@Override
public BytecodeNode generateExpression(BytecodeGeneratorContext generatorContext, Type returnType, List<RowExpression> arguments, Optional<Variable> outputBlockVariable) {
    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
    Variable firstValue = scope.createTempVariable(first.getType().getJavaType());
    BytecodeBlock block = new BytecodeBlock().comment("check if first arg is null").append(generatorContext.generate(first, Optional.empty())).append(ifWasNullPopAndGoto(scope, notMatch, void.class)).dup(first.getType().getJavaType()).putVariable(firstValue);
    Type firstType = first.getType();
    Type secondType = second.getType();
    // if (equal(cast(first as <common type>), cast(second as <common type>))
    FunctionAndTypeManager functionAndTypeManager = generatorContext.getFunctionManager();
    FunctionHandle equalFunction = functionAndTypeManager.resolveOperator(EQUAL, fromTypes(firstType, secondType));
    FunctionMetadata equalFunctionMetadata = functionAndTypeManager.getFunctionMetadata(equalFunction);
    JavaScalarFunctionImplementation equalsFunction = generatorContext.getFunctionManager().getJavaScalarFunctionImplementation(equalFunction);
    BytecodeNode equalsCall = generatorContext.generateCall(EQUAL.name(), equalsFunction, ImmutableList.of(cast(generatorContext, firstValue, firstType, equalFunctionMetadata.getArgumentTypes().get(0)), cast(generatorContext, generatorContext.generate(second, Optional.empty()), secondType, equalFunctionMetadata.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));
    outputBlockVariable.ifPresent(output -> block.append(generateWrite(generatorContext, returnType, output)));
    return block;
}
Also used : LabelNode(com.facebook.presto.bytecode.instruction.LabelNode) FunctionMetadata(com.facebook.presto.spi.function.FunctionMetadata) JavaScalarFunctionImplementation(com.facebook.presto.spi.function.JavaScalarFunctionImplementation) IfStatement(com.facebook.presto.bytecode.control.IfStatement) CastType(com.facebook.presto.metadata.CastType) Type(com.facebook.presto.common.type.Type) Variable(com.facebook.presto.bytecode.Variable) Scope(com.facebook.presto.bytecode.Scope) FunctionAndTypeManager(com.facebook.presto.metadata.FunctionAndTypeManager) BytecodeBlock(com.facebook.presto.bytecode.BytecodeBlock) RowExpression(com.facebook.presto.spi.relation.RowExpression) BytecodeNode(com.facebook.presto.bytecode.BytecodeNode) FunctionHandle(com.facebook.presto.spi.function.FunctionHandle)

Example 28 with IfStatement

use of com.facebook.presto.bytecode.control.IfStatement in project presto by prestodb.

the class JoinCompiler method generatePositionNotDistinctFromRowWithPageMethod.

private void generatePositionNotDistinctFromRowWithPageMethod(ClassDefinition classDefinition, CallSiteBinder callSiteBinder, List<Type> joinChannelTypes, List<FieldDefinition> joinChannelFields) {
    Parameter leftBlockIndex = arg("leftBlockIndex", int.class);
    Parameter leftBlockPosition = arg("leftBlockPosition", int.class);
    Parameter rightPosition = arg("rightPosition", int.class);
    Parameter page = arg("page", Page.class);
    Parameter rightChannels = arg("rightChannels", int[].class);
    MethodDefinition positionNotDistinctFromRowMethod = classDefinition.declareMethod(a(PUBLIC), "positionNotDistinctFromRow", type(boolean.class), leftBlockIndex, leftBlockPosition, rightPosition, page, rightChannels);
    Variable thisVariable = positionNotDistinctFromRowMethod.getThis();
    Scope scope = positionNotDistinctFromRowMethod.getScope();
    BytecodeBlock body = positionNotDistinctFromRowMethod.getBody();
    if (groupByUsesEqualTo) {
        // positionNotDistinctFromRow delegates to positionEqualsRow when groupByUsesEqualTo is set.
        body.append(thisVariable.invoke("positionEqualsRow", boolean.class, leftBlockIndex, leftBlockPosition, rightPosition, page, rightChannels).ret());
        return;
    }
    scope.declareVariable("wasNull", body, constantFalse());
    for (int index = 0; index < joinChannelTypes.size(); index++) {
        BytecodeExpression leftBlock = thisVariable.getField(joinChannelFields.get(index)).invoke("get", Object.class, leftBlockIndex).cast(Block.class);
        BytecodeExpression rightBlock = page.invoke("getBlock", Block.class, rightChannels.getElement(index));
        Type type = joinChannelTypes.get(index);
        // At that point, we'll be able to fully deprecate Type.equalTo (and friends) and remove this hack.
        if (type.getJavaType().equals(Slice.class)) {
            switch(type.getTypeSignature().getBase()) {
                case StandardTypes.CHAR:
                case StandardTypes.IPADDRESS:
                case StandardTypes.JSON:
                case StandardTypes.DECIMAL:
                case StandardTypes.VARBINARY:
                case StandardTypes.VARCHAR:
                    body.append(new IfStatement().condition(typeEquals(constantType(callSiteBinder, type), leftBlock, leftBlockPosition, rightBlock, rightPosition)).ifFalse(constantFalse().ret()));
                    continue;
            }
        }
        JavaScalarFunctionImplementation operator = functionAndTypeManager.getJavaScalarFunctionImplementation(functionAndTypeManager.resolveOperator(OperatorType.IS_DISTINCT_FROM, fromTypes(type, type)));
        callSiteBinder.bind(operator.getMethodHandle());
        List<BytecodeNode> argumentsBytecode = new ArrayList<>();
        argumentsBytecode.add(generateInputReference(callSiteBinder, scope, type, leftBlock, leftBlockPosition));
        argumentsBytecode.add(generateInputReference(callSiteBinder, scope, type, rightBlock, rightPosition));
        body.append(new IfStatement().condition(BytecodeUtils.generateInvocation(scope, "isDistinctFrom", operator, Optional.empty(), argumentsBytecode, callSiteBinder)).ifTrue(constantFalse().ret()));
    }
    body.append(constantTrue().ret());
}
Also used : JavaScalarFunctionImplementation(com.facebook.presto.spi.function.JavaScalarFunctionImplementation) Variable(com.facebook.presto.bytecode.Variable) BytecodeBlock(com.facebook.presto.bytecode.BytecodeBlock) ArrayList(java.util.ArrayList) IfStatement(com.facebook.presto.bytecode.control.IfStatement) BigintType(com.facebook.presto.common.type.BigintType) Type(com.facebook.presto.common.type.Type) SqlTypeBytecodeExpression.constantType(com.facebook.presto.sql.gen.SqlTypeBytecodeExpression.constantType) OperatorType(com.facebook.presto.common.function.OperatorType) Scope(com.facebook.presto.bytecode.Scope) MethodDefinition(com.facebook.presto.bytecode.MethodDefinition) Parameter(com.facebook.presto.bytecode.Parameter) BytecodeNode(com.facebook.presto.bytecode.BytecodeNode) BytecodeExpression(com.facebook.presto.bytecode.expression.BytecodeExpression)

Example 29 with IfStatement

use of com.facebook.presto.bytecode.control.IfStatement in project presto by prestodb.

the class BytecodeUtils method handleNullValue.

public static BytecodeNode handleNullValue(Scope scope, LabelNode label, Class<?> methodReturnType, List<Class<?>> stackArgsToPop, Optional<Variable> outputBlockVariable, boolean clearNullFlag) {
    if (outputBlockVariable.isPresent()) {
        checkArgument(methodReturnType == void.class);
    }
    Variable wasNull = scope.getVariable("wasNull");
    BytecodeBlock nullCheck = new BytecodeBlock().setDescription("ifWasNullGoto").append(wasNull);
    String clearComment = null;
    if (clearNullFlag) {
        nullCheck.append(wasNull.set(constantFalse()));
        clearComment = "clear wasNull";
    }
    BytecodeBlock isNull = new BytecodeBlock();
    for (Class<?> parameterType : stackArgsToPop) {
        isNull.pop(parameterType);
    }
    String loadDefaultOrAppendNullComment;
    if (!outputBlockVariable.isPresent()) {
        isNull.pushJavaDefault(methodReturnType);
        loadDefaultOrAppendNullComment = format("loadJavaDefault(%s)", methodReturnType.getName());
    } else {
        isNull.append(outputBlockVariable.get().invoke("appendNull", BlockBuilder.class).pop());
        loadDefaultOrAppendNullComment = "appendNullToOutputBlock";
    }
    isNull.gotoLabel(label);
    String popComment = null;
    if (!stackArgsToPop.isEmpty()) {
        popComment = format("pop(%s)", Joiner.on(", ").join(stackArgsToPop));
    }
    return new IfStatement("if wasNull then %s", Joiner.on(", ").skipNulls().join(clearComment, popComment, loadDefaultOrAppendNullComment, "goto " + label.getLabel())).condition(nullCheck).ifTrue(isNull);
}
Also used : IfStatement(com.facebook.presto.bytecode.control.IfStatement) Variable(com.facebook.presto.bytecode.Variable) BytecodeBlock(com.facebook.presto.bytecode.BytecodeBlock)

Example 30 with IfStatement

use of com.facebook.presto.bytecode.control.IfStatement in project presto by prestodb.

the class CoalesceCodeGenerator method generateExpression.

@Override
public BytecodeNode generateExpression(BytecodeGeneratorContext generatorContext, Type returnType, List<RowExpression> arguments, Optional<Variable> outputBlockVariable) {
    Variable wasNull = generatorContext.wasNull();
    LabelNode endLabel = new LabelNode("end");
    BytecodeBlock block = new BytecodeBlock();
    // Generate all but the last one.
    for (RowExpression expression : arguments.subList(0, arguments.size() - 1)) {
        block.append(generatorContext.generate(expression, Optional.empty()));
        // Check if null
        IfStatement ifStatement = new IfStatement().condition(wasNull);
        ifStatement.ifTrue().pop(returnType.getJavaType()).append(wasNull.set(constantFalse()));
        ifStatement.ifFalse().gotoLabel(endLabel);
        block.append(ifStatement);
    }
    // Just return the last one here if control reaches here.
    block.append(generatorContext.generate(arguments.get(arguments.size() - 1), Optional.empty()));
    block.visitLabel(endLabel);
    outputBlockVariable.ifPresent(output -> block.append(generateWrite(generatorContext, returnType, output)));
    return block;
}
Also used : LabelNode(com.facebook.presto.bytecode.instruction.LabelNode) IfStatement(com.facebook.presto.bytecode.control.IfStatement) Variable(com.facebook.presto.bytecode.Variable) BytecodeBlock(com.facebook.presto.bytecode.BytecodeBlock) RowExpression(com.facebook.presto.spi.relation.RowExpression)

Aggregations

IfStatement (com.facebook.presto.bytecode.control.IfStatement)77 BytecodeBlock (com.facebook.presto.bytecode.BytecodeBlock)72 Variable (com.facebook.presto.bytecode.Variable)65 MethodDefinition (com.facebook.presto.bytecode.MethodDefinition)45 Scope (com.facebook.presto.bytecode.Scope)43 Parameter (com.facebook.presto.bytecode.Parameter)41 BytecodeNode (com.facebook.presto.bytecode.BytecodeNode)23 ForLoop (com.facebook.presto.bytecode.control.ForLoop)19 BytecodeExpression (com.facebook.presto.bytecode.expression.BytecodeExpression)19 LabelNode (com.facebook.presto.bytecode.instruction.LabelNode)19 ImmutableList (com.google.common.collect.ImmutableList)18 Block (com.facebook.presto.spi.block.Block)15 Block (com.facebook.presto.common.block.Block)13 ClassDefinition (com.facebook.presto.bytecode.ClassDefinition)10 Type (com.facebook.presto.common.type.Type)10 DictionaryBlock (com.facebook.presto.spi.block.DictionaryBlock)10 LazyBlock (com.facebook.presto.spi.block.LazyBlock)10 RunLengthEncodedBlock (com.facebook.presto.spi.block.RunLengthEncodedBlock)10 CallSiteBinder (com.facebook.presto.bytecode.CallSiteBinder)9 BlockBuilder (com.facebook.presto.common.block.BlockBuilder)9