Skip to content

feat!: add ITSELF self-reference marker for element-level $elemMatch and $all - #770

Merged
tada5hi merged 3 commits into
masterfrom
feat/itself-marker
Jul 17, 2026
Merged

feat!: add ITSELF self-reference marker for element-level $elemMatch and $all#770
tada5hi merged 3 commits into
masterfrom
feat/itself-marker

Conversation

@tada5hi

@tada5hi tada5hi commented Jul 17, 2026

Copy link
Copy Markdown
Owner

Closes #768.

The reserved marker ITSELF (wire spelling $this) addresses the array element itself in the field position of a leaf condition inside an elemMatch interior — the core IR gap behind the two remaining mongo constructs @rapiq/parser-mongo had to reject. Design decisions (marker spelling, binding scope) are recorded in .agents/plans/016-itself-marker.md.

Changes

  • core: exports ITSELF = '$this'; defineFilters validates the marker contract on condition-node input, accepts mongo-style element-level $elemMatch operator objects ({ $elemMatch: { $gt: 5 } }), and now rejects $-prefixed keys as field names (matching the mongo-dialect reservation).
  • parser-mongo: lifts the plan-013 Q8 throw — element-level $elemMatch parses onto ITSELF (ucast hasOperators split, including $not and nested $elemMatch interiors); $all moves out of the unsupported set and desugars to an AND of independently scoped elemMatch(f, eq(ITSELF, v)) conditions with $in-style value validation; negated $all/$elemMatch throw OPERATOR_UNSUPPORTED.
  • memory: every elemMatch node opens its own quantifier scope (discriminated binding paths) — interiors share one element, sibling elemMatches bind independently (exact Mongo semantics, required for the $all desugar). ITSELF leaves evaluate the bound element and only match real array elements: missing fields, scalars, to-one objects and empty arrays never match (deliberately no mongo scalar fallback for $all).
  • sql / typeorm: FiltersBaseAdapter.buildField throws typed AdapterError.featureUnsupported('filters:itself') — a joined relation row is not a scalar column; dialect JSON-array support (json_each/unnest) stays a follow-up.
  • parser-expression / codec-url: new elemMatch(field, expr) grammar production (interior fields resolve against the related schema via descend, unbound fallback for non-relation fields) and a dedicated $this token; not(elemMatch(...)) throws. The expression encoder serializes ELEM_MATCH with full round-trip coverage — wire form filter=elemMatch(scores,gt($this,'5')); the simple codec keeps throwing typed under the subset law.
  • docs: parser-mongo (unsupported list updated, $all row), memory (quantifier semantics + ITSELF section, divergence table), sql (ITSELF limitation), parser-expression (grammar), codec-url and the filters / building-queries / wire guides.

Breaking changes

  • Two elemMatch nodes on one field (or an elemMatch beside a dotted sibling) no longer share an element binding in @rapiq/memory — the two plan-014 parity-fallout pinning specs were flipped. SQL keeps single-join-alias composition, so multi-elemMatch trees diverge between sql and memory (documented).
  • $-prefixed keys are rejected as field names in the build-layer filters object grammar.
  • In the expression filter dialect, elemMatch is a reserved keyword and $-words are reserved markers — fields with these names no longer tokenize/encode.

Verification

All 8 packages build; full test run passes (~60 new specs across core, parser-mongo, parser-expression, memory, sql, typeorm, codec-url); lint clean. End-to-end smoke: a mongo document with $all + element-level $elemMatch parses, evaluates with mongo semantics via compileFilters, and round-trips the URL codec.

Summary by CodeRabbit

  • New Features

    • Added elemMatch support to expression and Mongo-style query formats.
    • Added $all support for independently matching array elements.
    • Added $this element references for conditions inside elemMatch.
    • Added in-memory evaluation for nested and element-level array matching.
  • Bug Fixes

    • Corrected matching so separate elemMatch conditions evaluate independently.
  • Documentation

    • Expanded guidance on array matching, $this, dialect support, and adapter limitations.

…and $all

The reserved marker ITSELF ('$this') addresses the array element itself
inside an elemMatch interior, closing the core IR gap behind two mongo
constructs:

- parser-mongo parses element-level $elemMatch ({ $elemMatch: { $gt: 5 } })
  onto ITSELF and desugars $all to an AND of independently scoped
  elemMatch(f, eq(ITSELF, v)) conditions; negated forms throw typed.
- memory evaluates ITSELF leaves against the bound element; only real
  array elements match (missing/scalar/to-one/empty array never do).
- the expression dialect gains an elemMatch(field, expr) production with
  a dedicated $this token, and the URL codec encodes/decodes it.
- sql/typeorm throw a typed featureUnsupported for ITSELF leaves (a
  joined relation row is not a scalar column).
- the build layer exports ITSELF, accepts element-level $elemMatch
  operator objects and rejects marker misuse with typed BuildErrors.

BREAKING CHANGE: every elemMatch node now opens its own quantifier
scope in @rapiq/memory - two elemMatches on one field (or an elemMatch
beside a dotted sibling) bind independent elements (mongo semantics)
instead of sharing one binding. $-prefixed keys are no longer accepted
as field names in the build-layer filters object grammar. In the
expression filter dialect, elemMatch is now a reserved keyword and
$-prefixed words are reserved markers, so fields with these names no
longer tokenize.

closes #768
Copilot AI review requested due to automatic review settings July 17, 2026 08:41

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@coderabbitai

coderabbitai Bot commented Jul 17, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The change introduces the exported ITSELF/$this marker, supports element-level $elemMatch and $all, adds expression-dialect round trips, implements independent in-memory element quantification, and makes SQL adapters reject unsupported ITSELF leaves with typed errors.

Changes

ITSELF filter construction

Layer / File(s) Summary
Core marker and filter construction
packages/core/src/parameter/filters/*, packages/core/src/build/parameter/filters/module.ts, packages/core/test/unit/build/*, packages/docs/guide/building-queries.md
Exports ITSELF, restricts it to elemMatch interiors, and builds element-level operator conditions against the marker.

Parser support

Layer / File(s) Summary
Expression elemMatch parsing
packages/parser-expression/src/parameter/filters/*, packages/parser-expression/test/unit/parser/filters.spec.ts, packages/docs/packages/parser-expression.md
Parses elemMatch(...), $this, nested interiors, and schema-aware field scopes with validation for invalid marker usage.
Mongo elemMatch and all desugaring
packages/parser-mongo/src/parameter/filters/*, packages/parser-mongo/test/unit/parser/filters.spec.ts, packages/docs/packages/parser-mongo.md, .agents/references/ucast.md
Accepts element-level $elemMatch and $all, translating them into ITSELF-based, independently scoped conditions.

Encoding and evaluation

Layer / File(s) Summary
Expression codec round trips
packages/codec-url/src/expression/encoder/filters.ts, packages/codec-url/test/unit/*, packages/docs/packages/codec-url.md, packages/docs/guide/{filters.md,wire.md}
Serializes $this only inside elemMatch, supports expression-dialect round trips, and preserves simple-dialect failures.
Memory binding and element evaluation
packages/memory/src/parameter/filters/*, packages/memory/test/unit/filters/*, packages/docs/packages/memory.md, .agents/references/ucast.md
Evaluates ITSELF against real array elements, creates fresh scopes per elemMatch, and covers nested, missing, scalar, null, and multi-value cases.

Adapter boundary

Layer / File(s) Summary
SQL adapter rejection behavior
packages/sql/src/adapter/filters/base.ts, packages/sql/test/unit/interpreters/elem-match.spec.ts, packages/typeorm/test/unit/filters.spec.ts, packages/docs/packages/sql.md
Rejects ITSELF field rendering in SQL and TypeORM with FEATURE_UNSUPPORTED adapter errors.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Query
  participant MongoFiltersParser
  participant CoreFilters
  participant MemoryCompiler
  participant MemoryBinding
  Query->>MongoFiltersParser: Parse $elemMatch or $all
  MongoFiltersParser->>CoreFilters: Build ITSELF-scoped conditions
  CoreFilters->>MemoryCompiler: Compile elemMatch filter
  MemoryCompiler->>MemoryBinding: Create independent element scope
  MemoryBinding-->>MemoryCompiler: Bind array element
  MemoryCompiler-->>Query: Evaluate element predicate
Loading

Possibly related PRs

  • tada5hi/rapiq#700 — Adds typing and type-guard infrastructure used by the codec encoder.
  • tada5hi/rapiq#751 — Introduces the Mongo dialect extended here with $elemMatch, $all, and ITSELF desugaring.
  • tada5hi/rapiq#753 — Introduces the memory binding and compiler paths extended with ITSELF semantics.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title concisely names the new ITSELF marker and its impact on element-level $elemMatch and $all.
Linked Issues check ✅ Passed The changes implement ITSELF, element-level $elemMatch, $all desugaring, memory semantics, codec support, SQL errors, and docs as requested.
Out of Scope Changes check ✅ Passed The PR changes are focused on the ITSELF/$elemMatch/$all feature set and related tests/docs, with no clear unrelated additions.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/itself-marker

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@tada5hi

tada5hi commented Jul 17, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jul 17, 2026

Copy link
Copy Markdown
✅ Action performed

Full review finished.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/core/src/parameter/filters/constants.ts`:
- Around line 11-21: Update the ITSELF documentation in the constants module to
explicitly allow nested elemMatch(ITSELF, ...) expressions as a supported form.
Broaden the restriction currently limiting ITSELF to leaf conditions, while
preserving the existing rejection behavior for other invalid contexts and
unsupported backend adapters.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5af10c23-8ade-472f-beb0-6e1b566347e5

📥 Commits

Reviewing files that changed from the base of the PR and between 97e11d4 and 1a29eb5.

📒 Files selected for processing (30)
  • .agents/references/ucast.md
  • packages/codec-url/src/expression/encoder/filters.ts
  • packages/codec-url/test/unit/expression-roundtrip.spec.ts
  • packages/codec-url/test/unit/simple-roundtrip.spec.ts
  • packages/core/src/build/parameter/filters/module.ts
  • packages/core/src/parameter/filters/constants.ts
  • packages/core/src/parameter/filters/index.ts
  • packages/core/test/unit/build/module.spec.ts
  • packages/docs/guide/building-queries.md
  • packages/docs/guide/filters.md
  • packages/docs/guide/wire.md
  • packages/docs/packages/codec-url.md
  • packages/docs/packages/memory.md
  • packages/docs/packages/parser-expression.md
  • packages/docs/packages/parser-mongo.md
  • packages/docs/packages/sql.md
  • packages/memory/src/parameter/filters/binding.ts
  • packages/memory/src/parameter/filters/compiler.ts
  • packages/memory/src/parameter/filters/constants.ts
  • packages/memory/test/unit/filters/binding.spec.ts
  • packages/parser-expression/src/parameter/filters/constants.ts
  • packages/parser-expression/src/parameter/filters/module.ts
  • packages/parser-expression/test/unit/parser/filters.spec.ts
  • packages/parser-mongo/src/parameter/filters/constants.ts
  • packages/parser-mongo/src/parameter/filters/module.ts
  • packages/parser-mongo/src/parameter/filters/types.ts
  • packages/parser-mongo/test/unit/parser/filters.spec.ts
  • packages/sql/src/adapter/filters/base.ts
  • packages/sql/test/unit/interpreters/elem-match.spec.ts
  • packages/typeorm/test/unit/filters.spec.ts

Comment thread packages/core/src/parameter/filters/constants.ts Outdated
@tada5hi

tada5hi commented Jul 17, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai pause

@coderabbitai

coderabbitai Bot commented Jul 17, 2026

Copy link
Copy Markdown
✅ Action performed

Reviews paused.

@tada5hi
tada5hi merged commit e1d5c4c into master Jul 17, 2026
7 checks passed
This was referenced Jul 16, 2026
@tada5hi
tada5hi deleted the feat/itself-marker branch July 27, 2026 07:53
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.

Feature: ITSELF self-reference marker (element-level $elemMatch + $all)

2 participants