11<!--
2- $PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.300 2005/12/21 23:22:55 momjian Exp $
2+ $PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.301 2005/12/28 01:29:58 tgl Exp $
33PostgreSQL documentation
44-->
55
@@ -350,18 +350,18 @@ PostgreSQL documentation
350350 </indexterm>
351351 The ordinary comparison operators yield null (signifying <quote>unknown</>)
352352 when either input is null. Another way to do comparisons is with the
353- <literal>IS DISTINCT FROM</literal> construct:
353+ <literal>IS<optional> NOT </> DISTINCT FROM</literal> construct:
354354<synopsis>
355355<replaceable>expression</replaceable> IS DISTINCT FROM <replaceable>expression</replaceable>
356356<replaceable>expression</replaceable> IS NOT DISTINCT FROM <replaceable>expression</replaceable>
357357</synopsis>
358- For non-null inputs, <literal>IS DISTINCT FROM</literal>this is
358+ For non-null inputs, <literal>IS DISTINCT FROM</literal> is
359359 the same as the <literal><></> operator. However, when both
360360 inputs are null it will return false, and when just one input is
361361 null it will return true. Similarly, <literal>IS NOT DISTINCT
362362 FROM</literal> is identical to <literal>=</literal> for non-null
363- inputs, returns true when both inputs are null, and false
364- otherwise . Thus, these constructs effectively act as though null
363+ inputs,but it returns true when both inputs are null, and false when only
364+ one input is null . Thus, these constructs effectively act as though null
365365 were a normal data value, rather than <quote>unknown</>.
366366 </para>
367367
@@ -7999,8 +7999,8 @@ SELECT col1 FROM tab1
79997999 equal if all their corresponding members are non-null and equal; the rows
80008000 are unequal if any corresponding members are non-null and unequal;
80018001 otherwise the result of that row comparison is unknown (null).
8002- If all the row results are either unequal or null, with at least one null,
8003- then the result of <token>IN</token> is null.
8002+ If all theper- row results are either unequal or null, with at least one
8003+ null, then the result of <token>IN</token> is null.
80048004 </para>
80058005 </sect2>
80068006
@@ -8055,8 +8055,8 @@ SELECT col1 FROM tab1
80558055 equal if all their corresponding members are non-null and equal; the rows
80568056 are unequal if any corresponding members are non-null and unequal;
80578057 otherwise the result of that row comparison is unknown (null).
8058- If all the row results are either unequal or null, with at least one null,
8059- then the result of <token>NOT IN</token> is null.
8058+ If all theper- row results are either unequal or null, with at least one
8059+ null, then the result of <token>NOT IN</token> is null.
80608060 </para>
80618061 </sect2>
80628062
@@ -8109,23 +8109,19 @@ SELECT col1 FROM tab1
81098109 subquery, which must return exactly as many columns as there are
81108110 expressions in the left-hand row. The left-hand expressions are
81118111 evaluated and compared row-wise to each row of the subquery result,
8112- using the given <replaceable>operator</replaceable>. Presently,
8113- only <literal>=</literal> and <literal><></literal> operators are allowed
8114- in row-wise <token>ANY</token> constructs.
8115- The result of <token>ANY</token> is <quote>true</> if any equal or unequal row is
8116- found, respectively.
8117- The result is <quote>false</> if no such row is found (including the special
8118- case where the subquery returns no rows).
8112+ using the given <replaceable>operator</replaceable>.
8113+ The result of <token>ANY</token> is <quote>true</> if the comparison
8114+ returns true for any subquery row.
8115+ The result is <quote>false</> if the comparison returns false for every
8116+ subquery row (including the special case where the subquery returns no
8117+ rows).
8118+ The result is NULL if the comparison does not return true for any row,
8119+ and it returns NULL for at least one row.
81198120 </para>
81208121
81218122 <para>
8122- As usual, null values in the rows are combined per
8123- the normal rules of SQL Boolean expressions. Two rows are considered
8124- equal if all their corresponding members are non-null and equal; the rows
8125- are unequal if any corresponding members are non-null and unequal;
8126- otherwise the result of that row comparison is unknown (null).
8127- If there is at least one null row result, then the result of <token>ANY</token>
8128- cannot be false; it will be true or null.
8123+ See <xref linkend="row-wise-comparison"> for details about the meaning
8124+ of a row-wise comparison.
81298125 </para>
81308126 </sect2>
81318127
@@ -8145,20 +8141,14 @@ SELECT col1 FROM tab1
81458141 The result of <token>ALL</token> is <quote>true</> if all rows yield true
81468142 (including the special case where the subquery returns no rows).
81478143 The result is <quote>false</> if any false result is found.
8144+ The result is NULL if the comparison does not return false for any row,
8145+ and it returns NULL for at least one row.
81488146 </para>
81498147
81508148 <para>
81518149 <token>NOT IN</token> is equivalent to <literal><> ALL</literal>.
81528150 </para>
81538151
8154- <para>
8155- Note that if there are no failures but at least one right-hand row yields
8156- null for the operator's result, the result of the <token>ALL</token> construct
8157- will be null, not true.
8158- This is in accordance with SQL's normal rules for Boolean combinations
8159- of null values.
8160- </para>
8161-
81628152 <para>
81638153 As with <token>EXISTS</token>, it's unwise to assume that the subquery will
81648154 be evaluated completely.
@@ -8175,24 +8165,19 @@ SELECT col1 FROM tab1
81758165 subquery, which must return exactly as many columns as there are
81768166 expressions in the left-hand row. The left-hand expressions are
81778167 evaluated and compared row-wise to each row of the subquery result,
8178- using the given <replaceable>operator</replaceable>. Presently,
8179- only <literal>=</literal> and <literal><></literal> operators are allowed
8180- in row-wise <token>ALL</token> queries.
8181- The result of <token>ALL</token> is <quote>true</> if all subquery rows are equal
8182- or unequal, respectively (including the special
8168+ using the given <replaceable>operator</replaceable>.
8169+ The result of <token>ALL</token> is <quote>true</> if the comparison
8170+ returns true for all subquery rows (including the special
81838171 case where the subquery returns no rows).
8184- The result is <quote>false</> if any row is found to be unequal or equal,
8185- respectively.
8172+ The result is <quote>false</> if the comparison returns false for any
8173+ subquery row.
8174+ The result is NULL if the comparison does not return false for any
8175+ subquery row, and it returns NULL for at least one row.
81868176 </para>
81878177
81888178 <para>
8189- As usual, null values in the rows are combined per
8190- the normal rules of SQL Boolean expressions. Two rows are considered
8191- equal if all their corresponding members are non-null and equal; the rows
8192- are unequal if any corresponding members are non-null and unequal;
8193- otherwise the result of that row comparison is unknown (null).
8194- If there is at least one null row result, then the result of <token>ALL</token>
8195- cannot be true; it will be false or null.
8179+ See <xref linkend="row-wise-comparison"> for details about the meaning
8180+ of a row-wise comparison.
81968181 </para>
81978182 </sect2>
81988183
@@ -8216,17 +8201,11 @@ SELECT col1 FROM tab1
82168201 the subquery cannot return more than one row. (If it returns zero rows,
82178202 the result is taken to be null.) The left-hand side is evaluated and
82188203 compared row-wise to the single subquery result row.
8219- Presently, only <literal>=</literal> and <literal><></literal> operators are allowed
8220- in row-wise comparisons.
8221- The result is <quote>true</> if the two rows are equal or unequal, respectively.
82228204 </para>
82238205
82248206 <para>
8225- As usual, null values in the rows are combined per
8226- the normal rules of SQL Boolean expressions. Two rows are considered
8227- equal if all their corresponding members are non-null and equal; the rows
8228- are unequal if any corresponding members are non-null and unequal;
8229- otherwise the result of the row comparison is unknown (null).
8207+ See <xref linkend="row-wise-comparison"> for details about the meaning
8208+ of a row-wise comparison.
82308209 </para>
82318210 </sect2>
82328211 </sect1>
@@ -8255,6 +8234,10 @@ SELECT col1 FROM tab1
82558234 <primary>SOME</primary>
82568235 </indexterm>
82578236
8237+ <indexterm>
8238+ <primary>row-wise comparison</primary>
8239+ </indexterm>
8240+
82588241 <indexterm>
82598242 <primary>comparison</primary>
82608243 <secondary>row-wise</secondary>
@@ -8264,6 +8247,10 @@ SELECT col1 FROM tab1
82648247 <primary>IS DISTINCT FROM</primary>
82658248 </indexterm>
82668249
8250+ <indexterm>
8251+ <primary>IS NOT DISTINCT FROM</primary>
8252+ </indexterm>
8253+
82678254 <indexterm>
82688255 <primary>IS NULL</primary>
82698256 </indexterm>
@@ -8288,7 +8275,7 @@ SELECT col1 FROM tab1
82888275 <title><literal>IN</literal></title>
82898276
82908277<synopsis>
8291- <replaceable>expression</replaceable> IN (<replaceable>value</replaceable><optional>, ...</optional>)
8278+ <replaceable>expression</replaceable> IN (<replaceable>value</replaceable> <optional>, ...</optional>)
82928279</synopsis>
82938280
82948281 <para>
83198306 <title><literal>NOT IN</literal></title>
83208307
83218308<synopsis>
8322- <replaceable>expression</replaceable> NOT IN (<replaceable>value</replaceable><optional>, ...</optional>)
8309+ <replaceable>expression</replaceable> NOT IN (<replaceable>value</replaceable> <optional>, ...</optional>)
83238310</synopsis>
83248311
83258312 <para>
@@ -8425,7 +8412,7 @@ AND
84258412 </para>
84268413 </sect2>
84278414
8428- <sect2>
8415+ <sect2 id="row-wise-comparison" >
84298416 <title>Row-wise Comparison</title>
84308417
84318418<synopsis>
@@ -8436,23 +8423,52 @@ AND
84368423 Each side is a row constructor,
84378424 as described in <xref linkend="sql-syntax-row-constructors">.
84388425 The two row values must have the same number of fields.
8439- Each side is evaluated and they are compared row-wise.
8440- Presently, only <literal>=</literal> and <literal><></literal> operators are allowed
8441- in row-wise comparisons.
8442- The result is <quote>true</> if the two rows are equal or unequal, respectively.
8426+ Each side is evaluated and they are compared row-wise. Row comparisons
8427+ are allowed when the <replaceable>operator</replaceable> is
8428+ <literal>=</>,
8429+ <literal><></>,
8430+ <literal><</>,
8431+ <literal><=</>,
8432+ <literal>></> or
8433+ <literal>>=</>,
8434+ or has semantics similar to one of these. (To be specific, an operator
8435+ can be a row comparison operator if it is a member of a btree operator
8436+ class, or is the negator of the <literal>=</> member of a btree operator
8437+ class.)
84438438 </para>
84448439
84458440 <para>
8446- As usual, null values in the rows are combined per
8447- thenormal rules of SQL Boolean expressions . Two rows are considered
8441+ The <literal>=</> and <literal><></> cases work slightly differently
8442+ from theothers . Two rows are considered
84488443 equal if all their corresponding members are non-null and equal; the rows
84498444 are unequal if any corresponding members are non-null and unequal;
84508445 otherwise the result of the row comparison is unknown (null).
84518446 </para>
84528447
8453- <indexterm>
8454- <primary>IS DISTINCT FROM</primary>
8455- </indexterm>
8448+ <para>
8449+ For the <literal><</>, <literal><=</>, <literal>></> and
8450+ <literal>>=</> cases, the row elements are compared left-to-right,
8451+ stopping as soon as an unequal or null pair of elements is found.
8452+ If either of this pair of elements is null, the result of the
8453+ row comparison is unknown (null); otherwise comparison of this pair
8454+ of elements determines the result. For example,
8455+ <literal>ROW(1,2,NULL) < ROW(1,3,0)</>
8456+ yields true, not null, because the third pair of elements are not
8457+ considered.
8458+ </para>
8459+
8460+ <note>
8461+ <para>
8462+ Prior to <productname>PostgreSQL</productname> 8.2, the
8463+ <literal><</>, <literal><=</>, <literal>></> and <literal>>=</>
8464+ cases were not handled per SQL specification. A comparison like
8465+ <literal>ROW(a,b) < ROW(c,d)</>
8466+ was implemented as
8467+ <literal>a < c AND b < d</>
8468+ whereas the correct behavior is equivalent to
8469+ <literal>a < c OR (a = c AND b < d)</>.
8470+ </para>
8471+ </note>
84568472
84578473<synopsis>
84588474<replaceable>row_constructor</replaceable> IS DISTINCT FROM <replaceable>row_constructor</replaceable>
@@ -8466,6 +8482,18 @@ AND
84668482 be either true or false, never null.
84678483 </para>
84688484
8485+ <synopsis>
8486+ <replaceable>row_constructor</replaceable> IS NOT DISTINCT FROM <replaceable>row_constructor</replaceable>
8487+ </synopsis>
8488+
8489+ <para>
8490+ This construct is similar to a <literal>=</literal> row comparison,
8491+ but it does not yield null for null inputs. Instead, any null value is
8492+ considered unequal to (distinct from) any non-null value, and any two
8493+ nulls are considered equal (not distinct). Thus the result will always
8494+ be either true or false, never null.
8495+ </para>
8496+
84698497<synopsis>
84708498<replaceable>row_constructor</replaceable> IS NULL
84718499<replaceable>row_constructor</replaceable> IS NOT NULL