NULL != text ?

Started by CSNover 20 years ago12 messagesgeneral
Jump to latest
#1CSN
cool_screen_name90001@yahoo.com

I was trying this:

IF (OLD.value != NEW.value) THEN
--
END IF;

and couldn't get the condition to evaluate to true at
all if OLD.value was NULL. I also tried:

IF (OLD.value NOT LIKE NEW.value) THEN
--
END IF;

with the same result. But this works:

IF ((OLD.value is NULL and NEW.value is NOT NULL) or
(OLD.value != NEW.value)) THEN
--
END IF;

So, does NULL != 'abc' always evaluate to false? The
manual
(http://www.postgresql.org/docs/8.0/interactive/functions-comparison.html)
states don't compare NULL values using =, but nothing
about using !=

CSN

__________________________________
Yahoo! Music Unlimited
Access over 1 million songs. Try it free.
http://music.yahoo.com/unlimited/

#2Michael Glaesemann
grzm@seespotcode.net
In reply to: CSN (#1)
Re: NULL != text ?

On Oct 20, 2005, at 15:04 , CSN wrote:

So, does NULL != 'abc' always evaluate to false? The
manual
(http://www.postgresql.org/docs/8.0/interactive/functions-
comparison.html)
states don't compare NULL values using =, but nothing
about using !=

The SQL standard way of checking for NULL is using IS NULL or IS NOT
NULL. NULL is unknown. You can't meaningfully compare with something
that is unknown, so you can't use = or <> (or it's alternate
spelling !=) to find out if something is NULL. Comparison with NULL
on one side of the comparison will result in NULL (*not* FALSE). For
a little fun (OK, I have to be a bit of a geek to call it that...)
with comparisons, see the end of this email.

I do my best to not allow any NULLs in my database schema, i.e.,
always use NOT NULL in table definitions, (I can't remember the last
time I didn't), which neatly avoids this problem entirely :) However,
given your schema, I'd try

if (OLD.value IS NOT NULL and NEW.value IS NOT NULL and OLD.value <>
NEW.value) or OLD.value IS NULL or NEW.value IS NULL

But that's untested and I have a hard time thinking in three-value
logic.

Hope this helps.

Michael Glaesemann
grzm myrealbox com

test=# select 1 = 1;
?column?
----------
t
(1 row)

test=# select 1 = 2;
?column?
----------
f
(1 row)

test=# select (1 <> NULL) IS NULL;
?column?
----------
t
(1 row)

test=# select (NULL = NULL) IS NULL;
?column?
----------
t
(1 row)

test=# select (0 <> NULL) IS NULL;
?column?
----------
t
(1 row)

test=# select (NULL IS NULL);
?column?
----------
t
(1 row)

test=# select (NULL IS NOT NULL);
?column?
----------
f
(1 row)

#3Michael Fuhr
mike@fuhr.org
In reply to: CSN (#1)
Re: NULL != text ?

On Wed, Oct 19, 2005 at 11:04:36PM -0700, CSN wrote:

So, does NULL != 'abc' always evaluate to false?

It never evaluates to false -- it evaluates to NULL.

http://www.postgresql.org/docs/8.0/interactive/functions-comparison.html

The ordinary comparison operators yield null (signifying "unknown")
when either input is null. Another way to do comparisons is with the
IS DISTINCT FROM construct:

expression IS DISTINCT FROM expression

For non-null inputs this is the same as the <> operator. However,
when both inputs are null it will return false, and when just one
input is null it will return true. Thus it effectively acts as
though null were a normal data value, rather than "unknown".

Examples:

test=> SELECT NULL = 'abc';
?column?
----------

(1 row)

test=> SELECT NULL <> 'abc';
?column?
----------

(1 row)

test=> SELECT NULL IS DISTINCT FROM 'abc';
?column?
----------
t
(1 row)

test=> SELECT NULL IS DISTINCT FROM NULL;
?column?
----------
f
(1 row)

--
Michael Fuhr

#4Michael Glaesemann
grzm@seespotcode.net
In reply to: Michael Fuhr (#3)
Re: NULL != text ?

On Oct 20, 2005, at 15:44 , Michael Fuhr wrote:

expression IS DISTINCT FROM expression

For non-null inputs this is the same as the <> operator. However,
when both inputs are null it will return false, and when just one
input is null it will return true. Thus it effectively acts as
though null were a normal data value, rather than "unknown".

Interesting! Thanks, Michael. You don't happen to know off the top of
your head if that's standard SQL, do you?

Michael Glaesemann
grzm myrealbox com

#5Alban Hertroys
alban@magproductions.nl
In reply to: Michael Glaesemann (#2)
Re: NULL != text ?

Michael Glaesemann wrote:

if (OLD.value IS NOT NULL and NEW.value IS NOT NULL and OLD.value <>
NEW.value) or OLD.value IS NULL or NEW.value IS NULL

But that's untested and I have a hard time thinking in three-value logic.

For completeness sake; Because of lazy evaluation, that boils down to:

if (OLD.value IS NULL OR NEW.value IS NULL OR OLD.value <> NEW.value)

The last part of the expression is only evaluated if both OLD.value and
NEW.value aren't NULL.

--
Alban Hertroys
alban@magproductions.nl

magproductions b.v.

T: ++31(0)534346874
F: ++31(0)534346876
M:
I: www.magproductions.nl
A: Postbus 416
7500 AK Enschede

//Showing your Vision to the World//

#6Tom Lane
tgl@sss.pgh.pa.us
In reply to: Alban Hertroys (#5)
Re: NULL != text ?

Alban Hertroys <alban@magproductions.nl> writes:

Michael Glaesemann wrote:

if (OLD.value IS NOT NULL and NEW.value IS NOT NULL and OLD.value <>
NEW.value) or OLD.value IS NULL or NEW.value IS NULL

But that's untested and I have a hard time thinking in three-value logic.

For completeness sake; Because of lazy evaluation, that boils down to:

if (OLD.value IS NULL OR NEW.value IS NULL OR OLD.value <> NEW.value)

The last part of the expression is only evaluated if both OLD.value and
NEW.value aren't NULL.

Wrong. SQL doesn't guarantee lazy evaluation. The above will work,
but it's because TRUE OR NULL is TRUE, not because anything is promised
about evaluation order.

regards, tom lane

#7Michael Fuhr
mike@fuhr.org
In reply to: Michael Glaesemann (#4)
Re: NULL != text ?

On Thu, Oct 20, 2005 at 03:57:41PM +0900, Michael Glaesemann wrote:

On Oct 20, 2005, at 15:44 , Michael Fuhr wrote:

expression IS DISTINCT FROM expression

For non-null inputs this is the same as the <> operator. However,
when both inputs are null it will return false, and when just one
input is null it will return true. Thus it effectively acts as
though null were a normal data value, rather than "unknown".

Interesting! Thanks, Michael. You don't happen to know off the top of
your head if that's standard SQL, do you?

IS DISTINCT FROM is defined in SQL:1999 and SQL:2003.

--
Michael Fuhr

#8Alban Hertroys
alban@magproductions.nl
In reply to: Tom Lane (#6)
3-state logic (was: Re: NULL != text ?)

Tom Lane wrote:

Wrong. SQL doesn't guarantee lazy evaluation. The above will work,
but it's because TRUE OR NULL is TRUE, not because anything is promised
about evaluation order.

Learned something new again, then.

I also noticed FALSE OR NULL is NULL, which went against my intuition. I
think I understand why:

- TRUE OR "unknown" can only evaluate to TRUE again; "unknown" is not
relevant for the operation.
- FALSE OR "unknown" remains "unknown", because "unknown" may be TRUE or
it may not. If it is, then the result would be TRUE, but if it isn't it
would be FALSE, but we don't know...

This 3-state logic can have some interesting results...

--
Alban Hertroys
alban@magproductions.nl

magproductions b.v.

T: ++31(0)534346874
F: ++31(0)534346876
M:
I: www.magproductions.nl
A: Postbus 416
7500 AK Enschede

//Showing your Vision to the World//

#9Michael Glaesemann
grzm@seespotcode.net
In reply to: Michael Fuhr (#7)
Re: NULL != text ?

On Oct 20, 2005, at 23:45 , Michael Fuhr wrote:

On Thu, Oct 20, 2005 at 03:57:41PM +0900, Michael Glaesemann wrote:

On Oct 20, 2005, at 15:44 , Michael Fuhr wrote:

expression IS DISTINCT FROM expression

For non-null inputs this is the same as the <> operator. However,
when both inputs are null it will return false, and when just one
input is null it will return true. Thus it effectively acts as
though null were a normal data value, rather than "unknown".

Interesting! Thanks, Michael. You don't happen to know off the top of
your head if that's standard SQL, do you?

IS DISTINCT FROM is defined in SQL:1999 and SQL:2003.

Thanks!

Michael Glaesemann
grzm myrealbox com

#10CSN
cool_screen_name90001@yahoo.com
In reply to: Michael Fuhr (#3)
Re: NULL != text ?

BTW, it (the SQL spec I presume) has always seemed
contradictory to me that you can't do:

select * from table where field=null;

but can do:

update table set field=null;

(as opposed to 'update table set field to null' or
similar).

CSN

__________________________________
Yahoo! Mail - PC Magazine Editors' Choice 2005
http://mail.yahoo.com

#11Tom Lane
tgl@sss.pgh.pa.us
In reply to: CSN (#10)
Re: NULL != text ?

CSN <cool_screen_name90001@yahoo.com> writes:

BTW, it (the SQL spec I presume) has always seemed
contradictory to me that you can't do:
select * from table where field=null;
but can do:
update table set field=null;

This only seems contradictory if you fail to make the distinction
between "=" used as a comparison operator and "=" used to mean
assignment.

Personally I prefer programming languages that actually spell the
two concepts differently ... but enough don't that one has to learn
to live with it.

regards, tom lane

#12Jan Wieck
JanWieck@Yahoo.com
In reply to: Alban Hertroys (#5)
Re: NULL != text ?

On 10/20/2005 6:10 AM, Alban Hertroys wrote:

Michael Glaesemann wrote:

if (OLD.value IS NOT NULL and NEW.value IS NOT NULL and OLD.value <>
NEW.value) or OLD.value IS NULL or NEW.value IS NULL

But that's untested and I have a hard time thinking in three-value logic.

For completeness sake; Because of lazy evaluation, that boils down to:

if (OLD.value IS NULL OR NEW.value IS NULL OR OLD.value <> NEW.value)

That would result in TRUE if both, OLD and NEW are NULL. Is that what
you intended?

Jan

The last part of the expression is only evaluated if both OLD.value and
NEW.value aren't NULL.

--
#======================================================================#
# It's easier to get forgiveness for being wrong than for being right. #
# Let's break this rule - forgive me. #
#================================================== JanWieck@Yahoo.com #