When it comes to converting between data types, DuckDB performs implicit conversions when required, while also enabling us to perform explicit conversions. Implicit conversions are performed automatically by DuckDB when we do some other operation, such as use a function that requires its argument/s in a different data type than the one we’re providing. Regarding explicit conversions, we have the option of using a function like cast()
or try_cast()
, or using the shorthand method.
In this article we’ll take a quick look at how to convert between data types using the shorthand method.
Syntax
The syntax for the shorthand method of data conversions is quite simple. It goes like this:
expr::TYPENAME
Where expr
is the expression/value that you want to convert, and TYPENAME
is the name of the data type you want the value converted to.
Example
Here’s a quick example to demonstrate:
SELECT 192::VARCHAR;
If we run that using duckbox
mode in the DuckDB CLI, we might see something like this:
+----------------------+
| CAST(192 AS VARCHAR) |
| varchar |
+----------------------+
| 192 |
+----------------------+
DuckDB’s duckbox
mode helpfully presents the data type in the column header. In this case we can see that the number has been cast as a varchar
as specified. Actually, the header also shows us the cast operation as if we’d used the cast()
function. That’s the exact code we’d use if we were to use cast()
to perform the conversion. Here they are alongside each other:
SELECT
cast(192 AS varchar) AS cast_function,
192::VARCHAR AS shorthand;
Output:
+---------------+-----------+
| cast_function | shorthand |
| varchar | varchar |
+---------------+-----------+
| 192 | 192 |
+---------------+-----------+
However, if we’re not using duckbox
mode in the DuckDB CLI, we can use the typeof()
function to check the resulting data type:
SELECT typeof(192::VARCHAR);
Output:
VARCHAR
Truncation
In some cases the value may be truncated, depending on the value being converted. For example, if we convert a timestamp
value to a date
, then the time portion will be truncated.
Example:
SET VARIABLE theValue = timestamp '2029-01-01 18:30:00';
SELECT
getvariable('theValue') AS original,
getvariable('theValue')::date AS converted;
Result:
+---------------------+------------+
| original | converted |
+---------------------+------------+
| 2029-01-01 18:30:00 | 2029-01-01 |
+---------------------+------------+
Rounding
Rounding can also occur in some cases when performing conversions. For example, if we convert a decimal value to an integer, the fractional part will be removed, and the resulting integer may be rounded up or down, depending on the value of the fractional part. Basically, if the fractional part is non-zero then it will be rounded one way or another.
Example:
SET VARIABLE theValue = 21.50;
SELECT
getvariable('theValue') AS original,
getvariable('theValue')::integer AS converted;
Result:
+----------+-----------+
| original | converted |
+----------+-----------+
| 21.50 | 22 |
+----------+-----------+
In this case, the value 21.50 was rounded up to 22.
Here’s what happens when the fractional part is lower than .50:
SET VARIABLE theValue = 21.49;
SELECT
getvariable('theValue') AS original,
getvariable('theValue')::integer AS converted;
Result:
+----------+-----------+
| original | converted |
+----------+-----------+
| 21.49 | 21 |
+----------+-----------+
This time it was rounded down.
When a Value Can’t Be Converted
Some data types simply can’t be converted to another data type. For example we can’t convert a number to a date. And we can’t convert a string like “duckdb” to an integer. When we try to perform such conversions, DuckDB will usually throw an error.
Here’s an example of trying to convert a number to a date:
SELECT 20201010::date;
Output:
Conversion Error:
Unimplemented type for cast (INTEGER -> DATE)
LINE 1: SELECT 20201010::date;
^
And here’s one that fails when we try to convert a string to an integer:
SELECT 'duckdb'::integer;
Output:
Conversion Error:
Could not convert string 'duckdb' to INT32
LINE 1: SELECT 'duckdb'::integer;
^
But not all strings will fail. If the string resembles a number, then DuckDB will work it out and go ahead with the conversion:
SELECT '123'::integer;
Output:
+------------------------+
| CAST('123' AS INTEGER) |
| int32 |
+------------------------+
| 123 |
+------------------------+