Search in sources :

Example 31 with Scope

use of com.facebook.presto.bytecode.Scope in project presto by prestodb.

the class MapFilterFunction method generateFilter.

private static MethodHandle generateFilter(Type keyType, Type valueType) {
    CallSiteBinder binder = new CallSiteBinder();
    MapType mapType = new MapType(keyType, valueType);
    Class<?> keyJavaType = Primitives.wrap(keyType.getJavaType());
    Class<?> valueJavaType = Primitives.wrap(valueType.getJavaType());
    ClassDefinition definition = new ClassDefinition(a(PUBLIC, FINAL), makeClassName("MapFilter"), type(Object.class));
    definition.declareDefaultConstructor(a(PRIVATE));
    Parameter block = arg("block", Block.class);
    Parameter function = arg("function", MethodHandle.class);
    MethodDefinition method = definition.declareMethod(a(PUBLIC, STATIC), "filter", type(Block.class), ImmutableList.of(block, function));
    BytecodeBlock body = method.getBody();
    Scope scope = method.getScope();
    Variable positionCount = scope.declareVariable(int.class, "positionCount");
    Variable position = scope.declareVariable(int.class, "position");
    Variable blockBuilder = scope.declareVariable(BlockBuilder.class, "blockBuilder");
    Variable keyElement = scope.declareVariable(keyJavaType, "keyElement");
    Variable valueElement = scope.declareVariable(valueJavaType, "valueElement");
    Variable keep = scope.declareVariable(Boolean.class, "keep");
    // invoke block.getPositionCount()
    body.append(positionCount.set(block.invoke("getPositionCount", int.class)));
    // create the interleaved block builder
    body.append(blockBuilder.set(newInstance(InterleavedBlockBuilder.class, constantType(binder, mapType).invoke("getTypeParameters", List.class), newInstance(BlockBuilderStatus.class), positionCount)));
    SqlTypeBytecodeExpression keySqlType = constantType(binder, keyType);
    BytecodeNode loadKeyElement;
    if (!keyType.equals(UNKNOWN)) {
        // key element must be non-null
        loadKeyElement = new BytecodeBlock().append(keyElement.set(keySqlType.getValue(block, position).cast(keyJavaType)));
    } else {
        loadKeyElement = new BytecodeBlock().append(keyElement.set(constantNull(keyJavaType)));
    }
    SqlTypeBytecodeExpression valueSqlType = constantType(binder, valueType);
    BytecodeNode loadValueElement;
    if (!valueType.equals(UNKNOWN)) {
        loadValueElement = new IfStatement().condition(block.invoke("isNull", boolean.class, add(position, constantInt(1)))).ifTrue(valueElement.set(constantNull(valueJavaType))).ifFalse(valueElement.set(valueSqlType.getValue(block, add(position, constantInt(1))).cast(valueJavaType)));
    } else {
        loadValueElement = new BytecodeBlock().append(valueElement.set(constantNull(valueJavaType)));
    }
    body.append(new ForLoop().initialize(position.set(constantInt(0))).condition(lessThan(position, positionCount)).update(incrementVariable(position, (byte) 2)).body(new BytecodeBlock().append(loadKeyElement).append(loadValueElement).append(keep.set(function.invoke("invokeExact", Boolean.class, keyElement, valueElement))).append(new IfStatement("if (keep != null && keep) ...").condition(and(notEqual(keep, constantNull(Boolean.class)), keep.cast(boolean.class))).ifTrue(new BytecodeBlock().append(keySqlType.invoke("appendTo", void.class, block, position, blockBuilder)).append(valueSqlType.invoke("appendTo", void.class, block, add(position, constantInt(1)), blockBuilder))))));
    body.append(blockBuilder.invoke("build", Block.class).ret());
    Class<?> generatedClass = defineClass(definition, Object.class, binder.getBindings(), MapFilterFunction.class.getClassLoader());
    return methodHandle(generatedClass, "filter", Block.class, MethodHandle.class);
}
Also used : Variable(com.facebook.presto.bytecode.Variable) Signature.typeVariable(com.facebook.presto.metadata.Signature.typeVariable) VariableInstruction.incrementVariable(com.facebook.presto.bytecode.instruction.VariableInstruction.incrementVariable) ForLoop(com.facebook.presto.bytecode.control.ForLoop) BytecodeBlock(com.facebook.presto.bytecode.BytecodeBlock) ClassDefinition(com.facebook.presto.bytecode.ClassDefinition) MapType(com.facebook.presto.type.MapType) IfStatement(com.facebook.presto.bytecode.control.IfStatement) Scope(com.facebook.presto.bytecode.Scope) MethodDefinition(com.facebook.presto.bytecode.MethodDefinition) CallSiteBinder(com.facebook.presto.sql.gen.CallSiteBinder) Parameter(com.facebook.presto.bytecode.Parameter) Block(com.facebook.presto.spi.block.Block) BytecodeBlock(com.facebook.presto.bytecode.BytecodeBlock) List(java.util.List) ImmutableList(com.google.common.collect.ImmutableList) BytecodeNode(com.facebook.presto.bytecode.BytecodeNode) BlockBuilderStatus(com.facebook.presto.spi.block.BlockBuilderStatus) SqlTypeBytecodeExpression(com.facebook.presto.sql.gen.SqlTypeBytecodeExpression)

