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

Reply via email to