Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Jan 16, 2026

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 using a quoted boolean that toggles on single quotes ('). This quote-tracking logic was introduced in #34917.

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

  • Remove single quotes from block comments
  • Use two single quotes in block comments to escape them

How found

Customer reported on 10.0.1

Regression

Yes, from EF Core 9.0. Introduced in #34917.

Testing

Added 11 tests.

Risk

Medium. The changes only affect custom SQL operations in migrations.


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

- 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 <[email protected]>
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
Copilot AI requested a review from AndriySvyryd January 16, 2026 00:27
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 <[email protected]>
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 <[email protected]>
- 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 <[email protected]>
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 <[email protected]>
- Simplified comment to "Reset "Maybe" states at line start"
- Moved MaybeLineComment and MaybeBlockCommentStart handling before main switch
- When these states transition to Normal, the current character is reprocessed
- Moved MaybeBlockCommentEnd to end of switch block
- Added default case that throws UnreachableException
- Added explicit cases for Normal, Quoted, and InBlockComment states to avoid default
- All 17 tests pass

Co-authored-by: AndriySvyryd <[email protected]>
Copy link
Contributor Author

Copilot AI commented Jan 16, 2026

Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • http://crl3.digicert.com:443/DigiCertTrustedG4RSA4096SHA256TimeStampingCA.crl
    • Triggering command: /usr/bin/dotnet dotnet build src/EFCore.SqlServer/EFCore.SqlServer.csproj --detach 6fe0.pid /run/containerd/io.containerd.runtime.v2.task/moby/17cb24c6361d5627f6d657f1cc3a5adae2b860e2c5b1dac8c18ee9896bc5302d/9de091e27e35a64e8a4e82cd61f3a4600691317ab977b24c24318149350413e6.pid 17cb24c6361d5627f6d657f1cc3a5adae2b860e2c5b1dac8c18ee9896bc5302d (http block)

If you need me to access, download, or install something from one of these locations, you can either:

@AndriySvyryd
Copy link
Member

@copilot Update progress by rewriting the PR summary using this template:

Fixes #{number}

**Description**
{Issue description}

**Customer impact**
{How does the reported issue affects customer's app? Are there workarounds?}

**How found**
{Was it customer reported or found during verification? How many customers are affected?}

**Regression**
{Is it a regression from a released version? Which one?}

**Testing**
{How the changes were tested}

**Risk**
{Low/Medium/High, argument why}

Removed comment "Fall through to process c with Normal state" as the fall-through behavior is self-evident from the code structure.

Co-authored-by: AndriySvyryd <[email protected]>
Removed "Fall through to process c with Normal state" comment as the behavior is clear from the code structure.

Co-authored-by: AndriySvyryd <[email protected]>
Copy link
Contributor Author

Copilot AI commented Jan 16, 2026

@copilot Update progress by rewriting the PR summary using this template:

...

Done in 181fdd0. Updated PR description using the requested template format.

@AndriySvyryd AndriySvyryd changed the title Fix GO batch separator not recognized when block comment contains single quote [release/10.0] Fix GO batch separator not recognized when block comment contains single quote Jan 16, 2026
Removed redundant comments from Normal, Quoted, and InBlockComment cases that just stated "continue" as this behavior is self-evident from the break statements.

Co-authored-by: AndriySvyryd <[email protected]>
Copilot AI requested a review from AndriySvyryd January 16, 2026 23:44
@AndriySvyryd AndriySvyryd marked this pull request as ready for review January 16, 2026 23:46
@AndriySvyryd AndriySvyryd requested a review from a team as a code owner January 16, 2026 23:46
Copilot AI review requested due to automatic review settings January 16, 2026 23:46
@AndriySvyryd AndriySvyryd requested a review from artl93 January 16, 2026 23:50
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a bug in SQL Server migrations where GO batch separators were not recognized when block comments contained single quotes. The issue was introduced in EF Core 9.0 when quote-tracking logic was added, but it didn't account for block comments.

Changes:

  • Replaces simple boolean quote tracking with a state machine that properly handles SQL strings, line comments, and block comments
  • Adds comprehensive test coverage with 11 new test cases covering various comment and string scenarios

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
src/EFCore.SqlServer/Migrations/SqlServerMigrationsSqlGenerator.cs Implements a state machine with 6 states (Normal, Quoted, InBlockComment, MaybeLineComment, MaybeBlockCommentStart, MaybeBlockCommentEnd) to correctly parse SQL and ignore quotes inside block comments
test/EFCore.SqlServer.FunctionalTests/Migrations/SqlServerMigrationsSqlGeneratorTest.cs Adds 11 test cases covering block comments with quotes, multiline comments, empty comments, nested comments/strings, and edge cases like GO inside comments

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants