Search in sources :

Example 16 with SqlArgument

use of io.confluent.ksql.schema.ksql.SqlArgument 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)

Example 17 with SqlArgument

use of io.confluent.ksql.schema.ksql.SqlArgument in project ksql by confluentinc.

the class UdafAggregateFunctionFactory method buildAllParams.

private List<SqlArgument> buildAllParams(final List<SqlArgument> argTypeList, final AggregateFunctionInitArguments initArgs) {
    if (initArgs.args().isEmpty()) {
        return argTypeList;
    }
    final List<SqlArgument> allParams = new ArrayList<>(argTypeList.size() + initArgs.args().size());
    allParams.addAll(argTypeList);
    for (final Object arg : initArgs.args()) {
        if (arg == null) {
            allParams.add(null);
            continue;
        }
        final SqlBaseType baseType = SchemaConverters.javaToSqlConverter().toSqlType(arg.getClass());
        try {
            // Only primitive types currently supported:
            final SqlPrimitiveType primitiveType = SqlPrimitiveType.of(baseType);
            allParams.add(SqlArgument.of(primitiveType));
        } catch (final Exception e) {
            throw new KsqlFunctionException("Only primitive init arguments are supported by UDAF " + getName() + ", but got " + arg, e);
        }
    }
    return allParams;
}
Also used : SqlArgument(io.confluent.ksql.schema.ksql.SqlArgument) SqlPrimitiveType(io.confluent.ksql.schema.ksql.types.SqlPrimitiveType) SqlBaseType(io.confluent.ksql.schema.ksql.types.SqlBaseType) ArrayList(java.util.ArrayList) KsqlException(io.confluent.ksql.util.KsqlException)

Example 18 with SqlArgument

use of io.confluent.ksql.schema.ksql.SqlArgument in project ksql by confluentinc.

the class FunctionArgumentsUtil method firstPassOverFunctionArguments.

private static List<SqlArgument> firstPassOverFunctionArguments(final List<Expression> arguments, final ExpressionTypeManager expressionTypeManager, final Map<String, SqlType> lambdaMapping) {
    final List<SqlArgument> functionArgumentTypes = new ArrayList<>();
    for (final Expression expression : arguments) {
        if (expression instanceof LambdaFunctionCall) {
            functionArgumentTypes.add(SqlArgument.of(SqlLambda.of(((LambdaFunctionCall) expression).getArguments().size())));
        } else {
            final SqlType resolvedArgType = expressionTypeManager.getExpressionSqlType(expression, new HashMap<>(lambdaMapping));
            functionArgumentTypes.add(SqlArgument.of(resolvedArgType));
        }
    }
    return functionArgumentTypes;
}
Also used : SqlArgument(io.confluent.ksql.schema.ksql.SqlArgument) Expression(io.confluent.ksql.execution.expression.tree.Expression) LambdaFunctionCall(io.confluent.ksql.execution.expression.tree.LambdaFunctionCall) ArrayList(java.util.ArrayList) SqlType(io.confluent.ksql.schema.ksql.types.SqlType)

Example 19 with SqlArgument

use of io.confluent.ksql.schema.ksql.SqlArgument in project ksql by confluentinc.

the class GenericsUtilTest method shouldFailToIdentifySqlLambdaResolvedWithDifferentSchema.

@Test
public void shouldFailToIdentifySqlLambdaResolvedWithDifferentSchema() {
    // Given:
    final GenericType typeA = GenericType.of("A");
    final GenericType typeB = GenericType.of("B");
    final GenericType typeC = GenericType.of("C");
    final LambdaType a = LambdaType.of(ImmutableList.of(typeA, typeC), typeB);
    final SqlArgument instance = SqlArgument.of(SqlLambdaResolved.of(ImmutableList.of(SqlTypes.DOUBLE), SqlTypes.BIGINT));
    // When:
    final Exception e = assertThrows(KsqlException.class, () -> GenericsUtil.reserveGenerics(a, instance));
    // Then:
    assertThat(e.getMessage(), containsString("Cannot infer generics for LAMBDA (A, C) => B from LAMBDA (DOUBLE) => BIGINT " + "because they do not have the same schema structure"));
}
Also used : LambdaType(io.confluent.ksql.function.types.LambdaType) GenericType(io.confluent.ksql.function.types.GenericType) SqlArgument(io.confluent.ksql.schema.ksql.SqlArgument) Test(org.junit.Test)

Example 20 with SqlArgument

use of io.confluent.ksql.schema.ksql.SqlArgument in project ksql by confluentinc.

the class GenericsUtilTest method shouldFailIdentifyMismatchStructureGeneric.

@Test(expected = KsqlException.class)
public void shouldFailIdentifyMismatchStructureGeneric() {
    // Given:
    final MapType a = MapType.of(GenericType.of("A"), GenericType.of("B"));
    final SqlArgument instance = SqlArgument.of(SqlTypes.array(SqlTypes.STRING));
    // When:
    GenericsUtil.reserveGenerics(a, instance);
}
Also used : SqlArgument(io.confluent.ksql.schema.ksql.SqlArgument) MapType(io.confluent.ksql.function.types.MapType) Test(org.junit.Test)

Aggregations

SqlArgument (io.confluent.ksql.schema.ksql.SqlArgument)21 Test (org.junit.Test)14 GenericType (io.confluent.ksql.function.types.GenericType)12 LambdaType (io.confluent.ksql.function.types.LambdaType)10 SqlType (io.confluent.ksql.schema.ksql.types.SqlType)10 HashMap (java.util.HashMap)7 MapType (io.confluent.ksql.function.types.MapType)4 KsqlException (io.confluent.ksql.util.KsqlException)4 Expression (io.confluent.ksql.execution.expression.tree.Expression)3 ParamType (io.confluent.ksql.function.types.ParamType)3 ArrayList (java.util.ArrayList)3 Optional (java.util.Optional)3 VisibleForTesting (com.google.common.annotations.VisibleForTesting)2 LambdaFunctionCall (io.confluent.ksql.execution.expression.tree.LambdaFunctionCall)2 UdfUtil (io.confluent.ksql.execution.function.UdfUtil)2 ParamTypes (io.confluent.ksql.function.types.ParamTypes)2 Udf (io.confluent.ksql.function.udf.Udf)2 UdfParameter (io.confluent.ksql.function.udf.UdfParameter)2 UdfSchemaProvider (io.confluent.ksql.function.udf.UdfSchemaProvider)2 SchemaConverters (io.confluent.ksql.schema.ksql.SchemaConverters)2