You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@calcite.apache.org by "Anton Haidai (Jira)" <ji...@apache.org> on 2019/09/23 10:32:00 UTC
[jira] [Updated] (CALCITE-3364) Can't group table function result
due to a type cast error if table functions returns a single value
[ https://issues.apache.org/jira/browse/CALCITE-3364?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Anton Haidai updated CALCITE-3364:
----------------------------------
Summary: Can't group table function result due to a type cast error if table functions returns a single value (was: Can't group table function result due to a type cast error)
> Can't group table function result due to a type cast error if table functions returns a single value
> ----------------------------------------------------------------------------------------------------
>
> Key: CALCITE-3364
> URL: https://issues.apache.org/jira/browse/CALCITE-3364
> Project: Calcite
> Issue Type: Bug
> Affects Versions: 1.21.0
> Reporter: Anton Haidai
> Priority: Major
>
> I was not able to find a suitable test, so I'll describe the issue using a custom minimal table function as an example. I believe, that it should be reproducible against any table function.
> There is a simple table function my_dummy() that just prints numbers 1 to 5. Simple select works as expected:
> {code}
> SQL:
> select val from table(my_dummy())
> Result:
> val : INTEGER
> 5
> 4
> 3
> 2
> 1
> {code}
> However, when trying to make an aggregation on top of it, there is a class cast error:
> {code}
> SQL:
> select val from table(my_dummy())
> group by val
> Error:
> java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to java.lang.Integer
> at org.apache.calcite.avatica.util.AbstractCursor$IntAccessor.getInt(AbstractCursor.java:541)
> at org.apache.calcite.avatica.AvaticaSite.get(AvaticaSite.java:340)
> at org.apache.calcite.avatica.AvaticaResultSet.getObject(AvaticaResultSet.java:393)
> {code}
> Actually, this array Object[] contains a single integer produced by the table function. Also I faced similar class cast errors in a generated code making hashJoin (in a complex production code), I believe, the cause should be the same as in this minimal example.
> Here is this my_dummy() table function implementation (single file):
> {code}
> package com.myapp.tf;
> import org.apache.calcite.DataContext;
> import org.apache.calcite.linq4j.AbstractEnumerable;
> import org.apache.calcite.linq4j.Enumerable;
> import org.apache.calcite.linq4j.Enumerator;
> import org.apache.calcite.linq4j.tree.Types;
> import org.apache.calcite.rel.type.RelDataType;
> import org.apache.calcite.rel.type.RelDataTypeFactory;
> import org.apache.calcite.schema.ScannableTable;
> import org.apache.calcite.schema.TableFunction;
> import org.apache.calcite.schema.impl.AbstractTable;
> import org.apache.calcite.schema.impl.TableFunctionImpl;
> import org.apache.calcite.sql.SqlIdentifier;
> import org.apache.calcite.sql.SqlOperatorBinding;
> import org.apache.calcite.sql.parser.SqlParserPos;
> import org.apache.calcite.sql.type.SqlTypeName;
> import org.apache.calcite.sql.validate.SqlUserDefinedTableFunction;
> import java.util.Collections;
> import java.util.concurrent.atomic.AtomicInteger;
> import static org.apache.calcite.sql.type.OperandTypes.family;
> public class DummyFunction extends SqlUserDefinedTableFunction {
> public static String DUMMY_FUNCTION_NAME = "my_dummy";
> public static final TableFunction DUMMY_TABLE_FUNCTION = TableFunctionImpl.create(Types.lookupMethod(
> DummyFunction.class,
> "createDummyTable"
> ));
> public static DummyTable createDummyTable() {
> return new DummyTable();
> }
> public DummyFunction() {
> super(new SqlIdentifier(DUMMY_FUNCTION_NAME, SqlParserPos.ZERO),
> null,
> null,
> family(),
> Collections.emptyList(),
> DUMMY_TABLE_FUNCTION
> );
> }
> @Override
> public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
> RelDataTypeFactory typeFactory = opBinding.getTypeFactory();
> return typeFactory.builder()
> .add("val", SqlTypeName.INTEGER)
> .build();
> }
> }
> class DummyTable extends AbstractTable implements ScannableTable {
> private final AtomicInteger cnt = new AtomicInteger(6);
> @Override
> public Enumerable<Object[]> scan(DataContext root) {
> return new AbstractEnumerable<Object[]>() {
> public Enumerator<Object[]> enumerator() {
> return new Enumerator<Object[]> () {
> @Override
> public Object[] current() {
> return new Object[] { cnt.intValue() };
> }
> @Override
> public boolean moveNext() {
> return cnt.decrementAndGet() > 0;
> }
> @Override
> public void reset() {
> }
> @Override
> public void close() {
> }
> };
> }
> };
> }
> @Override
> public RelDataType getRowType(RelDataTypeFactory typeFactory) {
> return typeFactory.builder()
> .add("val", SqlTypeName.INTEGER)
> .build();
> }
> }
> {code}
> And adding it into a schema:
> {code}
> mySchemaPlus.add(DUMMY_FUNCTION_NAME, DummyFunction.DUMMY_TABLE_FUNCTION);
> {code}
--
This message was sent by Atlassian Jira
(v8.3.4#803005)