Reduce "Var IS [NOT] NULL" quals during constant folding master github/master
authorRichard Guo <rguo@postgresql.org>
Tue, 22 Jul 2025 02:21:36 +0000 (11:21 +0900)
committerRichard Guo <rguo@postgresql.org>
Tue, 22 Jul 2025 02:21:36 +0000 (11:21 +0900)
commite2debb64380ebcf0979708a0fa88d9c8d924005b
tree8f1d25ac2efb78c4512c7c4540f94a8d778b5b63
parent904f6a593a06649f77597ab9a72ef97c21e39a93
Reduce "Var IS [NOT] NULL" quals during constant folding

In commit b262ad440, we introduced an optimization that reduces an IS
[NOT] NULL qual on a NOT NULL column to constant true or constant
false, provided we can prove that the input expression of the NullTest
is not nullable by any outer joins or grouping sets.  This deduction
happens quite late in the planner, during the distribution of quals to
rels in query_planner.  However, this approach has some drawbacks: we
can't perform any further folding with the constant, and it turns out
to be prone to bugs.

Ideally, this deduction should happen during constant folding.
However, the per-relation information about which columns are defined
as NOT NULL is not available at that point.  This information is
currently collected from catalogs when building RelOptInfos for base
or "other" relations.

This patch moves the collection of NOT NULL attribute information for
relations before pull_up_sublinks, storing it in a hash table keyed by
relation OID.  It then uses this information to perform the NullTest
deduction for Vars during constant folding.  This also makes it
possible to leverage this information to pull up NOT IN subqueries.

Note that this patch does not get rid of restriction_is_always_true
and restriction_is_always_false.  Removing them would prevent us from
reducing some IS [NOT] NULL quals that we were previously able to
reduce, because (a) the self-join elimination may introduce new IS NOT
NULL quals after constant folding, and (b) if some outer joins are
converted to inner joins, previously irreducible NullTest quals may
become reducible.

Author: Richard Guo <guofenglinux@gmail.com>
Reviewed-by: Robert Haas <robertmhaas@gmail.com>
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/CAMbWs4-bFJ1At4btk5wqbezdu8PLtQ3zv-aiaY3ry9Ymm=jgFQ@mail.gmail.com
17 files changed:
contrib/postgres_fdw/expected/postgres_fdw.out
contrib/postgres_fdw/sql/postgres_fdw.sql
src/backend/optimizer/plan/initsplan.c
src/backend/optimizer/plan/planner.c
src/backend/optimizer/plan/subselect.c
src/backend/optimizer/prep/prepjointree.c
src/backend/optimizer/util/clauses.c
src/backend/optimizer/util/inherit.c
src/backend/optimizer/util/plancat.c
src/include/nodes/pathnodes.h
src/include/optimizer/optimizer.h
src/include/optimizer/plancat.h
src/test/regress/expected/generated_virtual.out
src/test/regress/expected/join.out
src/test/regress/expected/predicate.out
src/test/regress/sql/predicate.sql
src/tools/pgindent/typedefs.list