Thread
-
Can't use NULL in IN conditional?
PostgreSQL Bugs List <pgsql-bugs@postgresql.org> — 2000-12-11T07:49:19Z
Charles Tassell (ctassell@isn.net) reports a bug with a severity of 3 The lower the number the more severe it is. Short Description Can't use NULL in IN conditional? Long Description I don't know if this is a "feature" that comes alogn with NULL values, or somethign I'm doing wrong, but I can't seem to search for the NULL value via a WHERE xx IN clause. I've re-written the query to use OR and it works fine then, but not with the IN clause. This is with Postgres 7.02 on a Linux system (PostgreSQL 7.0.2 on i686-pc-linux-gnu, compiled by gcc egcs-2.91.66) Sample Code CREATE TABLE product_types ( type_id serial, code text ) INSERT INTO product_types (code) VALUES ('0A'); INSERT INTO product_types (code) VALUES (NULL); -- This works SELECT type_id, code FROM product_types WHERE code = '0A' OR code = NULL; -- This doesn't SELECT type_id, code FROM product_types WHERE code IN ('OA', NULL); No file was uploaded with this report -
Re: Can't use NULL in IN conditional?
Tom Lane <tgl@sss.pgh.pa.us> — 2000-12-11T15:51:56Z
pgsql-bugs@postgresql.org writes: > -- This works > SELECT type_id, code FROM product_types WHERE code = '0A' OR code = NULL; > -- This doesn't > SELECT type_id, code FROM product_types WHERE code IN ('OA', NULL); "code = NULL" is not legal SQL --- or at least, the standard's interpretation of it is not what you appear to expect. According to the spec the result must always be NULL, which is effectively FALSE in this context. Since certain Microsoft products misinterpret "var = NULL" as "var IS NULL", we've inserted a hack into our parser to convert a comparison against a literal NULL to an IS NULL clause. However, that only works for the specific cases of "var = NULL" and "var <> NULL", not for any other contexts where a null might be compared against something else. Personally I regard this hack as a bad idea, and would prefer to take it out. I'd certainly resist extending it to the IN operator... regards, tom lane -
Re: Can't use NULL in IN conditional?
Robert B. Easter <reaster@comptechnews.com> — 2000-12-11T17:01:40Z
On Monday 11 December 2000 10:51, Tom Lane wrote: > pgsql-bugs@postgresql.org writes: > > -- This works > > SELECT type_id, code FROM product_types WHERE code = '0A' OR code = NULL; > > -- This doesn't > > SELECT type_id, code FROM product_types WHERE code IN ('OA', NULL); > > "code = NULL" is not legal SQL --- or at least, the standard's > interpretation of it is not what you appear to expect. According to the > spec the result must always be NULL, which is effectively FALSE in this > context. > > Since certain Microsoft products misinterpret "var = NULL" as "var IS > NULL", we've inserted a hack into our parser to convert a comparison > against a literal NULL to an IS NULL clause. However, that only works for > the specific cases of "var = NULL" and "var <> NULL", not for any other > contexts where a null might be compared against something else. > > Personally I regard this hack as a bad idea, and would prefer to take it > out. I'd certainly resist extending it to the IN operator... > > regards, tom lane What you are saying agrees with things I've read elsewhere, and a little definition/note that I wrote on my "Databasing" Terms page: three-valued logic: a logic system that employs TRUE, FALSE, and UNKNOWN. NULL values introduce UNKNOWN into boolean operations. A truth table must be used to lookup the proper value (TRUE or FALSE) of UNKNOWN under specific operations. In SQL implementations that use three-valued logic, you must consult the documentation for its truth table. Some newer implementations of SQL eliminate UNKNOWN, and may generally behave as follows: all boolean tests involving NULL return FALSE except the explicit test IS NULL, e.g., if NULL is a possibility, it has to be tested for explicity using IS NULL or IS NOT NULL. (any additions/corrections to this definition/note will be happily considered) I think Bruce Momjian's book says this too: http://www.postgresql.org/docs/aw_pgsql_book/node45.html (that book is really useful!) -- -------- Robert B. Easter reaster@comptechnews.com --------- - CompTechNews Message Board http://www.comptechnews.com/ - - CompTechServ Tech Services http://www.comptechserv.com/ - ---------- http://www.comptechnews.com/~reaster/ ------------ -
Re: Can't use NULL in IN conditional?
Tom Lane <tgl@sss.pgh.pa.us> — 2000-12-11T17:34:07Z
"Robert B. Easter" <reaster@comptechnews.com> writes: > What you are saying agrees with things I've read elsewhere, and a little > definition/note that I wrote on my "Databasing" Terms page: > three-valued logic: > a logic system that employs TRUE, FALSE, and UNKNOWN. NULL values introduce > UNKNOWN into boolean operations. A truth table must be used to lookup the > proper value (TRUE or FALSE) of UNKNOWN under specific operations. In SQL > implementations that use three-valued logic, you must consult the > documentation for its truth table. Three-valued logic is perfectly straightforward if you keep in mind the interpretation of NULL/UNKNOWN: "I don't know if this is true or false". Thus: NOT unknown => unknown false AND unknown => false (it can't possibly be true) true AND unknown => unknown unknown AND unknown => unknown false OR unknown => unknown true OR unknown => true (it's true no matter what the unknown is) unknown OR unknown => unknown For ordinary operators such as "=", the result is generally NULL if any input is NULL, although there are some specific cases where you can deduce a correct result knowing only some of the inputs. In particular, NULL = NULL does not yield TRUE, it yields UNKNOWN. This is correct when you consider that NULL is not a specific value, but a placeholder for an unknown value. (Reference: SQL99 section 8.2 general rule 1a.) IS NULL and IS NOT NULL are not ordinary operators in this sense, since they can deliver a non-null result for NULL input. Also, SQL specifies that a WHERE clause that evaluates to "unknown" is taken as false, ie, the row is not selected. Bottom line is that in a spec-conformant implementation, WHERE code = '0A' OR code = NULL will act the same as if you'd just written "WHERE code = '0A'"; the second clause always yields unknown and so can never cause the WHERE to be taken as true. > Some newer implementations of SQL > eliminate UNKNOWN, and may generally behave as follows: all boolean tests > involving NULL return FALSE except the explicit test IS NULL, e.g., if NULL > is a possibility, it has to be tested for explicity using IS NULL or IS NOT > NULL. They may *appear* to return FALSE if you aren't looking too closely, since WHERE treats top-level results of FALSE and UNKNOWN the same. If they really don't make the distinction then they are broken. AFAICT, neither SQL92 nor SQL99 regard NULL support as optional. regards, tom lane
-
Re: Can't use NULL in IN conditional?
Robert B. Easter <reaster@comptechnews.com> — 2000-12-12T05:01:28Z
On Monday 11 December 2000 12:34, Tom Lane wrote: > Three-valued logic is perfectly straightforward if you keep in mind the > interpretation of NULL/UNKNOWN: "I don't know if this is true or false". > Thus: > > NOT unknown => unknown > > false AND unknown => false (it can't possibly be true) > true AND unknown => unknown > unknown AND unknown => unknown > > false OR unknown => unknown > true OR unknown => true (it's true no matter what the unknown is) > unknown OR unknown => unknown > > For ordinary operators such as "=", the result is generally NULL if any > input is NULL, although there are some specific cases where you can > deduce a correct result knowing only some of the inputs. In particular, > NULL = NULL does not yield TRUE, it yields UNKNOWN. This is correct > when you consider that NULL is not a specific value, but a placeholder > for an unknown value. (Reference: SQL99 section 8.2 general rule 1a.) > > IS NULL and IS NOT NULL are not ordinary operators in this sense, since > they can deliver a non-null result for NULL input. > > Also, SQL specifies that a WHERE clause that evaluates to "unknown" is > taken as false, ie, the row is not selected. > > Bottom line is that in a spec-conformant implementation, > WHERE code = '0A' OR code = NULL > will act the same as if you'd just written "WHERE code = '0A'"; the > second clause always yields unknown and so can never cause the WHERE to > be taken as true. > > > Some newer implementations of SQL > > eliminate UNKNOWN, and may generally behave as follows: all boolean tests > > involving NULL return FALSE except the explicit test IS NULL, e.g., if > > NULL is a possibility, it has to be tested for explicity using IS NULL or > > IS NOT NULL. > > They may *appear* to return FALSE if you aren't looking too closely, > since WHERE treats top-level results of FALSE and UNKNOWN the same. > If they really don't make the distinction then they are broken. > AFAICT, neither SQL92 nor SQL99 regard NULL support as optional. > > regards, tom lane Thanks for the clarification and SQL reference. I spent some time on this today and updated a file of mine at http://www.comptechnews.com/~reaster/dbdesign.html#three-valued-logic to take into consideration these things. If you do take a look at it and find an error, I will fix it. This dbdesign.html file is a file linked to from http://postgresql.readysetnet.com/docs/faq-english.html so I'm hoping to keep it correct and useful. Thanks :) -- -------- Robert B. Easter reaster@comptechnews.com --------- - CompTechNews Message Board http://www.comptechnews.com/ - - CompTechServ Tech Services http://www.comptechserv.com/ - ---------- http://www.comptechnews.com/~reaster/ ------------