You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@calcite.apache.org by "Laurent Goujon (JIRA)" <ji...@apache.org> on 2019/07/26 16:32:00 UTC

[jira] [Commented] (CALCITE-3216) ClassCastException when running window function over union

    [ https://issues.apache.org/jira/browse/CALCITE-3216?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16893969#comment-16893969 ] 

Laurent Goujon commented on CALCITE-3216:
-----------------------------------------

The problem is likely to be common to any set operator: if the children of the operator are compatible but not exactly the same, the operator row type is the least restrictive of all the input types. But as far as I can tell, during execution, Calcite execution engine doesn't coerce the the records generated by the operator to match the row type, causing issues for parent operators as their physical representation do not match the expected type.

It's easy to spot in the generated source code:
{code:java}
 public org.apache.calcite.linq4j.Enumerable bind(final org.apache.calcite.DataContext root) {
   final org.apache.calcite.linq4j.Enumerable _inputEnumerable = org.apache.calcite.linq4j.Linq4j.asEnumerable(new Integer[] {
     0});
   final org.apache.calcite.linq4j.AbstractEnumerable child0 = new org.apache.calcite.linq4j.AbstractEnumerable(){
     public org.apache.calcite.linq4j.Enumerator enumerator() {
       return new org.apache.calcite.linq4j.Enumerator(){
           public final org.apache.calcite.linq4j.Enumerator inputEnumerator = _inputEnumerable.enumerator();
           public void reset() { 
             inputEnumerator.reset();
           }         
 
           public boolean moveNext() {
             return inputEnumerator.moveNext();
           }         
 
           public void close() { 
             inputEnumerator.close();
           }         
 
           public Object current() {
             return (byte)1;
           }         
 
         };        
     }
 
   };
   final org.apache.calcite.linq4j.Enumerable _inputEnumerable0 = child0.union(org.apache.calcite.linq4j.Linq4j.asEnumerable(new Integer[] {
     2}));
   return new org.apache.calcite.linq4j.AbstractEnumerable(){
       public org.apache.calcite.linq4j.Enumerator enumerator() {
         return new org.apache.calcite.linq4j.Enumerator(){
             public final org.apache.calcite.linq4j.Enumerator inputEnumerator = _inputEnumerable0.enumerator();
             public void reset() { 
               inputEnumerator.reset();
             }         
 
             public boolean moveNext() {
               return inputEnumerator.moveNext();
             }         
 
             public void close() { 
               inputEnumerator.close();
             }         
 
             public Object current() {
               return org.apache.calcite.runtime.SqlFunctions.toInt(inputEnumerator.current()) * 2;
             }         
 
           };        
       }
 
     };
 }
 
 
 public Class getElementType() {
   return int.class;
 }
{code}

Alas, I'm not familiar at all with the execution engine, and have no idea what the fix should look like.

> ClassCastException when running window function over union
> ----------------------------------------------------------
>
>                 Key: CALCITE-3216
>                 URL: https://issues.apache.org/jira/browse/CALCITE-3216
>             Project: Calcite
>          Issue Type: Bug
>          Components: core
>            Reporter: Laurent Goujon
>            Priority: Major
>
> I discovered an issue in Calcite execution engine which can be captured by this simple query:
> {code:sql}
> select *, count(*) over (partition by "id") from (
> select "id" from (VALUES(CAST(1 AS TINYINT))) "foo"("id")
> union
> select "id" from (VALUES(2)) "foo"("id"))
> {code}
> When running this query using JdbcTest for example, I got the following stacktrace:
> {noformat}
> Caused by: java.lang.ClassCastException: java.lang.Byte cannot be cast to java.lang.Integer
> 	at Baz$3.apply(ANONYMOUS.java:55)
> 	at org.apache.calcite.linq4j.DefaultEnumerable.foreach(DefaultEnumerable.java:77)
> 	at Baz.bind(Baz.java:43)
> 	at org.apache.calcite.jdbc.CalcitePrepare$CalciteSignature.enumerable(CalcitePrepare.java:355)
> 	at org.apache.calcite.jdbc.CalciteConnectionImpl.enumerable(CalciteConnectionImpl.java:316)
> 	at org.apache.calcite.jdbc.CalciteMetaImpl._createIterable(CalciteMetaImpl.java:506)
> 	at org.apache.calcite.jdbc.CalciteMetaImpl.createIterable(CalciteMetaImpl.java:497)
> 	at org.apache.calcite.avatica.AvaticaResultSet.execute(AvaticaResultSet.java:182)
> 	at org.apache.calcite.jdbc.CalciteResultSet.execute(CalciteResultSet.java:64)
> 	at org.apache.calcite.jdbc.CalciteResultSet.execute(CalciteResultSet.java:1)
> 	at org.apache.calcite.avatica.AvaticaConnection$1.execute(AvaticaConnection.java:667)
> 	at org.apache.calcite.jdbc.CalciteMetaImpl.prepareAndExecute(CalciteMetaImpl.java:566)
> 	at org.apache.calcite.avatica.AvaticaConnection.prepareAndExecuteInternal(AvaticaConnection.java:675)
> 	at org.apache.calcite.avatica.AvaticaStatement.executeInternal(AvaticaStatement.java:156)
> {noformat}



--
This message was sent by Atlassian JIRA
(v7.6.14#76016)