use of com.facebook.presto.spi.relation.ConstantExpression in project presto by prestodb.
the class InCodeGenerator method isDeterminateConstant.
private static boolean isDeterminateConstant(RowExpression expression, MethodHandle isIndeterminateFunction) {
if (!(expression instanceof ConstantExpression)) {
return false;
}
ConstantExpression constantExpression = (ConstantExpression) expression;
Object value = constantExpression.getValue();
boolean isNull = value == null;
if (isNull) {
return false;
}
try {
return !(boolean) isIndeterminateFunction.invoke(value, false);
} catch (Throwable t) {
throwIfUnchecked(t);
throw new RuntimeException(t);
}
}
use of com.facebook.presto.spi.relation.ConstantExpression 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.spi.relation.ConstantExpression in project presto by prestodb.
the class TestRowExpressionOptimizer method testCastWithJsonParseOptimization.
@Test
public void testCastWithJsonParseOptimization() {
FunctionHandle jsonParseFunctionHandle = functionAndTypeManager.lookupFunction("json_parse", fromTypes(VARCHAR));
// constant
FunctionHandle jsonCastFunctionHandle = functionAndTypeManager.lookupCast(CAST, JSON.getTypeSignature(), parseTypeSignature("array(integer)"));
RowExpression jsonCastExpression = new CallExpression(CAST.name(), jsonCastFunctionHandle, new ArrayType(INTEGER), ImmutableList.of(call("json_parse", jsonParseFunctionHandle, JSON, constant(utf8Slice("[1, 2]"), VARCHAR))));
RowExpression resultExpression = optimize(jsonCastExpression);
assertInstanceOf(resultExpression, ConstantExpression.class);
Object resultValue = ((ConstantExpression) resultExpression).getValue();
assertInstanceOf(resultValue, IntArrayBlock.class);
assertEquals(toValues(INTEGER, (IntArrayBlock) resultValue), ImmutableList.of(1, 2));
// varchar to array
jsonCastFunctionHandle = functionAndTypeManager.lookupCast(CAST, JSON.getTypeSignature(), parseTypeSignature("array(varchar)"));
jsonCastExpression = call(CAST.name(), jsonCastFunctionHandle, new ArrayType(VARCHAR), ImmutableList.of(call("json_parse", jsonParseFunctionHandle, JSON, field(1, VARCHAR))));
resultExpression = optimize(jsonCastExpression);
assertEquals(resultExpression, call(JSON_TO_ARRAY_CAST.name(), functionAndTypeManager.lookupCast(JSON_TO_ARRAY_CAST, VARCHAR.getTypeSignature(), parseTypeSignature("array(varchar)")), new ArrayType(VARCHAR), field(1, VARCHAR)));
// varchar to map
jsonCastFunctionHandle = functionAndTypeManager.lookupCast(CAST, JSON.getTypeSignature(), parseTypeSignature("map(integer,varchar)"));
jsonCastExpression = call(CAST.name(), jsonCastFunctionHandle, mapType(INTEGER, VARCHAR), ImmutableList.of(call("json_parse", jsonParseFunctionHandle, JSON, field(1, VARCHAR))));
resultExpression = optimize(jsonCastExpression);
assertEquals(resultExpression, call(JSON_TO_MAP_CAST.name(), functionAndTypeManager.lookupCast(JSON_TO_MAP_CAST, VARCHAR.getTypeSignature(), parseTypeSignature("map(integer, varchar)")), mapType(INTEGER, VARCHAR), field(1, VARCHAR)));
// varchar to row
jsonCastFunctionHandle = functionAndTypeManager.lookupCast(CAST, JSON.getTypeSignature(), parseTypeSignature("row(varchar,bigint)"));
jsonCastExpression = call(CAST.name(), jsonCastFunctionHandle, RowType.anonymous(ImmutableList.of(VARCHAR, BIGINT)), ImmutableList.of(call("json_parse", jsonParseFunctionHandle, JSON, field(1, VARCHAR))));
resultExpression = optimize(jsonCastExpression);
assertEquals(resultExpression, call(JSON_TO_ROW_CAST.name(), functionAndTypeManager.lookupCast(JSON_TO_ROW_CAST, VARCHAR.getTypeSignature(), parseTypeSignature("row(varchar,bigint)")), RowType.anonymous(ImmutableList.of(VARCHAR, BIGINT)), field(1, VARCHAR)));
}
use of com.facebook.presto.spi.relation.ConstantExpression in project presto by prestodb.
the class SimplifyCountOverConstant method isCountOverConstant.
private boolean isCountOverConstant(AggregationNode.Aggregation aggregation, Assignments inputs) {
if (!functionResolution.isCountFunction(aggregation.getFunctionHandle()) || aggregation.getArguments().size() != 1) {
return false;
}
RowExpression argument = aggregation.getArguments().get(0);
RowExpression assigned = null;
if (argument instanceof VariableReferenceExpression) {
assigned = inputs.get((VariableReferenceExpression) argument);
}
return assigned instanceof ConstantExpression && !isNull(assigned);
}
use of com.facebook.presto.spi.relation.ConstantExpression in project presto by prestodb.
the class ParquetDereferencePushDown method createNestedColumn.
private Subfield createNestedColumn(Map<String, ColumnHandle> baseColumnHandles, RowExpression rowExpression, ExpressionOptimizer expressionOptimizer, ConnectorSession session) {
if (!(rowExpression instanceof SpecialFormExpression) || ((SpecialFormExpression) rowExpression).getForm() != DEREFERENCE) {
throw new IllegalArgumentException("expecting SpecialFormExpression(DEREFERENCE), but got: " + rowExpression);
}
RowExpression currentRowExpression = rowExpression;
List<Subfield.PathElement> elements = new ArrayList<>();
while (true) {
if (currentRowExpression instanceof VariableReferenceExpression) {
Collections.reverse(elements);
String name = ((VariableReferenceExpression) currentRowExpression).getName();
ColumnHandle handle = baseColumnHandles.get(name);
checkArgument(handle != null, "Missing Column handle: " + name);
String originalColumnName = getColumnName(handle);
return new Subfield(originalColumnName, unmodifiableList(elements));
}
if (currentRowExpression instanceof SpecialFormExpression && ((SpecialFormExpression) currentRowExpression).getForm() == DEREFERENCE) {
SpecialFormExpression dereferenceExpression = (SpecialFormExpression) currentRowExpression;
RowExpression base = dereferenceExpression.getArguments().get(0);
RowType baseType = (RowType) base.getType();
RowExpression indexExpression = expressionOptimizer.optimize(dereferenceExpression.getArguments().get(1), ExpressionOptimizer.Level.OPTIMIZED, session);
if (indexExpression instanceof ConstantExpression) {
Object index = ((ConstantExpression) indexExpression).getValue();
if (index instanceof Number) {
Optional<String> fieldName = baseType.getFields().get(((Number) index).intValue()).getName();
if (fieldName.isPresent()) {
elements.add(new Subfield.NestedField(fieldName.get()));
currentRowExpression = base;
continue;
}
}
}
}
break;
}
throw new IllegalArgumentException("expecting SpecialFormExpression(DEREFERENCE) with constants for indices, but got: " + currentRowExpression);
}
Aggregations