Skip to content

fix(plugin-mongodb): make MQL exports and the query editor round-trip BSON values - #2090

Merged
datlechin merged 3 commits into
mainfrom
fix/2086-followups
Aug 11, 2026
Merged

fix(plugin-mongodb): make MQL exports and the query editor round-trip BSON values#2090
datlechin merged 3 commits into
mainfrom
fix/2086-followups

Conversation

@datlechin

Copy link
Copy Markdown
Member

Follow-ups to #2089. Three commits, each standalone.

1. MQL export loses BSON binary values

MQLExportPlugin hardcoded "subType": "00" on every binary cell. Investigating it turned up a bigger defect in the same line: the export writes {"$binary": {...}}, but the docs say the file is a mongosh script, and mongosh is a JavaScript REPL. It reads that as a plain object literal and inserts a subdocument with a $binary key, not a BSON binary. Fixing only the subtype would have corrected a value inside a container that never worked.

Both are now fixed together: binary exports as BinData(<subtype>, "<base64>"), a real mongosh constructor.

The subtype reaches the exporter with no PluginKit change. PluginStreamHeader already carries columnTypeNames and MQLExportPlugin was discarding it while holding the column index. BsonValueKind.binary (a MongoDB-plugin-internal enum) gained a UInt8 payload, and typeName now emits BLOB(3) where it emitted BLOB. ColumnTypeClassifier splits a type name at the first ( and looks up the base, so BLOB(3) still classifies as .blob and nothing about the grid, the hex editor, the edit guard or copy changes. MongoDBUuidCodec.columnTypeName(forSubtype:) and binarySubtype(fromColumnTypeName:) are the only places that spelling is written or read, and MQL export is supportedDatabaseTypeIds = ["MongoDB"], so it never sees another driver's BLOB.

This also reverses one thing #2089 got wrong: it taught MQL export to turn a UUID wrapper into $binary Extended JSON, which is the same mistake in the other direction. A wrapper now becomes BinData(...) too, so the output needs no particular mongosh version.

2. The query editor rejects mongosh syntax

Copy UUID("8cd003eb-…") out of the grid, paste it into a filter, get a parse error. libbson's bson_new_from_json speaks only Extended JSON, and TablePro supported no shell helper syntax at all: ObjectId(...), ISODate(...) and BinData(...) all failed the same way. #2089 made it visible by rendering text users would naturally paste.

MongoShellValueTranslator (new, in PluginKit, pure) rewrites value constructors into Extended JSON. MongoShellParser.parse runs it once over the whole statement, so every payload is covered from one place: filter, update, replacement, documents, pipeline, index keys, sort, projection and runCommand. That includes .sort({at: NumberInt(-1)}), which used to be dropped silently rather than reported.

The scan is string-aware and rests on one rule: a method call is always preceded by a dot and a constructor never is. That separates find( from ObjectId(, leaves a helper inside a string literal alone, and makes the pass idempotent, which matters because buildExplainQuery re-parses translated text.

Supported: ObjectId, ISODate, Date, NumberInt, NumberLong, NumberDecimal, Timestamp, BinData, HexData, MinKey, MaxKey, UUID and the legacy UUID names, which route through the existing codec rather than re-deriving the byte orders. Malformed arguments throw an error naming the helper. An unknown constructor is passed through untouched for the driver to reject, and text carrying no helper short-circuits, so the translator never doubles as a JSON validator.

Still not evaluated, and documented as such: new Date(), arithmetic, and regex literals like /abc/i.

3. Strings catalog

Java, C# and Python are driver identifiers, and CLAUDE.md says not to localize technical terms, so they are plain literals now, matching the SCRAM-SHA-1 / X.509 / AWS IAM options in the same form. Legacy UUID Encoding and Do Not Decode are added to the catalog as empty entries, the same shape as the 91 others awaiting translation. Verified that Connection Mode and Auth Method from the LibSQL and Trino plugins are present the same way, which is what confirmed the app-side mirror is what gets a key extracted.

Verification

  • 8623 tests in 1052 suites pass, running the full TableProTests target with CI's own quarantine skip list.
  • AllPlugins builds. This matters more than usual: see below.
  • PluginKit ABI diff is additive, zero removed symbols.

Worth knowing: PR CI does not compile registry-only plugins

While working on this I introduced a hard compile error in BsonDocumentFlattener.swift and the app build still reported success. macos-tests.yml builds -scheme TablePro, whose dependencies are the 14 bundled plugins; MongoDB and the other 15 registry plugins are only compiled by the AllPlugins aggregate, which nothing in PR CI runs. build-plugin.yml only fires on plugin-*-v* tags.

So a change confined to a registry plugin can pass CI while being broken. My error happened to be caught because BsonDocumentFlattener.swift is in the test target's source list, but the rest of the MongoDB plugin is not compiled by CI at all. Adding an AllPlugins build step to macos-tests.yml would close it. I have not done that here since it is a CI change beyond these follow-ups.

Not included

  • ObjectId still exports as a bare string, because unwrapExtendedJson maps $oid to a String and the type is gone by export time. Same class of bug as the binary subtype was, and it needs the same boxing treatment. Its own change.
  • Binary nested inside a subdocument exports as a quoted string, since the parent is serialized as JSON before the exporter sees it.

https://claude.ai/code/session_01628orR3jwc3ATfcFCLVUMB

@mintlify

mintlify Bot commented Aug 11, 2026

Copy link
Copy Markdown

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

Project Status Preview Updated (UTC)
TablePro 🟢 Ready View Preview Aug 11, 2026, 1:48 PM

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

@datlechin datlechin added the abi-additive PluginKit ABI diff reviewed as additive; no version bump needed label Aug 11, 2026
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@datlechin
datlechin merged commit 30445b1 into main Aug 11, 2026
4 checks passed
@datlechin
datlechin deleted the fix/2086-followups branch August 11, 2026 14:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

abi-additive PluginKit ABI diff reviewed as additive; no version bump needed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant