Search in sources :

Example 1 with OperatorType

use of io.trino.spi.function.OperatorType in project trino by trinodb.

the class GlobalFunctionCatalog method checkNotSpecializedTypeOperator.

/**
 * Type operators are handled automatically by the engine, so custom operator implementations
 * cannot be registered for these.
 */
private static void checkNotSpecializedTypeOperator(Signature signature) {
    String name = signature.getName();
    if (!isOperatorName(name)) {
        return;
    }
    OperatorType operatorType = unmangleOperator(name);
    // The trick here is the Generic*Operator implementations implement these exact signatures,
    // so we only these exact signatures to be registered.  Since, only a single function with
    // a specific signature can be registered, it prevents others from being registered.
    Type expectedReturnType;
    TypeVariableConstraint typeParameter;
    switch(operatorType) {
        case EQUAL:
        case IS_DISTINCT_FROM:
        case INDETERMINATE:
            expectedReturnType = BOOLEAN;
            typeParameter = comparableTypeParameter("T");
            break;
        case HASH_CODE:
        case XX_HASH_64:
            expectedReturnType = BIGINT;
            typeParameter = comparableTypeParameter("T");
            break;
        case COMPARISON_UNORDERED_FIRST:
        case COMPARISON_UNORDERED_LAST:
            expectedReturnType = INTEGER;
            typeParameter = orderableTypeParameter("T");
            break;
        case LESS_THAN:
        case LESS_THAN_OR_EQUAL:
            expectedReturnType = BOOLEAN;
            typeParameter = orderableTypeParameter("T");
            break;
        default:
            return;
    }
    Signature expectedSignature = new Signature(signature.getName(), ImmutableList.of(typeParameter), ImmutableList.of(), expectedReturnType.getTypeSignature(), Collections.nCopies(operatorType.getArgumentCount(), new TypeSignature("T")), false);
    checkArgument(signature.equals(expectedSignature), "Can not register %s functionMetadata: %s", operatorType, signature);
}
Also used : Type(io.trino.spi.type.Type) OperatorType(io.trino.spi.function.OperatorType) TypeSignature(io.trino.spi.type.TypeSignature) TypeSignature(io.trino.spi.type.TypeSignature) OperatorType(io.trino.spi.function.OperatorType)

Example 2 with OperatorType

use of io.trino.spi.function.OperatorType in project trino by trinodb.

the class MinMaxCompare method getMinMaxCompare.

public static MethodHandle getMinMaxCompare(FunctionDependencies dependencies, Type type, InvocationConvention convention, boolean min) {
    OperatorType comparisonOperator = getMinMaxCompareOperatorType(min);
    MethodHandle handle = dependencies.getOperatorInvoker(comparisonOperator, List.of(type, type), convention).getMethodHandle();
    return comparisonToMinMaxResult(min, handle);
}
Also used : OperatorType(io.trino.spi.function.OperatorType) MethodHandle(java.lang.invoke.MethodHandle)

Example 3 with OperatorType

use of io.trino.spi.function.OperatorType in project trino by trinodb.

the class TestGlobalFunctionCatalog method testExactMatchBeforeCoercion.

@Test
public void testExactMatchBeforeCoercion() {
    TestingFunctionResolution functionResolution = new TestingFunctionResolution();
    Metadata metadata = functionResolution.getMetadata();
    boolean foundOperator = false;
    for (FunctionMetadata function : listOperators(metadata)) {
        OperatorType operatorType = unmangleOperator(function.getSignature().getName());
        if (operatorType == OperatorType.CAST || operatorType == OperatorType.SATURATED_FLOOR_CAST) {
            continue;
        }
        if (!function.getSignature().getTypeVariableConstraints().isEmpty()) {
            continue;
        }
        if (function.getSignature().getArgumentTypes().stream().anyMatch(TypeSignature::isCalculated)) {
            continue;
        }
        List<Type> argumentTypes = function.getSignature().getArgumentTypes().stream().map(functionResolution.getPlannerContext().getTypeManager()::getType).collect(toImmutableList());
        BoundSignature exactOperator = functionResolution.resolveOperator(operatorType, argumentTypes).getSignature();
        assertEquals(exactOperator.toSignature(), function.getSignature());
        foundOperator = true;
    }
    assertTrue(foundOperator);
}
Also used : TypeSignatureTranslator.parseTypeSignature(io.trino.sql.analyzer.TypeSignatureTranslator.parseTypeSignature) TypeSignature(io.trino.spi.type.TypeSignature) Type(io.trino.spi.type.Type) SqlType(io.trino.spi.function.SqlType) DecimalType.createDecimalType(io.trino.spi.type.DecimalType.createDecimalType) ArrayType(io.trino.spi.type.ArrayType) OperatorType(io.trino.spi.function.OperatorType) UnknownType(io.trino.type.UnknownType) OperatorType(io.trino.spi.function.OperatorType) Test(org.testng.annotations.Test)

