Search in sources :

Example 26 with RowExpression

use of io.trino.sql.relational.RowExpression in project trino by trinodb.

the class OrCodeGenerator method generateExpression.

@Override
public BytecodeNode generateExpression(BytecodeGeneratorContext generator) {
    Variable wasNull = generator.wasNull();
    BytecodeBlock block = new BytecodeBlock().comment("OR").setDescription("OR");
    // keep track of whether we've seen a null so far
    block.push(false);
    LabelNode end = new LabelNode("end");
    LabelNode returnTrue = new LabelNode("returnTrue");
    for (int i = 0; i < terms.size(); i++) {
        RowExpression term = terms.get(i);
        block.append(generator.generate(term));
        IfStatement ifWasNull = new IfStatement(format("if term %s wasNull...", i)).condition(wasNull);
        ifWasNull.ifTrue().comment("clear the null flag, pop residual value off stack, and push was null flag on the stack (true)").pop(// discard residual value
        term.getType().getJavaType()).pop(// discard the previous "we've seen a null flag"
        boolean.class).push(true);
        ifWasNull.ifFalse().comment("if term is true, short circuit and return true").ifTrueGoto(returnTrue);
        block.append(ifWasNull).append(// prepare for the next loop
        wasNull.set(constantFalse()));
    }
    block.putVariable(wasNull).push(// result is false
    false).gotoLabel(end);
    block.visitLabel(returnTrue).append(wasNull.set(constantFalse())).pop(// discard the previous "we've seen a null flag"
    boolean.class).push(// result is true
    true);
    block.visitLabel(end);
    return block;
}
Also used : LabelNode(io.airlift.bytecode.instruction.LabelNode) IfStatement(io.airlift.bytecode.control.IfStatement) Variable(io.airlift.bytecode.Variable) BytecodeBlock(io.airlift.bytecode.BytecodeBlock) RowExpression(io.trino.sql.relational.RowExpression)

Example 27 with RowExpression

use of io.trino.sql.relational.RowExpression in project trino by trinodb.

the class ExpressionCompiler method compilePageProcessor.

private Supplier<PageProcessor> compilePageProcessor(Optional<RowExpression> filter, List<? extends RowExpression> projections, Optional<String> classNameSuffix, OptionalInt initialBatchSize) {
    Optional<Supplier<PageFilter>> filterFunctionSupplier = filter.map(expression -> pageFunctionCompiler.compileFilter(expression, classNameSuffix));
    List<Supplier<PageProjection>> pageProjectionSuppliers = projections.stream().map(projection -> pageFunctionCompiler.compileProjection(projection, classNameSuffix)).collect(toImmutableList());
    return () -> {
        Optional<PageFilter> filterFunction = filterFunctionSupplier.map(Supplier::get);
        List<PageProjection> pageProjections = pageProjectionSuppliers.stream().map(Supplier::get).collect(toImmutableList());
        return new PageProcessor(filterFunction, pageProjections, initialBatchSize);
    };
}
Also used : CacheStatsMBean(io.airlift.jmx.CacheStatsMBean) ParameterizedType.type(io.airlift.bytecode.ParameterizedType.type) Nested(org.weakref.jmx.Nested) BOOLEAN(io.trino.spi.type.BooleanType.BOOLEAN) OptionalInt(java.util.OptionalInt) Supplier(java.util.function.Supplier) Access.a(io.airlift.bytecode.Access.a) NonEvictableLoadingCache(io.trino.collect.cache.NonEvictableLoadingCache) PageFilter(io.trino.operator.project.PageFilter) Inject(javax.inject.Inject) ImmutableList(com.google.common.collect.ImmutableList) Managed(org.weakref.jmx.Managed) CursorProcessor(io.trino.operator.project.CursorProcessor) Objects.requireNonNull(java.util.Objects.requireNonNull) PageProcessor(io.trino.operator.project.PageProcessor) CompilerUtils.makeClassName(io.trino.util.CompilerUtils.makeClassName) FINAL(io.airlift.bytecode.Access.FINAL) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) BytecodeUtils.invoke(io.trino.sql.gen.BytecodeUtils.invoke) Expressions.constant(io.trino.sql.relational.Expressions.constant) TrinoException(io.trino.spi.TrinoException) PageProjection(io.trino.operator.project.PageProjection) FunctionManager(io.trino.metadata.FunctionManager) CompilerUtils.defineClass(io.trino.util.CompilerUtils.defineClass) CacheLoader(com.google.common.cache.CacheLoader) Objects(java.util.Objects) SafeCaches.buildNonEvictableCache(io.trino.collect.cache.SafeCaches.buildNonEvictableCache) COMPILER_ERROR(io.trino.spi.StandardErrorCode.COMPILER_ERROR) CompilationException(io.airlift.bytecode.CompilationException) List(java.util.List) RowExpression(io.trino.sql.relational.RowExpression) PUBLIC(io.airlift.bytecode.Access.PUBLIC) Optional(java.util.Optional) VisibleForTesting(com.google.common.annotations.VisibleForTesting) CacheBuilder(com.google.common.cache.CacheBuilder) ClassDefinition(io.airlift.bytecode.ClassDefinition) MoreObjects.toStringHelper(com.google.common.base.MoreObjects.toStringHelper) PageProcessor(io.trino.operator.project.PageProcessor) Optional(java.util.Optional) Supplier(java.util.function.Supplier) ImmutableList(com.google.common.collect.ImmutableList) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) List(java.util.List)

