Search in sources :

Example 21 with ParamType

use of io.confluent.ksql.function.types.ParamType in project ksql by confluentinc.

the class UdfIndex method addFunction.

void addFunction(final T function) {
    final List<ParamType> parameters = function.parameters();
    if (allFunctions.put(parameters, function) != null) {
        throw new KsqlFunctionException("Can't add function " + function.name() + " with parameters " + function.parameters() + " as a function with the same name and parameter types already exists " + allFunctions.get(parameters));
    }
    Node curr = root;
    Node parent = curr;
    for (final ParamType parameter : parameters) {
        final Parameter param = new Parameter(parameter, false);
        parent = curr;
        curr = curr.children.computeIfAbsent(param, ignored -> new Node());
    }
    if (function.isVariadic()) {
        // first add the function to the parent to address the
        // case of empty varargs
        parent.update(function);
        // then add a new child node with the parameter value type
        // and add this function to that node
        final ParamType varargSchema = Iterables.getLast(parameters);
        final Parameter vararg = new Parameter(varargSchema, true);
        final Node leaf = parent.children.computeIfAbsent(vararg, ignored -> new Node());
        leaf.update(function);
        // add a self referential loop for varargs so that we can
        // add as many of the same param at the end and still retrieve
        // this node
        leaf.children.putIfAbsent(vararg, leaf);
    }
    curr.update(function);
}
Also used : Iterables(com.google.common.collect.Iterables) FormatOptions(io.confluent.ksql.schema.utils.FormatOptions) Logger(org.slf4j.Logger) ParamType(io.confluent.ksql.function.types.ParamType) SqlArgument(io.confluent.ksql.schema.ksql.SqlArgument) ParamTypes(io.confluent.ksql.function.types.ParamTypes) Collection(java.util.Collection) LoggerFactory(org.slf4j.LoggerFactory) HashMap(java.util.HashMap) Collectors(java.util.stream.Collectors) StringUtils(org.apache.commons.lang3.StringUtils) ArrayList(java.util.ArrayList) Objects(java.util.Objects) List(java.util.List) Map(java.util.Map) ArrayType(io.confluent.ksql.function.types.ArrayType) Entry(java.util.Map.Entry) KsqlException(io.confluent.ksql.util.KsqlException) Optional(java.util.Optional) VisibleForTesting(com.google.common.annotations.VisibleForTesting) SqlType(io.confluent.ksql.schema.ksql.types.SqlType) Comparator(java.util.Comparator) GenericType(io.confluent.ksql.function.types.GenericType) ParamType(io.confluent.ksql.function.types.ParamType)

Example 22 with ParamType

use of io.confluent.ksql.function.types.ParamType in project ksql by confluentinc.

the class GenericsUtilTest method shouldFindNoConstituentGenerics.

@Test
public void shouldFindNoConstituentGenerics() {
    // Given:
    final StructType struct = StructType.builder().field("a", ParamTypes.LONG).field("b", ParamTypes.DECIMAL).build();
    // When:
    final Set<ParamType> generics = GenericsUtil.constituentGenerics(struct);
    // Then:
    assertThat(generics, empty());
}
Also used : StructType(io.confluent.ksql.function.types.StructType) ParamType(io.confluent.ksql.function.types.ParamType) Test(org.junit.Test)

Example 23 with ParamType

use of io.confluent.ksql.function.types.ParamType in project ksql by confluentinc.

the class GenericsUtilTest method shouldFindAllConstituentGenericsInLambdaType.

@Test
public void shouldFindAllConstituentGenericsInLambdaType() {
    // Given:
    final GenericType a = GenericType.of("A");
    final GenericType b = GenericType.of("B");
    final GenericType c = GenericType.of("C");
    final GenericType d = GenericType.of("D");
    final ParamType lambda = LambdaType.of(ImmutableList.of(GenericType.of("C"), GenericType.of("A"), GenericType.of("B")), GenericType.of("D"));
    // When:
    final Set<ParamType> generics = GenericsUtil.constituentGenerics(lambda);
    // Then:
    assertThat(generics, containsInAnyOrder(a, b, c, d));
}
Also used : GenericType(io.confluent.ksql.function.types.GenericType) ParamType(io.confluent.ksql.function.types.ParamType) Test(org.junit.Test)

Example 24 with ParamType

use of io.confluent.ksql.function.types.ParamType in project ksql by confluentinc.

the class GenericsUtilTest method shouldResolveMapSchemaWithMapping.

@Test
public void shouldResolveMapSchemaWithMapping() {
    // Given:
    final GenericType a = GenericType.of("A");
    final GenericType b = GenericType.of("B");
    final ParamType map = MapType.of(a, b);
    final ImmutableMap<GenericType, SqlType> mapping = ImmutableMap.of(a, SqlTypes.INTEGER, b, SqlTypes.DOUBLE);
    // When:
    final SqlType resolved = GenericsUtil.applyResolved(map, mapping);
    // Then:
    assertThat(resolved, is(SqlTypes.map(SqlTypes.INTEGER, SqlTypes.DOUBLE)));
}
Also used : GenericType(io.confluent.ksql.function.types.GenericType) SqlType(io.confluent.ksql.schema.ksql.types.SqlType) ParamType(io.confluent.ksql.function.types.ParamType) Test(org.junit.Test)

Example 25 with ParamType

use of io.confluent.ksql.function.types.ParamType in project ksql by confluentinc.

the class FunctionLoaderUtils method handleUdfReturnSchema.

