FOR PORTION OF does not recompute GENERATED STORED columns that depend on the range column

First seen: 2026-04-07 08:42:42+00:00 · Messages: 30 · Participants: 6

Latest Update

2026-06-01 · claude-opus-4-6

Monthly Summary: FOR PORTION OF and GENERATED STORED Columns (May 2026)

Overview

This thread underwent a dramatic arc in May 2026: a 12-version patch series addressing stale GENERATED STORED columns on FOR PORTION OF updates was ultimately rendered unnecessary by a fundamental design reversal decided at PGConf.dev. The original bug, the iterative fixes, and the final resolution all illuminate a deep architectural tension in how PostgreSQL's updatedCols bitmapset serves multiple purposes.

The Original Bug

PostgreSQL 18's FOR PORTION OF feature narrows a range column when performing temporal UPDATE/DELETE, inserting "leftover" rows for portions outside the targeted sub-range. The bug: GENERATED ALWAYS AS ... STORED columns referencing the range column produce stale values on the updated row because the range column is deliberately omitted from updatedCols, and the executor only recomputes generated columns whose dependencies intersect that bitmapset.

The omission was intentional — it was a permissions design choice (users shouldn't need UPDATE privilege on the range column since the system, not the user, is narrowing it). But updatedCols also drives generated column recomputation, UPDATE OF trigger firing, and HOT/index optimizations, all of which need to know the range column changed.

Patch Evolution (v1–v12)

The series went through increasingly sophisticated approaches:

Key technical findings during this period:

The Design Reversal (PGConf.dev)

After v12 achieved review consensus, Paul reported that an in-person discussion with Peter Eisentraut at PGConf.dev led to a complete reversal: the range column should require UPDATE permission, and therefore should be in updatedCols from the start.

This eliminates the entire ExecGetUpdatedCols centralization approach. The fix becomes trivial: add the range attno in transformForPortionOfClause at parse time. All downstream consumers (permissions, generated columns, triggers, HOT) work automatically via existing mechanisms.

The SQL Standard's apparent intent (no UPDATE privilege needed on the range column) was overridden as pragmatically incorrect for PostgreSQL's architecture.

Remaining Items

History (1 prior analysis)
2026-06-01 · claude-opus-4-6

No substantive progress

Jian's single new message is a minor terminology nit on v13: the patch uses "generated stored column(s)" where PostgreSQL convention is "stored generated column(s)". This is a pure wording consistency issue with no technical substance. No new patch version, no design discussion, no position shift.