Skip to content

Commit 46b4ba5

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 039549d commit 46b4ba5

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
@@ -3109,6 +3109,13 @@ restriction_is_always_true(PlannerInfo *root,
31093109
if (nulltest->nulltesttype != IS_NOT_NULL)
31103110
return false;
31113111

3112+
/*
3113+
* Empty rows can appear NULL in some contexts and NOT NULL in others,
3114+
* so avoid this optimization for row expressions.
3115+
*/
3116+
if (nulltest->argisrow)
3117+
return false;
3118+
31123119
return expr_is_nonnullable(root, nulltest->arg);
31133120
}
31143121

@@ -3167,6 +3174,13 @@ restriction_is_always_false(PlannerInfo *root,
31673174
if (nulltest->nulltesttype != IS_NULL)
31683175
return false;
31693176

3177+
/*
3178+
* Empty rows can appear NULL in some contexts and NOT NULL in others,
3179+
* so avoid this optimization for row expressions.
3180+
*/
3181+
if (nulltest->argisrow)
3182+
return false;
3183+
31703184
return expr_is_nonnullable(root, nulltest->arg);
31713185
}
31723186

0 commit comments

Comments
 (0)