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

Ran Tao updated CALCITE-5948:
-----------------------------
    Description: 
First, we need to reach a consensus to allow types of the same family to 
coexist in array functions (calcite use SameOperandTypeChecker or 
LeastRestrictiveType to support it).

It means the form like `{*}array(1, cast(2 as tinyint)){*}` is correct(the 
LeastRestrictiveType is Integer).In fact, the most of mature engines such as 
spark/hive/flink just also support this behavior. However, this function 
validate success in calcite but it failed in runtime, exception stack is:
{code:java}
java.lang.ClassCastException: class java.lang.Byte cannot be cast to class 
java.lang.Integer
    at 
org.apache.calcite.avatica.util.AbstractCursor$IntAccessor.getInt(AbstractCursor.java:522)
    at 
org.apache.calcite.avatica.util.AbstractCursor$ArrayAccessor.convertValue(AbstractCursor.java:1396)
    at 
org.apache.calcite.avatica.util.AbstractCursor$ArrayAccessor.getObject(AbstractCursor.java:1377)
    at 
org.apache.calcite.avatica.util.AbstractCursor$ArrayAccessor.getArray(AbstractCursor.java:1432)
    at 
org.apache.calcite.avatica.util.AbstractCursor$ArrayAccessor.getString(AbstractCursor.java:1444)
    at 
org.apache.calcite.avatica.AvaticaResultSet.getString(AvaticaResultSet.java:241)
    at org.apache.calcite.util.JdbcTypeImpl$10.get(JdbcTypeImpl.java:112)
    at org.apache.calcite.util.JdbcTypeImpl$10.get(JdbcTypeImpl.java:109)
    at 
org.apache.calcite.sql.test.ResultCheckers.compareResultSetWithMatcher(ResultCheckers.java:248)
    at 
