Data types Stay organized with collections Save and categorize content based on your preferences.
This page provides an overview of all GoogleSQL for Bigtabledata types, including information about their valuedomains. Forinformation on data type literals and constructors, seeLexical Structure and Syntax.
Data type list
| Name | Summary |
|---|---|
| Array type | An ordered list of zero or more elements of non-array values. SQL type name: ARRAY |
| Boolean type | A value that can be eitherTRUE orFALSE.SQL type name: BOOLSQL aliases: BOOLEAN |
| Bytes type | Variable-length binary data. SQL type name: BYTES |
| Date type | A Gregorian calendar date, independent of time zone. SQL type name: DATE |
| Enum type | Named type that enumerates a list of possible values. SQL type name: ENUM |
| Map type | Unordered collection of keys and associated values. SQL type name: MAP |
| Numeric types | A numeric value. Several types are supported. A 64-bit integer. An approximate single precision numeric value. An approximate double precision numeric value. |
| String type | Variable-length character data. SQL type name: STRING |
| Struct type | Container of ordered fields. SQL type name: STRUCT |
| Timestamp type | A timestamp value represents an absolute point in time, independent of any time zone or convention such as daylight saving time (DST). SQL type name: TIMESTAMP |
Data type properties
When storing and querying data, it's helpful to keep the following data typeproperties in mind:
Nullable data types
For nullable data types,NULL is a valid value. Currently, all existingdata types are nullable.
Orderable data types
Expressions of orderable data types can be used in anORDER BY clause.Applies to all data types except for:
STRUCTMAP
OrderingNULLs
In the context of theORDER BY clause,NULLs are the minimumpossible value; that is,NULLs appear first inASC sorts.
To learn more about usingASC, seetheORDER BY clause.
Ordering floating points
Floating point values are sorted in this order, from least to greatest:
NULLNaN— AllNaNvalues are considered equal when sorting.-inf- Negative numbers
- 0 or -0 — All zero values are considered equal when sorting.
- Positive numbers
+inf
Ordering arrays
ARRAY<T> is orderable if its type,T, is orderable. Empty arrays aresorted before non-empty arrays. Non-empty arrays are sortedlexicographically by element. An array that's a strict prefix of another arrayorders less than the longer array.
Lexicographical ordering for arrays first compares the elements of each arrayfrom the first element to the last. If an element orders before a correspondingelement in another array, then the arrays are ordered accordingly. Subsequentarray elements are ignored.
For example:
Groupable data types
Can generally appear in an expression followingGROUP BY andDISTINCT.All data types are supported except for:
MAPARRAYSTRUCT
Comparable data types
Values of the same comparable data type can be compared to each other.All data types are supported except for:
MAPARRAY
Notes:
- Equality comparisons for structs are supported field by field, infield order. Field names are ignored. Less than and greater than comparisonsaren't supported.
Collatable data types
Collatable data types support collation, which determines how to sort andcompare strings. These data types support collation:
- String
- String fields in a struct
- String elements in an array
Array type
| Name | Description |
|---|---|
ARRAY | Ordered list of zero or more elements of any non-array type. |
An array is an ordered list of zero or more elements of non-array values.Elements in an array must share the same type.
Arrays of arrays aren't allowed. Queries that would produce an array ofarrays return an error. Instead, a struct must be inserted between thearrays using theSELECT AS STRUCT construct.
To learn more about the literal representation of an array type,seeArray literals.
NULLs and the array type
An empty array and aNULL array are two distinct values. Arrays can containNULL elements.
Declaring an array type
ARRAY<T>Array types are declared using the angle brackets (< and>). The typeof the elements of an array can be arbitrarily complex with the exception thatan array can't directly contain another array.
Examples
| Type Declaration | Meaning |
|---|---|
ARRAY<INT64> | Simple array of 64-bit integers. |
ARRAY<STRUCT<INT64, INT64>> | An array of structs, each of which contains two 64-bit integers. |
ARRAY<ARRAY<INT64>>(not supported) | This is aninvalid type declaration which is included herejust in case you came looking for how to create a multi-level array. Arrayscan't contain arrays directly. Instead see the next example. |
ARRAY<STRUCT<ARRAY<INT64>>> | An array of arrays of 64-bit integers. Notice that there is a struct betweenthe two arrays because arrays can't hold other arrays directly. |
Constructing an array
You can construct an array using array literals or array functions.
Using array literals
You can build an array literal in GoogleSQL using brackets ([ and]). Each element in an array is separated by a comma.
SELECT[1,2,3]ASnumbers;SELECT["apple","pear","orange"]ASfruit;SELECT[true,false,true]ASbooleans;You can also create arrays from any expressions that have compatible types.
To declare a specific data type for an array, use anglebrackets (< and>). For example:
SELECTARRAY<FLOAT64>[1,2,3]ASfloats;Arrays of most data types, such asINT64 orSTRING, don't requirethat you declare them first.
SELECT[1,2,3]ASnumbers;You can write an empty array of a specific type usingARRAY<type>[]. You canalso write an untyped empty array using[], in which case GoogleSQLattempts to infer the array type from the surrounding context. IfGoogleSQL can't infer a type, the default typeARRAY<INT64> is used.
Using generated values
You can also construct anARRAY with generated values.
Generating arrays of integers
GENERATE_ARRAYgenerates an array of values from a starting and ending value and a step value.For example, the following query generates an array that contains all of the oddintegers from 11 to 33, inclusive:
SELECTGENERATE_ARRAY(11,33,2)ASodds;/*--------------------------------------------------+ | odds | +--------------------------------------------------+ | [11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33] | +--------------------------------------------------*/You can also generate an array of values in descending order by giving anegative step value:
SELECTGENERATE_ARRAY(21,14,-1)AScountdown;/*----------------------------------+ | countdown | +----------------------------------+ | [21, 20, 19, 18, 17, 16, 15, 14] | +----------------------------------*/Generating arrays of dates
GENERATE_DATE_ARRAYgenerates an array ofDATEs from a starting and endingDATE and a stepINTERVAL.
You can generate a set ofDATE values usingGENERATE_DATE_ARRAY. Forexample, this query returns the currentDATE and the followingDATEs at 1WEEK intervals up to and including a laterDATE:
SELECTGENERATE_DATE_ARRAY('2017-11-21','2017-12-31',INTERVAL1WEEK)ASdate_array;/*--------------------------------------------------------------------------+ | date_array | +--------------------------------------------------------------------------+ | [2017-11-21, 2017-11-28, 2017-12-05, 2017-12-12, 2017-12-19, 2017-12-26] | +--------------------------------------------------------------------------*/Boolean type
| Name | Description |
|---|---|
BOOLBOOLEAN | Boolean values are represented by the keywordsTRUE andFALSE (case-insensitive). |
BOOLEAN is an alias forBOOL.
Boolean values are sorted in this order, from least to greatest:
NULLFALSETRUE
Bytes type
| Name | Description |
|---|---|
BYTES | Variable-length binary data. |
String and bytes are separate types that can't be used interchangeably.Most functions on strings are also defined on bytes. The bytes versionoperates on raw bytes rather than Unicode characters. Casts between string andbytes enforce that the bytes are encoded using UTF-8.
You can convert a base64-encodedSTRING expression into theBYTES formatusing theFROM_BASE64 function.You can also convert a sequence ofBYTES into a base64-encodedSTRINGexpression using theTO_BASE64 function.
To learn more about the literal representation of a bytes type,seeBytes literals.
Date type
| Name | Range |
|---|---|
DATE | 0001-01-01 to 9999-12-31. |
The date type represents a Gregorian calendar date, independent of time zone. Adate value doesn't represent a specific 24-hour time period. Rather, a givendate value represents a different 24-hour period when interpreted in differenttime zones, and may represent a shorter or longer day during daylight savingtime (DST) transitions.To represent an absolute point in time,use atimestamp.
Canonical format
YYYY-[M]M-[D]DYYYY: Four-digit year.[M]M: One or two digit month.[D]D: One or two digit day.
To learn more about the literal representation of a date type,seeDate literals.
Enum type
| Name | Description |
|---|---|
ENUM | Named type that maps string constants to integer constants. |
An enum is a named type that enumerates a list of possible values, each of whichcontains:
- An integer value: Integers are used for comparison and ordering enum values.There is no requirement that these integers start at zero or that they becontiguous.
- A string value for its name: Strings are case sensitive. In the case ofprotocol buffer open enums, this name is optional.
- Optional alias values: One or more additional string values that act asaliases.
Enum values are referenced using their integer value or their string value.You reference an enum type, such as when using CAST, by using its fullyqualified name.
You can't create new enum types using GoogleSQL.
To learn more about the literal representation of an enum type,seeEnum literals.
Map type
| Name | Description |
|---|---|
MAP | Unordered collection of keys and associated values. |
Declaring a map type
MAP<KEY_TYPE,VALUE_TYPE>To declare a map type, you must include angle brackets (< and>) andthe data types for the map keys and values.
KEY_TYPE: The data type for the key. Groupable data types are allowed.VALUE_TYPE: The data type for the key's associated value. All data typesare allowed.
Numeric types
Numeric types include the following types:
INT64FLOAT32FLOAT64
Integer type
Integers are numeric values that don't have fractional components.
| Name | Range |
|---|---|
INT64 | -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 |
To learn more about the literal representation of an integer type,seeInteger literals.
Floating point types
Floating point values are approximate numeric values with fractional components.
| Name | Description |
|---|---|
FLOAT32 | Single precision (approximate) numeric values. |
FLOAT64 | Double precision (approximate) numeric values. |
To learn more about the literal representation of a floating point type,seeFloating point literals.
Floating point semantics
When working with floating point numbers, there are special non-numeric valuesthat need to be considered:NaN and+/-inf
Arithmetic operators provide standard IEEE-754 behavior for all finite inputvalues that produce finite output and for all operations for which at least oneinput is non-finite.
Function calls and operators return an overflow error if the input is finitebut the output would be non-finite. If the input contains non-finite values, theoutput can be non-finite. In general functions don't introduceNaNs or+/-inf. However, specific functions likeIEEE_DIVIDE can return non-finitevalues on finite input. All such cases are noted explicitly inMathematical functions.
Floating point values are approximations.
- The binary format used to represent floating point values can only representa subset of the numbers between the most positive number and mostnegative number in the value range. This enables efficient handling of amuch larger range than would be possible otherwise.Numbers that aren't exactly representable are approximated by utilizing aclose value instead. For example,
0.1can't be represented as an integerscaled by a power of2. When this value is displayed as a string, it'srounded to a limited number of digits, and the value approximating0.1might appear as"0.1", hiding the fact that the value isn't precise.In other situations, the approximation can be visible. - Summation of floating point values might produce surprising results becauseoflimited precision. For example,
(1e30 + 1) - 1e30 = 0, while(1e30 - 1e30) + 1 = 1.0. This isbecause the floating point value doesn't have enough precision torepresent(1e30 + 1), and the result is rounded to1e30.This example also shows that the result of theSUMaggregate function offloating points values depends on the order in which the values areaccumulated. In general, this order isn't deterministic and therefore theresult isn't deterministic. Thus, the resultingSUMoffloating point values might not be deterministic and two executions of thesame query on the same tables might produce different results.
Mathematical function examples
| Left Term | Operator | Right Term | Returns |
|---|---|---|---|
| Any value | + | NaN | NaN |
| 1.0 | + | +inf | +inf |
| 1.0 | + | -inf | -inf |
-inf | + | +inf | NaN |
MaximumFLOAT64 value | + | MaximumFLOAT64 value | Overflow error |
MinimumFLOAT64 value | / | 2.0 | 0.0 |
| 1.0 | / | 0.0 | "Divide by zero" error |
Comparison operators provide standard IEEE-754 behavior for floating pointinput.
Comparison operator examples
| Left Term | Operator | Right Term | Returns |
|---|---|---|---|
NaN | = | Any value | FALSE |
NaN | < | Any value | FALSE |
| Any value | < | NaN | FALSE |
| -0.0 | = | 0.0 | TRUE |
| -0.0 | < | 0.0 | FALSE |
For more information on how these values are ordered and grouped so theycan be compared,seeOrdering floating point values.
String type
| Name | Description |
|---|---|
STRING | Variable-length character (Unicode) data. |
Input string values must be UTF-8 encoded and output string values will be UTF-8encoded. Alternate encodings like CESU-8 and Modified UTF-8 aren't treated asvalid UTF-8.
All functions and operators that act on string values operate on Unicodecharacters rather than bytes. For example, functions likeSUBSTR andLENGTHapplied to string input count the number of characters, not bytes.
Each Unicode character has a numeric value called a code point assigned to it.Lower code points are assigned to lower characters. When characters arecompared, the code points determine which characters are less than or greaterthan other characters.
Most functions on strings are also defined on bytes. The bytes versionoperates on raw bytes rather than Unicode characters. Strings and bytes areseparate types that can't be used interchangeably. There is no implicit castingin either direction. Explicit casting between string and bytes doesUTF-8 encoding and decoding. Casting bytes to string returns an error if thebytes aren't valid UTF-8.
To learn more about the literal representation of a string type,seeString literals.
Struct type
| Name | Description |
|---|---|
STRUCT | Container of ordered fields each with a type (required) and field name(optional). |
To learn more about the literal representation of a struct type,seeStruct literals.
Declaring a struct type
STRUCT<T>Struct types are declared using the angle brackets (< and>). The type ofthe elements of a struct can be arbitrarily complex.
Examples
| Type Declaration | Meaning |
|---|---|
STRUCT<INT64> | Simple struct with a single unnamed 64-bit integer field. |
STRUCT<x STRUCT<y INT64, z INT64>> | A struct with a nested struct namedx inside it. The structx has two fields,y andz, both of whichare 64-bit integers. |
STRUCT<inner_array ARRAY<INT64>> | A struct containing an array namedinner_array that holds64-bit integer elements. |
Constructing a struct
Tuple syntax
(expr1,expr2[,...])The output type is an anonymous struct type with anonymous fields with typesmatching the types of the input expressions. There must be at least twoexpressions specified. Otherwise this syntax is indistinguishable from anexpression wrapped with parentheses.
Examples
| Syntax | Output Type | Notes |
|---|---|---|
(x, x+y) | STRUCT<?,?> | If column names are used (unquoted strings), the struct field data type isderived from the column data type.x andy arecolumns, so the data types of the struct fields are derived from the columntypes and the output type of the addition operator. |
This syntax can also be used with struct comparison for comparison expressionsusing multi-part keys, e.g., in aWHERE clause:
WHERE(Key1,Key2)IN((12,34),(56,78))Typeless struct syntax
STRUCT(expr1[ASfield_name][,...])Duplicate field names are allowed. Fields without names are considered anonymousfields and can't be referenced by name. struct values can beNULL, or canhaveNULL field values.
Examples
| Syntax | Output Type |
|---|---|
STRUCT(1,2,3) | STRUCT<int64,int64,int64> |
STRUCT() | STRUCT<> |
STRUCT('abc') | STRUCT<string> |
STRUCT(1, t.str_col) | STRUCT<int64, str_col string> |
STRUCT(1 AS a, 'abc' AS b) | STRUCT<a int64, b string> |
STRUCT(str_col AS abc) | STRUCT<abc string> |
Typed struct syntax
STRUCT<[field_name]field_type,...>(expr1[,...])Typed syntax allows constructing structs with an explicit struct data type. Theoutput type is exactly thefield_type provided. The input expression iscoerced tofield_type if the two types aren't the same, and an error isproduced if the types aren't compatible.AS alias isn't allowed on the inputexpressions. The number of expressions must match the number of fields in thetype, and the expression types must be coercible or literal-coercible to thefield types.
Examples
| Syntax | Output Type |
|---|---|
STRUCT<int64>(5) | STRUCT<int64> |
STRUCT<date>("2011-05-05") | STRUCT<date> |
STRUCT<x int64, y string>(1, t.str_col) | STRUCT<x int64, y string> |
STRUCT<int64>(int_col) | STRUCT<int64> |
STRUCT<x int64>(5 AS x) | Error - Typed syntax doesn't allowAS |
Limited comparisons for structs
Structs can be directly compared using equality operators:
- Equal (
=) - Not Equal (
!=or<>) - [
NOT]IN
Notice, though, that these direct equality comparisons compare the fields ofthe struct pairwise in ordinal order ignoring any field names. If instead youwant to compare identically named fields of a struct, you can compare theindividual fields directly.
Timestamp type
| Name | Range |
|---|---|
TIMESTAMP | 0001-01-01 00:00:00 to 9999-12-31 23:59:59.999999 UTC |
A timestamp value represents an absolute point in time,independent of any time zone or convention such as daylight saving time (DST),withmicrosecond precision.
A timestamp is typically represented internally as the number of elapsedmicroseconds since a fixed initial point in time.
Note that a timestamp itself doesn't have a time zone; it represents the sameinstant in time globally. However, thedisplay of a timestamp for humanreadability usually includes a Gregorian date, a time, and a time zone, in animplementation-dependent format. For example, the displayed values "2020-01-0100:00:00 UTC", "2019-12-31 19:00:00 America/New_York", and "2020-01-01 05:30:00Asia/Kolkata" all represent the same instant in time and therefore represent thesame timestamp value.
- To represent a Gregorian date as it might appear on a calendar(a civil date), use adate value.
Canonical format
The canonical format for a timestamp literal has the following parts:
{civil_date_part[time_part[time_zone]]|civil_date_part[time_part[time_zone_offset]]|civil_date_part[time_part[utc_time_zone]]}civil_date_part:YYYY-[M]M-[D]Dtime_part:{|T|t}[H]H:[M]M:[S]S[.F]YYYY: Four-digit year.[M]M: One or two digit month.[D]D: One or two digit day.{ |T|t}: A space or aTortseparator. TheTandtseparators are flags for time.[H]H: One or two digit hour (valid values from 00 to 23).[M]M: One or two digit minutes (valid values from 00 to 59).[S]S: One or two digit seconds (valid values from 00 to 60).[.F]: Up to six fractional digits(microsecond precision).[time_zone]: String representing the time zone. When a timezone isn't explicitly specified, the default time zone,UTC, is used. For details, seetimezones.[time_zone_offset]: String representing the offset from theCoordinated Universal Time (UTC) time zone. For details, seetime zones.[utc_time_zone]: String representing the Coordinated UniversalTime (UTC), usually the letterZorz. For details, seetime zones.
To learn more about the literal representation of a timestamp type,seeTimestamp literals.
Time zones
A time zone is used when converting from a civil date or time (as might appearon a calendar or clock) to a timestamp (an absolute time), or vice versa. Thisincludes the operation of parsing a string containing a civil date and time like"2020-01-01 00:00:00" and converting it to a timestamp. The resulting timestampvalue itself doesn't store a specific time zone, because it represents oneinstant in time globally.
Time zones are represented by strings in one of these canonical formats:
- Offset from Coordinated Universal Time (UTC), or the letter
ZorzforUTC. - Time zone name from thetz database.
The following timestamps are identical because the time zone offsetforAmerica/Los_Angeles is-08 for the specified date and time.
SELECTUNIX_MILLIS(TIMESTAMP'2008-12-25 15:30:00 America/Los_Angeles')ASmillis;SELECTUNIX_MILLIS(TIMESTAMP'2008-12-25 15:30:00-08:00')ASmillis;Specify Coordinated Universal Time (UTC)
You can specify UTC using the following suffix:
{Z|z}You can also specify UTC using the following time zone name:
{Etc/UTC}TheZ suffix is a placeholder that implies UTC when converting anRFC3339-format value to aTIMESTAMP value. The valueZ isn'ta valid time zone for functions that accept a time zone. If you're specifying atime zone, or you're unsure of the format to use to specify UTC, we recommendusing theEtc/UTC time zone name.
TheZ suffix isn't case sensitive. When using theZ suffix, no space isallowed between theZ and the rest of the timestamp. The following areexamples of using theZ suffix and theEtc/UTC time zone name:
SELECTTIMESTAMP'2014-09-27T12:30:00.45Z'SELECTTIMESTAMP'2014-09-27 12:30:00.45z'SELECTTIMESTAMP'2014-09-27T12:30:00.45 Etc/UTC'Specify an offset from Coordinated Universal Time (UTC)
You can specify the offset from UTC using the following format:
{+|-}H[H][:M[M]]Examples:
-08:00-8:15+3:00+07:30-7When using this format, no space is allowed between the time zone and the restof the timestamp.
2014-09-2712:30:00.45-8:00Time zone name
Format:
tz_identifierA time zone name is a tz identifier from thetz database.For a less comprehensive but simpler reference, see theList of tz database time zones on Wikipedia.
Examples:
America/Los_AngelesAmerica/Argentina/Buenos_AiresEtc/UTCPacific/AucklandWhen using a time zone name, a space is required between the name and the restof the timestamp:
2014-09-2712:30:00.45America/Los_AngelesNote that not all time zone names are interchangeable even if they do happen toreport the same time during a given part of the year. For example,America/Los_Angeles reports the same time asUTC-7:00 during daylightsaving time (DST), but reports the same time asUTC-8:00 outside of DST.
If a time zone isn't specified, the default time zone value is used.
Leap seconds
A timestamp is simply an offset from 1970-01-01 00:00:00 UTC, assuming there areexactly 60 seconds per minute. Leap seconds aren't represented as part of astored timestamp.
If the input contains values that use ":60" in the seconds field to represent aleap second, that leap second isn't preserved when converting to a timestampvalue. Instead that value is interpreted as a timestamp with ":00" in theseconds field of the following minute.
Leap seconds don't affect timestamp computations. All timestamp computationsare done using Unix-style timestamps, which don't reflect leap seconds. Leapseconds are only observable through functions that measure real-world time. Inthese functions, it's possible for a timestamp second to be skipped or repeatedwhen there is a leap second.
Daylight saving time
A timestamp is unaffected by daylight saving time (DST) because it represents apoint in time. When you display a timestamp as a civil time,with a timezone that observes DST, the following rules apply:
During the transition from standard time to DST, one hour is skipped. Acivil time from the skipped hour is treated the same as if it were writtenan hour later. For example, in the
America/Los_Angelestime zone, the hourbetween 2 AM and 3 AM on March 10, 2024 is skipped on a clock. The times2:30 AM and 3:30 AM on that date are treated as the same point in time:SELECTFORMAT_TIMESTAMP("%c %Z","2024-03-10 02:30:00 America/Los_Angeles","UTC")AStwo_thirty,FORMAT_TIMESTAMP("%c %Z","2024-03-10 03:30:00 America/Los_Angeles","UTC")ASthree_thirty;/*------------------------------+------------------------------+ | two_thirty | three_thirty | +------------------------------+------------------------------+ | Sun Mar 10 10:30:00 2024 UTC | Sun Mar 10 10:30:00 2024 UTC | +------------------------------+------------------------------*/When there's ambiguity in how to represent a civil time in a particulartimezone because of DST, the later time is chosen:
SELECTFORMAT_TIMESTAMP("%c %Z","2024-03-10 10:30:00 UTC","America/Los_Angeles")asten_thirty;/*--------------------------------+ | ten_thirty | +--------------------------------+ | Sun Mar 10 03:30:00 2024 UTC-7 | +--------------------------------*/During the transition from DST to standard time, one hour is repeated. Acivil time that shows a time during that hour is treated as if it's theearlier instance of that time. For example, in the
America/Los_Angelestimezone, the hour between 1 AM and 2 AM on November 3, 2024, is repeated on aclock. The time 1:30 AM on that date is treated as the earlier (DST) instanceof that time.SELECTFORMAT_TIMESTAMP("%c %Z","2024-11-03 01:30:00 America/Los_Angeles","UTC")asone_thirty,FORMAT_TIMESTAMP("%c %Z","2024-11-03 02:30:00 America/Los_Angeles","UTC")astwo_thirty;/*------------------------------+------------------------------+ | one_thirty | two_thirty | +------------------------------+------------------------------+ | Sun Nov 3 08:30:00 2024 UTC | Sun Nov 3 10:30:00 2024 UTC | +------------------------------+------------------------------*/
Except as otherwise noted, the content of this page is licensed under theCreative Commons Attribution 4.0 License, and code samples are licensed under theApache 2.0 License. For details, see theGoogle Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.
Last updated 2025-12-17 UTC.