This is an automated email from the ASF dual-hosted git repository.

voonhous pushed a commit to branch asf-site
in repository https://gitbox.apache.org/repos/asf/hudi.git


The following commit(s) were added to refs/heads/asf-site by this push:
     new b549b1ca0de7 docs: pushVariantIntoScan workaround for 1.2.x (#20159)
b549b1ca0de7 is described below

commit b549b1ca0de7c293d7d491b7e7ed50baa4ba84bc
Author: voonhous <[email protected]>
AuthorDate: Thu Oct 1 14:08:44 2026 +0800

    docs: pushVariantIntoScan workaround for 1.2.x (#20159)
    
    * docs: pushVariantIntoScan workaround for 1.2.x
    
    The 1.2.1 known issue on VARIANT reads under Spark 4.1 also applies to
    1.2.0 and is wider than stated: two more failures only happen with
    the PushVariantIntoScan rule on, one of them on Copy-on-Write tables.
    List all four, say where each is fixed, and show how to turn the rule
    off when a read hits one of them.
    
    Correct the Spark 4.0 sentence: with the rule turned on there, every
    read of a table with a VARIANT column fails.
    
    Add the same caution to the VARIANT section of the 1.2.0 and 1.2.1
    SQL DDL pages and to the 1.2.0 release notes, and describe the
    setting on the current SQL DDL page.
    
    * docs: flag the silent null-VARIANT case in sql_ddl
    
    The versioned sql_ddl caution only told users to react to a failing
    read. The MOR null-VARIANT case raises no error, so repeat the release
    notes guidance to keep the rule off for those reads.
---
 website/docs/sql_ddl.md                         |  9 +++++++-
 website/releases/release-1.2.md                 | 29 ++++++++++++++++++++-----
 website/versioned_docs/version-1.2.0/sql_ddl.md | 15 ++++++++++++-
 website/versioned_docs/version-1.2.1/sql_ddl.md | 15 ++++++++++++-
 4 files changed, 60 insertions(+), 8 deletions(-)

diff --git a/website/docs/sql_ddl.md b/website/docs/sql_ddl.md
index 150a8197ffc0..205a81387dfa 100644
--- a/website/docs/sql_ddl.md
+++ b/website/docs/sql_ddl.md
@@ -2,7 +2,7 @@
 title: SQL DDL
 summary: "In this page, we discuss using SQL DDL commands with Hudi"
 toc: true
-last_modified_at: 2026-08-07T20:54:32+05:30
+last_modified_at: 2026-09-30T18:50:00+08:00
 ---
 import Tabs from '@theme/Tabs';
 import TabItem from '@theme/TabItem';
@@ -333,6 +333,13 @@ decodable in application code if needed. What you do 
**not** get on Spark 3.x:
 | Flink &lt; 2.1 | Throws `UnsupportedOperationException` on VARIANT columns. |
 | Flink ≥ 2.1 | Surfaces VARIANT as `ROW<metadata BYTES, value BYTES>`. Flink 
can read the underlying struct but cannot decode it as a variant value. |
 
+Spark's `PushVariantIntoScan` rule is controlled by 
`spark.sql.variant.pushVariantIntoScan` (on by
+default from Spark 4.1, off by default in Spark 4.0). Hudi reads the rewritten 
scan on Spark 4.1+.
+If a read of a VARIANT column fails with the rule on, set it to `false`: Spark 
then reads the
+whole VARIANT and evaluates `variant_get` and casts after the scan, with the 
same results. On
+Spark 4.0 keep it off: Hudi rejects a read of a table with a VARIANT column 
while it is on. For
+Hudi 1.2.0 and 1.2.1 on Spark 4.1, see the [1.2 release 
notes](/releases/release-1.2#known-issues).
+
 VARIANT columns are not supported on Lance-backed tables.
 
 Only unshredded VARIANT is exposed at the user-facing level: every Spark/Hudi 
schema conversion
diff --git a/website/releases/release-1.2.md b/website/releases/release-1.2.md
index 5f854617182e..1bdadc3c35e5 100644
--- a/website/releases/release-1.2.md
+++ b/website/releases/release-1.2.md
@@ -2,7 +2,7 @@
 title: "Release 1.2"
 layout: releases
 toc: true
-last_modified_at: 2026-09-24T18:00:00-08:00
+last_modified_at: 2026-09-30T18:50:00+08:00
 ---
 import Tabs from '@theme/Tabs';
 import TabItem from '@theme/TabItem';
@@ -50,15 +50,30 @@ The Trino-Hudi connector now lives in the Hudi repo 
(RFC-105, [#18837](https://g
 
 ## Known Issues
 
-On Spark 4.1, `spark.sql.variant.pushVariantIntoScan` is on by default. With 
it on, snapshot reads of Merge-on-Read tables with `VARIANT` columns can go 
wrong when log files are merged:
+These issues affect 1.2.0 and 1.2.1. Spark's `PushVariantIntoScan` rule is 
controlled by `spark.sql.variant.pushVariantIntoScan`, which is on by default 
in Spark 4.1 and off by default in Spark 4.0.
+
+On Spark 4.1 with the rule on, reads of `VARIANT` columns can go wrong. On 
Merge-on-Read tables, when a snapshot read merges log files:
 
 * A top-level `VARIANT` value set to null by an update is read back as a 
struct of nulls instead of `NULL`, so a filter such as `v IS NULL` misses the 
row.
 * A `VARIANT` nested inside a struct can crash the executor JVM.
+* A query that extracts several paths from one `VARIANT` can fail with 
`NegativeArraySizeException` when rows lack some of those paths.
 
-Copy-on-Write tables are not affected. Spark 4.0 is affected only if 
`spark.sql.variant.pushVariantIntoScan` is turned on, since it is off by 
default there. A fix is tracked in 
[#20039](https://github.com/apache/hudi/pull/20039).
+On Copy-on-Write and Merge-on-Read tables:
 
-:::tip
-Until the fix is released, set `spark.sql.variant.pushVariantIntoScan=false` 
for Spark 4.1 reads of Merge-on-Read tables with `VARIANT` columns.
+* A `VARIANT` column added with `ALTER TABLE ... ADD COLUMNS` cannot be read 
from files written before it was added. The read fails with 
`INVALID_VARIANT_SHREDDING_SCHEMA`.
+
+Reads with the rule off are not affected. The first two are fixed on the 1.2.x 
branch ([#20039](https://github.com/apache/hudi/pull/20039)); no release 
carries that fix yet. The other two are tracked in 
[#20040](https://github.com/apache/hudi/issues/20040) and 
[#20135](https://github.com/apache/hudi/issues/20135).
+
+On Spark 4.0 the rule is not supported. With it turned on, every read of a 
table that has a `VARIANT` column fails with `HoodieSchemaException: Illegal 
initial character: 0`, so leave it at its default there.
+
+:::tip Workaround
+If a read hits one of these, turn the rule off for the session:
+
+```sql
+SET spark.sql.variant.pushVariantIntoScan=false;
+```
+
+or start Spark with `--conf spark.sql.variant.pushVariantIntoScan=false`. 
Spark then reads the whole `VARIANT` and evaluates `variant_get` and casts 
after the scan. The setting is per Spark session and also applies to the 
non-Hudi Parquet tables read in it. The first issue raises no error, so keep 
the rule off for Spark 4.1 reads of Merge-on-Read tables whose `VARIANT` 
columns can be null.
 :::
 
 ## Raw Release Notes
@@ -146,6 +161,10 @@ Engine support: native `VARIANT` keyword on Spark 4.0+; on 
Spark 3.x, VARIANT su
 
 **Limitations as of 1.2.0**: Shredding is not supported in this release. Hudi 
1.2.0 stores the entire VARIANT as the binary value payload plus its 
key-dictionary metadata; frequently accessed fields are not projected into 
native typed columns. As a result, predicates and projections over fields 
inside a VARIANT are not pushed down at the column level. A query that filters 
on a nested field (for example `WHERE tool_calls[0].name = 'search'`) reads and 
decodes the binary payload rather tha [...]
 
+:::caution
+On Spark 4.1, some reads of `VARIANT` columns fail or miss rows on 1.2.0 and 
1.2.1. Setting `spark.sql.variant.pushVariantIntoScan=false` avoids them. See 
[Known Issues](#known-issues).
+:::
+
 ##### BLOB
 
 Images, PDFs, audio, video, and model artifacts are increasingly first-class 
inputs and outputs of data pipelines, but storing them in a separate object 
store and joining by path is awkward, error-prone, and breaks transactional 
guarantees. Putting raw bytes into a `BINARY` column works for small payloads 
but bloats every scan that doesn't need the bytes.
diff --git a/website/versioned_docs/version-1.2.0/sql_ddl.md 
b/website/versioned_docs/version-1.2.0/sql_ddl.md
index 150a8197ffc0..2e31fc6dcf0f 100644
--- a/website/versioned_docs/version-1.2.0/sql_ddl.md
+++ b/website/versioned_docs/version-1.2.0/sql_ddl.md
@@ -2,7 +2,7 @@
 title: SQL DDL
 summary: "In this page, we discuss using SQL DDL commands with Hudi"
 toc: true
-last_modified_at: 2026-08-07T20:54:32+05:30
+last_modified_at: 2026-09-30T18:50:00+08:00
 ---
 import Tabs from '@theme/Tabs';
 import TabItem from '@theme/TabItem';
@@ -333,6 +333,19 @@ decodable in application code if needed. What you do 
**not** get on Spark 3.x:
 | Flink &lt; 2.1 | Throws `UnsupportedOperationException` on VARIANT columns. |
 | Flink ≥ 2.1 | Surfaces VARIANT as `ROW<metadata BYTES, value BYTES>`. Flink 
can read the underlying struct but cannot decode it as a variant value. |
 
+:::caution Spark 4.1 and `spark.sql.variant.pushVariantIntoScan`
+In Hudi 1.2.0 and 1.2.1, reads of VARIANT columns can return wrong rows or 
fail while Spark's
+`PushVariantIntoScan` rule is on, which is the Spark 4.1 default: on 
Merge-on-Read tables when
+log files are merged, and on any table for a VARIANT column added with
+`ALTER TABLE ... ADD COLUMNS`. If a read hits one of these, set
+`spark.sql.variant.pushVariantIntoScan=false` for the session. One case raises 
no error: on
+Merge-on-Read, a VARIANT set to null by an update is read back as a struct of 
nulls, so
+`v IS NULL` misses the row. Keep the rule off for Spark 4.1 reads of 
Merge-on-Read tables whose
+VARIANT columns can be null. On Spark 4.0 keep the setting at
+its default (`false`): with it on, every read of a table with a VARIANT column 
fails. See the
+[1.2 release notes](/releases/release-1.2#known-issues).
+:::
+
 VARIANT columns are not supported on Lance-backed tables.
 
 Only unshredded VARIANT is exposed at the user-facing level: every Spark/Hudi 
schema conversion
diff --git a/website/versioned_docs/version-1.2.1/sql_ddl.md 
b/website/versioned_docs/version-1.2.1/sql_ddl.md
index 150a8197ffc0..2e31fc6dcf0f 100644
--- a/website/versioned_docs/version-1.2.1/sql_ddl.md
+++ b/website/versioned_docs/version-1.2.1/sql_ddl.md
@@ -2,7 +2,7 @@
 title: SQL DDL
 summary: "In this page, we discuss using SQL DDL commands with Hudi"
 toc: true
-last_modified_at: 2026-08-07T20:54:32+05:30
+last_modified_at: 2026-09-30T18:50:00+08:00
 ---
 import Tabs from '@theme/Tabs';
 import TabItem from '@theme/TabItem';
@@ -333,6 +333,19 @@ decodable in application code if needed. What you do 
**not** get on Spark 3.x:
 | Flink &lt; 2.1 | Throws `UnsupportedOperationException` on VARIANT columns. |
 | Flink ≥ 2.1 | Surfaces VARIANT as `ROW<metadata BYTES, value BYTES>`. Flink 
can read the underlying struct but cannot decode it as a variant value. |
 
+:::caution Spark 4.1 and `spark.sql.variant.pushVariantIntoScan`
+In Hudi 1.2.0 and 1.2.1, reads of VARIANT columns can return wrong rows or 
fail while Spark's
+`PushVariantIntoScan` rule is on, which is the Spark 4.1 default: on 
Merge-on-Read tables when
+log files are merged, and on any table for a VARIANT column added with
+`ALTER TABLE ... ADD COLUMNS`. If a read hits one of these, set
+`spark.sql.variant.pushVariantIntoScan=false` for the session. One case raises 
no error: on
+Merge-on-Read, a VARIANT set to null by an update is read back as a struct of 
nulls, so
+`v IS NULL` misses the row. Keep the rule off for Spark 4.1 reads of 
Merge-on-Read tables whose
+VARIANT columns can be null. On Spark 4.0 keep the setting at
+its default (`false`): with it on, every read of a table with a VARIANT column 
fails. See the
+[1.2 release notes](/releases/release-1.2#known-issues).
+:::
+
 VARIANT columns are not supported on Lance-backed tables.
 
 Only unshredded VARIANT is exposed at the user-facing level: every Spark/Hudi 
schema conversion

Reply via email to