[release/10.0] Fix GO batch separator not recognized in comments and escaped identifiers#37521
Merged
AndriySvyryd merged 20 commits intorelease/10.0from Feb 2, 2026
Merged
Conversation
- Add tracking for block comments (/* ... */) to prevent incorrect quote state toggling - Block comments can now contain single quotes without affecting GO batch separator recognition - Add comprehensive tests for various block comment scenarios - All tests pass successfully Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
Copilot
AI
changed the title
[WIP] Fix GO batch separator recognition for block comments
Fix GO batch separator not recognized when block comment contains single quote
Jan 16, 2026
src/EFCore.SqlServer/Migrations/SqlServerMigrationsSqlGenerator.cs
Outdated
Show resolved
Hide resolved
Removed separate if statements and i++ increments. Block comment detection now integrated into the main switch statement, making the code cleaner and more maintainable. Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
test/EFCore.SqlServer.FunctionalTests/Migrations/SqlServerMigrationsSqlGeneratorTest.cs
Show resolved
Hide resolved
Added test to verify that /* inside a line comment (-- /*) doesn't trigger block comment state and GO is still correctly recognized as a batch separator. Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
test/EFCore.SqlServer.FunctionalTests/Migrations/SqlServerMigrationsSqlGeneratorTest.cs
Show resolved
Hide resolved
- Changed all GO to go in new test SQL strings (will still appear as GO in output) - Added test for multiline block comment with go on separate line to verify go inside block comments is correctly ignored Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
Refactored to use foreach instead of for loop with index by tracking blockCommentStart and blockCommentEnd flags to detect /* and */ patterns across iterations. Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
src/EFCore.SqlServer/Migrations/SqlServerMigrationsSqlGenerator.cs
Outdated
Show resolved
Hide resolved
artl93
approved these changes
Jan 20, 2026
Member
artl93
left a comment
There was a problem hiding this comment.
Obviously, we want to avoid regression. The more we can add, the better, but otherwise, approved.
roji
reviewed
Jan 21, 2026
src/EFCore.SqlServer/Migrations/SqlServerMigrationsSqlGenerator.cs
Outdated
Show resolved
Hide resolved
src/EFCore.SqlServer/Migrations/SqlServerMigrationsSqlGenerator.cs
Outdated
Show resolved
Hide resolved
src/EFCore.SqlServer/Migrations/SqlServerMigrationsSqlGenerator.cs
Outdated
Show resolved
Hide resolved
src/EFCore.SqlServer/Migrations/SqlServerMigrationsSqlGenerator.cs
Outdated
Show resolved
Hide resolved
src/EFCore.SqlServer/Migrations/SqlServerMigrationsSqlGenerator.cs
Outdated
Show resolved
Hide resolved
src/EFCore.SqlServer/Migrations/SqlServerMigrationsSqlGenerator.cs
Outdated
Show resolved
Hide resolved
src/EFCore.SqlServer/Migrations/SqlServerMigrationsSqlGenerator.cs
Outdated
Show resolved
Hide resolved
src/EFCore.SqlServer/Migrations/SqlServerMigrationsSqlGenerator.cs
Outdated
Show resolved
Hide resolved
src/EFCore.SqlServer/Migrations/SqlServerMigrationsSqlGenerator.cs
Outdated
Show resolved
Hide resolved
src/EFCore.SqlServer/Migrations/SqlServerMigrationsSqlGenerator.cs
Outdated
Show resolved
Hide resolved
test/EFCore.SqlServer.FunctionalTests/Migrations/SqlServerMigrationsSqlGeneratorTest.cs
Show resolved
Hide resolved
…upport - Changed from foreach to for loop with look-ahead to eliminate Maybe* states - Simplified enum from 6 states to 5: Normal, Quoted, InBlockComment, InSquareBrackets, InDoubleQuotes - Added support for escaped identifiers: [go] and "go" - Added support for escaped closing brackets: [g]]o] - Changed switch statement to switch expression for cleaner code - Removed state reset logic (no longer needed without Maybe* states) - Added 9 comprehensive tests for escaped identifiers and character combinations - All 26 tests pass Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
Copilot
AI
changed the title
[release/10.0] Fix GO batch separator not recognized when block comment contains single quote
[release/10.0] Fix GO batch separator not recognized in comments and escaped identifiers
Jan 21, 2026
src/EFCore.SqlServer/Migrations/SqlServerMigrationsSqlGenerator.cs
Outdated
Show resolved
Hide resolved
test/EFCore.SqlServer.FunctionalTests/Migrations/SqlServerMigrationsSqlGeneratorTest.cs
Outdated
Show resolved
Hide resolved
test/EFCore.SqlServer.FunctionalTests/Migrations/SqlServerMigrationsSqlGeneratorTest.cs
Outdated
Show resolved
Hide resolved
test/EFCore.SqlServer.FunctionalTests/Migrations/SqlServerMigrationsSqlGeneratorTest.cs
Outdated
Show resolved
Hide resolved
test/EFCore.SqlServer.FunctionalTests/Migrations/SqlServerMigrationsSqlGeneratorTest.cs
Show resolved
Hide resolved
test/EFCore.SqlServer.FunctionalTests/Migrations/SqlServerMigrationsSqlGeneratorTest.cs
Outdated
Show resolved
Hide resolved
- Renamed ParsingState.Quoted to ParsingState.InQuotes and moved to end of enum
- Enhanced tests to include EOL before/after go and escaped characters
- Added 11 new comprehensive tests:
- Line comments inside quotes, square brackets, and double quotes
- Brackets and double quotes inside block comments
- Single quotes inside block comments
- All delimiter types inside line comments
- Escaped quotes in strings ('test''s value')
- Multiple delimiters in strings
- Updated existing tests with better coverage (double quote escaping, EOL placement)
- All 37 SqlOperation tests pass
Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
test/EFCore.SqlServer.FunctionalTests/Migrations/SqlServerMigrationsSqlGeneratorTest.cs
Outdated
Show resolved
Hide resolved
test/EFCore.SqlServer.FunctionalTests/Migrations/SqlServerMigrationsSqlGeneratorTest.cs
Outdated
Show resolved
Hide resolved
test/EFCore.SqlServer.FunctionalTests/Migrations/SqlServerMigrationsSqlGeneratorTest.cs
Outdated
Show resolved
Hide resolved
test/EFCore.SqlServer.FunctionalTests/Migrations/SqlServerMigrationsSqlGeneratorTest.cs
Outdated
Show resolved
Hide resolved
test/EFCore.SqlServer.FunctionalTests/Migrations/SqlServerMigrationsSqlGeneratorTest.cs
Outdated
Show resolved
Hide resolved
test/EFCore.SqlServer.FunctionalTests/Migrations/SqlServerMigrationsSqlGeneratorTest.cs
Outdated
Show resolved
Hide resolved
- Changed double quote identifier test to include newlines within the identifier (double quote spans multiple lines with go inside) - Changed square bracket test to include newlines within the identifier (bracket spans multiple lines with column inside) - Changed block comment tests to show unclosed brackets/quotes (removed closing bracket/quote to test edge cases) - Changed line comment tests to show unclosed brackets/quotes (line comments end at EOL, so bracket/quote is not closed) - These changes test that the parser correctly handles: - Multi-line escaped identifiers with go inside - Unclosed delimiters in comments (which are valid SQL since comments don't need matched delimiters) Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
roji
approved these changes
Jan 22, 2026
Member
roji
left a comment
There was a problem hiding this comment.
Thanks for making the changes, this is now easier to follow and I can't think of any problems.
This was referenced Feb 3, 2026
6 tasks
6 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #37494
Description
EF Core splits SQL Server migration scripts into batches on lines starting with GO. To avoid splitting inside string literals, SqlServerMigrationsSqlGenerator tracks whether it is inside a quoted string.
The implementation does not handle standard SQL block comments (/* ... */). If a block comment contains a single quote, the quoted state is incorrectly toggled even though the quote is inside a comment. Since there is no matching closing quote, quoted toggle remains true across subsequent lines. As a result, a later GO line is not recognized as a batch separator and is sent to SQL Server as literal text, causing:
Microsoft.Data.SqlClient.SqlException: Incorrect syntax near 'go'.Customer impact
Customers using SQL migrations with stored procedures or other SQL scripts that include block comments containing single quotes will experience migration failures with "Incorrect syntax near 'go'" errors. This can occur when documentation comments in SQL scripts use contractions or possessives (e.g., "It's", "user's").
Workarounds:
How found
Customer reported on 10.0.1
Regression
Yes, from EF Core 9.0. Introduced in #34917.
Testing
Added 31 tests covering:
[GO]and double quotes"GO"[g]]o]"go""lum"gotext inside (e.g.,INSERT INTO "\ngo\n" VALUES (1))--) inside quotes and escaped identifiers/* [bracket */- valid SQL since comments don't require matched delimiters)-- [column- valid SQL since line comments end at EOL)'test''s value')Risk
Medium, because the fix entails changes to a parser, so all the possible consequences aren't as clear. However, the changes only affect custom SQL operations in migrations.