RowBinary

### DateTime[​](#datetime "Direct link to DateTime")

Stored as `UInt32` (four bytes) representing the number of seconds ***since*** `1970-01-01 00:00:00 UTC`.

Syntax:

```
DateTime([timezone])
```

For example, `DateTime` or `DateTime('UTC')`.

Note

The binary value is always a UTC epoch offset. The timezone does not change the encoding. However, the timezone **does** affect how string values are interpreted on insertion: inserting `'2024-01-15 10:30:00'` into a `DateTime('America/New_York')` column stores a different epoch value than inserting the same string into a `DateTime('UTC')` column, because the string is interpreted as local time in the column's timezone. On the wire, both are just `UInt32` epoch seconds.

Supported range of values: `[1970-01-01 00:00:00, 2106-02-07 06:28:15]`.

Sample underlying values for `DateTime`:

```
SELECT CAST('2024-01-15 10:30:00', 'DateTime(\'UTC\')') AS d
```

```
0x28, 0x09, 0xA5, 0x65, // 1705314600 as UInt32 (little-endian)
```

### DateTime64[​](#datetime64 "Direct link to DateTime64")

Stored as `Int64` (eight bytes) representing the number of **ticks** ***before or after*** `1970-01-01 00:00:00 UTC`. Tick resolution is defined by the `precision` parameter, see the syntax below:

```
DateTime64(precision, [timezone])
```

Where `precision` is an integer from `0` to `9`. Typically, only the following are used: `3` (milliseconds), `6` (microseconds),
`9` (nanoseconds).

Examples of valid DateTime64 definitions: `DateTime64(0)`, `DateTime64(3)`, `DateTime64(6, 'UTC')`, or `DateTime64(9, 'Europe/Amsterdam')`.

Note

