8.5Type Casting Functions

8.5.1CAST()

Converts a value from one data type to another

Result typeAs specified by target_type

Syntax

  |CAST (<expression> AS <target_type>)
  | 
  |<target_type> ::= <domain_or_non_array_type> | <array_datatype>
  | 
  |<domain_or_non_array_type> ::=
  |  !! See Scalar Data Types Syntax !!
  | 
  |<array_datatype> ::=
  |  !! See Array Data Types Syntax !!

Table 8.62CAST Function Parameters
ParameterDescription

expression

SQL expression

sql_datatype

SQL data type

CAST converts an expression to the desired data type or domain. If the conversion is not possible, an error is raised.

8.5.1.1Shorthand Syntax

Alternative syntax, supported only when casting a string literal to a DATE, TIME or TIMESTAMP:

  |datatype 'date/timestring'

This syntax was already available in InterBase, but was never properly documented. In the SQL standard, this feature is called datetime literals.

Note

Since Firebird 4.0, the use of 'NOW', 'YESTERDAY' and 'TOMORROW' in the shorthand cast is no longer allowed; only literals defining a fixed moment in time are supported.

8.5.1.2Allowed Type Conversions

The following table shows the type conversions possible with CAST.

Table 8.63Possible Type-castings with CAST
FromTo

Numeric types

Numeric types [VAR]CHAR BLOB

[VAR]CHAR BLOB

[VAR]CHAR BLOB Numeric types DATE TIME TIMESTAMP

DATE TIME

[VAR]CHAR BLOB TIMESTAMP

TIMESTAMP

[VAR]CHAR BLOB DATE TIME

Keep in mind that sometimes information is lost, for instance when you cast a TIMESTAMP to a DATE. Also, the fact that types are CAST-compatible is in itself no guarantee that a conversion will succeed. CAST(123456789 as SMALLINT) will definitely result in an error, as will CAST('Judgement Day' as DATE).

8.5.1.3Casting Parameters

You can also cast statement parameters to a data type:

  |cast (? as integer)

This gives you control over the type of the parameter set up by the engine. Please notice that with statement parameters, you always need a full-syntax cast — shorthand casts are not supported.

8.5.1.4Casting to a Domain or its Type

Casting to a domain or its base type are supported. When casting to a domain, any constraints (NOT NULL and/or CHECK) declared for the domain must be satisfied, or the cast will fail. Please be aware that a CHECK passes if it evaluates to TRUE or NULL! So, given the following statements:

  |create domain quint as int check (value >= 5000);
  |select cast (2000 as quint) from rdb$database;     
  |select cast (8000 as quint) from rdb$database;     
  |select cast (null as quint) from rdb$database;     

only cast number 1 will result in an error.

When the TYPE OF modifier is used, the expression is cast to the base type of the domain, ignoring any constraints. With domain quint defined as above, the following two casts are equivalent and will both succeed:

  |select cast (2000 as type of quint) from rdb$database;
  |select cast (2000 as int) from rdb$database;

If TYPE OF is used with a (VAR)CHAR type, its character set and collation are retained:

   |create domain iso20 varchar(20) character set iso8859_1;
   |create domain dunl20 varchar(20) character set iso8859_1 collate du_nl;
   |create table zinnen (zin varchar(20));
   |commit;
   |insert into zinnen values ('Deze');
   |insert into zinnen values ('Die');
   |insert into zinnen values ('die');
   |insert into zinnen values ('deze');
   | 
   |select cast(zin as type of iso20) from zinnen order by 1;
   |-- returns Deze -> Die -> deze -> die
   | 
   |select cast(zin as type of dunl20) from zinnen order by 1;
   |-- returns deze -> Deze -> die -> Die
🛑
Warning

If a domain’s definition is changed, existing CASTs to that domain or its type may become invalid. If these CASTs occur in PSQL modules, their invalidation may be detected. See the note The RDB$VALID_BLR field, in Appendix A.

8.5.1.5Casting to a Column’s Type

It is also possible to cast expressions to the type of an existing table or view column. Only the type itself is used; in the case of string types, this includes the character set but not the collation. Constraints and default values of the source column are not applied.

  |create table ttt (
  |  s varchar(40) character set utf8 collate unicode_ci_ai
  |);
  |commit;
  | 
  |select cast ('Jag har många vänner' as type of column ttt.s)
  |from rdb$database;
🛑
Warning

If a column’s definition is altered, existing CASTs to that column’s type may become invalid. If these CASTs occur in PSQL modules, their invalidation may be detected. See the note The RDB$VALID_BLR field, in Appendix A.

8.5.1.6Cast Examples

A full-syntax cast:

  |select cast ('12' || '-June-' || '1959' as date) from rdb$database

A shorthand string-to-date cast:

  |update People set AgeCat = 'Old'
  |  where BirthDate < date '1-Jan-1943'

Notice that you can drop even the shorthand cast from the example above, as the engine will understand from the context (comparison to a DATE field) how to interpret the string:

  |update People set AgeCat = 'Old'
  |  where BirthDate < '1-Jan-1943'

However, this is not always possible. The cast below cannot be dropped, otherwise the engine would find itself with an integer to be subtracted from a string:

  |select cast('today' as date) - 7 from rdb$database