diff --git a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/catalog/dm/DamengDataTypeConvertor.java b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/catalog/dm/DamengDataTypeConvertor.java index 533f7db9cd40..4bffdd244f7b 100644 --- a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/catalog/dm/DamengDataTypeConvertor.java +++ b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/catalog/dm/DamengDataTypeConvertor.java @@ -30,6 +30,7 @@ import com.google.auto.service.AutoService; import java.util.Collections; +import java.util.Locale; import java.util.Map; import static org.apache.seatunnel.connectors.seatunnel.jdbc.internal.dialect.dm.DmdbTypeConverter.DM_DEC; @@ -61,7 +62,7 @@ public SeaTunnelDataType toSeaTunnelType( String field, String dataType, Map properties) { Integer precision = null; Integer scale = null; - switch (dataType.toUpperCase()) { + switch (dataType.toUpperCase(Locale.ROOT)) { case DM_NUMERIC: case DM_NUMBER: case DM_DECIMAL: diff --git a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/catalog/duckdb/DuckDBCatalog.java b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/catalog/duckdb/DuckDBCatalog.java index e9652f129d71..bc45bd58d17e 100644 --- a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/catalog/duckdb/DuckDBCatalog.java +++ b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/catalog/duckdb/DuckDBCatalog.java @@ -42,6 +42,7 @@ import java.util.Enumeration; import java.util.Iterator; import java.util.List; +import java.util.Locale; import java.util.Properties; import java.util.regex.Pattern; @@ -262,6 +263,6 @@ protected String getOptionTableName(TablePath tablePath) { } private boolean isDuckDBDecimal(String typeName) { - return typeName.toUpperCase().startsWith(DuckDBTypeConverter.DUCKDB_DECIMAL); + return typeName.toUpperCase(Locale.ROOT).startsWith(DuckDBTypeConverter.DUCKDB_DECIMAL); } } diff --git a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/catalog/oceanbase/OceanBaseOracleCreateTableSqlBuilder.java b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/catalog/oceanbase/OceanBaseOracleCreateTableSqlBuilder.java index 34de2822b742..23af6ed1a2ca 100644 --- a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/catalog/oceanbase/OceanBaseOracleCreateTableSqlBuilder.java +++ b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/catalog/oceanbase/OceanBaseOracleCreateTableSqlBuilder.java @@ -25,6 +25,8 @@ import org.apache.seatunnel.connectors.seatunnel.jdbc.internal.dialect.DatabaseIdentifier; import org.apache.seatunnel.connectors.seatunnel.jdbc.internal.dialect.oracle.OracleTypeConverter; +import java.util.Locale; + public class OceanBaseOracleCreateTableSqlBuilder extends OracleCreateTableSqlBuilder { public OceanBaseOracleCreateTableSqlBuilder(CatalogTable catalogTable, boolean createIndex) { @@ -46,7 +48,7 @@ protected String buildColumnSql(Column column) { // handle OceanBase Oracle compatible mode unsupported types, please refer // https://www.oceanbase.com/docs/enterprise-oceanbase-database-cn-10000000000355002 // and https://www.oceanbase.com/docs/enterprise-oms-doc-cn-1000000002530110 - switch (column.getSourceType().toUpperCase()) { + switch (column.getSourceType().toUpperCase(Locale.ROOT)) { case OracleTypeConverter.ORACLE_LONG: columnType = OracleTypeConverter.ORACLE_CLOB; break; diff --git a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/catalog/redshift/RedshiftCatalog.java b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/catalog/redshift/RedshiftCatalog.java index 3d130aec4634..0cd805953fff 100644 --- a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/catalog/redshift/RedshiftCatalog.java +++ b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/catalog/redshift/RedshiftCatalog.java @@ -33,6 +33,7 @@ import java.sql.ResultSet; import java.sql.SQLException; +import java.util.Locale; @Slf4j public class RedshiftCatalog extends AbstractJdbcCatalog { @@ -82,7 +83,7 @@ protected String getTableName(ResultSet rs) throws SQLException { .append(".") .append(rs.getString(2)) .toString() - .toLowerCase(); + .toLowerCase(Locale.ROOT); } @Override @@ -133,7 +134,7 @@ protected TableIdentifier getTableIdentifier(TablePath tablePath) { @Override protected Column buildColumn(ResultSet resultSet) throws SQLException { String columnName = resultSet.getString("COLUMN_NAME"); - String typeName = resultSet.getString("DATA_TYPE").toUpperCase(); + String typeName = resultSet.getString("DATA_TYPE").toUpperCase(Locale.ROOT); long precision = resultSet.getLong("NUMERIC_PRECISION"); int scale = resultSet.getInt("NUMERIC_SCALE"); long columnLength = resultSet.getLong("CHARACTER_MAXIMUM_LENGTH"); diff --git a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/catalog/redshift/RedshiftDataTypeConvertor.java b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/catalog/redshift/RedshiftDataTypeConvertor.java index 743a26a5c9ac..35e5dfd17c9c 100644 --- a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/catalog/redshift/RedshiftDataTypeConvertor.java +++ b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/catalog/redshift/RedshiftDataTypeConvertor.java @@ -31,6 +31,7 @@ import com.google.auto.service.AutoService; import java.util.Collections; +import java.util.Locale; import java.util.Map; import static org.apache.seatunnel.shade.com.google.common.base.Preconditions.checkNotNull; @@ -58,7 +59,7 @@ public SeaTunnelDataType toSeaTunnelType( Integer precision = null; Integer scale = null; - switch (connectorDataType.toUpperCase()) { + switch (connectorDataType.toUpperCase(Locale.ROOT)) { case RedshiftTypeConverter.PG_NUMERIC: precision = MapUtils.getInteger(dataTypeProperties, PRECISION, DEFAULT_PRECISION); scale = MapUtils.getInteger(dataTypeProperties, SCALE, DEFAULT_SCALE); diff --git a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/catalog/xugu/XuguCatalog.java b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/catalog/xugu/XuguCatalog.java index e10886e6d912..c9c4cd828b34 100644 --- a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/catalog/xugu/XuguCatalog.java +++ b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/catalog/xugu/XuguCatalog.java @@ -41,6 +41,7 @@ import java.sql.SQLException; import java.util.ArrayList; import java.util.List; +import java.util.Locale; import java.util.Objects; import java.util.stream.Collectors; @@ -157,13 +158,13 @@ public boolean databaseExists(String databaseName) throws CatalogException { } try { return querySQLResultExists( - defaultUrl, getDatabaseWithConditionSql(databaseName.toUpperCase())); + defaultUrl, getDatabaseWithConditionSql(databaseName.toUpperCase(Locale.ROOT))); } catch (SeaTunnelRuntimeException e) { if (e.getSeaTunnelErrorCode().getCode().equals(UNSUPPORTED_METHOD.getCode())) { log.warn( "The catalog: {} is not supported the getDatabaseWithConditionSql for databaseExists", this.catalogName); - return listDatabases().contains(databaseName.toUpperCase()); + return listDatabases().contains(databaseName.toUpperCase(Locale.ROOT)); } throw e; } catch (SQLException e) { diff --git a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/catalog/yashandb/YashanDbCatalog.java b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/catalog/yashandb/YashanDbCatalog.java index cd9a1b849acb..09dfc5865b4d 100644 --- a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/catalog/yashandb/YashanDbCatalog.java +++ b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/catalog/yashandb/YashanDbCatalog.java @@ -44,6 +44,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Locale; import java.util.Set; import java.util.stream.Collectors; @@ -153,7 +154,11 @@ protected Column buildColumn(ResultSet resultSet) throws SQLException { // DATA_TYPE from all_tab_columns may include precision like TIMESTAMP(6), // strip parenthesized digits to get the pure type name String typeName = - resultSet.getString("DATA_TYPE").toUpperCase().replaceAll("\\(\\d+\\)", "").trim(); + resultSet + .getString("DATA_TYPE") + .toUpperCase(Locale.ROOT) + .replaceAll("\\(\\d+\\)", "") + .trim(); // e.g NUMBER(10, 2) String fullTypeName = resultSet.getString("FULL_TYPE_NAME"); long columnLength = resultSet.getLong("COLUMN_LENGTH"); diff --git a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/db2/DB2TypeConverter.java b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/db2/DB2TypeConverter.java index 73a95337f150..9c7a6a15bcac 100644 --- a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/db2/DB2TypeConverter.java +++ b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/db2/DB2TypeConverter.java @@ -32,6 +32,8 @@ import com.google.auto.service.AutoService; import lombok.extern.slf4j.Slf4j; +import java.util.Locale; + // reference https://www.ibm.com/docs/en/db2/11.5?topic=statements-create-table#r0000927__title__52 @Slf4j @AutoService(TypeConverter.class) @@ -106,7 +108,7 @@ public Column convert(BasicTypeDefine typeDefine) { .defaultValue(typeDefine.getDefaultValue()) .comment(typeDefine.getComment()); - String db2Type = typeDefine.getDataType().toUpperCase(); + String db2Type = typeDefine.getDataType().toUpperCase(Locale.ROOT); switch (db2Type) { case DB2_BOOLEAN: builder.sourceType(DB2_BOOLEAN); diff --git a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/dm/DmdbTypeConverter.java b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/dm/DmdbTypeConverter.java index 226789328310..c5ad5aaa2dd4 100644 --- a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/dm/DmdbTypeConverter.java +++ b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/dm/DmdbTypeConverter.java @@ -32,6 +32,8 @@ import com.google.auto.service.AutoService; import lombok.extern.slf4j.Slf4j; +import java.util.Locale; + // reference https://eco.dameng.com/document/dm/zh-cn/sql-dev/dmpl-sql-datatype.html @Slf4j @AutoService(TypeConverter.class) @@ -125,7 +127,7 @@ public Column convert(BasicTypeDefine typeDefine) { .defaultValue(typeDefine.getDefaultValue()) .comment(typeDefine.getComment()); - String dmType = typeDefine.getDataType().toUpperCase(); + String dmType = typeDefine.getDataType().toUpperCase(Locale.ROOT); if (dmType.startsWith("TIMESTAMP(") && dmType.endsWith(" WITH LOCAL TIME ZONE")) { dmType = DM_TIMESTAMP_WITH_LOCAL_TIME_ZONE; } diff --git a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/gbase8a/Gbase8aTypeMapper.java b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/gbase8a/Gbase8aTypeMapper.java index 84935274f1d2..fcabd50d5b3f 100644 --- a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/gbase8a/Gbase8aTypeMapper.java +++ b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/gbase8a/Gbase8aTypeMapper.java @@ -30,6 +30,7 @@ import java.sql.ResultSetMetaData; import java.sql.SQLException; +import java.util.Locale; @Slf4j public class Gbase8aTypeMapper implements JdbcDialectTypeMapper { @@ -64,7 +65,7 @@ public class Gbase8aTypeMapper implements JdbcDialectTypeMapper { @Override public SeaTunnelDataType mapping(ResultSetMetaData metadata, int colIndex) throws SQLException { - String gbase8aType = metadata.getColumnTypeName(colIndex).toUpperCase(); + String gbase8aType = metadata.getColumnTypeName(colIndex).toUpperCase(Locale.ROOT); int precision = metadata.getPrecision(colIndex); int scale = metadata.getScale(colIndex); switch (gbase8aType) { diff --git a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/hive/HiveTypeMapper.java b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/hive/HiveTypeMapper.java index 54057ddead5a..b859670ff771 100644 --- a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/hive/HiveTypeMapper.java +++ b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/hive/HiveTypeMapper.java @@ -30,6 +30,7 @@ import java.sql.ResultSetMetaData; import java.sql.SQLException; +import java.util.Locale; public class HiveTypeMapper implements JdbcDialectTypeMapper { @@ -68,7 +69,7 @@ public class HiveTypeMapper implements JdbcDialectTypeMapper { @Override public SeaTunnelDataType mapping(ResultSetMetaData metadata, int colIndex) throws SQLException { - String columnType = metadata.getColumnTypeName(colIndex).toUpperCase(); + String columnType = metadata.getColumnTypeName(colIndex).toUpperCase(Locale.ROOT); int precision = metadata.getPrecision(colIndex); switch (columnType) { case HIVE_TINYINT: diff --git a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/iris/IrisTypeConverter.java b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/iris/IrisTypeConverter.java index 1baee2ddad1c..e2c1072c193b 100644 --- a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/iris/IrisTypeConverter.java +++ b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/iris/IrisTypeConverter.java @@ -31,6 +31,7 @@ import com.google.auto.service.AutoService; import lombok.extern.slf4j.Slf4j; +import java.util.Locale; import java.util.Objects; /** @@ -144,7 +145,7 @@ public Column convert(BasicTypeDefine typeDefine) { .nullable(typeDefine.isNullable()) .defaultValue(typeDefine.getDefaultValue()) .comment(typeDefine.getComment()); - String irisDataType = typeDefine.getDataType().toUpperCase(); + String irisDataType = typeDefine.getDataType().toUpperCase(Locale.ROOT); long charOrBinaryLength = Objects.nonNull(typeDefineLength) && typeDefineLength > 0 ? typeDefineLength : 1; switch (irisDataType) { diff --git a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/kingbase/KingbaseTypeConverter.java b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/kingbase/KingbaseTypeConverter.java index 08133ba83d4f..9cea19a8aa98 100644 --- a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/kingbase/KingbaseTypeConverter.java +++ b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/kingbase/KingbaseTypeConverter.java @@ -37,6 +37,7 @@ import lombok.extern.slf4j.Slf4j; import java.sql.Types; +import java.util.Locale; // reference https://help.kingbase.com.cn/v8/development/sql-plsql/sql/datatype.html#id2 @Slf4j @@ -74,7 +75,7 @@ public Column convert(BasicTypeDefine typeDefine) { .defaultValue(typeDefine.getDefaultValue()) .comment(typeDefine.getComment()); - String kingbaseDataType = typeDefine.getDataType().toUpperCase(); + String kingbaseDataType = typeDefine.getDataType().toUpperCase(Locale.ROOT); switch (kingbaseDataType) { // MySQL compatibility - only types not in PostgresTypeConverter // int not in PG (PG has SMALLINT/INTEGER/BIGINT) diff --git a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/mysql/MysqlDialect.java b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/mysql/MysqlDialect.java index 685b19efad20..046625d8aa25 100644 --- a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/mysql/MysqlDialect.java +++ b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/mysql/MysqlDialect.java @@ -205,7 +205,7 @@ public Long approximateRowCntStatement(Connection connection, JdbcSourceTable ta boolean useTableStats = StringUtils.isBlank(table.getQuery()) - || (!table.getQuery().toLowerCase().contains("where") + || (!table.getQuery().toLowerCase(Locale.ROOT).contains("where") && table.getTablePath() != null && !TablePath.DEFAULT .getFullName() diff --git a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/oceanbase/OceanBaseMysqlDialect.java b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/oceanbase/OceanBaseMysqlDialect.java index f505559bad56..d147ac4d788c 100644 --- a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/oceanbase/OceanBaseMysqlDialect.java +++ b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/oceanbase/OceanBaseMysqlDialect.java @@ -42,6 +42,7 @@ import java.util.Arrays; import java.util.HashMap; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Optional; import java.util.stream.Collectors; @@ -204,7 +205,7 @@ public Long approximateRowCntStatement(Connection connection, JdbcSourceTable ta boolean useTableStats = StringUtils.isBlank(table.getQuery()) - || (!table.getQuery().toLowerCase().contains("where") + || (!table.getQuery().toLowerCase(Locale.ROOT).contains("where") && table.getTablePath() != null && !TablePath.DEFAULT .getFullName() diff --git a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/oracle/OracleDialect.java b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/oracle/OracleDialect.java index 2612b2c5cba8..b565a85b8fa6 100644 --- a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/oracle/OracleDialect.java +++ b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/oracle/OracleDialect.java @@ -51,6 +51,7 @@ import java.util.Collections; import java.util.LinkedHashSet; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Optional; import java.util.Set; @@ -242,7 +243,7 @@ public Long approximateRowCntStatement(Connection connection, JdbcSourceTable ta boolean useTableStats = StringUtils.isBlank(query) - || (!query.toLowerCase().contains("where") + || (!query.toLowerCase(Locale.ROOT).contains("where") && table.getTablePath() != null && !TablePath.DEFAULT .getFullName() diff --git a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/oracle/OracleTypeConverter.java b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/oracle/OracleTypeConverter.java index b997367485c9..dc6e9f63791f 100644 --- a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/oracle/OracleTypeConverter.java +++ b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/oracle/OracleTypeConverter.java @@ -33,6 +33,8 @@ import com.google.auto.service.AutoService; import lombok.extern.slf4j.Slf4j; +import java.util.Locale; + // reference https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/Data-Types.html @Slf4j @AutoService(TypeConverter.class) @@ -127,7 +129,7 @@ public Column convert(BasicTypeDefine typeDefine) { .defaultValue(typeDefine.getDefaultValue()) .comment(typeDefine.getComment()); - String oracleType = typeDefine.getDataType().toUpperCase(); + String oracleType = typeDefine.getDataType().toUpperCase(Locale.ROOT); if (oracleType.startsWith(ORACLE_INTERVAL)) { // The JDBC driver may report precision qualifiers in the type name, // e.g. "INTERVAL DAY(2) TO SECOND(6)", strip them for exact matching. diff --git a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/phoenix/PhoenixTypeConverter.java b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/phoenix/PhoenixTypeConverter.java index 8facf0304385..d0700246593f 100644 --- a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/phoenix/PhoenixTypeConverter.java +++ b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/phoenix/PhoenixTypeConverter.java @@ -32,6 +32,8 @@ import lombok.extern.slf4j.Slf4j; +import java.util.Locale; + import static org.apache.seatunnel.connectors.seatunnel.jdbc.internal.dialect.DatabaseIdentifier.PHOENIX; // reference https://phoenix.apache.org/language/datatypes.html @@ -98,7 +100,7 @@ public Column convert(BasicTypeDefine typeDefine) { .defaultValue(typeDefine.getDefaultValue()) .comment(typeDefine.getComment()); - String phoenixDataType = typeDefine.getDataType().toUpperCase(); + String phoenixDataType = typeDefine.getDataType().toUpperCase(Locale.ROOT); switch (phoenixDataType) { case PHOENIX_BOOLEAN: builder.dataType(BasicType.BOOLEAN_TYPE); diff --git a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/presto/PrestoTypeMapper.java b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/presto/PrestoTypeMapper.java index 2ef5fa921acd..2a7889a8aea3 100644 --- a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/presto/PrestoTypeMapper.java +++ b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/presto/PrestoTypeMapper.java @@ -28,6 +28,7 @@ import java.sql.ResultSetMetaData; import java.sql.SQLException; +import java.util.Locale; public class PrestoTypeMapper implements JdbcDialectTypeMapper { // ============================data types===================== @@ -66,7 +67,7 @@ public class PrestoTypeMapper implements JdbcDialectTypeMapper { @Override public SeaTunnelDataType mapping(ResultSetMetaData metadata, int colIndex) throws SQLException { - String columnType = metadata.getColumnTypeName(colIndex).toUpperCase(); + String columnType = metadata.getColumnTypeName(colIndex).toUpperCase(Locale.ROOT); // VARCHAR(x) ---> VARCHAR if (columnType.indexOf("(") > -1) { columnType = columnType.split("\\(")[0]; diff --git a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/psql/PostgresDialect.java b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/psql/PostgresDialect.java index 0572163d1223..76db4ec99a75 100644 --- a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/psql/PostgresDialect.java +++ b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/psql/PostgresDialect.java @@ -50,6 +50,7 @@ import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Optional; import java.util.Set; @@ -275,7 +276,7 @@ public Long approximateRowCntStatement(Connection connection, JdbcSourceTable ta boolean useTableStats = StringUtils.isBlank(table.getQuery()) - || (!table.getQuery().toLowerCase().contains("where") + || (!table.getQuery().toLowerCase(Locale.ROOT).contains("where") && table.getTablePath() != null && !TablePath.DEFAULT .getFullName() @@ -360,7 +361,7 @@ public void applySchemaChange( @Override public boolean needsQuotesWithDefaultValue(BasicTypeDefine columnDefine) { - String pgDataType = columnDefine.getDataType().toLowerCase(); + String pgDataType = columnDefine.getDataType().toLowerCase(Locale.ROOT); switch (pgDataType) { case PG_CHAR: case PG_VARCHAR: diff --git a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/psql/PostgresTypeConverter.java b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/psql/PostgresTypeConverter.java index 6d4a3b13ba42..5ed9751cec93 100644 --- a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/psql/PostgresTypeConverter.java +++ b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/psql/PostgresTypeConverter.java @@ -35,6 +35,7 @@ import lombok.extern.slf4j.Slf4j; import java.sql.Types; +import java.util.Locale; import java.util.regex.Pattern; // reference http://www.postgres.cn/docs/13/datatype.html @@ -141,7 +142,7 @@ public Column convert(BasicTypeDefine typeDefine) { .defaultValue(typeDefine.getDefaultValue()) .comment(typeDefine.getComment()); - String pgDataType = typeDefine.getDataType().toLowerCase(); + String pgDataType = typeDefine.getDataType().toLowerCase(Locale.ROOT); switch (pgDataType) { case PG_BOOLEAN: builder.dataType(BasicType.BOOLEAN_TYPE); diff --git a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/redshift/RedshiftDialect.java b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/redshift/RedshiftDialect.java index 55df1558ae44..bd3a4a220baf 100644 --- a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/redshift/RedshiftDialect.java +++ b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/redshift/RedshiftDialect.java @@ -33,6 +33,7 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; +import java.util.Locale; import java.util.Optional; public class RedshiftDialect implements JdbcDialect { @@ -145,7 +146,7 @@ public Long approximateRowCntStatement(Connection connection, JdbcSourceTable ta boolean useTableStats = StringUtils.isBlank(table.getQuery()) - || (!table.getQuery().toLowerCase().contains("where") + || (!table.getQuery().toLowerCase(Locale.ROOT).contains("where") && table.getTablePath() != null && !TablePath.DEFAULT .getFullName() diff --git a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/redshift/RedshiftTypeConverter.java b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/redshift/RedshiftTypeConverter.java index 3b4243030f70..7a188ece1010 100644 --- a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/redshift/RedshiftTypeConverter.java +++ b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/redshift/RedshiftTypeConverter.java @@ -35,6 +35,7 @@ import lombok.extern.slf4j.Slf4j; import java.sql.Types; +import java.util.Locale; // reference https://docs.aws.amazon.com/redshift/latest/dg/c_Supported_data_types.html @Slf4j @@ -91,7 +92,7 @@ public Column convert(BasicTypeDefine typeDefine) { .defaultValue(typeDefine.getDefaultValue()) .comment(typeDefine.getComment()); - String dataType = typeDefine.getDataType().toUpperCase(); + String dataType = typeDefine.getDataType().toUpperCase(Locale.ROOT); switch (dataType) { case REDSHIFT_BOOLEAN: builder.sourceType(REDSHIFT_BOOLEAN); diff --git a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/saphana/SapHanaTypeConverter.java b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/saphana/SapHanaTypeConverter.java index b0e4699db2cb..97b5f0e46633 100644 --- a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/saphana/SapHanaTypeConverter.java +++ b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/saphana/SapHanaTypeConverter.java @@ -36,6 +36,7 @@ import java.util.Arrays; import java.util.List; +import java.util.Locale; // reference // https://help.sap.com/docs/SAP_HANA_PLATFORM/4fe29514fd584807ac9f2a04f6754767/20a1569875191014b507cf392724b7eb.html?locale=en-US @@ -126,7 +127,7 @@ public Column convert(BasicTypeDefine typeDefine) { .defaultValue(typeDefine.getDefaultValue()) .comment(typeDefine.getComment()); - String hanaType = typeDefine.getDataType().toUpperCase(); + String hanaType = typeDefine.getDataType().toUpperCase(Locale.ROOT); if (typeDefine.getColumnType().endsWith(" ARRAY")) { typeDefine.setColumnType(typeDefine.getColumnType().replace(" ARRAY", "")); typeDefine.setDataType(removeColumnSizeIfNeed(typeDefine.getColumnType())); diff --git a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/snowflake/SnowflakeTypeConverter.java b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/snowflake/SnowflakeTypeConverter.java index ac0a74624771..9958a6bb1b4f 100644 --- a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/snowflake/SnowflakeTypeConverter.java +++ b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/snowflake/SnowflakeTypeConverter.java @@ -32,6 +32,8 @@ import com.google.auto.service.AutoService; import lombok.extern.slf4j.Slf4j; +import java.util.Locale; + // reference https://docs.snowflake.com/en/sql-reference/intro-summary-data-types @Slf4j @AutoService(TypeConverter.class) @@ -100,7 +102,7 @@ public Column convert(BasicTypeDefine typeDefine) { .nullable(typeDefine.isNullable()) .defaultValue(typeDefine.getDefaultValue()) .comment(typeDefine.getComment()); - String dataType = typeDefine.getDataType().toUpperCase(); + String dataType = typeDefine.getDataType().toUpperCase(Locale.ROOT); switch (dataType) { case SNOWFLAKE_SMALLINT: case SNOWFLAKE_TINYINT: diff --git a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/sqlite/SqliteTypeMapper.java b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/sqlite/SqliteTypeMapper.java index 21330996f74f..8dbcb0186359 100644 --- a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/sqlite/SqliteTypeMapper.java +++ b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/sqlite/SqliteTypeMapper.java @@ -28,6 +28,7 @@ import java.sql.ResultSetMetaData; import java.sql.SQLException; +import java.util.Locale; @Slf4j public class SqliteTypeMapper implements JdbcDialectTypeMapper { @@ -96,7 +97,8 @@ public class SqliteTypeMapper implements JdbcDialectTypeMapper { @Override public SeaTunnelDataType mapping(ResultSetMetaData metadata, int colIndex) throws SQLException { - String columnTypeName = metadata.getColumnTypeName(colIndex).toUpperCase().trim(); + String columnTypeName = + metadata.getColumnTypeName(colIndex).toUpperCase(Locale.ROOT).trim(); switch (columnTypeName) { case SQLITE_BIT: case SQLITE_BOOLEAN: diff --git a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/sqlserver/SqlServerDialect.java b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/sqlserver/SqlServerDialect.java index 9639d4f123af..865773a51725 100644 --- a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/sqlserver/SqlServerDialect.java +++ b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/sqlserver/SqlServerDialect.java @@ -45,6 +45,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Locale; import java.util.Optional; import java.util.stream.Collectors; @@ -199,7 +200,7 @@ public Long approximateRowCntStatement(Connection connection, JdbcSourceTable ta boolean useTableStats = StringUtils.isBlank(table.getQuery()) - || (!table.getQuery().toLowerCase().contains("where") + || (!table.getQuery().toLowerCase(Locale.ROOT).contains("where") && table.getTablePath() != null && !TablePath.DEFAULT .getFullName() diff --git a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/tablestore/TablestoreTypeMapper.java b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/tablestore/TablestoreTypeMapper.java index 36a5eabc27e4..bc9e1c6af4ad 100644 --- a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/tablestore/TablestoreTypeMapper.java +++ b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/tablestore/TablestoreTypeMapper.java @@ -28,6 +28,7 @@ import java.sql.ResultSetMetaData; import java.sql.SQLException; +import java.util.Locale; @Slf4j public class TablestoreTypeMapper implements JdbcDialectTypeMapper { @@ -52,7 +53,7 @@ public class TablestoreTypeMapper implements JdbcDialectTypeMapper { @Override public SeaTunnelDataType mapping(ResultSetMetaData metadata, int colIndex) throws SQLException { - String tablestoreServerType = metadata.getColumnTypeName(colIndex).toUpperCase(); + String tablestoreServerType = metadata.getColumnTypeName(colIndex).toUpperCase(Locale.ROOT); switch (tablestoreServerType) { case TABLESTORE_BOOL: return BasicType.BOOLEAN_TYPE; diff --git a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/teradata/TeradataTypeMapper.java b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/teradata/TeradataTypeMapper.java index f8bd0e99eaf6..771aded5cf8b 100644 --- a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/teradata/TeradataTypeMapper.java +++ b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/teradata/TeradataTypeMapper.java @@ -28,6 +28,7 @@ import java.sql.ResultSetMetaData; import java.sql.SQLException; +import java.util.Locale; public class TeradataTypeMapper implements JdbcDialectTypeMapper { @@ -61,7 +62,7 @@ public class TeradataTypeMapper implements JdbcDialectTypeMapper { @Override public SeaTunnelDataType mapping(ResultSetMetaData metadata, int colIndex) throws SQLException { - String teradataType = metadata.getColumnTypeName(colIndex).toUpperCase(); + String teradataType = metadata.getColumnTypeName(colIndex).toUpperCase(Locale.ROOT); switch (teradataType) { case TERADATA_BYTEINT: return BasicType.BYTE_TYPE; diff --git a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/vertica/VerticaTypeMapper.java b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/vertica/VerticaTypeMapper.java index b9e27d170093..22481137348d 100644 --- a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/vertica/VerticaTypeMapper.java +++ b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/vertica/VerticaTypeMapper.java @@ -32,6 +32,7 @@ import java.sql.ResultSetMetaData; import java.sql.SQLException; +import java.util.Locale; public class VerticaTypeMapper implements JdbcDialectTypeMapper { @@ -92,7 +93,7 @@ public class VerticaTypeMapper implements JdbcDialectTypeMapper { @Override public SeaTunnelDataType mapping(ResultSetMetaData metadata, int colIndex) throws SQLException { - String type = metadata.getColumnTypeName(colIndex).toUpperCase(); + String type = metadata.getColumnTypeName(colIndex).toUpperCase(Locale.ROOT); int precision = metadata.getPrecision(colIndex); int scale = metadata.getScale(colIndex); switch (type) { diff --git a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/xugu/XuguTypeConverter.java b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/xugu/XuguTypeConverter.java index 8074e6ce4e72..ead1ff4ef859 100644 --- a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/xugu/XuguTypeConverter.java +++ b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/xugu/XuguTypeConverter.java @@ -32,6 +32,8 @@ import com.google.auto.service.AutoService; import lombok.extern.slf4j.Slf4j; +import java.util.Locale; + // reference // https://docs.xugudb.com/content/reference/sql/datatype/numerical @Slf4j @@ -104,7 +106,7 @@ public Column convert(BasicTypeDefine typeDefine) { .defaultValue(typeDefine.getDefaultValue()) .comment(typeDefine.getComment()); - String xuguDataType = typeDefine.getDataType().toUpperCase(); + String xuguDataType = typeDefine.getDataType().toUpperCase(Locale.ROOT); switch (xuguDataType) { case XUGU_BOOLEAN: case XUGU_BOOL: diff --git a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/yashandb/YashanDbDialect.java b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/yashandb/YashanDbDialect.java index a8bd0ef9cfc6..52c9b6990c99 100644 --- a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/yashandb/YashanDbDialect.java +++ b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/yashandb/YashanDbDialect.java @@ -44,6 +44,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Locale; import java.util.Objects; import java.util.Optional; import java.util.stream.Collectors; @@ -209,7 +210,7 @@ public Long approximateRowCntStatement(Connection connection, JdbcSourceTable ta boolean useTableStats = StringUtils.isBlank(query) - || (!query.toLowerCase().contains("where") + || (!query.toLowerCase(Locale.ROOT).contains("where") && table.getTablePath() != null && !TablePath.DEFAULT .getFullName() diff --git a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/yashandb/YashanDbTypeConverter.java b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/yashandb/YashanDbTypeConverter.java index 022dc54c2dfa..cc6168f3ed3d 100644 --- a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/yashandb/YashanDbTypeConverter.java +++ b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/yashandb/YashanDbTypeConverter.java @@ -37,6 +37,7 @@ import java.util.Collections; import java.util.EnumSet; +import java.util.Locale; import java.util.Set; // reference @@ -164,7 +165,7 @@ public Column convert(BasicTypeDefine typeDefine) { .defaultValue(typeDefine.getDefaultValue()) .comment(typeDefine.getComment()); - String yashanType = typeDefine.getDataType().toUpperCase(); + String yashanType = typeDefine.getDataType().toUpperCase(Locale.ROOT); switch (yashanType) { // ====================== Integer types ====================== diff --git a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/source/CollationBasedSplitter.java b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/source/CollationBasedSplitter.java index eb98a28a4cf9..c6f5d6a50881 100644 --- a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/source/CollationBasedSplitter.java +++ b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/source/CollationBasedSplitter.java @@ -21,6 +21,7 @@ import java.math.BigInteger; import java.util.Arrays; +import java.util.Locale; @Slf4j public class CollationBasedSplitter { @@ -140,7 +141,7 @@ private static String stringToAsciiString( expectedLength, paddingAtEnd, isCaseInsensitive); - String str = isCaseInsensitive ? s.toLowerCase() : s; + String str = isCaseInsensitive ? s.toLowerCase(Locale.ROOT) : s; char[] paddedChars = new char[expectedLength]; if (paddingAtEnd) { diff --git a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/source/JdbcSourceFactory.java b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/source/JdbcSourceFactory.java index 573664ad1f8c..21dd375ff6d6 100644 --- a/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/source/JdbcSourceFactory.java +++ b/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/source/JdbcSourceFactory.java @@ -41,6 +41,7 @@ import java.io.Serializable; import java.util.List; +import java.util.Locale; import java.util.stream.Collectors; @Slf4j @@ -184,7 +185,7 @@ public String description() { @Override public boolean evaluate(ReadonlyConfig config, String value) { - return value == null || value.toLowerCase().startsWith("where"); + return value == null || value.toLowerCase(Locale.ROOT).startsWith("where"); } } } diff --git a/seatunnel-connectors-v2/connector-jdbc/src/test/java/org/apache/seatunnel/connectors/seatunnel/jdbc/catalog/redshift/RedshiftCatalogLocaleTest.java b/seatunnel-connectors-v2/connector-jdbc/src/test/java/org/apache/seatunnel/connectors/seatunnel/jdbc/catalog/redshift/RedshiftCatalogLocaleTest.java new file mode 100644 index 000000000000..ce8e1086cae1 --- /dev/null +++ b/seatunnel-connectors-v2/connector-jdbc/src/test/java/org/apache/seatunnel/connectors/seatunnel/jdbc/catalog/redshift/RedshiftCatalogLocaleTest.java @@ -0,0 +1,86 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.seatunnel.connectors.seatunnel.jdbc.catalog.redshift; + +import org.apache.seatunnel.api.table.type.BasicType; +import org.apache.seatunnel.common.utils.JdbcUrlUtil; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.parallel.ResourceLock; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Locale; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +/** + * Verifies that catalog schema discovery does not depend on the JVM default locale. + * + *

{@link RedshiftCatalog#buildColumn(ResultSet)} upper-cases the driver column type before it is + * matched against the dialect constants. Under a Turkish locale a bare {@code toUpperCase()} turns + * {@code integer} into {@code İNTEGER} ({@code U+0130}) and the column is no longer recognized, so + * this test drives the real discovery method with a mocked result set instead of calling the type + * converter directly. All three locale categories are restored afterwards. + */ +@ResourceLock("java.util.Locale") +public class RedshiftCatalogLocaleTest { + + @Test + public void testBuildColumnUnderTurkishLocale() throws SQLException { + Locale base = Locale.getDefault(); + Locale display = Locale.getDefault(Locale.Category.DISPLAY); + Locale format = Locale.getDefault(Locale.Category.FORMAT); + try { + Locale.setDefault(new Locale("tr", "TR")); + + Assertions.assertEquals( + BasicType.INT_TYPE, catalog().buildColumn(column("integer")).getDataType()); + Assertions.assertEquals( + BasicType.LONG_TYPE, catalog().buildColumn(column("bigint")).getDataType()); + } finally { + Locale.setDefault(base); + Locale.setDefault(Locale.Category.DISPLAY, display); + Locale.setDefault(Locale.Category.FORMAT, format); + } + } + + private static RedshiftCatalog catalog() { + return new RedshiftCatalog( + "redshift", + "user", + "pwd", + JdbcUrlUtil.getUrlInfo("jdbc:redshift://127.0.0.1:5439/test"), + "public", + null); + } + + private static ResultSet column(String dataType) throws SQLException { + ResultSet resultSet = mock(ResultSet.class); + when(resultSet.getString("COLUMN_NAME")).thenReturn("test"); + when(resultSet.getString("DATA_TYPE")).thenReturn(dataType); + when(resultSet.getLong("NUMERIC_PRECISION")).thenReturn(10L); + when(resultSet.getInt("NUMERIC_SCALE")).thenReturn(0); + when(resultSet.getLong("CHARACTER_MAXIMUM_LENGTH")).thenReturn(0L); + when(resultSet.getObject("COLUMN_DEFAULT")).thenReturn(null); + when(resultSet.getString("IS_NULLABLE")).thenReturn("YES"); + return resultSet; + } +} diff --git a/seatunnel-connectors-v2/connector-jdbc/src/test/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/JdbcTypeConverterLocaleTest.java b/seatunnel-connectors-v2/connector-jdbc/src/test/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/JdbcTypeConverterLocaleTest.java new file mode 100644 index 000000000000..fb18a7ba26ba --- /dev/null +++ b/seatunnel-connectors-v2/connector-jdbc/src/test/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/JdbcTypeConverterLocaleTest.java @@ -0,0 +1,153 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.seatunnel.connectors.seatunnel.jdbc.internal.dialect; + +import org.apache.seatunnel.api.table.converter.BasicTypeDefine; +import org.apache.seatunnel.api.table.converter.TypeConverter; +import org.apache.seatunnel.api.table.type.BasicType; +import org.apache.seatunnel.api.table.type.DecimalType; +import org.apache.seatunnel.api.table.type.SeaTunnelDataType; +import org.apache.seatunnel.connectors.seatunnel.jdbc.internal.dialect.db2.DB2TypeConverter; +import org.apache.seatunnel.connectors.seatunnel.jdbc.internal.dialect.dm.DmdbTypeConverter; +import org.apache.seatunnel.connectors.seatunnel.jdbc.internal.dialect.iris.IrisTypeConverter; +import org.apache.seatunnel.connectors.seatunnel.jdbc.internal.dialect.kingbase.KingbaseTypeConverter; +import org.apache.seatunnel.connectors.seatunnel.jdbc.internal.dialect.oracle.OracleTypeConverter; +import org.apache.seatunnel.connectors.seatunnel.jdbc.internal.dialect.psql.PostgresTypeConverter; +import org.apache.seatunnel.connectors.seatunnel.jdbc.internal.dialect.redshift.RedshiftTypeConverter; +import org.apache.seatunnel.connectors.seatunnel.jdbc.internal.dialect.saphana.SapHanaTypeConverter; +import org.apache.seatunnel.connectors.seatunnel.jdbc.internal.dialect.xugu.XuguTypeConverter; +import org.apache.seatunnel.connectors.seatunnel.jdbc.internal.dialect.yashandb.YashanDbTypeConverter; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.parallel.ResourceLock; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.util.Locale; +import java.util.stream.Stream; + +/** + * Verifies that the dialect type converters do not depend on the JVM default locale. + * + *

Every converter runs as its own parameterized invocation, so a regression in a single dialect + * fails with that converter's name instead of hiding inside one combined assertion. + * + *

The default locale is switched to Turkish, where {@code i} upper-cases to a dotted capital + * {@code I} ({@code U+0130}), in {@link BeforeEach} and restored in {@link AfterEach}: the previous + * base, {@code DISPLAY} and {@code FORMAT} defaults are captured before the switch, and JUnit runs + * the restore even when the converter call throws, so a Turkish default cannot leak into other + * tests sharing the JVM. {@link ResourceLock} keeps the class out of the way if parallel execution + * is enabled later. + */ +@ResourceLock("java.util.Locale") +public class JdbcTypeConverterLocaleTest { + + private Locale base; + private Locale display; + private Locale format; + + @BeforeEach + public void switchToTurkishLocale() { + base = Locale.getDefault(); + display = Locale.getDefault(Locale.Category.DISPLAY); + format = Locale.getDefault(Locale.Category.FORMAT); + Locale.setDefault(new Locale("tr", "TR")); + } + + @AfterEach + public void restoreDefaultLocale() { + Locale.setDefault(base); + Locale.setDefault(Locale.Category.DISPLAY, display); + Locale.setDefault(Locale.Category.FORMAT, format); + } + + @ParameterizedTest(name = "{0} maps {2}") + @MethodSource("converters") + public void convertsSourceTypeUnderTurkishLocale( + String dialect, + TypeConverter converter, + String sourceType, + SeaTunnelDataType expectedType) { + Assertions.assertEquals( + expectedType, + converter.convert(typeDefine(sourceType)).getDataType(), + dialect + " folded " + sourceType + " to the wrong type under tr-TR"); + } + + private static Stream converters() { + return Stream.of( + Arguments.of( + "DB2TypeConverter", + DB2TypeConverter.INSTANCE, + "integer", + BasicType.INT_TYPE), + Arguments.of( + "DmdbTypeConverter", DmdbTypeConverter.INSTANCE, "int", BasicType.INT_TYPE), + Arguments.of( + "IrisTypeConverter", + IrisTypeConverter.INSTANCE, + "integer", + BasicType.INT_TYPE), + Arguments.of( + "KingbaseTypeConverter", + KingbaseTypeConverter.INSTANCE, + "int", + BasicType.INT_TYPE), + Arguments.of( + "OracleTypeConverter", + OracleTypeConverter.INSTANCE, + "integer", + new DecimalType(OracleTypeConverter.DEFAULT_PRECISION, 0)), + Arguments.of( + "PostgresTypeConverter", + PostgresTypeConverter.INSTANCE, + "INT4", + BasicType.INT_TYPE), + Arguments.of( + "RedshiftTypeConverter", + RedshiftTypeConverter.INSTANCE, + "integer", + BasicType.INT_TYPE), + Arguments.of( + "SapHanaTypeConverter", + SapHanaTypeConverter.INSTANCE, + "integer", + BasicType.INT_TYPE), + Arguments.of( + "XuguTypeConverter", + XuguTypeConverter.INSTANCE, + "integer", + BasicType.INT_TYPE), + Arguments.of( + "YashanDbTypeConverter", + YashanDbTypeConverter.INSTANCE, + "integer", + BasicType.INT_TYPE)); + } + + private static BasicTypeDefine typeDefine(String dataType) { + return BasicTypeDefine.builder() + .name("test") + .columnType(dataType) + .dataType(dataType) + .build(); + } +} diff --git a/seatunnel-connectors-v2/connector-jdbc/src/test/java/org/apache/seatunnel/connectors/seatunnel/jdbc/source/CharsetBasedSplitterTest.java b/seatunnel-connectors-v2/connector-jdbc/src/test/java/org/apache/seatunnel/connectors/seatunnel/jdbc/source/CharsetBasedSplitterTest.java index c877e30827a5..a398a52e4543 100644 --- a/seatunnel-connectors-v2/connector-jdbc/src/test/java/org/apache/seatunnel/connectors/seatunnel/jdbc/source/CharsetBasedSplitterTest.java +++ b/seatunnel-connectors-v2/connector-jdbc/src/test/java/org/apache/seatunnel/connectors/seatunnel/jdbc/source/CharsetBasedSplitterTest.java @@ -17,16 +17,20 @@ package org.apache.seatunnel.connectors.seatunnel.jdbc.source; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.parallel.ResourceLock; import lombok.extern.slf4j.Slf4j; import java.math.BigInteger; +import java.util.Locale; import static org.junit.jupiter.api.Assertions.assertEquals; @Slf4j +@ResourceLock("java.util.Locale") public class CharsetBasedSplitterTest { private static final String DEFAULT_CHARSET = "0123456789abcdefghijklmnopqrstuvwxyz"; @@ -186,4 +190,39 @@ public void testRandomStrings() { assertEquals(randomString, decoded.trim()); } } + + @Test + @DisplayName("Case insensitive encoding of I is stable under a Turkish default locale") + public void testCaseInsensitiveEncodingUnderTurkishLocale() { + Locale base = Locale.getDefault(); + Locale display = Locale.getDefault(Locale.Category.DISPLAY); + Locale format = Locale.getDefault(Locale.Category.FORMAT); + int radix = DEFAULT_CHARSET.length() + 1; + try { + Locale.setDefault(Locale.ROOT); + BigInteger lower = + CollationBasedSplitter.encodeStringToNumericRange( + "i", 1, true, true, DEFAULT_CHARSET, radix); + Assertions.assertEquals( + lower, + CollationBasedSplitter.encodeStringToNumericRange( + "I", 1, true, true, DEFAULT_CHARSET, radix)); + + Locale.setDefault(new Locale("tr", "TR")); + Assertions.assertEquals( + lower, + CollationBasedSplitter.encodeStringToNumericRange( + "I", 1, true, true, DEFAULT_CHARSET, radix), + "upper case I must fold to i and not to the dotless \u0131"); + Assertions.assertEquals( + "i", + CollationBasedSplitter.decodeNumericRangeToString( + lower.toString(), 1, radix, DEFAULT_CHARSET) + .trim()); + } finally { + Locale.setDefault(base); + Locale.setDefault(Locale.Category.DISPLAY, display); + Locale.setDefault(Locale.Category.FORMAT, format); + } + } } diff --git a/seatunnel-e2e/seatunnel-connector-v2-e2e/connector-jdbc-e2e/connector-jdbc-e2e-part-7/src/test/java/org/apache/seatunnel/connectors/seatunnel/jdbc/JdbcMysqlSplitIT.java b/seatunnel-e2e/seatunnel-connector-v2-e2e/connector-jdbc-e2e/connector-jdbc-e2e-part-7/src/test/java/org/apache/seatunnel/connectors/seatunnel/jdbc/JdbcMysqlSplitIT.java index fe850d5f9c31..4e2cf82b2d1c 100644 --- a/seatunnel-e2e/seatunnel-connector-v2-e2e/connector-jdbc-e2e/connector-jdbc-e2e-part-7/src/test/java/org/apache/seatunnel/connectors/seatunnel/jdbc/JdbcMysqlSplitIT.java +++ b/seatunnel-e2e/seatunnel-connector-v2-e2e/connector-jdbc-e2e/connector-jdbc-e2e-part-7/src/test/java/org/apache/seatunnel/connectors/seatunnel/jdbc/JdbcMysqlSplitIT.java @@ -69,6 +69,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Set; import java.util.concurrent.TimeUnit; @@ -873,4 +874,167 @@ public void testFixedNumericSplitsReadAllRows() throws Exception { } } } + + // The charset_based string splitter encodes MIN/MAX of the partition column into a number and + // decodes the interior boundaries back to strings. Under tr-TR a bare toLowerCase() turns the + // I of "I1" into a dotless i (U+0131), and CollationBasedSplitter#charToIndex maps any + // character outside the collation sequence to index 0 - the same index as the padding + // character - so the encoded range collapses and every interior bound decodes to a string that + // starts with the U+0001 placeholder instead of "i". + // + // Asserting on the rows read cannot see that: the first split still starts at the literal MIN + // and the last still ends at the literal MAX, so every row is read exactly once and only the + // boundaries move. This test therefore compares the generated boundaries under Locale.ROOT and + // under tr-TR, and keeps the row identity check as an extra guard. + @Test + public void testFixedStringSplitBoundsAreLocaleIndependent() throws Exception { + String tableName = "fixed_string_locale"; + String qualifiedTable = MYSQL_DATABASE + "." + tableName; + List ids = + Arrays.asList( + "I1", "i2", "I3", "i4", "I5", "i6", "I7", "i8", "I9", "i10", "I11", "i12", + "i13", "i14", "I15", "i16", "I17", "i18", "I19", "i20"); + try (Connection connection = getJdbcConnection(); + Statement statement = connection.createStatement()) { + statement.execute( + "CREATE TABLE " + + qualifiedTable + + " (id VARCHAR(32) PRIMARY KEY) COLLATE utf8mb4_general_ci"); + try { + try (PreparedStatement insert = + connection.prepareStatement( + "INSERT INTO " + qualifiedTable + " (id) VALUES (?)")) { + for (String id : ids) { + insert.setString(1, id); + insert.addBatch(); + } + insert.executeBatch(); + } + + String query = "SELECT id FROM " + qualifiedTable; + Map configMap = new HashMap<>(); + configMap.put("url", mysqlUrlInfo.getUrlWithDatabase().get()); + configMap.put("driver", "com.mysql.cj.jdbc.Driver"); + configMap.put("username", MYSQL_USERNAME); + configMap.put("password", MYSQL_PASSWORD); + configMap.put("query", query); + configMap.put("partition_column", "id"); + configMap.put("split.string_split_mode", "charset_based"); + // isCaseInsensitive is not read from the table collation: FixedChunkSplitter asks + // JdbcDialect#getCollationSequence for the ASCII order of the connection and treats + // a sequence that contains an "aa"-like pair as case insensitive. Pinning the + // collation here keeps that decision deterministic (the server default may not tie + // A with a) and documents which collation the fixture actually exercises. The + // table collation above still drives the MIN/MAX ordering the fixture relies on. + configMap.put("split.string_split_mode_collate", "utf8mb4_general_ci"); + + TablePath tablePath = TablePath.of(MYSQL_DATABASE, tableName); + try (MySqlCatalog mySqlCatalog = + new MySqlCatalog( + "mysql", + MYSQL_USERNAME, + MYSQL_PASSWORD, + mysqlUrlInfo, + null); + FixedChunkSplitter splitter = getFixedChunkSplitter(configMap)) { + // MySqlCatalog is fixed in the sibling PR, so read the catalog table before the + // default locale is switched: only the split generation below has to run under + // tr-TR. + mySqlCatalog.open(); + CatalogTable table = mySqlCatalog.getTable(tablePath); + JdbcSourceTable jdbcSourceTable = + JdbcSourceTable.builder() + .tablePath(tablePath) + .catalogTable(table) + .query(query) + .partitionColumn("id") + .partitionNumber(4) + .build(); + + List rootSplits; + List rootBounds; + List turkishBounds; + Map readCounts = new HashMap<>(); + int splitCount = 0; + Locale base = Locale.getDefault(); + Locale display = Locale.getDefault(Locale.Category.DISPLAY); + Locale format = Locale.getDefault(Locale.Category.FORMAT); + try { + Locale.setDefault(Locale.ROOT); + rootSplits = new ArrayList<>(splitter.generateSplits(jdbcSourceTable)); + rootBounds = splitBounds(rootSplits); + + Locale.setDefault(new Locale("tr", "TR")); + Collection turkishSplits = + splitter.generateSplits(jdbcSourceTable); + turkishBounds = splitBounds(turkishSplits); + for (JdbcSourceSplit split : turkishSplits) { + splitCount++; + try (PreparedStatement splitStatement = + splitter.generateSplitStatement( + split, table.getTableSchema()); + ResultSet resultSet = splitStatement.executeQuery()) { + while (resultSet.next()) { + readCounts.merge(resultSet.getString(1), 1, Integer::sum); + } + } + } + } finally { + Locale.setDefault(base); + Locale.setDefault(Locale.Category.DISPLAY, display); + Locale.setDefault(Locale.Category.FORMAT, format); + } + + Assertions.assertEquals( + rootBounds, + turkishBounds, + "split bounds depend on the JVM default locale"); + for (int i = 0; i < rootSplits.size(); i++) { + if (i > 0) { + assertFoldedBound(rootSplits.get(i).getSplitStart()); + } + if (i < rootSplits.size() - 1) { + assertFoldedBound(rootSplits.get(i).getSplitEnd()); + } + } + Assertions.assertTrue( + splitCount > 1, "expected more than one split, got " + splitCount); + Assertions.assertEquals( + ids.size(), + readCounts.size(), + "row identities read across splits differ: " + readCounts.keySet()); + for (String id : ids) { + Assertions.assertEquals( + 1, + readCounts.getOrDefault(id, 0), + "row " + id + " was not read exactly once"); + } + } + } finally { + statement.execute("DROP TABLE IF EXISTS " + qualifiedTable); + } + } + } + + private static List splitBounds(FixedChunkSplitter splitter, JdbcSourceTable table) + throws Exception { + return splitBounds(splitter.generateSplits(table)); + } + + private static List splitBounds(Collection splits) { + List bounds = new ArrayList<>(); + for (JdbcSourceSplit split : splits) { + bounds.add(split.getSplitStart() + ".." + split.getSplitEnd()); + } + return bounds; + } + + private static void assertFoldedBound(Object bound) { + Assertions.assertNotNull(bound, "generated interior bound must not be null"); + String text = bound.toString(); + Assertions.assertEquals( + text.toLowerCase(Locale.ROOT), + text, + "interior bound " + text + " is not folded to the case insensitive sequence"); + } }