Fix: non-primary snake_case ObjectId fields not converted (issue #12)#16
Open
Fix: non-primary snake_case ObjectId fields not converted (issue #12)#16
Conversation
Query by non-primary ObjectId fields like `transaction_id` returns no results because `convertObjectIds()` only handles `_id`, camelCase `Id`, and `Ids` suffixes, missing snake_case `_id` suffix fields. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Extend `convertObjectIds()` to also handle fields ending in `_id` (snake_case), so queries like `WHERE transaction_id = '<hex>'` correctly convert the string to a MongoDB ObjectId before comparison. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Instead of guessing which fields need ObjectId conversion based on field name patterns (Id, _id, etc.), sample one document from the collection and check which fields are actually ObjectId instances. Use that type map to convert string values in filters before querying. This correctly handles any arbitrarily-named ObjectId field (e.g. transaction_id, source_ref, parent) without relying on naming conventions. Closes #12 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ECTID
Users can now explicitly cast a string to ObjectId in any position,
regardless of field name or collection schema.
Supported syntax:
WHERE ref = CAST('507f...' AS OBJECTID)
WHERE ref = '507f...'::OBJECTID
Implementation:
- parser.ts: preprocess both cast forms into a '__QL_OBJECTID_hex__'
sentinel string before the SQL AST is built
- compiler.ts: convertValue() detects the sentinel and returns a
{ __qlObjectId: hex } marker object
- executor/index.ts: resolveSentinels() walks the compiled filter after
schema-based conversion and turns any remaining markers into
ObjectId instances; non-plain objects (ObjectId, Date, etc.) are
skipped to avoid destructuring already-typed BSON values
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…elds Previously _id was hardcoded as always-ObjectId regardless of what was actually stored. Now resolveFilterObjectIds() trusts the schema sample for _id too — only adding it to objectIdFields if the sampled document has an ObjectId there. The only assumption made is for empty collections, where _id defaults to ObjectId (MongoDB's standard default). Tests added: - external_id stored as integer → NOT converted to ObjectId - external_id stored as 24-char hex string → NOT converted to ObjectId - _id stored as integer → NOT converted to ObjectId - _id stored as 24-char hex plain string → NOT converted to ObjectId Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
convertObjectIds()inexecutor/index.tsonly handles_id, camelCaseIdandIdssuffixes — it misses snake_case_idsuffix fields liketransaction_idSELECT * FROM soldinventories WHERE transaction_id = '<hex>'returns 0 results instead of matching documentsRoot cause
In
packages/lib/src/executor/index.ts:234, the condition is:A field like
transaction_idfails all three checks, so the string value is never converted tonew ObjectId(...), and MongoDB's strict type comparison returns no results.Test plan
should handle ObjectId conversions on non-primary snake_case id fields (issue #12)added toedge-cases.integration.test.tsconvertObjectIds()to also handle fields ending in_id— test should then passCloses #12