Commit be8100d6 authored by Neil Conway's avatar Neil Conway

Implement IS NOT DISTINCT FROM, update the regression tests and docs.

Patch from Pavel Stehule, minor fixups by myself.
parent c1059314
<!-- <!--
$PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.297 2005/12/03 16:45:05 momjian Exp $ $PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.298 2005/12/11 10:54:27 neilc Exp $
PostgreSQL documentation PostgreSQL documentation
--> -->
...@@ -345,16 +345,24 @@ PostgreSQL documentation ...@@ -345,16 +345,24 @@ PostgreSQL documentation
<indexterm> <indexterm>
<primary>IS DISTINCT FROM</primary> <primary>IS DISTINCT FROM</primary>
</indexterm> </indexterm>
<indexterm>
<primary>IS NOT DISTINCT FROM</primary>
</indexterm>
The ordinary comparison operators yield null (signifying <quote>unknown</>) The ordinary comparison operators yield null (signifying <quote>unknown</>)
when either input is null. Another way to do comparisons is with the when either input is null. Another way to do comparisons is with the
<literal>IS DISTINCT FROM</literal> construct: <literal>IS DISTINCT FROM</literal> construct:
<synopsis> <synopsis>
<replaceable>expression</replaceable> IS DISTINCT FROM <replaceable>expression</replaceable> <replaceable>expression</replaceable> IS DISTINCT FROM <replaceable>expression</replaceable>
<replaceable>expression</replaceable> IS NOT DISTINCT FROM <replaceable>expression</replaceable>
</synopsis> </synopsis>
For non-null inputs this is the same as the <literal>&lt;&gt;</> operator. For non-null inputs, <literal>IS DISTINCT FROM</literal> this is
However, when both inputs are null it will return false, and when just the same as the <literal>&lt;&gt;</> operator. However, when both
one input is null it will return true. Thus it effectively acts as though inputs are null it will return false, and when just one input is
null were a normal data value, rather than <quote>unknown</>. null it will return true. Similarly, <literal>IS NOT DISTINCT
FROM</literal> is identical to <literal>=</literal> for non-null
inputs, returns true when both inputs are null, and false
otherwise. Thus, these constructs effectively act as though null
were a normal data value, rather than <quote>unknown</>.
</para> </para>
<para> <para>
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.516 2005/11/28 04:35:31 tgl Exp $ * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.517 2005/12/11 10:54:27 neilc Exp $
* *
* HISTORY * HISTORY
* AUTHOR DATE MAJOR EVENT * AUTHOR DATE MAJOR EVENT
...@@ -6715,6 +6715,13 @@ a_expr: c_expr { $$ = $1; } ...@@ -6715,6 +6715,13 @@ a_expr: c_expr { $$ = $1; }
{ {
$$ = (Node *) makeSimpleA_Expr(AEXPR_DISTINCT, "=", $1, $5); $$ = (Node *) makeSimpleA_Expr(AEXPR_DISTINCT, "=", $1, $5);
} }
| a_expr IS NOT DISTINCT FROM a_expr %prec IS
{
$$ = (Node *) makeA_Expr(AEXPR_NOT, NIL, NULL,
(Node *) makeSimpleA_Expr(AEXPR_DISTINCT,
"=", $1, $6));
}
| a_expr IS OF '(' type_list ')' %prec IS | a_expr IS OF '(' type_list ')' %prec IS
{ {
$$ = (Node *) makeSimpleA_Expr(AEXPR_OF, "=", $1, (Node *) $5); $$ = (Node *) makeSimpleA_Expr(AEXPR_OF, "=", $1, (Node *) $5);
...@@ -6880,6 +6887,11 @@ b_expr: c_expr ...@@ -6880,6 +6887,11 @@ b_expr: c_expr
{ {
$$ = (Node *) makeSimpleA_Expr(AEXPR_DISTINCT, "=", $1, $5); $$ = (Node *) makeSimpleA_Expr(AEXPR_DISTINCT, "=", $1, $5);
} }
| b_expr IS NOT DISTINCT FROM b_expr %prec IS
{
$$ = (Node *) makeA_Expr(AEXPR_NOT, NIL,
NULL, (Node *) makeSimpleA_Expr(AEXPR_DISTINCT, "=", $1, $6));
}
| b_expr IS OF '(' type_list ')' %prec IS | b_expr IS OF '(' type_list ')' %prec IS
{ {
$$ = (Node *) makeSimpleA_Expr(AEXPR_OF, "=", $1, (Node *) $5); $$ = (Node *) makeSimpleA_Expr(AEXPR_OF, "=", $1, (Node *) $5);
......
...@@ -195,3 +195,28 @@ SELECT null IS DISTINCT FROM null as "no"; ...@@ -195,3 +195,28 @@ SELECT null IS DISTINCT FROM null as "no";
f f
(1 row) (1 row)
-- ANSI SQL 2003 form
SELECT 1 IS NOT DISTINCT FROM 2 as "no";
no
----
f
(1 row)
SELECT 2 IS NOT DISTINCT FROM 2 as "yes";
yes
-----
t
(1 row)
SELECT 2 IS NOT DISTINCT FROM null as "no";
no
----
f
(1 row)
SELECT null IS NOT DISTINCT FROM null as "yes";
yes
-----
t
(1 row)
...@@ -56,3 +56,9 @@ SELECT 1 IS DISTINCT FROM 2 as "yes"; ...@@ -56,3 +56,9 @@ SELECT 1 IS DISTINCT FROM 2 as "yes";
SELECT 2 IS DISTINCT FROM 2 as "no"; SELECT 2 IS DISTINCT FROM 2 as "no";
SELECT 2 IS DISTINCT FROM null as "yes"; SELECT 2 IS DISTINCT FROM null as "yes";
SELECT null IS DISTINCT FROM null as "no"; SELECT null IS DISTINCT FROM null as "no";
-- ANSI SQL 2003 form
SELECT 1 IS NOT DISTINCT FROM 2 as "no";
SELECT 2 IS NOT DISTINCT FROM 2 as "yes";
SELECT 2 IS NOT DISTINCT FROM null as "no";
SELECT null IS NOT DISTINCT FROM null as "yes";
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment