Thread: What's wrong with this query?

What's wrong with this query?

From
Mike Christensen
Date:
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

Re: What's wrong with this query?

From
Thomas Kellerer
Date:
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

Re: What's wrong with this query?

From
Steve Atkins
Date:
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


Re: What's wrong with this query?

From
Martin Gainty
Date:
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.

Re: What's wrong with this query?

From
Mike Christensen
Date:
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.

Re: What's wrong with this query?

From
Martin Gainty
Date:
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. Check it out.

Re: What's wrong with this query?

From
Mike Christensen
Date:
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:
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. Check it out.

Re: What's wrong with this query?

From
"Albe Laurenz"
Date:
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

Re: What's wrong with this query?

From
Thomas Kellerer
Date:
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