On 27-05-2020 16:31, Emil Totev wrote:
It seems that it is only possible to CAST() from/to boolean as char/varchar (values 'TRUE' and 'FALSE'), and the same also applies to the new SET BIND OF BOOLEAN TO type-to.

Is this restricted by the SQL standard? Wouldn't it also make sense to be able to cast /set bind of  booleans to any numeric type as 0 (false) and 1 (true)? Or maybe even the often used Y/N char(1)?

Yes, SQL:2016 specifies that CAST supports the following

from character types to boolean
from boolean to boolean
from boolean to character types

For casts to boolean, it specifies:

(TD: Target Domain, SD: Source Domain, SV: Source Value, VE: Value Expression, TV: Target Value)

"""
21) If TD is boolean, then
Case:
a) If SD is character string, then SV is replaced by
TRIM ( BOTH ' ' FROM VE )
Case:
i) If the rules for <literal> in Subclause 5.3, “<literal>”, can be applied to SV to determine a valid value of the data type TD, then let TV be that value. ii) Otherwise, an exception condition is raised: data exception — invalid character value for cast.
b) If SD is boolean, then TV is SV.
"""

It looks like Firebird might be violating this rule a little bit (specifically 21.a.i), because CAST('unknown' TO BOOLEAN) does not result in a null (or unknown) value. That might be my interpretation though.

For casts from boolean, it specifies (quoted from rules for variable-length character string or large object character string, but it is similar for character):

(MLTD: Maximum Length Target Domain)

"""
f) If SD is boolean, then
Case:
i) If SV is True and MLTD is not less than 4, then TV is 'TRUE'.
ii) If SV is False and MLTD is not less than 5, then TV is 'FALSE'.
iii) Otherwise, an exception condition is raised: data exception — invalid character value for cast.
"""

Again, Firebird has a minor violation of the spec here by reporting a truncation error if the MLTD is too small, instead of an equivalent of invalid character value for cast.

Also this error message is now quite confusing:
SQL> select cast(true as smallint) from rdb$database;

    CAST
=======
Statement failed, SQLSTATE = 22018
conversion error from string "BOOLEAN"

The error message is indeed wrong. at minimum I would expect "TRUE" here (even though it isn't a string value, but reporting the datatype here seems wrong to me). It should something like 'conversion error from boolean', 'conversion error from boolean to smallint', or 'invalid cast specification', or something like that.

Could you report it in the tracker. This is BTW als reproducible in Firebird 3.

This might be a historical problem. For example, CAST(1 AS TIMESTAMP) will result in a similar error "conversion error from string "1"", while it is not a string, but an integer.

Mark
--
Mark Rotteveel


Firebird-Devel mailing list, web interface at 
https://lists.sourceforge.net/lists/listinfo/firebird-devel

Reply via email to