Skip to content

fix(sidebar): refuse a saved query too large to sync instead of cutting it short - #3086

Merged
datlechin merged 1 commit into
mainfrom
fix/favorite-size-cap-truncation
Sep 23, 2026
Merged

datlechin merged 1 commit into
mainfrom
fix/favorite-size-cap-truncation

Conversation

@datlechin

Copy link
Copy Markdown
Member

Summary

Saving a query longer than 500,000 characters as a favorite stored a truncated copy with nothing on screen. A 10,000-line seed script (about 690 KB) was saved and synced cut off mid-statement. The dialog now keeps the whole query. A saved query too large to sync is refused with an inline message and a dimmed Save button.

Found while investigating #2505.

Root cause

FavoriteEditDialog.save() checked (query as NSString).length > 500_000 and then stored String(query.prefix(500_000)): a Character-count prefix of a UTF-16 length check. There was no message and Save stayed enabled. The cap came in with the first favorites commit (#332), before favorites synced, and nothing local needs it. SQLite and the FTS5 index store the full text, and a new storage test round-trips an 830 KB query intact.

The real limit is iCloud. query is a plain String field on the SQLFavorite CKRecord (SyncRecordMapper.toCKRecord(sqlFavorite:)). Apple's CKRecord documentation, under Supported Data Types, says: "the data that a record stores must not exceed 1 MB. Assets don't count toward this limit, but all other data types do." The old check also measured the wrong unit. 500,000 UTF-16 units of CJK text is 1.5 MB of UTF-8, which CloudKit rejects. A rejected record keeps its dirty flag and is retried on every sync.

Fix

  • SQLFavoriteSizeValidation (valid / tooLarge) counts the UTF-8 bytes of name + query + keyword, the text the synced record carries, against maximumSyncableByteCount = 900_000. That leaves 100 KB under the 1 MB record limit for ids, dates and field names.
  • SQLFavoriteEditValidation.canSave takes the size result. The dialog dims Save and shows a red message under the query, in the same style as the keyword field's message: "Saved queries are limited to 900 KB so they fit in iCloud. Save a query this large as a .sql file instead."
  • The dialog's save logic moved into SQLFavoriteEditDraft: trimming, newFavorite() and applied(to:at:). The size check reads exactly the values that get saved, and the no-truncation behaviour is testable. save() also guards isValid.
  • Docs: one sentence in docs/features/favorites.mdx states the limit and points bigger scripts to linked SQL folders.

Cost: utf8.count on a string bridged from NSTextView is O(n). Measured at about 2 ms for a 960 KB query and about 20 microseconds for a 10 KB one. It runs twice per dialog render.

Tests

  • SQLFavoriteSizeValidationTests: exactly at the limit is valid. One byte over is too large and the message names the limit. A 700,000-character seed script (past the old cap) is valid. 300,001 CJK characters are too large even though they are under 500,000 UTF-16 units. Name and keyword count toward the limit.
  • SQLFavoriteEditValidationTests: too large blocks save.
  • SQLFavoriteEditDraftTests: a new or edited favorite keeps a 687,787-character script whole, including its last statement. Editing keeps the id, sort order and creation date. Name and keyword are trimmed and a blank keyword is dropped. Folder and scope carry through. The size check reads the trimmed values.
  • SQLFavoriteStorageTests: a query past 500,000 characters is stored and read back whole.

No UI test: showing the message needs close to 1 MB of text typed or pasted into a TextEditor, and that does not drive deterministically under XCUITest.

@mintlify

mintlify Bot commented Sep 23, 2026

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated
TablePro 🟢 Ready View Preview Sep 23, 2026, 3:20 PM

💡 Tip: Enable Automations to automatically generate PRs for you.

@datlechin
datlechin force-pushed the fix/favorite-size-cap-truncation branch from d40293c to 3f5dfa2 Compare September 23, 2026 15:49
@datlechin
datlechin merged commit 6987192 into main Sep 23, 2026
4 checks passed
@datlechin
datlechin deleted the fix/favorite-size-cap-truncation branch September 23, 2026 19:19

This branch was successfully deployed

1 active deployment
staging - docs 3f5dfa2f Deployed Sep 23, 2026 by mintlify[bot]
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