You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Bug][Connector-V2][JDBC] SQL Server column types and instanceName break under a Turkish or Azerbaijani locale #13075
I had searched in the issues and found no similar issues.
What happened
Two case conversions in the SQL Server JDBC code use the JVM default locale. Under tr-TR and az-AZ, "i".toUpperCase() is "İ" (U+0130), so both break on a worker with such a default locale.
Column types.SqlServerTypeConverter.convert upper cases the type name before its switch (SqlServerTypeConverter.java:112):
SQL Server type names are lower case: the catalog reads sys.types.name, the query path reads ResultSetMetaData.getColumnTypeName, and the Microsoft JDBC driver reports names such as int, bigint, datetime2 and decimal (its SSType names, checked in mssql-jdbc 9.2.1). So int becomes İNT and the column fails to convert. Every type name with an i is affected: int, bigint, tinyint, smallint, bit, decimal, numeric, datetime, datetime2, smalldatetime, time, binary, varbinary, image, uniqueidentifier. This one method serves the catalog (table_path), the query path and SQL Server CDC (SqlServerTypeUtils). In a JVM started with -Duser.language=tr -Duser.country=TR, 13 tests in SqlServerTypeConverterTest fail on dev.
instanceName in the URL.SqlServerURLParser.parse upper cases the URL property keys to match them case insensitively (SqlServerURLParser.java:52), then looks up "INSTANCENAME". Under tr-TR the key becomes İNSTANCENAME, the instance is not found, and the parser falls back to port 1433. Measured with the class from dev, for jdbc:sqlserver://localhost;instanceName=SQLEXPRESS;databaseName=myDB;encrypt=false:
The driver documentation says that when both a port and an instance name are given, the port takes precedence and the instance name is ignored. So the catalog and SQL Server CDC connect to the default instance instead of the named one.
Thanks for the detailed report and reproduction. Agreed: the toUpperCase() calls in SqlServerTypeConverter.convert and SqlServerURLParser.parse should use a fixed, locale-independent conversion instead of the JVM default locale. Since you offered to submit a PR, please go ahead. While you are at it, it would be worth checking the rest of connector-jdbc for other locale-sensitive case conversions.
For regression coverage, a test that exercises the type converter and URL parser under the Turkish locale (for example, running SqlServerTypeConverterTest with -Duser.language=tr -Duser.country=TR) would be helpful.
You verified this on dev; could you also confirm whether the latest release is affected? That helps decide whether a backport is needed.
Latest release: affected. I ran the same reproduction against the released connector-jdbc jars from Maven Central, 3.0.0 and 2.3.13, on JDK 17. Under tr-TR and az-AZ both versions fail convert("int") with 'SqlServer' unsupported convert type 'İNT' (and BİGİNT, DATETİME2 for bigint and datetime2), and the instanceName URL comes back as jdbc:sqlserver://localhost:1433;instanceName=SQLEXPRESS;encrypt=false, port 1433. Under en-US both versions are correct.
Regression tests:#13077 adds SqlServerTypeConverterTest#testConvertDoesNotDependOnTheDefaultLocale and SqlServerURLParserTest#testInstanceNamePropertyDoesNotDependOnTheDefaultLocale. They set tr-TR and then az-AZ as the default locale inside the test and restore it afterwards, so they run in the normal CI build without extra -D flags.
Rest of connector-jdbc: on current dev (fcb404c) there are 53 toUpperCase() / toLowerCase() calls without a locale under connector-jdbc/src/main.
9 only check whether a query starts with or contains where. That word has no i, so the result is the same in every locale.
The other 30 are mostly the type converters and mappers of other dialects (Oracle, DB2, DM, Kingbase, IRIS, Xugu, YashanDB, SAP HANA, Snowflake, Redshift, Hive, Presto, Teradata, Vertica and a few more), plus the Xugu database name lookup and CollationBasedSplitter. Whether each one actually breaks depends on what case the driver or catalog query returns, so I will check them one by one and open small follow-ups grouped by dialect for the ones that do, keeping [Fix][Connector-V2][JDBC] Make SQL Server type and URL parsing independent of the default locale #13077 to SQL Server.
An update on the rest of connector-jdbc that I said I would check: @sharpca is covering it in #13079 and #13083 (the other dialects, CollationBasedSplitter and the Xugu catalog), so I will not open separate follow-ups for it.
I checked the heads: with #13063, #13076, #13077 and #13083 together, only one bare case conversion remains in connector-jdbc/src/main, the where prefix check in SqlWhereConditionHelper, which does not depend on the locale because where has no i. #13077 stays limited to the SQL Server type converter and URL parser.
The reproduction against the released 3.0.0 and 2.3.13 connector-jdbc jars settles the question: the 'İNT' / BİGİNT / DATETİME2 failures from SqlServerTypeConverter.convert and the instanceName URL falling back to port 1433 under tr-TR / az-AZ, with en-US correct, matches the original report, so I am treating this as a confirmed bug rather than an environment quirk.
The two regression tests you describe cover both affected call sites, and switching the default locale inside the test rather than via -D flags is the right approach so CI exercises them unconditionally. Please just make sure the default locale is restored even when an assertion fails, so it cannot leak into other tests in the same JVM.
On scope: keeping #13077 limited to the SQL Server type converter and URL parser, with the remaining connector-jdbc call sites handled in the other open PRs, works for me. Your inventory on dev (fcb404c) is useful to have on record here, and I agree the where prefix check in SqlWhereConditionHelper is locale-neutral and can stay as-is.
Thanks @SEZ9. Both tests in #13077 already restore it on failure: they save the default locale and the FORMAT and DISPLAY category defaults before the try, and set all three back in finally (SqlServerURLParserTest.java:163-181 and SqlServerTypeConverterTest.java:916-934), so a failed assertion cannot leak the Turkish or Azerbaijani locale into other tests in the JVM.
Thanks for the clarification, @SEPURI-SAI-KRISHNA — that settles the locale-restoration concern. Saving the default locale plus the FORMAT and DISPLAY category defaults before the try and resetting all three in finally is exactly what I wanted to see; with that, a failed assertion in either testConvertDoesNotDependOnTheDefaultLocale or testInstanceNamePropertyDoesNotDependOnTheDefaultLocale cannot leak tr-TR or az-AZ into the rest of the JVM, and the tests can run in the normal CI build without extra -D flags as you described.
Also noted on the follow-up scope: with the other dialects, CollationBasedSplitter and the Xugu catalog being handled in #13079 and #13083, and the remaining where prefix check in SqlWhereConditionHelper being locale-neutral, I agree there is nothing further for you to open here, and keeping #13077 limited to the SQL Server type converter and URL parser is the right call.
Nothing else outstanding from my side on this issue. I will finish the review on #13077 itself; once it lands, please drop a short note here so we can close this issue referencing the fix.
Activity
SEZ9 commentedon Nov 1, 2026
Thanks for the detailed report and reproduction. Agreed: the
toUpperCase()calls inSqlServerTypeConverter.convertandSqlServerURLParser.parseshould use a fixed, locale-independent conversion instead of the JVM default locale. Since you offered to submit a PR, please go ahead. While you are at it, it would be worth checking the rest ofconnector-jdbcfor other locale-sensitive case conversions.For regression coverage, a test that exercises the type converter and URL parser under the Turkish locale (for example, running
SqlServerTypeConverterTestwith-Duser.language=tr -Duser.country=TR) would be helpful.You verified this on
dev; could you also confirm whether the latest release is affected? That helps decide whether a backport is needed.SEPURI-SAI-KRISHNA commentedon Nov 1, 2026
Thanks for the review. The fix is up in #13077.
Latest release: affected. I ran the same reproduction against the released
connector-jdbcjars from Maven Central, 3.0.0 and 2.3.13, on JDK 17. Undertr-TRandaz-AZboth versions failconvert("int")with'SqlServer' unsupported convert type 'İNT'(andBİGİNT,DATETİME2forbigintanddatetime2), and theinstanceNameURL comes back asjdbc:sqlserver://localhost:1433;instanceName=SQLEXPRESS;encrypt=false, port 1433. Underen-USboth versions are correct.Regression tests: #13077 adds
SqlServerTypeConverterTest#testConvertDoesNotDependOnTheDefaultLocaleandSqlServerURLParserTest#testInstanceNamePropertyDoesNotDependOnTheDefaultLocale. They settr-TRand thenaz-AZas the default locale inside the test and restore it afterwards, so they run in the normal CI build without extra-Dflags.Rest of
connector-jdbc: on currentdev(fcb404c) there are 53toUpperCase()/toLowerCase()calls without a locale underconnector-jdbc/src/main.field_ide,CatalogUtilsandJdbcDialect), [Fix][Connector-V2][JDBC] Read MySQL and OceanBase column types independently of the default locale #13076 (MySQL and OceanBase) and [Fix][Connector-V2][JDBC] Make SQL Server type and URL parsing independent of the default locale #13077 (SQL Server).where. That word has noi, so the result is the same in every locale.CollationBasedSplitter. Whether each one actually breaks depends on what case the driver or catalog query returns, so I will check them one by one and open small follow-ups grouped by dialect for the ones that do, keeping [Fix][Connector-V2][JDBC] Make SQL Server type and URL parsing independent of the default locale #13077 to SQL Server.SEPURI-SAI-KRISHNA commentedon Nov 1, 2026
An update on the rest of
connector-jdbcthat I said I would check: @sharpca is covering it in #13079 and #13083 (the other dialects,CollationBasedSplitterand the Xugu catalog), so I will not open separate follow-ups for it.I checked the heads: with #13063, #13076, #13077 and #13083 together, only one bare case conversion remains in
connector-jdbc/src/main, thewhereprefix check inSqlWhereConditionHelper, which does not depend on the locale becausewherehas noi. #13077 stays limited to the SQL Server type converter and URL parser.SEZ9 commentedon Nov 2, 2026
Thanks for the thorough follow-up, @SEPURI-SAI-KRISHNA.
The reproduction against the released 3.0.0 and 2.3.13
connector-jdbcjars settles the question: the'İNT'/BİGİNT/DATETİME2failures fromSqlServerTypeConverter.convertand theinstanceNameURL falling back to port 1433 undertr-TR/az-AZ, withen-UScorrect, matches the original report, so I am treating this as a confirmed bug rather than an environment quirk.The two regression tests you describe cover both affected call sites, and switching the default locale inside the test rather than via
-Dflags is the right approach so CI exercises them unconditionally. Please just make sure the default locale is restored even when an assertion fails, so it cannot leak into other tests in the same JVM.On scope: keeping #13077 limited to the SQL Server type converter and URL parser, with the remaining
connector-jdbccall sites handled in the other open PRs, works for me. Your inventory ondev(fcb404c) is useful to have on record here, and I agree thewhereprefix check inSqlWhereConditionHelperis locale-neutral and can stay as-is.I will do the detailed review on #13077 itself.
SEPURI-SAI-KRISHNA commentedon Nov 2, 2026
Thanks @SEZ9. Both tests in #13077 already restore it on failure: they save the default locale and the
FORMATandDISPLAYcategory defaults before thetry, and set all three back infinally(SqlServerURLParserTest.java:163-181andSqlServerTypeConverterTest.java:916-934), so a failed assertion cannot leak the Turkish or Azerbaijani locale into other tests in the JVM.SEZ9 commentedon Nov 3, 2026
Thanks for the clarification, @SEPURI-SAI-KRISHNA — that settles the locale-restoration concern. Saving the default locale plus the
FORMATandDISPLAYcategory defaults before thetryand resetting all three infinallyis exactly what I wanted to see; with that, a failed assertion in eithertestConvertDoesNotDependOnTheDefaultLocaleortestInstanceNamePropertyDoesNotDependOnTheDefaultLocalecannot leaktr-TRoraz-AZinto the rest of the JVM, and the tests can run in the normal CI build without extra-Dflags as you described.Also noted on the follow-up scope: with the other dialects,
CollationBasedSplitterand the Xugu catalog being handled in #13079 and #13083, and the remainingwhereprefix check inSqlWhereConditionHelperbeing locale-neutral, I agree there is nothing further for you to open here, and keeping #13077 limited to the SQL Server type converter and URL parser is the right call.Nothing else outstanding from my side on this issue. I will finish the review on #13077 itself; once it lands, please drop a short note here so we can close this issue referencing the fix.