From f18eeb881de8bb187b93d22ea0fe1599939c759f Mon Sep 17 00:00:00 2001 From: Nevin Zheng Date: Fri, 17 Jul 2026 23:23:08 -0700 Subject: [PATCH 1/5] [MINOR] fix(jdbc-doris): reject unsupported timestamps --- .../doris/converter/DorisTypeConverter.java | 13 ++++++ .../converter/TestDorisTypeConverter.java | 23 ++++++++++ .../integration/test/CatalogDorisIT.java | 43 +++++++++++++++++++ docs/jdbc-doris-catalog.md | 6 ++- 4 files changed, 84 insertions(+), 1 deletion(-) diff --git a/catalogs/catalog-jdbc-doris/src/main/java/org/apache/gravitino/catalog/doris/converter/DorisTypeConverter.java b/catalogs/catalog-jdbc-doris/src/main/java/org/apache/gravitino/catalog/doris/converter/DorisTypeConverter.java index df1fd341da9..6dbc697cfb0 100644 --- a/catalogs/catalog-jdbc-doris/src/main/java/org/apache/gravitino/catalog/doris/converter/DorisTypeConverter.java +++ b/catalogs/catalog-jdbc-doris/src/main/java/org/apache/gravitino/catalog/doris/converter/DorisTypeConverter.java @@ -24,6 +24,8 @@ /** Type converter for Apache Doris. */ public class DorisTypeConverter extends JdbcTypeConverter { + private static final int MAX_DATETIME_PRECISION = 6; + static final String BOOLEAN = "boolean"; static final String TINYINT = "tinyint"; static final String SMALLINT = "smallint"; @@ -188,6 +190,12 @@ public String fromGravitino(Type type) { return DATEV2; } else if (type instanceof Types.TimestampType) { Types.TimestampType timestampType = (Types.TimestampType) type; + if (timestampType.hasTimeZone()) { + throw unsupportedType(type, "Doris DATETIME does not store time-zone information"); + } + if (timestampType.hasPrecisionSet() && timestampType.precision() > MAX_DATETIME_PRECISION) { + throw unsupportedType(type, "fractional-second precision must be between 0 and 6"); + } return timestampType.hasPrecisionSet() ? String.format("%s(%d)", DATETIME, timestampType.precision()) : DATETIME; @@ -218,4 +226,9 @@ public String fromGravitino(Type type) { throw new IllegalArgumentException( String.format("Couldn't convert Gravitino type %s to Doris type", type.simpleString())); } + + private static IllegalArgumentException unsupportedType(Type type, String reason) { + return new IllegalArgumentException( + String.format("Doris does not support Gravitino type %s: %s", type.simpleString(), reason)); + } } diff --git a/catalogs/catalog-jdbc-doris/src/test/java/org/apache/gravitino/catalog/doris/converter/TestDorisTypeConverter.java b/catalogs/catalog-jdbc-doris/src/test/java/org/apache/gravitino/catalog/doris/converter/TestDorisTypeConverter.java index 3958ef0e469..a191df85206 100644 --- a/catalogs/catalog-jdbc-doris/src/test/java/org/apache/gravitino/catalog/doris/converter/TestDorisTypeConverter.java +++ b/catalogs/catalog-jdbc-doris/src/test/java/org/apache/gravitino/catalog/doris/converter/TestDorisTypeConverter.java @@ -115,6 +115,29 @@ public void testFromGravitinoType() { () -> DORIS_TYPE_CONVERTER.fromGravitino(Types.UnparsedType.of(USER_DEFINED_TYPE))); } + @Test + public void testRejectNanosecondTimestampTypes() { + checkGravitinoTypeToJdbcType("datetime(6)", Types.TimestampType.withoutTimeZone(6)); + + IllegalArgumentException timestampException = + Assertions.assertThrows( + IllegalArgumentException.class, + () -> DORIS_TYPE_CONVERTER.fromGravitino(Types.TimestampType.withoutTimeZone(9))); + Assertions.assertTrue( + timestampException + .getMessage() + .contains("fractional-second precision must be between 0 and 6")); + + IllegalArgumentException timestampTzException = + Assertions.assertThrows( + IllegalArgumentException.class, + () -> DORIS_TYPE_CONVERTER.fromGravitino(Types.TimestampType.withTimeZone(9))); + Assertions.assertTrue( + timestampTzException + .getMessage() + .contains("Doris DATETIME does not store time-zone information")); + } + @Test public void testExternalTypeRoundTrip() { // ExternalType round-trip: fromGravitino(ExternalType) → toGravitino 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 e474c10fa76..f13ca06e7cf 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 @@ -77,6 +77,7 @@ 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.Type; import org.apache.gravitino.rel.types.Types; import org.apache.gravitino.utils.RandomNameUtils; import org.awaitility.Awaitility; @@ -950,6 +951,18 @@ void testTableWithTimeStampColumn() { } } + @Test + void testRejectNanosecondTimestampsWithoutSideEffects() { + assertUnsupportedV3TypeDoesNotCreateTable( + "test_timestamp_ns", + Types.TimestampType.withoutTimeZone(9), + "fractional-second precision must be between 0 and 6"); + assertUnsupportedV3TypeDoesNotCreateTable( + "test_timestamp_tz_ns", + Types.TimestampType.withTimeZone(9), + "Doris DATETIME does not store time-zone information"); + } + @Test void testNonPartitionedTable() { // create a non-partitioned table @@ -1239,4 +1252,34 @@ void testMultiColumnListPartitionRoundTrip() { assertPartition(Partitions.list("p1", p1Values, Collections.emptyMap()), partitions.get("p1")); assertPartition(Partitions.list("p2", p2Values, Collections.emptyMap()), partitions.get("p2")); } + + private void assertUnsupportedV3TypeDoesNotCreateTable( + String tablePrefix, Type type, String expectedMessage) { + NameIdentifier tableIdentifier = + NameIdentifier.of(schemaName, GravitinoITUtils.genRandomName(tablePrefix)); + Column[] columns = { + Column.of("id", Types.IntegerType.get(), "distribution column"), + Column.of("v3_column", type, "V3 column") + }; + Distribution distribution = Distributions.hash(1, NamedReference.field("id")); + + IllegalArgumentException exception = + assertThrows( + IllegalArgumentException.class, + () -> + catalog + .asTableCatalog() + .createTable( + tableIdentifier, + columns, + null, + Collections.emptyMap(), + Transforms.EMPTY_TRANSFORM, + distribution, + null, + Indexes.EMPTY_INDEXES)); + + assertTrue(exception.getMessage().contains(expectedMessage), exception::getMessage); + assertFalse(catalog.asTableCatalog().tableExists(tableIdentifier)); + } } diff --git a/docs/jdbc-doris-catalog.md b/docs/jdbc-doris-catalog.md index 474ceee62f8..6c5d3e82bc5 100644 --- a/docs/jdbc-doris-catalog.md +++ b/docs/jdbc-doris-catalog.md @@ -126,7 +126,7 @@ Refer to | `Double` | `Double` | | `Decimal` | `Decimal` | | `Date` | `Date`/`DateV2` | -| `Timestamp[(p)]` | `Datetime[(p)]` | +| `Timestamp[(p)]` | `Datetime[(p)]`, p in [0, 6] | | `VarChar` | `VarChar` | | `FixedChar` | `Char` | | `String` | `String` | @@ -139,6 +139,10 @@ Refer to | `ExternalType("bitmap")` | `Bitmap` | | `ExternalType("hll")` | `HLL` | +Apache Doris `DATETIME` supports fractional-second precision from 0 through 6 and does not store +time-zone information. The catalog rejects `Timestamp` precision from 7 through 9 and all +`Timestamp_tz` types before executing DDL. + Doris doesn't support Gravitino `Fixed` `Timestamp_tz` `IntervalDay` `IntervalYear` `Union` `UUID` type. The data types other than those listed above are mapped to Gravitino's **[Unparsed Type](./manage-relational-metadata-using-gravitino.md#unparsed-type)** that represents an unresolvable data type since 0.5.0. From e67f1a6d07abdbd3afd947ad7144e35e678c7f78 Mon Sep 17 00:00:00 2001 From: Nevin Zheng Date: Fri, 17 Jul 2026 23:24:21 -0700 Subject: [PATCH 2/5] [MINOR] fix(jdbc-doris): reject variant type --- .../doris/converter/DorisTypeConverter.java | 5 +++++ .../doris/converter/TestDorisTypeConverter.java | 14 ++++++++++++++ .../doris/integration/test/CatalogDorisIT.java | 8 ++++++++ docs/jdbc-doris-catalog.md | 7 ++++++- 4 files changed, 33 insertions(+), 1 deletion(-) diff --git a/catalogs/catalog-jdbc-doris/src/main/java/org/apache/gravitino/catalog/doris/converter/DorisTypeConverter.java b/catalogs/catalog-jdbc-doris/src/main/java/org/apache/gravitino/catalog/doris/converter/DorisTypeConverter.java index 6dbc697cfb0..fb419c0181d 100644 --- a/catalogs/catalog-jdbc-doris/src/main/java/org/apache/gravitino/catalog/doris/converter/DorisTypeConverter.java +++ b/catalogs/catalog-jdbc-doris/src/main/java/org/apache/gravitino/catalog/doris/converter/DorisTypeConverter.java @@ -220,6 +220,11 @@ public String fromGravitino(Type type) { return STRING; } else if (type instanceof Types.BinaryType) { return BINARY; + } else if (type instanceof Types.VariantType) { + throw unsupportedType( + type, + "MySQL JDBC metadata reports Doris VARIANT as UNKNOWN, so the catalog cannot preserve " + + "the type on round-trip"); } else if (type instanceof Types.ExternalType) { return ((Types.ExternalType) type).catalogString(); } diff --git a/catalogs/catalog-jdbc-doris/src/test/java/org/apache/gravitino/catalog/doris/converter/TestDorisTypeConverter.java b/catalogs/catalog-jdbc-doris/src/test/java/org/apache/gravitino/catalog/doris/converter/TestDorisTypeConverter.java index a191df85206..98de05526e5 100644 --- a/catalogs/catalog-jdbc-doris/src/test/java/org/apache/gravitino/catalog/doris/converter/TestDorisTypeConverter.java +++ b/catalogs/catalog-jdbc-doris/src/test/java/org/apache/gravitino/catalog/doris/converter/TestDorisTypeConverter.java @@ -138,6 +138,20 @@ public void testRejectNanosecondTimestampTypes() { .contains("Doris DATETIME does not store time-zone information")); } + @Test + public void testRejectVariantType() { + IllegalArgumentException exception = + Assertions.assertThrows( + IllegalArgumentException.class, + () -> DORIS_TYPE_CONVERTER.fromGravitino(Types.VariantType.get())); + Assertions.assertTrue( + exception + .getMessage() + .contains( + "MySQL JDBC metadata reports Doris VARIANT as UNKNOWN, so the catalog cannot " + + "preserve the type on round-trip")); + } + @Test public void testExternalTypeRoundTrip() { // ExternalType round-trip: fromGravitino(ExternalType) → toGravitino 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 f13ca06e7cf..72ab537a3bc 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 @@ -963,6 +963,14 @@ void testRejectNanosecondTimestampsWithoutSideEffects() { "Doris DATETIME does not store time-zone information"); } + @Test + void testRejectVariantWithoutSideEffects() { + assertUnsupportedV3TypeDoesNotCreateTable( + "test_variant", + Types.VariantType.get(), + "MySQL JDBC metadata reports Doris VARIANT as UNKNOWN"); + } + @Test void testNonPartitionedTable() { // create a non-partitioned table diff --git a/docs/jdbc-doris-catalog.md b/docs/jdbc-doris-catalog.md index 6c5d3e82bc5..a7b0a8d3dcb 100644 --- a/docs/jdbc-doris-catalog.md +++ b/docs/jdbc-doris-catalog.md @@ -143,7 +143,12 @@ Apache Doris `DATETIME` supports fractional-second precision from 0 through 6 an time-zone information. The catalog rejects `Timestamp` precision from 7 through 9 and all `Timestamp_tz` types before executing DDL. -Doris doesn't support Gravitino `Fixed` `Timestamp_tz` `IntervalDay` `IntervalYear` `Union` `UUID` type. +Although Doris 2.1 and later have a native `VARIANT` type, MySQL JDBC metadata reports it as +`UNKNOWN`. The catalog therefore rejects Gravitino `Variant` before executing DDL because a +create/get round-trip cannot preserve the type family. `ExternalType("variant")` remains the raw +Doris type escape hatch. + +Doris doesn't support Gravitino `Fixed` `Timestamp_tz` `IntervalDay` `IntervalYear` `Union` `UUID` `Variant` type. The data types other than those listed above are mapped to Gravitino's **[Unparsed Type](./manage-relational-metadata-using-gravitino.md#unparsed-type)** that represents an unresolvable data type since 0.5.0. :::note From 93fe1f25f0056f0eab40a07ced5a439959eaf162 Mon Sep 17 00:00:00 2001 From: Nevin Zheng Date: Fri, 17 Jul 2026 23:25:08 -0700 Subject: [PATCH 3/5] [MINOR] fix(jdbc-doris): reject unknown type --- .../catalog/doris/converter/DorisTypeConverter.java | 2 ++ .../doris/converter/TestDorisTypeConverter.java | 10 ++++++++++ .../catalog/doris/integration/test/CatalogDorisIT.java | 6 ++++++ docs/jdbc-doris-catalog.md | 5 ++++- 4 files changed, 22 insertions(+), 1 deletion(-) diff --git a/catalogs/catalog-jdbc-doris/src/main/java/org/apache/gravitino/catalog/doris/converter/DorisTypeConverter.java b/catalogs/catalog-jdbc-doris/src/main/java/org/apache/gravitino/catalog/doris/converter/DorisTypeConverter.java index fb419c0181d..0ddc8522617 100644 --- a/catalogs/catalog-jdbc-doris/src/main/java/org/apache/gravitino/catalog/doris/converter/DorisTypeConverter.java +++ b/catalogs/catalog-jdbc-doris/src/main/java/org/apache/gravitino/catalog/doris/converter/DorisTypeConverter.java @@ -225,6 +225,8 @@ public String fromGravitino(Type type) { type, "MySQL JDBC metadata reports Doris VARIANT as UNKNOWN, so the catalog cannot preserve " + "the type on round-trip"); + } else if (type instanceof Types.NullType) { + throw unsupportedType(type, "the null-only placeholder has no Doris column type"); } else if (type instanceof Types.ExternalType) { return ((Types.ExternalType) type).catalogString(); } diff --git a/catalogs/catalog-jdbc-doris/src/test/java/org/apache/gravitino/catalog/doris/converter/TestDorisTypeConverter.java b/catalogs/catalog-jdbc-doris/src/test/java/org/apache/gravitino/catalog/doris/converter/TestDorisTypeConverter.java index 98de05526e5..966378731ca 100644 --- a/catalogs/catalog-jdbc-doris/src/test/java/org/apache/gravitino/catalog/doris/converter/TestDorisTypeConverter.java +++ b/catalogs/catalog-jdbc-doris/src/test/java/org/apache/gravitino/catalog/doris/converter/TestDorisTypeConverter.java @@ -152,6 +152,16 @@ public void testRejectVariantType() { + "preserve the type on round-trip")); } + @Test + public void testRejectNullType() { + IllegalArgumentException exception = + Assertions.assertThrows( + IllegalArgumentException.class, + () -> DORIS_TYPE_CONVERTER.fromGravitino(Types.NullType.get())); + Assertions.assertTrue( + exception.getMessage().contains("the null-only placeholder has no Doris column type")); + } + @Test public void testExternalTypeRoundTrip() { // ExternalType round-trip: fromGravitino(ExternalType) → toGravitino 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 72ab537a3bc..2ef258cc802 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 @@ -971,6 +971,12 @@ void testRejectVariantWithoutSideEffects() { "MySQL JDBC metadata reports Doris VARIANT as UNKNOWN"); } + @Test + void testRejectNullTypeWithoutSideEffects() { + assertUnsupportedV3TypeDoesNotCreateTable( + "test_null", Types.NullType.get(), "the null-only placeholder has no Doris column type"); + } + @Test void testNonPartitionedTable() { // create a non-partitioned table diff --git a/docs/jdbc-doris-catalog.md b/docs/jdbc-doris-catalog.md index a7b0a8d3dcb..f80ecf02922 100644 --- a/docs/jdbc-doris-catalog.md +++ b/docs/jdbc-doris-catalog.md @@ -148,7 +148,10 @@ Although Doris 2.1 and later have a native `VARIANT` type, MySQL JDBC metadata r create/get round-trip cannot preserve the type family. `ExternalType("variant")` remains the raw Doris type escape hatch. -Doris doesn't support Gravitino `Fixed` `Timestamp_tz` `IntervalDay` `IntervalYear` `Union` `UUID` `Variant` type. +Gravitino `Null` (the V3 unknown type) is rejected before executing DDL because it is a null-only +placeholder, not a Doris column type. + +Doris doesn't support Gravitino `Fixed` `Timestamp_tz` `IntervalDay` `IntervalYear` `Union` `UUID` `Variant` `Null` type. The data types other than those listed above are mapped to Gravitino's **[Unparsed Type](./manage-relational-metadata-using-gravitino.md#unparsed-type)** that represents an unresolvable data type since 0.5.0. :::note From 12d3e3d786d5993609d08f9d9c5ae30bd3e2b1c5 Mon Sep 17 00:00:00 2001 From: Nevin Zheng Date: Fri, 17 Jul 2026 23:25:51 -0700 Subject: [PATCH 4/5] [MINOR] fix(jdbc-doris): reject geometry type --- .../doris/converter/DorisTypeConverter.java | 5 +++++ .../doris/converter/TestDorisTypeConverter.java | 14 ++++++++++++++ .../doris/integration/test/CatalogDorisIT.java | 8 ++++++++ docs/jdbc-doris-catalog.md | 6 +++++- 4 files changed, 32 insertions(+), 1 deletion(-) diff --git a/catalogs/catalog-jdbc-doris/src/main/java/org/apache/gravitino/catalog/doris/converter/DorisTypeConverter.java b/catalogs/catalog-jdbc-doris/src/main/java/org/apache/gravitino/catalog/doris/converter/DorisTypeConverter.java index 0ddc8522617..8b81b905bca 100644 --- a/catalogs/catalog-jdbc-doris/src/main/java/org/apache/gravitino/catalog/doris/converter/DorisTypeConverter.java +++ b/catalogs/catalog-jdbc-doris/src/main/java/org/apache/gravitino/catalog/doris/converter/DorisTypeConverter.java @@ -227,6 +227,11 @@ public String fromGravitino(Type type) { + "the type on round-trip"); } else if (type instanceof Types.NullType) { throw unsupportedType(type, "the null-only placeholder has no Doris column type"); + } else if (type instanceof Types.GeometryType) { + throw unsupportedType( + type, + "Doris GEO uses String/Varchar storage and cannot preserve Geometry CRS metadata as a " + + "column type"); } else if (type instanceof Types.ExternalType) { return ((Types.ExternalType) type).catalogString(); } diff --git a/catalogs/catalog-jdbc-doris/src/test/java/org/apache/gravitino/catalog/doris/converter/TestDorisTypeConverter.java b/catalogs/catalog-jdbc-doris/src/test/java/org/apache/gravitino/catalog/doris/converter/TestDorisTypeConverter.java index 966378731ca..06c68d26572 100644 --- a/catalogs/catalog-jdbc-doris/src/test/java/org/apache/gravitino/catalog/doris/converter/TestDorisTypeConverter.java +++ b/catalogs/catalog-jdbc-doris/src/test/java/org/apache/gravitino/catalog/doris/converter/TestDorisTypeConverter.java @@ -162,6 +162,20 @@ public void testRejectNullType() { exception.getMessage().contains("the null-only placeholder has no Doris column type")); } + @Test + public void testRejectGeometryType() { + IllegalArgumentException exception = + Assertions.assertThrows( + IllegalArgumentException.class, + () -> DORIS_TYPE_CONVERTER.fromGravitino(Types.GeometryType.of("SRID:3857"))); + Assertions.assertTrue( + exception + .getMessage() + .contains( + "Doris GEO uses String/Varchar storage and cannot preserve Geometry CRS metadata " + + "as a column type")); + } + @Test public void testExternalTypeRoundTrip() { // ExternalType round-trip: fromGravitino(ExternalType) → toGravitino 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 2ef258cc802..3f3a2a78d8b 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 @@ -977,6 +977,14 @@ void testRejectNullTypeWithoutSideEffects() { "test_null", Types.NullType.get(), "the null-only placeholder has no Doris column type"); } + @Test + void testRejectGeometryWithoutSideEffects() { + assertUnsupportedV3TypeDoesNotCreateTable( + "test_geometry", + Types.GeometryType.of("SRID:3857"), + "Doris GEO uses String/Varchar storage and cannot preserve Geometry CRS metadata"); + } + @Test void testNonPartitionedTable() { // create a non-partitioned table diff --git a/docs/jdbc-doris-catalog.md b/docs/jdbc-doris-catalog.md index f80ecf02922..9bd883523e9 100644 --- a/docs/jdbc-doris-catalog.md +++ b/docs/jdbc-doris-catalog.md @@ -151,7 +151,11 @@ Doris type escape hatch. Gravitino `Null` (the V3 unknown type) is rejected before executing DDL because it is a null-only placeholder, not a Doris column type. -Doris doesn't support Gravitino `Fixed` `Timestamp_tz` `IntervalDay` `IntervalYear` `Union` `UUID` `Variant` `Null` type. +Gravitino `Geometry` is rejected before executing DDL. Doris GEO is not a column type; it stores +geospatial values in `String`/`VarChar`, which cannot preserve Gravitino CRS metadata as part of the +type. + +Doris doesn't support Gravitino `Fixed` `Timestamp_tz` `IntervalDay` `IntervalYear` `Union` `UUID` `Variant` `Null` `Geometry` type. The data types other than those listed above are mapped to Gravitino's **[Unparsed Type](./manage-relational-metadata-using-gravitino.md#unparsed-type)** that represents an unresolvable data type since 0.5.0. :::note From a33dc0ab1e5c5cbda4e2801f117374ce8f99bbe2 Mon Sep 17 00:00:00 2001 From: Nevin Zheng Date: Fri, 17 Jul 2026 23:26:39 -0700 Subject: [PATCH 5/5] [MINOR] fix(jdbc-doris): reject geography type --- .../doris/converter/DorisTypeConverter.java | 4 ++++ .../doris/converter/TestDorisTypeConverter.java | 15 +++++++++++++++ .../doris/integration/test/CatalogDorisIT.java | 8 ++++++++ docs/jdbc-doris-catalog.md | 5 ++++- 4 files changed, 31 insertions(+), 1 deletion(-) diff --git a/catalogs/catalog-jdbc-doris/src/main/java/org/apache/gravitino/catalog/doris/converter/DorisTypeConverter.java b/catalogs/catalog-jdbc-doris/src/main/java/org/apache/gravitino/catalog/doris/converter/DorisTypeConverter.java index 8b81b905bca..8df2b4d332f 100644 --- a/catalogs/catalog-jdbc-doris/src/main/java/org/apache/gravitino/catalog/doris/converter/DorisTypeConverter.java +++ b/catalogs/catalog-jdbc-doris/src/main/java/org/apache/gravitino/catalog/doris/converter/DorisTypeConverter.java @@ -232,6 +232,10 @@ public String fromGravitino(Type type) { type, "Doris GEO uses String/Varchar storage and cannot preserve Geometry CRS metadata as a " + "column type"); + } else if (type instanceof Types.GeographyType) { + throw unsupportedType( + type, + "Doris GEO has no Geography column type that preserves CRS and edge-algorithm metadata"); } else if (type instanceof Types.ExternalType) { return ((Types.ExternalType) type).catalogString(); } diff --git a/catalogs/catalog-jdbc-doris/src/test/java/org/apache/gravitino/catalog/doris/converter/TestDorisTypeConverter.java b/catalogs/catalog-jdbc-doris/src/test/java/org/apache/gravitino/catalog/doris/converter/TestDorisTypeConverter.java index 06c68d26572..ba301027d6b 100644 --- a/catalogs/catalog-jdbc-doris/src/test/java/org/apache/gravitino/catalog/doris/converter/TestDorisTypeConverter.java +++ b/catalogs/catalog-jdbc-doris/src/test/java/org/apache/gravitino/catalog/doris/converter/TestDorisTypeConverter.java @@ -176,6 +176,21 @@ public void testRejectGeometryType() { + "as a column type")); } + @Test + public void testRejectGeographyType() { + IllegalArgumentException exception = + Assertions.assertThrows( + IllegalArgumentException.class, + () -> + DORIS_TYPE_CONVERTER.fromGravitino(Types.GeographyType.of("EPSG:4326", "karney"))); + Assertions.assertTrue( + exception + .getMessage() + .contains( + "Doris GEO has no Geography column type that preserves CRS and edge-algorithm " + + "metadata")); + } + @Test public void testExternalTypeRoundTrip() { // ExternalType round-trip: fromGravitino(ExternalType) → toGravitino 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 3f3a2a78d8b..a9341bc17c1 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 @@ -985,6 +985,14 @@ void testRejectGeometryWithoutSideEffects() { "Doris GEO uses String/Varchar storage and cannot preserve Geometry CRS metadata"); } + @Test + void testRejectGeographyWithoutSideEffects() { + assertUnsupportedV3TypeDoesNotCreateTable( + "test_geography", + Types.GeographyType.of("EPSG:4326", "karney"), + "Doris GEO has no Geography column type that preserves CRS and edge-algorithm metadata"); + } + @Test void testNonPartitionedTable() { // create a non-partitioned table diff --git a/docs/jdbc-doris-catalog.md b/docs/jdbc-doris-catalog.md index 9bd883523e9..d830b7fbe74 100644 --- a/docs/jdbc-doris-catalog.md +++ b/docs/jdbc-doris-catalog.md @@ -155,7 +155,10 @@ Gravitino `Geometry` is rejected before executing DDL. Doris GEO is not a column geospatial values in `String`/`VarChar`, which cannot preserve Gravitino CRS metadata as part of the type. -Doris doesn't support Gravitino `Fixed` `Timestamp_tz` `IntervalDay` `IntervalYear` `Union` `UUID` `Variant` `Null` `Geometry` type. +Gravitino `Geography` is also rejected before executing DDL because Doris has no geography column +type that preserves both its CRS and edge-algorithm metadata. + +Doris doesn't support Gravitino `Fixed` `Timestamp_tz` `IntervalDay` `IntervalYear` `Union` `UUID` `Variant` `Null` `Geometry` `Geography` type. The data types other than those listed above are mapped to Gravitino's **[Unparsed Type](./manage-relational-metadata-using-gravitino.md#unparsed-type)** that represents an unresolvable data type since 0.5.0. :::note