Search in sources :

Example 1 with FunctionTypeInfo

use of io.confluent.ksql.execution.util.FunctionArgumentsUtil.FunctionTypeInfo in project ksql by confluentinc.

the class TermCompiler method visitFunctionCall.

@Override
public Term visitFunctionCall(final FunctionCall node, final Context context) {
    final UdfFactory udfFactory = functionRegistry.getUdfFactory(node.getName());
    final FunctionTypeInfo argumentsAndContext = FunctionArgumentsUtil.getFunctionTypeInfo(expressionTypeManager, node, udfFactory, context.getLambdaSqlTypeMapping());
    final List<ArgumentInfo> argumentInfos = argumentsAndContext.getArgumentInfos();
    final KsqlScalarFunction function = argumentsAndContext.getFunction();
    final SqlType functionReturnSchema = argumentsAndContext.getReturnType();
    final Class<?> javaClass = SchemaConverters.sqlToJavaConverter().toJavaType(functionReturnSchema);
    final List<Expression> arguments = node.getArguments();
    final List<Term> args = new ArrayList<>();
    for (int i = 0; i < arguments.size(); i++) {
        final Expression arg = arguments.get(i);
        // lambda arguments and null values are considered to have null type
        final SqlType sqlType = argumentInfos.get(i).getSqlArgument().getSqlType().orElse(null);
        ;
        final ParamType paramType;
        if (i >= function.parameters().size() - 1 && function.isVariadic()) {
            paramType = ((ArrayType) Iterables.getLast(function.parameters())).element();
        } else {
            paramType = function.parameters().get(i);
        }
        // This will attempt to cast to the expected argument type and will throw an error if
        // it cannot be done.
        final Term argTerm = process(convertArgument(arg, sqlType, paramType), new Context(argumentInfos.get(i).getLambdaSqlTypeMapping()));
        args.add(argTerm);
    }
    final Kudf kudf = function.newInstance(ksqlConfig);
    return new FunctionCallTerm(kudf, args, javaClass, functionReturnSchema);
}
Also used : Context(io.confluent.ksql.execution.interpreter.TermCompiler.Context) ArrayList(java.util.ArrayList) UdfFactory(io.confluent.ksql.function.UdfFactory) Term(io.confluent.ksql.execution.interpreter.terms.Term) LambdaFunction3Term(io.confluent.ksql.execution.interpreter.terms.LambdaFunctionTerms.LambdaFunction3Term) ColumnReferenceTerm(io.confluent.ksql.execution.interpreter.terms.ColumnReferenceTerm) LambdaFunction1Term(io.confluent.ksql.execution.interpreter.terms.LambdaFunctionTerms.LambdaFunction1Term) LikeTerm(io.confluent.ksql.execution.interpreter.terms.LikeTerm) FunctionCallTerm(io.confluent.ksql.execution.interpreter.terms.FunctionCallTerm) SearchedCaseTerm(io.confluent.ksql.execution.interpreter.terms.SearchedCaseTerm) StructTerm(io.confluent.ksql.execution.interpreter.terms.StructTerm) LambdaVariableTerm(io.confluent.ksql.execution.interpreter.terms.LambdaVariableTerm) CreateMapTerm(io.confluent.ksql.execution.interpreter.terms.CreateMapTerm) LambdaFunction2Term(io.confluent.ksql.execution.interpreter.terms.LambdaFunctionTerms.LambdaFunction2Term) SubscriptTerm(io.confluent.ksql.execution.interpreter.terms.SubscriptTerm) NotTerm(io.confluent.ksql.execution.interpreter.terms.NotTerm) IsNullTerm(io.confluent.ksql.execution.interpreter.terms.IsNullTerm) CreateArrayTerm(io.confluent.ksql.execution.interpreter.terms.CreateArrayTerm) DereferenceTerm(io.confluent.ksql.execution.interpreter.terms.DereferenceTerm) IsNotNullTerm(io.confluent.ksql.execution.interpreter.terms.IsNotNullTerm) InPredicateTerm(io.confluent.ksql.execution.interpreter.terms.InPredicateTerm) ParamType(io.confluent.ksql.function.types.ParamType) Kudf(io.confluent.ksql.function.udf.Kudf) KsqlScalarFunction(io.confluent.ksql.function.KsqlScalarFunction) FunctionTypeInfo(io.confluent.ksql.execution.util.FunctionArgumentsUtil.FunctionTypeInfo) LogicalBinaryExpression(io.confluent.ksql.execution.expression.tree.LogicalBinaryExpression) Expression(io.confluent.ksql.execution.expression.tree.Expression) DereferenceExpression(io.confluent.ksql.execution.expression.tree.DereferenceExpression) ArithmeticUnaryExpression(io.confluent.ksql.execution.expression.tree.ArithmeticUnaryExpression) SimpleCaseExpression(io.confluent.ksql.execution.expression.tree.SimpleCaseExpression) InListExpression(io.confluent.ksql.execution.expression.tree.InListExpression) SearchedCaseExpression(io.confluent.ksql.execution.expression.tree.SearchedCaseExpression) ArithmeticBinaryExpression(io.confluent.ksql.execution.expression.tree.ArithmeticBinaryExpression) CreateMapExpression(io.confluent.ksql.execution.expression.tree.CreateMapExpression) CreateArrayExpression(io.confluent.ksql.execution.expression.tree.CreateArrayExpression) CreateStructExpression(io.confluent.ksql.execution.expression.tree.CreateStructExpression) NotExpression(io.confluent.ksql.execution.expression.tree.NotExpression) SubscriptExpression(io.confluent.ksql.execution.expression.tree.SubscriptExpression) ComparisonExpression(io.confluent.ksql.execution.expression.tree.ComparisonExpression) SqlType(io.confluent.ksql.schema.ksql.types.SqlType) FunctionCallTerm(io.confluent.ksql.execution.interpreter.terms.FunctionCallTerm) ArgumentInfo(io.confluent.ksql.execution.util.FunctionArgumentsUtil.ArgumentInfo)

Example 2 with FunctionTypeInfo

use of io.confluent.ksql.execution.util.FunctionArgumentsUtil.FunctionTypeInfo in project ksql by confluentinc.

the class FunctionArgumentsUtilTest method shouldResolveFunctionWithoutLambdas.

@Test
public void shouldResolveFunctionWithoutLambdas() {
    // Given:
    givenUdfWithNameAndReturnType("NoLambdas", SqlTypes.STRING);
    when(function.parameters()).thenReturn(ImmutableList.of(ParamTypes.STRING));
    final FunctionCall expression = new FunctionCall(FunctionName.of("NoLambdas"), ImmutableList.of(new StringLiteral("a")));
    // When:
    final FunctionTypeInfo argumentsAndContexts = FunctionArgumentsUtil.getFunctionTypeInfo(expressionTypeManager, expression, udfFactory, Collections.emptyMap());
    // Then:
    assertThat(argumentsAndContexts.getReturnType(), is(SqlTypes.STRING));
    assertThat(argumentsAndContexts.getArgumentInfos().size(), is(1));
    verify(udfFactory).getFunction(ImmutableList.of(SqlArgument.of(SqlTypes.STRING)));
    verify(function).getReturnType(ImmutableList.of(SqlArgument.of(SqlTypes.STRING)));
}
Also used : FunctionTypeInfo(io.confluent.ksql.execution.util.FunctionArgumentsUtil.FunctionTypeInfo) StringLiteral(io.confluent.ksql.execution.expression.tree.StringLiteral) LambdaFunctionCall(io.confluent.ksql.execution.expression.tree.LambdaFunctionCall) FunctionCall(io.confluent.ksql.execution.expression.tree.FunctionCall) Test(org.junit.Test)

Example 3 with FunctionTypeInfo

use of io.confluent.ksql.execution.util.FunctionArgumentsUtil.FunctionTypeInfo in project ksql by confluentinc.

the class FunctionArgumentsUtilTest method shouldResolveGenericsInLambdaFunction.

