Re: Bug: Rule actions see wrong values for generated columns (NEW.gen reads OLD value)

From: Dean Rasheed <dean(dot)a(dot)rasheed(at)gmail(dot)com>
To: Richard Guo <guofenglinux(at)gmail(dot)com>
Cc: Chao Li <li(dot)evan(dot)chao(at)gmail(dot)com>, SATYANARAYANA NARLAPURAM <satyanarlapuram(at)gmail(dot)com>, PostgreSQL Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org>, Peter Eisentraut <peter(at)eisentraut(dot)org>
Subject: Re: Bug: Rule actions see wrong values for generated columns (NEW.gen reads OLD value)
Date: 2026-04-13 11:03:53
Message-ID: CAEZATCWYqyJJJcMNEj-LEvCSwog2H_HS61hTROZLKYuaiy5YTg@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On Mon, 13 Apr 2026, 09:20 Richard Guo, <guofenglinux(at)gmail(dot)com> wrote:

> On Mon, Apr 13, 2026 at 4:21 PM Chao Li <li(dot)evan(dot)chao(at)gmail(dot)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

>

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Bertrand Drouvot 2026-04-13 11:04:09 Re: Reduce build times of pg_trgm GIN indexes
Previous Message vignesh C 2026-04-13 10:51:18 Re: Support EXCEPT for ALL SEQUENCES publications