Hi all, Following the previous requirements and technical design discussions, I have submitted a PR implementing the rate(), increase(), irate(), and delta() aggregate functions for the table model.
PR: https://github.com/apache/iotdb/pull/18334 Related issue: https://github.com/apache/iotdb/issues/17976 The supported signatures are: rate(value_col, time_col, window_start, window_end) increase(value_col, time_col, window_start, window_end) irate(value_col, time_col) delta(value_col, time_col, window_start, window_end) All four functions return DOUBLE. value_col supports INT32, INT64, FLOAT, and DOUBLE, while the time arguments support TIMESTAMP and INT64. The main function semantics are: rate() calculates the average per-second growth rate, including counter-reset correction and boundary extrapolation. increase() returns the total corrected and extrapolated increase. irate() calculates the per-second rate from the last two valid samples and handles a reset between those samples without boundary extrapolation. delta() calculates the extrapolated change between the first and last samples without counter-reset correction. Negative values and results are allowed. The implementation reuses the existing table-model aggregation framework and supports both TableAccumulator and GroupedAccumulator paths. Two execution strategies are provided: Ordered implementations process samples in one pass with O(n) time and O(1) additional state per group. Naive implementations buffer and sort samples, requiring O(n log n) time and O(n) space per group. The Ordered implementation is selected only for SINGLE aggregation when the physical planner can prove that samples are ordered by time_col within each SQL group. Otherwise, including all PARTIAL, INTERMEDIATE, and FINAL stages, the Naive implementation is used. For distributed aggregation, the intermediate BLOB preserves the complete valid sample set and the window boundaries where applicable. Samples from multiple states are merged first, then sorted and validated before the final counter-reset and extrapolation calculations. The buffered state is integrated with the existing query memory-management mechanism, including incremental accounting for grouped accumulators. The PR also adds: Prometheus-style boundary extrapolation with the 1.1 average-interval threshold. Counter zero-point protection for rate() and increase(). Timestamp-precision-aware conversion to per-second results. Validation for argument counts and types, NULL time or window arguments, invalid window boundaries, out-of-window samples, inconsistent group boundaries, duplicate timestamps, NaN, Infinity, and negative counter values. English and Chinese localized error messages. Support for date_bin(), date_bin_gapfill(), TUMBLE(), and HOP() usage. Integration tests covering normal input, counter resets, unordered and distributed input, boundary extrapolation, zero-point protection, empty windows, all supported value types, extreme integer values, and exceptional cases. The current version does not push these functions into aggregation table-scan nodes because time_col may not be the physical TIME column and the calculations require the original samples. I would especially appreciate feedback on: The function semantics and edge-case handling. The planner’s ordered-input proof and Ordered/Naive selection. The distributed intermediate-state format. The grouped memory-accounting approach. Please take a look when convenient. Any comments or suggestions are welcome. Best regards, Xinqi Zhao
