Re: Fold NOT IN / <> ALL expressions containing NULL to FALSE

From: Rustam ALLAKOV <rustamallakov(at)gmail(dot)com>
To: pgsql-hackers(at)lists(dot)postgresql(dot)org
Cc: Ilia Evdokimov <ilya(dot)evdokimov(at)tantorlabs(dot)com>
Subject: Re: Fold NOT IN / <> ALL expressions containing NULL to FALSE
Date: 2026-09-13 16:12:38
Message-ID: 178931595876.1175.14939651707100946419.pgcf@coridan.postgresql.org
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

The following review has been posted through the commitfest application:
make installcheck-world: tested, passed
Implements feature: tested, failed
Spec compliant: tested, passed
Documentation: tested, passed

Hi Ilia,

Denis Smirnov and I reviewed v2 and found these issues:

1. Multidimensional arrays

CREATE TEMP TABLE mda (a int[]);
INSERT INTO mda VALUES (NULL::int[]);
SELECT * FROM mda WHERE 1 <> ALL (ARRAY[NULL::int[], a]);

master: 1 row
v2: 0 rows

2. ON CONFLICT with a partial index

CREATE TEMP TABLE t (a int, b int);
CREATE UNIQUE INDEX ti ON t (a) WHERE b <> ALL (ARRAY[1, NULL]);
INSERT INTO t VALUES (1, 5)
ON CONFLICT (a) WHERE b <> ALL (ARRAY[1, NULL]) DO NOTHING;

master: succeeds
v2: ERROR: there is no unique or exclusion constraint matching
the ON CONFLICT specification

3. No folding under AND/OR

CREATE TEMP TABLE s (x int);

-- Plans with v2:
EXPLAIN (COSTS OFF) SELECT * FROM s
WHERE x NOT IN (42, NULL); -- One-Time Filter: false
EXPLAIN (COSTS OFF) SELECT * FROM s
WHERE x NOT IN (42, NULL) AND x = 1; -- Seq Scan
EXPLAIN (COSTS OFF) SELECT * FROM s
WHERE x NOT IN (42, NULL) OR false; -- Seq Scan

Perhaps this could be handled in canonicalize_qual().

Regards,
--
Rustam Allakov
Denis Smirnov

The new status of this patch is: Waiting on Author

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Oleg Bartunov 2026-09-13 16:22:27 Re: Support for 8-byte TOAST values, round two
Previous Message 신성준 2026-09-13 15:50:43 Re: Add wait events for server logging destination writes