Hi Xinqi,

Thanks for the comprehensive technical design — it's well structured and
covers the key aspects thoroughly. I also appreciate Yuan's detailed
review, which raised important points on correctness and consistency.

A few additional thoughts:

1. The ordered-vs-unordered dual-mode approach is a pragmatic design. The
O(1) streaming path will make a real difference for the common case of
time-ordered table scans, while the buffered fallback ensures correctness
for arbitrary inputs.
2. The inputOrderedByTimeAscending property on AggregationNode — while
initially motivated by these four functions — could potentially benefit
other time-aware aggregations in the future. Worth calling that out in the
design doc so it's not treated as a one-off.
3. Given that counter resets, duplicate timestamps, NaN/Infinity, and
boundary conditions all have subtle interactions, I'd suggest including a
test-case matrix in the implementation plan covering at minimum: counter
wraps, gaps larger than the extrapolation threshold, single-sample windows,
and mixed NULL/non-NULL sequences for each function.

Looking forward to seeing this land — Prometheus-compatible rate/irate is a
valuable addition for observability use cases on IoTDB.

Best,
Xuan Wang

Xinqi Zhao <[email protected]> 于2026年7月9日周四 15:32写道:

> Subject: [DISCUSS] Add Prometheus-like rate/irate/increase/delta aggregate
> functions for table model
> Hi IoTDB community,
> I would like to start a discussion about adding four Prometheus-like
> functions to IoTDB table model SQL:
> rate()
> irate()
> increase()
> delta()
> Related issue:
> https://github.com/apache/iotdb/issues/17976
>
> Background
> In IoT and observability scenarios, metrics are often collected as
> counters or gauges. Systems such as Prometheus commonly provide rate(),
> irate(), increase(), and delta() to calculate rates, increments, and value
> changes over a time window.
> Currently, IoTDB table model SQL does not provide these functions
> directly. Users need to write complex SQL manually or export raw data to
> external systems for further calculation.
>
> Proposal
> I propose to add these four functions as built-in aggregate functions for
> the IoTDB table model.
> The proposed 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, window_start, window_end)
> delta(value_col, time_col, window_start, window_end)
> The reason for using four arguments is that the function needs to know
> both the sample timestamp and the exact aggregation window boundary. This
> is especially important for sliding windows, such as HOP windows, where one
> data point may belong to multiple overlapping windows.
>
> Parameter constraints
> value_col:
> Supported types: INT32, INT64, FLOAT, DOUBLE.
> time_col:
> TIMESTAMP expression or column, usually the table model time column.
> window_start and window_end:
> TIMESTAMP expressions representing the current aggregation window boundary.
> Other constraints:
> The number of arguments must be 4.
> window_start must be less than window_end.
> If there are fewer than two valid non-null samples in the current
> group/window, the function returns NULL.
> If the first and last valid samples used for calculation have the same
> timestamp, the function returns NULL.
>
> Function semantics
> rate():
> Uses all valid samples in the current aggregation window.
> Handles counter reset.
> Applies Prometheus-compatible boundary extrapolation.
> Returns the average per-second rate.
> increase():
> Uses all valid samples in the current aggregation window.
> Handles counter reset.
> Applies Prometheus-compatible boundary extrapolation.
> Returns the total increase in the window.
> It is semantically close to rate() multiplied by the window duration in
> seconds.
> irate():
> Uses only the last two valid samples in the current aggregation window.
> Handles counter reset between the last two samples.
> Does not apply boundary extrapolation.
> Returns the instant per-second rate.
> delta():
> Uses all valid samples in the current aggregation window.
> Does not handle counter reset.
> Applies Prometheus-compatible boundary extrapolation.
> Returns the extrapolated value change over the whole window.
> Negative results are allowed.
>
> SQL usage
> For fixed non-overlapping windows, users can use date_bin/date_bin_gapfill
> with GROUP BY:
> SELECT
>   device_id,
>   date_bin(5m, time) AS window_start,
>   rate(s1, time, window_start, window_start + 5m) AS s1_rate
> FROM table1
> WHERE time >= '1970-01-01T00:00:00'
>   AND time <  '1970-01-01T01:00:00'
> GROUP BY device_id, window_start;
> For window table functions, users can directly use window_start and
> window_end generated by TUMBLE/HOP:
> SELECT
>   device_id,
>   window_start,
>   window_end,
>   rate(s1, time, window_start, window_end) AS s1_rate
> FROM HOP(
>   DATA => (
>     SELECT time, device_id, s1
>     FROM table1
>     WHERE time >= '1970-01-01T00:00:00'
>       AND time <  '1970-01-01T01:00:00'
>   ),
>   TIMECOL => 'time',
>   SLIDE => 1m,
>   SIZE => 5m
> )
> GROUP BY device_id, window_start, window_end;
>
> Best regards,
> Xinqi Zhao

Reply via email to