// CHECKSTYLE_RULES.OFF: CyclomaticComplexity
static SchemaProvider handleUdfReturnSchema(final Class theClass, final ParamType javaReturnSchema, final String annotationSchema, final SqlTypeParser parser, final String schemaProviderFunctionName, final String functionName, final boolean isVariadic) {
    // CHECKSTYLE_RULES.ON: CyclomaticComplexity
    final Function<List<SqlArgument>, SqlType> schemaProvider;
    if (!Udf.NO_SCHEMA_PROVIDER.equals(schemaProviderFunctionName)) {
        schemaProvider = handleUdfSchemaProviderAnnotation(schemaProviderFunctionName, theClass, functionName);
    } else if (!Udf.NO_SCHEMA.equals(annotationSchema)) {
        final SqlType sqlType = parser.parse(annotationSchema).getSqlType();
        schemaProvider = args -> sqlType;
    } else if (!GenericsUtil.hasGenerics(javaReturnSchema)) {
        // it is important to do this eagerly and not in the lambda so that
        // we can fail early (when loading the UDF) instead of when the user
        // attempts to use the UDF
        final SqlType sqlType = fromJavaType(javaReturnSchema, functionName);
        schemaProvider = args -> sqlType;
    } else {
        schemaProvider = null;
    }
    return (parameters, arguments) -> {
        if (schemaProvider != null) {
            final SqlType returnType = schemaProvider.apply(arguments);
            if (!(ParamTypes.areCompatible(SqlArgument.of(returnType), javaReturnSchema, false))) {
                throw new KsqlException(String.format("Return type %s of UDF %s does not match the declared " + "return type %s.", returnType, functionName.toUpperCase(), SchemaConverters.functionToSqlConverter().toSqlType(javaReturnSchema)));
            }
            return returnType;
        }
        final Map<GenericType, SqlType> genericMapping = new HashMap<>();
        for (int i = 0; i < Math.min(parameters.size(), arguments.size()); i++) {
            final ParamType schema = parameters.get(i);
            if (schema instanceof LambdaType) {
                if (isVariadic && i == parameters.size() - 1) {
                    throw new KsqlException(String.format("Lambda function %s cannot be variadic.", arguments.get(i).toString()));
                }
                genericMapping.putAll(GenericsUtil.reserveGenerics(schema, arguments.get(i)));
            } else {
                // we resolve any variadic as if it were an array so that the type
                // structure matches the input type
                final SqlType instance = isVariadic && i == parameters.size() - 1 ? SqlTypes.array(arguments.get(i).getSqlTypeOrThrow()) : arguments.get(i).getSqlTypeOrThrow();
                genericMapping.putAll(GenericsUtil.reserveGenerics(schema, SqlArgument.of(instance)));
            }
        }
        return GenericsUtil.applyResolved(javaReturnSchema, genericMapping);
    };
}
Also used : IntStream(java.util.stream.IntStream) Arrays(java.util.Arrays) UdfParameter(io.confluent.ksql.function.udf.UdfParameter) ParamType(io.confluent.ksql.function.types.ParamType) HashMap(java.util.HashMap) Function(java.util.function.Function) UdfUtil(io.confluent.ksql.execution.function.UdfUtil) Parameter(java.lang.reflect.Parameter) Map(java.util.Map) SqlTypeParser(io.confluent.ksql.schema.ksql.SqlTypeParser) SchemaConverters(io.confluent.ksql.schema.ksql.SchemaConverters) SqlType(io.confluent.ksql.schema.ksql.types.SqlType) Method(java.lang.reflect.Method) Udf(io.confluent.ksql.function.udf.Udf) SqlArgument(io.confluent.ksql.schema.ksql.SqlArgument) ParamTypes(io.confluent.ksql.function.types.ParamTypes) Collectors(java.util.stream.Collectors) InvocationTargetException(java.lang.reflect.InvocationTargetException) LambdaType(io.confluent.ksql.function.types.LambdaType) List(java.util.List) Type(java.lang.reflect.Type) UdfSchemaProvider(io.confluent.ksql.function.udf.UdfSchemaProvider) KsqlException(io.confluent.ksql.util.KsqlException) Optional(java.util.Optional) VisibleForTesting(com.google.common.annotations.VisibleForTesting) SqlTypes(io.confluent.ksql.schema.ksql.types.SqlTypes) GenericType(io.confluent.ksql.function.types.GenericType) LambdaType(io.confluent.ksql.function.types.LambdaType) List(java.util.List) SqlType(io.confluent.ksql.schema.ksql.types.SqlType) KsqlException(io.confluent.ksql.util.KsqlException) HashMap(java.util.HashMap) Map(java.util.Map) ParamType(io.confluent.ksql.function.types.ParamType)

Aggregations

ParamType (io.confluent.ksql.function.types.ParamType)35 GenericType (io.confluent.ksql.function.types.GenericType)26 Test (org.junit.Test)22 LambdaType (io.confluent.ksql.function.types.LambdaType)20 StructType (io.confluent.ksql.function.types.StructType)20 ArrayType (io.confluent.ksql.function.types.ArrayType)19 Type (java.lang.reflect.Type)19 MapType (io.confluent.ksql.function.types.MapType)18 SqlType (io.confluent.ksql.schema.ksql.types.SqlType)11 HashMap (java.util.HashMap)5 KsqlException (io.confluent.ksql.util.KsqlException)4 ParameterizedType (java.lang.reflect.ParameterizedType)4 ArrayList (java.util.ArrayList)4 GenericArrayType (java.lang.reflect.GenericArrayType)3 TypeVariable (java.lang.reflect.TypeVariable)3 VisibleForTesting (com.google.common.annotations.VisibleForTesting)2 Expression (io.confluent.ksql.execution.expression.tree.Expression)2 KsqlScalarFunction (io.confluent.ksql.function.KsqlScalarFunction)2 ParamTypes (io.confluent.ksql.function.types.ParamTypes)2 Kudf (io.confluent.ksql.function.udf.Kudf)2