Pattern 05 — Add a SUM Aggregate Column
Class: In-place
Cost: Seconds to minutes (proportional to row count)
Test: test_cookbook_05_add_sum_aggregate_column
When to use
Add a new SUM aggregate to an existing DIFFERENTIAL stream table without rebuilding it. The new column is backfilled incrementally; the existing materialised data is preserved.
Migration file
-- migrations/streams/c05_totals.sql (after)
-- @aqueduct:schedule = "30s"
-- @aqueduct:refresh_mode = "DIFFERENTIAL"
SELECT id,
SUM(amount) AS total,
SUM(discount) AS discount_total -- ← new column
FROM raw_orders
GROUP BY id;
Plan output
Project analytics v11 → v12
Target prod
Changes 1 node affected
~ c05_totals [in-place] add column discount_total (SUM)
Cost estimate:
Step Rows (est) Duration (est) Class
──────────────────────────────────────────────────────────────────
ALTER stream c05_totals — < 1s in-place
BACKFILL c05_totals 1.4M ~52s in-place
Why it's In-place
Adding a new SUM aggregate column does not change the GROUP BY keys, the FROM clause,
or the WHERE predicate. The existing rows remain valid — only the new column is
NULL until backfilled. pg_trickle fills the new column incrementally without
re-materialising the entire table.
Notes
- The same pattern applies to
COUNT,MIN,MAX, andAVGcolumns. See Pattern 06 for COUNT. - For tables with
allow_full_refresh = falseinaqueduct.toml, an In-place column addition is always safe.