Skip to content

[Bug][Connector-V2][JDBC] SQL Server column types and instanceName break under a Turkish or Azerbaijani locale #13075

Open

Description

@SEPURI-SAI-KRISHNA

Search before asking

  • 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):

String sqlServerType = typeDefine.getDataType().toUpperCase();

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:

ROOT   jdbc:sqlserver://localhost\SQLEXPRESS;instanceName=SQLEXPRESS;encrypt=false   port=null
tr-TR  jdbc:sqlserver://localhost:1433;instanceName=SQLEXPRESS;encrypt=false        port=1433

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.

SeaTunnel Version

dev (f3e1c2e)

SeaTunnel Config

source {
  Jdbc {
    url = "jdbc:sqlserver://localhost;instanceName=SQLEXPRESS;databaseName=test;encrypt=false"
    driver = "com.microsoft.sqlserver.jdbc.SQLServerDriver"
    user = "sa"
    password = "..."
    table_path = "test.dbo.orders"
  }
}

Running Command

Any SQL Server job on a worker started with -Duser.language=tr -Duser.country=TR

Error Exception

ErrorCode:[COMMON-17], ErrorDescription:['SqlServer' unsupported convert type 'İNT' of 'test' to SeaTunnel data type.]

Zeta or Flink or Spark Version

All engines. The code is in connector-jdbc.

Java or Scala Version

Reproduced on JDK 17.

Screenshots

No response

Are you willing to submit PR?

  • Yes I am willing to submit a PR!

Code of Conduct

Activity

  1. SEZ9 commented on Nov 1, 2026

    @SEZ9
    Collaborator

    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.

  2. SEPURI-SAI-KRISHNA commented on Nov 1, 2026

    @SEPURI-SAI-KRISHNA
    CollaboratorAuthor

    Thanks for the review. The fix is up in #13077.

    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.

  3. SEPURI-SAI-KRISHNA commented on Nov 1, 2026

    @SEPURI-SAI-KRISHNA
    CollaboratorAuthor

    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.

  4. SEZ9 commented on Nov 2, 2026

    @SEZ9
    Collaborator

    Thanks for the thorough follow-up, @SEPURI-SAI-KRISHNA.

    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.

    I will do the detailed review on #13077 itself.

  5. SEPURI-SAI-KRISHNA commented on Nov 2, 2026

    @SEPURI-SAI-KRISHNA
    CollaboratorAuthor

    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.

  6. SEZ9 commented on Nov 3, 2026

    @SEZ9
    Collaborator

    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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions