|
| 1 | +--- |
| 2 | +'@objectstack/driver-mongodb': patch |
| 3 | +--- |
| 4 | + |
| 5 | +`driver-mongodb` refuses an aggregate function it does not lower, instead of |
| 6 | +answering it as a silent SUM (#12818). |
| 7 | + |
| 8 | +`buildAccumulator`'s `switch` on `agg.function` ended with |
| 9 | +`default: return { $sum: fieldRef ?? 0 }`, so ANY name this driver does not |
| 10 | +lower — a typo (`median`), a miscased spelling (`COUNT_DISTINCT`), a function |
| 11 | +added to the contract but not to this file, or an unnarrowed `method` arriving |
| 12 | +from `StrategyContext.executeAggregate` (#12776) — was answered as a **sum of |
| 13 | +that column**, under the alias the caller asked for, with no error, no envelope |
| 14 | +and no log. It is the worst available answer precisely because it is |
| 15 | +arithmetically plausible: a dashboard tile renders the number without complaint, |
| 16 | +so nothing downstream can tell "your function ran" from "your function was |
| 17 | +silently replaced". The field-less spelling was quieter still — `{ $sum: 0 }`, |
| 18 | +i.e. `0`, which reads as "no matching rows". |
| 19 | + |
| 20 | +The refusal is the two-class ADR-0112 envelope both SQL faces already answer |
| 21 | +with (#5907), first sentence for first sentence, so one condition cannot have |
| 22 | +two wire identities depending on which backend served it: |
| 23 | + |
| 24 | +- a name the Query Protocol does not declare answers `INVALID_QUERY` / **400** |
| 25 | + and names the declared vocabulary (`@objectstack/spec AggregationFunction`); |
| 26 | +- a DECLARED name this backend does not lower answers `NOT_IMPLEMENTED` / **501** |
| 27 | + and names what it does lower. That class is empty today — every member of |
| 28 | + `AggregationFunction` lowers here — and is pinned as a positive assertion, so |
| 29 | + the day the spec grows a function this driver misses, the suite goes red |
| 30 | + rather than quietly stopping to cover anything. |
| 31 | + |
| 32 | +Judged case-sensitively, which is what the enum is: `COUNT_DISTINCT` is not |
| 33 | +`count_distinct`, and telling its author the backend has a capability gap would |
| 34 | +be false. |
| 35 | + |
| 36 | +**Graded `patch`, deliberately.** No correct query's answer moves: all six |
| 37 | +declared functions and the two retired ones this face still lowers |
| 38 | +(`array_agg` / `string_agg`, an existing divergence from the SQL faces, recorded |
| 39 | +and filed as #13075 rather than closed here) are byte-identically unchanged, |
| 40 | +pinned by controls that compute their values in the same suite. The only inputs |
| 41 | +whose behaviour changes are ones this driver was already answering *wrongly*, so |
| 42 | +there is no working capability being removed — the same shape, in this same |
| 43 | +package, that #10576's per-aggregation-`filter` refusal shipped as a patch. |
| 44 | + |
| 45 | +Nothing to migrate. A caller that was reaching the old `default` arm was reading |
| 46 | +a SUM in place of the function it asked for; the refusal now names the function |
| 47 | +and the remedy. |
0 commit comments