You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@calcite.apache.org by "Vladimir Sitnikov (Jira)" <ji...@apache.org> on 2026/10/12 05:35:00 UTC

[jira] [Created] (CALCITE-7848) Array.getArray() throws ClassCastException for an ARRAY or MULTISET of INTEGER ARRAYs or MULTISETs

Vladimir Sitnikov created CALCITE-7848:
------------------------------------------

             Summary: Array.getArray() throws ClassCastException for an ARRAY or MULTISET of INTEGER ARRAYs or MULTISETs
                 Key: CALCITE-7848
                 URL: https://issues.apache.org/jira/browse/CALCITE-7848
             Project: Calcite
          Issue Type: Bug
          Components: core
    Affects Versions: 1.42.0
            Reporter: Vladimir Sitnikov


Reading a nested collection through the standard JDBC path fails when the inner collection holds a primitive type such as INTEGER. ResultSet.getObject returns a java.sql.Array, and calling getArray() on it throws ClassCastException. getString on the same column returns the correct value, and the same query with VARCHAR elements works.

Reproduced with calcite-core 1.42.0 (avatica-core 1.28.0, JDK 21.0.9) and on main at 843f468405 (Avatica 1.29.0):

{code:java}
try (Connection c = DriverManager.getConnection("jdbc:calcite:");
     ResultSet rs = c.createStatement()
         .executeQuery("select array[array[1, 2], array[3, 4]]")) {
  rs.next();
  System.out.println(rs.getString(1));
  Array array = (Array) rs.getObject(1);
  System.out.println(Arrays.toString((Object[]) array.getArray()));
}
{code}

Output for three queries:

{noformat}
select array[array[1, 2], array[3, 4]]
  getString:           [[1, 2], [3, 4]]
  getObject.getArray:  java.lang.ClassCastException: class org.apache.calcite.avatica.util.ArrayImpl cannot be cast to class java.lang.Integer (org.apache.calcite.avatica.util.ArrayImpl is in unnamed module of loader 'app'; java.lang.Integer is in module java.base of loader 'bootstrap')
      at org.apache.calcite.avatica.util.ArrayImpl.getArray(ArrayImpl.java:115)
      at org.apache.calcite.avatica.util.ArrayImpl.getArray(ArrayImpl.java:50)
select multiset[multiset[1, 2], multiset[3, 4]]
  getString:           [[1, 2], [3, 4]]
  getObject.getArray:  java.lang.ClassCastException: class org.apache.calcite.avatica.util.ArrayImpl cannot be cast to class java.lang.Integer (...)
select array[array['a', 'b'], array['c', 'd']]
  getString:           [[a, b], [c, d]]
  getObject.getArray:  [[a, b], [c, d]]
{noformat}

The same exception occurs on main for multiset[array[1, 2]], array[multiset[1, 2]] and multiset[multiset[array[1, 2]]].

h3. Expected

For select array[array[1, 2], array[3, 4]], getArray() returns an Object[] of two java.sql.Array elements whose own getArray() returns int[] {1, 2} and int[] {3, 4}. This is what the java.sql.Array contract describes for an ARRAY base type, and it is what Calcite already returns when the inner elements are VARCHAR.

h3. Analysis (a guess; the report above stands without it)

CalcitePrepareImpl.avaticaType passes the Rep of the component's Java class to ColumnMetaData.array, so the metadata of INTEGER ARRAY carries Rep.PRIMITIVE_INT. ArrayImpl.getArray of the outer collection switches on the component type's rep, takes the PRIMITIVE_INT branch, and casts each inner ArrayImpl to Integer. VARCHAR maps to Rep.STRING, falls through to the Object[] branch, and works. CALCITE-910 (commit 4000edd8e6, 2015) introduced the component-based rep; before it the rep came from the collection's own class. Passing Rep.ARRAY or Rep.MULTISET, as the Avatica test for CALCITE-3557 (ArrayAccessorTest.resultSetFromMultisetArray) does, makes all the queries above return nested java.sql.Array values, and the core test suite passes.

h3. Related

CALCITE-3557 fixed the ClassCastException on the getString path (Avatica 1.23.0); this report is about getObject().getArray(), which still fails. CALCITE-1335 is about getArray() returning internal representations of DATE and TIMESTAMP, not this exception.



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