What's wrong with this query?

Started by Mike Christensenalmost 17 years ago9 messagesgeneral
Jump to latest
#1Mike Christensen
mike@kitchenpc.com

I just tracked down a bug in my software due to an "unexpected" behavior in
Postgres.. Can someone clarify why this doesn't work (I haven't tried it on
MSSQL or anything else, so I'm not sure if this is the official SQL standard
or anything)..

CREATE TABLE test
(
value uuid
);

INSERT INTO test VALUES ('00000000-0000-0000-0000-000000000000');
INSERT INTO test VALUES ('11111111-1111-1111-1111-111111111111');
INSERT INTO test VALUES (null);

select * from test where value != '00000000-0000-0000-0000-000000000000';

What I expect to get is two rows: the '11111111-1111-1111-1111-111111111111'
row and the null row, as both those values are in fact not
'00000000-0000-0000-0000-000000000000'. However, I only get the first one.

I can change my query to:

select * from test where value is null or value !=
'00000000-0000-0000-0000-000000000000';

and that will give me the null rows, or rows that don't match that UUID. Is
there a better way of writing this query? Thanks!

Mike

#2Thomas Kellerer
spam_eater@gmx.net
In reply to: Mike Christensen (#1)
Re: What's wrong with this query?

Mike Christensen wrote on 22.06.2009 00:10:

I just tracked down a bug in my software due to an "unexpected" behavior
in Postgres.. Can someone clarify why this doesn't work (I haven't
tried it on MSSQL or anything else, so I'm not sure if this is the
official SQL standard or anything)..

CREATE TABLE test
(
value uuid
);

INSERT INTO test VALUES ('00000000-0000-0000-0000-000000000000');
INSERT INTO test VALUES ('11111111-1111-1111-1111-111111111111');
INSERT INTO test VALUES (null);

select * from test where value != '00000000-0000-0000-0000-000000000000';

What I expect to get is two rows: the
'11111111-1111-1111-1111-111111111111' row and the null row, as both
those values are in fact not '00000000-0000-0000-0000-000000000000'.
However, I only get the first one.

That is standard behaviour.
A comparison with a NULL value always returns false (and that is not a Postgres
speciality).

You need to use

select *
from test
where value != '00000000-0000-0000-0000-000000000000'
or value is null;

Thomas

