Skip to content

[GLUTEN-12597][CORE] Remodel Kafka read onto ReadRel.ExtensionTable (Substrait 0.98) - #12841

Merged
zhouyuan merged 1 commit into
apache:mainfrom
nielspardon:feat/substrait-0.98-kafka-extension-table
Oct 6, 2026
Merged

zhouyuan merged 1 commit into
apache:mainfrom
nielspardon:feat/substrait-0.98-kafka-extension-table

Conversation

@nielspardon

@nielspardon nielspardon commented Aug 20, 2026 •

Copy link
Copy Markdown
Contributor

What changes are proposed in this pull request?

Part of #12597.

This makes ReadRel.read_type verbatim upstream Substrait 0.98 by removing Gluten's last graft on it -- the bool stream_kafka = 1000 discriminator and the nested ReadRel.StreamKafka message -- and remodels Gluten's ClickHouse Kafka streaming read onto the official extension_table = 8 path, the same mechanism MergeTree and Range already use. read_type now matches upstream exactly, which never allocated field 1000, so the retired tag is not reserved.

The StreamKafka payload moves out of algebra.proto into a new Gluten-owned kafka.proto (package gluten, org.apache.gluten.proto), packed into a google.protobuf.Any and carried in ReadRel.ExtensionTable.detail. The native consumer discriminates a Kafka read by the detail's type_url via detail().Is<gluten::StreamKafka>() -- mirroring the already-merged Velox Iceberg idiom enhancement().Is<gluten::IcebergReadExtension>(). This Any-in-an-official-extension-field pattern is the preferred way to carry Gluten payloads going forward, rather than grafting new fields onto the vendored Substrait messages; WriteRel.bucket_spec (field 1000) remains the one legacy graft.

Compatibility: this is a JVM-producer + ClickHouse-consumer change with no wire-compatibility constraint -- Gluten plans are transient, and the JAR and native library are generated from one proto source and ship together. Two side effects are worth calling out. The Kafka split-info payload changes from a bare StreamKafka to a ReadRel.ExtensionTable wrapping it; and read_type, which the unconditional stream_kafka flag used to set on every ReadRel, is now left unset for non-Kafka scans (no native code reads read_type_case). A JAR and native library must therefore be rebuilt together. This path is ClickHouse-only -- Kafka has no Velox path.

How was this patch tested?

Locally: standalone protoc confirms the post-delete read_type oneof is well-formed and that the relocated gluten.StreamKafka generates cleanly under both native codegen styles (flat kafka.pb.h). The JVM producer builds green -- mvn -Pspark-3.5 -Pkafka -pl gluten-core,gluten-substrait,gluten-kafka -am -DskipTests clean install (-Pkafka is required; clean clears stale generated .java from the removed message) -- with no lingering references to ReadRel.StreamKafka / setStreamKafka and scalastyle/checkstyle passing in-phase.

The native ClickHouse local-engine build (ReadRelParser.cpp, StreamKafkaRelParser.cpp, generated kafka.pb.*) needs the Linux/Docker toolchain and is verified here by inspection only. The Kafka runtime suites (GlutenKafkaScanSuite / ClickhouseGlutenKafkaScanSuite) require -Pkafka plus an external localhost:9092 broker and are not run by any in-repo GitHub Actions job, so the end-to-end Kafka path is not exercised in CI. A maintainer running -Pkafka against a broker before merge would be the real end-to-end check; the JVM toProtobuf and the CH deserialize are kept as literal mirrors of the existing extension-table readers to minimize that risk.

Was this patch authored or co-authored using generative AI tooling?

Generated-by: Claude Code (Claude Opus 4.8)

🤖 Generated with AI

@nielspardon
nielspardon force-pushed the feat/substrait-0.98-kafka-extension-table branch 4 times, most recently from 550be87 to bedfb96 Compare August 20, 2026 16:55
@github-actions github-actions Bot added CORE works for Gluten Core CLICKHOUSE DOCS labels Aug 20, 2026
@github-actions

Copy link
Copy Markdown

Run Gluten Clickhouse CI on x86

3 similar comments
@github-actions

Copy link
Copy Markdown

Run Gluten Clickhouse CI on x86

@github-actions

Copy link
Copy Markdown

Run Gluten Clickhouse CI on x86

@github-actions

Copy link
Copy Markdown

Run Gluten Clickhouse CI on x86

@github-actions

Copy link
Copy Markdown

Run Gluten Clickhouse CI on x86

@nielspardon
nielspardon force-pushed the feat/substrait-0.98-kafka-extension-table branch from bedfb96 to 0f4d98c Compare August 20, 2026 17:46
@github-actions

Copy link
Copy Markdown

Run Gluten Clickhouse CI on x86

@zhouyuan
zhouyuan requested a lite review from Copilot August 20, 2026 19:17

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR continues the Substrait 0.98 ReadRel.read_type migration by removing Gluten’s legacy Kafka graft from the vendored Substrait proto and modeling ClickHouse Kafka reads via the official ReadRel.ExtensionTable path, carrying a Gluten-owned gluten.StreamKafka payload in google.protobuf.Any.

Changes:

  • Remove stream_kafka / ReadRel.StreamKafka from algebra.proto and rely on ReadRel.ExtensionTable + Any type discrimination for Kafka.
  • Introduce gluten-owned kafka.proto (gluten.StreamKafka) and update JVM producer + ClickHouse native parser accordingly.
  • Add a shared JVM helper to pack ReadRel.ExtensionTable and adjust build wiring (protobuf dependency + CMake glob).

Reviewed changes

