Skip to content

feat(core)!: bump substrait to v0.99.0 - #1042

Open
nielspardon wants to merge 1 commit into
substrait-io:mainfrom
nielspardon:bump-substrait-v0.99.0
Open

feat(core)!: bump substrait to v0.99.0#1042
nielspardon wants to merge 1 commit into
substrait-io:mainfrom
nielspardon:bump-substrait-v0.99.0

Conversation

@nielspardon

@nielspardon nielspardon commented Jul 27, 2026

Copy link
Copy Markdown
Member

Summary

Bumps the substrait-packaging artifacts to v0.99.0 and implements its one feature — the new built-in unbound type (substrait-io/substrait#1081).

unbound is a placeholder for a type that has not yet been bound to a concrete type. It lets a producer serialize the shape of a plan — its relations and the names and ordering of its fields — before the concrete field types are known; a downstream binder fills them in before execution. A plan that contains an unbound type anywhere within it is partially bound.

Changes

  • substrait-packaging bumped 0.98.00.99.0 in gradle/libs.versions.toml. This pulls in the regenerated proto (adds Type.Unbound), the repackaged extension YAMLs (the old extensions/unknown.yaml placeholder is dropped upstream), and the dialect schema with UNBOUND. The spec version reported by io.substrait.SubstraitVersion.VERSION follows from the same catalog bump.
  • New Type.Unbound POJO, wired through TypeVisitor and both proto converters (TypeProtoConverter / ProtoTypeConverter), plus the remaining direct TypeVisitor implementors (StringTypeVisitor, NamedFieldCountingTypeVisitor, Isthmus/Spark IgnoreNullableAndParameters, examples TypeStringify).
  • TypeKind.UNBOUND added to the dialect model for parity with the updated dialect schema.
  • Tests: a bare Type.Unbound proto round-trip, and a NamedScan whose schema carries unbound field types (the partially-bound-plan use case).

A note on nullability

Unlike every other Substrait type, unbound's proto message is empty: it carries no nullability and no parameters (both are determined only when it is bound). So Type.Unbound.nullable() throws UnsupportedOperationException and withNullable() is a no-op, rather than falsely reporting the type as non-nullable. Isthmus and Spark reject unbound types — their type visitors inherit the throwing default — matching the spec guidance that consumers which do not support partially bound plans should reject them.

Closes #1038

BREAKING CHANGE: adds Type.Unbound and a new TypeVisitor.visit(Type.Unbound) method that direct TypeVisitor implementors must handle.

🤖 Generated with AI

Bumps the substrait-packaging artifacts in the version catalog to 0.99.0,
which regenerates the proto (adding Type.Unbound) and repackages the extension
YAMLs (dropping the old extensions/unknown.yaml placeholder). The spec version
reported by SubstraitVersion.VERSION follows from the same catalog bump.

Adds the new built-in `unbound` type introduced in Substrait v0.99.0: a
placeholder for a type that has not yet been bound to a concrete type. It lets
a producer serialize the shape of a plan (its relations and the names and
ordering of its fields) before the concrete field types are known. A plan
containing an unbound type is partially bound and must be bound before
execution.

Unlike every other type, the unbound type carries no nullability and no
parameters, so Type.Unbound.nullable() throws and withNullable() is a no-op.
Isthmus and Spark reject unbound types, matching the spec guidance that
consumers not supporting partially bound plans should reject them.

BREAKING CHANGE: adds Type.Unbound and a new TypeVisitor.visit(Type.Unbound)
method that direct TypeVisitor implementors must handle.
@nielspardon
nielspardon force-pushed the bump-substrait-v0.99.0 branch from 0ac19a2 to 2f1f443 Compare July 28, 2026 13:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Update to Substrait v0.99.0

1 participant