Fix: Isolate query execution state per editor instance to prevent shared SPID issues #20407
+291
−95
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.
When multiple editors view the same SQL file (split views or tabs), they share a single QueryRunner instance and SQL Server session (SPID). This causes UI state synchronization issues: if Tab 1 starts a transaction, Tab 2's completed query incorrectly shows "executing..." until Tab 1 commits.
Changes
Key generation for editor instances
getEditorInstanceKey()to generate unique keys per editor using URI + viewColumn (e.g.,"file:///test.sql::2")getDocumentUriFromEditorKey()to extract document URI from instance keysExecution state isolation
Document lifecycle handling
onDidCloseTextDocument(): Cleans up all editor instances for closed document (handles keys matchingdocumentUriordocumentUri::*)onUntitledFileSaved()/updateQueryRunnerUri(): Remaps all editor instances when document is saved/renamedArchitecture
Connections remain keyed by document URI (shared), while execution state and SPIDs are isolated per editor instance.
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:
update.code.visualstudio.com/usr/local/bin/node ./out/test/unit/runTest.js --grep Editor Instance Key(dns block)If you need me to access, download, or install something from one of these locations, you can either:
Original prompt
This section details on the original issue you should resolve
<issue_title>Keeps running while in transaction</issue_title>
<issue_description>
Type: Bug
begin tran
delete command
exec sp
select
while committing (or even on previous commands), the editor keep "executing query"
Extension version: 1.30.0
VS Code version: Code 1.99.2 (4949701c880d4bdb949e3c0e6b400288da7f474b, 2025-04-10T01:21:25.295Z)
OS version: Windows_NT x64 10.0.26100
Modes:
System Info
canvas_oop_rasterization: enabled_on
direct_rendering_display_compositor: disabled_off_ok
gpu_compositing: enabled
multiple_raster_threads: enabled_on
opengl: enabled_on
rasterization: enabled
raw_draw: disabled_off_ok
skia_graphite: disabled_off
video_decode: enabled
video_encode: enabled
vulkan: disabled_off
webgl: enabled
webgl2: enabled
webgpu: enabled
webnn: disabled_off
A/B Experiments
<agent_instructions>Problem Statement
When a user opens the same SQL file in multiple editor instances (tabs, split views, or windows), all editors share the same query execution state and SQL Server session (SPID). This causes critical UI state synchronization issues:
Primary Issue - Shared Execution State:
When multiple tabs/editors are open for the same file and they share the same SPID:
Tab 1 executes a query that starts a transaction (e.g., BEGIN TRANSACTION; UPDATE table SET column = value;)
Tab 2 executes a different query (e.g., SELECT * FROM another_table;)
Problem: Tab 2's query completes successfully and returns results, BUT the UI shows the query as still "executing" indefinitely because Tab 1's transaction hasn't been committed
The execution state is shared between both tabs, so Tab 1's active transaction causes Tab 2's UI to remain in "executing" state even though Tab 2's query finished
Secondary Issue - Session Sharing:
Both editors use the same SQL Server session (SPID), which means:
Any transaction state from one editor affects the other
Query execution contexts are not isolated
Users cannot work independently in different tabs of the same file
Reproduction Steps:
Open a SQL file (e.g., test.sql)
Split the editor or open the same file in a second tab
In Tab 1: Execute BEGIN TRANSACTION; UPDATE table SET column = value; (leaves transaction open)
In Tab 2: Execute SELECT * FROM another_table; (different query, no locks needed)
Result: Tab 2 gets query results successfully, but the UI shows "executing..." indefinitely until Tab 1 commits the transaction
Root Cause
The extension currently keys all connection state, query runners, and execution state tracking by document URI only. When multiple editors view the same document, they all share:
The same QueryRunner instance
The same execution state tracking in SqlOutputContentProvider
The same SQL Server session (SPID)
The same status bar state in StatusView
This means UI updates and execution state from one editor instance overwrite or interfere with another editor's state.
Required Solution
Implement per-editor-instance isolation for query execution state and SQL Server sessions while maintaining shared connection profiles:
Generate unique editor instance keys using both document URI and VS Code's viewColumn property (e.g., "file:///path/to/file.sql::1", "file:///path/to/file.sql::2")
Separate connection sharing from execution context: Connection credentials can be shared, but each editor instance must get:
Its own QueryRunner with independent execution state tracking
Its own SQL Server session (SPID) for query execution
Its own status bar state showing query execution status
Update state management across these components:
ConnectionManager: Track execution contexts per editor instance while sharing connection profiles
SqlOutputContentProvider: Key query runners by editor instance, not just document URI - each editor needs its own QueryRunnerState
QueryRunner: Us...
✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.