Re: Bug: Rule actions see wrong values for generated columns (NEW.gen reads OLD value) - Mailing list pgsql-hackers

From Dean Rasheed
Subject Re: Bug: Rule actions see wrong values for generated columns (NEW.gen reads OLD value)
Date
Msg-id CAEZATCWYqyJJJcMNEj-LEvCSwog2H_HS61hTROZLKYuaiy5YTg@mail.gmail.com
Whole thread
In response to Bug: Rule actions see wrong values for generated columns (NEW.gen reads OLD value)  (SATYANARAYANA NARLAPURAM <satyanarlapuram@gmail.com>)
Responses Re: Bug: Rule actions see wrong values for generated columns (NEW.gen reads OLD value)
Re: Bug: Rule actions see wrong values for generated columns (NEW.gen reads OLD value)
List pgsql-hackers
On Mon, 13 Apr 2026, 09:20 Richard Guo, <guofenglinux@gmail.com> wrote:
On Mon, Apr 13, 2026 at 4:21 PM Chao Li <li.evan.chao@gmail.com> wrote:
> I think the issue is that rewriteTargetListIU() removes generated columns from the target list, as described by this comment:

> Later, when the rule action is rewritten, ReplaceVarsFromTargetList() cannot find a target list entry for NEW.gen. For UPDATE rules, the missing NEW column is handled with REPLACEVARS_CHANGE_VARNO, so it falls back to referencing the original target relation row, which gives the old value.

I came to the same conclusion.

> One possible fix is to build a new target list that adds generated columns back when there are rules to fire. I tried the solution locally with some quick and dirty code and it seems to fix both stored and virtual generated columns for me.

I think a simpler fix might be to expand generated column references
in the NEW relation to their generation expressions before
ReplaceVarsFromTargetList resolves NEW references, so that the base
column Vars within the expressions can be correctly resolved.
Something like attached.

- Richard

One thing about that approach is that it leads to 2 full rewrites of the rule action using ReplaceVarsFromTargetList(). I think that could be avoided by using including generated column expressions in the targetlist passed to ReplaceVarsFromTargetList() by rewriteRuleAction(). I haven't tried it, but I imagine it could reuse some code from expand_generated_columns_internal().

Regards,
Dean

pgsql-hackers by date:

Previous
From: vignesh C
Date:
Subject: Re: Support EXCEPT for ALL SEQUENCES publications
Next
From: Bertrand Drouvot
Date:
Subject: Re: Reduce build times of pg_trgm GIN indexes