From 76775013947d9345b4754e33d9b807845f86546f Mon Sep 17 00:00:00 2001 From: Ilia Evdokimov Date: Fri, 20 Feb 2026 12:03:10 +0300 Subject: [PATCH v2] Reduce planning time for large NOT IN lists containing NULL For x <> ALL (...) / x NOT IN (...), the presence of a NULL element makes the selectivity 0.0. The planner currently still iterates over all elements and computes per-element selectivity, even though the final result is known. Add an early NULL check for constant arrays and immediately return 0.0 under ALL semantics. This reduces planning time for large NOT IN / <> ALL lists without changing semantics. --- src/backend/utils/adt/selfuncs.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c index 29fec655593..9770656f125 100644 --- a/src/backend/utils/adt/selfuncs.c +++ b/src/backend/utils/adt/selfuncs.c @@ -2025,6 +2025,10 @@ scalararraysel(PlannerInfo *root, elmlen, elmbyval, elmalign, &elem_values, &elem_nulls, &num_elems); + /* Selectivity of "WHERE x NOT IN (NULL, ... )" is always 0 "*/ + if (!useOr && ARR_HASNULL(arrayval)) + return (Selectivity) 0.0; + /* * For generic operators, we assume the probability of success is * independent for each array element. But for "= ANY" or "<> ALL", @@ -2115,6 +2119,9 @@ scalararraysel(PlannerInfo *root, List *args; Selectivity s2; + /* Selectivity of "WHERE x NOT IN (NULL, ... )" is always 0 "*/ + if (!useOr && IsA(elem, Const) && ((Const *) elem)->constisnull) + return (Selectivity) 0.0; /* * Theoretically, if elem isn't of nominal_element_type we should * insert a RelabelType, but it seems unlikely that any operator -- 2.34.1