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;
}
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);
};
}
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;
}
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;
}
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;
}
Aggregations