Re: [BUG] ON CONFLICT DO UPDATE SET x = EXCLUDED.<virtual-generated-column> errors or silently writes NULL
SATYANARAYANA NARLAPURAM <satyanarlapuram@gmail.com>
From: SATYANARAYANA NARLAPURAM <satyanarlapuram@gmail.com>
To: Dean Rasheed <dean.a.rasheed@gmail.com>
Cc: PostgreSQL Hackers <pgsql-hackers@lists.postgresql.org>
Date: 2026-04-20T00:55:26Z
Lists: pgsql-hackers
HI, On Sat, Apr 18, 2026 at 11:14 AM Dean Rasheed <dean.a.rasheed@gmail.com> wrote: > On Thu, 16 Apr 2026 at 21:49, SATYANARAYANA NARLAPURAM > <satyanarlapuram@gmail.com> wrote: > > > > Virtual generated column (bgc) behavior for plain and partitioned tables > is different > > when EXCLUDED.<vgc> references inside for INSERT ... ON CONFLICT DO > UPDATE. > > For plain table it errors out with the message "unexpected virtual > generated column reference" > > and for partitioned tables, it silently writes NULL (wrong data). > > Nice catch! > > > I tried fixing this by replacing build_tlist_index with > build_tlist_index_other_vars . This fix > > works because build_tlist_index_other_vars only indexes plain-Var TEs of > exclRelTlist and > > leaves has_non_vars = false, so fix_join_expr skips whole-subtree > matching and never collapses > > the VGC-expanded (EXCLUDED.a * 10) in onConflictSet back into a > Var(INNER_VAR, vgc_attno). > > This doesn't quite work in all cases -- if the generated expression is > simply a Var, then it is found in the indexed tlist without the > non_var matching code, leading to the same problem. For example, > modifying your original test case to this: > > CREATE TABLE t (id int PRIMARY KEY, > c int GENERATED ALWAYS AS (a) VIRTUAL, a int); > > Admittedly, that's a rather silly example, but we really ought to have > a fix that works for all cases. > Agreed. > > Looking more closely, I think the right fix is to not expand virtual > generated columns in the targetlist of EXCLUDED (exclRelTlist), so > then they will not be found as matching expressions in the setrefs.c > code. > > I also noticed that there are already a couple of places in the > planner that claim that exclRelTlist contains only Vars, so this > approach makes that claim true (though I don't think those other > places represented actual bugs). > > Attached is a v2 patch doing it that way, with the same tests, which all > pass. > Reran the failing tests and they all passed. Additionally ran the regression tests. Patch looks good to me. > > Regards, > Dean >
Commits
Same data as JSON:
GET /api/v1/messages/:b64id/commits
the thread's linked commits as JSON, with link sources.
API reference →
-
Fix expansion of EXCLUDED virtual generated columns.
- cf38dedf693a 18.4 landed
- 783425175809 19 (unreleased) landed