You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
isthmus: ITEM on a ROW passes Calcite's 1-based index through as a 0-based struct field #1385
FieldSelectionConverter passes the integer index of a Calcite ITEM(row, n) call straight through as a 0-based struct_field offset. Calcite's ROW ITEM is 1-based (SqlItemOperator.inferReturnType reads getFieldList().get(index - 1)), so the conversion selects the next field over, and an index equal to the field count throws.
// $0 : ROW(a INTEGER, b VARCHAR(10))rexBuilder.makeCall(SqlStdOperatorTable.ITEM, $0, 1) // Calcite type INTEGER (field a)// -> FieldReference{[StructField 1, StructField 0]}, type varchar<10> (field b)rexBuilder.makeCall(SqlStdOperatorTable.ITEM, $0, 2) // Calcite type VARCHAR(10) (field b)// -> IndexOutOfBoundsException: Index 2 out of bounds for length 2
Measured on main at 559c80e. SQL r[1] is not affected, because StandardConvertletTable.convertItem lowers it to a RexFieldAccess; only calls built through RexBuilder/RelBuilder reach this branch. The ARRAY branch of the same method has the same base error, which #1261 fixes; the fix here is to subtract 1 from the ROW index the same way.
A ROW subscript by field name fails too. Calcite's StandardConvertletTable.convertItem only lowers integer ROW subscripts to a RexFieldAccess, so SQL r['q'] reaches FieldSelectionConverter as ITEM(r, 'q'), where toInt declines the character literal. With CREATE TABLE t (r ROW(p INTEGER, q INTEGER)), SELECT r['q'] FROM t throws IllegalArgumentException: Unable to convert call ITEM(struct<i32?, i32?>?, char<1>). Measured on main at eb8d3f7. Resolving the name with getField(name, false, false).getIndex() would fit alongside the integer fix.
Activity
nielspardon commentedon Oct 9, 2026
A ROW subscript by field name fails too. Calcite's
StandardConvertletTable.convertItemonly lowers integer ROW subscripts to aRexFieldAccess, so SQLr['q']reachesFieldSelectionConverterasITEM(r, 'q'), wheretoIntdeclines the character literal. WithCREATE TABLE t (r ROW(p INTEGER, q INTEGER)),SELECT r['q'] FROM tthrowsIllegalArgumentException: Unable to convert call ITEM(struct<i32?, i32?>?, char<1>).Measured onmainat eb8d3f7. Resolving the name withgetField(name, false, false).getIndex()would fit alongside the integer fix.