Search in sources :

Example 1 with SqlTypeBytecodeExpression

use of com.facebook.presto.sql.gen.SqlTypeBytecodeExpression in project presto by prestodb.

the class AbstractMinMaxBy method generateInputMethod.

private void generateInputMethod(ClassDefinition definition, CallSiteBinder binder, MethodHandle compareMethod, Type keyType, Type valueType, Class<?> stateClass) {
    Parameter state = arg("state", stateClass);
    Parameter value = arg("value", Block.class);
    Parameter key = arg("key", Block.class);
    Parameter position = arg("position", int.class);
    MethodDefinition method = definition.declareMethod(a(PUBLIC, STATIC), "input", type(void.class), state, value, key, position);
    if (keyType.equals(UNKNOWN)) {
        method.getBody().ret();
        return;
    }
    SqlTypeBytecodeExpression keySqlType = constantType(binder, keyType);
    BytecodeBlock ifBlock = new BytecodeBlock().append(state.invoke("setFirst", void.class, keySqlType.getValue(key, position))).append(state.invoke("setFirstNull", void.class, constantBoolean(false))).append(state.invoke("setSecondNull", void.class, value.invoke("isNull", boolean.class, position)));
    if (!valueType.equals(UNKNOWN)) {
        SqlTypeBytecodeExpression valueSqlType = constantType(binder, valueType);
        ifBlock.append(new IfStatement().condition(value.invoke("isNull", boolean.class, position)).ifFalse(state.invoke("setSecond", void.class, valueSqlType.getValue(value, position))));
    }
    method.getBody().append(new IfStatement().condition(or(state.invoke("isFirstNull", boolean.class), and(not(key.invoke("isNull", boolean.class, position)), loadConstant(binder, compareMethod, MethodHandle.class).invoke("invokeExact", boolean.class, keySqlType.getValue(key, position), state.invoke("getFirst", keyType.getJavaType()))))).ifTrue(ifBlock)).ret();
}
Also used : IfStatement(com.facebook.presto.bytecode.control.IfStatement) MethodDefinition(com.facebook.presto.bytecode.MethodDefinition) BytecodeBlock(com.facebook.presto.bytecode.BytecodeBlock) Parameter(com.facebook.presto.bytecode.Parameter) Signature.orderableTypeParameter(com.facebook.presto.metadata.Signature.orderableTypeParameter) SqlTypeBytecodeExpression(com.facebook.presto.sql.gen.SqlTypeBytecodeExpression) MethodHandle(java.lang.invoke.MethodHandle)

Example 2 with SqlTypeBytecodeExpression

use of com.facebook.presto.sql.gen.SqlTypeBytecodeExpression in project presto by prestodb.

the class StateCompiler method generateSerialize.

private static <T> void generateSerialize(ClassDefinition definition, CallSiteBinder binder, Class<T> clazz, List<StateField> fields) {
    Parameter state = arg("state", Object.class);
    Parameter out = arg("out", BlockBuilder.class);
    MethodDefinition method = definition.declareMethod(a(PUBLIC), "serialize", type(void.class), state, out);
    Scope scope = method.getScope();
    BytecodeBlock serializerBody = method.getBody();
    if (fields.size() == 1) {
        Method getter = getGetter(clazz, fields.get(0));
        SqlTypeBytecodeExpression sqlType = constantType(binder, fields.get(0).getSqlType());
        Variable fieldValue = scope.declareVariable(getter.getReturnType(), "value");
        serializerBody.append(fieldValue.set(state.cast(getter.getDeclaringClass()).invoke(getter)));
        if (!fields.get(0).isPrimitiveType()) {
            serializerBody.append(new IfStatement().condition(equal(fieldValue, constantNull(getter.getReturnType()))).ifTrue(out.invoke("appendNull", BlockBuilder.class).pop()).ifFalse(sqlType.writeValue(out, fieldValue)));
        } else {
            // For primitive type, we need to cast here because we serialize byte fields with TINYINT (whose java type is long).
            serializerBody.append(sqlType.writeValue(out, fieldValue.cast(fields.get(0).getSqlType().getJavaType())));
        }
    } else {
        Variable rowBuilder = scope.declareVariable(BlockBuilder.class, "rowBuilder");
        serializerBody.append(rowBuilder.set(out.invoke("beginBlockEntry", BlockBuilder.class)));
        for (StateField field : fields) {
            Method getter = getGetter(clazz, field);
            SqlTypeBytecodeExpression sqlType = constantType(binder, field.getSqlType());
            Variable fieldValue = scope.createTempVariable(getter.getReturnType());
            serializerBody.append(fieldValue.set(state.cast(getter.getDeclaringClass()).invoke(getter)));
            if (!field.isPrimitiveType()) {
                serializerBody.append(new IfStatement().condition(equal(fieldValue, constantNull(getter.getReturnType()))).ifTrue(rowBuilder.invoke("appendNull", BlockBuilder.class).pop()).ifFalse(sqlType.writeValue(rowBuilder, fieldValue)));
            } else {
                // For primitive type, we need to cast here because we serialize byte fields with TINYINT (whose java type is long).
                serializerBody.append(sqlType.writeValue(rowBuilder, fieldValue.cast(field.getSqlType().getJavaType())));
            }
        }
        serializerBody.append(out.invoke("closeEntry", BlockBuilder.class).pop());
    }
    serializerBody.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) Method(java.lang.reflect.Method) SqlTypeBytecodeExpression(com.facebook.presto.sql.gen.SqlTypeBytecodeExpression)

Example 3 with SqlTypeBytecodeExpression

use of com.facebook.presto.sql.gen.SqlTypeBytecodeExpression 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)

Aggregations

BytecodeBlock (com.facebook.presto.bytecode.BytecodeBlock)3 MethodDefinition (com.facebook.presto.bytecode.MethodDefinition)3 Parameter (com.facebook.presto.bytecode.Parameter)3 IfStatement (com.facebook.presto.bytecode.control.IfStatement)3 SqlTypeBytecodeExpression (com.facebook.presto.sql.gen.SqlTypeBytecodeExpression)3 Scope (com.facebook.presto.bytecode.Scope)2 Variable (com.facebook.presto.bytecode.Variable)2 BytecodeNode (com.facebook.presto.bytecode.BytecodeNode)1 ClassDefinition (com.facebook.presto.bytecode.ClassDefinition)1 ForLoop (com.facebook.presto.bytecode.control.ForLoop)1 VariableInstruction.incrementVariable (com.facebook.presto.bytecode.instruction.VariableInstruction.incrementVariable)1 Signature.orderableTypeParameter (com.facebook.presto.metadata.Signature.orderableTypeParameter)1 Signature.typeVariable (com.facebook.presto.metadata.Signature.typeVariable)1 Block (com.facebook.presto.spi.block.Block)1 BlockBuilderStatus (com.facebook.presto.spi.block.BlockBuilderStatus)1 CallSiteBinder (com.facebook.presto.sql.gen.CallSiteBinder)1 MapType (com.facebook.presto.type.MapType)1 ImmutableList (com.google.common.collect.ImmutableList)1 MethodHandle (java.lang.invoke.MethodHandle)1 Method (java.lang.reflect.Method)1