You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@calcite.apache.org by Julian Hyde <jh...@gmail.com> on 2021/08/04 04:15:28 UTC

Re: ClassCastException: FamilyOperandTypeChecker cannot be cast to SqlOperandMetadata

SqlOperandMetadata only needs to be implemented by user-defined functions. (User-defined functions have fixed number of parameters, and the parameters have names; built-in functions may have a variable number of arguments, but they do not have names.)

So, maybe the cause is a function that isn’t sure whether it’s a UDF or a built-in.

My money is on user error rather than Calcite bug.

> On Jul 28, 2021, at 12:19 AM, Yanjing Wang <zh...@gmail.com> wrote:
> 
> It may be a bug caused by CALCITE-4427
> <https://issues.apache.org/jira/browse/CALCITE-4427>, I
> think lookupSubjectRoutines behavior is a bit strange. when found routines
> are less than two, It returns directly whatever the routine SqlKind is.
> otherwise filtered by SqlKind. This behavior may cause empty routine
> results when all candidates are filtered out. @Julian, could you help the
> exception to be fixed?
> 
> wrstrs <wr...@foxmail.com> 于2021年7月27日周二 下午3:33写道:
> 
>> Hi, all
>> 
>> how to solve this problem?
>> 
>> 
>> 
>> 
>> my code:
>> String sql = "select UNIX_TIMESTAMP(concat(substr('2021-07-27
>> 12:12:12',0,11),'09:00:00'))";
>> 
>> SqlOperatorTable opTab =
>> &nbsp; &nbsp; &nbsp;
>> &nbsp;SqlLibraryOperatorTableFactory.INSTANCE.getOperatorTable(EnumSet.of(
>> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;SqlLibrary.HIVE,
>> SqlLibrary.SPARK, SqlLibrary.BIG_QUERY, SqlLibrary.ORACLE,
>> SqlLibrary.MYSQL, SqlLibrary.STANDARD));
>> SchemaPlus rootSchema = Frameworks.createRootSchema(true);
>> 
>> FrameworkConfig frameworkConfig = Frameworks.newConfigBuilder()
>> &nbsp; &nbsp; &nbsp; &nbsp;.defaultSchema(rootSchema)
>> &nbsp; &nbsp; &nbsp; &nbsp;.operatorTable(opTab)
>> &nbsp; &nbsp; &nbsp; &nbsp;.build();
>> 
>> Planner planner = Frameworks.getPlanner(frameworkConfig);
>> SqlNode sqlNode = planner.parse(sql);
>> SqlNode validateSqlNode = planner.validate(sqlNode);
>> 
>> 
>> 
>> throw exception:
>> 
>> Exception in thread "main" org.apache.calcite.tools.ValidationException:
>> java.lang.ClassCastException:
>> org.apache.calcite.sql.type.FamilyOperandTypeChecker cannot be cast to
>> org.apache.calcite.sql.type.SqlOperandMetadata
>> 
>>        at
>> org.apache.calcite.prepare.PlannerImpl.validate(PlannerImpl.java:228)
>> 
>> Caused by: java.lang.ClassCastException:
>> org.apache.calcite.sql.type.FamilyOperandTypeChecker cannot be cast to
>> org.apache.calcite.sql.type.SqlOperandMetadata
>> 
>>        at
>> org.apache.calcite.sql.validate.implicit.TypeCoercionImpl.userDefinedFunctionCoercion(TypeCoercionImpl.java:589)
>> 
>>        at
>> org.apache.calcite.sql.SqlFunction.deriveType(SqlFunction.java:303)
>> 
>>        at
>> org.apache.calcite.sql.SqlFunction.deriveType(SqlFunction.java:231)


Re: ClassCastException: FamilyOperandTypeChecker cannot be cast to SqlOperandMetadata

Posted by Yanjing Wang <zh...@gmail.com>.
The ClassCastException just is the side effect
of filterOperatorRoutinesByKind. Let's see substr('2021-07-27
12:12:12',0,11) in the sql, calcite will find three SqlFunctions
of SqlKind.SUBSTR_XXX before filterOperatorRoutinesByKind because that the
user has specified SqlLibrary.BIG_QUERY, SqlLibrary.ORACLE,
SqlLibrary.MYSQL.

