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);
};
}
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;
}
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;
}
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"));
}
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);
}
Aggregations