Example 4 with OperatorType

use of io.trino.spi.function.OperatorType in project trino by trinodb.

the class TypeRegistry method verifyTypes.

public void verifyTypes() {
    Set<Type> missingOperatorDeclaration = new HashSet<>();
    Multimap<Type, OperatorType> missingOperators = HashMultimap.create();
    for (Type type : ImmutableList.copyOf(types.values())) {
        if (type.getTypeOperatorDeclaration(typeOperators) == null) {
            missingOperatorDeclaration.add(type);
            continue;
        }
        if (type.isComparable()) {
            if (!hasEqualMethod(type)) {
                missingOperators.put(type, EQUAL);
            }
            if (!hasHashCodeMethod(type)) {
                missingOperators.put(type, HASH_CODE);
            }
            if (!hasXxHash64Method(type)) {
                missingOperators.put(type, XX_HASH_64);
            }
            if (!hasDistinctFromMethod(type)) {
                missingOperators.put(type, IS_DISTINCT_FROM);
            }
            if (!hasIndeterminateMethod(type)) {
                missingOperators.put(type, INDETERMINATE);
            }
        }
        if (type.isOrderable()) {
            if (!hasComparisonUnorderedLastMethod(type)) {
                missingOperators.put(type, COMPARISON_UNORDERED_LAST);
            }
            if (!hasComparisonUnorderedFirstMethod(type)) {
                missingOperators.put(type, COMPARISON_UNORDERED_FIRST);
            }
            if (!hasLessThanMethod(type)) {
                missingOperators.put(type, LESS_THAN);
            }
            if (!hasLessThanOrEqualMethod(type)) {
                missingOperators.put(type, LESS_THAN_OR_EQUAL);
            }
        }
    }
    // TODO: verify the parametric types too
    if (!missingOperators.isEmpty()) {
        List<String> messages = new ArrayList<>();
        for (Type type : missingOperatorDeclaration) {
            messages.add(format("%s types operators is null", type));
        }
        for (Type type : missingOperators.keySet()) {
            messages.add(format("%s missing for %s", missingOperators.get(type), type));
        }
        throw new IllegalStateException(Joiner.on(", ").join(messages));
    }
}
Also used : DecimalParametricType(io.trino.type.DecimalParametricType) VarcharParametricType(io.trino.type.VarcharParametricType) Re2JRegexpType(io.trino.type.Re2JRegexpType) ParametricType(io.trino.spi.type.ParametricType) Type(io.trino.spi.type.Type) CharParametricType(io.trino.type.CharParametricType) OperatorType(io.trino.spi.function.OperatorType) ArrayList(java.util.ArrayList) OperatorType(io.trino.spi.function.OperatorType) HashSet(java.util.HashSet)

Example 5 with OperatorType

use of io.trino.spi.function.OperatorType in project trino by trinodb.

the class FunctionsParserHelper method createTypeVariableConstraints.