Example 28 with RowExpression

use of io.trino.sql.relational.RowExpression in project trino by trinodb.

the class InCodeGenerator method checkSwitchGenerationCase.

@VisibleForTesting
static SwitchGenerationCase checkSwitchGenerationCase(Type type, List<RowExpression> values) {
    if (values.size() >= 8) {
        // Tipping point is between 5 and 10 (using round 8)
        return SwitchGenerationCase.SET_CONTAINS;
    }
    if (type.getJavaType() != long.class) {
        return SwitchGenerationCase.HASH_SWITCH;
    }
    for (RowExpression expression : values) {
        // Same argument applies for nulls.
        if (!(expression instanceof ConstantExpression)) {
            continue;
        }
        Object constant = ((ConstantExpression) expression).getValue();
        if (constant == null) {
            continue;
        }
        long longConstant = ((Number) constant).longValue();
        if (longConstant < Integer.MIN_VALUE || longConstant > Integer.MAX_VALUE) {
            return SwitchGenerationCase.HASH_SWITCH;
        }
    }
    return SwitchGenerationCase.DIRECT_SWITCH;
}
Also used : ConstantExpression(io.trino.sql.relational.ConstantExpression) RowExpression(io.trino.sql.relational.RowExpression) VisibleForTesting(com.google.common.annotations.VisibleForTesting)

Example 29 with RowExpression

use of io.trino.sql.relational.RowExpression in project trino by trinodb.

the class LambdaBytecodeGenerator method generateLambda.

public static BytecodeNode generateLambda(BytecodeGeneratorContext context, List<RowExpression> captureExpressions, CompiledLambda compiledLambda, Class<?> lambdaInterface) {
    if (!lambdaInterface.isAnnotationPresent(FunctionalInterface.class)) {
        // lambdaInterface is checked to be annotated with FunctionalInterface when generating ScalarFunctionImplementation
        throw new VerifyException("lambda should be generated as class annotated with FunctionalInterface");
    }
    BytecodeBlock block = new BytecodeBlock().setDescription("Partial apply");
    Scope scope = context.getScope();
    Variable wasNull = scope.getVariable("wasNull");
    // generate values to be captured
    ImmutableList.Builder<BytecodeExpression> captureVariableBuilder = ImmutableList.builder();
    for (RowExpression captureExpression : captureExpressions) {
        Class<?> valueType = Primitives.wrap(captureExpression.getType().getJavaType());
        Variable valueVariable = scope.createTempVariable(valueType);
        block.append(context.generate(captureExpression));
        block.append(boxPrimitiveIfNecessary(scope, valueType));
        block.putVariable(valueVariable);
        block.append(wasNull.set(constantFalse()));
        captureVariableBuilder.add(valueVariable);
    }
    List<BytecodeExpression> captureVariables = ImmutableList.<BytecodeExpression>builder().add(scope.getThis(), scope.getVariable("session")).addAll(captureVariableBuilder.build()).build();
    Type instantiatedMethodAsmType = getMethodType(compiledLambda.getReturnType().getAsmType(), compiledLambda.getParameterTypes().stream().skip(// skip capture variables and ConnectorSession
    captureExpressions.size() + 1).map(ParameterizedType::getAsmType).collect(toImmutableList()).toArray(new Type[0]));
    block.append(invokeDynamic(LAMBDA_CAPTURE_METHOD, ImmutableList.of(getType(getSingleApplyMethod(lambdaInterface)), compiledLambda.getLambdaAsmHandle(), instantiatedMethodAsmType), "apply", type(lambdaInterface), captureVariables));
    return block;
}
Also used : Type(org.objectweb.asm.Type) Type.getType(org.objectweb.asm.Type.getType) Type.getMethodType(org.objectweb.asm.Type.getMethodType) ParameterizedType(io.airlift.bytecode.ParameterizedType) Variable(io.airlift.bytecode.Variable) Scope(io.airlift.bytecode.Scope) VerifyException(com.google.common.base.VerifyException) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) ImmutableList(com.google.common.collect.ImmutableList) BytecodeBlock(io.airlift.bytecode.BytecodeBlock) RowExpression(io.trino.sql.relational.RowExpression) BytecodeExpression(io.airlift.bytecode.expression.BytecodeExpression)

