Skip to content

Latest commit

 

History

History
798 lines (625 loc) · 20.1 KB

conversion_rules.md

File metadata and controls

798 lines (625 loc) · 20.1 KB

Conversion rules

ZetaSQL supports conversion. Conversion includes, but is not limited to, casting, coercion, and supertyping.

  • Casting is explicit conversion and uses the CAST() function.
  • Coercion is implicit conversion, which ZetaSQL performs automatically under the conditions described below.
  • A supertype is a common type to which two or more expressions can be coerced.

There are also conversions that have their own function names, such as PARSE_DATE(). To learn more about these functions, see Conversion functions

Comparison of casting and coercion

The following table summarizes all possible cast and coercion possibilities for ZetaSQL data types. The Coerce to column applies to all expressions of a given data type, (for example, a column), but literals and parameters can also be coerced. See literal coercion and parameter coercion for details.

From type Cast to Coerce to
INT32 BOOL
INT32
INT64
UINT32
UINT64
NUMERIC
BIGNUMERIC
FLOAT
DOUBLE
STRING
ENUM
INT64
NUMERIC
BIGNUMERIC
DOUBLE
INT64 BOOL
INT32
INT64
UINT32
UINT64
NUMERIC
BIGNUMERIC
FLOAT
DOUBLE
STRING
ENUM
NUMERIC
BIGNUMERIC
DOUBLE
UINT32 BOOL
INT32
INT64
UINT32
UINT64
NUMERIC
BIGNUMERIC
FLOAT
DOUBLE
STRING
ENUM
INT64
UINT64
NUMERIC
BIGNUMERIC
DOUBLE
UINT64 BOOL
INT32
INT64
UINT32
UINT64
NUMERIC
BIGNUMERIC
FLOAT
DOUBLE
STRING
ENUM
NUMERIC
BIGNUMERIC
DOUBLE
NUMERIC INT32
INT64
UINT32
UINT64
NUMERIC
BIGNUMERIC
FLOAT
DOUBLE
STRING
BIGNUMERIC
DOUBLE
BIGNUMERIC INT32
INT64
UINT32
UINT64
NUMERIC
BIGNUMERIC
FLOAT
DOUBLE
STRING
DOUBLE
FLOAT INT32
INT64
UINT32
UINT64
NUMERIC
BIGNUMERIC
FLOAT
DOUBLE
STRING
DOUBLE
DOUBLE INT32
INT64
UINT32
UINT64
NUMERIC
BIGNUMERIC
FLOAT
DOUBLE
STRING
 
BOOL BOOL
INT32
INT64
UINT32
UINT64
STRING
 
STRING BOOL
INT32
INT64
UINT32
UINT64
NUMERIC
BIGNUMERIC
FLOAT
DOUBLE
STRING
BYTES
DATE
DATETIME
TIME
TIMESTAMP
ENUM
PROTO
 
BYTES STRING
BYTES
PROTO
 
DATE STRING
DATE
DATETIME
TIMESTAMP
DATETIME
DATETIME STRING
DATE
DATETIME
TIME
TIMESTAMP
 
TIME STRING
TIME
 
TIMESTAMP STRING
DATE
DATETIME
TIME
TIMESTAMP
 
ARRAY ARRAY  
ENUM ENUM (with the same ENUM name)
INT32
INT64
UINT32
UINT64
STRING
ENUM (with the same ENUM name)
STRUCT STRUCT  
PROTO PROTO (with the same PROTO name)
STRING
BYTES
PROTO (with the same PROTO name)

Casting

Most data types can be cast from one type to another with the CAST function. When using CAST, a query can fail if ZetaSQL is unable to perform the cast. If you want to protect your queries from these types of errors, you can use SAFE_CAST. To learn more about the rules for CAST, SAFE_CAST and other casting functions, see Conversion functions.

Coercion

ZetaSQL coerces the result type of an argument expression to another type if needed to match function signatures. For example, if function func() is defined to take a single argument of type DOUBLE and an expression is used as an argument that has a result type of INT64, then the result of the expression will be coerced to DOUBLE type before func() is computed.

Literal coercion

ZetaSQL supports the following literal coercions:

Input data type Result data type Notes
Integer literal INT32
UINT32
UINT64
ENUM

