Search in sources :

Example 31 with SpecialFormExpression

use of com.facebook.presto.spi.relation.SpecialFormExpression in project urban-eureka by errir503.

the class PageFunctionCompiler method compileProjectionInternal.

private Supplier<PageProjection> compileProjectionInternal(SqlFunctionProperties sqlFunctionProperties, Map<SqlFunctionId, SqlInvokedFunction> sessionFunctions, List<RowExpression> projections, boolean isOptimizeCommonSubExpression, Optional<String> classNameSuffix) {
    requireNonNull(projections, "projections is null");
    checkArgument(!projections.isEmpty() && projections.stream().allMatch(projection -> projection instanceof CallExpression || projection instanceof SpecialFormExpression));
    PageFieldsToInputParametersRewriter.Result result = rewritePageFieldsToInputParameters(projections);
    List<RowExpression> rewrittenExpression = result.getRewrittenExpressions();
    CallSiteBinder callSiteBinder = new CallSiteBinder();
    // generate Work
    ClassDefinition pageProjectionWorkDefinition = definePageProjectWorkClass(sqlFunctionProperties, sessionFunctions, rewrittenExpression, callSiteBinder, isOptimizeCommonSubExpression, classNameSuffix);
    Class<? extends Work> pageProjectionWorkClass;
    try {
        pageProjectionWorkClass = defineClass(pageProjectionWorkDefinition, Work.class, callSiteBinder.getBindings(), getClass().getClassLoader());
    } catch (PrestoException prestoException) {
        throw prestoException;
    } catch (Exception e) {
        throw new PrestoException(COMPILER_ERROR, e);
    }
    return () -> new GeneratedPageProjection(rewrittenExpression, rewrittenExpression.stream().allMatch(determinismEvaluator::isDeterministic), result.getInputChannels(), constructorMethodHandle(pageProjectionWorkClass, List.class, SqlFunctionProperties.class, Page.class, SelectedPositions.class));
}
Also used : SqlFunctionProperties(com.facebook.presto.common.function.SqlFunctionProperties) RowExpression(com.facebook.presto.spi.relation.RowExpression) PrestoException(com.facebook.presto.spi.PrestoException) GeneratedPageProjection(com.facebook.presto.operator.project.GeneratedPageProjection) Page(com.facebook.presto.common.Page) ClassDefinition(com.facebook.presto.bytecode.ClassDefinition) PrestoException(com.facebook.presto.spi.PrestoException) UncheckedExecutionException(com.google.common.util.concurrent.UncheckedExecutionException) PageFieldsToInputParametersRewriter(com.facebook.presto.operator.project.PageFieldsToInputParametersRewriter) CallSiteBinder(com.facebook.presto.bytecode.CallSiteBinder) SelectedPositions(com.facebook.presto.operator.project.SelectedPositions) Work(com.facebook.presto.operator.Work) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) List(java.util.List) ImmutableList(com.google.common.collect.ImmutableList) CallExpression(com.facebook.presto.spi.relation.CallExpression) SpecialFormExpression(com.facebook.presto.spi.relation.SpecialFormExpression)

Example 32 with SpecialFormExpression

use of com.facebook.presto.spi.relation.SpecialFormExpression in project urban-eureka by errir503.

the class CursorProcessorCompiler method fieldReferenceCompiler.

