<literal><></literal> operator. However, if both
inputs are null it returns false, and if only one input is
null it returns true. Similarly, <literal>IS NOT DISTINCT
FROM</literal> is identical to <literal>=</literal> for non-null
inputs, but it returns true when both inputs are null, and false when only
one input is null. Thus, these predicates effectively act as though null
were a normal data value, rather than <quote>unknown</quote>.
</para>
<para>
<indexterm>
<primary>IS NULL</primary>
</indexterm>
<indexterm>
<primary>IS NOT NULL</primary>
</indexterm>
<indexterm>
<primary>ISNULL</primary>
</indexterm>
<indexterm>
<primary>NOTNULL</primary>
</indexterm>
To check whether a value is or is not null, use the predicates:
<synopsis>
<replaceable>expression</replaceable> IS NULL
<replaceable>expression</replaceable> IS NOT NULL
</synopsis>
or the equivalent, but nonstandard, predicates:
<synopsis>
<replaceable>expression</replaceable> ISNULL
<replaceable>expression</replaceable> NOTNULL
</synopsis>
<indexterm><primary>null value</primary><secondary>comparing</secondary></indexterm>
</para>
<para>
Do <emphasis>not</emphasis> write
<literal><replaceable>expression</replaceable> = NULL</literal>
because <literal>NULL</literal> is not <quote>equal to</quote>
<literal>NULL</literal>. (The null value represents an unknown value,
and it is not known whether two unknown values are equal.)
</para>
<tip>
<para>
Some applications might expect that
<literal><replaceable>expression</replaceable> = NULL</literal>
returns true if <replaceable>expression</replaceable> evaluates to
the null value. It is highly recommended that these applications
be modified to comply with the SQL standard. However, if that
cannot be done the <xref linkend="guc-transform-null-equals"/>
configuration variable is available. If it is enabled,
<productname>PostgreSQL</productname> will convert <literal>x =
NULL</literal> clauses to <literal>x IS NULL</literal>.
</para>
</tip>
<para>
If the <replaceable>expression</replaceable> is row-valued, then
<literal>IS NULL</literal> is true when the row expression itself is null
or when all the row's fields are null, while
<literal>IS NOT NULL</literal> is true when the row expression itself is non-null
and all the row's fields are non-null. Because of this behavior,
<literal>IS NULL</literal> and <literal>IS NOT NULL</literal> do not always return
inverse results for row-valued expressions; in particular, a row-valued
expression that contains both null and non-null fields will return false
for both tests. For example:
<programlisting>
SELECT ROW(1,2.5,'this is a test') = ROW(1, 3, 'not the same');
SELECT ROW(table.*) IS NULL FROM table; -- detect all-null rows
SELECT ROW(table.*) IS NOT NULL FROM table; -- detect all-non-null rows
SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in rows
</programlisting>
In some cases, it may be preferable to
write <replaceable>row</replaceable> <literal>IS DISTINCT FROM NULL</literal>
or <replaceable>row</replaceable> <literal>IS NOT DISTINCT FROM NULL</literal>,
which will simply check whether the overall row value is null without any
additional tests on the row fields.
</para>
<para>
<indexterm>
<primary>IS TRUE</primary>
</indexterm>
<indexterm>
<primary>IS NOT TRUE</primary>
</indexterm>
<indexterm>
<primary>IS FALSE</primary>
</indexterm>
<indexterm>
<primary>IS NOT FALSE</primary>
</indexterm>
<indexterm>
<primary>IS UNKNOWN</primary>
</indexterm>
<indexterm>
<primary>IS NOT UNKNOWN</primary>
</indexterm>
Boolean values can also be tested using the predicates
<synopsis>
<replaceable>boolean_expression</replaceable> IS TRUE
<replaceable>boolean_expression</replaceable>