Skip to content

Commit b8b1e87

Browse files
committed
Fix PG 17 [NOT] NULL optimization bug for domains
A PG 17 optimization allowed columns with NOT NULL constraints to skip table scans for IS NULL queries, and to skip IS NOT NULL checks for IS NOT NULL queries. This didn't work for domain types, since domain types don't follow the IS NULL/IS NOT NULL constraint logic. To fix, disable this optimization for domains for PG 17+. Reported-by: Jan Behrens Diagnosed-by: Tom Lane Discussion: https://postgr.es/m/Z37p0paENWWUarj-@momjian.us Backpatch-through: 17
1 parent 5cbbe70 commit b8b1e87

File tree

2 files changed

+16
-1
lines changed

2 files changed

+16
-1
lines changed

doc/src/sgml/ref/create_domain.sgml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,8 @@ CREATE TABLE us_snail_addy (
283283
<para>
284284
The syntax <literal>NOT NULL</literal> in this command is a
285285
<productname>PostgreSQL</productname> extension. (A standard-conforming
286-
way to write the same would be <literal>CHECK (VALUE IS NOT
286+
way to write the same for non-composite data types would be
287+
<literal>CHECK (VALUE IS NOT
287288
NULL)</literal>. However, per <xref linkend="sql-createdomain-notes"/>,
288289
such constraints are best avoided in practice anyway.) The
289290
<literal>NULL</literal> <quote>constraint</quote> is a

src/backend/optimizer/plan/initsplan.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2758,6 +2758,13 @@ restriction_is_always_true(PlannerInfo *root,
27582758
if (nulltest->nulltesttype != IS_NOT_NULL)
27592759
return false;
27602760

2761+
/*
2762+
* Empty rows can appear NULL in some contexts and NOT NULL in others,
2763+
* so avoid this optimization for row expressions.
2764+
*/
2765+
if (nulltest->argisrow)
2766+
return false;
2767+
27612768
return expr_is_nonnullable(root, nulltest->arg);
27622769
}
27632770

@@ -2816,6 +2823,13 @@ restriction_is_always_false(PlannerInfo *root,
28162823
if (nulltest->nulltesttype != IS_NULL)
28172824
return false;
28182825

2826+
/*
2827+
* Empty rows can appear NULL in some contexts and NOT NULL in others,
2828+
* so avoid this optimization for row expressions.
2829+
*/
2830+
if (nulltest->argisrow)
2831+
return false;
2832+
28192833
return expr_is_nonnullable(root, nulltest->arg);
28202834
}
28212835

0 commit comments

Comments
 (0)