@Test
public void shouldResolveGenericsInLambdaFunction() {
    // Given:
    givenUdfWithNameAndReturnType("ComplexFunction", SqlTypes.DOUBLE);
    when(function.parameters()).thenReturn(ImmutableList.of(ArrayType.of(GenericType.of("X")), MapType.of(GenericType.of("K"), GenericType.of("V")), GenericType.of("Q"), LambdaType.of(ImmutableList.of(GenericType.of("K"), GenericType.of("V"), GenericType.of("Q")), GenericType.of("K")), LambdaType.of(ImmutableList.of(GenericType.of("Q"), GenericType.of("V")), GenericType.of("X"))));
    final FunctionCall expression = givenFunctionCallWithMultipleLambdas();
    // When:
    final FunctionTypeInfo argumentsAndContexts = FunctionArgumentsUtil.getFunctionTypeInfo(expressionTypeManager, expression, udfFactory, Collections.emptyMap());
    // Then:
    assertThat(argumentsAndContexts.getReturnType(), is(SqlTypes.DOUBLE));
    assertThat(argumentsAndContexts.getArgumentInfos().size(), is(5));
    assertThat(argumentsAndContexts.getArgumentInfos().get(3).getSqlArgument(), is(SqlArgument.of(SqlLambdaResolved.of(ImmutableList.of(SqlTypes.BIGINT, SqlTypes.DOUBLE, SqlTypes.STRING), SqlTypes.BIGINT))));
    assertThat(argumentsAndContexts.getArgumentInfos().get(3).getLambdaSqlTypeMapping().get("X"), is(SqlTypes.BIGINT));
    assertThat(argumentsAndContexts.getArgumentInfos().get(3).getLambdaSqlTypeMapping().get("Y"), is(SqlTypes.DOUBLE));
    assertThat(argumentsAndContexts.getArgumentInfos().get(3).getLambdaSqlTypeMapping().get("Z"), is(SqlTypes.STRING));
    assertThat(argumentsAndContexts.getArgumentInfos().get(4).getSqlArgument(), is(SqlArgument.of(SqlLambdaResolved.of(ImmutableList.of(SqlTypes.STRING, SqlTypes.DOUBLE), SqlTypes.DOUBLE))));
    assertThat(argumentsAndContexts.getArgumentInfos().get(4).getLambdaSqlTypeMapping().get("A"), is(SqlTypes.STRING));
    assertThat(argumentsAndContexts.getArgumentInfos().get(4).getLambdaSqlTypeMapping().get("B"), is(SqlTypes.DOUBLE));
    // in the first pass we should have
    verify(udfFactory).getFunction(ImmutableList.of(SqlArgument.of(SqlTypes.array(SqlTypes.DOUBLE)), SqlArgument.of(SqlTypes.map(SqlTypes.BIGINT, SqlTypes.DOUBLE)), SqlArgument.of(SqlTypes.STRING), SqlArgument.of(SqlLambda.of(3)), SqlArgument.of(SqlLambda.of(2))));
    verify(function).getReturnType(ImmutableList.of(SqlArgument.of(SqlTypes.array(SqlTypes.DOUBLE)), SqlArgument.of(SqlTypes.map(SqlTypes.BIGINT, SqlTypes.DOUBLE)), SqlArgument.of(SqlTypes.STRING), SqlArgument.of(SqlLambdaResolved.of(ImmutableList.of(SqlTypes.BIGINT, SqlTypes.DOUBLE, SqlTypes.STRING), SqlTypes.BIGINT)), SqlArgument.of(SqlLambdaResolved.of(ImmutableList.of(SqlTypes.STRING, SqlTypes.DOUBLE), SqlTypes.DOUBLE))));
}
Also used : FunctionTypeInfo(io.confluent.ksql.execution.util.FunctionArgumentsUtil.FunctionTypeInfo) LambdaFunctionCall(io.confluent.ksql.execution.expression.tree.LambdaFunctionCall) FunctionCall(io.confluent.ksql.execution.expression.tree.FunctionCall) Test(org.junit.Test)

Example 4 with FunctionTypeInfo

use of io.confluent.ksql.execution.util.FunctionArgumentsUtil.FunctionTypeInfo in project ksql by confluentinc.

the class FunctionArgumentsUtilTest method shouldResolveLambdaWithoutGenerics.

