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

yuqi1129 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 cf289fb759 [#11590] fix(doris): fix partition parsing for Doris 3.0+ 
format (#11732)
cf289fb759 is described below

commit cf289fb759c26cb8cde984cb98e35b9770f08ff4
Author: StormSpirit <[email protected]>
AuthorDate: Mon Jul 13 21:31:37 2026 +0800

    [#11590] fix(doris): fix partition parsing for Doris 3.0+ format (#11732)
    
    ## What changes were proposed in this pull request?
    
    ### Partition Regex Fix (`DorisUtils.java`)
    
    - Added `\\s*` to `PARTITION_INFO_PATTERN` to tolerate whitespace
    between `LIST`/`RANGE` and `(` in Doris 3.0+ `SHOW CREATE TABLE` output
    (`PARTITION BY LIST (` vs `PARTITION BY LIST(`)
    
    ### Integration Tests
    
    - `CatalogDorisIT` (1.2.x): `testListPartitionRoundTrip` +
    `testMultiColumnListPartitionRoundTrip`
    - `CatalogDoris3xIT` (3.0.x): `testListPartitionRoundTrip` +
    `testRangePartitionRoundTrip`
    - `CatalogDoris4xIT` (4.0.x): `testListPartitionRoundTrip` +
    `testRangePartitionRoundTrip`
    
    All tests verify partition metadata survives the create → Doris → load
    round-trip.
    
    
    Fixed: #11590
    
    ## Does this PR introduce any user-facing change?
    
    No. Partition parsing fix is internal to Gravitino metadata loading.
    
    ## How was this patch tested?
    
    Unit tests: `TestDorisUtils` (existing, covers both LIST and RANGE
    parsing)
    
    Integration tests (Docker, all three Doris versions):
    - `CatalogDorisIT` (1.2.x): 19/19 passed
    - `CatalogDoris3xIT` (3.0.x): 8/8 passed
    - `CatalogDoris4xIT` (4.0.x): 8/8 passed
    
    ---------
    
    Signed-off-by: jiangxt2 <[email protected]>
---
 .../gravitino/catalog/doris/utils/DorisUtils.java  |   2 +-
 .../doris/integration/test/CatalogDoris3xIT.java   | 112 +++++++++++++++++++++
 .../doris/integration/test/CatalogDoris4xIT.java   | 111 ++++++++++++++++++++
 .../doris/integration/test/CatalogDorisIT.java     |  89 ++++++++++++++++
 .../catalog/doris/utils/TestDorisUtils.java        |  21 ++++
 5 files changed, 334 insertions(+), 1 deletion(-)

diff --git 
a/catalogs/catalog-jdbc-doris/src/main/java/org/apache/gravitino/catalog/doris/utils/DorisUtils.java
 
b/catalogs/catalog-jdbc-doris/src/main/java/org/apache/gravitino/catalog/doris/utils/DorisUtils.java
index 0a565bb6f6..03d4dd136e 100644
--- 
a/catalogs/catalog-jdbc-doris/src/main/java/org/apache/gravitino/catalog/doris/utils/DorisUtils.java
+++ 
b/catalogs/catalog-jdbc-doris/src/main/java/org/apache/gravitino/catalog/doris/utils/DorisUtils.java
@@ -45,7 +45,7 @@ import org.slf4j.LoggerFactory;
 public final class DorisUtils {
   private static final Logger LOGGER = 
LoggerFactory.getLogger(DorisUtils.class);
   private static final Pattern PARTITION_INFO_PATTERN =
-      Pattern.compile("PARTITION BY \\b(LIST|RANGE)\\b\\((.+)\\)");
+      Pattern.compile("PARTITION BY \\b(LIST|RANGE)\\b\\s*\\((.+)\\)");
 
   private static final Pattern DISTRIBUTION_INFO_PATTERN =
       Pattern.compile(
diff --git 
a/catalogs/catalog-jdbc-doris/src/test/java/org/apache/gravitino/catalog/doris/integration/test/CatalogDoris3xIT.java
 
b/catalogs/catalog-jdbc-doris/src/test/java/org/apache/gravitino/catalog/doris/integration/test/CatalogDoris3xIT.java
index d3f80abedf..712b5201d8 100644
--- 
a/catalogs/catalog-jdbc-doris/src/test/java/org/apache/gravitino/catalog/doris/integration/test/CatalogDoris3xIT.java
+++ 
b/catalogs/catalog-jdbc-doris/src/test/java/org/apache/gravitino/catalog/doris/integration/test/CatalogDoris3xIT.java
@@ -18,6 +18,7 @@
  */
 package org.apache.gravitino.catalog.doris.integration.test;
 
+import static 
org.apache.gravitino.integration.test.util.ITUtils.assertPartition;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
 
@@ -27,6 +28,7 @@ import java.util.Arrays;
 import java.util.Collections;
 import java.util.Map;
 import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
 import org.apache.commons.lang3.ArrayUtils;
 import org.apache.gravitino.Catalog;
 import org.apache.gravitino.NameIdentifier;
@@ -38,15 +40,23 @@ import 
org.apache.gravitino.integration.test.container.DorisImageName;
 import org.apache.gravitino.integration.test.util.BaseIT;
 import org.apache.gravitino.integration.test.util.GravitinoITUtils;
 import org.apache.gravitino.rel.Column;
+import org.apache.gravitino.rel.SupportsPartitions;
 import org.apache.gravitino.rel.Table;
 import org.apache.gravitino.rel.TableCatalog;
 import org.apache.gravitino.rel.TableChange;
 import org.apache.gravitino.rel.expressions.NamedReference;
 import org.apache.gravitino.rel.expressions.distributions.Distribution;
 import org.apache.gravitino.rel.expressions.distributions.Distributions;
+import org.apache.gravitino.rel.expressions.literals.Literal;
+import org.apache.gravitino.rel.expressions.literals.Literals;
+import org.apache.gravitino.rel.expressions.transforms.Transform;
 import org.apache.gravitino.rel.expressions.transforms.Transforms;
 import org.apache.gravitino.rel.indexes.Index;
 import org.apache.gravitino.rel.indexes.Indexes;
+import org.apache.gravitino.rel.partitions.ListPartition;
+import org.apache.gravitino.rel.partitions.Partition;
+import org.apache.gravitino.rel.partitions.Partitions;
+import org.apache.gravitino.rel.partitions.RangePartition;
 import org.apache.gravitino.rel.types.Types;
 import org.awaitility.Awaitility;
 import org.junit.jupiter.api.AfterAll;
@@ -315,6 +325,108 @@ public class CatalogDoris3xIT extends BaseIT {
     assertEquals(Types.ExternalType.of("json"), findColumn(t, 
"json_col").dataType());
   }
 
+  @Test
+  void testListPartitionRoundTrip() {
+    // Verify LIST partition with assignments round-trips correctly on Doris 
3.0.x.
+    // The partition parsing regex was updated to handle Doris 3.0+ format 
with spaces.
+    TableCatalog tc = catalog.asTableCatalog();
+    NameIdentifier tid =
+        NameIdentifier.of(schemaName, 
GravitinoITUtils.genRandomName("t_list_partition"));
+
+    Column cityCol = Column.of("city", Types.VarCharType.of(50), "city", 
false, false, null);
+    Distribution dist = Distributions.hash(1, NamedReference.field("city"));
+
+    // Create table with initial partition assignments so Doris 3.0.x 
recognizes it as partitioned.
+    Literal[][] p1Values = {{Literals.of("beijing", 
Types.VarCharType.of(50))}};
+    Literal[][] p2Values = {{Literals.of("shanghai", 
Types.VarCharType.of(50))}};
+    ListPartition p1 = Partitions.list("p1", p1Values, Collections.emptyMap());
+    ListPartition p2 = Partitions.list("p2", p2Values, Collections.emptyMap());
+    Transform[] partitioning = {
+      Transforms.list(new String[][] {{"city"}}, new ListPartition[] {p1, p2})
+    };
+
+    tc.createTable(
+        tid,
+        new Column[] {cityCol},
+        tableComment,
+        Collections.emptyMap(),
+        partitioning,
+        dist,
+        null,
+        null);
+
+    // Verify round-trip
+    Table loaded = tc.loadTable(tid);
+    assertEquals(1, loaded.partitioning().length);
+    assertEquals("list", loaded.partitioning()[0].name());
+
+    Map<String, ListPartition> partitions =
+        Arrays.stream(loaded.supportPartitions().listPartitions())
+            .collect(Collectors.toMap(Partition::name, p -> (ListPartition) 
p));
+    assertEquals(2, partitions.size());
+    assertPartition(Partitions.list("p1", p1Values, Collections.emptyMap()), 
partitions.get("p1"));
+    assertPartition(Partitions.list("p2", p2Values, Collections.emptyMap()), 
partitions.get("p2"));
+  }
+
+  @Test
+  void testRangePartitionRoundTrip() {
+    // Verify RANGE partition round-trips correctly on Doris 3.0.x.
+    // The regex was updated to tolerate space between RANGE and parenthesis.
+    TableCatalog tc = catalog.asTableCatalog();
+    NameIdentifier tid =
+        NameIdentifier.of(schemaName, 
GravitinoITUtils.genRandomName("t_range_partition"));
+
+    Column dateCol = Column.of("dt", Types.DateType.get(), "date", false, 
false, null);
+    Distribution dist = Distributions.hash(1, NamedReference.field("dt"));
+
+    Literal todayLiteral = Literals.of("2024-07-24", Types.DateType.get());
+    Literal tomorrowLiteral = Literals.of("2024-07-25", Types.DateType.get());
+    RangePartition p1 = Partitions.range("p1", todayLiteral, Literals.NULL, 
Collections.emptyMap());
+    RangePartition p2 =
+        Partitions.range("p2", tomorrowLiteral, todayLiteral, 
Collections.emptyMap());
+    RangePartition p3 =
+        Partitions.range("p3", Literals.NULL, tomorrowLiteral, 
Collections.emptyMap());
+    Transform[] partitioning = {
+      Transforms.range(new String[] {"dt"}, new RangePartition[] {p1, p2, p3})
+    };
+
+    tc.createTable(
+        tid,
+        new Column[] {dateCol},
+        tableComment,
+        Collections.emptyMap(),
+        partitioning,
+        dist,
+        null,
+        null);
+
+    Table loaded = tc.loadTable(tid);
+    assertEquals(1, loaded.partitioning().length);
+    assertEquals("range", loaded.partitioning()[0].name());
+
+    // Verify partition assignments
+    SupportsPartitions partitionOps = loaded.supportPartitions();
+    Map<String, RangePartition> partitions =
+        Arrays.stream(partitionOps.listPartitions())
+            .collect(Collectors.toMap(Partition::name, p -> (RangePartition) 
p));
+    assertEquals(3, partitions.size());
+    assertPartition(
+        Partitions.range(
+            "p1",
+            todayLiteral,
+            Literals.of("0000-01-01", Types.DateType.get()),
+            Collections.emptyMap()),
+        partitions.get("p1"));
+    assertPartition(p2, partitions.get("p2"));
+    assertPartition(
+        Partitions.range(
+            "p3",
+            Literals.of("MAXVALUE", Types.DateType.get()),
+            tomorrowLiteral,
+            Collections.emptyMap()),
+        partitions.get("p3"));
+  }
+
   private Column findColumn(Table table, String columnName) {
     return Arrays.stream(table.columns())
         .filter(c -> c.name().equals(columnName))
diff --git 
a/catalogs/catalog-jdbc-doris/src/test/java/org/apache/gravitino/catalog/doris/integration/test/CatalogDoris4xIT.java
 
b/catalogs/catalog-jdbc-doris/src/test/java/org/apache/gravitino/catalog/doris/integration/test/CatalogDoris4xIT.java
index 9d64f5bbee..b6d1f67f7c 100644
--- 
a/catalogs/catalog-jdbc-doris/src/test/java/org/apache/gravitino/catalog/doris/integration/test/CatalogDoris4xIT.java
+++ 
b/catalogs/catalog-jdbc-doris/src/test/java/org/apache/gravitino/catalog/doris/integration/test/CatalogDoris4xIT.java
@@ -18,6 +18,7 @@
  */
 package org.apache.gravitino.catalog.doris.integration.test;
 
+import static 
org.apache.gravitino.integration.test.util.ITUtils.assertPartition;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
 
@@ -27,6 +28,7 @@ import java.util.Arrays;
 import java.util.Collections;
 import java.util.Map;
 import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
 import org.apache.commons.lang3.ArrayUtils;
 import org.apache.gravitino.Catalog;
 import org.apache.gravitino.NameIdentifier;
@@ -38,15 +40,23 @@ import 
org.apache.gravitino.integration.test.container.DorisImageName;
 import org.apache.gravitino.integration.test.util.BaseIT;
 import org.apache.gravitino.integration.test.util.GravitinoITUtils;
 import org.apache.gravitino.rel.Column;
+import org.apache.gravitino.rel.SupportsPartitions;
 import org.apache.gravitino.rel.Table;
 import org.apache.gravitino.rel.TableCatalog;
 import org.apache.gravitino.rel.TableChange;
 import org.apache.gravitino.rel.expressions.NamedReference;
 import org.apache.gravitino.rel.expressions.distributions.Distribution;
 import org.apache.gravitino.rel.expressions.distributions.Distributions;
+import org.apache.gravitino.rel.expressions.literals.Literal;
+import org.apache.gravitino.rel.expressions.literals.Literals;
+import org.apache.gravitino.rel.expressions.transforms.Transform;
 import org.apache.gravitino.rel.expressions.transforms.Transforms;
 import org.apache.gravitino.rel.indexes.Index;
 import org.apache.gravitino.rel.indexes.Indexes;
+import org.apache.gravitino.rel.partitions.ListPartition;
+import org.apache.gravitino.rel.partitions.Partition;
+import org.apache.gravitino.rel.partitions.Partitions;
+import org.apache.gravitino.rel.partitions.RangePartition;
 import org.apache.gravitino.rel.types.Types;
 import org.awaitility.Awaitility;
 import org.junit.jupiter.api.AfterAll;
@@ -315,6 +325,107 @@ public class CatalogDoris4xIT extends BaseIT {
     assertEquals(Types.ExternalType.of("json"), findColumn(t, 
"json_col").dataType());
   }
 
+  @Test
+  void testListPartitionRoundTrip() {
+    // Verify LIST partition with assignments round-trips correctly on Doris 
4.0.x.
+    // Doris 4.0.x uses the same SHOW CREATE TABLE format as 3.0.x for 
partitions.
+    TableCatalog tc = catalog.asTableCatalog();
+    NameIdentifier tid =
+        NameIdentifier.of(schemaName, 
GravitinoITUtils.genRandomName("t_list_partition"));
+
+    Column cityCol = Column.of("city", Types.VarCharType.of(50), "city", 
false, false, null);
+    Distribution dist = Distributions.hash(1, NamedReference.field("city"));
+
+    // Create table with initial partition assignments so Doris 4.0.x 
recognizes it as partitioned.
+    Literal[][] p1Values = {{Literals.of("beijing", 
Types.VarCharType.of(50))}};
+    Literal[][] p2Values = {{Literals.of("shanghai", 
Types.VarCharType.of(50))}};
+    ListPartition p1 = Partitions.list("p1", p1Values, Collections.emptyMap());
+    ListPartition p2 = Partitions.list("p2", p2Values, Collections.emptyMap());
+    Transform[] partitioning = {
+      Transforms.list(new String[][] {{"city"}}, new ListPartition[] {p1, p2})
+    };
+
+    tc.createTable(
+        tid,
+        new Column[] {cityCol},
+        tableComment,
+        Collections.emptyMap(),
+        partitioning,
+        dist,
+        null,
+        null);
+
+    // Verify round-trip
+    Table loaded = tc.loadTable(tid);
+    assertEquals(1, loaded.partitioning().length);
+    assertEquals("list", loaded.partitioning()[0].name());
+
+    Map<String, ListPartition> partitions =
+        Arrays.stream(loaded.supportPartitions().listPartitions())
+            .collect(Collectors.toMap(Partition::name, p -> (ListPartition) 
p));
+    assertEquals(2, partitions.size());
+    assertPartition(Partitions.list("p1", p1Values, Collections.emptyMap()), 
partitions.get("p1"));
+    assertPartition(Partitions.list("p2", p2Values, Collections.emptyMap()), 
partitions.get("p2"));
+  }
+
+  @Test
+  void testRangePartitionRoundTrip() {
+    // Verify RANGE partition round-trips correctly on Doris 4.0.x.
+    // Behavior is identical to 3.0.x; tested separately to ensure full 
coverage.
+    TableCatalog tc = catalog.asTableCatalog();
+    NameIdentifier tid =
+        NameIdentifier.of(schemaName, 
GravitinoITUtils.genRandomName("t_range_partition"));
+
+    Column dateCol = Column.of("dt", Types.DateType.get(), "date", false, 
false, null);
+    Distribution dist = Distributions.hash(1, NamedReference.field("dt"));
+
+    Literal todayLiteral = Literals.of("2024-07-24", Types.DateType.get());
+    Literal tomorrowLiteral = Literals.of("2024-07-25", Types.DateType.get());
+    RangePartition p1 = Partitions.range("p1", todayLiteral, Literals.NULL, 
Collections.emptyMap());
+    RangePartition p2 =
+        Partitions.range("p2", tomorrowLiteral, todayLiteral, 
Collections.emptyMap());
+    RangePartition p3 =
+        Partitions.range("p3", Literals.NULL, tomorrowLiteral, 
Collections.emptyMap());
+    Transform[] partitioning = {
+      Transforms.range(new String[] {"dt"}, new RangePartition[] {p1, p2, p3})
+    };
+
+    tc.createTable(
+        tid,
+        new Column[] {dateCol},
+        tableComment,
+        Collections.emptyMap(),
+        partitioning,
+        dist,
+        null,
+        null);
+
+    Table loaded = tc.loadTable(tid);
+    assertEquals(1, loaded.partitioning().length);
+    assertEquals("range", loaded.partitioning()[0].name());
+
+    SupportsPartitions partitionOps = loaded.supportPartitions();
+    Map<String, RangePartition> partitions =
+        Arrays.stream(partitionOps.listPartitions())
+            .collect(Collectors.toMap(Partition::name, p -> (RangePartition) 
p));
+    assertEquals(3, partitions.size());
+    assertPartition(
+        Partitions.range(
+            "p1",
+            todayLiteral,
+            Literals.of("0000-01-01", Types.DateType.get()),
+            Collections.emptyMap()),
+        partitions.get("p1"));
+    assertPartition(p2, partitions.get("p2"));
+    assertPartition(
+        Partitions.range(
+            "p3",
+            Literals.of("MAXVALUE", Types.DateType.get()),
+            tomorrowLiteral,
+            Collections.emptyMap()),
+        partitions.get("p3"));
+  }
+
   private Column findColumn(Table table, String columnName) {
     return Arrays.stream(table.columns())
         .filter(c -> c.name().equals(columnName))
diff --git 
a/catalogs/catalog-jdbc-doris/src/test/java/org/apache/gravitino/catalog/doris/integration/test/CatalogDorisIT.java
 
b/catalogs/catalog-jdbc-doris/src/test/java/org/apache/gravitino/catalog/doris/integration/test/CatalogDorisIT.java
index 24a044c21f..e474c10fa7 100644
--- 
a/catalogs/catalog-jdbc-doris/src/test/java/org/apache/gravitino/catalog/doris/integration/test/CatalogDorisIT.java
+++ 
b/catalogs/catalog-jdbc-doris/src/test/java/org/apache/gravitino/catalog/doris/integration/test/CatalogDorisIT.java
@@ -1150,4 +1150,93 @@ public class CatalogDorisIT extends BaseIT {
         colDefaultValues[1].defaultValue());
     Assertions.assertEquals(DEFAULT_VALUE_OF_CURRENT_TIMESTAMP, 
colDefaultValues[2].defaultValue());
   }
+
+  @Test
+  void testListPartitionRoundTrip() {
+    // Verify LIST partition with assignments round-trips correctly on Doris 
1.2.x.
+    String tableName = GravitinoITUtils.genRandomName("test_list_partition");
+    NameIdentifier tableIdentifier = NameIdentifier.of(schemaName, tableName);
+    Column col = Column.of("city", Types.VarCharType.of(50), "city", false, 
false, null);
+    Distribution distribution = Distributions.hash(1, 
NamedReference.field("city"));
+    Index[] indexes = Indexes.EMPTY_INDEXES;
+
+    Transform[] partitioning = {Transforms.list(new String[][] {{"city"}})};
+    TableCatalog tableCatalog = catalog.asTableCatalog();
+    tableCatalog.createTable(
+        tableIdentifier,
+        new Column[] {col},
+        table_comment,
+        Collections.emptyMap(),
+        partitioning,
+        distribution,
+        null,
+        indexes);
+
+    SupportsPartitions partitionOps = 
tableCatalog.loadTable(tableIdentifier).supportPartitions();
+
+    // Add partitions
+    Literal[][] p1Values = {{Literals.of("beijing", 
Types.VarCharType.of(50))}};
+    Literal[][] p2Values = {{Literals.of("shanghai", 
Types.VarCharType.of(50))}};
+    partitionOps.addPartition(Partitions.list("p1", p1Values, 
Collections.emptyMap()));
+    partitionOps.addPartition(Partitions.list("p2", p2Values, 
Collections.emptyMap()));
+
+    // Verify round-trip: reload and check partition metadata
+    Table loadedTable = tableCatalog.loadTable(tableIdentifier);
+    SupportsPartitions loadedPartitionOps = loadedTable.supportPartitions();
+    Map<String, ListPartition> partitions =
+        Arrays.stream(loadedPartitionOps.listPartitions())
+            .collect(Collectors.toMap(Partition::name, p -> (ListPartition) 
p));
+    assertEquals(2, partitions.size());
+    assertPartition(Partitions.list("p1", p1Values, Collections.emptyMap()), 
partitions.get("p1"));
+    assertPartition(Partitions.list("p2", p2Values, Collections.emptyMap()), 
partitions.get("p2"));
+  }
+
+  @Test
+  void testMultiColumnListPartitionRoundTrip() {
+    // Verify multi-column LIST partition round-trip:
+    // create with assignments -> loadTable -> verify partition columns and 
values
+    String tableName = GravitinoITUtils.genRandomName("test_multi_col_list");
+    NameIdentifier tableIdentifier = NameIdentifier.of(schemaName, tableName);
+    Column col1 = Column.of("city", Types.VarCharType.of(50), "city", false, 
false, null);
+    Column col2 = Column.of("year_col", Types.IntegerType.get(), "year", 
false, false, null);
+    Distribution distribution = Distributions.hash(1, 
NamedReference.field("city"));
+    Index[] indexes = Indexes.EMPTY_INDEXES;
+
+    Transform[] partitioning = {Transforms.list(new String[][] {{"city"}, 
{"year_col"}})};
+    TableCatalog tableCatalog = catalog.asTableCatalog();
+    tableCatalog.createTable(
+        tableIdentifier,
+        new Column[] {col1, col2},
+        table_comment,
+        Collections.emptyMap(),
+        partitioning,
+        distribution,
+        null,
+        indexes);
+
+    SupportsPartitions partitionOps = 
tableCatalog.loadTable(tableIdentifier).supportPartitions();
+
+    // Add multi-column partition assignments
+    Literal[][] p1Values = {
+      {Literals.of("beijing", Types.VarCharType.of(50)), 
Literals.integerLiteral(2024)}
+    };
+    Literal[][] p2Values = {
+      {Literals.of("shanghai", Types.VarCharType.of(50)), 
Literals.integerLiteral(2024)}
+    };
+    partitionOps.addPartition(Partitions.list("p1", p1Values, 
Collections.emptyMap()));
+    partitionOps.addPartition(Partitions.list("p2", p2Values, 
Collections.emptyMap()));
+
+    // Verify round-trip
+    Table loadedTable = tableCatalog.loadTable(tableIdentifier);
+    assertEquals(1, loadedTable.partitioning().length);
+    assertEquals("list", loadedTable.partitioning()[0].name());
+
+    SupportsPartitions loadedPartitionOps = loadedTable.supportPartitions();
+    Map<String, ListPartition> partitions =
+        Arrays.stream(loadedPartitionOps.listPartitions())
+            .collect(Collectors.toMap(Partition::name, p -> (ListPartition) 
p));
+    assertEquals(2, partitions.size());
+    assertPartition(Partitions.list("p1", p1Values, Collections.emptyMap()), 
partitions.get("p1"));
+    assertPartition(Partitions.list("p2", p2Values, Collections.emptyMap()), 
partitions.get("p2"));
+  }
 }
diff --git 
a/catalogs/catalog-jdbc-doris/src/test/java/org/apache/gravitino/catalog/doris/utils/TestDorisUtils.java
 
b/catalogs/catalog-jdbc-doris/src/test/java/org/apache/gravitino/catalog/doris/utils/TestDorisUtils.java
index 019231f39d..c26f025beb 100644
--- 
a/catalogs/catalog-jdbc-doris/src/test/java/org/apache/gravitino/catalog/doris/utils/TestDorisUtils.java
+++ 
b/catalogs/catalog-jdbc-doris/src/test/java/org/apache/gravitino/catalog/doris/utils/TestDorisUtils.java
@@ -117,6 +117,27 @@ public class TestDorisUtils {
     assertTrue(transform.isPresent());
     assertEquals(Transforms.list(new String[][] {{"col1"}, {"col2"}}), 
transform.get());
 
+    // test range partition with space (Doris 3.0+ SHOW CREATE TABLE format)
+    createTableSql =
+        "CREATE TABLE `testTable` (\n`col1` date NOT NULL\n) ENGINE=OLAP\n 
PARTITION BY RANGE (`col1`)\n()\n DISTRIBUTED BY HASH(`col1`) BUCKETS 2";
+    transform = DorisUtils.extractPartitionInfoFromSql(createTableSql);
+    assertTrue(transform.isPresent());
+    assertEquals(Transforms.range(new String[] {"col1"}), transform.get());
+
+    // test list partition with space (Doris 3.0+ SHOW CREATE TABLE format)
+    createTableSql =
+        "CREATE TABLE `testTable` (\n`col1` int(11) NOT NULL\n) ENGINE=OLAP\n 
PARTITION BY LIST (`col1`)\n()\n DISTRIBUTED BY HASH(`col1`) BUCKETS 2";
+    transform = DorisUtils.extractPartitionInfoFromSql(createTableSql);
+    assertTrue(transform.isPresent());
+    assertEquals(Transforms.list(new String[][] {{"col1"}}), transform.get());
+
+    // test multi-column list partition with space
+    createTableSql =
+        "CREATE TABLE `testTable` (\n`col1` date NOT NULL,\n`col2` int(11) NOT 
NULL\n) ENGINE=OLAP\n PARTITION BY LIST (`col1`, `col2`)\n()\n DISTRIBUTED BY 
HASH(`col1`) BUCKETS 2";
+    transform = DorisUtils.extractPartitionInfoFromSql(createTableSql);
+    assertTrue(transform.isPresent());
+    assertEquals(Transforms.list(new String[][] {{"col1"}, {"col2"}}), 
transform.get());
+
     // test non-partitioned table
     createTableSql =
         "CREATE TABLE `testTable` (\n`testColumn` STRING NOT NULL COMMENT 
'test comment'\n) ENGINE=OLAP\nCOMMENT \"test comment\"";

Reply via email to