# v0.89.0 — Incremental Window Functions > **Status:** Planned > **Scope:** Large > **User promise:** *"One PostgreSQL instance can handle a lot."* > **Blocked by:** [v0.88.0](v0.88.0.md) > **Split from:** the original v0.84.0 "Fast Incremental Engine". ## Theme Replace partition-based recomputation for window functions with genuinely incremental algorithms. This is a release on its own, not a bullet point. Every entry in the table below is a distinct algorithm with its own auxiliary state, its own persistence and crash-recovery story, its own migration path for existing stream tables, and its own DIFFERENTIAL-versus-FULL proof obligation. Bundling it with the vectorized aggregate path and a delta-query cost model — as the original v0.84.0 did — produced a release that could not be scoped, reviewed or gated. ## Non-Goals - No new window functions beyond those PostgreSQL already supports. - No change to the window semantics users see; only to how they are maintained. - No removal of the partition-recomputation path — it remains the fallback. ## Items ### LT-7a: Incremental state model and persistence Before any individual algorithm, define once: - where per-partition auxiliary state lives (a side table keyed by stream table and partition key, not user-visible columns) - how it is initialised on first refresh and rebuilt on reinitialisation - how it survives crash, restore and `ALTER`, and how a mismatch is detected - how it is bounded, so a query with millions of partitions cannot grow state without a ceiling and an alert (bound sourced from `pg_trickle.memory_budget_mb`, v0.87.0) New metadata in `pgt_stream_tables`: `window_strategy JSONB` recording, per window function, the chosen strategy and its auxiliary state location. ### LT-7b: Rank-family algorithms | Function | Current Strategy | New Strategy | |----------|-----------------|--------------| | `ROW_NUMBER()` | Recompute partition | Maintain sorted index; insert/delete at position | | `RANK()` / `DENSE_RANK()` | Recompute partition | Track rank counts per distinct value; adjust on delta | Both must handle the case where one inserted row shifts every subsequent row's output — the delta is not proportional to the input change, and the release must document where the crossover to partition recomputation lies rather than pretending it does not exist. ### LT-7c: Offset and boundary algorithms | Function | Current Strategy | New Strategy | |----------|-----------------|--------------| | `LAG(col, N)` / `LEAD(col, N)` | Recompute partition | Ring buffer of N preceding/following values per partition | | `FIRST_VALUE()` / `LAST_VALUE()` | Recompute partition | Track min/max by sort key | | `NTH_VALUE()` | Recompute partition | Indexed array per partition | ### LT-7d: Aggregate-over-window algorithms | Function | Current Strategy | New Strategy | |----------|-----------------|--------------| | `SUM() OVER (...)` | Recompute partition | Running sum with prefix-sum tree for range frames | | `COUNT() OVER (...)` | Recompute partition | Running count (algebraic) | Non-invertible aggregates over windows (`MIN`/`MAX` with deletions) stay on the recomputation path unless a proof is available, consistent with the fail-closed rule established in [v0.83.0](v0.83.0.md). ### LT-7e: Fallback, reason codes and the support matrix Frames that are not covered — `ROWS BETWEEN` / `RANGE BETWEEN` variants outside the algorithms above, `EXCLUDE` clauses, `GROUPS` mode — fall back to partition recomputation with a reason code visible in refresh history and `explain()`, and are listed explicitly in `docs/DVM_SUPPORT_MATRIX.md`. A window function whose incremental algorithm is unavailable must never silently produce a different answer from PostgreSQL. ## Exit criteria - [ ] Auxiliary state model shipped, bounded, crash-tested and covered by the backup/restore suite - [ ] Every function in LT-7b/c/d has an incremental algorithm, or an explicit documented reason it stays on recomputation - [ ] Property tests compare DIFFERENTIAL with FULL after every INSERT, UPDATE and DELETE for each supported window shape - [ ] Measured speed-up published per function family, including the crossover point where recomputation is still faster - [ ] Unsupported frames fall back with a reason code and appear in `docs/DVM_SUPPORT_MATRIX.md` - [ ] Existing window stream tables upgrade without user action, or are flagged for reinitialisation with an actionable message