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

diqiu50 pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/gravitino.git


The following commit(s) were added to refs/heads/main by this push:
     new 636288c60a [#10302] fix(spark-connector): handle Hive default 
partition token in SHOW PARTITIONS (#11290)
636288c60a is described below

commit 636288c60a5b256724ddde742a7b911dd0b4b9c7
Author: mchades <[email protected]>
AuthorDate: Fri May 29 14:46:45 2026 +0800

    [#10302] fix(spark-connector): handle Hive default partition token in SHOW 
PARTITIONS (#11290)
    
    ### What changes were proposed in this pull request?
    
    This PR fixes `SHOW PARTITIONS` failure in Spark connector when a Hive
    partition value is null and represented as the default Hive partition
    token for non-string partition columns.
    
    Changes include:
    - Treat `__HIVE_DEFAULT_PARTITION__` and `HIVE_DEFAULT_PARTITION` as
    null in `SparkPartitionUtils.getSparkPartitionValue(...)`.
    - Add unit assertions in `TestSparkPartitionUtils` to verify
    token-to-null conversion.
    - Extend Hive integration test coverage in
    `SparkHiveCatalogIT.testManagePartitionTable` with a null `INT`
    partition scenario for `SHOW PARTITIONS`.
    
    ### Why are the changes needed?
    
    `SHOW PARTITIONS` could throw `UnsupportedOperationException` /
    `NumberFormatException` by trying to parse Hive default partition tokens
    (for null values) as numeric types.
    
    Fix: #10302
    
    ### Does this PR introduce _any_ user-facing change?
    
    Yes. `SHOW PARTITIONS` now works for Hive tables containing null values
    in non-string partition columns.
    
    ### How was this patch tested?
    
    - `./gradlew :spark-connector:spark-common:test --tests
    org.apache.gravitino.spark.connector.utils.TestSparkPartitionUtils`
    - `./gradlew :spark-connector:spark-3.5:test --tests
    
org.apache.gravitino.spark.connector.integration.test.hive.SparkHiveCatalogIT35.testManagePartitionTable
    -PskipDockerTests=false`
    - `./gradlew :spark-connector:spark-3.4:test --tests
    
org.apache.gravitino.spark.connector.integration.test.hive.SparkHiveCatalogIT34.testManagePartitionTable
    -PskipDockerTests=false`
    - `./gradlew :spark-connector:spark-3.3:test --tests
    
org.apache.gravitino.spark.connector.integration.test.hive.SparkHiveCatalogIT33.testManagePartitionTable
    -PskipDockerTests=false`
---
 .../gravitino/spark/connector/utils/SparkPartitionUtils.java  | 10 +++++++++-
 .../connector/integration/test/hive/SparkHiveCatalogIT.java   | 11 +++++++++++
 .../spark/connector/utils/TestSparkPartitionUtils.java        | 10 ++++++++++
 3 files changed, 30 insertions(+), 1 deletion(-)

diff --git 
a/spark-connector/spark-common/src/main/java/org/apache/gravitino/spark/connector/utils/SparkPartitionUtils.java
 
b/spark-connector/spark-common/src/main/java/org/apache/gravitino/spark/connector/utils/SparkPartitionUtils.java
index 232c4a7254..21498f9af3 100644
--- 
a/spark-connector/spark-common/src/main/java/org/apache/gravitino/spark/connector/utils/SparkPartitionUtils.java
+++ 
b/spark-connector/spark-common/src/main/java/org/apache/gravitino/spark/connector/utils/SparkPartitionUtils.java
@@ -43,6 +43,9 @@ import org.apache.spark.unsafe.types.UTF8String;
 
 public class SparkPartitionUtils {
 
+  private static final String HIVE_DEFAULT_PARTITION_NAME = 
"__HIVE_DEFAULT_PARTITION__";
+  private static final String HIVE_DEFAULT_PARTITION_NAME_LEGACY = 
"HIVE_DEFAULT_PARTITION";
+
   private SparkPartitionUtils() {}
 
   public static Literal<?> toGravitinoLiteral(InternalRow ident, int ordinal, 
DataType sparkType) {
@@ -126,7 +129,7 @@ public class SparkPartitionUtils {
   }
 
   public static Object getSparkPartitionValue(String hivePartitionValue, 
DataType dataType) {
-    if (hivePartitionValue == null) {
+    if (hivePartitionValue == null || 
isHiveDefaultPartitionValue(hivePartitionValue)) {
       return null;
     }
     try {
@@ -166,4 +169,9 @@ public class SparkPartitionUtils {
           e);
     }
   }
+
+  private static boolean isHiveDefaultPartitionValue(String 
hivePartitionValue) {
+    return HIVE_DEFAULT_PARTITION_NAME.equalsIgnoreCase(hivePartitionValue)
+        || 
HIVE_DEFAULT_PARTITION_NAME_LEGACY.equalsIgnoreCase(hivePartitionValue);
+  }
 }
diff --git 
a/spark-connector/spark-common/src/test/java/org/apache/gravitino/spark/connector/integration/test/hive/SparkHiveCatalogIT.java
 
b/spark-connector/spark-common/src/test/java/org/apache/gravitino/spark/connector/integration/test/hive/SparkHiveCatalogIT.java
index b0cd8716cb..c0ae42727d 100644
--- 
a/spark-connector/spark-common/src/test/java/org/apache/gravitino/spark/connector/integration/test/hive/SparkHiveCatalogIT.java
+++ 
b/spark-connector/spark-common/src/test/java/org/apache/gravitino/spark/connector/integration/test/hive/SparkHiveCatalogIT.java
@@ -166,6 +166,17 @@ public abstract class SparkHiveCatalogIT extends 
SparkCommonIT {
     partitionInfo = sql("SHOW PARTITIONS " + tableName + " PARTITION 
(age_p1=2)");
     Assertions.assertEquals(0, partitionInfo.size());
 
+    String nullPartitionTableName = "hive_null_partition_ops_table";
+    dropTableIfExists(nullPartitionTableName);
+    sql(
+        "CREATE TABLE "
+            + nullPartitionTableName
+            + " (id INT, name STRING) PARTITIONED BY (dt INT) STORED AS 
PARQUET");
+    sql("INSERT INTO " + nullPartitionTableName + " (id, name, dt) SELECT 1, 
'test', null");
+    List<Object[]> nullPartitionInfo = 
getTablePartitions(nullPartitionTableName);
+    Assertions.assertEquals(1, nullPartitionInfo.size());
+    
Assertions.assertTrue(String.valueOf(nullPartitionInfo.get(0)[0]).startsWith("dt="));
+
     Exception exception =
         Assertions.assertThrows(
             Exception.class,
diff --git 
a/spark-connector/spark-common/src/test/java/org/apache/gravitino/spark/connector/utils/TestSparkPartitionUtils.java
 
b/spark-connector/spark-common/src/test/java/org/apache/gravitino/spark/connector/utils/TestSparkPartitionUtils.java
index ea411e6ac1..19cf8c6059 100644
--- 
a/spark-connector/spark-common/src/test/java/org/apache/gravitino/spark/connector/utils/TestSparkPartitionUtils.java
+++ 
b/spark-connector/spark-common/src/test/java/org/apache/gravitino/spark/connector/utils/TestSparkPartitionUtils.java
@@ -157,6 +157,16 @@ public class TestSparkPartitionUtils {
           SparkPartitionUtils.getSparkPartitionValue(hivePartitionValues[i], 
dataType));
     }
 
+    Assertions.assertNull(
+        SparkPartitionUtils.getSparkPartitionValue(
+            "__HIVE_DEFAULT_PARTITION__", DataTypes.IntegerType));
+    Assertions.assertNull(
+        SparkPartitionUtils.getSparkPartitionValue(
+            "HIVE_DEFAULT_PARTITION", DataTypes.IntegerType));
+    Assertions.assertNull(
+        SparkPartitionUtils.getSparkPartitionValue(
+            "__HIVE_DEFAULT_PARTITION__", DataTypes.StringType));
+
     Assertions.assertThrowsExactly(
         UnsupportedOperationException.class,
         () ->

Reply via email to