#3Steve Atkins
steve@blighty.com
In reply to: Thomas Kellerer (#2)
Re: What's wrong with this query?

On Jun 21, 2009, at 3:37 PM, Thomas Kellerer wrote:

Mike Christensen wrote on 22.06.2009 00:10:

I just tracked down a bug in my software due to an "unexpected"
behavior in Postgres.. Can someone clarify why this doesn't work
(I haven't tried it on MSSQL or anything else, so I'm not sure if
this is the official SQL standard or anything)..
CREATE TABLE test
(
value uuid
);
INSERT INTO test VALUES ('00000000-0000-0000-0000-000000000000');
INSERT INTO test VALUES ('11111111-1111-1111-1111-111111111111');
INSERT INTO test VALUES (null);
select * from test where value !=
'00000000-0000-0000-0000-000000000000';
What I expect to get is two rows: the
'11111111-1111-1111-1111-111111111111' row and the null row, as
both those values are in fact not
'00000000-0000-0000-0000-000000000000'. However, I only get the
first one.

That is standard behaviour.
A comparison with a NULL value always returns false (and that is not
a Postgres speciality).

You need to use

select *
from test
where value != '00000000-0000-0000-0000-000000000000'
or value is null;

Yup.

Or where value is distinct from '00000000-0000-0000-0000-000000000000';

Cheers,
Steve

#4Martin Gainty
mgainty@hotmail.com
In reply to: Thomas Kellerer (#2)
Re: What's wrong with this query?

testcase for a null uuid?

thanks,
Martin
______________________________________________
Verzicht und Vertraulichkeitanmerkung/Note de déni et de confidentialité

Diese Nachricht ist vertraulich. Sollten Sie nicht der vorgesehene Empfaenger sein, so bitten wir hoeflich um eine Mitteilung. Jede unbefugte Weiterleitung oder Fertigung einer Kopie ist unzulaessig. Diese Nachricht dient lediglich dem Austausch von Informationen und entfaltet keine rechtliche Bindungswirkung. Aufgrund der leichten Manipulierbarkeit von E-Mails koennen wir keine Haftung fuer den Inhalt uebernehmen.
Ce message est confidentiel et peut être privilégié. Si vous n'êtes pas le destinataire prévu, nous te demandons avec bonté que pour satisfaire informez l'expéditeur. N'importe quelle diffusion non autorisée ou la copie de ceci est interdite. Ce message sert à l'information seulement et n'aura pas n'importe quel effet légalement obligatoire. Étant donné que les email peuvent facilement être sujets à la manipulation, nous ne pouvons accepter aucune responsabilité pour le contenu fourni.

To: pgsql-general@postgresql.org
From: spam_eater@gmx.net
Subject: Re: [GENERAL] What's wrong with this query?
Date: Mon, 22 Jun 2009 00:37:41 +0200

Mike Christensen wrote on 22.06.2009 00:10:

I just tracked down a bug in my software due to an "unexpected" behavior
in Postgres.. Can someone clarify why this doesn't work (I haven't
tried it on MSSQL or anything else, so I'm not sure if this is the
official SQL standard or anything)..

CREATE TABLE test
(
value uuid
);

INSERT INTO test VALUES ('00000000-0000-0000-0000-000000000000');
INSERT INTO test VALUES ('11111111-1111-1111-1111-111111111111');
INSERT INTO test VALUES (null);

select * from test where value != '00000000-0000-0000-0000-000000000000';

What I expect to get is two rows: the
'11111111-1111-1111-1111-111111111111' row and the null row, as both
those values are in fact not '00000000-0000-0000-0000-000000000000'.
However, I only get the first one.

That is standard behaviour.
A comparison with a NULL value always returns false (and that is not a Postgres
speciality).

You need to use

select *
from test
where value != '00000000-0000-0000-0000-000000000000'
or value is null;

Thomas

--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general

_________________________________________________________________
Insert movie times and more without leaving Hotmail®.
http://windowslive.com/Tutorial/Hotmail/QuickAdd?ocid=TXT_TAGLM_WL_HM_Tutorial_QuickAdd_062009

#5Mike Christensen
mike@kitchenpc.com
In reply to: Martin Gainty (#4)
Re: What's wrong with this query?

Thanks all, that's pretty much what I figured - just wanted to make sure..
I'm still trying to master this SQL thing you speak of.

On Sun, Jun 21, 2009 at 5:20 PM, Martin Gainty <mgainty@hotmail.com> wrote:

Show quoted text

testcase for a null uuid?

thanks,
Martin
______________________________________________
Verzicht und Vertraulichkeitanmerkung/Note de déni et de confidentialité

Diese Nachricht ist vertraulich. Sollten Sie nicht der vorgesehene
Empfaenger sein, so bitten wir hoeflich um eine Mitteilung. Jede unbefugte
Weiterleitung oder Fertigung einer Kopie ist unzulaessig. Diese Nachricht
dient lediglich dem Austausch von Informationen und entfaltet keine
rechtliche Bindungswirkung. Aufgrund der leichten Manipulierbarkeit von
E-Mails koennen wir keine Haftung fuer den Inhalt uebernehmen.

Ce message est confidentiel et peut être privilégié. Si vous n'êtes pas le destinataire prévu, nous te demandons avec bonté que pour satisfaire informez l'expéditeur. N'importe quelle diffusion non autorisée ou la copie de ceci est interdite. Ce message sert à l'information seulement et n'aura pas n'importe quel effet légalement obligatoire. Étant donné que les email peuvent facilement être sujets à la manipulation, nous ne pouvons accepter aucune responsabilité pour le contenu fourni.

To: pgsql-general@postgresql.org
From: spam_eater@gmx.net
Subject: Re: [GENERAL] What's wrong with this query?
Date: Mon, 22 Jun 2009 00:37:41 +0200

Mike Christensen wrote on 22.06.2009 00:10:

I just tracked down a bug in my software due to an "unexpected"

behavior

in Postgres.. Can someone clarify why this doesn't work (I haven't
tried it on MSSQL or anything else, so I'm not sure if this is the
official SQL standard or anything)..

CREATE TABLE test
(
value uuid
);

INSERT INTO test VALUES ('00000000-0000-0000-0000-000000000000');
INSERT INTO test VALUES ('11111111-1111-1111-1111-111111111111');
INSERT INTO test VALUES (null);

select * from test where value !=

'00000000-0000-0000-0000-000000000000';

What I expect to get is two rows: the
'11111111-1111-1111-1111-111111111111' row and the null row, as both
those values are in fact not '00000000-0000-0000-0000-000000000000'.
However, I only get the first one.

That is standard behaviour.
A comparison with a NULL value always returns false (and that is not a

Postgres

speciality).

You need to use

select *
from test
where value != '00000000-0000-0000-0000-000000000000'
or value is null;

Thomas

--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general

------------------------------
Insert movie times and more without leaving Hotmail®. See how.<http://windowslive.com/Tutorial/Hotmail/QuickAdd?ocid=TXT_TAGLM_WL_HM_Tutorial_QuickAdd_062009&gt;

#6Martin Gainty
mgainty@hotmail.com
In reply to: Mike Christensen (#5)
Re: What's wrong with this query?

hi mike-

is null uuid valid ?

my experience would suggest a uuid is a foreign key to some other entity
so any table containing object types (classes/structs) or table created from an object type
(class/struct) must have a not null uuid (other systems call it guid)
would require the uuid/guid to be not null otherwise the entity you would be pointing to
has been 'orphaned'

thanks,
Martin
______________________________________________
Verzicht und Vertraulichkeitanmerkung/Note de déni et de confidentialité

Diese Nachricht ist vertraulich. Sollten Sie nicht der vorgesehene Empfaenger sein, so bitten wir hoeflich um eine Mitteilung. Jede unbefugte Weiterleitung oder Fertigung einer Kopie ist unzulaessig. Diese Nachricht dient lediglich dem Austausch von Informationen und entfaltet keine rechtliche Bindungswirkung. Aufgrund der leichten Manipulierbarkeit von E-Mails koennen wir keine Haftung fuer den Inhalt uebernehmen.
Ce message est confidentiel et peut être privilégié. Si vous n'êtes pas le destinataire prévu, nous te demandons avec bonté que pour satisfaire informez l'expéditeur. N'importe quelle diffusion non autorisée ou la copie de ceci est interdite. Ce message sert à l'information seulement et n'aura pas n'importe quel effet légalement obligatoire. Étant donné que les email peuvent facilement être sujets à la manipulation, nous ne pouvons accepter aucune responsabilité pour le contenu fourni.

Date: Sun, 21 Jun 2009 18:43:42 -0700
Subject: Re: [GENERAL] What's wrong with this query?
From: mike@kitchenpc.com
To: mgainty@hotmail.com
CC: spam_eater@gmx.net; pgsql-general@postgresql.org

Thanks all, that's pretty much what I figured - just wanted to make sure.. I'm still trying to master this SQL thing you speak of.

On Sun, Jun 21, 2009 at 5:20 PM, Martin Gainty <mgainty@hotmail.com> wrote:

testcase for a null uuid?

thanks,
Martin
______________________________________________
Verzicht und Vertraulichkeitanmerkung/Note de déni et de confidentialité

Diese Nachricht ist vertraulich. Sollten Sie nicht der vorgesehene Empfaenger sein, so bitten wir hoeflich um eine Mitteilung. Jede unbefugte Weiterleitung oder Fertigung einer Kopie ist unzulaessig. Diese Nachricht dient lediglich dem Austausch von Informationen und entfaltet keine rechtliche Bindungswirkung. Aufgrund der leichten Manipulierbarkeit von E-Mails koennen wir keine Haftung fuer den Inhalt uebernehmen.

Ce message est confidentiel et peut être privilégié. Si vous n'êtes pas le destinataire prévu, nous te demandons avec bonté que pour satisfaire informez l'expéditeur. N'importe quelle diffusion non autorisée ou la copie de ceci est interdite. Ce message sert à l'information seulement et n'aura pas n'importe quel effet légalement obligatoire. Étant donné que les email peuvent facilement être sujets à la manipulation, nous ne pouvons accepter aucune responsabilité pour le contenu fourni.

To: pgsql-general@postgresql.org
From: spam_eater@gmx.net
Subject: Re: [GENERAL] What's wrong with this query?

Date: Mon, 22 Jun 2009 00:37:41 +0200

Mike Christensen wrote on 22.06.2009 00:10:

I just tracked down a bug in my software due to an "unexpected" behavior

in Postgres.. Can someone clarify why this doesn't work (I haven't
tried it on MSSQL or anything else, so I'm not sure if this is the
official SQL standard or anything)..

CREATE TABLE test
(
value uuid
);

INSERT INTO test VALUES ('00000000-0000-0000-0000-000000000000');
INSERT INTO test VALUES ('11111111-1111-1111-1111-111111111111');

INSERT INTO test VALUES (null);

select * from test where value != '00000000-0000-0000-0000-000000000000';

What I expect to get is two rows: the
'11111111-1111-1111-1111-111111111111' row and the null row, as both

those values are in fact not '00000000-0000-0000-0000-000000000000'.
However, I only get the first one.

That is standard behaviour.
A comparison with a NULL value always returns false (and that is not a Postgres

speciality).

You need to use

select *
from test
where value != '00000000-0000-0000-0000-000000000000'
or value is null;

Thomas

--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general

Insert movie times and more without leaving Hotmail®. See how.

_________________________________________________________________
Hotmail® has ever-growing storage! Don’t worry about storage limits.
http://windowslive.com/Tutorial/Hotmail/Storage?ocid=TXT_TAGLM_WL_HM_Tutorial_Storage_062009

#7Mike Christensen
mike@kitchenpc.com
In reply to: Martin Gainty (#6)
Re: What's wrong with this query?

The table in question is a list of events associated with user actions.
Users who are subscribed to another user's "channel" will see those events
on the home page. The column in question is a "RecipientId" which only
contains a link to a User Id if the action was performed on another user,
otherwise the value is null. So to answer your question, yes the column has
a FK but it can also be null depending on the type of action the row
represents.

Mike

On Sun, Jun 21, 2009 at 7:03 PM, Martin Gainty <mgainty@hotmail.com> wrote:

Show quoted text

hi mike-

is null uuid valid ?

my experience would suggest a uuid is a foreign key to some other entity
so any table containing object types (classes/structs) or table created
from an object type
(class/struct) must have a not null uuid (other systems call it guid)
would require the uuid/guid to be not null otherwise the entity you would
be pointing to
has been 'orphaned'

thanks,
Martin
______________________________________________
Verzicht und Vertraulichkeitanmerkung/Note de déni et de confidentialité

Diese Nachricht ist vertraulich. Sollten Sie nicht der vorgesehene
Empfaenger sein, so bitten wir hoeflich um eine Mitteilung. Jede unbefugte
Weiterleitung oder Fertigung einer Kopie ist unzulaessig. Diese Nachricht
dient lediglich dem Austausch von Informationen und entfaltet keine
rechtliche Bindungswirkung. Aufgrund der leichten Manipulierbarkeit von
E-Mails koennen wir keine Haftung fuer den Inhalt uebernehmen.

Ce message est confidentiel et peut être privilégié. Si vous n'êtes pas le destinataire prévu, nous te demandons avec bonté que pour satisfaire informez l'expéditeur. N'importe quelle diffusion non autorisée ou la copie de ceci est interdite. Ce message sert à l'information seulement et n'aura pas n'importe quel effet légalement obligatoire. Étant donné que les email peuvent facilement être sujets à la manipulation, nous ne pouvons accepter aucune responsabilité pour le contenu fourni.

------------------------------
Date: Sun, 21 Jun 2009 18:43:42 -0700
Subject: Re: [GENERAL] What's wrong with this query?
From: mike@kitchenpc.com
To: mgainty@hotmail.com
CC: spam_eater@gmx.net; pgsql-general@postgresql.org

Thanks all, that's pretty much what I figured - just wanted to make sure..
I'm still trying to master this SQL thing you speak of.

On Sun, Jun 21, 2009 at 5:20 PM, Martin Gainty <mgainty@hotmail.com>wrote:

testcase for a null uuid?

thanks,
Martin
______________________________________________
Verzicht und Vertraulichkeitanmerkung/Note de déni et de confidentialité

Diese Nachricht ist vertraulich. Sollten Sie nicht der vorgesehene
Empfaenger sein, so bitten wir hoeflich um eine Mitteilung. Jede unbefugte
Weiterleitung oder Fertigung einer Kopie ist unzulaessig. Diese Nachricht
dient lediglich dem Austausch von Informationen und entfaltet keine
rechtliche Bindungswirkung. Aufgrund der leichten Manipulierbarkeit von
E-Mails koennen wir keine Haftung fuer den Inhalt uebernehmen.

Ce message est confidentiel et peut être privilégié. Si vous n'êtes pas le destinataire prévu, nous te demandons avec bonté que pour satisfaire informez l'expéditeur. N'importe quelle diffusion non autorisée ou la copie de ceci est interdite. Ce message sert à l'information seulement et n'aura pas n'importe quel effet légalement obligatoire. Étant donné que les email peuvent facilement être sujets à la manipulation, nous ne pouvons accepter aucune responsabilité pour le contenu fourni.

To: pgsql-general@postgresql.org
From: spam_eater@gmx.net
Subject: Re: [GENERAL] What's wrong with this query?
Date: Mon, 22 Jun 2009 00:37:41 +0200

Mike Christensen wrote on 22.06.2009 00:10:

I just tracked down a bug in my software due to an "unexpected"

behavior

in Postgres.. Can someone clarify why this doesn't work (I haven't
tried it on MSSQL or anything else, so I'm not sure if this is the
official SQL standard or anything)..

CREATE TABLE test
(
value uuid
);

INSERT INTO test VALUES ('00000000-0000-0000-0000-000000000000');
INSERT INTO test VALUES ('11111111-1111-1111-1111-111111111111');
INSERT INTO test VALUES (null);

select * from test where value !=

'00000000-0000-0000-0000-000000000000';

What I expect to get is two rows: the
'11111111-1111-1111-1111-111111111111' row and the null row, as both
those values are in fact not '00000000-0000-0000-0000-000000000000'.
However, I only get the first one.

That is standard behaviour.
A comparison with a NULL value always returns false (and that is not a

Postgres

speciality).

You need to use

select *
from test
where value != '00000000-0000-0000-0000-000000000000'
or value is null;

Thomas

--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general

------------------------------
Insert movie times and more without leaving Hotmail®. See how.<http://windowslive.com/Tutorial/Hotmail/QuickAdd?ocid=TXT_TAGLM_WL_HM_Tutorial_QuickAdd_062009&gt;

------------------------------
Hotmail® has ever-growing storage! Don’t worry about storage limits. Check
it out.<http://windowslive.com/Tutorial/Hotmail/Storage?ocid=TXT_TAGLM_WL_HM_Tutorial_Storage_062009&gt;

#8Laurenz Albe
laurenz.albe@cybertec.at
In reply to: Thomas Kellerer (#2)
Re: What's wrong with this query?

Thomas Kellerer wrote:

CREATE TABLE test
(
value uuid
);

INSERT INTO test VALUES ('00000000-0000-0000-0000-000000000000');
INSERT INTO test VALUES ('11111111-1111-1111-1111-111111111111');
INSERT INTO test VALUES (null);

select * from test where value != '00000000-0000-0000-0000-000000000000';

What I expect to get is two rows: the
'11111111-1111-1111-1111-111111111111' row and the null row, as both
those values are in fact not '00000000-0000-0000-0000-000000000000'.
However, I only get the first one.

That is standard behaviour.
A comparison with a NULL value always returns false (and that
is not a Postgres speciality).

Sorry to be nitpicking, but maybe in that case it adds to clarity:

A comparison with NULL does not return FALSE, but "undefined" or NULL.

Try to run the following queries:

SELECT 1 = 2;
and
SELECT 1 = NULL;

and observe the different result.

In the context of the original question this difference does not matter,
because a comparison is considered successful only if it returns TRUE.

But I think this way it becomes clearer *why* neither = nor != will
succeed for a NULL (= undefined) value: if you don't know which value
a certain thing has, you can neither say that it is equal to 1 nor
that it is not equal to 1.

Yours,
Laurenz Albe

#9Thomas Kellerer
spam_eater@gmx.net
In reply to: Laurenz Albe (#8)
Re: What's wrong with this query?

Albe Laurenz, 22.06.2009 09:52:

Sorry to be nitpicking, but maybe in that case it adds to clarity:

A comparison with NULL does not return FALSE, but "undefined" or NULL.

Try to run the following queries:

SELECT 1 = 2;
and
SELECT 1 = NULL;

and observe the different result.

In the context of the original question this difference does not matter,
because a comparison is considered successful only if it returns TRUE.

But I think this way it becomes clearer *why* neither = nor != will
succeed for a NULL (= undefined) value: if you don't know which value
a certain thing has, you can neither say that it is equal to 1 nor
that it is not equal to 1.

Good points :)

Thanks for the clarification!

I recently saw a blog talking about interview questions. One of them was:

Under which circumstances does the following query *not* return all rows

SELECT *
FROM the_table
WHERE some_column = some_column;

boils down to the same behaviour...

Regards
Thomas