[VL] Support native Spark 4.1 OneRowRelationExec - #12963
Conversation
|
Run Gluten Clickhouse CI on x86 |
Add native Velox execution for Spark 4.1 OneRowRelationExec using a zero-column, one-row Substrait virtual table converted to a Velox ValuesNode. Add conservative dependency-free stage execution and preserve fallback for unsupported Spark versions and backends. Implement complete native support for Spark 4.1 OneRowRelationExec in Apache Gluten. Preserve exact Spark semantics, backend and version isolation, AQE and subquery reuse, metrics compatibility, and existing failure behavior. Cover the implementation with focused JVM, Spark integration, and native tests. - Apache Gluten contribution guide: https://github.com/apache/gluten/blob/main/CONTRIBUTING.md - Apache Spark 4.1 physical operators: https://github.com/apache/spark/blob/v4.1.0/sql/core/src/main/scala/org/apache/spark/sql/execution/basicPhysicalOperators.scala - Substrait algebra definition: https://github.com/substrait-io/substrait/blob/main/proto/substrait/algebra.proto Spark 4.1 uses OneRowRelationExec for literal-only queries and scalar subqueries. Leaving this leaf in Spark creates an avoidable fallback and row-to-columnar boundary inside otherwise native plans. A zero-column, one-row ValuesNode represents the operator without inventing a dummy column. The no-input execution capability is explicit and conservatively propagated so unrelated empty or broadcast-only stages retain their previous failure behavior. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 4c916137-55c6-47f0-a5e3-90cdd2098486
36afad0 to
76b4ff5
Compare
|
Run Gluten Clickhouse CI on x86 |
## Summary Exclude Spark's SPARK-52060 plan-shape assertions from the Spark 4.1 Velox suite because Gluten intentionally replaces OneRowRelationExec with its native transformer. Extend Gluten's native OneRowRelation test across both whole-stage codegen settings and both AQE settings so the original behavioral coverage is retained. ## Prompting Intent Monitor Apache Gluten PR apache#12963 until every pipeline succeeds. Diagnose and fix any actionable failure, validate the fix, commit and push it, and repeat the CI watching process until the draft can be marked ready for review. ## Linked Sources - Apache Gluten PR apache#12963: apache#12963 - Failing Spark 4.1 CI job: https://github.com/apache/gluten/actions/runs/33756022513/job/100657209417 - Apache Spark SPARK-52060 test: https://github.com/apache/spark/blob/v4.1.0/sql/core/src/test/scala/org/apache/spark/sql/SQLQuerySuite.scala ## Rationale The inherited Spark tests require Spark's physical OneRowRelationExec node to remain visible, which conflicts with the native offload this PR deliberately adds. A Velox-only exclusion follows Gluten's existing treatment of upstream plan-shape assertions, while exercising the native replacement under the same codegen modes preserves correctness coverage without weakening production behavior. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 4c916137-55c6-47f0-a5e3-90cdd2098486
|
Run Gluten Clickhouse CI on x86 |
## Summary Exclude Spark's SPARK-52060 plan-shape assertions from the Spark 4.1 Velox suite because Gluten intentionally replaces OneRowRelationExec with its native transformer. Extend Gluten's native OneRowRelation test across both whole-stage codegen settings and both AQE settings so the original behavioral coverage is retained. ## Prompting Intent Monitor Apache Gluten PR apache#12963 until every pipeline succeeds. Diagnose and fix any actionable failure, validate the fix, commit and push it, and repeat the CI watching process until the draft can be marked ready for review. ## Linked Sources - Apache Gluten PR apache#12963: apache#12963 - Failing Spark 4.1 CI job: https://github.com/apache/gluten/actions/runs/33756022513/job/100657209417 - Apache Spark SPARK-52060 test: https://github.com/apache/spark/blob/v4.1.0/sql/core/src/test/scala/org/apache/spark/sql/SQLQuerySuite.scala ## Rationale The inherited Spark tests require Spark's physical OneRowRelationExec node to remain visible, which conflicts with the native offload this PR deliberately adds. A Velox-only exclusion follows Gluten's existing treatment of upstream plan-shape assertions, while exercising the native replacement under the same codegen modes preserves correctness coverage without weakening production behavior. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 4c916137-55c6-47f0-a5e3-90cdd2098486
fddf696 to
37cb99d
Compare
|
Run Gluten Clickhouse CI on x86 |
## Summary Exclude Spark's SPARK-52060 plan-shape assertions from the Spark 4.1 Velox suite because Gluten intentionally replaces OneRowRelationExec with its native transformer. Extend Gluten's native OneRowRelation test across both whole-stage codegen settings and both AQE settings so the original behavioral coverage is retained. ## Prompting Intent Monitor Apache Gluten PR apache#12963 until every pipeline succeeds. Diagnose and fix any actionable failure, validate the fix, commit and push it, and repeat the CI watching process until the draft can be marked ready for review. ## Linked Sources - Apache Gluten PR apache#12963: apache#12963 - Failing Spark 4.1 CI job: https://github.com/apache/gluten/actions/runs/33756022513/job/100657209417 - Apache Spark SPARK-52060 test: https://github.com/apache/spark/blob/v4.1.0/sql/core/src/test/scala/org/apache/spark/sql/SQLQuerySuite.scala ## Rationale The inherited Spark tests require Spark's physical OneRowRelationExec node to remain visible, which conflicts with the native offload this PR deliberately adds. A Velox-only exclusion follows Gluten's existing treatment of upstream plan-shape assertions, while exercising the native replacement under the same codegen modes preserves correctness coverage without weakening production behavior. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 4c916137-55c6-47f0-a5e3-90cdd2098486
37cb99d to
9545cad
Compare
|
Run Gluten Clickhouse CI on x86 |
There was a problem hiding this comment.
🔵 Needs a closer look
It changes execution semantics and plan conversion across JVM + native (including partition discovery behavior), which warrants final human review despite strong test coverage.
Pull request overview
Adds Velox-backend support for Spark 4.1’s OneRowRelationExec by recognizing it in the Spark 4.1 shim, transforming it into a native Velox-friendly leaf (ValuesNode via Substrait ReadRel.VirtualTable), and introducing an explicit “no-input execution” capability to safely run dependency-free native stages with exactly one Spark partition.
Changes:
- Extend Spark 4.1 shims and offload rules to detect
OneRowRelationExecand route it through a backend-specific transformer hook. - Introduce Substrait virtual-table construction on the JVM side plus Velox conversion/validation to
ValuesNode(including trivial-leaf split bookkeeping). - Add “supportsNoInputExecution” capability and propagate it through safe operators (unary, union, streamed-side broadcast joins), with broad JVM + native test coverage and documentation updates.
File summaries
| File | Description |
|---|---|
| shims/spark41/src/test/scala/org/apache/gluten/sql/shims/spark41/Spark41ShimsOneRowRelationSuite.scala | Adds Spark 4.1 shim tests for OneRowRelationExec recognition and false-positive rejection. |
| shims/spark41/src/main/scala/org/apache/gluten/sql/shims/spark41/Spark41Shims.scala | Implements isOneRowRelationExec for Spark 4.1 using the Spark 4.1 class type. |
| shims/common/src/main/scala/org/apache/gluten/sql/shims/SparkShims.scala | Adds cross-version shim hook isOneRowRelationExec (default false). |
| gluten-ut/spark41/src/test/scala/org/apache/spark/sql/GlutenSQLQuerySuite.scala | Adjusts Spark 4.1 explain-plan expectations to account for native OneRowRelation in Velox. |
| gluten-ut/spark41/src/test/scala/org/apache/gluten/utils/velox/VeloxTestSettings.scala | Excludes a Spark test whose plan checks conflict with Gluten’s native replacement. |
| gluten-substrait/src/test/scala/org/apache/gluten/substrait/rel/VirtualTableRelNodeSuite.scala | Adds unit tests for virtual-table rel creation/validation and protobuf round-tripping. |
| gluten-substrait/src/test/scala/org/apache/gluten/substrait/rel/VirtualTableProtoSuite.scala | Updates rationale/comments around virtual-table descriptor pinning. |
| gluten-substrait/src/test/scala/org/apache/gluten/execution/WholeStageNoInputSuite.scala | Adds unit tests for synthetic single-partition behavior with no non-broadcast inputs. |
| gluten-substrait/src/test/scala/org/apache/gluten/backendsapi/SparkPlanExecApiSuite.scala | Verifies unsupported backends preserve original Spark plans for this hook. |
| gluten-substrait/src/main/scala/org/apache/gluten/extension/columnar/offload/OffloadSingleNodeRules.scala | Adds offload rule path to transform OneRowRelationExec via backend API hook. |
| gluten-substrait/src/main/scala/org/apache/gluten/execution/WholeStageTransformer.scala | Introduces supportsNoInputExecution and uses it in partition discovery for whole-stage execution. |
| gluten-substrait/src/main/scala/org/apache/gluten/execution/UnionExecTransformer.scala | Propagates no-input capability across union when all children are eligible. |
| gluten-substrait/src/main/scala/org/apache/gluten/execution/BroadcastNestedLoopJoinExecTransformer.scala | Propagates no-input capability from the streamed side for nested-loop broadcast join. |
| gluten-substrait/src/main/scala/org/apache/gluten/backendsapi/SparkPlanExecApi.scala | Adds backend hook genOneRowRelationExecTransformer (default no-op). |
| gluten-substrait/src/main/java/org/apache/gluten/substrait/rel/VirtualTableRelNode.java | Implements JVM-side Substrait virtual-table ReadRel construction. |
| gluten-substrait/src/main/java/org/apache/gluten/substrait/rel/RelBuilder.java | Adds makeVirtualTableReadRel helper and registers rel-to-operator mapping. |
| docs/velox-backend-support-progress.md | Documents ReadRel.VirtualTable and Spark 4.1 OneRowRelationExec support status/constraints. |
| cpp/velox/tests/Substrait2VeloxValuesNodeConversionTest.cc | Adds native tests for zero-column values, split isolation, and validation behaviors. |
| cpp/velox/tests/data/substrait_virtualTable_emptySchema.json | Adds test JSON plan for empty-schema virtual table inputs. |
| cpp/velox/substrait/SubstraitToVeloxPlan.cc | Converts Substrait virtual tables to Velox ValuesNode with validation and trivial-leaf split info. |
| backends-velox/src/test/scala/org/apache/gluten/execution/MiscOperatorSuite.scala | Expands integration coverage for OneRowRelation across AQE/codegen/union/joins and mixed scans. |
| backends-velox/src/main/scala/org/apache/gluten/execution/OneRowRelationExecTransformer.scala | Adds Velox leaf transformer emitting a zero-column, one-row Substrait virtual table. |
| backends-velox/src/main/scala/org/apache/gluten/execution/HashJoinExecTransformer.scala | Propagates no-input capability from streamed side for broadcast hash join. |
| backends-velox/src/main/scala/org/apache/gluten/backendsapi/velox/VeloxSparkPlanExecApi.scala | Implements Velox-specific OneRowRelation transformer generation with tag preservation. |
Review details
- Files reviewed: 24/24 changed files
- Comments generated: 0
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
What changes are proposed in this pull request?
Spark 4.1 uses
OneRowRelationExecas the physical source for zero-column,one-row inputs in literal-only queries and scalar subqueries. The Velox backend
does not currently transform this leaf, so an otherwise native plan must retain
a Spark operator and cross a row-to-columnar boundary.
This PR adds native Spark 4.1
OneRowRelationExecsupport by:4.1 dependency into common code;
plan for unsupported backends and Spark versions;
table and converting it to a Velox
ValuesNode;supported dependency-free native stage receives exactly one Spark partition;
broadcast-join paths;
values, and split-free native conversion; and
OneRowRelationExecbehavior.This is needed for Spark 4.1 native-plan completeness. The existing Spark
fallback produces correct results, but it fragments literal-only and
scalar-subquery pipelines and leaves an avoidable execution boundary. The new
no-input behavior is deliberately opt-in: unrelated empty or broadcast-only
stages retain their previous failure behavior, and unsupported backends retain
their original Spark plans.
This PR is not presented as a performance optimization. Its purpose is to close
the Spark 4.1 capability gap with explicit execution semantics and regression
coverage.
How was this patch tested?
Added and ran JVM unit, Spark integration, and native C++ tests covering:
validation, zero-column cardinality, and legal zero-row execution;
access and unsupported-stage rejection;
join, broadcast nested-loop join, and multi-partition file-scan coexistence;
removal of the OneRow-specific fallback boundary; and
ValuesNodeexecution, malformed and non-literal rejection,trivial-leaf registration, and file-split isolation.
Results on the current
mainbase:gluten-substraittests passed.MiscOperatorSuitetests passed; one existing test wasignored.
skipped.
clang-format-15, license-header, andsource-hygiene checks passed.
Was this patch authored or co-authored using generative AI tooling?
Co-authored by: GitHub Copilot CLI 1.0.83-0