Example 32 with Scope

use of com.facebook.presto.bytecode.Scope in project presto by prestodb.

the class TestSetFieldBytecodeExpression method assertSetPoint.

public static void assertSetPoint(Function<BytecodeExpression, BytecodeExpression> setX) throws Exception {
    Function<Scope, BytecodeNode> nodeGenerator = scope -> {
        Variable point = scope.declareVariable(Point.class, "point");
        BytecodeExpression setExpression = setX.apply(point);
        assertEquals(setExpression.toString(), "point.x = 42;");
        return new BytecodeBlock().append(point.set(newInstance(Point.class, constantInt(3), constantInt(7)))).append(setExpression).append(point.ret());
    };
    assertBytecodeNode(nodeGenerator, type(Point.class), new Point(42, 7));
}
Also used : Variable(com.facebook.presto.bytecode.Variable) BytecodeExpressionAssertions.assertBytecodeNode(com.facebook.presto.bytecode.expression.BytecodeExpressionAssertions.assertBytecodeNode) BytecodeExpressions.constantInt(com.facebook.presto.bytecode.expression.BytecodeExpressions.constantInt) Throwables(com.google.common.base.Throwables) Assert.assertEquals(org.testng.Assert.assertEquals) Test(org.testng.annotations.Test) Point(java.awt.Point) Field(java.lang.reflect.Field) BytecodeExpressions.newInstance(com.facebook.presto.bytecode.expression.BytecodeExpressions.newInstance) Function(java.util.function.Function) BytecodeExpressions.constantString(com.facebook.presto.bytecode.expression.BytecodeExpressions.constantString) BytecodeNode(com.facebook.presto.bytecode.BytecodeNode) BytecodeExpressions.setStatic(com.facebook.presto.bytecode.expression.BytecodeExpressions.setStatic) Scope(com.facebook.presto.bytecode.Scope) ParameterizedType.type(com.facebook.presto.bytecode.ParameterizedType.type) BytecodeExpressionAssertions.assertBytecodeExpression(com.facebook.presto.bytecode.expression.BytecodeExpressionAssertions.assertBytecodeExpression) BytecodeBlock(com.facebook.presto.bytecode.BytecodeBlock) Variable(com.facebook.presto.bytecode.Variable) Scope(com.facebook.presto.bytecode.Scope) BytecodeBlock(com.facebook.presto.bytecode.BytecodeBlock) BytecodeExpressionAssertions.assertBytecodeNode(com.facebook.presto.bytecode.expression.BytecodeExpressionAssertions.assertBytecodeNode) BytecodeNode(com.facebook.presto.bytecode.BytecodeNode) Point(java.awt.Point) BytecodeExpressionAssertions.assertBytecodeExpression(com.facebook.presto.bytecode.expression.BytecodeExpressionAssertions.assertBytecodeExpression)

Example 33 with Scope