org.apache.calcite.sql.test.ResultCheckers$MatcherResultChecker.checkResult(ResultCheckers
 {code}
e.g. and more array functions failed in runtime when use element cast.
{code:java}
//java.lang.ClassCastException: java.lang.Byte cannot be cast to 
java.lang.Integer
select array(1, cast(2 as tinyint))


// java.lang.ClassCastException: java.lang.Short cannot be cast to 
java.lang.Integer
select array(1, cast(2 as smallint))


// java.lang.ClassCastException: java.lang.Integer cannot be cast to 
java.lang.Long
select array(1, cast(2 as bigint))


// java.lang.ClassCastException: java.lang.Integer cannot be cast to 
java.lang.Long
select array_prepend(array[1, cast(2 as bigint)], 3)
select array_prepend(array[1, 2], cast(3 as bigint))


// java.lang.ClassCastException: java.lang.Short cannot be cast to 
java.lang.Integer
select array_append(array[1, cast(2 as smallint)], 3)
select array_append(array[1, 2], cast(3 as smallint))


// java.lang.ClassCastException: java.lang.Integer cannot be cast to 
java.lang.Long
select array_reverse(array[1, cast(2 as bigint)])


// java.lang.ClassCastException: java.lang.Short cannot be cast to 
java.lang.Integer
array_distinct(array[1, 2, cast(2 as smallint), 1])


more functions failed... {code}
 

the error code path(IntAccessor and ShortAccessor  is just one of them, as an 
example):
{code:java}
private static class IntAccessor extends ExactNumericAccessor {
  private IntAccessor(Getter getter) {
    super(getter);
  }

  public int getInt() throws SQLException {
    Integer o = (Integer) super.getObject();  --> error logic
    return o == null ? 0 : o;
  }

  public long getLong() throws SQLException {
    return getInt();
  }
}{code}
 
{code:java}
private static class ShortAccessor extends ExactNumericAccessor {
  private ShortAccessor(Getter getter) {
    super(getter);
  }

  public short getShort() throws SQLException {
    Object obj = getObject();
    if (null == obj) {
      return 0;
    } else if (obj instanceof Integer) {
      return ((Integer) obj).shortValue(); 
    }
    return (Short) obj; --> error logic   } {code}
 
{code:java}
private static class ByteAccessor extends ExactNumericAccessor {
  private ByteAccessor(Getter getter) {
    super(getter);
  }

  public byte getByte() throws SQLException {
    Object obj = getObject();
    if (null == obj) {
      return 0;
    } else if (obj instanceof Integer) {
      return ((Integer) obj).byteValue();
    }
    return (Byte) obj; --> error logic   } {code}


we may should fix it in calcite-avatica. and add more test cases to cover it in 
calcite-main.

 

  was:
First, we need to reach a consensus to allow types of the same family to 
coexist in array functions (calcite use SameOperandTypeChecker or 
LeastRestrictiveType to support it).

It means the form like `{*}array(1, cast(2 as tinyint)){*}` is correct(the 
LeastRestrictiveType is Integer).In fact, the most of mature engines such as 
spark/hive/flink just also support this behavior. However, this function 
validate success in calcite but it failed in runtime, exception stack is:
{code:java}
java.lang.ClassCastException: class java.lang.Byte cannot be cast to class 
java.lang.Integer
    at 
org.apache.calcite.avatica.util.AbstractCursor$IntAccessor.getInt(AbstractCursor.java:522)
    at 
org.apache.calcite.avatica.util.AbstractCursor$ArrayAccessor.convertValue(AbstractCursor.java:1396)
    at 
org.apache.calcite.avatica.util.AbstractCursor$ArrayAccessor.getObject(AbstractCursor.java:1377)
    at 
org.apache.calcite.avatica.util.AbstractCursor$ArrayAccessor.getArray(AbstractCursor.java:1432)
    at 
org.apache.calcite.avatica.util.AbstractCursor$ArrayAccessor.getString(AbstractCursor.java:1444)
    at 
org.apache.calcite.avatica.AvaticaResultSet.getString(AvaticaResultSet.java:241)
    at org.apache.calcite.util.JdbcTypeImpl$10.get(JdbcTypeImpl.java:112)
    at org.apache.calcite.util.JdbcTypeImpl$10.get(JdbcTypeImpl.java:109)
    at 
org.apache.calcite.sql.test.ResultCheckers.compareResultSetWithMatcher(ResultCheckers.java:248)
    at 
org.apache.calcite.sql.test.ResultCheckers$MatcherResultChecker.checkResult(ResultCheckers
 {code}
e.g. and more array functions failed in runtime when use element cast.
{code:java}
//java.lang.ClassCastException: java.lang.Byte cannot be cast to 
java.lang.Integer
select array(1, cast(2 as tinyint))


// java.lang.ClassCastException: java.lang.Short cannot be cast to 
java.lang.Integer
select array(1, cast(2 as smallint))


// java.lang.ClassCastException: java.lang.Integer cannot be cast to 
java.lang.Long
select array(1, cast(2 as bigint))


// java.lang.ClassCastException: java.lang.Integer cannot be cast to 
java.lang.Long
select array_prepend(array[1, cast(2 as bigint)], 3)
select array_prepend(array[1, 2], cast(3 as bigint))


// java.lang.ClassCastException: java.lang.Short cannot be cast to 
java.lang.Integer
select array_append(array[1, cast(2 as smallint)], 3)
select array_append(array[1, 2], cast(3 as smallint))


// java.lang.ClassCastException: java.lang.Integer cannot be cast to 
java.lang.Long
select array_reverse(array[1, cast(2 as bigint)])


// java.lang.ClassCastException: java.lang.Short cannot be cast to 
java.lang.Integer
array_distinct(array[1, 2, cast(2 as smallint), 1])


more functions failed... {code}
 

the error code path(IntAccessor is just one of them, as an example):
{code:java}
private static class IntAccessor extends ExactNumericAccessor {
  private IntAccessor(Getter getter) {
    super(getter);
  }

  public int getInt() throws SQLException {
    Integer o = (Integer) super.getObject();  --> error logic
    return o == null ? 0 : o;
  }

  public long getLong() throws SQLException {
    return getInt();
  }
}{code}
we may should fix it in calcite-avatica. and add more test cases to cover it in 
calcite-main.


> A serials of array functions failed in runtime cause by incorrect avatica 
> type cast behavior 
> ---------------------------------------------------------------------------------------------
>
>                 Key: CALCITE-5948
>                 URL: https://issues.apache.org/jira/browse/CALCITE-5948
>             Project: Calcite
>          Issue Type: Bug
>          Components: avatica
>    Affects Versions: 1.35.0
>            Reporter: Ran Tao
>            Assignee: Ran Tao
>            Priority: Major
>
> First, we need to reach a consensus to allow types of the same family to 
> coexist in array functions (calcite use SameOperandTypeChecker or 
> LeastRestrictiveType to support it).
> It means the form like `{*}array(1, cast(2 as tinyint)){*}` is correct(the 
> LeastRestrictiveType is Integer).In fact, the most of mature engines such as 
> spark/hive/flink just also support this behavior. However, this function 
> validate success in calcite but it failed in runtime, exception stack is:
> {code:java}
> java.lang.ClassCastException: class java.lang.Byte cannot be cast to class 
> java.lang.Integer
>     at 
> org.apache.calcite.avatica.util.AbstractCursor$IntAccessor.getInt(AbstractCursor.java:522)
>     at 
> org.apache.calcite.avatica.util.AbstractCursor$ArrayAccessor.convertValue(AbstractCursor.java:1396)
>     at 
> org.apache.calcite.avatica.util.AbstractCursor$ArrayAccessor.getObject(AbstractCursor.java:1377)
>     at 
> org.apache.calcite.avatica.util.AbstractCursor$ArrayAccessor.getArray(AbstractCursor.java:1432)
>     at 
> org.apache.calcite.avatica.util.AbstractCursor$ArrayAccessor.getString(AbstractCursor.java:1444)
>     at 
> org.apache.calcite.avatica.AvaticaResultSet.getString(AvaticaResultSet.java:241)
>     at org.apache.calcite.util.JdbcTypeImpl$10.get(JdbcTypeImpl.java:112)
>     at org.apache.calcite.util.JdbcTypeImpl$10.get(JdbcTypeImpl.java:109)
>     at 
> org.apache.calcite.sql.test.ResultCheckers.compareResultSetWithMatcher(ResultCheckers.java:248)
>     at 
> org.apache.calcite.sql.test.ResultCheckers$MatcherResultChecker.checkResult(ResultCheckers
>  {code}
> e.g. and more array functions failed in runtime when use element cast.
> {code:java}
> //java.lang.ClassCastException: java.lang.Byte cannot be cast to 
> java.lang.Integer
> select array(1, cast(2 as tinyint))
> // java.lang.ClassCastException: java.lang.Short cannot be cast to 
> java.lang.Integer
> select array(1, cast(2 as smallint))
> // java.lang.ClassCastException: java.lang.Integer cannot be cast to 
> java.lang.Long
> select array(1, cast(2 as bigint))
> // java.lang.ClassCastException: java.lang.Integer cannot be cast to 
> java.lang.Long
> select array_prepend(array[1, cast(2 as bigint)], 3)
> select array_prepend(array[1, 2], cast(3 as bigint))
> // java.lang.ClassCastException: java.lang.Short cannot be cast to 
> java.lang.Integer
> select array_append(array[1, cast(2 as smallint)], 3)
> select array_append(array[1, 2], cast(3 as smallint))
> // java.lang.ClassCastException: java.lang.Integer cannot be cast to 
> java.lang.Long
> select array_reverse(array[1, cast(2 as bigint)])
> // java.lang.ClassCastException: java.lang.Short cannot be cast to 
> java.lang.Integer
> array_distinct(array[1, 2, cast(2 as smallint), 1])
> more functions failed... {code}
>  
> the error code path(IntAccessor and ShortAccessor  is just one of them, as an 
> example):
> {code:java}
> private static class IntAccessor extends ExactNumericAccessor {
>   private IntAccessor(Getter getter) {
>     super(getter);
>   }
>   public int getInt() throws SQLException {
>     Integer o = (Integer) super.getObject();  --> error logic
>     return o == null ? 0 : o;
>   }
>   public long getLong() throws SQLException {
>     return getInt();
>   }
> }{code}
>  
> {code:java}
> private static class ShortAccessor extends ExactNumericAccessor {
>   private ShortAccessor(Getter getter) {
>     super(getter);
>   }
>   public short getShort() throws SQLException {
>     Object obj = getObject();
>     if (null == obj) {
>       return 0;
>     } else if (obj instanceof Integer) {
>       return ((Integer) obj).shortValue(); 
>     }
>     return (Short) obj; --> error logic   } {code}
>  
> {code:java}
> private static class ByteAccessor extends ExactNumericAccessor {
>   private ByteAccessor(Getter getter) {
>     super(getter);
>   }
>   public byte getByte() throws SQLException {
>     Object obj = getObject();
>     if (null == obj) {
>       return 0;
>     } else if (obj instanceof Integer) {
>       return ((Integer) obj).byteValue();
>     }
>     return (Byte) obj; --> error logic   } {code}
> we may should fix it in calcite-avatica. and add more test cases to cover it 
> in calcite-main.
>  



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to