Background
Gluten vendors its Substrait .proto files (gluten-substrait/src/main/resources/substrait/proto/substrait/) pinned near Substrait v0.23.0 with local patches, while upstream Substrait is now at 0.98.0. The JVM plan producer and both native consumers (Velox, ClickHouse) regenerate from this single proto source and ship together, and Gluten's Substrait plans are transient (built per query, serialized across JNI, discarded) — so there is no wire-compatibility constraint and the rebase is a pure code migration.
Goal
Bring the vendored proto to official 0.98.0 core (verbatim) plus Gluten's genuinely engine-specific additions grafted at non-colliding numbers, migrating the JVM producer and both native backends in lockstep.
Approach
Land as small, independently-green PRs, one per message family (each keeps protoc + JVM + both native builds compiling). Minimal rebase first — relocate only colliding fork fields and drop dead/decided-drop items; extracting engine-specific forks to formal Substrait extensions is deferred to a follow-up.
Increments
One PR per message family; each keeps protoc + JVM + both native builds green. Progress: 3 merged · 6 in review · 1 draft · 2 to do · 1 resolved upstream.
Upstream Substrait convergence PRs
Some kept forks converge by landing the equivalent field/type in Substrait core (substrait-io/substrait) rather than by dropping the fork. These are tracked under the apache-gluten label:
Tracked for later extraction waves (not driving a rebase increment):
Note on Type.Nothing
Following the Substrait community sync (2026-07-29), the earlier plan to drop the Type.Nothing fork is superseded: upstream is adding a dedicated core null type (substrait-io/substrait#1147 — Type.Null at kind field 40). Increment 2 relocates Nothing to field 40 to match, so once that PR releases the fork converges by renaming the message Nothing→Null — no field renumbering, no consumer-mapping changes. Gluten keeps Type.Nothing until then.
Related: upstream consolidation work is tracked under the apache-gluten label in substrait-io/substrait.
Background
Gluten vendors its Substrait
.protofiles (gluten-substrait/src/main/resources/substrait/proto/substrait/) pinned near Substrait v0.23.0 with local patches, while upstream Substrait is now at 0.98.0. The JVM plan producer and both native consumers (Velox, ClickHouse) regenerate from this single proto source and ship together, and Gluten's Substrait plans are transient (built per query, serialized across JNI, discarded) — so there is no wire-compatibility constraint and the rebase is a pure code migration.Goal
Bring the vendored proto to official 0.98.0 core (verbatim) plus Gluten's genuinely engine-specific additions grafted at non-colliding numbers, migrating the JVM producer and both native backends in lockstep.
Approach
Land as small, independently-green PRs, one per message family (each keeps
protoc+ JVM + both native builds compiling). Minimal rebase first — relocate only colliding fork fields and drop dead/decided-drop items; extracting engine-specific forks to formal Substrait extensions is deferred to a follow-up.Increments
One PR per message family; each keeps
protoc+ JVM + both native builds green. Progress: 3 merged · 6 in review · 1 draft · 2 to do · 1 resolved upstream.Expression.Enum— merged ([GLUTEN-12597][CORE] Remove unused vendored Substrait proto files and dead proto-based type derivation #12598)plan.proto/extensions.proto→ 0.98 (URI→URN) — merged ([GLUTEN-12597][CORE] Migrate Substrait extension referencing from URI to URN #12604)AdvancedExtension.optimizationsingular → repeated — merged ([GLUTEN-12597][CORE] Make AdvancedExtension.optimization repeated #12642)PrecisionTimestamp*; relocateType.Nothing(kind33→40, kept) — in review ([GLUTEN-12597][CORE] Migrate Substrait type system to 0.98 temporal types #12650)CrossRel→NestedLoopJoinRel(+ join-type enum remap) — in review ([GLUTEN-12597][CORE] Migrate nested loop joins from CrossRel to NestedLoopJoinRel (Substrait 0.98) #12700)WindowRel→ConsistentPartitionWindowRel;WindowType→BoundsType— in review ([GLUTEN-12597][CORE] Migrate WindowRel to ConsistentPartitionWindowRel + BoundsType (Substrait 0.98) #12727)FetchReloffset/count → expressions — in review ([GLUTEN-12597][CORE] Migrate FetchRel offset/count to expressions (Substrait 0.98) #12704)AggregateRel.Grouping→ expression references — in review ([GLUTEN-12597][CORE] Migrate AggregateRel.Grouping to expression references (Substrait 0.98) #12724)ExpandRel.advanced_extension— converged upstream via substrait-io/substrait#1167 (merged, ships 0.100.0); Gluten's graft already matches, no Gluten PR neededTopNRel→Expression count+offset+FetchMode— in review ([GLUTEN-12597][CORE] Migrate TopNRel to Expression count + FetchMode (Substrait 0.98) #12728)WriteRel: relocatebucket_spec(→ 1000); addcreate_mode/advanced_extension;OUTPUT_MODE_MODIFIED_TUPLES→_RECORDS— draft ([GLUTEN-12597][CORE] Migrate WriteRel to Substrait 0.98 (relocate bucket_spec; add create_mode/advanced_extension) #12746)ReadRel: relocatestream_kafka; text-options redesign;VirtualTable.values→expressions— to doReloneof reconciliation to exact 0.98 layout + dropRelRoot.output_schema— to doUpstream Substrait convergence PRs
Some kept forks converge by landing the equivalent field/type in Substrait core (
substrait-io/substrait) rather than by dropping the fork. These are tracked under theapache-glutenlabel:advanced_extensiononExpandRel— merged, ships 0.100.0 → drives increment 5c; Gluten's graft already matches verbatimType.Nullfor untyped nulls — open → increment 2 relocatesType.Nothingtokind40 to match; converge by renamingNothing→Nullonce released (see note below)ReadRel.LocalFiles— open → upstreams Gluten'sjsonread-options fork; increment 7 keeps the vendoredjson = 15until this mergesReadRel.LocalFiles— open → upstreams Gluten's partition-columns fork; the field-16 collision with theicebergfork is a post-merge concernsubstrait-io/substrait#1140— docs on typing untyped nulls — closed, superseded by substrait-io/substrait#1147Tracked for later extraction waves (not driving a rebase increment):
GenerateRelfor lateral view / unnest (@EpsilonPrime) — upstreams the pattern of Gluten'sGenerateRelforkNote on
Type.NothingFollowing the Substrait community sync (2026-07-29), the earlier plan to drop the
Type.Nothingfork is superseded: upstream is adding a dedicated corenulltype (substrait-io/substrait#1147 —Type.Nullatkindfield 40). Increment 2 relocatesNothingto field 40 to match, so once that PR releases the fork converges by renaming the messageNothing→Null— no field renumbering, no consumer-mapping changes. Gluten keepsType.Nothinguntil then.Related: upstream consolidation work is tracked under the
apache-glutenlabel insubstrait-io/substrait.