use of com.facebook.presto.bytecode.Scope in project presto by prestodb.

the class TestSetVariableBytecodeExpression method testGetField.

@Test
public void testGetField() throws Exception {
    Function<Scope, BytecodeNode> nodeGenerator = scope -> {
        Variable point = scope.declareVariable(Point.class, "point");
        BytecodeExpression setPoint = point.set(newInstance(Point.class, constantInt(3), constantInt(7)));
        assertEquals(setPoint.toString(), "point = new Point(3, 7);");
        return new BytecodeBlock().append(setPoint).append(point.ret());
    };
    assertBytecodeNode(nodeGenerator, type(Point.class), new Point(3, 7));
}
Also used : BytecodeNode(com.facebook.presto.bytecode.BytecodeNode) Variable(com.facebook.presto.bytecode.Variable) BytecodeExpressionAssertions.assertBytecodeNode(com.facebook.presto.bytecode.expression.BytecodeExpressionAssertions.assertBytecodeNode) Scope(com.facebook.presto.bytecode.Scope) ParameterizedType.type(com.facebook.presto.bytecode.ParameterizedType.type) BytecodeExpressions.constantInt(com.facebook.presto.bytecode.expression.BytecodeExpressions.constantInt) Assert.assertEquals(org.testng.Assert.assertEquals) BytecodeBlock(com.facebook.presto.bytecode.BytecodeBlock) Test(org.testng.annotations.Test) Point(java.awt.Point) BytecodeExpressions.newInstance(com.facebook.presto.bytecode.expression.BytecodeExpressions.newInstance) Function(java.util.function.Function) Variable(com.facebook.presto.bytecode.Variable) Scope(com.facebook.presto.bytecode.Scope) BytecodeBlock(com.facebook.presto.bytecode.BytecodeBlock) BytecodeNode(com.facebook.presto.bytecode.BytecodeNode) BytecodeExpressionAssertions.assertBytecodeNode(com.facebook.presto.bytecode.expression.BytecodeExpressionAssertions.assertBytecodeNode) Point(java.awt.Point) Test(org.testng.annotations.Test)

Example 34 with Scope

use of com.facebook.presto.bytecode.Scope in project presto by prestodb.

the class CursorProcessorCompiler method generateProjectMethod.

private void generateProjectMethod(ClassDefinition classDefinition, CallSiteBinder callSiteBinder, CachedInstanceBinder cachedInstanceBinder, String methodName, RowExpression projection) {
    PreGeneratedExpressions preGeneratedExpressions = generateMethodsForLambdaAndTry(classDefinition, callSiteBinder, cachedInstanceBinder, projection, methodName);
    Parameter session = arg("session", ConnectorSession.class);
    Parameter cursor = arg("cursor", RecordCursor.class);
    Parameter output = arg("output", BlockBuilder.class);
    MethodDefinition method = classDefinition.declareMethod(a(PUBLIC), methodName, type(void.class), session, cursor, output);
    method.comment("Projection: %s", projection.toString());
    Scope scope = method.getScope();
    Variable wasNullVariable = scope.declareVariable(type(boolean.class), "wasNull");
    BytecodeExpressionVisitor visitor = new BytecodeExpressionVisitor(callSiteBinder, cachedInstanceBinder, fieldReferenceCompiler(cursor), metadata.getFunctionRegistry(), preGeneratedExpressions);
    method.getBody().comment("boolean wasNull = false;").putVariable(wasNullVariable, false).getVariable(output).comment("evaluate projection: " + projection.toString()).append(projection.accept(visitor, scope)).append(generateWrite(callSiteBinder, scope, wasNullVariable, projection.getType())).ret();
}
Also used : Variable(com.facebook.presto.bytecode.Variable) Scope(com.facebook.presto.bytecode.Scope) MethodDefinition(com.facebook.presto.bytecode.MethodDefinition) Parameter(com.facebook.presto.bytecode.Parameter)

Example 35 with Scope

use of com.facebook.presto.bytecode.Scope in project presto by prestodb.

the class CursorProcessorCompiler method fieldReferenceCompiler.

private static RowExpressionVisitor<Scope, BytecodeNode> fieldReferenceCompiler(Variable cursorVariable) {
    return new RowExpressionVisitor<Scope, BytecodeNode>() {

        @Override
        public BytecodeNode visitInputReference(InputReferenceExpression node, Scope scope) {
            int field = node.getField();
            Type type = node.getType();
            Variable wasNullVariable = scope.getVariable("wasNull");
            Class<?> javaType = type.getJavaType();
            if (!javaType.isPrimitive() && javaType != Slice.class) {
                javaType = Object.class;
            }
            IfStatement ifStatement = new IfStatement();
            ifStatement.condition().setDescription(format("cursor.get%s(%d)", type, field)).getVariable(cursorVariable).push(field).invokeInterface(RecordCursor.class, "isNull", boolean.class, int.class);
            ifStatement.ifTrue().putVariable(wasNullVariable, true).pushJavaDefault(javaType);
            ifStatement.ifFalse().getVariable(cursorVariable).push(field).invokeInterface(RecordCursor.class, "get" + Primitives.wrap(javaType).getSimpleName(), javaType, int.class);
            return ifStatement;
        }

        @Override
        public BytecodeNode visitCall(CallExpression call, Scope scope) {
            throw new UnsupportedOperationException("not yet implemented");
        }

        @Override
        public BytecodeNode visitConstant(ConstantExpression literal, Scope scope) {
            throw new UnsupportedOperationException("not yet implemented");
        }

        @Override
        public BytecodeNode visitLambda(LambdaDefinitionExpression lambda, Scope context) {
            throw new UnsupportedOperationException();
        }

        @Override
        public BytecodeNode visitVariableReference(VariableReferenceExpression reference, Scope context) {
            throw new UnsupportedOperationException();
        }
    };
}
Also used : InputReferenceExpression(com.facebook.presto.sql.relational.InputReferenceExpression) Variable(com.facebook.presto.bytecode.Variable) ConstantExpression(com.facebook.presto.sql.relational.ConstantExpression) IfStatement(com.facebook.presto.bytecode.control.IfStatement) Type(com.facebook.presto.spi.type.Type) Scope(com.facebook.presto.bytecode.Scope) Slice(io.airlift.slice.Slice) VariableReferenceExpression(com.facebook.presto.sql.relational.VariableReferenceExpression) RowExpressionVisitor(com.facebook.presto.sql.relational.RowExpressionVisitor) CallExpression(com.facebook.presto.sql.relational.CallExpression) LambdaDefinitionExpression(com.facebook.presto.sql.relational.LambdaDefinitionExpression)

Aggregations

Scope (com.facebook.presto.bytecode.Scope)37 Variable (com.facebook.presto.bytecode.Variable)33 BytecodeBlock (com.facebook.presto.bytecode.BytecodeBlock)32 MethodDefinition (com.facebook.presto.bytecode.MethodDefinition)29 Parameter (com.facebook.presto.bytecode.Parameter)28 IfStatement (com.facebook.presto.bytecode.control.IfStatement)24 Block (com.facebook.presto.spi.block.Block)16 BytecodeNode (com.facebook.presto.bytecode.BytecodeNode)11 ImmutableList (com.google.common.collect.ImmutableList)11 Type (com.facebook.presto.spi.type.Type)9 ForLoop (com.facebook.presto.bytecode.control.ForLoop)8 BytecodeExpression (com.facebook.presto.bytecode.expression.BytecodeExpression)8 DictionaryBlock (com.facebook.presto.spi.block.DictionaryBlock)8 LazyBlock (com.facebook.presto.spi.block.LazyBlock)8 RunLengthEncodedBlock (com.facebook.presto.spi.block.RunLengthEncodedBlock)8 ClassDefinition (com.facebook.presto.bytecode.ClassDefinition)7 LabelNode (com.facebook.presto.bytecode.instruction.LabelNode)7 BlockBuilder (com.facebook.presto.spi.block.BlockBuilder)7 CallSiteBinder (com.facebook.presto.sql.gen.CallSiteBinder)6 List (java.util.List)6