Integer literals will implicitly coerce to ENUM type when necessary, or can be explicitly CAST to a specific ENUM type name.

DOUBLE literal

NUMERIC

FLOAT

Coercion may not be exact, and returns a close value.
STRING literal DATE
DATETIME
TIME
TIMESTAMP
ENUM
PROTO

String literals will implicitly coerce to PROTO or ENUM type when necessary, or can be explicitly CAST to a specific PROTO or ENUM type name.

BYTES literal PROTO  

Literal coercion is needed when the actual literal type is different from the type expected by the function in question. For example, if function func() takes a DATE argument, then the expression func("2014-09-27") is valid because the string literal "2014-09-27" is coerced to DATE.

Literal conversion is evaluated at analysis time, and gives an error if the input literal cannot be converted successfully to the target type.

Note: String literals do not coerce to numeric types.

Parameter coercion

ZetaSQL supports the following parameter coercions:

Input data type Result data type
INT32 parameter ENUM
INT64 parameter ENUM
STRING parameter DATE
DATETIME
TIME
TIMESTAMP
ENUM
PROTO
BYTES parameter PROTO

If the parameter value cannot be coerced successfully to the target type, an error is provided.

Supertypes

A supertype is a common type to which two or more expressions can be coerced. Supertypes are used with set operations such as UNION ALL and expressions such as CASE that expect multiple arguments with matching types. Each type has one or more supertypes, including itself, which defines its set of supertypes.

<tr>
  <td>BOOL</td>
  <td>BOOL</td>
</tr>


<tr>
  <td>INT32</td>
  <td>

INT32
INT64
FLOAT
DOUBLE
NUMERIC
BIGNUMERIC

<tr>
  <td>INT64</td>
  <td>

INT64
FLOAT
DOUBLE
NUMERIC
BIGNUMERIC

<tr>
  <td>UINT32</td>
  <td>

UINT32
INT64
UINT64
FLOAT
DOUBLE
NUMERIC
BIGNUMERIC

<tr>
  <td>UINT64</td>
  <td>

UINT64
FLOAT
DOUBLE
NUMERIC
BIGNUMERIC

<tr>
  <td>FLOAT</td>
  <td>

FLOAT
DOUBLE

<tr>
  <td>DOUBLE</td>
  <td>

DOUBLE

<tr>
  <td>NUMERIC</td>
  <td>

NUMERIC
BIGNUMERIC
DOUBLE

<tr>
  <td>DECIMAL</td>
  <td>

DECIMAL
BIGDECIMAL
DOUBLE

<tr>
  <td>BIGNUMERIC</td>
  <td>

BIGNUMERIC
DOUBLE

<tr>
  <td>BIGDECIMAL</td>
  <td>

BIGDECIMAL
DOUBLE

<tr>
  <td>STRING</td>
  <td>STRING</td>
</tr>


<tr>
  <td>DATE</td>
  <td>DATE</td>
</tr>


<tr>
  <td>TIME</td>
  <td>TIME</td>
</tr>


<tr>
  <td>DATETIME</td>
  <td>DATETIME</td>
</tr>


<tr>
  <td>TIMESTAMP</td>
  <td>TIMESTAMP</td>
</tr>


<tr>
  <td>ENUM</td>
  <td>
    ENUM with the same name. The resulting enum supertype is the one that
    occurred first.
  </td>
</tr>


<tr>
  <td>BYTES</td>
  <td>BYTES</td>
</tr>


<tr>
  <td>STRUCT</td>
  <td>
    STRUCT with the same field position types.
  </td>
</tr>


<tr>
  <td>ARRAY</td>
  <td>
    ARRAY with the same element types.
  </td>
</tr>


<tr>
  <td>PROTO</td>
  <td>
    PROTO with the same name. The resulting PROTO supertype is the one that
    occurred first. For example, the first occurrence could be in the
    first branch of a set operation or the first result expression in
    a CASE statement.
  </td>
</tr>


<tr>
  <td>GEOGRAPHY</td>
  <td>
    GEOGRAPHY
  </td>
</tr>
Input type Supertypes

If you want to find the supertype for a set of input types, first determine the intersection of the set of supertypes for each input type. If that set is empty then the input types have no common supertype. If that set is non-empty, then the common supertype is generally the most specific type in that set. Generally, the most specific type is the type with the most restrictive domain.

