]> git.ipfire.org Git - thirdparty/postgresql.git/commit
Optimize IS DISTINCT FROM with non-nullable inputs
authorRichard Guo <rguo@postgresql.org>
Tue, 10 Feb 2026 01:17:45 +0000 (10:17 +0900)
committerRichard Guo <rguo@postgresql.org>
Tue, 10 Feb 2026 01:17:45 +0000 (10:17 +0900)
commit0a379612540cc51e54dc1c0cc4b9ef8797d2533c
treecf6778ceaa10be9a7137348643421aa8f8d90a74
parent158408fef8b96907bb14f89654dd2beab27ff030
Optimize IS DISTINCT FROM with non-nullable inputs

The IS DISTINCT FROM construct compares values acting as though NULL
were a normal data value, rather than "unknown".  Semantically, "x IS
DISTINCT FROM y" yields true if the values differ or if exactly one is
NULL, and false if they are equal or both NULL.  Unlike ordinary
comparison operators, it never returns NULL.

Previously, the planner only simplified this construct if all inputs
were constants, folding it to a constant boolean result.  This patch
extends the optimization to cases where inputs are non-constant but
proven to be non-nullable.  Specifically, "x IS DISTINCT FROM NULL"
folds to constant TRUE if "x" is known to be non-nullable.  For cases
where both inputs are guaranteed not to be NULL, the expression
becomes semantically equivalent to "x <> y", and the DistinctExpr is
converted into an inequality OpExpr.

This transformation provides several benefits.  It converts the
comparison into a standard operator, allowing the use of partial
indexes and constraint exclusion.  Furthermore, if the clause is
negated (i.e., "IS NOT DISTINCT FROM"), it simplifies to an equality
operator.  This enables the planner to generate better plans using
index scans, merge joins, hash joins, and EC-based qual deduction.

Author: Richard Guo <guofenglinux@gmail.com>
Reviewed-by: Tender Wang <tndrwang@gmail.com>
Discussion: https://postgr.es/m/CAMbWs49BMAOWvkdSHxpUDnniqJcEcGq3_8dd_5wTR4xrQY8urA@mail.gmail.com
contrib/postgres_fdw/expected/postgres_fdw.out
contrib/postgres_fdw/sql/postgres_fdw.sql
src/backend/optimizer/util/clauses.c
src/test/regress/expected/predicate.out
src/test/regress/sql/predicate.sql