use of com.facebook.presto.common.function.OperatorType in project presto by prestodb.
the class AbstractMinMaxBy method generateAggregation.
private InternalAggregationFunction generateAggregation(Type valueType, Type keyType, FunctionAndTypeManager functionAndTypeManager) {
Class<?> stateClazz = getStateClass(keyType.getJavaType(), valueType.getJavaType());
DynamicClassLoader classLoader = new DynamicClassLoader(getClass().getClassLoader());
// Generate states and serializers:
// For value that is a Block or Slice, we store them as Block/position combination
// to avoid generating long-living objects through getSlice or getBlock.
// This can also help reducing cross-region reference in G1GC engine.
// TODO: keys can have the same problem. But usually they are primitive types (given the nature of comparison).
AccumulatorStateFactory<?> stateFactory;
AccumulatorStateSerializer<?> stateSerializer;
if (valueType.getJavaType().isPrimitive()) {
Map<String, Type> stateFieldTypes = ImmutableMap.of("First", keyType, "Second", valueType);
stateFactory = StateCompiler.generateStateFactory(stateClazz, stateFieldTypes, classLoader);
stateSerializer = StateCompiler.generateStateSerializer(stateClazz, stateFieldTypes, classLoader);
} else {
// StateCompiler checks type compatibility.
// Given "Second" in this case is always a Block, we only need to make sure the getter and setter of the Blocks are properly generated.
// We deliberately make "SecondBlock" an array type so that the compiler will treat it as a block to workaround the sanity check.
stateFactory = StateCompiler.generateStateFactory(stateClazz, ImmutableMap.of("First", keyType, "SecondBlock", new ArrayType(valueType)), classLoader);
// States can be generated by StateCompiler given the they are simply classes with getters and setters.
// However, serializers have logic in it. Creating serializers is better than generating them.
stateSerializer = getStateSerializer(keyType, valueType);
}
Type intermediateType = stateSerializer.getSerializedType();
List<Type> inputTypes = ImmutableList.of(valueType, keyType);
CallSiteBinder binder = new CallSiteBinder();
OperatorType operator = min ? LESS_THAN : GREATER_THAN;
MethodHandle compareMethod = functionAndTypeManager.getJavaScalarFunctionImplementation(functionAndTypeManager.resolveOperator(operator, fromTypes(keyType, keyType))).getMethodHandle();
ClassDefinition definition = new ClassDefinition(a(PUBLIC, FINAL), makeClassName("processMaxOrMinBy"), type(Object.class));
definition.declareDefaultConstructor(a(PRIVATE));
generateInputMethod(definition, binder, compareMethod, keyType, valueType, stateClazz);
generateCombineMethod(definition, binder, compareMethod, keyType, valueType, stateClazz);
generateOutputMethod(definition, binder, valueType, stateClazz);
Class<?> generatedClass = defineClass(definition, Object.class, binder.getBindings(), classLoader);
MethodHandle inputMethod = methodHandle(generatedClass, "input", stateClazz, Block.class, Block.class, int.class);
MethodHandle combineMethod = methodHandle(generatedClass, "combine", stateClazz, stateClazz);
MethodHandle outputMethod = methodHandle(generatedClass, "output", stateClazz, BlockBuilder.class);
AggregationMetadata metadata = new AggregationMetadata(generateAggregationName(getSignature().getNameSuffix(), valueType.getTypeSignature(), inputTypes.stream().map(Type::getTypeSignature).collect(toImmutableList())), createInputParameterMetadata(valueType, keyType), inputMethod, combineMethod, outputMethod, ImmutableList.of(new AccumulatorStateDescriptor(stateClazz, stateSerializer, stateFactory)), valueType);
GenericAccumulatorFactoryBinder factory = AccumulatorCompiler.generateAccumulatorFactoryBinder(metadata, classLoader);
return new InternalAggregationFunction(getSignature().getNameSuffix(), inputTypes, ImmutableList.of(intermediateType), valueType, true, false, factory);
}
use of com.facebook.presto.common.function.OperatorType in project presto by prestodb.
the class RowComparisonOperator method getMethodHandles.
protected List<MethodHandle> getMethodHandles(RowType type, FunctionAndTypeManager functionAndTypeManager, OperatorType operatorType) {
ImmutableList.Builder<MethodHandle> argumentMethods = ImmutableList.builder();
for (Type parameterType : type.getTypeParameters()) {
FunctionHandle operatorHandle = functionAndTypeManager.resolveOperator(operatorType, fromTypes(parameterType, parameterType));
argumentMethods.add(functionAndTypeManager.getJavaScalarFunctionImplementation(operatorHandle).getMethodHandle());
}
return argumentMethods.build();
}
use of com.facebook.presto.common.function.OperatorType in project presto by prestodb.
the class SpatialJoinUtils method getFlippedFunctionHandle.
public static FunctionHandle getFlippedFunctionHandle(CallExpression callExpression, FunctionAndTypeManager functionAndTypeManager) {
FunctionMetadata callExpressionMetadata = functionAndTypeManager.getFunctionMetadata(callExpression.getFunctionHandle());
checkArgument(callExpressionMetadata.getOperatorType().isPresent());
OperatorType operatorType = flip(callExpressionMetadata.getOperatorType().get());
List<TypeSignatureProvider> typeProviderList = fromTypes(callExpression.getArguments().stream().map(RowExpression::getType).collect(toImmutableList()));
checkArgument(typeProviderList.size() == 2, "Expected there to be only two arguments in type provider");
return functionAndTypeManager.resolveOperator(operatorType, ImmutableList.of(typeProviderList.get(1), typeProviderList.get(0)));
}
use of com.facebook.presto.common.function.OperatorType in project presto by prestodb.
the class RowExpressionVerifier method visitArithmeticBinary.
@Override
protected Boolean visitArithmeticBinary(ArithmeticBinaryExpression expected, RowExpression actual) {
if (actual instanceof CallExpression) {
FunctionMetadata functionMetadata = metadata.getFunctionAndTypeManager().getFunctionMetadata(((CallExpression) actual).getFunctionHandle());
if (!functionMetadata.getOperatorType().isPresent() || !functionMetadata.getOperatorType().get().isArithmeticOperator()) {
return false;
}
OperatorType actualOperatorType = functionMetadata.getOperatorType().get();
OperatorType expectedOperatorType = getOperatorType(expected.getOperator());
if (expectedOperatorType.equals(actualOperatorType)) {
return process(expected.getLeft(), ((CallExpression) actual).getArguments().get(0)) && process(expected.getRight(), ((CallExpression) actual).getArguments().get(1));
}
}
return false;
}
use of com.facebook.presto.common.function.OperatorType in project presto by prestodb.
the class DynamicFilters method getPlaceholder.
public static Optional<DynamicFilterPlaceholder> getPlaceholder(RowExpression expression) {
if (!(expression instanceof CallExpression)) {
return Optional.empty();
}
CallExpression call = (CallExpression) expression;
List<RowExpression> arguments = call.getArguments();
if (!call.getDisplayName().equals(DynamicFilterPlaceholderFunction.NAME)) {
return Optional.empty();
}
checkArgument(arguments.size() == 3, "invalid arguments count: %s", arguments.size());
RowExpression probeSymbol = arguments.get(0);
RowExpression operatorExpression = arguments.get(1);
checkArgument(operatorExpression instanceof ConstantExpression);
checkArgument(operatorExpression.getType() instanceof VarcharType);
String operator = ((Slice) ((ConstantExpression) operatorExpression).getValue()).toStringUtf8();
RowExpression idExpression = arguments.get(2);
checkArgument(idExpression instanceof ConstantExpression);
checkArgument(idExpression.getType() instanceof VarcharType);
String id = ((Slice) ((ConstantExpression) idExpression).getValue()).toStringUtf8();
OperatorType operatorType = OperatorType.valueOf(operator);
if (operatorType.isComparisonOperator()) {
return Optional.of(new DynamicFilterPlaceholder(id, probeSymbol, operatorType));
}
return Optional.empty();
}
Aggregations