SQL NULL is not Application Language NULL 14 July 2009
Posted by manniwood in Java, PostgreSQL, Programming, Python, SQL, SQL NULLs.trackback
When I first started using Python, it irritated me that null was None. C uses NULL, Java and JavaScript use null; why did Python have to use None? And why did Lisp have to use nil? Can’t all languages just standardise on null? It seems so arbitrary and capricious.
I’ve had a change of heart: I actually think the word ‘null’ needs to go away: languages should specify exactly what they mean by null, the way Python means None when it says None.
Like most application languages, Python throws errors when you try to add None to an integer, or concatenate None with strings:
>>> 1 + None Traceback (most recent call last): File "", line 1, in TypeError: unsupported operand type(s) for +: 'int' and 'NoneType' >>> "foo " + None Traceback (most recent call last): File "", line 1, in TypeError: cannot concatenate 'str' and 'NoneType' objects
In Java, you get null pointer errors trying to do similar things with Integer objects and Strings. Maybe it would be nice if Java also called null None, seeing as that’s what null really means in Java too.
In the case of SQL, it would be nice if NULL was called UNKNOWN. (Unfortunately, UNKNOWN is already taken! When was the last time you used the UNKNOWN keyword in SQL? Me neither. But it’s there…)
SQL’s NULL is often (ab)used to indicate “none”, but that’s incorrect: really a SQL NULL means “I have no idea”.
Watch this to see what I mean.
I fire up a PostgreSQL client, and ask it to print “NULL” instead of whitespace whenever NULL is encountered in result sets:
mydb=# \pset null 'NULL' Null display is "NULL".
and now I try to add an integer and NULL, then try to concatenate NULL to a string:
mydb# select 1 + null as "RESULT"; RESULT -------- NULL (1 row) mydb# select 'foo ' || null as "RESULT"; RESULT -------- NULL (1 row)
No tracebacks or null pointer errors in SQL! Nope. You get results. Why? Because SQL NULL does not mean “None”, it means “I have no idea!”
Hence, the only logical answer to adding one and “I have no idea” is “I have no idea”, because we have no idea what to what we are adding the number one—so if we are forced to provide an answer, we must respond “I have no idea!” And I’ll say it again: in SQL, NULL means “I have no idea”, not “None”. (Given that SQL has the UNKNOWN keyword, you’d think that UNKNOWN would be the result to the above queries. For whatever reason, SQL returns NULL instead. On the plus side, this re-inforces the fact that even SQL considers NULL to be the equivalent of UNKONWN.)
Likewise for concatenating ‘foo ‘ and SQL NULL: The answer is not ‘foo ‘ as you might expect if you were concatenating ‘foo ‘ and nothing; the answer is SQL NULL, because we are concatenating ‘foo ‘ and “I have no idea”. And when we have no idea what we are concatenating ‘foo ‘ to, we cannot predict what the resulting string would be, so the only logical answer is “I have no idea!”
In a sense, you could argue that Java null and Python None also mean “I have no idea”, it’s just that, in those languages, when you try to add 1 to “I have no idea”, you get an error. The compiler is basically stopping and asking for a time out: “Just what are you asking me to do here? I can’t add one and ‘I have no idea’!” Wouldn’t it be nice if SQL did that? But it does not. SQL happily returns the result: “I have no idea what one plus ‘I have no idea’ equals.”
My next blog post will be an appreciation of why Joe Celko says to avoid nulls in SQL whenever you can, and why C. J. Date says nulls should not even be part of the relational data model. I want to keep on typing, but I want to leave this blog entry with only one major idea: that nulls in your code’s business logic layer are not the same as nulls in your RDBMS!
[...] NULLs are Evil! 15 July 2009 Posted by manniwood in PostgreSQL, SQL, SQL NULLs. trackback In my last post, I spoke about how null in your business application language is not the same as NULL in SQL. [...]
[...] previous None, nil, Nothing, undef, NA, and SQL NULL, which goes into greather depth than my own SQL NULL is not Application Language NULL, and was written earlier—proving that anything I decide to blog about has indeed already been [...]
> languages should specify exactly what they mean by null, the way Python means None when it says None.
I think that it’s hard to express what is really meant in a single word. NULL and None have similar meanings in English, so I don’t think we can really draw a distinction there.
> Because SQL NULL does not mean “None”, it means “I have no idea!”
Sometimes, kind of. 1 + NULL is NULL, but SUM of 1 and NULL is 1. I don’t think you can pin down any particular meaning for SQL NULL.
> The compiler is basically stopping and asking for a time out: “Just what are you asking me to do here? I can’t add one and ‘I have no idea’!” Wouldn’t it be nice if SQL did that?
Hear, hear!
[ However, in the case of java and python, the error happens at runtime, not compile time. ]