This is an automated email from the ASF dual-hosted git repository. github-merge-queue[bot] pushed a commit to branch gh-readonly-queue/dev/pr-12582-752a68ce4de4460f053b90663d61304a348e0dc7 in repository https://gitbox.apache.org/repos/asf/seatunnel.git
commit ce4071f0eacffb95c5c5d650273ab731931c58b5 Author: hutiefang76 <[email protected]> AuthorDate: Sun Oct 4 22:59:37 2026 +0000 [Fix][Connector-V2] Match DuckDB type names independently of locale (#12582) --- docs/en/connectors/source/DuckDB.md | 2 ++ docs/zh/connectors/source/DuckDB.md | 2 ++ .../dialect/duckdb/DuckDBTypeConverter.java | 4 ++- .../dialect/duckdb/DuckDBTypeConverterTest.java | 38 ++++++++++++++++++++++ 4 files changed, 45 insertions(+), 1 deletion(-) diff --git a/docs/en/connectors/source/DuckDB.md b/docs/en/connectors/source/DuckDB.md index 0d80cc2a8f..0768306acf 100644 --- a/docs/en/connectors/source/DuckDB.md +++ b/docs/en/connectors/source/DuckDB.md @@ -69,6 +69,8 @@ and reading multiple tables in one job through `table_list`. | TIMESTAMP<br/>TIMESTAMP WITH TIME ZONE | TIMESTAMP | | BLOB<br/>ARRAY<br/>STRUCT<br/>MAP | BYTES | +> Type names are matched without regard to case or the JVM default locale. For example, `integer` and `INTEGER` both map to `INT`, including under `tr-TR`. + ## Source Options | Name | Type | Required | Default | Description | diff --git a/docs/zh/connectors/source/DuckDB.md b/docs/zh/connectors/source/DuckDB.md index 4278e39f13..dba1cd6b0b 100644 --- a/docs/zh/connectors/source/DuckDB.md +++ b/docs/zh/connectors/source/DuckDB.md @@ -66,6 +66,8 @@ import ChangeLog from '../changelog/connector-jdbc.md'; | TIMESTAMP<br/>TIMESTAMP WITH TIME ZONE | TIMESTAMP | | BLOB<br/>ARRAY<br/>STRUCT<br/>MAP | BYTES | +> 类型名识别不区分大小写,也不受 JVM 默认区域设置影响。例如,在 `tr-TR` 下,`integer` 和 `INTEGER` 均映射为 `INT`。 + ## 源选项 | 名称 | 类型 | 是否必需 | 默认值 | 描述 | diff --git a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/duckdb/DuckDBTypeConverter.java b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/duckdb/DuckDBTypeConverter.java index 88dddab005..ebfcde02ea 100644 --- a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/duckdb/DuckDBTypeConverter.java +++ b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/duckdb/DuckDBTypeConverter.java @@ -31,6 +31,8 @@ import org.apache.seatunnel.connectors.seatunnel.jdbc.internal.dialect.DatabaseI import com.google.auto.service.AutoService; import lombok.extern.slf4j.Slf4j; +import java.util.Locale; + @Slf4j @AutoService(TypeConverter.class) public class DuckDBTypeConverter implements TypeConverter<BasicTypeDefine> { @@ -98,7 +100,7 @@ public class DuckDBTypeConverter implements TypeConverter<BasicTypeDefine> { .nullable(typeDefine.isNullable()) .defaultValue(typeDefine.getDefaultValue()) .comment(typeDefine.getComment()); - String duckDBType = typeDefine.getDataType().toUpperCase(); + String duckDBType = typeDefine.getDataType().toUpperCase(Locale.ROOT); Long length = typeDefine.getLength(); long lengthValue = length == null ? 0L : length; switch (duckDBType) { diff --git a/seatunnel-connectors-v2/connector-jdbc/src/test/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/duckdb/DuckDBTypeConverterTest.java b/seatunnel-connectors-v2/connector-jdbc/src/test/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/duckdb/DuckDBTypeConverterTest.java index bcb0b00f15..140d966df0 100644 --- a/seatunnel-connectors-v2/connector-jdbc/src/test/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/duckdb/DuckDBTypeConverterTest.java +++ b/seatunnel-connectors-v2/connector-jdbc/src/test/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/duckdb/DuckDBTypeConverterTest.java @@ -29,6 +29,9 @@ import org.apache.seatunnel.common.exception.SeaTunnelRuntimeException; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.parallel.ResourceLock; + +import java.util.Locale; public class DuckDBTypeConverterTest { @@ -281,6 +284,41 @@ public class DuckDBTypeConverterTest { Assertions.assertEquals(64L, column.getColumnLength()); } + @Test + @ResourceLock("java.util.Locale") + void testConvertTypeNameRecognitionIsIndependentOfDefaultLocale() { + Locale originalLocale = Locale.getDefault(); + try { + Locale.setDefault(new Locale("tr", "TR")); + + Assertions.assertEquals( + BasicType.INT_TYPE, convert("f_integer", "integer").getDataType()); + Assertions.assertEquals( + BasicType.BYTE_TYPE, convert("f_tinyint", "tinyint").getDataType()); + Assertions.assertEquals( + BasicType.LONG_TYPE, convert("f_bigint", "bigint").getDataType()); + Column bit = convert("f_bit", "bit", 8L); + Assertions.assertEquals(BasicType.STRING_TYPE, bit.getDataType()); + Assertions.assertEquals(8L, bit.getColumnLength()); + + Assertions.assertEquals( + BasicType.INT_TYPE, convert("f_integer_upper", "INTEGER").getDataType()); + Assertions.assertEquals( + BasicType.BYTE_TYPE, convert("f_tinyint_upper", "TINYINT").getDataType()); + Assertions.assertEquals( + BasicType.LONG_TYPE, convert("f_bigint_upper", "BIGINT").getDataType()); + Column bitUpper = convert("f_bit_upper", "BIT", 8L); + Assertions.assertEquals(BasicType.STRING_TYPE, bitUpper.getDataType()); + Assertions.assertEquals(8L, bitUpper.getColumnLength()); + + Column unknown = convert("f_unknown", "geography", 64L); + Assertions.assertEquals(BasicType.STRING_TYPE, unknown.getDataType()); + Assertions.assertEquals(64L, unknown.getColumnLength()); + } finally { + Locale.setDefault(originalLocale); + } + } + @Test void testReconvertBoolean() { BasicTypeDefine<?> typeDefine =
