Thread: Is NULL equal to NULL or not?

Is NULL equal to NULL or not?

From
jco@cornelius-olsen.dk
Date:

Hi,

My first message on this list:

Using PostgreSQL 7.1.3.

I've noticed that
        select NULL=NULL;
yields TRUE. It is also possible to select rows in this manner.

At the same time in PL/pgSQL:

        > drop function demo1();
        create function demo1() returns boolean as '
        declare
          a boolean:=NULL;
          b boolean:=NULL;
        begin
          return a=b;
        end;
        ' language 'plpgsql';

        > select demo1();
yields NULL. Yet if I'd written "return NULL=NULL" I would have gotten the same result as in the simple query;

Is there any logical explanation for this inconsistency? ... or should I have been posting a bug? :-)

Regards
/Jørn Cornelius Olsen

Re: Is NULL equal to NULL or not?

From
Mike Mascari
Date:
jco@cornelius-olsen.dk wrote:
>
> Hi,
>
> My first message on this list:
>
> Using PostgreSQL 7.1.3.
>
> I've noticed that
>         select NULL=NULL;
> yields TRUE. It is also possible to select rows in this manner.

Not generally since 7.2:

http://www.us.postgresql.org/users-lounge/docs/7.3/postgres/release-7-2.html

"In this release, comparisons using = NULL will always return
false (or NULL, more precisely). Previous releases automatically
transformed this syntax to IS NULL. The old behavior can be
re-enabled using a postgresql.conf parameter."

> At the same time in PL/pgSQL:
>
> drop function demo1();
> create function demo1() returns boolean as '
> declare
>  a boolean:=NULL;
>  b boolean:=NULL;
> begin
>  return a=b;
> end;
> ' language 'plpgsql';

Not sure why that is. Different sub-parsing paths, perhaps?
However, the default has changed since the old days (7.1). The
hack was in place because ancient versions of Access (re: Access
95) used to call into the ODBC driver with parameters which
resulted in PostgreSQL getting queried with:

SELECT
...
WHERE field = NULL;

That behavior changed in Microsoft products a long time ago, so
the PostgreSQL behavior now mirrors the SQL standard. So from
this point forward, I'd code using IS NULL for NULL comparisons.
And I'd upgrade... ;-)

Hope that helps,

Mike Mascari

P.S.: NULLs are evil.







Re: Is NULL equal to NULL or not?

From
"scott.marlowe"
Date:
On Mon, 9 Dec 2002 jco@cornelius-olsen.dk wrote:

> Hi,
>
> My first message on this list:
>
> Using PostgreSQL 7.1.3.

Stop.  Upgrade right now.  You're asking questions about a version of
postgresql that is quite old now.  I'm not sure I remember using 7.1.3,
but since I started out with 6.5.2, I'm sure I must have.  But it's been a
long long long time since I've used either, and I certainly don't have a
test box laying around running it.  So I can't test anything on my end to
see how it works.

However, on 7.3, select 1 where null=null; gets me a 0 output.  Same goes
for 7.2.3.

> I've noticed that
>         select NULL=NULL;
> yields TRUE. It is also possible to select rows in this manner.

That's NOT because null EQUALS null, but because it allowed you to assign
one null value to another.  which technically can be done, so it came out
true.

> At the same time in PL/pgSQL:
>
>         > drop function demo1();
>         create function demo1() returns boolean as '
>         declare
>           a boolean:=NULL;
>           b boolean:=NULL;
>         begin
>           return a=b;
>         end;
>         ' language 'plpgsql';
>
>         > select demo1();
> yields NULL. Yet if I'd written "return NULL=NULL" I would have gotten the
> same result as in the simple query;

Try a line like this:

return a is null;

and see what you get.  Use the verb is, not the = sign to compared nulls.
NOT is to decide it not null.



Re: Is NULL equal to NULL or not?

From
Mike Mascari
Date:
scott.marlowe wrote:
> On Mon, 9 Dec 2002 jco@cornelius-olsen.dk wrote:

>>I've noticed that
>>        select NULL=NULL;
>>yields TRUE. It is also possible to select rows in this manner.
>
>
> That's NOT because null EQUALS null, but because it allowed you to assign
> one null value to another.  which technically can be done, so it came out
> true.