If the user specifies only SqlLibrary.BIG_QUERY, Calcite just returns the
only one substr SqlFunction regardless of filterOperatorRoutinesByKind. But
if the user specifies more that have the same SqlFunctions, the found
SqlFunctions will experience filterOperatorRoutinesByKind. Due to the fact
that any non built-in functions will be SqlKind.OTHER_FUNCTION, so no
SqlFunctions will be found finally and the execution falls
into userDefinedFunctionCoercion which causes the ClassCastException.

The solution may be modifying the filterOperatorRoutinesByKind to be
lenient when the function is kind of SqlKind.OTHER_FUNCTION, or changing
all the substr function kind to SqlKind.OTHER_FUNCTION. I'm not sure
whether it's reasonable.



Julian Hyde <jh...@gmail.com> 于2021年8月4日周三 下午12:16写道:

> SqlOperandMetadata only needs to be implemented by user-defined functions.
> (User-defined functions have fixed number of parameters, and the parameters
> have names; built-in functions may have a variable number of arguments, but
> they do not have names.)
>
> So, maybe the cause is a function that isn’t sure whether it’s a UDF or a
> built-in.
>
> My money is on user error rather than Calcite bug.
>
> > On Jul 28, 2021, at 12:19 AM, Yanjing Wang <zh...@gmail.com>
> wrote:
> >
> > It may be a bug caused by CALCITE-4427
> > <https://issues.apache.org/jira/browse/CALCITE-4427>, I
> > think lookupSubjectRoutines behavior is a bit strange. when found
> routines
> > are less than two, It returns directly whatever the routine SqlKind is.
> > otherwise filtered by SqlKind. This behavior may cause empty routine
> > results when all candidates are filtered out. @Julian, could you help the
> > exception to be fixed?
> >
> > wrstrs <wr...@foxmail.com> 于2021年7月27日周二 下午3:33写道:
> >
> >> Hi, all
> >>
> >> how to solve this problem?
> >>
> >>
> >>
> >>
> >> my code:
> >> String sql = "select UNIX_TIMESTAMP(concat(substr('2021-07-27
> >> 12:12:12',0,11),'09:00:00'))";
> >>
> >> SqlOperatorTable opTab =
> >> &nbsp; &nbsp; &nbsp;
> >>
> &nbsp;SqlLibraryOperatorTableFactory.INSTANCE.getOperatorTable(EnumSet.of(
> >> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;SqlLibrary.HIVE,
> >> SqlLibrary.SPARK, SqlLibrary.BIG_QUERY, SqlLibrary.ORACLE,
> >> SqlLibrary.MYSQL, SqlLibrary.STANDARD));
> >> SchemaPlus rootSchema = Frameworks.createRootSchema(true);
> >>
> >> FrameworkConfig frameworkConfig = Frameworks.newConfigBuilder()
> >> &nbsp; &nbsp; &nbsp; &nbsp;.defaultSchema(rootSchema)
> >> &nbsp; &nbsp; &nbsp; &nbsp;.operatorTable(opTab)
> >> &nbsp; &nbsp; &nbsp; &nbsp;.build();
> >>
> >> Planner planner = Frameworks.getPlanner(frameworkConfig);
> >> SqlNode sqlNode = planner.parse(sql);
> >> SqlNode validateSqlNode = planner.validate(sqlNode);
> >>
> >>
> >>
> >> throw exception:
> >>
> >> Exception in thread "main" org.apache.calcite.tools.ValidationException:
> >> java.lang.ClassCastException:
> >> org.apache.calcite.sql.type.FamilyOperandTypeChecker cannot be cast to
> >> org.apache.calcite.sql.type.SqlOperandMetadata
> >>
> >>        at
> >> org.apache.calcite.prepare.PlannerImpl.validate(PlannerImpl.java:228)
> >>
> >> Caused by: java.lang.ClassCastException:
> >> org.apache.calcite.sql.type.FamilyOperandTypeChecker cannot be cast to
> >> org.apache.calcite.sql.type.SqlOperandMetadata
> >>
> >>        at
> >>
> org.apache.calcite.sql.validate.implicit.TypeCoercionImpl.userDefinedFunctionCoercion(TypeCoercionImpl.java:589)
> >>
> >>        at
> >> org.apache.calcite.sql.SqlFunction.deriveType(SqlFunction.java:303)
> >>
> >>        at
> >> org.apache.calcite.sql.SqlFunction.deriveType(SqlFunction.java:231)
>
>