[VL] Fall back to vanilla Delta write for VariantType columns#12444
Conversation
There was a problem hiding this comment.
Pull request overview
This PR prevents Delta Lake writes from failing when the table schema contains Spark VARIANT columns by bypassing the Velox native columnar write path (which cannot represent VariantType in Arrow) and delegating those writes to the vanilla Delta writer instead.
Changes:
- Add a recursive schema check (
schemaContainsVariant) and guardGlutenOptimisticTransaction.writeFilesto fall back tosuper.writeFileswhen anyVARIANTis present (including nested). - Add a Delta 4.0 Velox-backend test suite validating top-level, struct-nested, and
UPDATEwrites involvingVARIANT.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| backends-velox/src-delta40/main/scala/org/apache/spark/sql/delta/GlutenOptimisticTransaction.scala | Adds a schema-based guard to route VARIANT-containing writes through vanilla Delta instead of the native Velox writer. |
| backends-velox/src-delta40/test/scala/org/apache/spark/sql/delta/GlutenDeltaVariantWriteSuite.scala | Adds coverage ensuring VARIANT writes and updates succeed and round-trip correctly. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
b7c684f to
d97a33e
Compare
d97a33e to
bff7ffa
Compare
bff7ffa to
c40c3c7
Compare
c40c3c7 to
84e9591
Compare
…thout the fix) Adds only GlutenDeltaVariantWriteSuite, WITHOUT the GlutenOptimisticTransaction guard from apache#12444, to demonstrate that the suite fails on an unpatched main: with native Delta write enabled, the Velox write path throws `UnsupportedOperationException: Unsupported data type: variant` at runtime. Do not merge -- this PR exists only to validate that the test is an effective regression test for apache#12444. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Validation that it fails without the fix is here: #12445 (comment) |
|
@baibaichen could you please review? |
| // RowToVeloxColumnarExec transition whose SparkArrowUtil.toArrowSchema call throws | ||
| // `Unsupported data type: variant` at runtime. Delegate writes whose schema contains a | ||
| // variant column to the vanilla Delta write path instead of offloading them. | ||
| if (inputData.schema.existsRecursively(_.isInstanceOf[VariantType])) { |
There was a problem hiding this comment.
Thanks, could we reuse the existing VeloxValidatorApi.validateSchema / doSchemaValidate for Delta/native write schema validation instead of adding another one-off VariantType guard? That would make unsupported Spark types fail consistently before RowToVeloxColumnarExec / Arrow schema conversion.
There was a problem hiding this comment.
Done. Thanks for the suggestion
There was a problem hiding this comment.
@zml1206 I also addressed some Copilot comments. Could you review again please?
84e9591 to
f113e26
Compare
…thout the fix) Adds only GlutenDeltaVariantWriteSuite, WITHOUT the GlutenOptimisticTransaction guard from apache#12444, to demonstrate that the suite fails on an unpatched main: with native Delta write enabled, the Velox write path throws `UnsupportedOperationException: Unsupported data type: variant` at runtime. Do not merge -- this PR exists only to validate that the test is an effective regression test for apache#12444. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
5db07eb to
c143d1d
Compare
c143d1d to
95d8dcf
Compare
There was a problem hiding this comment.
Nit: Could we rename this suite to DeltaVariantWriteSuite? Other Delta suites in this source set do not use the Gluten prefix, and the file already lives under Gluten's Velox Delta tests, so DeltaVariantWriteSuite would be more consistent. cc @zhztheplayer
95d8dcf to
e7b4d4c
Compare
e7b4d4c to
6d77625
Compare
Velox cannot write every Spark type. When native Delta write is enabled, Gluten offloads certain Delta write commands to the native writer via OffloadDeltaCommand -- DataFrameWriter.save (append/overwrite), CREATE/REPLACE TABLE AS SELECT, UPDATE, DELETE and OPTIMIZE. The native write path inserts a RowToVeloxColumnarExec transition whose SparkArrowUtil.toArrowSchema call throws `UnsupportedOperationException: Unsupported data type: <type>` at runtime for any type it has no Arrow mapping for (VariantType is the motivating example). (Plain SQL INSERT INTO and MERGE are not offloaded and were unaffected.) Guard GlutenOptimisticTransaction.writeFiles with the backend's existing schema validator: if VeloxValidatorApi.validateSchema reports the input schema is not supported, delegate to super.writeFiles (the vanilla Delta write path) instead of offloading. This reuses the same check Velox already applies to scan schemas, so unsupported types fall back consistently before Arrow schema conversion rather than adding a one-off VariantType guard. Supported writes are unaffected, and the validator's reason is logged when it falls back. Adds DeltaVariantWriteSuite, which exercises offloaded writes: top-level and struct-nested variant columns via DataFrameWriter.save, plus an UPDATE. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
6d77625 to
decb51c
Compare
What changes are proposed in this pull request?
Velox cannot write every Spark type. When native Delta write is enabled, Gluten offloads certain
Delta write commands to the native columnar writer (
OffloadDeltaCommand) --DataFrameWriter.save(append/overwrite),CREATE/REPLACE TABLE AS SELECT,UPDATE,DELETEand
OPTIMIZE. The native write path inserts aRowToVeloxColumnarExectransition that convertsthe schema via
SparkArrowUtil.toArrowSchema, which throwsUnsupportedOperationException: Unsupported data type: <type>at runtime for any type it has noArrow mapping for (
VariantTypeis the motivating example). (Plain SQLINSERT INTOandMERGEare not offloaded and were unaffected.)
This PR guards
GlutenOptimisticTransaction.writeFileswith the backend's existing schemavalidator: if
VeloxValidatorApi.validateSchema(inputData.schema)reports the schema is notsupported, it delegates to
super.writeFiles(the vanilla Delta write path) instead of offloadingto Velox, and logs an info message when it falls back. This reuses the same validator Velox already
applies to scan schemas (
VeloxBackend.validateDataSchema), so unsupported types fall backconsistently before the Arrow schema conversion -- rather than adding a one-off
VariantTypeguard(per review feedback). Supported writes are unaffected.
How was this patch tested?
Adds
DeltaVariantWriteSuite(backends-velox, delta-4.0). It exercises offloaded writes --top-level and struct-nested variant columns via
DataFrameWriter.save, plus anUPDATE-- andasserts the data is written and read back correctly. The suite runs with the Gluten plugin and
spark.gluten.sql.columnar.backend.velox.delta.enableNativeWrite=true, so these writes go throughthe native path that previously failed.
Was this patch authored or co-authored using generative AI tooling?
Generated-by: GitHub Copilot CLI (Claude Opus 4.8)