Skip to content

isthmus: TypeConverter's switch NPEs on a type with no SqlTypeName, before the unsupported-type arm can report it #1255

Description

@nielspardon

TypeConverter.toSubstrait(RelDataType, List<String>) dispatches on switch (type.getSqlTypeName()), and Calcite does not guarantee that accessor is non-null. RelDataTypeImpl's base implementation is return castNonNull(null); — a no-op cast at runtime — and RelCrossType, which RelDataTypeFactory.createJoinType(...) returns, does not override it. So the switch throws before the unsupported-type arm can report anything:

RelDataType cross = TYPE_FACTORY.createJoinType(structA, structB);
// cross.getSqlTypeName() == null,  cross.toString() == CrossType(RecordType(INTEGER a), RecordType(VARCHAR b))

TypeConverter.DEFAULT.toSubstrait(cross)
-> NullPointerException: Cannot invoke "org.apache.calcite.sql.type.SqlTypeName.ordinal()" because the return value of "org.apache.calcite.rel.type.RelDataType.getSqlTypeName()" is null

createJoinType is called nowhere in this repo and CROSS JOIN does not produce a RelCrossType — Calcite derives join row types as RelRecordType — so this needs a caller-supplied type through the public entry point, the same reachability class #1244 described for its multiset route. A sweep of the RelDataType implementations on the isthmus test classpath found RelCrossType the only concrete type that inherits the null-returning accessor.

The cost is only diagnostics, but it is the same cost #1244 was about: toSubstrait(RelDataType) documents @throws UnsupportedOperationException, and a caller who follows that still sees an unrelated unchecked exception escape. A null check before the switch, routing into the same default: message, closes it — and the message can name the type, since toString() works fine.

Measured on main at 944b921.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingisthmus

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions