use of com.facebook.presto.bytecode.BytecodeNode in project presto by prestodb.
the class JoinFilterFunctionCompiler method generateFilterMethod.
private void generateFilterMethod(SqlFunctionProperties sqlFunctionProperties, Map<SqlFunctionId, SqlInvokedFunction> sessionFunctions, ClassDefinition classDefinition, CallSiteBinder callSiteBinder, CachedInstanceBinder cachedInstanceBinder, Map<LambdaDefinitionExpression, CompiledLambda> compiledLambdaMap, RowExpression filter, int leftBlocksSize, FieldDefinition propertiesField) {
// int leftPosition, Page leftPage, int rightPosition, Page rightPage
Parameter leftPosition = arg("leftPosition", int.class);
Parameter leftPage = arg("leftPage", Page.class);
Parameter rightPosition = arg("rightPosition", int.class);
Parameter rightPage = arg("rightPage", Page.class);
MethodDefinition method = classDefinition.declareMethod(a(PUBLIC), "filter", type(boolean.class), ImmutableList.<Parameter>builder().add(leftPosition).add(leftPage).add(rightPosition).add(rightPage).build());
method.comment("filter: %s", filter.toString());
BytecodeBlock body = method.getBody();
Scope scope = method.getScope();
Variable wasNullVariable = scope.declareVariable("wasNull", body, constantFalse());
scope.declareVariable("properties", body, method.getThis().getField(propertiesField));
RowExpressionCompiler compiler = new RowExpressionCompiler(classDefinition, callSiteBinder, cachedInstanceBinder, fieldReferenceCompiler(callSiteBinder, leftPosition, leftPage, rightPosition, rightPage, leftBlocksSize), metadata, sqlFunctionProperties, sessionFunctions, compiledLambdaMap);
BytecodeNode visitorBody = compiler.compile(filter, scope, Optional.empty());
Variable result = scope.declareVariable(boolean.class, "result");
body.append(visitorBody).putVariable(result).append(new IfStatement().condition(wasNullVariable).ifTrue(constantFalse().ret()).ifFalse(result.ret()));
}
use of com.facebook.presto.bytecode.BytecodeNode in project presto by prestodb.
the class NullIfCodeGenerator method generateExpression.
@Override
public BytecodeNode generateExpression(BytecodeGeneratorContext generatorContext, Type returnType, List<RowExpression> arguments, Optional<Variable> outputBlockVariable) {
Scope scope = generatorContext.getScope();
RowExpression first = arguments.get(0);
RowExpression second = arguments.get(1);
LabelNode notMatch = new LabelNode("notMatch");
// push first arg on the stack
Variable firstValue = scope.createTempVariable(first.getType().getJavaType());
BytecodeBlock block = new BytecodeBlock().comment("check if first arg is null").append(generatorContext.generate(first, Optional.empty())).append(ifWasNullPopAndGoto(scope, notMatch, void.class)).dup(first.getType().getJavaType()).putVariable(firstValue);
Type firstType = first.getType();
Type secondType = second.getType();
// if (equal(cast(first as <common type>), cast(second as <common type>))
FunctionAndTypeManager functionAndTypeManager = generatorContext.getFunctionManager();
FunctionHandle equalFunction = functionAndTypeManager.resolveOperator(EQUAL, fromTypes(firstType, secondType));
FunctionMetadata equalFunctionMetadata = functionAndTypeManager.getFunctionMetadata(equalFunction);
JavaScalarFunctionImplementation equalsFunction = generatorContext.getFunctionManager().getJavaScalarFunctionImplementation(equalFunction);
BytecodeNode equalsCall = generatorContext.generateCall(EQUAL.name(), equalsFunction, ImmutableList.of(cast(generatorContext, firstValue, firstType, equalFunctionMetadata.getArgumentTypes().get(0)), cast(generatorContext, generatorContext.generate(second, Optional.empty()), secondType, equalFunctionMetadata.getArgumentTypes().get(1))));
BytecodeBlock conditionBlock = new BytecodeBlock().append(equalsCall).append(BytecodeUtils.ifWasNullClearPopAndGoto(scope, notMatch, void.class, boolean.class));
// if first and second are equal, return null
BytecodeBlock trueBlock = new BytecodeBlock().append(generatorContext.wasNull().set(constantTrue())).pop(first.getType().getJavaType()).pushJavaDefault(first.getType().getJavaType());
// else return first (which is still on the stack
block.append(new IfStatement().condition(conditionBlock).ifTrue(trueBlock).ifFalse(notMatch));
outputBlockVariable.ifPresent(output -> block.append(generateWrite(generatorContext, returnType, output)));
return block;
}
use of com.facebook.presto.bytecode.BytecodeNode in project presto by prestodb.
the class JoinCompiler method generatePositionEqualsPositionMethod.
private static void generatePositionEqualsPositionMethod(ClassDefinition classDefinition, CallSiteBinder callSiteBinder, List<Type> joinChannelTypes, List<FieldDefinition> joinChannelFields, boolean ignoreNulls) {
Parameter leftBlockIndex = arg("leftBlockIndex", int.class);
Parameter leftBlockPosition = arg("leftBlockPosition", int.class);
Parameter rightBlockIndex = arg("rightBlockIndex", int.class);
Parameter rightBlockPosition = arg("rightBlockPosition", int.class);
MethodDefinition positionEqualsPositionMethod = classDefinition.declareMethod(a(PUBLIC), ignoreNulls ? "positionEqualsPositionIgnoreNulls" : "positionEqualsPosition", type(boolean.class), leftBlockIndex, leftBlockPosition, rightBlockIndex, rightBlockPosition);
Variable thisVariable = positionEqualsPositionMethod.getThis();
for (int index = 0; index < joinChannelTypes.size(); index++) {
BytecodeExpression type = constantType(callSiteBinder, joinChannelTypes.get(index));
BytecodeExpression leftBlock = thisVariable.getField(joinChannelFields.get(index)).invoke("get", Object.class, leftBlockIndex).cast(Block.class);
BytecodeExpression rightBlock = thisVariable.getField(joinChannelFields.get(index)).invoke("get", Object.class, rightBlockIndex).cast(Block.class);
BytecodeNode equalityCondition;
if (ignoreNulls) {
equalityCondition = typeEqualsIgnoreNulls(type, leftBlock, leftBlockPosition, rightBlock, rightBlockPosition);
} else {
equalityCondition = typeEquals(type, leftBlock, leftBlockPosition, rightBlock, rightBlockPosition);
}
LabelNode checkNextField = new LabelNode("checkNextField");
positionEqualsPositionMethod.getBody().append(equalityCondition).ifTrueGoto(checkNextField).push(false).retBoolean().visitLabel(checkNextField);
}
positionEqualsPositionMethod.getBody().push(true).retInt();
}
use of com.facebook.presto.bytecode.BytecodeNode in project presto by prestodb.
the class JoinCompiler method generatePositionNotDistinctFromRowWithPageMethod.
private void generatePositionNotDistinctFromRowWithPageMethod(ClassDefinition classDefinition, CallSiteBinder callSiteBinder, List<Type> joinChannelTypes, List<FieldDefinition> joinChannelFields) {
Parameter leftBlockIndex = arg("leftBlockIndex", int.class);
Parameter leftBlockPosition = arg("leftBlockPosition", int.class);
Parameter rightPosition = arg("rightPosition", int.class);
Parameter page = arg("page", Page.class);
Parameter rightChannels = arg("rightChannels", int[].class);
MethodDefinition positionNotDistinctFromRowMethod = classDefinition.declareMethod(a(PUBLIC), "positionNotDistinctFromRow", type(boolean.class), leftBlockIndex, leftBlockPosition, rightPosition, page, rightChannels);
Variable thisVariable = positionNotDistinctFromRowMethod.getThis();
Scope scope = positionNotDistinctFromRowMethod.getScope();
BytecodeBlock body = positionNotDistinctFromRowMethod.getBody();
if (groupByUsesEqualTo) {
// positionNotDistinctFromRow delegates to positionEqualsRow when groupByUsesEqualTo is set.
body.append(thisVariable.invoke("positionEqualsRow", boolean.class, leftBlockIndex, leftBlockPosition, rightPosition, page, rightChannels).ret());
return;
}
scope.declareVariable("wasNull", body, constantFalse());
for (int index = 0; index < joinChannelTypes.size(); index++) {
BytecodeExpression leftBlock = thisVariable.getField(joinChannelFields.get(index)).invoke("get", Object.class, leftBlockIndex).cast(Block.class);
BytecodeExpression rightBlock = page.invoke("getBlock", Block.class, rightChannels.getElement(index));
Type type = joinChannelTypes.get(index);
// At that point, we'll be able to fully deprecate Type.equalTo (and friends) and remove this hack.
if (type.getJavaType().equals(Slice.class)) {
switch(type.getTypeSignature().getBase()) {
case StandardTypes.CHAR:
case StandardTypes.IPADDRESS:
case StandardTypes.JSON:
case StandardTypes.DECIMAL:
case StandardTypes.VARBINARY:
case StandardTypes.VARCHAR:
body.append(new IfStatement().condition(typeEquals(constantType(callSiteBinder, type), leftBlock, leftBlockPosition, rightBlock, rightPosition)).ifFalse(constantFalse().ret()));
continue;
}
}
JavaScalarFunctionImplementation operator = functionAndTypeManager.getJavaScalarFunctionImplementation(functionAndTypeManager.resolveOperator(OperatorType.IS_DISTINCT_FROM, fromTypes(type, type)));
callSiteBinder.bind(operator.getMethodHandle());
List<BytecodeNode> argumentsBytecode = new ArrayList<>();
argumentsBytecode.add(generateInputReference(callSiteBinder, scope, type, leftBlock, leftBlockPosition));
argumentsBytecode.add(generateInputReference(callSiteBinder, scope, type, rightBlock, rightPosition));
body.append(new IfStatement().condition(BytecodeUtils.generateInvocation(scope, "isDistinctFrom", operator, Optional.empty(), argumentsBytecode, callSiteBinder)).ifTrue(constantFalse().ret()));
}
body.append(constantTrue().ret());
}
use of com.facebook.presto.bytecode.BytecodeNode in project presto by prestodb.
the class IsNullCodeGenerator method generateExpression.
@Override
public BytecodeNode generateExpression(BytecodeGeneratorContext generatorContext, Type returnType, List<RowExpression> arguments, Optional<Variable> outputBlockVariable) {
Preconditions.checkArgument(arguments.size() == 1);
RowExpression argument = arguments.get(0);
if (argument.getType().equals(UNKNOWN)) {
return loadBoolean(true);
}
BytecodeNode value = generatorContext.generate(argument, Optional.empty());
// evaluate the expression, pop the produced value, and load the null flag
Variable wasNull = generatorContext.wasNull();
BytecodeBlock block = new BytecodeBlock().comment("is null").append(value).pop(argument.getType().getJavaType()).append(wasNull);
// clear the null flag
block.append(wasNull.set(constantFalse()));
outputBlockVariable.ifPresent(output -> block.append(generateWrite(generatorContext, returnType, output)));
return block;
}
Aggregations