From 94fe52cc67445c0d771dedf9926c3b604493430f Mon Sep 17 00:00:00 2001 From: Mohammad Dashti Date: Mon, 27 Apr 2026 15:04:37 -0700 Subject: [PATCH] docs: clarify SUM finalize returning None diverges from Elasticsearch Surface the trade-off in the doc comment so future reviewers see why this differs from ES (which returns "value": 0 for sum over empty/all-missing buckets) and what consumers (ParadeDB SQL NULL) the None variant is meant to serve. --- src/aggregation/metric/sum.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/aggregation/metric/sum.rs b/src/aggregation/metric/sum.rs index 8e1dc0f5d..1b64aa00d 100644 --- a/src/aggregation/metric/sum.rs +++ b/src/aggregation/metric/sum.rs @@ -64,6 +64,14 @@ impl IntermediateSum { /// Returns `None` when no values were collected (all documents had /// missing/NULL values for the field), matching the behavior of /// `IntermediateMin`, `IntermediateMax`, and `IntermediateAvg`. + /// + /// Note: this diverges from Elasticsearch, which returns `"value": 0` + /// for sum aggregations over empty / all-missing buckets (min/max/avg + /// return `null`). Returning `None` here lets SQL-style consumers + /// (e.g. ParadeDB, where `SUM` of no rows is `NULL`) distinguish + /// "nothing was summed" from "values summed to 0" via the existing + /// `SingleMetricResult { value: Option }` boundary, which on + /// `main` is an `Option` that is never `None` for sum. pub fn finalize(&self) -> Option { let stats = self.stats.finalize(); if stats.count == 0 {