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