AFAIU, an SQL engine internally assigns a datatype to NULL
values, for example, some engines use the datatype integer as default. I know, that this may cause an error in UNION
operations when the column of the other table is not compatible (e.g. VARCHAR
) (here). Still, I struggle to understand why the following code works/does not work (on Exasol DB):
A)
This works
SELECT NULL AS TEST
UNION
SELECT DATE '2022-11-03' AS TEST
;
B)
But when I do 'the same' using a subquery, it throws a datatypes are not compatible
error.
SELECT A.* FROM (SELECT NULL AS TEST) A
UNION
SELECT DATE '2022-11-03' AS TEST
;
C)
B can be fixed by explicit type casting of the NULL
value:
SELECT A.* FROM (SELECT CAST(NULL AS DATE) AS TEST) A
UNION
SELECT DATE '2022-11-03' AS TEST
;
Still, I do not understand what happens in B behind the scenes, so A works but B does not. Apparently, the subquery (or a join) makes a difference for the type of the NULL
column. But why?
Can anyone explain what exactly happens here?
PS. The same is the case for JOINS.
B2)
Does not work.
SELECT 'Dummy' AS C1, SELECT NULL AS TEST
UNION
SELECT 'Dummy' AS C1, SELECT DATE '2022-11-03' AS TEST
;
C2)
Does work.
SELECT 'Dummy' AS C1, SELECT CAST(NULL AS DATE) AS TEST
UNION
SELECT 'Dummy' AS C1, SELECT DATE '2022-11-03' AS TEST
;
CodePudding user response:
In general, NULL
has the type BOOLEAN
in Exasol. You can check this either by using TYPEOF or DESCRIBE:
select TYPEOF(NULL); -- The TYPEOF function is available since version 7.1
-- Old way to see the type of an expression:
create schema s;
create or replace table tmp as select null expr;
describe tmp;
However, sometimes Exasol changes this type internally. One of these cases is if a NULL
literal occurs directly inside an UNION
clause. It only does this if it is an explicit NULL
literal. E.g. the following also doesn't work:
SELECT NULL NULL AS TEST
UNION
SELECT DATE '2022-11-03' AS TEST;
But it works if the expected type is BOOLEAN
:
SELECT NULL NULL AS TEST
UNION
SELECT TRUE AS TEST;
As you mentioned, the workaround is to wrap the expression in a CAST
.