@@ -51,10 +51,23 @@ extension MainContentCoordinator {
5151 // Wrap in a transaction for atomicity
5252 try await driver. beginTransaction ( )
5353
54+ /// Rollback transaction and reset executing state for early exits.
55+ @MainActor func rollbackAndResetState( ) async {
56+ try ? await driver. rollbackTransaction ( )
57+ if let idx = tabManager. tabs. firstIndex ( where: { $0. id == tabId } ) {
58+ tabManager. tabs [ idx] . isExecuting = false
59+ }
60+ currentQueryTask = nil
61+ toolbarState. setExecuting ( false )
62+ }
63+
5464 for (stmtIndex, sql) in statements. enumerated ( ) {
55- guard !Task. isCancelled else { break }
65+ guard !Task. isCancelled else {
66+ await rollbackAndResetState ( )
67+ return
68+ }
5669 guard capturedGeneration == queryGeneration else {
57- try ? await driver . rollbackTransaction ( )
70+ await rollbackAndResetState ( )
5871 return
5972 }
6073
@@ -123,7 +136,19 @@ extension MainContentCoordinator {
123136 try ? await driver. rollbackTransaction ( )
124137 }
125138
126- guard capturedGeneration == queryGeneration else { return }
139+ // Always reset isExecuting even if generation is stale —
140+ // skipping this leaves the tab permanently stuck in "executing" state.
141+ if capturedGeneration != queryGeneration {
142+ await MainActor . run { [ weak self] in
143+ guard let self else { return }
144+ if let idx = tabManager. tabs. firstIndex ( where: { $0. id == tabId } ) {
145+ tabManager. tabs [ idx] . isExecuting = false
146+ }
147+ currentQueryTask = nil
148+ toolbarState. setExecuting ( false )
149+ }
150+ return
151+ }
127152
128153 let failedStmtIndex = executedCount + 1
129154 let contextMsg = " Statement \( failedStmtIndex) / \( totalCount) failed: "
@@ -189,7 +214,13 @@ extension MainContentCoordinator {
189214 toolbarState. setExecuting ( false )
190215 toolbarState. lastQueryDuration = cumulativeTime
191216
192- guard capturedGeneration == queryGeneration else { return }
217+ // Always reset isExecuting even if generation is stale
218+ if capturedGeneration != queryGeneration {
219+ if let idx = tabManager. tabs. firstIndex ( where: { $0. id == tabId } ) {
220+ tabManager. tabs [ idx] . isExecuting = false
221+ }
222+ return
223+ }
193224 guard let idx = tabManager. tabs. firstIndex ( where: { $0. id == tabId } ) else {
194225 return
195226 }
0 commit comments