fix(plugin-mssql): run SQL Server scripts as GO batches and show every result set they return - #3105
Merged
Merged
Conversation
…y result set they return
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Automations to automatically generate PRs for you. |
Signed-off-by: Ngô Quốc Đạt <datlechin@gmail.com>
This was referenced Sep 24, 2026
fix(datagrid): sort a query result by re-running its own statement with the values it ran with
#3114
Merged
fix(editor): keep the semicolon that ends a SQL Server MERGE, which the server refuses without
#3115
Merged
Merged
This branch was successfully deployed
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 #3078.
Root cause
The editor split a SQL Server script at every
;and sent each piece in its own request. SQL Server treats every request as a batch, and a local variable, a table variable, aTRY...CATCHor anIF ... BEGIN ... ENDblock lives only inside the batch that declares it. SoDECLARE @snwas gone by the time the nextSELECTran:Statement 2/5 failed: Must declare the scalar variable "@sn".The editor could not send a script whole because the driver could only hand back one result set per request. The FreeTDS loop put every later result set's rows under the first one's columns, and the streaming path trapped when a later result set was wider.
What changed
Scripts now run the way
sqlcmd, SSMS and Azure Data Studio run them: a batch at a time, cut atGOlines, with every result set a batch returns in its own result tab.GOis a statement boundary in the SQL Server grammar. It is a new grammar fact,batchSeparatorLines, with its PluginKit partner. The gutter, run at cursor, navigation, Explain and the Safe Mode gate all see it, so aDROPbehind aGOline is classified, andGOnever reaches the server.GO nruns the batch n times.executeBatch(query:rowCap:parameters:) -> PluginBatchResult?returns every complete result set, the rows affected, and each server error with its line and procedure. It is additive, with a default of nil and aresultSetBatchescapability, and it reuses kit 33, already pending this cycle. The ABI check shows 22 additions and 0 removals. An installed MSSQL plugin that predates this keeps running statement by statement, and refusesGO nwith a message rather than running the batch once.FAILfromdbresultsfails only that statement.SELECT 1/0, a conversion error mid-scan) are reported instead of showing an empty or short result.-1counts are ignored.PRINTreaches the Output view throughfetchServerOutput.:namevalues are bound with a leadingDECLAREon the batch's first line, soBEGIN TRAN,#temptables andUSEbehave as they would unbound.sp_executesqlis kept only for batches that must be alone: routine definitions and bare procedure calls.QueryExecutionCoordinator+Batches.BEGIN TRANandTRY...CATCHdecide, and a transaction the script leaves open is reported.Batch 2/3 failed: Line 7: …, with the line mapped to the editor.DECLARE/SETnames each result after its query and keeps Load More, unless the query reads a variable. Other batches number their results.EXEC sp_help, runs as a batch and shows all its result sets.Before / After
The reporter's script on SQL Server (Azure SQL Edge in Docker). Before: TablePro 0.75.0 with the published MSSQL plugin 1.0.46:
After: this branch. One batch, four result sets (
serialnew,v_wms_joined,drm_report_n,serial_existed), the last one shown:A second batch after a
GOthat hits a missing table. The line is the editor line, and thePRINTfrom that batch is shown before the error. The grid under the banner shows the previous run's columns. That behaviour is already onmainfor every engine: it reproduces on SQLite through the unchanged statement-by-statement path. It is not part of this change.Verification
verify.sh build: PASS.verify.sh plugins(AllPlugins, including the registry-only MSSQL driver): PASS.verify.sh testover 29 suites that own the changed types, including the planner, sort, batch run, failure report, gate, status model, adapter,SQLScriptText, scanner and all MSSQL suites: 531/531.TableProSQLGrammarTests: 51, including 22 newGOseparator tests.TableProQueryTests: 60.TableProMSSQLCoreTests: 78 swift-testing and 66 XCTest.scripts/check-mssql-batch-results.shis a new live check. It builds the real MSSQL plugin sources and runs them against Azure SQL Edge in Docker: 40/40. Againstmain's driver sources the checks fail, 7 of the first 12, and the stream path then traps with index out of range.GOerror case above. In-place sorting and its reset are covered byMainContentCoordinatorSortTests.Release note
MSSQL is a registry-only plugin, so the fix reaches users when this app release ships and the MSSQL plugin is re-published against kit 33. An older installed MSSQL plugin keeps today's behaviour, minus
GObeing sent to the server.Known limitations
DECLARE @x int = 1orSET @x = …adds 1 to a batch's rows affected.mainshows the same count for those statements.?rewriter still differs from the app's:namescanner inside bracketed identifiers such as[Total:USD]. That difference is already onmain.