Re: [BUG] ON CONFLICT DO UPDATE SET x = EXCLUDED.<virtual-generated-column> errors or silently writes NULL

From: Ayush Tiwari <ayushtiwari(dot)slg01(at)gmail(dot)com>
To: Dean Rasheed <dean(dot)a(dot)rasheed(at)gmail(dot)com>
Cc: Alexander Lakhin <exclusion(at)gmail(dot)com>, SATYANARAYANA NARLAPURAM <satyanarlapuram(at)gmail(dot)com>, PostgreSQL Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org>
Subject: Re: [BUG] ON CONFLICT DO UPDATE SET x = EXCLUDED.<virtual-generated-column> errors or silently writes NULL
Date: 2026-09-12 18:10:23
Message-ID: CAJTYsWW2uGkcL=E7GuOWTtzFSxh3wEm+xGz63XquhOJ0kywr5g@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hi,

On Sat, 12 Sept 2026 at 23:10, Dean Rasheed <dean(dot)a(dot)rasheed(at)gmail(dot)com> wrote:
>
> On Fri, 11 Sept 2026 at 08:45, Ayush Tiwari <ayushtiwari(dot)slg01(at)gmail(dot)com> wrote:
> >
> > On Fri, 11 Sept 2026 at 09:30, Alexander Lakhin <exclusion(at)gmail(dot)com> wrote:
> > >
> > > Please look at a case broken by 783425175:
> > > CREATE TABLE t (id int PRIMARY KEY, c int GENERATED ALWAYS AS (tableoid));
> > > INSERT INTO t VALUES (1) ON CONFLICT (id) DO UPDATE SET id = 1 WHERE excluded.c > 0;
> > >
> > > ERROR: XX000: variable not found in subplan target lists
> > > LOCATION: fix_join_expr_mutator, setrefs.c:3229
> >
> > ISTM virtual generated column is expanded to the tableoid reference, but the
> > EXCLUDED target list has no tableoid entry for setrefs.c to resolve.
> >
> > Attached patch adds that entry and the statement you sent works fine with it.
> >
>
> Hmm, I'm not sure that this is the right approach. For example,
> consider this case, without a generated column:
>
> CREATE TABLE t (id int PRIMARY KEY, val int);
> INSERT INTO t VALUES (1,2)
> ON CONFLICT (id) DO UPDATE SET val = 0 WHERE excluded.tableoid > 0;
>
> ERROR: column excluded.tableoid does not exist
>
> That error is on point -- "excluded" is not a real table, it is a
> pseudo-table constructed from the values proposed for insertion, not
> the existing values. As such, it has no system columns.
>
> So, ISTM that when "c" is a virtual generated column, and "excluded.c"
> is expanded to "excluded.tableoid", it *should* produce an error.
>
> So rather than trying to fix this, I think it would be better to have
> it produce a more meaningful error message.

Thanks for looking at this.

My thinking was that excluded.c could use the table that the row would
have been inserted into when evaluating its generation expression.

Would that be a reasonable meaning for tableoid here, or should it be
considered unavailable because EXCLUDED represents only a proposed row?
That was the distinction I had in mind, but I may be missing something.

Regards,
Ayush

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Alexander Korotkov 2026-09-12 19:18:58 Re: timeout value overflow in wait for lsn
Previous Message Andrey Borodin 2026-09-12 18:01:21 Re: SSI: ON CONFLICT DO SELECT takes no predicate lock on the returned row