use of io.prestosql.spi.function.OperatorType in project hetu-core by openlookeng.
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 getObject.
// 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.getBuiltInScalarFunctionImplementation(functionAndTypeManager.resolveOperatorFunctionHandle(operator, TypeSignatureProvider.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 aggregationMetadata = 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(aggregationMetadata, classLoader);
return new InternalAggregationFunction(getSignature().getNameSuffix(), inputTypes, ImmutableList.of(intermediateType), valueType, true, false, factory);
}
use of io.prestosql.spi.function.OperatorType in project hetu-core by openlookeng.
the class RowExpressionVerifier method visitComparisonExpression.
@Override
protected Boolean visitComparisonExpression(ComparisonExpression expected, RowExpression actual) {
if (actual instanceof CallExpression) {
FunctionMetadata functionMetadata = metadata.getFunctionAndTypeManager().getFunctionMetadata(((CallExpression) actual).getFunctionHandle());
if (!functionMetadata.getOperatorType().isPresent() || !functionMetadata.getOperatorType().get().isComparisonOperator()) {
return false;
}
OperatorType actualOperatorType = functionMetadata.getOperatorType().get();
OperatorType expectedOperatorType = getOperatorType(expected.getOperator());
if (expectedOperatorType.equals(actualOperatorType)) {
if (actualOperatorType == EQUAL) {
return (process(expected.getLeft(), ((CallExpression) actual).getArguments().get(0)) && process(expected.getRight(), ((CallExpression) actual).getArguments().get(1))) || (process(expected.getLeft(), ((CallExpression) actual).getArguments().get(1)) && process(expected.getRight(), ((CallExpression) actual).getArguments().get(0)));
}
// TODO support other comparison operators
return process(expected.getLeft(), ((CallExpression) actual).getArguments().get(0)) && process(expected.getRight(), ((CallExpression) actual).getArguments().get(1));
}
}
return false;
}
use of io.prestosql.spi.function.OperatorType in project hetu-core by openlookeng.
the class BaseJdbcRowExpressionConverter method handleOperator.
private String handleOperator(CallExpression call, FunctionMetadata functionMetadata, JdbcConverterContext context) {
FunctionHandle functionHandle = call.getFunctionHandle();
List<RowExpression> arguments = call.getArguments();
if (standardFunctionResolution.isCastFunction(functionHandle)) {
if (call.getType().getDisplayName().equals(LIKE_PATTERN_NAME)) {
return arguments.get(0).accept(this, context);
}
return format("CAST(%s AS %s)", arguments.get(0).accept(this, context), call.getType().getDisplayName());
}
if (call.getArguments().size() == 1 && standardFunctionResolution.isNegateFunction(functionHandle)) {
String value = call.getArguments().get(0).accept(this, context);
String separator = value.startsWith("-") ? " " : "";
return format("-%s%s", separator, value);
}
Optional<OperatorType> operatorTypeOptional = functionMetadata.getOperatorType();
if (operatorTypeOptional.isPresent() && arguments.size() == 2 && (standardFunctionResolution.isComparisonFunction(functionHandle) || standardFunctionResolution.isArithmeticFunction(functionHandle))) {
return format("(%s %s %s)", arguments.get(0).accept(this, context), operatorTypeOptional.get().getOperator(), arguments.get(1).accept(this, context));
}
if (standardFunctionResolution.isSubscriptFunction(functionHandle)) {
String base = call.getArguments().get(0).accept(this, context);
String index = call.getArguments().get(1).accept(this, context);
return format("%s[%s]", base, index);
}
throw new PrestoException(NOT_SUPPORTED, String.format("Unknown operator %s in push down", operatorTypeOptional));
}
use of io.prestosql.spi.function.OperatorType in project hetu-core by openlookeng.
the class SplitFiltering method isSupportedExpression.
private static boolean isSupportedExpression(RowExpression predicate) {
if (predicate instanceof SpecialForm) {
SpecialForm specialForm = (SpecialForm) predicate;
switch(specialForm.getForm()) {
case BETWEEN:
case IN:
return true;
case AND:
case OR:
return isSupportedExpression(specialForm.getArguments().get(0)) && isSupportedExpression(specialForm.getArguments().get(1));
default:
return false;
}
}
if (predicate instanceof CallExpression) {
CallExpression call = (CallExpression) predicate;
FunctionHandle builtInFunctionHandle = call.getFunctionHandle();
if (builtInFunctionHandle instanceof BuiltInFunctionHandle) {
Signature signature = ((BuiltInFunctionHandle) builtInFunctionHandle).getSignature();
if (signature.getName().getObjectName().equals("not")) {
return true;
}
try {
OperatorType operatorType = Signature.unmangleOperator(signature.getName().getObjectName());
if (operatorType.isComparisonOperator() && operatorType != IS_DISTINCT_FROM) {
return true;
}
return false;
} catch (IllegalArgumentException e) {
return false;
}
}
}
return false;
}
use of io.prestosql.spi.function.OperatorType in project hetu-core by openlookeng.
the class SplitFiltering method getAllColumns.
public static void getAllColumns(RowExpression expression, Set<String> columns, Map<Symbol, ColumnHandle> assignments) {
if (expression instanceof SpecialForm) {
SpecialForm specialForm = (SpecialForm) expression;
RowExpression left;
switch(specialForm.getForm()) {
case BETWEEN:
case IN:
left = extractExpression(specialForm.getArguments().get(0));
break;
case AND:
case OR:
getAllColumns(specialForm.getArguments().get(0), columns, assignments);
getAllColumns(specialForm.getArguments().get(1), columns, assignments);
return;
default:
return;
}
if (!(left instanceof VariableReferenceExpression)) {
LOG.warn("Invalid Left of expression %s, should be an VariableReferenceExpression", left.toString());
return;
}
String columnName = ((VariableReferenceExpression) left).getName();
Symbol columnSymbol = new Symbol(columnName);
if (assignments.containsKey(columnSymbol)) {
columnName = assignments.get(columnSymbol).getColumnName();
}
columns.add(columnName);
return;
}
if (expression instanceof CallExpression) {
CallExpression call = (CallExpression) expression;
try {
FunctionHandle builtInFunctionHandle = call.getFunctionHandle();
Signature signature;
if (builtInFunctionHandle instanceof BuiltInFunctionHandle) {
signature = ((BuiltInFunctionHandle) builtInFunctionHandle).getSignature();
} else {
return;
}
OperatorType operatorType = Signature.unmangleOperator(signature.getName().getObjectName());
if (!operatorType.isComparisonOperator()) {
return;
}
RowExpression left = extractExpression(call.getArguments().get(0));
if (!(left instanceof VariableReferenceExpression)) {
LOG.warn("Invalid Left of expression %s, should be an VariableReferenceExpression", left.toString());
return;
}
String columnName = ((VariableReferenceExpression) left).getName();
Symbol columnSymbol = new Symbol(columnName);
if (assignments.containsKey(columnSymbol)) {
columnName = assignments.get(columnSymbol).getColumnName();
}
columns.add(columnName);
return;
} catch (IllegalArgumentException e) {
return;
}
}
return;
}
Aggregations