public static List<TypeVariableConstraint> createTypeVariableConstraints(Collection<TypeParameter> typeParameters, List<ImplementationDependency> dependencies) {
    Set<String> typeParameterNames = typeParameters.stream().map(TypeParameter::value).collect(toImmutableSortedSet(CASE_INSENSITIVE_ORDER));
    Set<String> orderableRequired = new TreeSet<>(CASE_INSENSITIVE_ORDER);
    Set<String> comparableRequired = new TreeSet<>(CASE_INSENSITIVE_ORDER);
    HashMultimap<String, String> castableTo = HashMultimap.create();
    HashMultimap<String, String> castableFrom = HashMultimap.create();
    for (ImplementationDependency dependency : dependencies) {
        if (dependency instanceof OperatorImplementationDependency) {
            OperatorImplementationDependency operatorDependency = (OperatorImplementationDependency) dependency;
            OperatorType operator = operatorDependency.getOperator();
            List<TypeSignature> argumentTypes = operatorDependency.getArgumentTypes();
            if (COMPARABLE_TYPE_OPERATORS.contains(operator)) {
                verifyOperatorSignature(operator, argumentTypes);
                TypeSignature typeSignature = argumentTypes.get(0);
                if (typeParameterNames.contains(typeSignature.getBase())) {
                    comparableRequired.add(typeSignature.toString());
                } else {
                    verifyTypeSignatureDoesNotContainAnyTypeParameters(typeSignature, typeSignature, typeParameterNames);
                }
            } else if (ORDERABLE_TYPE_OPERATORS.contains(operator)) {
                verifyOperatorSignature(operator, argumentTypes);
                TypeSignature typeSignature = argumentTypes.get(0);
                if (typeParameterNames.contains(typeSignature.getBase())) {
                    orderableRequired.add(typeSignature.toString());
                } else {
                    verifyTypeSignatureDoesNotContainAnyTypeParameters(typeSignature, typeSignature, typeParameterNames);
                }
            } else {
                throw new IllegalArgumentException("Operator dependency on " + operator + " is not allowed");
            }
        } else if (dependency instanceof CastImplementationDependency) {
            CastImplementationDependency castImplementationDependency = (CastImplementationDependency) dependency;
            TypeSignature fromType = castImplementationDependency.getFromType();
            TypeSignature toType = castImplementationDependency.getToType();
            if (typeParameterNames.contains(fromType.getBase())) {
                // fromType is a type parameter, so it must be castable to the toType, which might also be a type parameter
                castableTo.put(fromType.toString().toLowerCase(Locale.ENGLISH), toType.toString());
            } else if (typeParameterNames.contains(toType.getBase())) {
                // toType is a type parameter, so it must be castable from the toType, which is not a type parameter
                castableFrom.put(toType.toString().toLowerCase(Locale.ENGLISH), fromType.toString());
            } else {
                verifyTypeSignatureDoesNotContainAnyTypeParameters(fromType, fromType, typeParameterNames);
                verifyTypeSignatureDoesNotContainAnyTypeParameters(toType, toType, typeParameterNames);
            }
        }
    }
    ImmutableList.Builder<TypeVariableConstraint> typeVariableConstraints = ImmutableList.builder();
    for (String name : typeParameterNames) {
        typeVariableConstraints.add(new TypeVariableConstraint(name, comparableRequired.contains(name), orderableRequired.contains(name), null, castableTo.get(name).stream().map(type -> parseTypeSignature(type, typeParameterNames)).collect(toImmutableSet()), castableFrom.get(name).stream().map(type -> parseTypeSignature(type, typeParameterNames)).collect(toImmutableSet())));
    }
    return typeVariableConstraints.build();
}
Also used : TypeParameterSpecialization(io.trino.spi.function.TypeParameterSpecialization) Arrays(java.util.Arrays) Description(io.trino.spi.function.Description) TypeSignatureTranslator.parseTypeSignature(io.trino.sql.analyzer.TypeSignatureTranslator.parseTypeSignature) Constraint(io.trino.type.Constraint) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) HashMultimap(com.google.common.collect.HashMultimap) Locale(java.util.Locale) Map(java.util.Map) LongVariableConstraint(io.trino.metadata.LongVariableConstraint) EQUAL(io.trino.spi.function.OperatorType.EQUAL) Method(java.lang.reflect.Method) COMPARISON_UNORDERED_LAST(io.trino.spi.function.OperatorType.COMPARISON_UNORDERED_LAST) TypeSignature(io.trino.spi.type.TypeSignature) ImmutableSortedSet.toImmutableSortedSet(com.google.common.collect.ImmutableSortedSet.toImmutableSortedSet) INDETERMINATE(io.trino.spi.function.OperatorType.INDETERMINATE) ImmutableSet(com.google.common.collect.ImmutableSet) IsNull(io.trino.spi.function.IsNull) Predicate(java.util.function.Predicate) Collection(java.util.Collection) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) Set(java.util.Set) List(java.util.List) Stream(java.util.stream.Stream) Modifier(java.lang.reflect.Modifier) Annotation(java.lang.annotation.Annotation) Optional(java.util.Optional) ImplementationDependency.isImplementationDependencyAnnotation(io.trino.operator.annotations.ImplementationDependency.isImplementationDependencyAnnotation) TypeSignatureParameter(io.trino.spi.type.TypeSignatureParameter) AnnotatedElement(java.lang.reflect.AnnotatedElement) SqlNullable(io.trino.spi.function.SqlNullable) CASE_INSENSITIVE_ORDER(java.lang.String.CASE_INSENSITIVE_ORDER) HashMap(java.util.HashMap) LiteralParameters(io.trino.spi.function.LiteralParameters) Constructor(java.lang.reflect.Constructor) TreeSet(java.util.TreeSet) IS_DISTINCT_FROM(io.trino.spi.function.OperatorType.IS_DISTINCT_FROM) ImmutableList(com.google.common.collect.ImmutableList) SqlType(io.trino.spi.function.SqlType) LESS_THAN_OR_EQUAL(io.trino.spi.function.OperatorType.LESS_THAN_OR_EQUAL) ImmutableSet.toImmutableSet(com.google.common.collect.ImmutableSet.toImmutableSet) Signature(io.trino.metadata.Signature) XX_HASH_64(io.trino.spi.function.OperatorType.XX_HASH_64) Nullable(javax.annotation.Nullable) TypeVariableConstraint(io.trino.metadata.TypeVariableConstraint) OperatorType(io.trino.spi.function.OperatorType) HASH_CODE(io.trino.spi.function.OperatorType.HASH_CODE) COMPARISON_UNORDERED_FIRST(io.trino.spi.function.OperatorType.COMPARISON_UNORDERED_FIRST) TypeParameter(io.trino.spi.function.TypeParameter) LESS_THAN(io.trino.spi.function.OperatorType.LESS_THAN) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) ImmutableList(com.google.common.collect.ImmutableList) OperatorType(io.trino.spi.function.OperatorType) TypeVariableConstraint(io.trino.metadata.TypeVariableConstraint) TypeSignatureTranslator.parseTypeSignature(io.trino.sql.analyzer.TypeSignatureTranslator.parseTypeSignature) TypeSignature(io.trino.spi.type.TypeSignature) TreeSet(java.util.TreeSet)

