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 1vxibt-00H4LI-1b for pgsql-hackers@arkaria.postgresql.org; Wed, 04 Mar 2026 09:33:41 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1vxibr-00C4uu-1i for pgsql-hackers@arkaria.postgresql.org; Wed, 04 Mar 2026 09:33:40 +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 1vxibr-00C4um-0n for pgsql-hackers@lists.postgresql.org; Wed, 04 Mar 2026 09:33:39 +0000 Received: from mail-ot1-x331.google.com ([2607:f8b0:4864:20::331]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1vxibp-00000000VQZ-2PJx for pgsql-hackers@lists.postgresql.org; Wed, 04 Mar 2026 09:33:39 +0000 Received: by mail-ot1-x331.google.com with SMTP id 46e09a7af769-7d4c65d772cso5922975a34.1 for ; Wed, 04 Mar 2026 01:33:37 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1772616816; cv=none; d=google.com; s=arc-20240605; b=EBbpE3k5qShvDy7+8ffKTkeYZVgu0/d2dfbAsC51Y9z6OrjeNAhT1VjgJvseWvyoYT /bopXEB/NXmE+K7I4/H67umqDs2Boo5RR6YOTBMGt1Kc94ef5F95VrMMpRDmdsbV3pku ASnD+eWD9DofRJn7aa0hkkETCwZpquK8LI1C3dySRTs/cIlv/+kreVu3EhqFFSUkkLtb e4hlYAa3JfzWFRlwQZqhXp3E+E3LAVu0NyPb4MbweCwumT1PVAtWKiDbtVwz6Zpsf1Qm mVeUgQLDrtvJy/wc6A2+kUhBuTVVDCK00bGD5v70kCcWPWlkbHqwGwOTVuKrlXr23vor iBpw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:dkim-signature; bh=VJYLIZn0Ioq2xKZzgu/deJ4JCvpZ28NpAq3BninBxxY=; fh=MopyST+JPi7eqQVu6gRjxYOVIKR7XNKfB9ofLKgO66k=; b=EWQ6yaIuv2hh+867i9oUj5blyC61qiuoxVvcPGVBQE0BeoajtCM25Dd5AohIJKuhpq 7jOrikSoLRu6NX23EuVr+XKIoOMFGrbhZ96W6qSfTceOvttXaDBoMMIvgCyIBpt2oaGU mLmfV9/nBXMWGDTvmYMAC0OqFV4KoSiwl5y8W84WGNmCpg9XJxeGkKXAF4G4z/uYfUvr ig6qx1xex1bGKRhI4koeoZYp7ZNbD4mdB3WgZ8gzcGYHNJFBUJEryET4gvQLEkLqiJfi rX1P4DRlwYzPAKz5CyE7lLQFds2M2AozIAHdlvCntq6MpH06leKKiCV0qgc5bwIr0zS/ +U6w==; 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=20230601; t=1772616816; x=1773221616; darn=lists.postgresql.org; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=VJYLIZn0Ioq2xKZzgu/deJ4JCvpZ28NpAq3BninBxxY=; b=jFw4BSEw00mZaVCWDSMZU3ctaeYkAmjP7fdFvocxgl45agI3tpw2G/OTXzthkG1MY5 vBX5poJxS1S2FcvVxdPkWjNY+axC1PUk30QU111tjiwQUTqwcTsY19X4XIi/qUOzt9/L 6nAmU92WFBPPV1oCa7OXHDnUf3T8f7YI0eUfRVVCjAeAH8PSGQLAYPSKih1QCYPki76Z uuHDyTO5ORbZ/0/F6Z0wHUupZ2fXQn6BpUtDI3sv5jhvQKTfEffPyvqG34PHY5BbLS3e zgPsqqiMGVRTPJhMGCi9k0dCN+kcOjldFpcLNm1nhheaXFNXN2Z+y0D5aGW6UdSGhN3+ HQAA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772616816; x=1773221616; h=content-transfer-encoding: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=VJYLIZn0Ioq2xKZzgu/deJ4JCvpZ28NpAq3BninBxxY=; b=Dq9UIiekV2nAc/sICeAsu3AzzPIOaRZ5ngBgv4KVnXEUX4VsCbeY99MBwxOzGBTm8k /n+bF+g3Ai3YkQeofygH1ZE33Xzxr1wRO2HYKpWGbqSP18kvvWqgb6vPJjcNJD1BHJ9h /RZt4KLCsmamJhYwWD4Aqkh7fveygZysUSgyUjJttmYf5grHzQw7oQdG6ur152NPl/UO 2GqH6a4AsDVDadZ3GSnITDWeZ6iKuv/GKRNu3C3rVxM/hnXEQ5gIfOCVBhVxGXnYzLkK nTznYBSafrSDRfxhk0bH1tC0j5dllgB+3ppzbexpFWN1pscfx6GSwFeZglzpLnbiYc26 1+zw== X-Gm-Message-State: AOJu0Yz0bL757bFLdUT2WpwnEHt53zCrchEj07weBEsPcWZYZ12rghTE PHVT3sbDMPYmN1FPAlsTZD03PDrB+/+FditzWdZBV21lwv6X1bPsiwlLG1lbhbLZp1gL3IShrGT yzA8264Ywhhv0IJKvkbLv38fgS3EpEJ0= X-Gm-Gg: ATEYQzwgSjX4y2qQ4fjB2haRy7RK7peMwQz7YNvW6wZbrJq3MYu9usopMjiCH4BgaHP g5hALMv+p66qLddICxbNPxgDrmQRKbqXArq5noxbMOPevbDTvBYKhYUU9fbGeT2/UjErmJ0PzJm 80pWVfoaGhbdOI/kERax7HpiTI98h7sbNcXXTTVy64xMZEucDrJbnVYWj1OI2fsdKoXGeG7DED6 CDyuTKPGfOhdnOQkXXBTPoN47l2ySOf1HsETwdao4gyFLiil4QHsgJZoBSjl0AqOoibd/vb9SAU k3RIGpvOTwm81DUs9aVJ X-Received: by 2002:a05:6830:610f:b0:7c7:60aa:6496 with SMTP id 46e09a7af769-7d6c7f5e473mr761637a34.4.1772616815653; Wed, 04 Mar 2026 01:33:35 -0800 (PST) MIME-Version: 1.0 References: <2df5912f-8888-4f27-9384-4c69ba22105c@gmail.com> <0dd7bed2-2a1d-4a12-bddf-e00013744eab@gmail.com> In-Reply-To: <0dd7bed2-2a1d-4a12-bddf-e00013744eab@gmail.com> From: Richard Guo Date: Wed, 4 Mar 2026 18:33:24 +0900 X-Gm-Features: AaiRm51RwXg3vxwmMSDaBw_3Fy0mFxgS8-C2C8SfFt8KWW8ylzekQu8XbzX5l9g Message-ID: Subject: Re: Convert NOT IN sublinks to anti-joins when safe To: David Geier Cc: Pg Hackers Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On Mon, Mar 2, 2026 at 9:50=E2=80=AFPM David Geier wr= ote: > The very last rewrite combines both cases. The rewritten query then > looks like: > > SELECT t1.c1 FROM T1 WHERE > t1.c1 IS NOT NULL AND > NOT EXISTS (SELECT 1 FROM t2 WHERE t1.c1 =3D t2.c1) AND > NOT EXISTS (SELECT 1 FROM t2 WHERE t2.c1 IS NULL) I'm still not convinced this rewrite is correct. As I mentioned earlier, it breaks down if t2 is empty while t1 contains NULL rows. For example: CREATE TABLE t1 (c1 int); CREATE TABLE t2 (c1 int); INSERT INTO t1 VALUES (1), (NULL); SELECT t1.c1 FROM t1 WHERE t1.c1 NOT IN (SELECT t2.c1 FROM t2); c1 ---- 1 (2 rows) SELECT t1.c1 FROM T1 WHERE t1.c1 IS NOT NULL AND NOT EXISTS (SELECT 1 FROM t2 WHERE t1.c1 =3D t2.c1) AND NOT EXISTS (SELECT 1 FROM t2 WHERE t2.c1 IS NULL); c1 ---- 1 (1 row) > Seems reasonable to start with the non-NULL variant, though there are > certainly cases where there's no PK / unique index on the relevant column= s. Yeah. I don't know how to optimize nullable NOT IN clauses. It seems quite difficult to handle safely purely via query transformations. Maybe we can explore adding a dedicated Null-Aware Anti-Join execution node, much like Oracle's approach. But that is definitely beyond the scope of this current patch. - Richard