Skip to content

fix(ios): prevent crash when a query returns a very large result#1437

Merged
datlechin merged 3 commits into
mainfrom
fix/ios-query-editor-large-result-crash
May 27, 2026
Merged

fix(ios): prevent crash when a query returns a very large result#1437
datlechin merged 3 commits into
mainfrom
fix/ios-query-editor-large-result-crash

Conversation

@datlechin
Copy link
Copy Markdown
Member

What

Running a query that returns a very large result could crash the iOS app with an out-of-memory (jetsam) termination. Reported via TestFlight on build 15: comment "Crash", repro "when execute query with large data table".

Root cause

The SQL query editor drained up to 100,000 rows into memory with no back-pressure, no per-app memory budget check, and no memory-pressure handling. The Data Browser had all three; the editor's handlePressure existed but was never wired into the view, so it was dead code. The two view models also duplicated the streaming machinery (flush, shrink, apply, batch constants), which is how the editor drifted from the Browser's safety behavior.

A memory termination produces a TestFlight "Crash" with no symbolicated stack, which matches the sparse report.

Fix

  • New StreamingResultBuffer: one type that owns row accumulation, batched flushing, shrink, and reset. Both view models delegate to it, so they can't diverge again.
  • The editor checks os_proc_available_memory() every 500 rows and stops at a 64 MB headroom margin, before jetsam fires, rather than only reacting to memory-pressure signals (which can arrive too late). Backstop cap of 10,000 rows, with the window sized so it never slides, so the first rows are kept.
  • The editor is now wired to didReceiveMemoryWarningNotification and MemoryPressureMonitor.currentLevel, matching the Data Browser.
  • Truncation banner in the editor: "Showing the first N rows. Add LIMIT to fetch more." (plus a memory-stopped variant).

An editor result is a forward-only cursor that can't be re-paged, so the editor keeps the first rows and stops, instead of sliding a window and discarding the head like the Data Browser (which can re-fetch pages with LIMIT/OFFSET).

Tests

  • QueryEditorViewModelTests: cap keeps the head, clean finish, memory-pressure handling, reset.
  • StreamingResultBufferTests: flush / shrink / reset invariants.

Notes

  • iOS-only. No macOS files touched.
  • The 10,000-row backstop and 64 MB margin are the two tunable numbers.
  • Not run locally: xcodebuild and the test bundle (please run the TableProMobile tests). The new localized strings were extracted into the iOS string catalog by an Xcode build, which confirms the iOS target compiled.

@datlechin datlechin merged commit f7fff5b into main May 27, 2026
1 of 2 checks passed
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.

1 participant