Examples

<tr>
  <td>

INT64
FLOAT

<tr>
  <td>

INT64
DOUBLE

Input types Common supertype Returns Notes
DOUBLE DOUBLE If you apply supertyping to INT64 and FLOAT, supertyping succeeds because they they share a supertype, DOUBLE.
DOUBLE DOUBLE If you apply supertyping to INT64 and DOUBLE, supertyping succeeds because they they share a supertype, DOUBLE.

INT64
BOOL

None Error If you apply supertyping to INT64 and BOOL, supertyping fails because they do not share a common supertype.

Exact and inexact types

Numeric types can be exact or inexact. For supertyping, if all of the input types are exact types, then the resulting supertype can only be an exact type.

The following table contains a list of exact and inexact numeric data types.

Exact types Inexact types

INT32
UINT32
INT64
UINT64
NUMERIC
BIGNUMERIC

FLOAT
DOUBLE

Examples

<tr>
  <td>

UINT64
INT64

<tr>
  <td>

UINT32
INT32

<tr>
  <td>

INT64
DOUBLE

<tr>
  <td>

UINT64
INT64
DOUBLE

Input types Common supertype Returns Notes
DOUBLE Error If you apply supertyping to INT64 and UINT64, supertyping fails because they are both exact numeric types and the only shared supertype is DOUBLE, which is an inexact numeric type.
INT64 INT64 If you apply supertyping to INT32 and UINT32, supertyping succeeds because they are both exact numeric types and they share an exact supertype, INT64.
DOUBLE DOUBLE If supertyping is applied to INT64 and DOUBLE, supertyping succeeds because there are exact and inexact numeric types being supertyped.
DOUBLE DOUBLE If supertyping is applied to INT64, UINT64, and DOUBLE, supertyping succeeds because there are exact and inexact numeric types being supertyped.

Types specificity

Each type has a domain of values that it supports. A type with a narrow domain is more specific than a type with a wider domain. Exact types are more specific than inexact types because inexact types have a wider range of domain values that are supported than exact types. For example, INT64 is more specific than DOUBLE.

Supertypes and literals

Supertype rules for literals are more permissive than for normal expressions, and are consistent with implicit coercion rules. The following algorithm is used when the input set of types includes types related to literals:

  • If there exists non-literals in the set, find the set of common supertypes of the non-literals.
  • If there is at least one possible supertype, find the most specific type to which the remaining literal types can be implicitly coerced and return that supertype. Otherwise, there is no supertype.
  • If the set only contains types related to literals, compute the supertype of the literal types.
  • If all input types are related to NULL literals, then the resulting supertype is INT64.
  • If no common supertype is found, an error is produced.

Examples

<tr>
  <td>
    INT64 literal<br />
    INT32 expression<br />
  </td>
  <td>INT32</td>
  <td>INT32</td>
</tr>


<tr>
  <td>
    INT64 literal<br />
    UINT32 expression<br />
  </td>
  <td>UINT32</td>
  <td>UINT32</td>
</tr>

<tr>
  <td>
    INT64 literal<br />
    UINT64 expression<br />
  </td>
  <td>UINT64</td>
  <td>UINT64</td>
</tr>

<tr>
  <td>
    DOUBLE literal<br />
    FLOAT expression<br />
  </td>
  <td>FLOAT</td>
  <td>FLOAT</td>
</tr>


<tr>
  <td>
    INT64 literal<br />
    DOUBLE literal<br />
  </td>
  <td>DOUBLE</td>
  <td>DOUBLE</td>
</tr>


<tr>
  <td>
    INT64 expression<br />
    UINT64 expression<br />
    DOUBLE literal<br />
  </td>
  <td>DOUBLE</td>
  <td>DOUBLE</td>
</tr>


<tr>
  <td>
    TIMESTAMP expression<br />
    STRING literal<br />
  </td>
  <td>TIMESTAMP</td>
  <td>TIMESTAMP</td>
</tr>

<tr>
  <td>
    NULL literal<br />
    NULL literal<br />
  </td>
  <td>INT64</td>
  <td>INT64</td>
</tr>
<tr>
  <td>
    BOOL literal<br />
    TIMESTAMP literal<br />
  </td>
  <td>None</td>
  <td>Error</td>
</tr>
Input types Common supertype Returns