Skip to content

Inline char constants as Unicode string literals in SQL Server IndexO… - #39104

Open
ilkertskn wants to merge 1 commit into
dotnet:mainfrom
ilkertskn:fix/sqlserver-char-constant-unicode-literal
Open

ilkertskn wants to merge 1 commit into
dotnet:mainfrom
ilkertskn:fix/sqlserver-char-constant-unicode-literal

Conversation

@ilkertskn

Copy link
Copy Markdown
Contributor

…f/Replace translations

SqlServerStringMethodTranslator applied CharTypeMapping to char arguments of string.IndexOf(char) and string.Replace(char, char). CharTypeMapping's literal has no N prefix, so a constant such as 'ş' or '中' was emitted as a non-Unicode literal and best-fit mapped to the database code page before the comparison: on the default collation CHARINDEX('ş', N'aşb') returns 0 while CHARINDEX('ş', N'asb') returns 2, and REPLACE(N'Şişlis', 'ş', 'x') replaces the trailing 's'. Passing the same char as a parameter (sent as nvarchar) gave the right answer, and an ExecuteUpdate with an inline char could silently corrupt data.

Emit char constants as string constants with the string argument's type mapping (N'ş' for nvarchar columns) and keep CharTypeMapping only for non-constant char expressions. Existing baselines change from 'e' to N'e' accordingly; a varchar column still gets a non-Unicode literal.

  • [x ] I've read the guidelines for contributing and seen the walkthrough
  • [x ] I've posted a comment on an issue with a detailed description of how I am planning to contribute and got approval from a member of the team
  • [x ] The code builds and tests pass locally (also verified by our automated build checks)
  • [ x] Commit messages follow this format:
        Summary of the changes
        - Detail 1
        - Detail 2

        Fixes #bugnumber
  • [x ] Tests for the changes have been added (for bug fixes / features)
  • [x ] Code follows the same patterns and style as existing code in this repo

…f/Replace translations

SqlServerStringMethodTranslator applied CharTypeMapping to char arguments of
string.IndexOf(char) and string.Replace(char, char). CharTypeMapping's literal has
no N prefix, so a constant such as 'ş' or '中' was emitted as a non-Unicode literal
and best-fit mapped to the database code page before the comparison: on the
default collation `CHARINDEX('ş', N'aşb')` returns 0 while `CHARINDEX('ş', N'asb')`
returns 2, and `REPLACE(N'Şişlis', 'ş', 'x')` replaces the trailing 's'. Passing the
same char as a parameter (sent as nvarchar) gave the right answer, and an
ExecuteUpdate with an inline char could silently corrupt data.

Emit char constants as string constants with the string argument's type mapping
(N'ş' for nvarchar columns) and keep CharTypeMapping only for non-constant char
expressions. Existing baselines change from 'e' to N'e' accordingly; a varchar
column still gets a non-Unicode literal.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant