Skip to content

Arithmetic expression support - #3

Merged
colemancda merged 4 commits into
masterfrom
feature/arithmetic-expression
Aug 16, 2026
Merged

Arithmetic expression support#3
colemancda merged 4 commits into
masterfrom
feature/arithmetic-expression

Conversation

@colemancda

Copy link
Copy Markdown
Member

Implements ArithmeticExpression (CoreModel 2.11.0), split between the server and the existing in-memory fallback by where the semantics can be honored.

Server-side: add, subtract, multiply

(a <op> b) <operator> constant compiles to a guarded aggregation $expr filter:

{ $expr: { $and: [
    { $isNumber: { $add: ["$age", 10] } },
    { $gt: [ { $add: ["$age", 10] }, 45 ] }
] } }

The $isNumber guard is load-bearing: $add of a missing or null field yields null, and aggregation comparisons rank null below every number — so without it, arithmetic < constant would spuriously match rows where the operand is absent. CoreModel's engine yields nil for such rows, which matches no comparison; the guard reproduces that. Key paths become $-prefixed field paths, so composite elements ($location.latitude) work unchanged.

In-memory: divide and modulus

Routed through the existing requiresInMemoryEvaluation fallback (the same path custom functions use), because the server cannot match CoreModel's semantics:

  • $divide aborts the whole query on division by zero, where CoreModel yields nil (comparison false)
  • $divide always produces floating point — no truncating integer division
  • $mod computes on floats, where CoreModel defines remainder for integers only

The fallback evaluation mirrors CoreModel's internal engine exactly (integer ops stay integer with truncating division, mixed/float as Double, nil on zero division, overflow, or float modulus). A division nested anywhere in an expression tree routes the request to memory.

Also fixed

testMongoDB registered its MongoClient cleanup defer after the first throwing await, so with no server listening the client deinitialized unclosed and MongoSwift's assertion killed the test process (SIGTRAP). The defer now comes first; the test fails cleanly with a connection error instead.

Testing

13 server-free tests: the $expr document shapes (flat, nested, composite-element operands), memory-routing for divide/modulus including nested, native routing for add/subtract/multiply, and the in-memory semantics (truncation, zero division across operators, float promotion, float modulus, non-numeric operands). The end-to-end $expr path against a live mongod remains unexercised, as with the composite work.

@colemancda
colemancda merged commit c67a319 into master Aug 16, 2026
2 checks passed
@colemancda
colemancda deleted the feature/arithmetic-expression branch August 16, 2026 21:05
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