I'm using Apache Calcite to validate SQL. I add tables and UDFs dynamically. The problem is when I add a UDF with variable number parameter, the validator can not find this function.
Version of Calcite is 1.18.0
And this is my code.
TestfuncFunction.java
public class TestfuncFunction {
public String testfunc(String... arg0) {
return null;
}
}
Add UDF
Function schemafunction = ScalarFunctionImpl.create(TestfuncFunction.class),"testfunc");
SchemaPlus schemaPlus = Frameworks.createRootSchema(true);
schemaPlus.add("testfunc", schemafunction);
SQL
select testfunc(field1, field2) from test_table
testfunc is a ScalarFunction with variable number parameter,field1 and field2 are columns of test_table. So this is a legal SQL. But I got this CalciteContextException when validating:
No match found for function signature testfunc(<CHARACTER>, <CHARACTER>)
I tryed to change my sql into one parameter like this:
select testfunc(field1) from test_table
and got this exception
java.lang.AssertionError: No assign rules for OTHER defined
at org.apache.calcite.sql.type.SqlTypeAssignmentRules.canCastFrom(SqlTypeAssignmentRules.java:386)
at org.apache.calcite.sql.type.SqlTypeUtil.canCastFrom(SqlTypeUtil.java:864)
at org.apache.calcite.sql.SqlUtil.lambda$filterRoutinesByParameterType$4(SqlUtil.java:554)
...
It seems that calcite transform java array type into SqlTypeName.OTHER. I have tryed to override method "createJavaType" in JavaTypeFactoryImpl like this:
private static class CustomJavaTypeFactoryImpl extends JavaTypeFactoryImpl {
@Override
public RelDataType createJavaType(Class clazz) {
if (clazz.isArray()) {
return new ArraySqlType(super.createJavaType(clazz.getComponentType()), true);
}
return super.createJavaType(clazz);
}
}
but it did not work.
Do Calcite support UDF with variable number parameter, and what should I do.