On Wed, Jan 8, 2025 at 04:24:34PM -0500, Tom Lane wrote: > Bruce Momjian <br...@momjian.us> writes: > > I think this needs some serious research. > > We've discussed this topic before. The spec's definition of IS [NOT] > NULL for composite values is bizarre to say the least. I think > there's been an intentional choice to keep most NOT NULL checks > "simple", that is we look at the overall value's isnull bit and > don't probe any deeper than that. > > If the optimizations added in v17 changed existing behavior, > I agree that's bad. We should probably fix it so that those > are only applied when argisrow is false.
I have developed the attached patch using your argisrow suggestion which fixes the test I posted. Is this something we should backpatch? -- Bruce Momjian <br...@momjian.us> https://momjian.us EDB https://enterprisedb.com Do not let urgent matters crowd out time for investment in the future.
diff --git a/doc/src/sgml/ref/create_domain.sgml b/doc/src/sgml/ref/create_domain.sgml index ce555203486..c111285a69c 100644 --- a/doc/src/sgml/ref/create_domain.sgml +++ b/doc/src/sgml/ref/create_domain.sgml @@ -283,7 +283,8 @@ CREATE TABLE us_snail_addy ( <para> The syntax <literal>NOT NULL</literal> in this command is a <productname>PostgreSQL</productname> extension. (A standard-conforming - way to write the same would be <literal>CHECK (VALUE IS NOT + way to write the same for non-composite data types would be + <literal>CHECK (VALUE IS NOT NULL)</literal>. However, per <xref linkend="sql-createdomain-notes"/>, such constraints are best avoided in practice anyway.) The <literal>NULL</literal> <quote>constraint</quote> is a diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index 2cb0ae6d659..e291547112d 100644 --- a/src/backend/optimizer/plan/initsplan.c +++ b/src/backend/optimizer/plan/initsplan.c @@ -3100,6 +3100,13 @@ restriction_is_always_true(PlannerInfo *root, if (nulltest->nulltesttype != IS_NOT_NULL) return false; + /* + * Empty rows can appear NULL in some contexts and NOT NULL in others, + * so avoid this optimization for row expressions. + */ + if (nulltest->argisrow) + return false; + return expr_is_nonnullable(root, nulltest->arg); } @@ -3149,6 +3156,13 @@ restriction_is_always_false(PlannerInfo *root, if (nulltest->nulltesttype != IS_NULL) return false; + /* + * Empty rows can appear NULL in some contexts and NOT NULL in others, + * so avoid this optimization for row expressions. + */ + if (nulltest->argisrow) + return false; + return expr_is_nonnullable(root, nulltest->arg); }