It *is* because null EQUALS null, on version 7.1. '=' is the
comparison operator. ':=' is the PL/pgSQL assignment operator.
Older versions of PostgreSQL allowed comparisons between NULLs
for compatibility with older versions of Access.

Mike Mascari



Re: Is NULL equal to NULL or not?

From
Rich Shepard
Date:
On Mon, 9 Dec 2002, scott.marlowe wrote:

> > I've noticed that
> >         select NULL=NULL;
> > yields TRUE. It is also possible to select rows in this manner.
>
> That's NOT because null EQUALS null, but because it allowed you to assign
> one null value to another.  which technically can be done, so it came out
> true.

  This is a common misuderstanding. NULL means indeterminant, not zero or
missing. Since NULL is and unknown value there's no way to compare it with
another unknown value. You are absolutely correct in that the syntax 'are
both values unknown' equates to NULL is NULL while there is no meaning to
NULL=NULL.

Rich

Dr. Richard B. Shepard, President

                       Applied Ecosystem Services, Inc. (TM)
            2404 SW 22nd Street | Troutdale, OR 97060-1247 | U.S.A.
 + 1 503-667-4517 (voice) | + 1 503-667-8863 (fax) | rshepard@appl-ecosys.com
                         http://www.appl-ecosys.com/


Re: Is NULL equal to NULL or not?

From
Tom Lane
Date:
Mike Mascari <mascarm@mascari.com> writes:
>> On Mon, 9 Dec 2002 jco@cornelius-olsen.dk wrote:
>>> I've noticed that
>>> select NULL=NULL;
>>> yields TRUE. It is also possible to select rows in this manner.
>>
>> That's NOT because null EQUALS null, but because it allowed you to assign
>> one null value to another.  which technically can be done, so it came out
>> true.

> It *is* because null EQUALS null, on version 7.1. '=' is the
> comparison operator.

Not quite ... thanks for playing.

NULL has never equaled NULL, in any version of PG AFAICT --- the
comparison operator would always yield NULL if either input was NULL.
That behavior is per SQL spec.

Beginning in release 6.5 there was a special kluge for Access
compatibility, originally this two-line patch:

1999-03-14 00:14  momjian

    * src/backend/parser/: gram.c, gram.y: I have a problem with
    Access97 not working properly when entering new records using a sub
    form, i.e. entering a new order/orderlines or master and detail
    tables.  The problem is caused by a SQL statement that Access97
    makes involving NULL.  The syntax that fails is "column_name" =
    NULL.  The following attachment was provided by -Jose'-.  It
    contains a very small enhancement to gram.y that will allow
    Access97 to work properly with sub forms.  Can this enhancement be
    added to release 6.5?

     <<gram.patch>>
    Thanks, Michael

which basically hacked the parser so that the syntax

    expression = NULL

would be treated as

    expression IS NULL

But note that this is a *parse time* transformation, and would only
fire when the right-hand operand of '=' is the literal keyword NULL.
(Thus, it does not fire in jco's plpgsql example, where the operands
are both plpgsql variables.)

This should never have been made the default behavior IMHO, and
certainly not the sole behavior, because it blatantly broke SQL
compatibility, not to mention violating any usable concept of what
NULL means.  As of 7.2 it's a disabled-by-default option, which is
the way it should have been handled to begin with (though I suppose
the lack of a flexible runtime-parameter-configuration mechanism
back then might have had something to do with the original decision).
But 6.5, 7.0, and 7.1 lasted long enough to allow a lot of people to
become confused :-(

NULL is not "=" to NULL.  It is not "<>" NULL, either.  It's off in
its own little universe.  Except for a very small number of special
syntaxes like "x IS NULL" and "x IS NOT NULL", any standard SQL
operation applied to one or more NULL inputs will yield a NULL output.
In particular equality comparison will yield NULL.

(It may help you to realize that "IS" is not a kind of equals operator
here --- rather the entire phrase "IS NULL" or "IS NOT NULL" is a
special operator.  For comparison, "x IS 3" is not an acceptable way of
spelling "x = 3".)

            regards, tom lane