use of com.facebook.presto.common.function.SqlFunctionProperties in project presto by prestodb.
the class CursorProcessorCompiler method generateMethods.
@Override
public void generateMethods(SqlFunctionProperties sqlFunctionProperties, ClassDefinition classDefinition, CallSiteBinder callSiteBinder, RowExpression filter, List<RowExpression> projections) {
CachedInstanceBinder cachedInstanceBinder = new CachedInstanceBinder(classDefinition, callSiteBinder);
List<RowExpression> rowExpressions = ImmutableList.<RowExpression>builder().addAll(projections).add(filter).build();
Map<LambdaDefinitionExpression, CompiledLambda> compiledLambdaMap = generateMethodsForLambda(classDefinition, callSiteBinder, cachedInstanceBinder, rowExpressions, metadata, sqlFunctionProperties, sessionFunctions, "");
Map<VariableReferenceExpression, CommonSubExpressionFields> cseFields = ImmutableMap.of();
RowExpressionCompiler compiler = new RowExpressionCompiler(classDefinition, callSiteBinder, cachedInstanceBinder, fieldReferenceCompiler(cseFields), metadata, sqlFunctionProperties, sessionFunctions, compiledLambdaMap);
if (isOptimizeCommonSubExpressions) {
Map<Integer, Map<RowExpression, VariableReferenceExpression>> commonSubExpressionsByLevel = collectCSEByLevel(rowExpressions);
if (!commonSubExpressionsByLevel.isEmpty()) {
cseFields = declareCommonSubExpressionFields(classDefinition, commonSubExpressionsByLevel);
compiler = new RowExpressionCompiler(classDefinition, callSiteBinder, cachedInstanceBinder, fieldReferenceCompiler(cseFields), metadata, sqlFunctionProperties, sessionFunctions, compiledLambdaMap);
generateCommonSubExpressionMethods(classDefinition, compiler, commonSubExpressionsByLevel, cseFields);
Map<RowExpression, VariableReferenceExpression> commonSubExpressions = commonSubExpressionsByLevel.values().stream().flatMap(m -> m.entrySet().stream()).collect(toImmutableMap(Map.Entry::getKey, Map.Entry::getValue));
projections = rewriteRowExpressionsWithCSE(projections, commonSubExpressions);
filter = rewriteRowExpressionsWithCSE(ImmutableList.of(filter), commonSubExpressions).get(0);
}
}
generateProcessMethod(classDefinition, projections.size(), cseFields);
generateFilterMethod(classDefinition, compiler, filter);
for (int i = 0; i < projections.size(); i++) {
String methodName = "project_" + i;
generateProjectMethod(classDefinition, compiler, methodName, projections.get(i));
}
MethodDefinition constructorDefinition = classDefinition.declareConstructor(a(PUBLIC));
BytecodeBlock constructorBody = constructorDefinition.getBody();
Variable thisVariable = constructorDefinition.getThis();
constructorBody.comment("super();").append(thisVariable).invokeConstructor(Object.class);
initializeCommonSubExpressionFields(cseFields.values(), thisVariable, constructorBody);
cachedInstanceBinder.generateInitializations(thisVariable, constructorBody);
constructorBody.ret();
}
use of com.facebook.presto.common.function.SqlFunctionProperties in project presto by prestodb.
the class PageFunctionCompiler method definePageProjectWorkClass.
private ClassDefinition definePageProjectWorkClass(SqlFunctionProperties sqlFunctionProperties, Map<SqlFunctionId, SqlInvokedFunction> sessionFunctions, List<RowExpression> projections, CallSiteBinder callSiteBinder, boolean isOptimizeCommonSubExpression, Optional<String> classNameSuffix) {
ClassDefinition classDefinition = new ClassDefinition(a(PUBLIC, FINAL), generateProjectionWorkClassName(classNameSuffix), type(Object.class), type(Work.class));
FieldDefinition blockBuilderFields = classDefinition.declareField(a(PRIVATE), "blockBuilders", type(List.class, BlockBuilder.class));
FieldDefinition propertiesField = classDefinition.declareField(a(PRIVATE), "properties", SqlFunctionProperties.class);
FieldDefinition pageField = classDefinition.declareField(a(PRIVATE), "page", Page.class);
FieldDefinition selectedPositionsField = classDefinition.declareField(a(PRIVATE), "selectedPositions", SelectedPositions.class);
FieldDefinition nextIndexOrPositionField = classDefinition.declareField(a(PRIVATE), "nextIndexOrPosition", int.class);
FieldDefinition resultField = classDefinition.declareField(a(PRIVATE), "result", List.class);
CachedInstanceBinder cachedInstanceBinder = new CachedInstanceBinder(classDefinition, callSiteBinder);
// process
generateProcessMethod(classDefinition, blockBuilderFields, projections.size(), propertiesField, pageField, selectedPositionsField, nextIndexOrPositionField, resultField);
// getResult
MethodDefinition method = classDefinition.declareMethod(a(PUBLIC), "getResult", type(Object.class), ImmutableList.of());
method.getBody().append(method.getThis().getField(resultField)).ret(Object.class);
Map<LambdaDefinitionExpression, CompiledLambda> compiledLambdaMap = generateMethodsForLambda(classDefinition, callSiteBinder, cachedInstanceBinder, projections, metadata, sqlFunctionProperties, sessionFunctions, "");
// cse
Map<VariableReferenceExpression, CommonSubExpressionFields> cseFields = ImmutableMap.of();
RowExpressionCompiler compiler = new RowExpressionCompiler(classDefinition, callSiteBinder, cachedInstanceBinder, new FieldAndVariableReferenceCompiler(callSiteBinder, cseFields), metadata, sqlFunctionProperties, sessionFunctions, compiledLambdaMap);
if (isOptimizeCommonSubExpression) {
Map<Integer, Map<RowExpression, VariableReferenceExpression>> commonSubExpressionsByLevel = collectCSEByLevel(projections);
if (!commonSubExpressionsByLevel.isEmpty()) {
cseFields = declareCommonSubExpressionFields(classDefinition, commonSubExpressionsByLevel);
compiler = new RowExpressionCompiler(classDefinition, callSiteBinder, cachedInstanceBinder, new FieldAndVariableReferenceCompiler(callSiteBinder, cseFields), metadata, sqlFunctionProperties, sessionFunctions, compiledLambdaMap);
generateCommonSubExpressionMethods(classDefinition, compiler, commonSubExpressionsByLevel, cseFields);
Map<RowExpression, VariableReferenceExpression> commonSubExpressions = commonSubExpressionsByLevel.values().stream().flatMap(m -> m.entrySet().stream()).collect(toImmutableMap(Map.Entry::getKey, Map.Entry::getValue));
projections = projections.stream().map(projection -> rewriteExpressionWithCSE(projection, commonSubExpressions)).collect(toImmutableList());
if (log.isDebugEnabled()) {
log.debug("Extracted %d common sub-expressions", commonSubExpressions.size());
commonSubExpressions.entrySet().forEach(entry -> log.debug("\t%s = %s", entry.getValue(), entry.getKey()));
log.debug("Rewrote %d projections: %s", projections.size(), Joiner.on(", ").join(projections));
}
}
}
// evaluate
generateEvaluateMethod(classDefinition, compiler, projections, blockBuilderFields, cseFields);
// constructor
Parameter blockBuilders = arg("blockBuilders", type(List.class, BlockBuilder.class));
Parameter properties = arg("properties", SqlFunctionProperties.class);
Parameter page = arg("page", Page.class);
Parameter selectedPositions = arg("selectedPositions", SelectedPositions.class);
MethodDefinition constructorDefinition = classDefinition.declareConstructor(a(PUBLIC), blockBuilders, properties, page, selectedPositions);
BytecodeBlock body = constructorDefinition.getBody();
Variable thisVariable = constructorDefinition.getThis();
body.comment("super();").append(thisVariable).invokeConstructor(Object.class).append(thisVariable.setField(blockBuilderFields, invokeStatic(ImmutableList.class, "copyOf", ImmutableList.class, blockBuilders.cast(Collection.class)))).append(thisVariable.setField(propertiesField, properties)).append(thisVariable.setField(pageField, page)).append(thisVariable.setField(selectedPositionsField, selectedPositions)).append(thisVariable.setField(nextIndexOrPositionField, selectedPositions.invoke("getOffset", int.class))).append(thisVariable.setField(resultField, constantNull(Block.class)));
initializeCommonSubExpressionFields(cseFields.values(), thisVariable, body);
cachedInstanceBinder.generateInitializations(thisVariable, body);
body.ret();
return classDefinition;
}
use of com.facebook.presto.common.function.SqlFunctionProperties in project presto by prestodb.
the class LiteralInterpreter method evaluate.
public static Object evaluate(ConnectorSession session, ConstantExpression node) {
Type type = node.getType();
SqlFunctionProperties properties = session.getSqlFunctionProperties();
if (node.getValue() == null) {
return null;
}
if (type instanceof BooleanType) {
return node.getValue();
}
if (type instanceof BigintType || type instanceof TinyintType || type instanceof SmallintType || type instanceof IntegerType) {
return node.getValue();
}
if (type instanceof DoubleType) {
return node.getValue();
}
if (type instanceof RealType) {
Long number = (Long) node.getValue();
return intBitsToFloat(number.intValue());
}
if (type instanceof DecimalType) {
DecimalType decimalType = (DecimalType) type;
if (decimalType.isShort()) {
checkState(node.getValue() instanceof Long);
return decodeDecimal(BigInteger.valueOf((long) node.getValue()), decimalType);
}
checkState(node.getValue() instanceof Slice);
Slice value = (Slice) node.getValue();
return decodeDecimal(decodeUnscaledValue(value), decimalType);
}
if (type instanceof VarcharType || type instanceof CharType) {
return ((Slice) node.getValue()).toStringUtf8();
}
if (type instanceof VarbinaryType) {
return new SqlVarbinary(((Slice) node.getValue()).getBytes());
}
if (type instanceof DateType) {
return new SqlDate(((Long) node.getValue()).intValue());
}
if (type instanceof TimeType) {
if (properties.isLegacyTimestamp()) {
return new SqlTime((long) node.getValue(), properties.getTimeZoneKey());
}
return new SqlTime((long) node.getValue());
}
if (type instanceof TimestampType) {
try {
if (properties.isLegacyTimestamp()) {
return new SqlTimestamp((long) node.getValue(), properties.getTimeZoneKey());
}
return new SqlTimestamp((long) node.getValue());
} catch (RuntimeException e) {
throw new PrestoException(GENERIC_USER_ERROR, format("'%s' is not a valid timestamp literal", (String) node.getValue()));
}
}
if (type instanceof IntervalDayTimeType) {
return new SqlIntervalDayTime((long) node.getValue());
}
if (type instanceof IntervalYearMonthType) {
return new SqlIntervalYearMonth(((Long) node.getValue()).intValue());
}
if (type.getJavaType().equals(Slice.class)) {
// DO NOT ever remove toBase64. Calling toString directly on Slice whose base is not byte[] will cause JVM to crash.
return "'" + VarbinaryFunctions.toBase64((Slice) node.getValue()).toStringUtf8() + "'";
}
// We should not fail at the moment; just return the raw value (block, regex, etc) to the user
return node.getValue();
}
use of com.facebook.presto.common.function.SqlFunctionProperties in project presto by prestodb.
the class InterpretedFunctionInvoker method invoke.
/**
* Arguments must be the native container type for the corresponding SQL types.
* <p>
* Returns a value in the native container type corresponding to the declared SQL return type
*/
private Object invoke(JavaScalarFunctionImplementation function, SqlFunctionProperties properties, List<Object> arguments) {
ScalarFunctionImplementationChoice choice = getAllScalarFunctionImplementationChoices(function).get(0);
MethodHandle method = choice.getMethodHandle();
// handle function on instance method, to allow use of fields
method = bindInstanceFactory(method, function);
if (method.type().parameterCount() > 0 && method.type().parameterType(0) == SqlFunctionProperties.class) {
method = method.bindTo(properties);
}
List<Object> actualArguments = new ArrayList<>();
for (int i = 0; i < arguments.size(); i++) {
Object argument = arguments.get(i);
ArgumentProperty argumentProperty = choice.getArgumentProperty(i);
if (argumentProperty.getArgumentType() == VALUE_TYPE) {
if (choice.getArgumentProperty(i).getNullConvention() == RETURN_NULL_ON_NULL) {
if (argument == null) {
return null;
}
actualArguments.add(argument);
} else if (choice.getArgumentProperty(i).getNullConvention() == USE_NULL_FLAG) {
boolean isNull = argument == null;
if (isNull) {
argument = Defaults.defaultValue(method.type().parameterType(actualArguments.size()));
}
actualArguments.add(argument);
actualArguments.add(isNull);
} else {
actualArguments.add(argument);
}
} else {
argument = asInterfaceInstance(argumentProperty.getLambdaInterface(), (MethodHandle) argument);
actualArguments.add(argument);
}
}
try {
return method.invokeWithArguments(actualArguments);
} catch (Throwable throwable) {
throw propagate(throwable);
}
}
use of com.facebook.presto.common.function.SqlFunctionProperties in project presto by prestodb.
the class TestParametricScalarImplementationValidation method testSqlFunctionPropertiesPosition.
@Test
public void testSqlFunctionPropertiesPosition() {
// Without cached instance factory
MethodHandle validFunctionMethodHandle = methodHandle(TestParametricScalarImplementationValidation.class, "validSqlFunctionPropertiesParameterPosition", SqlFunctionProperties.class, long.class, long.class);
BuiltInScalarFunctionImplementation validFunction = new BuiltInScalarFunctionImplementation(false, ImmutableList.of(valueTypeArgumentProperty(RETURN_NULL_ON_NULL), valueTypeArgumentProperty(RETURN_NULL_ON_NULL)), validFunctionMethodHandle);
assertEquals(validFunction.getMethodHandle(), validFunctionMethodHandle);
try {
BuiltInScalarFunctionImplementation invalidFunction = new BuiltInScalarFunctionImplementation(false, ImmutableList.of(valueTypeArgumentProperty(RETURN_NULL_ON_NULL), valueTypeArgumentProperty(RETURN_NULL_ON_NULL)), methodHandle(TestParametricScalarImplementationValidation.class, "invalidSqlFunctionPropertiesParameterPosition", long.class, long.class, SqlFunctionProperties.class));
fail("expected exception");
} catch (IllegalArgumentException e) {
assertEquals(e.getMessage(), "SqlFunctionProperties must be the first argument when instanceFactory is not present");
}
// With cached instance factory
MethodHandle validFunctionWithInstanceFactoryMethodHandle = methodHandle(TestParametricScalarImplementationValidation.class, "validSqlFunctionPropertiesParameterPosition", Object.class, SqlFunctionProperties.class, long.class, long.class);
BuiltInScalarFunctionImplementation validFunctionWithInstanceFactory = new BuiltInScalarFunctionImplementation(false, ImmutableList.of(valueTypeArgumentProperty(RETURN_NULL_ON_NULL), valueTypeArgumentProperty(RETURN_NULL_ON_NULL)), validFunctionWithInstanceFactoryMethodHandle, Optional.of(STATE_FACTORY));
assertEquals(validFunctionWithInstanceFactory.getMethodHandle(), validFunctionWithInstanceFactoryMethodHandle);
try {
BuiltInScalarFunctionImplementation invalidFunctionWithInstanceFactory = new BuiltInScalarFunctionImplementation(false, ImmutableList.of(valueTypeArgumentProperty(RETURN_NULL_ON_NULL), valueTypeArgumentProperty(RETURN_NULL_ON_NULL)), methodHandle(TestParametricScalarImplementationValidation.class, "invalidSqlFunctionPropertiesParameterPosition", Object.class, long.class, long.class, SqlFunctionProperties.class), Optional.of(STATE_FACTORY));
fail("expected exception");
} catch (IllegalArgumentException e) {
assertEquals(e.getMessage(), "SqlFunctionProperties must be the second argument when instanceFactory is present");
}
}
Aggregations