use of com.facebook.presto.bytecode.expression.BytecodeExpression in project presto by prestodb.
the class AccumulatorCompiler method generateSetGroupIdFromGroupIdsBlock.
private static void generateSetGroupIdFromGroupIdsBlock(Scope scope, List<FieldDefinition> stateFields, BytecodeBlock block) {
Variable groupIdsBlock = scope.getVariable("groupIdsBlock");
Variable position = scope.getVariable("position");
for (FieldDefinition stateField : stateFields) {
BytecodeExpression state = scope.getThis().getField(stateField);
block.append(state.invoke("setGroupId", void.class, groupIdsBlock.invoke("getGroupId", long.class, position)));
}
}
use of com.facebook.presto.bytecode.expression.BytecodeExpression in project presto by prestodb.
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;
}
use of com.facebook.presto.bytecode.expression.BytecodeExpression in project presto by prestodb.
the class JoinCompiler method generateCompareSortChannelPositionsMethod.
private static void generateCompareSortChannelPositionsMethod(ClassDefinition classDefinition, CallSiteBinder callSiteBinder, List<Type> types, List<FieldDefinition> channelFields, Optional<Integer> sortChannel) {
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 compareMethod = classDefinition.declareMethod(a(PUBLIC), "compareSortChannelPositions", type(int.class), leftBlockIndex, leftBlockPosition, rightBlockIndex, rightBlockPosition);
if (!sortChannel.isPresent()) {
compareMethod.getBody().append(newInstance(UnsupportedOperationException.class)).throwObject();
return;
}
Variable thisVariable = compareMethod.getThis();
int index = sortChannel.get();
BytecodeExpression type = constantType(callSiteBinder, types.get(index));
BytecodeExpression leftBlock = thisVariable.getField(channelFields.get(index)).invoke("get", Object.class, leftBlockIndex).cast(Block.class);
BytecodeExpression rightBlock = thisVariable.getField(channelFields.get(index)).invoke("get", Object.class, rightBlockIndex).cast(Block.class);
BytecodeNode comparison = type.invoke("compareTo", int.class, leftBlock, leftBlockPosition, rightBlock, rightBlockPosition).ret();
compareMethod.getBody().append(comparison);
}
use of com.facebook.presto.bytecode.expression.BytecodeExpression in project presto by prestodb.
the class JoinCompiler method generatePositionEqualsRowMethod.
private static void generatePositionEqualsRowMethod(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 rightPosition = arg("rightPosition", int.class);
Parameter rightPage = arg("rightPage", Page.class);
MethodDefinition positionEqualsRowMethod = classDefinition.declareMethod(a(PUBLIC), ignoreNulls ? "positionEqualsRowIgnoreNulls" : "positionEqualsRow", type(boolean.class), leftBlockIndex, leftBlockPosition, rightPosition, rightPage);
Variable thisVariable = positionEqualsRowMethod.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 = rightPage.invoke("getBlock", Block.class, constantInt(index));
BytecodeNode equalityCondition;
if (ignoreNulls) {
equalityCondition = typeEqualsIgnoreNulls(type, leftBlock, leftBlockPosition, rightBlock, rightPosition);
} else {
equalityCondition = typeEquals(type, leftBlock, leftBlockPosition, rightBlock, rightPosition);
}
LabelNode checkNextField = new LabelNode("checkNextField");
positionEqualsRowMethod.getBody().append(equalityCondition).ifTrueGoto(checkNextField).push(false).retBoolean().visitLabel(checkNextField);
}
positionEqualsRowMethod.getBody().push(true).retInt();
}
use of com.facebook.presto.bytecode.expression.BytecodeExpression in project presto by prestodb.
the class JoinCompiler method generateIsPositionNull.
private static void generateIsPositionNull(ClassDefinition classDefinition, List<FieldDefinition> joinChannelFields) {
Parameter blockIndex = arg("blockIndex", int.class);
Parameter blockPosition = arg("blockPosition", int.class);
MethodDefinition isPositionNullMethod = classDefinition.declareMethod(a(PUBLIC), "isPositionNull", type(boolean.class), blockIndex, blockPosition);
for (FieldDefinition joinChannelField : joinChannelFields) {
BytecodeExpression block = isPositionNullMethod.getThis().getField(joinChannelField).invoke("get", Object.class, blockIndex).cast(Block.class);
IfStatement ifStatement = new IfStatement();
ifStatement.condition(block.invoke("isNull", boolean.class, blockPosition));
ifStatement.ifTrue(constantTrue().ret());
isPositionNullMethod.getBody().append(ifStatement);
}
isPositionNullMethod.getBody().append(constantFalse().ret());
}
Aggregations