As with `DateTime`, the binary value is always a UTC epoch offset. The timezone affects how string values are interpreted on insertion (see the [DateTime](#datetime) note), but the encoding itself is always `Int64` ticks since the UTC epoch.

The underlying `Int64` value of the `DateTime64` type can be interpreted as the number of the following units before or after the UNIX epoch:

- `DateTime64(0)` - seconds.
- `DateTime64(3)` - milliseconds.
- `DateTime64(6)` - microseconds.
- `DateTime64(9)` - nanoseconds.

Supported range of values: `[1900-01-01 00:00:00, 2299-12-31 23:59:59.99999999]`.

Sample underlying values for `DateTime64`:

- `DateTime64(3)`: value `1546300800000` represents `2019-01-01 00:00:00 UTC`.
- `DateTime64(6)`: value `1705314600123456` represents `2024-01-15 10:30:00.123456 UTC`.
- `DateTime64(9)`: value `1705314600123456789` represents `2024-01-15 10:30:00.123456789 UTC`.

Note

The precision of the maximum value is 8. If the maximum precision of 9 digits (nanoseconds) is used, the maximum supported value is 2262-04-11 23:47:16 in UTC.

### Time[​](#time "Direct link to Time")

Stored as `Int32` representing a time value in seconds. Negative values are valid.

Supported range of values: `[-999:59:59, 999:59:59]` (i.e., `[-3599999, 3599999]` seconds).

Note

At the moment, the setting `enable_time_time64_type` must be set to `1` to use `Time` or `Time64`.

Sample underlying values for `Time`:

```
SET enable_time_time64_type = 1;
SELECT CAST('15:32:16', 'Time') AS t
```

```
0x80, 0xDA, 0x00, 0x00, // 55936 seconds = 15:32:16
```

### Time64[​](#time64 "Direct link to Time64")

Internally stored as a `Decimal64` (which is stored as `Int64`) representing a time value with fractional seconds, with configurable precision. Negative values are valid.

Syntax:

```
Time64(precision)
```

Where `precision` is an integer from `0` to `9`. Common values: `3` (milliseconds), `6` (microseconds), `9` (nanoseconds).

Supported range of values: `[-999:59:59.xxxxxxxxx, 999:59:59.xxxxxxxxx]`.

Note

At the moment, the setting `enable_time_time64_type` must be set to `1` to use `Time` or `Time64`.

The underlying `Int64` value represents fractional seconds scaled by `10^precision`.

Sample underlying values for `Time64`:

```
SET enable_time_time64_type = 1;
SELECT CAST('15:32:16.123456', 'Time64(6)') AS t
```

```
0x40, 0x82, 0x0D, 0x06,
0x0D, 0x00, 0x00, 0x00, // 55936123456 as Int64
// 55936123456 / 10^6 = 55936.123456 seconds = 15:32:16.123456
```

### Interval types[​](#interval-types "Direct link to Interval types")

All interval types are stored as `Int64` (eight bytes, little-endian). The value represents the count of the respective time unit. Negative values are valid.

The interval types are: `IntervalNanosecond`, `IntervalMicrosecond`, `IntervalMillisecond`, `IntervalSecond`, `IntervalMinute`, `IntervalHour`, `IntervalDay`, `IntervalWeek`, `IntervalMonth`, `IntervalQuarter`, `IntervalYear`.

Note

The interval type name (e.g., `IntervalSecond` vs `IntervalDay`) determines the unit of the stored value. The wire encoding is always the same.

Sample underlying values:

```
SELECT INTERVAL 5 SECOND   AS a,
     INTERVAL 10 DAY     AS b,
     INTERVAL -7 DAY     AS c,
     INTERVAL 3 YEAR     AS d,
     INTERVAL 500 MICROSECOND AS e
```

```
// IntervalSecond: 5
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// IntervalDay: 10
0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// IntervalDay: -7
0xF9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
// IntervalYear: 3
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// IntervalMicrosecond: 500
0xF4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
```

### Enum8, Enum16[​](#enum8-enum16 "Direct link to Enum8, Enum16")

Stored as a single byte (`Enum8` == `Int8`) or two bytes (`Enum16` == `Int16`) representing the index of the enum value in the enum definition. Note that the storage type is **signed** — enum values can be negative (e.g., `Enum8('a' = -128, 'b' = 0)`).

An Enum can be defined in a simple way, like this:

```
SELECT 1 :: Enum8('hello' = 1, 'world' = 2) AS e;
```

```
   ┌─e─────┐
1. │ hello │
   └───────┘
```

The Enum8 defined above will have the following values map on the client:

```
Map<Int8, String> {
  1: 'hello',
  2: 'world'
}
```

Or in a more complex way, like this:

```
SELECT 42 :: Enum16('f\'' = 1, 'x =' = 2, 'b\'\'' = 3, '\'c=4=' = 42, '4' = 1234) AS e;
```

```
   ┌─e─────┐
1. │ 'c=4= │
   └───────┘
```

The Enum16 defined above will have the following values map on the client:

```
Map<Int16, String> {
  1:    'f\'',
  2:    'x =',
  3:    'b\'',
  42:   '\'c=4=',
  1234: '4'
}
```

For the data type parser, the main challenge is tracking escaped symbols in the enum definition, such as `\'`, and special symbols like `=` that may appear within quoted strings.

### UUID[​](#uuid "Direct link to UUID")

Represented as a sequence of 16 bytes. The UUID is stored as **two little-endian `UInt64` values**: the first 8 bytes of the standard UUID representation are byte-reversed, and the second 8 bytes are independently byte-reversed.

For example, given UUID `61f0c404-5cb3-11e7-907b-a6006ad3dba0`:

- Standard byte representation: `61 f0 c4 04 5c b3 11 e7` | `90 7b a6 00 6a d3 db a0`
- First half reversed (LE UInt64): `e7 11 b3 5c 04 c4 f0 61`
- Second half reversed (LE UInt64): `a0 db d3 6a 00 a6 7b 90`

Sample underlying values for `UUID`:

- `61f0c404-5cb3-11e7-907b-a6006ad3dba0` is represented as:

```
0xE7, 0x11, 0xB3, 0x5C, 0x04, 0xC4, 0xF0, 0x61,
0xA0, 0xDB, 0xD3, 0x6A, 0x00, 0xA6, 0x7B, 0x90,
```

- The default UUID `00000000-0000-0000-0000-000000000000` is represented as 16 zero bytes:

```
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
```

It can be used when a new record was inserted, but the UUID value was not specified.

### IPv4[​](#ipv4 "Direct link to IPv4")

Stored in four bytes as `UInt32` in **little-endian** byte order. Note that this differs from the traditional network byte order (big-endian) commonly used for IP addresses. Sample underlying values for `IPv4`:

```
SELECT    
  CAST('0.0.0.0',         'IPv4') AS a,
  CAST('127.0.0.1',       'IPv4') AS b,
  CAST('192.168.0.1',     'IPv4') AS c,
  CAST('255.255.255.255', 'IPv4') AS d,
  CAST('168.212.226.204', 'IPv4') AS e
```

```
0x00, 0x00, 0x00, 0x00, // 0.0.0.0
0x01, 0x00, 0x00, 0x7f, // 127.0.0.1
0x01, 0x00, 0xa8, 0xc0, // 192.168.0.1
0xff, 0xff, 0xff, 0xff, // 255.255.255.255
0xcc, 0xe2, 0xd4, 0xa8, // 168.212.226.204
```

### IPv6[​](#ipv6 "Direct link to IPv6")