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

yuqi1129 pushed a commit to branch branch-1.3
in repository https://gitbox.apache.org/repos/asf/gravitino.git


The following commit(s) were added to refs/heads/branch-1.3 by this push:
     new 2e6d713025 [Cherry-pick to branch-1.3] [#11879] fix(clickhouse): fix 
type conversion for Decimal, DateTime64, LowCardinality, and IPv4/IPv6 (#11884) 
(#11894)
2e6d713025 is described below

commit 2e6d713025c97c73a9db09c7dacc822ca970cb4b
Author: github-actions[bot] 
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Sat Jul 4 21:45:04 2026 +0800

    [Cherry-pick to branch-1.3] [#11879] fix(clickhouse): fix type conversion 
for Decimal, DateTime64, LowCardinality, and IPv4/IPv6 (#11884) (#11894)
    
    **Cherry-pick Information:**
    - Original commit: b096dd2c42b041fcf4aa03af0c713394fd94bc94
    - Target branch: `branch-1.3`
    - Status: ✅ Clean cherry-pick (no conflicts)
    
    Signed-off-by: jiangxt2 <[email protected]>
    Co-authored-by: StormSpirit <[email protected]>
---
 .../converter/ClickHouseTypeConverter.java         | 23 ++++++++++++++---
 .../catalog/clickhouse/converter/TypeUtils.java    |  6 ++++-
 .../converter/TestClickHouseTypeConverter.java     | 29 ++++++++++++++++++++++
 .../operations/TestClickHouseTableOperations.java  |  4 +--
 4 files changed, 55 insertions(+), 7 deletions(-)

diff --git 
a/catalogs-contrib/catalog-jdbc-clickhouse/src/main/java/org/apache/gravitino/catalog/clickhouse/converter/ClickHouseTypeConverter.java
 
b/catalogs-contrib/catalog-jdbc-clickhouse/src/main/java/org/apache/gravitino/catalog/clickhouse/converter/ClickHouseTypeConverter.java
index 14acbfa84c..8915a8c0c3 100644
--- 
a/catalogs-contrib/catalog-jdbc-clickhouse/src/main/java/org/apache/gravitino/catalog/clickhouse/converter/ClickHouseTypeConverter.java
+++ 
b/catalogs-contrib/catalog-jdbc-clickhouse/src/main/java/org/apache/gravitino/catalog/clickhouse/converter/ClickHouseTypeConverter.java
@@ -76,7 +76,10 @@ public class ClickHouseTypeConverter extends 
JdbcTypeConverter {
 
   @Override
   public Type toGravitino(JdbcTypeBean typeBean) {
-    String typeName = TypeUtils.stripNullable(typeBean.getTypeName());
+    // ClickHouse allows LowCardinality wrapping Nullable: 
LowCardinality(Nullable(String)).
+    // Nullable(LowCardinality(X)) is invalid in ClickHouse and not handled 
here.
+    String typeName = TypeUtils.stripLowCardinality(typeBean.getTypeName());
+    typeName = TypeUtils.stripNullable(typeName);
 
     Integer dateTimePrecision = TypeUtils.extractDateTimePrecision(typeName);
     if (dateTimePrecision != null) {
@@ -126,6 +129,11 @@ public class ClickHouseTypeConverter extends 
JdbcTypeConverter {
               String.format("Decimal scale %s is out of range [0, %s]", scale, 
precision));
         }
 
+        // ClickHouse supports Decimal up to precision 76 (Decimal128=38, 
Decimal256=76),
+        // but Gravitino core DecimalType enforces precision <= 38. Use 
ExternalType for larger.
+        if (precision > 38) {
+          return Types.ExternalType.of(String.format("%s(%s,%s)", DECIMAL, 
precision, scale));
+        }
         return Types.DecimalType.of(precision, scale);
       case STRING:
         return Types.StringType.get();
@@ -141,6 +149,10 @@ public class ClickHouseTypeConverter extends 
JdbcTypeConverter {
         return Types.BooleanType.get();
       case UUID:
         return Types.UUIDType.get();
+      case IPV4:
+        return Types.ExternalType.of(IPV4);
+      case IPV6:
+        return Types.ExternalType.of(IPV6);
       default:
         return Types.ExternalType.of(typeBean.getTypeName());
     }
@@ -164,9 +176,12 @@ public class ClickHouseTypeConverter extends 
JdbcTypeConverter {
       return STRING;
     } else if (type instanceof Types.DateType) {
       return DATE;
-    } else if (type instanceof Types.TimestampType) {
-      // Gravitino timestamp type maps to ClickHouse DateTime with precision 
0, and
-      // Use the external type to handle DateTime64
+    } else if (type instanceof Types.TimestampType timestampType) {
+      // Gravitino timestamp type maps to ClickHouse DateTime with precision 0.
+      // For precision > 0, use DateTime64(N).
+      if (timestampType.precision() > 0) {
+        return DATETIME64 + "(" + timestampType.precision() + ")";
+      }
       return DATETIME;
     } else if (type instanceof Types.TimeType) {
       return TIME;
diff --git 
a/catalogs-contrib/catalog-jdbc-clickhouse/src/main/java/org/apache/gravitino/catalog/clickhouse/converter/TypeUtils.java
 
b/catalogs-contrib/catalog-jdbc-clickhouse/src/main/java/org/apache/gravitino/catalog/clickhouse/converter/TypeUtils.java
index 8a9bb76bb4..7ac74a143d 100644
--- 
a/catalogs-contrib/catalog-jdbc-clickhouse/src/main/java/org/apache/gravitino/catalog/clickhouse/converter/TypeUtils.java
+++ 
b/catalogs-contrib/catalog-jdbc-clickhouse/src/main/java/org/apache/gravitino/catalog/clickhouse/converter/TypeUtils.java
@@ -29,8 +29,12 @@ public class TypeUtils {
     return typeName.replaceFirst("^Nullable\\((.*)\\)$", "$1");
   }
 
+  public static String stripLowCardinality(String typeName) {
+    return typeName.replaceFirst("^LowCardinality\\((.*)\\)$", "$1");
+  }
+
   public static Integer extractDateTimePrecision(String typeName) {
-    Matcher matcher = 
Pattern.compile("^DateTime\\((\\d+)\\)$").matcher(typeName);
+    Matcher matcher = 
Pattern.compile("^DateTime(?:64)?\\((\\d+)\\)$").matcher(typeName);
     if (matcher.matches()) {
       return Integer.parseInt(matcher.group(1));
     }
diff --git 
a/catalogs-contrib/catalog-jdbc-clickhouse/src/test/java/org/apache/gravitino/catalog/clickhouse/converter/TestClickHouseTypeConverter.java
 
b/catalogs-contrib/catalog-jdbc-clickhouse/src/test/java/org/apache/gravitino/catalog/clickhouse/converter/TestClickHouseTypeConverter.java
index 36e2ad51dc..c644724994 100644
--- 
a/catalogs-contrib/catalog-jdbc-clickhouse/src/test/java/org/apache/gravitino/catalog/clickhouse/converter/TestClickHouseTypeConverter.java
+++ 
b/catalogs-contrib/catalog-jdbc-clickhouse/src/test/java/org/apache/gravitino/catalog/clickhouse/converter/TestClickHouseTypeConverter.java
@@ -31,6 +31,8 @@ import static 
org.apache.gravitino.catalog.clickhouse.converter.ClickHouseTypeCo
 import static 
org.apache.gravitino.catalog.clickhouse.converter.ClickHouseTypeConverter.INT32;
 import static 
org.apache.gravitino.catalog.clickhouse.converter.ClickHouseTypeConverter.INT64;
 import static 
org.apache.gravitino.catalog.clickhouse.converter.ClickHouseTypeConverter.INT8;
+import static 
org.apache.gravitino.catalog.clickhouse.converter.ClickHouseTypeConverter.IPV4;
+import static 
org.apache.gravitino.catalog.clickhouse.converter.ClickHouseTypeConverter.IPV6;
 import static 
org.apache.gravitino.catalog.clickhouse.converter.ClickHouseTypeConverter.STRING;
 import static 
org.apache.gravitino.catalog.clickhouse.converter.ClickHouseTypeConverter.UINT16;
 import static 
org.apache.gravitino.catalog.clickhouse.converter.ClickHouseTypeConverter.UINT32;
@@ -95,6 +97,28 @@ public class TestClickHouseTypeConverter {
     Assertions.assertEquals(
         Types.ExternalType.of("IPv4"), 
CLICKHOUSE_TYPE_CONVERTER.toGravitino(ipv4));
 
+    JdbcTypeConverter.JdbcTypeBean ipv6 = createTypeBean("IPv6", null, null);
+    Assertions.assertEquals(
+        Types.ExternalType.of("IPv6"), 
CLICKHOUSE_TYPE_CONVERTER.toGravitino(ipv6));
+
+    // DateTime64(3) should map to TimestampType.withoutTimeZone(3)
+    JdbcTypeConverter.JdbcTypeBean dateTime64WithPrecision =
+        createTypeBean("DateTime64(3)", null, null);
+    Assertions.assertEquals(
+        Types.TimestampType.withoutTimeZone(3),
+        CLICKHOUSE_TYPE_CONVERTER.toGravitino(dateTime64WithPrecision));
+
+    // LowCardinality(Nullable(String)) should map to StringType
+    JdbcTypeConverter.JdbcTypeBean lowCardNullable =
+        createTypeBean("LowCardinality(Nullable(String))", null, null);
+    Assertions.assertEquals(
+        Types.StringType.get(), 
CLICKHOUSE_TYPE_CONVERTER.toGravitino(lowCardNullable));
+
+    // Decimal(50, 10) should map to ExternalType (not crash, since precision 
> 38)
+    JdbcTypeConverter.JdbcTypeBean decimal50 = createTypeBean("Decimal", 50, 
10);
+    Assertions.assertEquals(
+        Types.ExternalType.of("Decimal(50,10)"), 
CLICKHOUSE_TYPE_CONVERTER.toGravitino(decimal50));
+
     JdbcTypeConverter.JdbcTypeBean decimalTooLarge = createTypeBean("Decimal", 
77, 2);
     Assertions.assertThrows(
         IllegalArgumentException.class,
@@ -128,6 +152,11 @@ public class TestClickHouseTypeConverter {
     checkGravitinoTypeToJdbcType(UUID, Types.UUIDType.get());
     checkGravitinoTypeToJdbcType(USER_DEFINED_TYPE, 
Types.ExternalType.of(USER_DEFINED_TYPE));
     checkGravitinoTypeToJdbcType("DateTime", 
Types.TimestampType.withoutTimeZone(0));
+    // DateTime64(3) round-trip
+    checkGravitinoTypeToJdbcType(DATETIME64 + "(3)", 
Types.TimestampType.withoutTimeZone(3));
+    // IPv4/IPv6 round-trip
+    checkGravitinoTypeToJdbcType(IPV4, Types.ExternalType.of(IPV4));
+    checkGravitinoTypeToJdbcType(IPV6, Types.ExternalType.of(IPV6));
     checkGravitinoTypeToJdbcType(TIME, Types.TimeType.get());
     Assertions.assertThrows(
         IllegalArgumentException.class,
diff --git 
a/catalogs-contrib/catalog-jdbc-clickhouse/src/test/java/org/apache/gravitino/catalog/clickhouse/operations/TestClickHouseTableOperations.java
 
b/catalogs-contrib/catalog-jdbc-clickhouse/src/test/java/org/apache/gravitino/catalog/clickhouse/operations/TestClickHouseTableOperations.java
index 68f72d2e12..93c928a539 100644
--- 
a/catalogs-contrib/catalog-jdbc-clickhouse/src/test/java/org/apache/gravitino/catalog/clickhouse/operations/TestClickHouseTableOperations.java
+++ 
b/catalogs-contrib/catalog-jdbc-clickhouse/src/test/java/org/apache/gravitino/catalog/clickhouse/operations/TestClickHouseTableOperations.java
@@ -589,7 +589,7 @@ public class TestClickHouseTableOperations extends 
TestClickHouse {
     columns.add(
         JdbcColumn.builder()
             .withName("c_dt64")
-            .withType(Types.ExternalType.of("DateTime64(3)"))
+            .withType(Types.TimestampType.withoutTimeZone(3))
             .withNullable(false)
             .build());
     columns.add(
@@ -647,7 +647,7 @@ public class TestClickHouseTableOperations extends 
TestClickHouse {
     Assertions.assertEquals(
         Types.TimestampType.withoutTimeZone(0), 
loaded.columns()[14].dataType());
     Assertions.assertEquals(
-        Types.ExternalType.of("DateTime64(3)"), 
loaded.columns()[15].dataType());
+        Types.TimestampType.withoutTimeZone(3), 
loaded.columns()[15].dataType());
     Assertions.assertEquals(Types.BooleanType.get(), 
loaded.columns()[16].dataType());
     Assertions.assertEquals(Types.UUIDType.get(), 
loaded.columns()[17].dataType());
     Assertions.assertEquals(Types.ExternalType.of("IPv4"), 
loaded.columns()[18].dataType());

Reply via email to