Data type conversion¶
In many cases, a value of one data type can be converted to another data type. For example, an INTEGER can be converted to a floating-point data type. Converting a data type is called casting.
Explicit casting vs implicit casting¶
Users can explicitly convert a value from one data type to another. This is called explicit casting.
In some situations, Snowflake converts a value to another data type automatically. This is called implicit casting or coercion.
Explicit casting¶
Users can explicitly cast a value by using any of the following options:
The CAST function.
The
::
operator (called the cast operator).The appropriate SQL function (e.g. TO_DOUBLE).
For example:
SELECT CAST('2022-04-01' AS DATE); SELECT '2022-04-01'::DATE; SELECT TO_DATE('2022-04-01');
Casting is allowed in most contexts in which a general expression is allowed, including the WHERE clause. For example:
SELECT date_column FROM log_table WHERE date_column >= '2022-04-01'::DATE;
Implicit casting (“coercion”)¶
Coercion occurs when a function (or operator) requires a data type that is different from, but compatible with, the arguments (or operands).
Examples for functions or stored procedures:
The following code coerces the INTEGER value in column
my_integer_column
to FLOAT so that the value can be passed to the functionmy_float_function()
, which expects a FLOAT:SELECT my_float_function(my_integer_column) FROM my_table;
Examples for operators:
The following code coerces the INTEGER value
17
to VARCHAR so that the values can be concatenated by using the||
operator:SELECT 17 || '76';
The result of this SELECT statement is the string
'1776'
.The following statement coerces the INTEGER value in column
my_integer_column
to FLOAT so that the value can be compared to the valuemy_float_column
using the<
comparison operator:SELECT ... FROM my_table WHERE my_integer_column < my_float_column;
Not all contexts (e.g. not all operators) support coercion.
Casting and precedence¶
When casting inside an expression, the code must take into account the precedence of the cast operator relative to other operators in the expression.
Consider the following example:
SELECT height * width::VARCHAR || " square meters" FROM dimensions;
The cast operator has higher precedence than the arithmetic operator *
(multiply), so the statement is interpreted as:
... height * (width::VARCHAR) ...
To cast the result of the expression height * width
, use parentheses, as shown below:
SELECT (height * width)::VARCHAR || " square meters" FROM dimensions;
As another example, consider the following statement:
SELECT -0.0::FLOAT::BOOLEAN;
You might expect this to be interpreted as:
SELECT (-0.0::FLOAT)::BOOLEAN;
and therefore to return FALSE (0 = FALSE, 1 = TRUE).
However, the cast operator has higher precedence than the unary minus (negation) operator, so the statement is interpreted as:
SELECT -(0.0::FLOAT::BOOLEAN);
and therefore results in an error message because the unary minus cannot be applied to a BOOLEAN.
Data types that can be cast¶
The table below shows the valid data type conversions in Snowflake. The table also shows which coercions Snowflake can perform automatically.
Note
Internally, the CAST function and the ::
operator call the appropriate conversion
function. For example, if you cast a NUMBER to a BOOLEAN, then Snowflake calls the TO_BOOLEAN
function. The usage notes for each conversion function apply when the function is called indirectly via a cast, as well as when
the function is called directly. For example, if you execute CAST(my_decimal_column as BOOLEAN)
, the rules for calling
TO_BOOLEAN
with a DECIMAL value apply. For convenience, the “Notes” column in the table below includes links to the
relevant conversion functions.
For details on conversions between semi-structured types and structured types, see Converting structured and semi-structured types.
Source Data Type |
Target Data Type |
Castable |
Coercible |
Conversion Function |
Notes |
---|---|---|---|---|---|
ARRAY |
|||||
✔ |
❌ |
||||
✔ |
✔ |
||||
✔ |
✔ |
||||
BINARY |
|||||
✔ |
❌ |
||||
✔ |
❌ |
||||
BOOLEAN |
|||||
✔ |
❌ |
||||
✔ |
✔ |
For example, from TRUE to ‘true’. |
|||
✔ |
✔ |
||||
DATE |
|||||
✔ |
✔ |
||||
✔ |
✔ |
||||
✔ |
❌ |
||||
FLOAT . (Floating-point numbers) |
|||||
✔ |
✔ |
For example, from 0.0 to FALSE. |
|||
✔ |
✔ |
||||
✔ |
✔ |
||||
✔ |
✔ |
||||
GEOGRAPHY |
|||||
✔ |
❌ |
||||
GEOMETRY |
|||||
✔ |
❌ |
||||
NUMBER[(p,s)] . (Fixed-point numbers, including INTEGER) |
|||||
✔ |
✔ |
For example, from 0 to FALSE. |
|||
✔ |
✔ |
||||
✔ |
✔ |
||||
✔ |
✔ |
||||
✔ |
✔ |
||||
OBJECT |
|||||
✔ |
❌ |
||||
✔ |
❌ |
||||
✔ |
✔ |
||||
TIME |
|||||
✔ |
✔ |
||||
✔ |
❌ |
||||
TIMESTAMP |
|||||
✔ |
✔ |
||||
✔ |
✔ |
||||
✔ |
✔ |
||||
✔ |
❌ |
||||
VARCHAR |
|||||
✔ |
✔ |
For example, from ‘false’ to FALSE. |
|||
✔ |
✔ |
||||
✔ |
✔ |
For example, from ‘12.34’ to 12.34. |
|||
✔ |
✔ |
For example, from ‘12.34’ to 12.34. |
|||
✔ |
✔ |
||||
✔ |
✔ |
||||
✔ |
❌ |
||||
VARIANT |
|||||
✔ |
✔ |
||||
✔ |
✔ |
For example, from a VARIANT containing ‘false’ to FALSE. |
|||
✔ |
✔ |
||||
✔ |
✔ |
||||
✔ |
❌ |
||||
✔ |
✔ |
||||
✔ |
✔ |
||||
✔ |
✔ |
||||
✔ |
✔ |
||||
✔ |
✔ |
||||
✔ |
❌ |
The VARIANT must contain an ARRAY of type FLOAT or INT. |
|||
VECTOR |
|||||
✔ |
✔ |
Notes:
For each listed data type (e.g. FLOAT), the rules apply for all aliases for that data type (e.g. the rules for FLOAT apply to DOUBLE, which is an alias for FLOAT).
Usage notes¶
Except where stated otherwise, the following rules apply to both explicit casting and implicit casting.
Conversion depends not only upon the data type, but also the value, of the source. For example:
The VARCHAR ‘123’ can be converted to a numeric value, but the VARCHAR ‘xyz’ cannot be converted to a numeric value.
The ability to cast a specific value of type VARIANT depends upon the type of the data inside the VARIANT. For example, if the VARIANT contains a value of type TIME, then you cannot cast the VARIANT to a TIMESTAMP because you cannot cast TIME to TIMESTAMP.
If possible, pass in arguments of the same type. Avoid passing in arguments of different types.
If one of the arguments is a number, the function coerces non-numeric string arguments (e.g.
'a string'
) and string arguments that are not constants to the type NUMBER(18,5).For numeric string arguments that are not constants, if NUMBER(18,5) is not sufficient to represent the numeric value, you should cast the argument to a type that can represent the value.
For some pairs of data types, conversion can result in loss of precision. For example:
Converting FLOAT to INTEGER rounds the value.
Converting a value from fixed-point numeric (e.g. NUMBER(38, 0)) to floating point (e.g. FLOAT) can result in rounding or truncation if the fixed-point number cannot be precisely represented in a floating point number.
Converting a TIMESTAMP to a DATE removes the information about the time of day.
Although Snowflake converts values in some situations where loss of precision can occur, Snowflake does not allow conversion in other situations where a loss of precision would occur. For example, Snowflake does not allow conversion when conversion would:
Truncate a VARCHAR value. For example, Snowflake does not cast VARCHAR(10) to VARCHAR(5), either implicitly or explicitly.
Result in the loss of digits other than the least significant digits. For example, the following fails:
select 12.3::FLOAT::NUMBER(3,2);
In this example, the number
12.3
has two digits prior to the decimal point, but the data typeNUMBER(3,2)
has room for only one digit before the decimal point.When converting from a type with less precision to a type with more precision, conversion uses default values. For example, converting a DATE to a TIMESTAMP_NTZ causes the hour, minute, second, and fractional seconds to be set to 0.
When a FLOAT value is cast to a VARCHAR, trailing zeros are omitted.
For example, the following statements create a table and insert a row that contains a VARCHAR, a FLOAT, and a VARIANT. The VARIANT is constructed from JSON that contains a floating-point value represented with trailing zeros.
create or replace table tmp ( varchar1 varchar, float1 float, variant1 variant ); insert into tmp select '5.000', 5.000, parse_json('{"Loan Number": 5.000}');
The following SELECT statement explicitly casts both the FLOAT column and the FLOAT value inside the VARIANT column to VARCHAR. In each case, the VARCHAR contains no trailing zeros:
select varchar1, float1::varchar, variant1:"Loan Number"::varchar from tmp; +----------+-----------------+---------------------------------+ | VARCHAR1 | FLOAT1::VARCHAR | VARIANT1:"LOAN NUMBER"::VARCHAR | |----------+-----------------+---------------------------------| | 5.000 | 5 | 5 | +----------+-----------------+---------------------------------+
Some operations can return different data types, depending upon a conditional expression. For example, the following COALESCE calls return slightly different data types depending upon the input values:
select system$typeof(ifnull(12.3, 0)), system$typeof(ifnull(NULL, 0)); +--------------------------------+--------------------------------+ | SYSTEM$TYPEOF(IFNULL(12.3, 0)) | SYSTEM$TYPEOF(IFNULL(NULL, 0)) | +--------------------------------+--------------------------------+ | NUMBER(3,1)[SB1] | NUMBER(1,0)[SB1] | +--------------------------------+--------------------------------+
If the expression has more than one possible data type, then Snowflake chooses the data type based on the actual result. (For more information about precision and scale in calculations, see Scale and precision in arithmetic operations.) If the query generates more than one result (e.g. multiple rows of results), then Snowflake chooses a data type that is capable of holding each of the individual results.
Some application programs, such as SnowSQL, and some graphical user interfaces, such as the Classic Console, apply their own conversion and formatting rules when displaying data. For example, SnowSQL displays BINARY values as a string that contains only hexadecimal digits; that string is generated by implicitly calling a conversion function. Therefore, the data that SnowSQL displays might not unambiguously indicate which data conversions Snowflake coerced.