Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1wEcvQ-004DkI-1C for pgsql-hackers@arkaria.postgresql.org; Mon, 20 Apr 2026 00:55:44 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1wEcvP-00H6TZ-2C for pgsql-hackers@arkaria.postgresql.org; Mon, 20 Apr 2026 00:55:43 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1wEcvP-00H6TR-0v for pgsql-hackers@lists.postgresql.org; Mon, 20 Apr 2026 00:55:43 +0000 Received: from mail-vs1-xe32.google.com ([2607:f8b0:4864:20::e32]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1wEcvN-000000023G2-0uYJ for pgsql-hackers@lists.postgresql.org; Mon, 20 Apr 2026 00:55:43 +0000 Received: by mail-vs1-xe32.google.com with SMTP id ada2fe7eead31-612d8a59cc0so761757137.3 for ; Sun, 19 Apr 2026 17:55:40 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1776646539; cv=none; d=google.com; s=arc-20240605; b=jdD3TEteP58mZw3vyA15IkqFpCtjTqH5qGxmgpge2ejGMfpncjhXE0n/A1zzVEbzEu 3tR3D0mTxO4d55Oyuz68pn/7RVRadUq5cA3yCbhHJFsrwfiEWNB16no8+R3n8atmiQVr I7mCor12R+k1uQz2te27zkS2zhO6/21m1hmvSX1qeC/Fu3seUrkxfEMgDZDc/ka21STz XdPL3RIEbzsxGR8g2LyGKZPYvmYoK26onnlKwERbfNwZVKvC8ROt+Fs5jpUfvRt2J/F5 CoeEWSRRdUrByN4zhQ5jsJhwWlL2l/g9e0t0+Z1vdeB/jQMQX0VIp914t/CHQalyNlB6 RR6Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:dkim-signature; bh=Os7nzvmarI4J6Bjprlx1IC+NJm/BhqQf2p+PhvLAiFQ=; fh=3tYH/hSrrcFXDNFZxQ87rOAxyC9W9gdzqfcTcCbnQxk=; b=TeY3t7p9RH17Naa7ik1i2izTk2nvlwS28pMpxXWOiPRCGuD9xg86I3gIG1ezD6XJuh Q85VfJgKnfHmkNR6AyCJZV1IJApSdfxBXuF+HzvzPNbeeo0YWb3G5Np598Fqu+o7IE4c pE8By4ayR2S/MUF7fbabcjvkD2Lp4T/H/GPLbmNl0l9pxt/x6CNFywmwa2Oh9K9YjYrF y2rhrgmtaTZyL/geKAlb8AleuEM0mSEYVwnDjF3Jjmfmtb9yfO9dpF9RFrIPGyZmN1Ne SJcwXhMMioSwNSg1UdbzNg/PdT77v8QRSrxukJVCKBjmfXuaMUlg768hgPnkHKekRbgU WXlw==; darn=lists.postgresql.org ARC-Authentication-Results: i=1; mx.google.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1776646539; x=1777251339; darn=lists.postgresql.org; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=Os7nzvmarI4J6Bjprlx1IC+NJm/BhqQf2p+PhvLAiFQ=; b=CSwyalOfaKdAHk6vZe+C0K4zzIdvSOsNS0vwQfQAKdnW/BZwM/ar51+vK7zd7eEvBq 7jc8j3OtKFCDDIbyzkGqckMnTdjOc9jayWZhjPXLi4iK/eW+zVVGCno/PY+TBg9AnfZI cc3fmC4njN1Fca8WP+nRZRNCYt/IgtzUP+5MHvxusdvIR79ZY7h7C0vV74Ffo3hmqUo9 4nFW9dYQZGG+WIEC6O9Fm1NFVUSM7p/cFoyt713aJTWG2juxK5chpdwmA8ANkYYKLWQU bsrjRI6BNagQVGqrl5UKlKcC5M9uczHUA9B5JXSEXCXy2Q4xmtdvLvWPgDME7CC3MU9o TVPA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1776646539; x=1777251339; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=Os7nzvmarI4J6Bjprlx1IC+NJm/BhqQf2p+PhvLAiFQ=; b=ez2cjlQS9PmXDu5qM2VVXaoPa5tyCGMZY8xh6eEQBK3HaP93bBoHiIrzyrEGuEWdp9 zVugWavcZbeao4MLq+P926UM9h6TR3Hv/39V/wG50Wthemn/IskRTwSNke05bpgP2mQf K6ry3gySJgMV046b8694sriLl7rRvUsFVu7iZJR/n6V90xSDsvGyyWCfOoWMWnrwGRf4 5OyjFHduNx3ADS60/VI5FR05LoUmSB8pQCzJ7/MOJ+lB1bt66eH+Du4T4Jj5r+8YVlbg mFTA62SxoJ2q2HLqu383MkCDwTRhsJ6eLTK/2LHh9AtSYrICRzc+XaPHiOF+8CCB4zIQ nvpA== X-Gm-Message-State: AOJu0YzIvLC1mYFlLSdQnHBepHoYkcomDHTuDiR16XXOtjNci1Sabclm /QseJH+Bjzvomsc+0ZjTHDzsiw3DEjTb1kC/lXahcG1J6eGo2lknaWhOCO5Hx5ge5m9BYSVS/YC Y/Gy0Gptzq1Ku5Lr7gt2t02UTOunxCVU= X-Gm-Gg: AeBDietvauiuaGPNG+kQsA0JqMuYmNjeoX40OSymmsKrgKPBkTW+2QPFF5xXGp0HpH4 3DlRFuzMURiV4WtZ3j6IGXEivFIdEKf2ETuYGS/XtKDZZMqDXntLzCMEVg+uthsdg8jMX2zlIK0 rCCgVMOWok3bCEorosZ3GpSf1UcNH3V/DD0NfpAzbdR73LBWesxWH5NaLkV4YBv5xMq/ABB7+lw 0QlXPEtSadJ7WuKulYsNVALtLRfT5xiX97SFkIkmuebnEnsKqGRuV9JKQtJHNBObiHz2lVJIkKi s5aepOcW1FE8IKUPmQ== X-Received: by 2002:a05:6102:6048:b0:605:5e9d:2e5e with SMTP id ada2fe7eead31-616f5db0b5dmr3663763137.7.1776646539236; Sun, 19 Apr 2026 17:55:39 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: From: SATYANARAYANA NARLAPURAM Date: Sun, 19 Apr 2026 17:55:26 -0700 X-Gm-Features: AQROBzCKr8N4NLvfKVSwXNHF5zZunYMbP0nzT6pXcdb12wfTzqJ36pWXlJsVZTk Message-ID: Subject: Re: [BUG] ON CONFLICT DO UPDATE SET x = EXCLUDED. errors or silently writes NULL To: Dean Rasheed Cc: PostgreSQL Hackers Content-Type: multipart/alternative; boundary="000000000000dcda8c064fd9c157" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --000000000000dcda8c064fd9c157 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable HI, On Sat, Apr 18, 2026 at 11:14=E2=80=AFAM Dean Rasheed wrote: > On Thu, 16 Apr 2026 at 21:49, SATYANARAYANA NARLAPURAM > wrote: > > > > Virtual generated column (bgc) behavior for plain and partitioned table= s > is different > > when EXCLUDED. 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 o= f > exclRelTlist and > > leaves has_non_vars =3D 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 > --000000000000dcda8c064fd9c157 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
HI,

On Sat, Apr 18, = 2026 at 11:14=E2=80=AFAM Dean Rasheed <dean.a.rasheed@gmail.com> wrote:
On Thu, 16 Apr 2026 at 21:49, SATYANARAY= ANA NARLAPURAM
<satyanar= lapuram@gmail.com> wrote:
>
> Virtual generated column (bgc) behavior for plain and partitioned tabl= es is different
> when EXCLUDED.<vgc> references inside for INSERT ... ON CONFLICT= DO UPDATE.
> For plain table it errors out with the message "unexpected virtua= l 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_in= dex_other_vars . This fix
> works because build_tlist_index_other_vars only indexes plain-Var TEs = of exclRelTlist and
> leaves has_non_vars =3D false, so fix_join_expr skips whole-subtree ma= tching and never collapses
>=C2=A0 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<= br> 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,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 c=C2=A0 int GENERAT= ED ALWAYS AS (a) VIRTUAL, a int);

Admittedly, that's a rather silly example, but we really ought to have<= br> a fix that works for all cases.

Agreed.=
=C2=A0

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 pa= ss.

Reran the failing tests and they al= l passed. Additionally ran the regression tests.
=C2=A0Patch look= s good to me.
=C2=A0

Regards,
Dean
--000000000000dcda8c064fd9c157--