Aggregations

OperatorType (io.trino.spi.function.OperatorType)5 Type (io.trino.spi.type.Type)3 TypeSignature (io.trino.spi.type.TypeSignature)3 SqlType (io.trino.spi.function.SqlType)2 TypeSignatureTranslator.parseTypeSignature (io.trino.sql.analyzer.TypeSignatureTranslator.parseTypeSignature)2 Preconditions.checkArgument (com.google.common.base.Preconditions.checkArgument)1 HashMultimap (com.google.common.collect.HashMultimap)1 ImmutableList (com.google.common.collect.ImmutableList)1 ImmutableList.toImmutableList (com.google.common.collect.ImmutableList.toImmutableList)1 ImmutableSet (com.google.common.collect.ImmutableSet)1 ImmutableSet.toImmutableSet (com.google.common.collect.ImmutableSet.toImmutableSet)1 ImmutableSortedSet.toImmutableSortedSet (com.google.common.collect.ImmutableSortedSet.toImmutableSortedSet)1 LongVariableConstraint (io.trino.metadata.LongVariableConstraint)1 Signature (io.trino.metadata.Signature)1 TypeVariableConstraint (io.trino.metadata.TypeVariableConstraint)1 ImplementationDependency.isImplementationDependencyAnnotation (io.trino.operator.annotations.ImplementationDependency.isImplementationDependencyAnnotation)1 Description (io.trino.spi.function.Description)1 IsNull (io.trino.spi.function.IsNull)1 LiteralParameters (io.trino.spi.function.LiteralParameters)1 COMPARISON_UNORDERED_FIRST (io.trino.spi.function.OperatorType.COMPARISON_UNORDERED_FIRST)1