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 1wAuLd-000YfG-2z for pgsql-hackers@arkaria.postgresql.org; Thu, 09 Apr 2026 18:43:26 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1wAuLb-007LZi-2o for pgsql-hackers@arkaria.postgresql.org; Thu, 09 Apr 2026 18:43:24 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1wAuLb-007LZZ-1V for pgsql-hackers@lists.postgresql.org; Thu, 09 Apr 2026 18:43:24 +0000 Received: from mail-vs1-xe2d.google.com ([2607:f8b0:4864:20::e2d]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1wAuLZ-00000000Cw5-2o5r for pgsql-hackers@lists.postgresql.org; Thu, 09 Apr 2026 18:43:23 +0000 Received: by mail-vs1-xe2d.google.com with SMTP id ada2fe7eead31-604f327bafcso441124137.0 for ; Thu, 09 Apr 2026 11:43:21 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1775760201; cv=none; d=google.com; s=arc-20240605; b=XzifyQFeJKGdAvuzmKjyLcMrq/Redd8I7hIZi7rylCK90q/q3QvU89X9M1NO+OaH4Y BUUR9NfQ5Z+48bJQw39GEsyJ3/Tckxa7oYDeJDEQXeccyDSokb5uGq1uAwt34OzNH5Xb jwPgvM4hEZGDHEE247wnZNsZkq+FhYfXLTsIeNeWJhHrMqK+9Euu6cCWH8BNgEn+FhHQ FnDGaNT/SbKZSi5REOUvouRgCcZ6Q5N+3ghWGMSyo/ZeZzaQrCqABPKTa0FC2yKdcXAS u0nIqrL8yQpnyUmggOnipI9u4Lhz7Ir3nniRrGXbS80GDJm7Be+0K01wBJ/jjIKbiAel YJEQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=to:subject:message-id:date:from:mime-version:dkim-signature; bh=nZyz7HQK/1MEdowdZGmtBVpt8Xdtg1S0A44gSXTL2gA=; fh=GdNpCHEgiXoJdwkRoFTWhu+0YxM0T4xK7fCuLbEzWiY=; b=OMhwgB31abFe2oAIUN4EXUCeomfzXhtXBgYjaO0LEjtnm8lLZsSr/JwEAuCADAEVUf AOGSDwaOFYJOdT2CrtdvCSDlsWithCc1nLWRvpZDI98na0el+ByIVFQ8p81hEBHra6JK KQAAgjPjQOhTyRPshDFU93EsE0X+gOhyrEg8TveufPXznhp8capYfIbECrdWZ5PGF/H8 YjUPGG8UEL5h8VtnIh5F//vrZt04LUwuAL/Cr6Mw/c1DM1filhhRW7lBsmUR3bXYbcKA 6Tr/MRGDgbZNVUQRohUPvhUqUJBEr/jEH0QmCXxePJ9W72yBZkvZlnhvkVh/uQcIulwk 6vlQ==; 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=1775760201; x=1776365001; darn=lists.postgresql.org; h=to:subject:message-id:date:from:mime-version:from:to:cc:subject :date:message-id:reply-to; bh=nZyz7HQK/1MEdowdZGmtBVpt8Xdtg1S0A44gSXTL2gA=; b=gf6CD+jHRH1W6sB9qV+jkEUIjhTDYWZtViQAjRWNL5LfOQu+L5tGE/qb2WOzVdPUiQ OjVb/d0jWAIVhs7HITokXCWFxdlGv6c/jjoVCdzrmEw4t5UErFZQ/fkz1i7+ZtUBGvaw QLzPuZXaFTAEIdKffktc1+80j3IMZuUy3OxsKwLmt1D11XPSnCTwzBo+a3kRiKsqXWvZ 7784Kv9CbDU6T2jKQktXuJFnIohqK3ot1lwnHwCZ2j2a38YqclPahUuqhzoAURKG6LAM blbLp1HJq8GLjAwThmQOCNXpJ33t1+kAEj8b0iv/D01DK4vgPSIy8e42Pe9LbLZkK9+F kQpA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1775760201; x=1776365001; h=to:subject:message-id:date:from:mime-version:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=nZyz7HQK/1MEdowdZGmtBVpt8Xdtg1S0A44gSXTL2gA=; b=RtBXeRDux46YDG0JkYDn/6Nlq7PKCSpWJ6J8QDR6iYZCQLWj1LwiHkEFFjPOitJXUe 2r2tPtf9rWj9gHwxMyBDwVivItqXDtvdD8Ng61pZ25gvrwZwK38jyhBOxXdVii94LwW5 DFTeltl1aRVRUs8/wATFbmZjqyPThGLyNsLkG40d4m4Y0CXzuqf/16viqzmtd26kIEa1 rqBVD6tADgSOHhhbSxA/h55xGF5PGAuB2JL/y629SnKsHDxF8e6QaInjySOHR0St3qw8 /jnuZP8e0F4kuy8UwBX4bv2k6k0kRUx7INOTg48npV5Ry/n0QgQME3jUuFyDWh3D3Iyy tYgA== X-Forwarded-Encrypted: i=1; AJvYcCW4zPHUdh3K1bCQXikw+F/qqwAoQjD7stpeaIXs4Ybh6kZS6/KtSKpO2uVmnultTsViYqOT7AKwLq3NMUAg@lists.postgresql.org X-Gm-Message-State: AOJu0YyyQmg6nn580kW+7qQow8jZgZCYxvh7jlpvqegTACigyWCHjOQj 7eSMOnWLN/1d5Q3RL/ONSGk3bzCw2iqTtObqPO/yUY837BjxarJgzKRFeRE7TxNNzp6LA7fmaCg V3WPbxyWjVqSn/2YX5qRovfIsk2A9Bm0= X-Gm-Gg: AeBDievo2zRCqXPMqbwb1503u1U/X6lzaUkFEUlgnXBh4qfmRYKxO9omcDNimatO62Y hrsy2QnfjRaEZhd7ykcm/9XiMhi4oz5aHcVlgggvgaoPFvaAV+H1tZWblS3PYBzG8PeW8rmY8aS FNrOK57hmiMOUnoxlHdsEPgKnhyjVObpPqqiQyP3Spw9x6yiXk6dfqYpgMyhysC7yUCJ9Z4QynI G+BmaQ4io2Tk4F9ewhM2FsayDGB/59gWZFOOzj3OP0GoXJCQo0iuEOhrcqi4TMpIhSynT9RFdir FDfIIwYN8w== X-Received: by 2002:a05:6102:4407:b0:604:ec90:ba14 with SMTP id ada2fe7eead31-609fefc78f2mr65243137.11.1775760201188; Thu, 09 Apr 2026 11:43:21 -0700 (PDT) MIME-Version: 1.0 From: SATYANARAYANA NARLAPURAM Date: Thu, 9 Apr 2026 11:43:09 -0700 X-Gm-Features: AQROBzDNJSn9OTk9M4B7kpDlFscGMq8I0P99Qf9pXiNTSuJrfNQ-AHQYkZOZhjI Message-ID: Subject: Bug: var_is_nonnullable() gives wrong results for old/new in RETURNING To: PostgreSQL-development , PostgreSQL Hackers Content-Type: multipart/mixed; boundary="000000000000ffb966064f0b6376" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --000000000000ffb966064f0b6376 Content-Type: multipart/alternative; boundary="000000000000ffb964064f0b6374" --000000000000ffb964064f0b6374 Content-Type: text/plain; charset="UTF-8" Hi hackers, It appears the optimizer incorrectly simplifies old. IS NULL to FALSE in RETURNING clauses when the underlying column has a NOT NULL constraint. The issue is that var_is_nonnullable() in clauses.c doesn't check Var.varreturningtype. It sees a NOT NULL column and concludes the Var can never be NULL. But this assumption is wrong for old.* and new.* references. Because the old tuple doesn't exist on INSERT, and the new tuple doesn't exist on DELETE I am not super familiar with this area, so I attempted to fix this as in the patch attached. Repro: postgres=# CREATE TABLE t (id INT NOT NULL PRIMARY KEY, val INT); INSERT INTO t VALUES (1, 10); MERGE INTO t USING (VALUES (1, 99), (2, 50)) AS s(id, val) ON t.id = s.id WHEN MATCHED THEN UPDATE SET val = s.val WHEN NOT MATCHED THEN INSERT VALUES (s.id, s.val) RETURNING merge_action(), old.id IS NULL AS is_new_row; CREATE TABLE INSERT 0 1 merge_action | is_new_row --------------+------------ UPDATE | f INSERT | f -- (this should be true) (2 rows) MERGE 2 Thanks, Satya --000000000000ffb964064f0b6374 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Hi hackers,

It appears the optimizer incorrectly si= mplifies old.<col> IS NULL to FALSE in RETURNING clauses when the und= erlying column has a NOT NULL constraint.

The issue is that var_is_n= onnullable() in clauses.c doesn't check Var.varreturningtype. It sees a= NOT NULL column and concludes the Var can never be NULL.
But this assu= mption is wrong for old.* and new.* references. Because the old tuple doesn= 't exist on INSERT, and the new tuple doesn't exist on DELETE=C2=A0=
I am not super familiar with this area, so I attempted to fix this as i= n the patch attached.

Repro:

<= div>postgres=3D# CREATE TABLE t (id INT NOT NULL PRIMARY KEY, val INT);
= INSERT INTO t VALUES (1, 10);

MERGE INTO t
USING (VALUES (1, 99),= (2, 50)) AS s(id, val) ON t.id =3D s.id
WHEN MATCHED THEN UPDATE SET val =3D s.val
WHEN= NOT MATCHED THEN INSERT VALUES (s.id, s.val)RETURNING merge_action(),
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 old.id IS NULL AS is_new_row;
CREATE TABLE
INS= ERT 0 1

=C2=A0merge_action | is_new_row
--------------+---------= ---
=C2=A0UPDATE =C2=A0 =C2=A0 =C2=A0 | f
=C2=A0INSERT =C2=A0 =C2=A0 = =C2=A0 | f=C2=A0 -- (this should be true)
(2 rows)

MERGE 2
<= div>

Thanks,
Satya

--000000000000ffb964064f0b6374-- --000000000000ffb966064f0b6376 Content-Type: application/octet-stream; name="0001-test-var_is_nonnullable-returning-old-new.patch" Content-Disposition: attachment; filename="0001-test-var_is_nonnullable-returning-old-new.patch" Content-Transfer-Encoding: base64 Content-ID: X-Attachment-Id: f_mnrtr1540 ZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3JlZ3Jlc3MvZXhwZWN0ZWQvbWVyZ2Uub3V0IGIvc3JjL3Rl c3QvcmVncmVzcy9leHBlY3RlZC9tZXJnZS5vdXQKaW5kZXggOWNiMWQ4NzAuLjQ0NDFlMzk5IDEw MDY0NAotLS0gYS9zcmMvdGVzdC9yZWdyZXNzL2V4cGVjdGVkL21lcmdlLm91dAorKysgYi9zcmMv dGVzdC9yZWdyZXNzL2V4cGVjdGVkL21lcmdlLm91dApAQCAtMTYwOSw2ICsxNjA5LDMxIEBAIExB VEVSQUwgKFNFTEVDVCByX2FjdGlvbiwgcl90aWQsIHJfYmFsYW5jZSBGUk9NIG1lcmdlX2ludG9f c3FfdGFyZ2V0KHNpZCwgYmFsYW5jCiAgSU5TRVJUICAgfCAgICAgNCB8ICAgICAgIDExMAogKDMg cm93cykKIAorUk9MTEJBQ0s7CistLSBUZXN0IHRoYXQgb2xkL25ldyBjb2x1bW4gSVMgTlVMTCBp cyBjb25zdGFudC1mb2xkZWQKKy0tIGZvciBOT1QgTlVMTCBjb2x1bW5zIGluIE1FUkdFIFJFVFVS TklORworQkVHSU47CitNRVJHRSBJTlRPIHNxX3RhcmdldCB0CitVU0lORyBzcV9zb3VyY2UgcyBP TiB0aWQgPSBzaWQKK1dIRU4gTUFUQ0hFRCBBTkQgdGlkID49IDIgVEhFTgorICAgIFVQREFURSBT RVQgYmFsYW5jZSA9IHQuYmFsYW5jZSArIGRlbHRhCitXSEVOIE5PVCBNQVRDSEVEIFRIRU4KKyAg ICBJTlNFUlQgKGJhbGFuY2UsIHRpZCkgVkFMVUVTIChiYWxhbmNlICsgZGVsdGEsIHNpZCkKK1dI RU4gTUFUQ0hFRCBBTkQgdGlkIDwgMiBUSEVOCisgICAgREVMRVRFCitSRVRVUk5JTkcgbWVyZ2Vf YWN0aW9uKCksCisgICAgb2xkLnRpZCBJUyBOVUxMIEFTIG9sZF90aWRfaXNfbnVsbCwKKyAgICBu ZXcudGlkIElTIE5VTEwgQVMgbmV3X3RpZF9pc19udWxsLAorICAgIG9sZCBJUyBOVUxMIEFTIG9s ZF9yb3dfaXNfbnVsbCwKKyAgICBuZXcgSVMgTlVMTCBBUyBuZXdfcm93X2lzX251bGw7CisgbWVy Z2VfYWN0aW9uIHwgb2xkX3RpZF9pc19udWxsIHwgbmV3X3RpZF9pc19udWxsIHwgb2xkX3Jvd19p c19udWxsIHwgbmV3X3Jvd19pc19udWxsIAorLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0t LS0rLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0K KyBERUxFVEUgICAgICAgfCBmICAgICAgICAgICAgICAgfCB0ICAgICAgICAgICAgICAgfCBmICAg ICAgICAgICAgICAgfCB0CisgVVBEQVRFICAgICAgIHwgZiAgICAgICAgICAgICAgIHwgZiAgICAg ICAgICAgICAgIHwgZiAgICAgICAgICAgICAgIHwgZgorIElOU0VSVCAgICAgICB8IHQgICAgICAg ICAgICAgICB8IGYgICAgICAgICAgICAgICB8IHQgICAgICAgICAgICAgICB8IGYKKygzIHJvd3Mp CisKIFJPTExCQUNLOwogLS0gRVhQTEFJTgogQ1JFQVRFIFRBQkxFIGV4X210YXJnZXQgKGEgaW50 LCBiIGludCkKZGlmZiAtLWdpdCBhL3NyYy90ZXN0L3JlZ3Jlc3Mvc3FsL21lcmdlLnNxbCBiL3Ny Yy90ZXN0L3JlZ3Jlc3Mvc3FsL21lcmdlLnNxbAppbmRleCAyNjYwYjE5Zi4uNjc4OWZjZDUgMTAw NjQ0Ci0tLSBhL3NyYy90ZXN0L3JlZ3Jlc3Mvc3FsL21lcmdlLnNxbAorKysgYi9zcmMvdGVzdC9y ZWdyZXNzL3NxbC9tZXJnZS5zcWwKQEAgLTEwNjAsNiArMTA2MCwyNSBAQCBGUk9NIChWQUxVRVMg KDEsIDAsIDApLCAoMywgMCwgMjApLCAoNCwgMTAwLCAxMCkpIEFTIHYoc2lkLCBiYWxhbmNlLCBk ZWx0YSksCiBMQVRFUkFMIChTRUxFQ1Qgcl9hY3Rpb24sIHJfdGlkLCByX2JhbGFuY2UgRlJPTSBt ZXJnZV9pbnRvX3NxX3RhcmdldChzaWQsIGJhbGFuY2UsIGRlbHRhKSkgbTsKIFJPTExCQUNLOwog CistLSBUZXN0IHRoYXQgb2xkL25ldyBjb2x1bW4gSVMgTlVMTCBpcyBjb25zdGFudC1mb2xkZWQK Ky0tIGZvciBOT1QgTlVMTCBjb2x1bW5zIGluIE1FUkdFIFJFVFVSTklORworQkVHSU47CitNRVJH RSBJTlRPIHNxX3RhcmdldCB0CitVU0lORyBzcV9zb3VyY2UgcyBPTiB0aWQgPSBzaWQKK1dIRU4g TUFUQ0hFRCBBTkQgdGlkID49IDIgVEhFTgorICAgIFVQREFURSBTRVQgYmFsYW5jZSA9IHQuYmFs YW5jZSArIGRlbHRhCitXSEVOIE5PVCBNQVRDSEVEIFRIRU4KKyAgICBJTlNFUlQgKGJhbGFuY2Us IHRpZCkgVkFMVUVTIChiYWxhbmNlICsgZGVsdGEsIHNpZCkKK1dIRU4gTUFUQ0hFRCBBTkQgdGlk IDwgMiBUSEVOCisgICAgREVMRVRFCitSRVRVUk5JTkcgbWVyZ2VfYWN0aW9uKCksCisgICAgb2xk LnRpZCBJUyBOVUxMIEFTIG9sZF90aWRfaXNfbnVsbCwKKyAgICBuZXcudGlkIElTIE5VTEwgQVMg bmV3X3RpZF9pc19udWxsLAorICAgIG9sZCBJUyBOVUxMIEFTIG9sZF9yb3dfaXNfbnVsbCwKKyAg ICBuZXcgSVMgTlVMTCBBUyBuZXdfcm93X2lzX251bGw7CitST0xMQkFDSzsKKwogLS0gRVhQTEFJ TgogQ1JFQVRFIFRBQkxFIGV4X210YXJnZXQgKGEgaW50LCBiIGludCkKICAgV0lUSCAoYXV0b3Zh Y3V1bV9lbmFibGVkPW9mZik7Cg== --000000000000ffb966064f0b6376 Content-Type: application/octet-stream; name="0001-fix-var_is_nonnullable-returning-old-new.patch" Content-Disposition: attachment; filename="0001-fix-var_is_nonnullable-returning-old-new.patch" Content-Transfer-Encoding: base64 Content-ID: X-Attachment-Id: f_mnrtripx1 ZGlmZiAtLWdpdCBhL3NyYy9iYWNrZW5kL29wdGltaXplci91dGlsL2NsYXVzZXMuYyBiL3NyYy9i YWNrZW5kL29wdGltaXplci91dGlsL2NsYXVzZXMuYwppbmRleCA5ZmIyNjZkMC4uZjI5MGE0Mzkg MTAwNjQ0Ci0tLSBhL3NyYy9iYWNrZW5kL29wdGltaXplci91dGlsL2NsYXVzZXMuYworKysgYi9z cmMvYmFja2VuZC9vcHRpbWl6ZXIvdXRpbC9jbGF1c2VzLmMKQEAgLTQ2MzEsNiArNDYzMSwxNSBA QCB2YXJfaXNfbm9ubnVsbGFibGUoUGxhbm5lckluZm8gKnJvb3QsIFZhciAqdmFyLCBOb3ROdWxs U291cmNlIHNvdXJjZSkKIAlpZiAodmFyLT52YXJsZXZlbHN1cCAhPSAwKQogCQlyZXR1cm4gZmFs c2U7CiAKKwkvKgorCSAqIEEgVmFyIHdpdGggVkFSX1JFVFVSTklOR19PTEQgb3IgVkFSX1JFVFVS TklOR19ORVcgcmVmZXJzIHRvIHRoZSBPTEQgb3IKKwkgKiBORVcgdHVwbGUgaW4gYSBSRVRVUk5J TkcgbGlzdC4gIFN1Y2ggYSBWYXIgY2FuIGJlIE5VTEwgZXZlbiBpZiB0aGUKKwkgKiB1bmRlcmx5 aW5nIGNvbHVtbiBpcyBkZWZpbmVkIE5PVCBOVUxMLCBiZWNhdXNlIHRoZSBPTEQgdHVwbGUgZG9l c24ndAorCSAqIGV4aXN0IGZvciBJTlNFUlQgYW5kIHRoZSBORVcgdHVwbGUgZG9lc24ndCBleGlz dCBmb3IgREVMRVRFLgorCSAqLworCWlmICh2YXItPnZhcnJldHVybmluZ3R5cGUgIT0gVkFSX1JF VFVSTklOR19ERUZBVUxUKQorCQlyZXR1cm4gZmFsc2U7CisKIAkvKiBjb3VsZCB0aGUgVmFyIGJl IG51bGxlZCBieSBhbnkgb3V0ZXIgam9pbnMgb3IgZ3JvdXBpbmcgc2V0cz8gKi8KIAlpZiAoIWJt c19pc19lbXB0eSh2YXItPnZhcm51bGxpbmdyZWxzKSkKIAkJcmV0dXJuIGZhbHNlOwo= --000000000000ffb966064f0b6376--