static RowExpressionVisitor<BytecodeNode, Scope> fieldReferenceCompiler(Map<VariableReferenceExpression, CommonSubExpressionFields> variableMap) {
    return new RowExpressionVisitor<BytecodeNode, Scope>() {

        @Override
        public BytecodeNode visitInputReference(InputReferenceExpression node, Scope scope) {
            int field = node.getField();
            Type type = node.getType();
            Variable wasNullVariable = scope.getVariable("wasNull");
            Variable cursorVariable = scope.getVariable("cursor");
            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) {
            CommonSubExpressionFields fields = variableMap.get(reference);
            return new BytecodeBlock().append(context.getThis().invoke(fields.getMethodName(), fields.getResultType(), context.getVariable("properties"), context.getVariable("cursor"))).append(unboxPrimitiveIfNecessary(context, Primitives.wrap(reference.getType().getJavaType())));
        }

        @Override
        public BytecodeNode visitSpecialForm(SpecialFormExpression specialForm, Scope context) {
            throw new UnsupportedOperationException();
        }
    };
}
Also used : InputReferenceExpression(com.facebook.presto.spi.relation.InputReferenceExpression) Variable(com.facebook.presto.bytecode.Variable) ConstantExpression(com.facebook.presto.spi.relation.ConstantExpression) BytecodeBlock(com.facebook.presto.bytecode.BytecodeBlock) IfStatement(com.facebook.presto.bytecode.control.IfStatement) Type(com.facebook.presto.common.type.Type) CommonSubExpressionFields.initializeCommonSubExpressionFields(com.facebook.presto.sql.gen.CommonSubExpressionRewriter.CommonSubExpressionFields.initializeCommonSubExpressionFields) CommonSubExpressionFields.declareCommonSubExpressionFields(com.facebook.presto.sql.gen.CommonSubExpressionRewriter.CommonSubExpressionFields.declareCommonSubExpressionFields) CommonSubExpressionFields(com.facebook.presto.sql.gen.CommonSubExpressionRewriter.CommonSubExpressionFields) Scope(com.facebook.presto.bytecode.Scope) Slice(io.airlift.slice.Slice) VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression) RowExpressionVisitor(com.facebook.presto.spi.relation.RowExpressionVisitor) CallExpression(com.facebook.presto.spi.relation.CallExpression) SpecialFormExpression(com.facebook.presto.spi.relation.SpecialFormExpression) LambdaDefinitionExpression(com.facebook.presto.spi.relation.LambdaDefinitionExpression)

Example 33 with SpecialFormExpression

use of com.facebook.presto.spi.relation.SpecialFormExpression in project urban-eureka by errir503.

the class LambdaBytecodeGenerator method variableReferenceCompiler.

private static RowExpressionVisitor<BytecodeNode, Scope> variableReferenceCompiler(Map<String, ParameterAndType> parameterMap) {
    return new RowExpressionVisitor<BytecodeNode, Scope>() {

        @Override
        public BytecodeNode visitInputReference(InputReferenceExpression node, Scope scope) {
            throw new UnsupportedOperationException();
        }

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

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

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

        @Override
        public BytecodeNode visitVariableReference(VariableReferenceExpression reference, Scope context) {
            ParameterAndType parameterAndType = parameterMap.get(reference.getName());
            Parameter parameter = parameterAndType.getParameter();
            Class<?> type = parameterAndType.getType();
            return new BytecodeBlock().append(parameter).append(unboxPrimitiveIfNecessary(context, type));
        }

        @Override
        public BytecodeNode visitSpecialForm(SpecialFormExpression specialForm, Scope context) {
            throw new UnsupportedOperationException();
        }
    };
}
Also used : InputReferenceExpression(com.facebook.presto.spi.relation.InputReferenceExpression) ConstantExpression(com.facebook.presto.spi.relation.ConstantExpression) BytecodeBlock(com.facebook.presto.bytecode.BytecodeBlock) Scope(com.facebook.presto.bytecode.Scope) VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression) RowExpressionVisitor(com.facebook.presto.spi.relation.RowExpressionVisitor) Parameter(com.facebook.presto.bytecode.Parameter) CallExpression(com.facebook.presto.spi.relation.CallExpression) SpecialFormExpression(com.facebook.presto.spi.relation.SpecialFormExpression) LambdaDefinitionExpression(com.facebook.presto.spi.relation.LambdaDefinitionExpression)

Example 34 with SpecialFormExpression

use of com.facebook.presto.spi.relation.SpecialFormExpression in project urban-eureka by errir503.

the class DereferenceCodeGenerator method generateExpression.

@Override
public BytecodeNode generateExpression(BytecodeGeneratorContext generator, Type returnType, List<RowExpression> arguments, Optional<Variable> outputBlockVariable) {
    checkArgument(arguments.size() == 2);
    CallSiteBinder callSiteBinder = generator.getCallSiteBinder();
    // Collect all nested intermediateDerefs
    ImmutableList.Builder<RowExpression> nestedDerefernces = ImmutableList.builder();
    RowExpression nestedObject = arguments.get(0);
    int leafFieldIndex = ((Number) ((ConstantExpression) arguments.get(1)).getValue()).intValue();
    // Find all the intermediate nestedDerefernces.
    while (nestedObject instanceof SpecialFormExpression && ((SpecialFormExpression) nestedObject).getForm() == DEREFERENCE) {
        nestedDerefernces.add(nestedObject);
        nestedObject = ((SpecialFormExpression) nestedObject).getArguments().get(0);
    }
    // Here nestedObject is the inner-most expression (so the toplevel object)
    // Just generate a loop
    BytecodeBlock block = new BytecodeBlock().comment("DEREFERENCE").setDescription("DEREFERENCE");
    Variable rowBlock = generator.getScope().createTempVariable(Block.class);
    Variable wasNull = generator.wasNull();
    // Labels for control-flow
    LabelNode end = new LabelNode("end");
    LabelNode returnNull = new LabelNode("returnNull");
    // clear the wasNull flag before evaluating the row value and evaluate the root (innermost) object
    block.putVariable(wasNull, false).append(generator.generate(nestedObject, Optional.empty())).putVariable(rowBlock).comment("If the object is null return null").append(wasNull).ifTrueGoto(returnNull);
    for (RowExpression rowExpression : nestedDerefernces.build().reverse()) {
        SpecialFormExpression nestedDerefernce = (SpecialFormExpression) rowExpression;
        int fieldIndex = ((Number) ((ConstantExpression) nestedDerefernce.getArguments().get(1)).getValue()).intValue();
        block.append(rowBlock).push(fieldIndex).invokeInterface(Block.class, "isNull", boolean.class, int.class).comment("If the deref result is null return null").ifTrueGoto(returnNull).append(constantType(callSiteBinder, nestedDerefernce.getType()).getValue(rowBlock, constantInt(fieldIndex))).putVariable(rowBlock);
    }
    block.append(rowBlock).push(((Number) ((ConstantExpression) arguments.get(1)).getValue()).intValue()).invokeInterface(Block.class, "isNull", boolean.class, int.class).ifTrueGoto(returnNull);
    BytecodeExpression value = constantType(callSiteBinder, returnType).getValue(rowBlock, constantInt(leafFieldIndex));
    block.append(wasNull).ifTrueGoto(returnNull).append(value).gotoLabel(end);
    // Here one of the enclosing objects is null
    Class<?> javaType = returnType.getJavaType();
    block.visitLabel(returnNull).pushJavaDefault(javaType).comment("if the field is null, push null to stack").putVariable(wasNull, true);
    block.visitLabel(end);
    outputBlockVariable.ifPresent(output -> block.append(generateWrite(generator, returnType, output)));
    return block;
}
Also used : LabelNode(com.facebook.presto.bytecode.instruction.LabelNode) Variable(com.facebook.presto.bytecode.Variable) ImmutableList(com.google.common.collect.ImmutableList) ConstantExpression(com.facebook.presto.spi.relation.ConstantExpression) BytecodeBlock(com.facebook.presto.bytecode.BytecodeBlock) RowExpression(com.facebook.presto.spi.relation.RowExpression) CallSiteBinder(com.facebook.presto.bytecode.CallSiteBinder) BytecodeBlock(com.facebook.presto.bytecode.BytecodeBlock) Block(com.facebook.presto.common.block.Block) BytecodeExpression(com.facebook.presto.bytecode.expression.BytecodeExpression) SpecialFormExpression(com.facebook.presto.spi.relation.SpecialFormExpression)

Example 35 with SpecialFormExpression

use of com.facebook.presto.spi.relation.SpecialFormExpression in project urban-eureka by errir503.

the class AndCodeGenerator method generateExpression.

