Skip to content

fix(sidebar): keep a linked SQL file's other header lines when editing its metadata - #3084

Merged
datlechin merged 1 commit into
mainfrom
fix/linked-metadata-keeps-unknown-keys
Sep 23, 2026
Merged

datlechin merged 1 commit into
mainfrom
fix/linked-metadata-keeps-unknown-keys

Conversation

@datlechin

Copy link
Copy Markdown
Member

Summary

Edit Metadata on a linked SQL file deleted every header line other than @name, @keyword and @description. A file with -- @author: alice and -- @reviewed: 2026-09-01 lost both on the first save, and a leading -- @formatter:off was deleted too. Found while investigating #2505.

Measured on main with -- @name: Monthly revenue\n-- @author: alice\n-- @reviewed: 2026-09-01\n-- @keyword: rev\nSELECT 1;\n: the save wrote -- @name: Monthly revenue\n-- @keyword: rev\n\nSELECT 1;\n. A CRLF file came back with an LF header over a CRLF body, and a description with a line break wrote its second line into the SQL.

Root cause

SQLFrontmatter.parseWithBody counts any leading -- @<key>: value line as frontmatter and moves the body offset past it, but only reads name, keyword and description. LinkedSQLFavoriteWriter.writeMetadata kept the text after that offset, and render wrote back only those three keys, joined with \n. The parser consumed every other line in the block, and nothing wrote it back.

Fix

  • SQLFrontmatter.split(_:) returns the header as lines, each with its raw text, its own terminator, its key and its value, plus the byte order mark and the untouched body. parse(_:) is built on it and reads the same metadata as before. SQLFrontmatter.Key names the three keys the app owns, in canonical order.
  • LinkedSQLFavoriteWriter.rewrite(_:with:) is a pure function that changes only the owned lines:
    • every other line keeps its position and its bytes;
    • an owned line whose value did not change keeps its original spelling, so saving unchanged metadata leaves the file identical;
    • a changed value is written as -- @key: value on the same line ending; a cleared one removes only its line; a duplicated owned key collapses to one line;
    • a missing key is inserted beside the other owned keys in name, keyword, description order;
    • inserted lines use the file's own line ending instead of always \n;
    • a value is written on one line, so a multi-line description can no longer leak into the SQL. It is split on CR and LF only, the same characters the parser splits on. A value holding U+0085 (byte 0x85 in a file read as Latin-1), U+2028 or U+2029 is therefore compared and written unchanged instead of losing that character.
  • A header created in a file that had none still gets the blank separator line it got before. Encoding handling in writeMetadata is unchanged.
  • The parser still treats any -- @key: value line as part of the block. That no longer decides what survives a save, since every line the app does not own is copied through.
  • docs/features/favorites.mdx now says where the block ends and what Edit Metadata changes. It no longer claims the file keeps its encoding. FileTextLoader.load strips a byte order mark, so a UTF-8 file with a BOM loses it on save and a UTF-16 BE file is written back little-endian. That behaviour predates this change and is left for a separate fix.

Tests

  • LinkedSQLFavoriteWriterTests: rename with foreign keys, byte-for-byte identity on unchanged metadata, canonical insertion, insertion before an existing keyword, clearing one key, clearing all keys, -- @formatter:off, CRLF preservation, CRLF for a created header, blank separator for a created header, multi-line description, duplicate owned keys, parse-back of the rewritten header, and a writeMetadata round trip through a temporary file on disk.
  • Three tests, each run with U+0085, U+2028 and U+2029: a value holding the character survives an unchanged save, survives a change to a sibling key, and a new value holding it is written as typed and parses back. One more writes a file whose name line holds byte 0x85, changes only the keyword through writeMetadata, and compares the bytes on disk.
  • SQLFrontmatterTests (5): raw text and terminators per header line (LF, CRLF, CR), block ending at a blank line, a last header line with no terminator, byte order mark, and owned keys read past foreign ones.
  • The new separator tests and the 0x85 disk test all fail against the previous revision of this branch (13 issues) and pass after the change. Against the old parser and writer on main, 12 of the original 14 rewrite tests fail. The two that pass guard behaviour this change keeps on purpose: the blank separator and parse-back.
  • No UI test: the flow is a sheet over a file on disk, and the whole behaviour sits in the pure rewrite covered above.

@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:19 PM

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

@datlechin
datlechin force-pushed the fix/linked-metadata-keeps-unknown-keys branch from 6dd738e to d3da1e3 Compare September 23, 2026 15:48
@datlechin
datlechin merged commit c1b4623 into main Sep 23, 2026
4 checks passed
@datlechin
datlechin deleted the fix/linked-metadata-keeps-unknown-keys branch September 23, 2026 19:19

This branch was successfully deployed

1 active deployment
staging - docs d3da1e35 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