Copilot reviewed 15 out of 15 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
gluten-substrait/src/main/scala/org/apache/gluten/utils/SubstraitUtil.scala Adds helper to pack Gluten payloads into ReadRel.ExtensionTable.detail.
gluten-substrait/src/main/scala/org/apache/gluten/utils/SubstraitPlanPrinterUtil.scala Extends TypeRegistry so Any-carried Gluten messages can print/parse as JSON.
gluten-substrait/src/main/resources/substrait/proto/substrait/algebra.proto Makes ReadRel.read_type match upstream (removes Kafka graft; keeps official fields).
gluten-substrait/src/main/java/org/apache/gluten/substrait/rel/StreamKafkaSourceNode.java Emits split-info payload as ReadRel.ExtensionTable containing gluten.StreamKafka in Any.
gluten-substrait/src/main/java/org/apache/gluten/substrait/rel/ReadRelNode.java Replaces boolean Kafka discriminator with an extension_table.detail Any.
gluten-kafka/src/main/scala/org/apache/gluten/execution/MicroBatchScanExecTransformer.scala Marks Kafka reads by stamping gluten.StreamKafka type into the in-plan extension_table.
gluten-kafka/pom.xml Moves protobuf-java to provided scope for compilation/runtime needs.
gluten-core/src/main/resources/org/apache/gluten/proto/kafka.proto Adds Gluten-owned StreamKafka message definition for Any payloads.
docs/developers/SubstraitModifications.md Updates Substrait modification inventory (removes old StreamKafka entry).
cpp-ch/local-engine/proto/CMakeLists.txt Makes proto glob reconfigure-aware (CONFIGURE_DEPENDS).
cpp-ch/local-engine/Parser/SerializedPlanParser.cpp Ensures Kafka reads always consume a split-info entry (asserts extension_table present).
cpp-ch/local-engine/Parser/RelParsers/StreamKafkaRelParser.cpp Parses split-info as ReadRel::ExtensionTable and unpacks gluten.StreamKafka from Any.
cpp-ch/local-engine/Parser/RelParsers/ReadRelParser.cpp Detects Kafka reads by extension_table.detail().Is<gluten::StreamKafka>().
backends-clickhouse/src/main/java/org/apache/spark/sql/execution/datasources/clickhouse/ExtensionTableNode.java Reuses the new helper to build extension tables.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@nielspardon
nielspardon marked this pull request as ready for review August 21, 2026 05:44
@nielspardon
nielspardon force-pushed the feat/substrait-0.98-kafka-extension-table branch from 0f4d98c to 54cd984 Compare August 21, 2026 05:50
@github-actions

Copy link
Copy Markdown

Run Gluten Clickhouse CI on x86

@nielspardon
nielspardon force-pushed the feat/substrait-0.98-kafka-extension-table branch from 54cd984 to 3264a7f Compare August 21, 2026 06:32
@github-actions

Copy link
Copy Markdown

Run Gluten Clickhouse CI on x86

@nielspardon

Copy link
Copy Markdown
Contributor Author

Run Gluten Clickhouse CI

@zhouyuan
zhouyuan requested a review from exmy August 21, 2026 09:08
@nielspardon
nielspardon force-pushed the feat/substrait-0.98-kafka-extension-table branch from 3264a7f to 14f322f Compare August 27, 2026 12:39
@github-actions

Copy link
Copy Markdown

Run Gluten Clickhouse CI on x86

@exmy
exmy requested a review from zzcclp September 2, 2026 02:24
…Substrait 0.98)

Part of apache#12597. Stacked on apache#12832 (the iceberg_table half of the ReadRel
read_type migration).

Makes ReadRel.read_type verbatim upstream Substrait 0.98 by removing Gluten's
last graft on it -- the `bool stream_kafka = 1000` discriminator and the
nested `ReadRel.StreamKafka` message. read_type now matches upstream exactly,
which never allocated field 1000, so the retired tag is not reserved.

Gluten's Kafka streaming read is remodeled onto the official
`extension_table = 8` path, the mechanism MergeTree and Range already use.
The StreamKafka payload moves to a new Gluten-owned `kafka.proto`
(`package gluten`, `org.apache.gluten.proto`), packed into a
`google.protobuf.Any` and carried in `ReadRel.ExtensionTable.detail`. The
native consumer discriminates a Kafka read by the detail's type_url
(`detail().Is<gluten::StreamKafka>()`) -- mirroring the already-merged Velox
Iceberg idiom (`enhancement().Is<gluten::IcebergReadExtension>()`). This
Any-in-an-official-extension-field pattern is preferred over grafting new
fields; `WriteRel.bucket_spec` (field 1000) remains the one legacy graft.

Gluten plans are transient and the JAR + native library are generated from one
proto source and ship together, so there is no wire-compatibility constraint.
Two side effects: the Kafka split-info payload changes from a bare StreamKafka
to a ReadRel.ExtensionTable wrapping it, and read_type -- previously set on
every ReadRel by the unconditional stream_kafka flag -- is now left unset for
non-Kafka scans (no native code reads read_type_case). A JAR and native library
must therefore be rebuilt together. ClickHouse-only; Kafka has no Velox path.

Generated-by: Claude Code (Claude Opus 4.8)
@nielspardon
nielspardon force-pushed the feat/substrait-0.98-kafka-extension-table branch from 14f322f to e31e44a Compare September 28, 2026 08:14
@github-actions

Copy link
Copy Markdown

Run Gluten Clickhouse CI on x86

@nielspardon

Copy link
Copy Markdown
Contributor Author

Rebased and fixed conflicts

@zzcclp

zzcclp commented Oct 3, 2026

Copy link
Copy Markdown
Contributor

LGTM

@zhouyuan zhouyuan left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@zhouyuan
zhouyuan merged commit 6c1baac into apache:main Oct 6, 2026
60 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLICKHOUSE CORE works for Gluten Core DOCS

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants