Chenxiao Mao created CALCITE-3547:
-------------------------------------

             Summary: 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


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