Example 30 with RowExpression

use of io.trino.sql.relational.RowExpression in project trino by trinodb.

the class AndCodeGenerator method generateExpression.

@Override
public BytecodeNode generateExpression(BytecodeGeneratorContext generator) {
    Variable wasNull = generator.wasNull();
    BytecodeBlock block = new BytecodeBlock().comment("AND").setDescription("AND");
    // keep track of whether we've seen a null so far
    block.push(false);
    LabelNode end = new LabelNode("end");
    LabelNode returnFalse = new LabelNode("returnFalse");
    for (int i = 0; i < terms.size(); i++) {
        RowExpression term = terms.get(i);
        block.append(generator.generate(term));
        IfStatement ifWasNull = new IfStatement(format("if term %s wasNull...", i)).condition(wasNull);
        ifWasNull.ifTrue().comment("clear the null flag, pop residual value off stack, and push was null flag on the stack (true)").pop(// discard residual value
        term.getType().getJavaType()).pop(// discard the previous "we've seen a null flag"
        boolean.class).push(true);
        ifWasNull.ifFalse().comment("if term is false, short circuit and return false").ifFalseGoto(returnFalse);
        block.append(ifWasNull).append(// prepare for the next loop
        wasNull.set(constantFalse()));
    }
    block.putVariable(wasNull).push(// result is true
    true).gotoLabel(end);
    block.visitLabel(returnFalse).append(wasNull.set(constantFalse())).pop(// discard the previous "we've seen a null flag"
    boolean.class).push(// result is false
    false);
    block.visitLabel(end);
    return block;
}
Also used : LabelNode(io.airlift.bytecode.instruction.LabelNode) IfStatement(io.airlift.bytecode.control.IfStatement) Variable(io.airlift.bytecode.Variable) BytecodeBlock(io.airlift.bytecode.BytecodeBlock) RowExpression(io.trino.sql.relational.RowExpression)

Aggregations

RowExpression (io.trino.sql.relational.RowExpression)34 Test (org.testng.annotations.Test)14 PageProcessor (io.trino.operator.project.PageProcessor)13 Page (io.trino.spi.Page)9 PlanNodeId (io.trino.sql.planner.plan.PlanNodeId)9 CursorProcessor (io.trino.operator.project.CursorProcessor)7 CallExpression (io.trino.sql.relational.CallExpression)7 MaterializedResult (io.trino.testing.MaterializedResult)7 ImmutableList (com.google.common.collect.ImmutableList)6 BytecodeBlock (io.airlift.bytecode.BytecodeBlock)6 Variable (io.airlift.bytecode.Variable)6 CatalogName (io.trino.connector.CatalogName)6 Split (io.trino.metadata.Split)6 ExpressionCompiler (io.trino.sql.gen.ExpressionCompiler)6 TestingSplit (io.trino.testing.TestingSplit)6 IfStatement (io.airlift.bytecode.control.IfStatement)5 Type (io.trino.spi.type.Type)5 Expression (io.trino.sql.tree.Expression)5 LabelNode (io.airlift.bytecode.instruction.LabelNode)4 FunctionManager (io.trino.metadata.FunctionManager)4