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

JingsongLi pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/paimon.git


The following commit(s) were added to refs/heads/master by this push:
     new ee43f5a9fe [spark] Fix conditional query failing on variant casts 
(#9385)
ee43f5a9fe is described below

commit ee43f5a9fe171a0bbb1e39c8521a94b23a650ca2
Author: Arnav Balyan <[email protected]>
AuthorDate: Wed Aug 26 08:13:26 2026 +0530

    [spark] Fix conditional query failing on variant casts (#9385)
---
 .../paimon/spark/read/VariantPushDownUtils.scala   |  7 ++++---
 .../apache/paimon/spark/sql/VariantTestBase.scala  | 22 ++++++++++++++++++----
 2 files changed, 22 insertions(+), 7 deletions(-)

diff --git 
a/paimon-spark/paimon-spark-common/src/main/scala/org/apache/paimon/spark/read/VariantPushDownUtils.scala
 
b/paimon-spark/paimon-spark-common/src/main/scala/org/apache/paimon/spark/read/VariantPushDownUtils.scala
index 16abb0e2d9..1ac017ac66 100644
--- 
a/paimon-spark/paimon-spark-common/src/main/scala/org/apache/paimon/spark/read/VariantPushDownUtils.scala
+++ 
b/paimon-spark/paimon-spark-common/src/main/scala/org/apache/paimon/spark/read/VariantPushDownUtils.scala
@@ -19,7 +19,7 @@
 package org.apache.paimon.spark.read
 
 import org.apache.paimon.data.variant.VariantMetadataUtils
-import org.apache.paimon.types.{DataField, RowType}
+import org.apache.paimon.types.{DataField, RowType, VarCharType}
 
 import scala.collection.JavaConverters._
 import scala.collection.mutable
@@ -40,8 +40,9 @@ object VariantPushDownUtils {
 
     var i = 0
     while (i < extractions.length) {
-      val (path, _, isVariantTarget) = extractions(i)
-      if (path.isEmpty || isVariantTarget) {
+      val (path, info, isVariantTarget) = extractions(i)
+      val canThrow = info.failOnError && 
!info.paimonType.isInstanceOf[VarCharType]
+      if (path.isEmpty || isVariantTarget || canThrow) {
         if (path.nonEmpty) {
           rejected += path
         }
diff --git 
a/paimon-spark/paimon-spark-ut/src/test/scala/org/apache/paimon/spark/sql/VariantTestBase.scala
 
b/paimon-spark/paimon-spark-ut/src/test/scala/org/apache/paimon/spark/sql/VariantTestBase.scala
index 4cb3837071..0799310b74 100644
--- 
a/paimon-spark/paimon-spark-ut/src/test/scala/org/apache/paimon/spark/sql/VariantTestBase.scala
+++ 
b/paimon-spark/paimon-spark-ut/src/test/scala/org/apache/paimon/spark/sql/VariantTestBase.scala
@@ -1034,19 +1034,33 @@ abstract class VariantTestBase extends 
PaimonSparkTestBase {
     sql("""INSERT INTO T VALUES (1, 
parse_json('{"age":26,"city":"Beijing"}'))""")
 
     val df =
-      sql("SELECT id, variant_get(v, '$.age', 'int'), variant_get(v, '$.city', 
'string') FROM T")
+      sql(
+        "SELECT id, try_variant_get(v, '$.age', 'int'), variant_get(v, 
'$.city', 'string') FROM T")
     val v = fieldByPath(scanReadSchemaOf(df), Seq("v"))
     if (variantPushDownEnabled) assertVariantStruct(v, expectedFieldCount = 2)
     else assert(isVariantType(v.dataType))
     checkAnswer(df, Seq(Row(1, 26, "Beijing")))
   }
 
+  test("Paimon Variant pushdown: strict cast preserves conditional 
evaluation") {
+    assume(gteqSpark4_1)
+    sql("CREATE TABLE T (id INT, v VARIANT)")
+    sql("""INSERT INTO T VALUES
+          | (0, parse_json('{"a":"bad"}')),
+          | (1, parse_json('{"a":1}'))
+          |""".stripMargin)
+
+    val df = sql("SELECT id, IF(id = 1, variant_get(v, '$.a', 'int'), NULL) 
FROM T ORDER BY id")
+    assert(isVariantType(fieldByPath(scanReadSchemaOf(df), Seq("v")).dataType))
+    checkAnswer(df, Seq(Row(0, null), Row(1, 1)))
+  }
+
   test("Paimon Variant pushdown: nested variant column inside a struct") {
     assume(gteqSpark4_1)
     sql("CREATE TABLE T (id INT, nested STRUCT<v: VARIANT, x: INT>)")
     sql("""INSERT INTO T VALUES (1, named_struct('v', 
parse_json('{"age":26}'), 'x', 100))""")
 
-    val df = sql("SELECT id, variant_get(nested.v, '$.age', 'int') FROM T")
+    val df = sql("SELECT id, try_variant_get(nested.v, '$.age', 'int') FROM T")
     val v = fieldByPath(scanReadSchemaOf(df), Seq("nested", "v"))
     if (variantPushDownEnabled) assertVariantStruct(v, expectedFieldCount = 1)
     else assert(isVariantType(v.dataType))
@@ -1073,7 +1087,7 @@ abstract class VariantTestBase extends 
PaimonSparkTestBase {
     sql("""INSERT INTO T VALUES (1, parse_json('{"a":1}'), 
parse_json('{"x":"hi","y":"bye"}'))""")
 
     val df = sql(
-      "SELECT variant_get(v1, '$.a', 'int'), variant_get(v2, '$.x', 'string'), 
variant_get(v2, '$.y', 'string') FROM T")
+      "SELECT try_variant_get(v1, '$.a', 'int'), variant_get(v2, '$.x', 
'string'), variant_get(v2, '$.y', 'string') FROM T")
     val readSchema = scanReadSchemaOf(df)
     val v1 = fieldByPath(readSchema, Seq("v1"))
     val v2 = fieldByPath(readSchema, Seq("v2"))
@@ -1105,7 +1119,7 @@ abstract class VariantTestBase extends 
PaimonSparkTestBase {
     sql("CREATE TABLE T (id INT, v VARIANT)")
     sql("""INSERT INTO T VALUES (1, parse_json('{"age":26}'))""")
 
-    val df = sql("SELECT variant_get(v, '$.age', 'int') FROM T")
+    val df = sql("SELECT try_variant_get(v, '$.age', 'int') FROM T")
     val desc = df.queryExecution.optimizedPlan
       .collectFirst { case DataSourceV2ScanRelation(_, scan, _, _, _) => 
scan.description() }
       .getOrElse(fail("expected a DataSourceV2ScanRelation in the plan"))

Reply via email to