Re: Document NULL

From: Chao Li <li(dot)evan(dot)chao(at)gmail(dot)com>
To: Álvaro Herrera <alvherre(at)kurilemu(dot)de>
Cc: "David G(dot) Johnston" <david(dot)g(dot)johnston(at)gmail(dot)com>, jian he <jian(dot)universality(at)gmail(dot)com>, Jeff Davis <pgsql(at)j-davis(dot)com>, Yugo NAGATA <nagata(at)sraoss(dot)co(dot)jp>, Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>, Peter Eisentraut <peter(at)eisentraut(dot)org>, David Rowley <dgrowleyml(at)gmail(dot)com>, PostgreSQL Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org>, Marcos Pegoraro <marcos(at)f10(dot)com(dot)br>
Subject: Re: Document NULL
Date: 2025-11-14 06:51:22
Message-ID: F3FA26F6-9C35-4F9D-983E-6F653D11E437@gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

> On Nov 11, 2025, at 23:34, Álvaro Herrera <alvherre(at)kurilemu(dot)de> wrote:
>
> On 2025-Jun-18, David G. Johnston wrote:
>
>> Version 8.
>>
>> Marking this Ready to Commit in CF 2025-09 (CF PG19-1)
>
> I have rebased this; here's v9. I haven't reviewed it in depth, but
> intend to give it a read and get it pushed sometime in the
> not-too-distant future, so if anybody wants to review it some more, it'd
> be appreciated.

I just reviewed this patch and got some comments:

>
> Note that this rebase was across the func.sgml split, which means I had
> to do some "manual" merging. Looking at the git diff --stat output, it
> seems to match what was there before, so I don't think anything was
> lost.
>
> --
> Álvaro Herrera Breisgau, Deutschland — https://www.EnterpriseDB.com/
> "Linux transformó mi computadora, de una `máquina para hacer cosas',
> en un aparato realmente entretenido, sobre el cual cada día aprendo
> algo nuevo" (Jaime Salinas)
> <v9-0001-doc-Add-an-overview-of-NULL-treatment-in-PostgreS.patch>

1 - func-comparsions.sgml
```
+ tests are AND'd together. Note that <literal>IS DISTINCT FROM</literal> is not an operator.
```

The “note that” sentence is not clear. I believe you meant to say the “IS DISTINCT FROM” cannot generate null values because it is not an operator. But one thing being not an operator doesn’t mean it cannot generate null value, right? So I think we’d be explicit, I am suggesting:

"Note that, IS DISTINCT FROM does not produce null results — it always returns true or false."

This comment applies to 2 occurrences.

2 - func-comparsions.sgml
```
+ Each side is evaluated and they are compared row-wise.
+ As discussed and shown in <xref linkend="nullvalues-multielementcomparison-composite"/>,
+ null values are treated as being equal to other null values and greater
+ than all non-null values.
+ Composite type
comparisons are allowed when the <replaceable>operator</replaceable> is
```

The “composite type” line is too short, consider move the next line up.

3 - func-comparsions.sgml
```
<para>
- If the array expression yields a null array, the result of
- <token>ANY</token> will be null. If the left-hand expression yields null,
- the result of <token>ANY</token> is ordinarily null (though a non-strict
- comparison operator could possibly yield a different result).
- Also, if the right-hand array contains any null elements and no true
- comparison result is obtained, the result of <token>ANY</token>
- will be null, not false (again, assuming a strict comparison operator).
- This is in accordance with SQL's normal rules for Boolean combinations
- of null values.
+ If <replaceable>operator</replaceable> can produce null valued booleans then, as explained in
+ <xref linkend="nullvalues-multielement"/>, it is not possible to see
+ a <quote>false</quote> result in the presence of both elements and null values since the multiple equality
+ tests are AND'd together. Note that <literal>IS DISTINCT FROM</literal> is not an operator.
</para>
```

For ANY, it should be “OR’d”.

4 - func-subquery.sgml
```
<para>
The right-hand side is a parenthesized
- subquery, which must return exactly one column. The left-hand expression
+ subquery, which must return exactly one column. The result of <token>IN</token>
+ is <quote>false</quote> if the subquery returns no rows, otherwise the left-hand expression
is evaluated and compared to each row of the subquery result.
- The result of <token>IN</token> is <quote>true</quote> if any equal subquery row is found.
- The result is <quote>false</quote> if no equal row is found (including the
- case where the subquery returns no rows).
+ The result is <quote>true</quote> if any equal subquery row is found.
+ The result is <quote>false</quote> if no equal row is found.
</para>

<para>
- Note that if the left-hand expression yields null, or if there are
- no equal right-hand values and at least one right-hand row yields
- null, the result of the <token>IN</token> construct will be null, not false.
- This is in accordance with SQL's normal rules for Boolean combinations
- of null values.
+ As explained in <xref linkend="nullvalues-multielement"/>, it is not possible to see
+ a <quote>false</quote> result in the presence of both rows and null values since the multiple equality
+ tests are AND'd together.
</para>
```

IN should be ORed.

5 - func-subquery.sgml
```
<para>
- The right-hand side is a parenthesized
- subquery, which must return exactly one column. The left-hand expression
- is evaluated and compared to each row of the subquery result.
- The result of <token>NOT IN</token> is <quote>true</quote> if only unequal subquery rows
- are found (including the case where the subquery returns no rows).
+ The right-hand side is a parenthesized subquery, which must return exactly one column.
+ The result of <token>NOT IN</token> is <quote>true</quote> if the subquery returns no rows,
+ otherwise the left-hand expression is evaluated and compared to each row of the subquery result.
+ The result is <quote>true</quote> if only unequal subquery rows are found.
The result is <quote>false</quote> if any equal row is found.
</para>

<para>
- Note that if the left-hand expression yields null, or if there are
- no equal right-hand values and at least one right-hand row yields
- null, the result of the <token>NOT IN</token> construct will be null, not true.
- This is in accordance with SQL's normal rules for Boolean combinations
- of null values.
+ As explained in <xref linkend="nullvalues-multielement"/>, it is not possible to see
+ a <quote>true</quote> result in the presence of both rows and null values since the multiple inequality
+ tests are OR'd together.
</para>
```

NOT IN should be ANDed.

6 - func-subquery.sgml
```
- The result of <token>ANY</token> is <quote>true</quote> if any true result is obtained.
- The result is <quote>false</quote> if no true result is found (including the
- case where the subquery returns no rows).
+ The result is <quote>true</quote> if any true result is obtained.
+ The result is <quote>false</quote> if no true result is found.
</para>

<para>
@@ -223,11 +213,10 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2);
</para>

<para>
- Note that if there are no successes and at least one right-hand row yields
- null for the operator's result, the result of the <token>ANY</token> construct
- will be null, not false.
- This is in accordance with SQL's normal rules for Boolean combinations
- of null values.
+ If <replaceable>operator</replaceable> can produce null valued booleans then, as explained in
+ <xref linkend="nullvalues-multielement"/>, it is not possible to see
+ a <quote>false</quote> result in the presence of both rows and null values since the multiple equality
+ tests are AND'd together. Note that <literal>IS DISTINCT FROM</literal> is not an operator.
</para>
```

ANY should be OR-ed

7 - func-subquery.sgml
```
+ Note that <literal>IS DISTINCT FROM</literal> is not an operator.
```

Same as 1.

8 - nullvalues.sgml
```
+ to any other value (e.g., <literal>IS DISTINCT</literal>, and <literal>IS TRUE</literal>.)
```

Should “IS DISTINCT” be “IS DISTINCT FROM”?

9 - nullvalues.sgml
```
+ all non-null valueS.
```

Nit typo. Should be small “s".

Best regards,
--
Chao Li (Evan)
HighGo Software Co., Ltd.
https://www.highgo.com/

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Chao Li 2025-11-14 07:03:15 Re: [PATCH] Add pg_get_database_ddl() function to reconstruct CREATE DATABASE statement
Previous Message Michael Paquier 2025-11-14 06:44:50 Re: [Patch] Windows relation extension failure at 2GB and 4GB