[ 
https://issues.apache.org/jira/browse/CALCITE-3547?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Danny Chen resolved CALCITE-3547.
---------------------------------
    Fix Version/s: 1.22.0
         Assignee: Danny Chen
       Resolution: Fixed

Fixed in 
[3f340bf|https://github.com/apache/calcite/commit/3f340bf9642b19e34be384a4f2b53f8cd4940a67],
 thanks for your PR, [~seancxmao] !

> SqlValidatorException because Planner cannot find UDFs added to schema
> ----------------------------------------------------------------------
>
>                 Key: CALCITE-3547
>                 URL: https://issues.apache.org/jira/browse/CALCITE-3547
>             Project: Calcite
>          Issue Type: Bug
>          Components: core
>    Affects Versions: 1.21.0
>            Reporter: Chenxiao Mao
>            Assignee: Danny Chen
>            Priority: Minor
>              Labels: pull-request-available
>             Fix For: 1.22.0
>
>          Time Spent: 1h 20m
>  Remaining Estimate: 0h
>
> This could be reproduce by the below test case:
> {code}
>   @Test public void testValidateUserDefinedFunctionInSchema() throws 
> Exception {
>     SchemaPlus rootSchema = Frameworks.createRootSchema(true);
>     rootSchema.add("my_plus",
>       ScalarFunctionImpl.create(Smalls.MyPlusFunction.class, "eval"));
>     final FrameworkConfig config = Frameworks.newConfigBuilder()
>       .defaultSchema(
>         CalciteAssert.addSchema(rootSchema, CalciteAssert.SchemaSpec.HR))
>       .build();
>     final Planner planner = Frameworks.getPlanner(config);
>     final String sql = "select \"my_plus\"(\"deptno\", 100) as \"p\"\n"
>       + "from \"hr\".\"emps\"";
>     SqlNode parse = planner.parse(sql);
>     SqlNode validate = planner.validate(parse);
>     assertThat(Util.toLinux(validate.toString()),
>       equalTo("SELECT `my_plus`(`emps`.`deptno`, 100) AS `p`\n"
>         + "FROM `hr`.`emps` AS `emps`"));
>   }
> {code}
> The exception is as below:
> {code}
> org.apache.calcite.sql.validate.SqlValidatorException: No match found for 
> function signature my_plus(<NUMERIC>, <NUMERIC>)
> {code}
> By digging into the related code, I found that the validator inside 
> PlannerImpl only looks for UDFs in SqlStdOperatorTable.
> If we let validator inside PlannerImpl looks for UDFs not only in 
> SqlStdOperatorTable but also CalciteCatalogReader like what 
> CalcitePrepareImpl does, we can avoid this validation exception.
> {code}
>   private SqlValidator createSqlValidator(Context context,
>       CalciteCatalogReader catalogReader) {
>     final SqlOperatorTable opTab0 =
>         context.config().fun(SqlOperatorTable.class,
>             SqlStdOperatorTable.instance());
>     final SqlOperatorTable opTab =
>         ChainedSqlOperatorTable.of(opTab0, catalogReader);
>     final JavaTypeFactory typeFactory = context.getTypeFactory();
>     final SqlConformance conformance = context.config().conformance();
>     return new CalciteSqlValidator(opTab, catalogReader, typeFactory,
>         conformance);
>   }
> {code}
> This seems to be the same problem discussed before at StackOverflow 
> (https://stackoverflow.com/questions/44147819/adding-a-user-defined-function-to-calcite).



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

Reply via email to