@Test
public void shouldResolveLambdaWithoutGenerics() {
    // Given:
    givenUdfWithNameAndReturnType("SmallLambda", SqlTypes.DOUBLE);
    when(function.parameters()).thenReturn(ImmutableList.of(ArrayType.of(ParamTypes.DOUBLE), LambdaType.of(ImmutableList.of(ParamTypes.INTEGER), ParamTypes.INTEGER)));
    final FunctionCall expression = new FunctionCall(FunctionName.of("SmallLambda"), ImmutableList.of(ARRAYCOL, new LambdaFunctionCall(ImmutableList.of("2.3"), new ArithmeticBinaryExpression(Operator.ADD, new DoubleLiteral(2.3), new DoubleLiteral(2.3)))));
    // When:
    final FunctionTypeInfo argumentsAndContexts = FunctionArgumentsUtil.getFunctionTypeInfo(expressionTypeManager, expression, udfFactory, Collections.emptyMap());
    // Then:
    assertThat(argumentsAndContexts.getReturnType(), is(SqlTypes.DOUBLE));
    assertThat(argumentsAndContexts.getArgumentInfos().size(), is(2));
    verify(udfFactory).getFunction(ImmutableList.of(SqlArgument.of(SqlTypes.array(SqlTypes.DOUBLE)), SqlArgument.of(SqlLambda.of(1))));
    verify(function).getReturnType(ImmutableList.of(SqlArgument.of(SqlTypes.array(SqlTypes.DOUBLE)), SqlArgument.of(SqlLambdaResolved.of(ImmutableList.of(SqlTypes.INTEGER), SqlTypes.DOUBLE))));
}
Also used : ArithmeticBinaryExpression(io.confluent.ksql.execution.expression.tree.ArithmeticBinaryExpression) FunctionTypeInfo(io.confluent.ksql.execution.util.FunctionArgumentsUtil.FunctionTypeInfo) LambdaFunctionCall(io.confluent.ksql.execution.expression.tree.LambdaFunctionCall) LambdaFunctionCall(io.confluent.ksql.execution.expression.tree.LambdaFunctionCall) FunctionCall(io.confluent.ksql.execution.expression.tree.FunctionCall) DoubleLiteral(io.confluent.ksql.execution.expression.tree.DoubleLiteral) Test(org.junit.Test)

Aggregations

FunctionTypeInfo (io.confluent.ksql.execution.util.FunctionArgumentsUtil.FunctionTypeInfo)4 FunctionCall (io.confluent.ksql.execution.expression.tree.FunctionCall)3 LambdaFunctionCall (io.confluent.ksql.execution.expression.tree.LambdaFunctionCall)3 Test (org.junit.Test)3 ArithmeticBinaryExpression (io.confluent.ksql.execution.expression.tree.ArithmeticBinaryExpression)2 ArithmeticUnaryExpression (io.confluent.ksql.execution.expression.tree.ArithmeticUnaryExpression)1 ComparisonExpression (io.confluent.ksql.execution.expression.tree.ComparisonExpression)1 CreateArrayExpression (io.confluent.ksql.execution.expression.tree.CreateArrayExpression)1 CreateMapExpression (io.confluent.ksql.execution.expression.tree.CreateMapExpression)1 CreateStructExpression (io.confluent.ksql.execution.expression.tree.CreateStructExpression)1 DereferenceExpression (io.confluent.ksql.execution.expression.tree.DereferenceExpression)1 DoubleLiteral (io.confluent.ksql.execution.expression.tree.DoubleLiteral)1 Expression (io.confluent.ksql.execution.expression.tree.Expression)1 InListExpression (io.confluent.ksql.execution.expression.tree.InListExpression)1 LogicalBinaryExpression (io.confluent.ksql.execution.expression.tree.LogicalBinaryExpression)1 NotExpression (io.confluent.ksql.execution.expression.tree.NotExpression)1 SearchedCaseExpression (io.confluent.ksql.execution.expression.tree.SearchedCaseExpression)1 SimpleCaseExpression (io.confluent.ksql.execution.expression.tree.SimpleCaseExpression)1 StringLiteral (io.confluent.ksql.execution.expression.tree.StringLiteral)1 SubscriptExpression (io.confluent.ksql.execution.expression.tree.SubscriptExpression)1