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 1wa2c9-001UNi-0r for pgsql-hackers@arkaria.postgresql.org; Thu, 18 Jun 2026 02:36:21 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1wa2c8-008oGK-0I for pgsql-hackers@arkaria.postgresql.org; Thu, 18 Jun 2026 02:36:20 +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 1wa2c7-008oGC-2c for pgsql-hackers@lists.postgresql.org; Thu, 18 Jun 2026 02:36:19 +0000 Received: from mail-pf1-x430.google.com ([2607:f8b0:4864:20::430]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1wa2c5-000000011Bd-1wGo for pgsql-hackers@lists.postgresql.org; Thu, 18 Jun 2026 02:36:19 +0000 Received: by mail-pf1-x430.google.com with SMTP id d2e1a72fcca58-8453a67659fso183723b3a.1 for ; Wed, 17 Jun 2026 19:36:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1781750175; x=1782354975; darn=lists.postgresql.org; h=to:references:message-id:content-transfer-encoding:cc:date :in-reply-to:from:subject:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=ClNbLNmS15eSS3TgL8LqvAO4Gz8YPzbuQov3A2Pq6Wk=; b=etWV8eDtEFLkKSX2Pn/Eosdne4mBpsnRhUnoNcNOBSkD52r/BdviXPT+v3ZUBA1CFq dKNT/o7qnWboWj59yIjAoVrVMu4GFJxaiX8RbQjRPVy93iQ748qy504huMQj6SrzP8E8 eHgvYETMvAfIrqIOdah/Ov6UWAXcZb4hCq6WnbaCXA7pZKy6UOl7JCiY+fqGfhu0Qfs6 CXG1JJDj2aK0WtPflukylX9ylq2z44UsuM0JY8kAoaioKe2hzBfr8GDmOKDO1iP1l+qP zoEIo8DbqDVgMvloMD9+1p3yL9LmkVxWoQfiwBHky9LlFUeDvo+m42iNMqFILTLR7OR9 Vizw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1781750175; x=1782354975; h=to:references:message-id:content-transfer-encoding:cc:date :in-reply-to:from:subject:mime-version:x-gm-gg:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=ClNbLNmS15eSS3TgL8LqvAO4Gz8YPzbuQov3A2Pq6Wk=; b=cFMgX6Bk6Eg9Wk4qpi+aWGcW5W0tulCoSmdp+auMiytw+GnL6wnqfIhabBvRxwsrQg 7jjjeW5EEqDE/PKt//6efFg7bAS8bYposetX1L7WFb57j4RbXRbscQs9mtGgeTaNWb9R tjIOIy9C60Hu+dRfhB5iV713AA7Zw7Oy9Ak1Pcv75vLdIDlAR8DWay2OydIN522DiLLx 75nl0eIRQuV9k7HhtBHnCllIeqJuAhM+hORscWukVi+qi9bMOp28KVg5dbNXXcRQcrtu qPxV/canXAE7atZvl+EIPPcWQL0dUiZtRlGTmTnptmRYWoSgLi7h6r+UMVHkqI8k+v42 JW/Q== X-Forwarded-Encrypted: i=1; AFNElJ8s9yEaTt7F5lFInODPwrVhhkxh2wmTxx0AIuJdiuwu3oCoN8kCNAZkc2M2zlpnMYbPnoWaN5/WmaXYGON9@lists.postgresql.org X-Gm-Message-State: AOJu0YwC1lDNYmnQmbWhW7nvDyuv1lM296ICjic86BoEv5VKSh7eksE2 2f+lWNLCJKqpnc8Eu28MyK8GB7pU61zSl70D0cb5EZjnuXEeIBk5HkkS X-Gm-Gg: Acq92OGdWRUYJLaKSN5xbLt7qOIYvwnSAK14DjourxWkyGUUBLKpFGDe1jKoMO5pAFN NOvbNwOvqRcxVMcH0BsPRi2MjTHNC6jDfdeumYcRj+V+72M3sFZoOTh59Lhl0lyA3w6KtimGQq1 ZvwuFWAUwp2SKNOGlGUv9wwKWPGea0i2H3S03ktauilQ3XO8DO2GiIsAfODFrJm8yKRyOpYIMyA Z2F6yw5Pyp5NqP5GxMyvshZCtfRxFo/AuSL5QafFBzWZvwZIFx9uljIPPNQkxU5S8Gb5D6QtsMN gUqGQQ7CL3iQO2x2/qE4J8npocxLZnlXR/7C6JnmEMpiz15FAzwDMznSfvvxvsZPvEoUCBh4GTF pgJ7hh7p+A7K03xEieuX1VfPNwsa6UqJYfysNbpqt1a/mdJs61x6PgMXjv2Jqc6f4RVv8/aVY6B HJ7Jb6cJS5yY3eVFOt2k/6mQ== X-Received: by 2002:a05:6a00:2d20:b0:83d:b11f:7979 with SMTP id d2e1a72fcca58-8453b2156e4mr1540952b3a.29.1781750175119; Wed, 17 Jun 2026 19:36:15 -0700 (PDT) Received: from smtpclient.apple ([185.135.79.161]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-8434accdca8sm21647790b3a.18.2026.06.17.19.36.12 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 17 Jun 2026 19:36:14 -0700 (PDT) Content-Type: text/plain; charset=utf-8 Mime-Version: 1.0 (Mac OS X Mail 16.0 \(3864.600.51.1.1\)) Subject: Re: Fix tuple deformation with virtual generated NOT NULL columns From: Chao Li In-Reply-To: Date: Thu, 18 Jun 2026 10:35:37 +0800 Cc: Tom Lane , Peter Eisentraut , Andres Freund , Postgres hackers Content-Transfer-Encoding: quoted-printable Message-Id: <2A622929-A45C-4370-943A-BC76FF4CC433@gmail.com> References: <1151393.1781734980@sss.pgh.pa.us> <1174236.1781736349@sss.pgh.pa.us> To: David Rowley X-Mailer: Apple Mail (2.3864.600.51.1.1) List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk > On Jun 18, 2026, at 07:37, David Rowley wrote: >=20 > On Thu, 18 Jun 2026 at 11:06, David Rowley = wrote: >> Just starting to look now, but I suspect that this code in >> llvmjit_deform.c needs to be updated now that we have virtual >> generated columns. >=20 > I've not fully processed all this code yet. I've still not worked out > why the loop that sets guaranteed_column_number doesn't break when it > finds something non-guaranteed. >=20 > Here's a draft patch I was experimenting with. It seems to fix the > issue. I need to spend more time to check it's correct. >=20 > David > I was not aware of the JIT code before. I think the good thing is that = the new test uncovered this JIT bug. I tested the fix, and it seems to work. While tracing the code, I = wondered about this part: ``` - if (att->attnullability =3D=3D ATTNULLABLE_VALID && - !att->atthasmissing && - !att->attisdropped) + if (attr->attgenerated =3D=3D = ATTRIBUTE_GENERATED_VIRTUAL) + break; + + if (catt->attnullability =3D=3D ATTNULLABLE_VALID && + !catt->atthasmissing && + !catt->attisdropped) guaranteed_column_number =3D attnum; ``` When computing guaranteed_column_number, I think we can just skip the = virtual generated column rather than break. Using the test from Tom=E2=80=99= s email: ``` CREATE TABLE gtest21c (a int NOT NULL, b int GENERATED ALWAYS AS (a * 2) = VIRTUAL NOT NULL, c int NOT NULL); ``` Here, =E2=80=9Cc" is a real NOT NULL column, so we can skip =E2=80=9Cb" = and let =E2=80=9Cc" set guaranteed_column_number. This matters for the = later check: ``` /* * Check if it is guaranteed that all the desired attributes are = available * in the tuple (but still possibly NULL), by dint of either the = last * to-be-deformed column being NOT NULL, or subsequent ones not = accessed * here being NOT NULL. If that's not guaranteed the tuple = headers natt's * has to be checked, and missing attributes potentially have to = be * fetched (using slot_getmissingattrs(). */ if ((natts - 1) <=3D guaranteed_column_number) { ``` If we break at =E2=80=9Cb", then this check goes to the else branch and = invokes the maxatt check plus slot_getmissingattrs(), even though the = later NOT NULL =E2=80=9Cc" proves that the tuple has enough attributes. Otherwise, the fix looks good to me. Best regards, -- Chao Li (Evan) HighGo Software Co., Ltd. https://www.highgo.com/