@Override
public BytecodeNode generateExpression(BytecodeGeneratorContext generator, Type returnType, List<RowExpression> arguments, Optional<Variable> outputBlockVariable) {
    Preconditions.checkArgument(arguments.size() == 2);
    // We flatten the AND here.
    Deque<RowExpression> stack = new ArrayDeque<>();
    stack.push(arguments.get(1));
    stack.push(arguments.get(0));
    ImmutableList.Builder<RowExpression> flattenedArgs = ImmutableList.builder();
    do {
        RowExpression operand = stack.pop();
        if (operand instanceof SpecialFormExpression && ((SpecialFormExpression) operand).getForm() == SpecialFormExpression.Form.AND) {
            stack.push(((SpecialFormExpression) operand).getArguments().get(1));
            stack.push(((SpecialFormExpression) operand).getArguments().get(0));
        } else {
            flattenedArgs.add(operand);
        }
    } while (!stack.isEmpty());
    BytecodeBlock block = new BytecodeBlock().comment("AND").setDescription("AND");
    LabelNode falseLabel = new LabelNode("false");
    LabelNode endLabel = new LabelNode("end");
    Variable wasNull = generator.wasNull();
    Variable hasNulls = generator.getScope().createTempVariable(boolean.class);
    block.initializeVariable(hasNulls);
    for (RowExpression expression : flattenedArgs.build()) {
        block.comment("do { eval arg; if (wasNull) { hasNull = true; wasNull = false; } else if (false) goto ret_false; }").append(generator.generate(expression, Optional.empty()));
        IfStatement ifOperandIsNull = new IfStatement("if left wasNulll...").condition(wasNull);
        ifOperandIsNull.ifTrue().comment("clear the null flag and remember there was a null").putVariable(hasNulls, true).putVariable(wasNull, false).pop(boolean.class);
        ifOperandIsNull.ifFalse().ifFalseGoto(falseLabel);
        block.append(ifOperandIsNull);
    }
    // We evaluated all operands. So check if any of them was null
    IfStatement ifHasNulls = new IfStatement("hasNulls is true");
    ifHasNulls.condition().append(hasNulls);
    ifHasNulls.ifTrue().comment("at least one of the arguments is null and none of them is false. So set wasNull to true").putVariable(wasNull, true).push(false);
    ifHasNulls.ifFalse().push(true);
    block.append(ifHasNulls).gotoLabel(endLabel);
    block.visitLabel(falseLabel).comment("at least one of the args is false, clear wasNull and return false").push(false).gotoLabel(endLabel);
    block.visitLabel(endLabel);
    outputBlockVariable.ifPresent(output -> block.append(generateWrite(generator, 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) ImmutableList(com.google.common.collect.ImmutableList) BytecodeBlock(com.facebook.presto.bytecode.BytecodeBlock) RowExpression(com.facebook.presto.spi.relation.RowExpression) SpecialFormExpression(com.facebook.presto.spi.relation.SpecialFormExpression) ArrayDeque(java.util.ArrayDeque)

Aggregations

SpecialFormExpression (com.facebook.presto.spi.relation.SpecialFormExpression)46 RowExpression (com.facebook.presto.spi.relation.RowExpression)38 ConstantExpression (com.facebook.presto.spi.relation.ConstantExpression)18 VariableReferenceExpression (com.facebook.presto.spi.relation.VariableReferenceExpression)18 CallExpression (com.facebook.presto.spi.relation.CallExpression)16 ImmutableList (com.google.common.collect.ImmutableList)14 BytecodeBlock (com.facebook.presto.bytecode.BytecodeBlock)12 Test (org.testng.annotations.Test)12 Variable (com.facebook.presto.bytecode.Variable)10 Type (com.facebook.presto.common.type.Type)10 IfStatement (com.facebook.presto.bytecode.control.IfStatement)8 LabelNode (com.facebook.presto.bytecode.instruction.LabelNode)8 Page (com.facebook.presto.common.Page)8 RowType (com.facebook.presto.common.type.RowType)8 Scope (com.facebook.presto.bytecode.Scope)6 Subfield (com.facebook.presto.common.Subfield)6 ArrayDeque (java.util.ArrayDeque)6 ArrayList (java.util.ArrayList)6 Map (java.util.Map)6 LambdaDefinitionExpression (com.facebook.presto.spi.relation.LambdaDefinitionExpression)5