将用户定义的函数添加到方解码

Mic*_*eev 7 java sql-parser apache-calcite

我需要为Calcite添加一个用户定义的函数,它将一个整数作为参数并返回一个整数.

    public class SquareFunction  {
        public int eval(int a) {
            return a*a;
        }
    }
Run Code Online (Sandbox Code Playgroud)

以及创建模式并添加函数的相关代码

     SchemaPlus rootSchema = Frameworks.createRootSchema(false);
     rootSchema.add("SQUARE_FUNC", 
                    ScalarFunctionImpl.create(SquareFunction.class,"eval"); 
Run Code Online (Sandbox Code Playgroud)

但是简单的SQL喜欢

select SQUARE_FUNC(1) from test;
Run Code Online (Sandbox Code Playgroud)

验证期间失败,并显示以下消息:

No match found for function signature SQUARE_FUNC(<NUMERIC>)
Run Code Online (Sandbox Code Playgroud)

堆栈跟踪是:

at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
    at org.apache.calcite.runtime.Resources$ExInstWithCause.ex(Resources.java:463)
    at org.apache.calcite.sql.SqlUtil.newContextException(SqlUtil.java:804)
    at org.apache.calcite.sql.SqlUtil.newContextException(SqlUtil.java:789)
    at org.apache.calcite.sql.validate.SqlValidatorImpl.newValidationError(SqlValidatorImpl.java:4386)
    at org.apache.calcite.sql.validate.SqlValidatorImpl.handleUnresolvedFunction(SqlValidatorImpl.java:1670)
    at org.apache.calcite.sql.SqlFunction.deriveType(SqlFunction.java:278)
    at org.apache.calcite.sql.SqlFunction.deriveType(SqlFunction.java:223)
    at org.apache.calcite.sql.validate.SqlValidatorImpl$DeriveTypeVisitor.visit(SqlValidatorImpl.java:4965)
    at org.apache.calcite.sql.validate.SqlValidatorImpl$DeriveTypeVisitor.visit(SqlValidatorImpl.java:1)
    at org.apache.calcite.sql.SqlCall.accept(SqlCall.java:137)
    at org.apache.calcite.sql.validate.SqlValidatorImpl.deriveTypeImpl(SqlValidatorImpl.java:1586)
    at org.apache.calcite.sql.validate.SqlValidatorImpl.deriveType(SqlValidatorImpl.java:1571)
    at org.apache.calcite.sql.validate.SqlValidatorImpl.expandSelectItem(SqlValidatorImpl.java:453)
    at org.apache.calcite.sql.validate.SqlValidatorImpl.validateSelectList(SqlValidatorImpl.java:3668)
    at org.apache.calcite.sql.validate.SqlValidatorImpl.validateSelect(SqlValidatorImpl.java:3186)
    at org.apache.calcite.sql.validate.SelectNamespace.validateImpl(SelectNamespace.java:60)
    at org.apache.calcite.sql.validate.AbstractNamespace.validate(AbstractNamespace.java:84)
    at org.apache.calcite.sql.validate.SqlValidatorImpl.validateNamespace(SqlValidatorImpl.java:937)
    at org.apache.calcite.sql.validate.SqlValidatorImpl.validateQuery(SqlValidatorImpl.java:918)
    at org.apache.calcite.sql.SqlSelect.validate(SqlSelect.java:220)
    at org.apache.calcite.sql.validate.SqlValidatorImpl.validateScopedExpression(SqlValidatorImpl.java:893)
    at org.apache.calcite.sql.validate.SqlValidatorImpl.validate(SqlValidatorImpl.java:603)
    at org.apache.calcite.prepare.PlannerImpl.validate(PlannerImpl.java:188) ... 26 more
Run Code Online (Sandbox Code Playgroud)

我遵循了Calcite的UdfTest.testUserDefinedFunctionInView实现,但仍然无法使其工作.我究竟做错了什么?

小智 1

SquareFunction内部类吗?如果是这样,请尝试将其设为静态。

如果这不起作用,请尝试创建eval静态方法。

  • SquareFunction 是一个常规类。使其成为公共内部静态(并使“eval”方法也静态)并没有帮助。在调试应用程序时,我可以看到 ScalarFunctionImpl.create 调用返回一个有效的 ScalarFunctionImpl 对象,该对象已成功添加到架构中。但是,当我从 SqlStdOperatorTable.lookupOperatorOverloads 方法转储 SqlStdOperatorTable.operators 多重映射的内容时,SQUARE_FUNC 名称不存在,并且 routput operatorList 为空。 (2认同)