vlsi opened a new pull request, #5322:
URL: https://github.com/apache/calcite/pull/5322

   Jira: [CALCITE-7848](https://issues.apache.org/jira/browse/CALCITE-7848), 
plus a regression test for 
[CALCITE-3557](https://issues.apache.org/jira/browse/CALCITE-3557).
   
   ## Why
   
   For a nested collection of INTEGER, such as `select array[array[1, 2], 
array[3, 4]]`, `ResultSet.getObject` returns a `java.sql.Array` whose 
`getArray()` throws `ClassCastException: class 
org.apache.calcite.avatica.util.ArrayImpl cannot be cast to class 
java.lang.Integer`. The same happens for `multiset[multiset[...]]`, 
`multiset[array[...]]` and `array[multiset[...]]`; `getString` returns the 
right value, and VARCHAR elements work. Reproduced with calcite-core 1.42.0 and 
on main.
   
   Through the remote driver, a query that returns a collection of INTEGER does 
not execute at all: `AbstractService.finagle` tries to change the column's rep 
from `PRIMITIVE_INT` to `NUMBER`, and `ColumnMetaData.ArrayType.setRep` throws 
`UnsupportedOperationException`.
   
   ## What
   
   `CalcitePrepareImpl.avaticaType` gave each `ArrayType` the rep of its 
component's Java class (since CALCITE-910), so `INTEGER ARRAY` carried 
`PRIMITIVE_INT`, and `ArrayImpl.getArray` of the outer collection took the 
primitive-int branch for the inner `ArrayImpl` values. The fix passes 
`Rep.ARRAY` or `Rep.MULTISET`, which is how Avatica's own 
`ArrayAccessorTest.resultSetFromMultisetArray` describes a nested collection. 
Fixing this in Avatica's `ArrayImpl` instead would need an Avatica release and 
would still leave the remote driver failing in `finagle`.
   
   The first commit is the end-to-end test from #2790 by @JiajunBernoulli, 
without its `Bug.CALCITE_3557_FIXED` guard. CALCITE-3557 was fixed in Avatica 
1.23.0, but nothing in Calcite ran these queries; with that Avatica fix 
reverted, 4 of its 6 cases fail.
   
   ## What the caller sees
   
   - `getObject(i).getArray()` on a collection of INTEGER ARRAY or MULTISET 
returns an `Object[]` of `java.sql.Array` whose `getArray()` returns `int[]`, 
instead of throwing `ClassCastException`.
   - The remote driver executes a query that returns a collection of a numeric 
type, instead of failing with `UnsupportedOperationException`.
   
   ## Verification
   
   - `JdbcTest.testGetArrayOfNestedCollection` (new): all four nesting shapes 
fail without the fix and pass with it.
   - `CalciteRemoteDriverTest.testRemoteIntegerCollections` (new): fails 
without the fix with `UnsupportedOperationException`, passes with it.
   - `./gradlew :core:test` with the fix: 16891 tests, none failed.
   
   ## Scope
   
   - Through the remote driver, `getString` on `multiset[multiset[1, 2]]` still 
throws `ClassCastException` (`java.util.ArrayList` cannot be cast to 
`java.lang.Integer`). That query could not run remotely before this change at 
all; it is not fixed here.
   - `MaterializationService` passes the top-level column rep to 
`CloneSchema.createCloneTable`, so a single-column materialization of a 
collection column now gets `java.sql.Array` or `List` as its element class 
instead of the component's primitive class. No test covers it, and I found no 
code that depends on the old value.
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to