Search in sources :

Example 11 with OperatorType

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);
}
Also used : DynamicClassLoader(io.airlift.bytecode.DynamicClassLoader) AccumulatorStateDescriptor(io.prestosql.operator.aggregation.AggregationMetadata.AccumulatorStateDescriptor) GenericAccumulatorFactoryBinder(io.prestosql.operator.aggregation.GenericAccumulatorFactoryBinder) ClassDefinition(io.airlift.bytecode.ClassDefinition) InternalAggregationFunction(io.prestosql.operator.aggregation.InternalAggregationFunction) OperatorType(io.prestosql.spi.function.OperatorType) ArrayType(io.prestosql.spi.type.ArrayType) SqlTypeBytecodeExpression.constantType(io.prestosql.sql.gen.SqlTypeBytecodeExpression.constantType) OperatorType(io.prestosql.spi.function.OperatorType) Type(io.prestosql.spi.type.Type) ArrayType(io.prestosql.spi.type.ArrayType) CallSiteBinder(io.prestosql.sql.gen.CallSiteBinder) AggregationMetadata(io.prestosql.operator.aggregation.AggregationMetadata) MethodHandle(java.lang.invoke.MethodHandle)

Example 12 with OperatorType

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;
}
Also used : FunctionMetadata(io.prestosql.spi.function.FunctionMetadata) CallExpression(io.prestosql.spi.relation.CallExpression) OperatorType(io.prestosql.spi.function.OperatorType)

Example 13 with OperatorType

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));
}
Also used : RowExpression(io.prestosql.spi.relation.RowExpression) PrestoException(io.prestosql.spi.PrestoException) FunctionHandle(io.prestosql.spi.function.FunctionHandle) OperatorType(io.prestosql.spi.function.OperatorType)

Example 14 with OperatorType

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;
}
Also used : Signature(io.prestosql.spi.function.Signature) BuiltInFunctionHandle(io.prestosql.spi.function.BuiltInFunctionHandle) CallExpression(io.prestosql.spi.relation.CallExpression) BuiltInFunctionHandle(io.prestosql.spi.function.BuiltInFunctionHandle) FunctionHandle(io.prestosql.spi.function.FunctionHandle) SpecialForm(io.prestosql.spi.relation.SpecialForm) OperatorType(io.prestosql.spi.function.OperatorType)

Example 15 with OperatorType

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;
}
Also used : VariableReferenceExpression(io.prestosql.spi.relation.VariableReferenceExpression) SerializationUtils.deserializeStripeSymbol(io.prestosql.spi.heuristicindex.SerializationUtils.deserializeStripeSymbol) Symbol(io.prestosql.spi.plan.Symbol) Signature(io.prestosql.spi.function.Signature) RowExpression(io.prestosql.spi.relation.RowExpression) BuiltInFunctionHandle(io.prestosql.spi.function.BuiltInFunctionHandle) CallExpression(io.prestosql.spi.relation.CallExpression) BuiltInFunctionHandle(io.prestosql.spi.function.BuiltInFunctionHandle) FunctionHandle(io.prestosql.spi.function.FunctionHandle) SpecialForm(io.prestosql.spi.relation.SpecialForm) OperatorType(io.prestosql.spi.function.OperatorType)

Aggregations

OperatorType (io.prestosql.spi.function.OperatorType)28 CallExpression (io.prestosql.spi.relation.CallExpression)11 PrestoException (io.prestosql.spi.PrestoException)10 Signature (io.prestosql.spi.function.Signature)9 ImmutableList (com.google.common.collect.ImmutableList)8 FunctionMetadata (io.prestosql.spi.function.FunctionMetadata)8 TypeSignature (io.prestosql.spi.type.TypeSignature)8 TypeSignature.parseTypeSignature (io.prestosql.spi.type.TypeSignature.parseTypeSignature)8 List (java.util.List)8 BuiltInFunctionHandle (io.prestosql.spi.function.BuiltInFunctionHandle)7 RowExpression (io.prestosql.spi.relation.RowExpression)7 FunctionHandle (io.prestosql.spi.function.FunctionHandle)6 Slice (io.airlift.slice.Slice)5 SqlType (io.prestosql.spi.function.SqlType)5 SpecialForm (io.prestosql.spi.relation.SpecialForm)5 Type (io.prestosql.spi.type.Type)5 Objects.requireNonNull (java.util.Objects.requireNonNull)5 ImmutableSet (com.google.common.collect.ImmutableSet)4 SqlScalarFunction (io.prestosql.metadata.SqlScalarFunction)4 UsedByGeneratedCode (io.prestosql.spi.annotation.UsedByGeneratedCode)4