Conversion rules

January 30, 2026 · View on GitHub

GoogleSQL supports conversion. Conversion includes, but isn't limited to, casting, coercion, and supertyping.

  • Casting is explicit conversion and uses the CAST() function.
  • Coercion is implicit conversion, which GoogleSQL 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 GoogleSQL 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 query parameter coercion for details.

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

BOOL
INT32
INT64
UINT32
UINT64
NUMERIC
BIGNUMERIC
FLOAT
DOUBLE
STRING
ENUM

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

BOOL
INT32
INT64
UINT32
UINT64
NUMERIC
BIGNUMERIC
FLOAT
DOUBLE
STRING
ENUM

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

BOOL
INT32
INT64
UINT32
UINT64
NUMERIC
BIGNUMERIC
FLOAT
DOUBLE
STRING
ENUM

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

BOOL
INT32
INT64
UINT32
UINT64
NUMERIC
BIGNUMERIC
FLOAT
DOUBLE
STRING
ENUM

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

INT32
INT64
UINT32
UINT64
NUMERIC
BIGNUMERIC
FLOAT
DOUBLE
STRING

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

INT32
INT64
UINT32
UINT64
NUMERIC
BIGNUMERIC
FLOAT
DOUBLE
STRING

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

INT32
INT64
UINT32
UINT64
NUMERIC
BIGNUMERIC
FLOAT
DOUBLE
STRING

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

INT32
INT64
UINT32
UINT64
NUMERIC
BIGNUMERIC
FLOAT
DOUBLE
STRING

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

BOOL
INT32
INT64
UINT32
UINT64
STRING

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

BOOL
INT32
INT64
UINT32
UINT64
NUMERIC
BIGNUMERIC
FLOAT
DOUBLE
STRING
BYTES
DATE
DATETIME
TIME
TIMESTAMP
ENUM
PROTO
RANGE

  </td>
  <td>&nbsp;</td>
</tr>

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

STRING
BYTES
PROTO

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

STRING
DATE
DATETIME
TIMESTAMP

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

STRING
DATE
DATETIME
TIME
TIMESTAMP

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

STRING
TIME

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

STRING
DATE
DATETIME
TIME
TIMESTAMP

<tr>
  <td><code>ARRAY</code></td>
  <td>

ARRAY

<tr>
  <td><code>ENUM</code></td>
  <td>
    <span>
      <code>ENUM</code>
      (with the same <code>ENUM</code> name)
    </span><br />
    

INT32
INT64
UINT32
UINT64
STRING

  </td>
  <td><code>ENUM</code> (with the same <code>ENUM</code> name)</td>
</tr>

<tr>
  <td><code>STRUCT</code></td>
  <td>

STRUCT

<tr>
  <td><code>PROTO</code></td>
  <td>
    <span>
      <code>PROTO</code>
      (with the same <code>PROTO</code> name)
    </span><br />
    

STRING
BYTES

  </td>
  <td><code>PROTO</code> (with the same <code>PROTO</code> name)</td>
</tr>

<tr>
  <td><code>RANGE</code></td>
  <td>

RANGE
STRING

From type Cast to Coerce to

INT64
NUMERIC
BIGNUMERIC
DOUBLE

NUMERIC
BIGNUMERIC
DOUBLE

INT64
UINT64
NUMERIC
BIGNUMERIC
DOUBLE

NUMERIC
BIGNUMERIC
DOUBLE

BIGNUMERIC
DOUBLE

DOUBLE

DOUBLE

 
 
 

DATETIME

 
 
 
 
 
 

Casting

Most data types can be cast from one type to another with the CAST function. When using CAST, a query can fail if GoogleSQL 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

GoogleSQL 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

GoogleSQL supports the following literal coercions:

Input data type Result data type Notes
Integer literal

INT32
UINT32
UINT64
ENUM

  Integer literals will implicitly coerce to <code>ENUM</code> type when
  necessary, or can be explicitly cast to a specific
  <code>ENUM</code> type name.
  
</td>
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 <code>PROTO</code> or
  <code>ENUM</code> type when necessary, or can be explicitly cast to a specific
  <code>PROTO</code> or <code>ENUM</code> type name.
  
</td>
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 can't be converted successfully to the target type.

Note: String literals don't coerce to numeric types.

Query parameter coercion

GoogleSQL supports the following query parameter coercions:

<tr>
  <td><code>INT32</code> parameter</td>
  <td>

ENUM

<tr>
  <td><code>INT64</code> parameter</td>
  <td>

ENUM

<tr>
  <td><code>STRING parameter</code></td>
  <td>

DATE
DATETIME
TIME
TIMESTAMP
ENUM
PROTO

<tr>
  <td><code>BYTES</code> parameter</td>
  <td><code>PROTO</code></td>
</tr>

<tr>
  <td><code>GRAPH_ELEMENT</code> parameter</td>
  <td>
    

GRAPH_ELEMENT

    <p>
      Coercion is only allowed from one graph element type to another
      graph element type if the second graph element type is a supertype of
      the first. After the conversion, the graph element type can access the
      properties that are described in its supertype.
    </p>
    <p>
      With <code>GRAPH_ELEMENT</code> coercion, the property reference
      returns <code>NULL</code>.
    </p>
  </td>
</tr>
Input data type Result data type

If the parameter value can't 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><code>BOOL</code></td>
  <td>

BOOL

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

INT32
INT64
FLOAT
DOUBLE
NUMERIC
BIGNUMERIC

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

INT64
FLOAT
DOUBLE
NUMERIC
BIGNUMERIC

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

UINT32
INT64
UINT64
FLOAT
DOUBLE
NUMERIC
BIGNUMERIC

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

UINT64
FLOAT
DOUBLE
NUMERIC
BIGNUMERIC

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

FLOAT
DOUBLE

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

DOUBLE

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

NUMERIC
BIGNUMERIC
DOUBLE

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

DECIMAL
BIGDECIMAL
DOUBLE

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

BIGNUMERIC
DOUBLE

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

BIGDECIMAL
DOUBLE

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

STRING

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

DATE

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

TIME

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

DATETIME

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

TIMESTAMP

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

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

BYTES

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

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

<tr>
  <td><code>PROTO</code></td>
  <td>
    <code>PROTO</code> with the same name. The resulting <code>PROTO</code>
    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 <code>CASE</code> statement.
  </td>
</tr>

<tr>
  <td><code>GEOGRAPHY</code></td>
  <td>

GEOGRAPHY

<tr>
  <td><code>GRAPH_ELEMENT</code></td>
  <td>
    <code>GRAPH_ELEMENT</code>. A graph element can be a supertype of
    another graph element if the following is true:
    <ul>
      <li>
        Graph element <code>a</code> is a supertype of graph element
        <code>b</code> and they're the same element kind.
      </li>
      <li>
        Graph element <code>a</code>'s property type list is a
        compatible superset of graph element <code>b</code>'s
        property type list. This means that properties with the same name
        must also have the same type.
      </li>
    </ul>
  </td>
</tr>

<tr>
  <td><code>RANGE</code></td>
  <td><code>RANGE</code> with the same subtype.</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 don't 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>
    <code>INT64</code> literal<br />
    <code>INT32</code> expression<br />
  </td>
  <td><code>INT32</code></td>
  <td><code>INT32</code></td>
</tr>


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

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

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


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


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


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

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