Encoding functions

**Returned value**

Returns a tuple of the specified size. [`Tuple(UInt64)`](/docs/sql-reference/data-types/tuple)

**Examples**

**Simple mode**

```
SELECT hilbertDecode(2, 31)
```

```
["3", "4"]
```

**Single argument**

```
-- Hilbert code for one argument is always the argument itself (as a tuple).
SELECT hilbertDecode(1, 1)
```

```
["1"]
```

**Expanded mode**

```
-- A single argument with a tuple specifying bit shifts will be right-shifted accordingly.
SELECT hilbertDecode(tuple(2), 32768)
```

```
["128"]
```

**Column usage**

```
-- First create the table and insert some data
CREATE TABLE hilbert_numbers(
    n1 UInt32,
    n2 UInt32
)
ENGINE=MergeTree()
ORDER BY n1 SETTINGS index_granularity_bytes = '10Mi';
insert into hilbert_numbers (*) values(1,2);

-- Use column names instead of constants as function arguments
SELECT untuple(hilbertDecode(2, hilbertEncode(n1, n2))) FROM hilbert_numbers;
```

```
1    2
```

## hilbertEncode[​](#hilbertEncode "Direct link to hilbertEncode")

Introduced in: v24.6.0

Calculates code for Hilbert Curve for a list of unsigned integers.

The function has two modes of operation:

- **Simple**
- **Expanded**

**Simple mode**

Accepts up to 2 unsigned integers as arguments and produces a UInt64 code.

**Expanded mode**

Accepts a range mask ([Tuple](/docs/sql-reference/data-types/tuple)) as the
first argument and up to 2 [unsigned integers](/docs/sql-reference/data-types/int-uint)
as other arguments.

Each number in the mask configures the number of bits by which the corresponding
argument will be shifted left, effectively scaling the argument within its range.

**Syntax**

```
-- Simplified mode
hilbertEncode(args)

-- Expanded mode
hilbertEncode(range_mask, args)
```

**Arguments**

- `args` — Up to two `UInt` values or columns of type `UInt`. [`UInt8/16/32/64`](/docs/sql-reference/data-types/int-uint)
- `range_mask` — For the expanded mode, up to two `UInt` values or columns of type `UInt`. [`UInt8/16/32/64`](/docs/sql-reference/data-types/int-uint)

**Returned value**

Returns a `UInt64` code. [`UInt64`](/docs/sql-reference/data-types/int-uint)

**Examples**

**Simple mode**

```
SELECT hilbertEncode(3, 4)
```

```
31
```

**Expanded mode**

```
-- Range expansion can be beneficial when you need a similar distribution for
-- arguments with wildly different ranges (or cardinality).
-- For example: 'IP Address' (0...FFFFFFFF) and 'Country code' (0...FF).
-- Note: tuple size must be equal to the number of the other arguments.
SELECT hilbertEncode((10, 6), 1024, 16)
```

```
4031541586602
```

**Single argument**

```
-- For a single argument without a tuple, the function returns the argument
-- itself as the Hilbert index, since no dimensional mapping is needed.
SELECT hilbertEncode(1)
```

```
1
```

**Expanded single argument**

```
-- If a single argument is provided with a tuple specifying bit shifts, the function
-- shifts the argument left by the specified number of bits.
SELECT hilbertEncode(tuple(2), 128)
```

```
512
```

**Column usage**

```
-- First create the table and insert some data
CREATE TABLE hilbert_numbers(
    n1 UInt32,
    n2 UInt32
)
ENGINE=MergeTree()
ORDER BY n1;
insert into hilbert_numbers (*) values(1, 2);

-- Use column names instead of constants as function arguments
SELECT hilbertEncode(n1, n2) FROM hilbert_numbers;
```

```
13
```

## mortonDecode[​](#mortonDecode "Direct link to mortonDecode")

Introduced in: v24.6.0

Decodes a Morton encoding (ZCurve) into the corresponding unsigned integer tuple.

As with the `mortonEncode` function, this function has two modes of operation:

- **Simple**
- **Expanded**

**Simple mode**

Accepts a resulting tuple size as the first argument and the code as the second argument.

**Expanded mode**

Accepts a range mask (tuple) as the first argument and the code as the second argument.
Each number in the mask configures the amount of range shrink:

- `1` - no shrink
- `2` - 2x shrink
- `3` - 3x shrink
  ⋮
- Up to 8x shrink.

Range expansion can be beneficial when you need a similar distribution for
arguments with wildly different ranges (or cardinality). For example: 'IP Address' `(0...FFFFFFFF)`
and 'Country code' `(0...FF)`. As with the encode function, this is limited to
8 numbers at most.

**Syntax**

```
-- Simple mode
mortonDecode(tuple_size, code)

-- Expanded mode
mortonDecode(range_mask, code)
```

**Arguments**

- `tuple_size` — Integer value no more than 8. [`UInt8/16/32/64`](/docs/sql-reference/data-types/int-uint)
- `range_mask` — For the expanded mode, the mask for each argument. The mask is a tuple of unsigned integers. Each number in the mask configures the amount of range shrink. [`Tuple(UInt8/16/32/64)`](/docs/sql-reference/data-types/tuple)
- `code` — UInt64 code. [`UInt64`](/docs/sql-reference/data-types/int-uint)

**Returned value**

Returns a tuple of the specified size. [`Tuple(UInt64)`](/docs/sql-reference/data-types/tuple)

**Examples**

**Simple mode**

```
SELECT mortonDecode(3, 53)
```

```
["1", "2", "3"]
```

**Single argument**

```
SELECT mortonDecode(1, 1)
```

```
["1"]
```

**Expanded mode, shrinking one argument**

```
SELECT mortonDecode(tuple(2), 32768)
```

```
["128"]
```

**Column usage**

```
-- First create the table and insert some data
CREATE TABLE morton_numbers(
    n1 UInt32,
    n2 UInt32,
    n3 UInt16,
    n4 UInt16,
    n5 UInt8,
    n6 UInt8,
    n7 UInt8,
    n8 UInt8
)
ENGINE=MergeTree()
ORDER BY n1;
INSERT INTO morton_numbers (*) values(1, 2, 3, 4, 5, 6, 7, 8);

-- Use column names instead of constants as function arguments
SELECT untuple(mortonDecode(8, mortonEncode(n1, n2, n3, n4, n5, n6, n7, n8))) FROM morton_numbers;
```

```
1 2 3 4 5 6 7 8
```

## mortonEncode[​](#mortonEncode "Direct link to mortonEncode")

Introduced in: v24.6.0

Calculates the Morton encoding (ZCurve) for a list of unsigned integers.

The function has two modes of operation:

- **Simple**
- *Expanded*\*

**Simple mode**

Accepts up to 8 unsigned integers as arguments and produces a `UInt64` code.

**Expanded mode**

Accepts a range mask ([Tuple](/docs/sql-reference/data-types/tuple)) as the first argument and
up to 8 [unsigned integers](/docs/sql-reference/data-types/int-uint) as other arguments.

Each number in the mask configures the amount of range expansion:

- 1 - no expansion
- 2 - 2x expansion
- 3 - 3x expansion
  ⋮
- Up to 8x expansion.

**Syntax**

```
-- Simplified mode
mortonEncode(args)

-- Expanded mode
mortonEncode(range_mask, args)
```

**Arguments**

- `args` — Up to 8 unsigned integers or columns of the aforementioned type. [`UInt8/16/32/64`](/docs/sql-reference/data-types/int-uint)
- `range_mask` — For the expanded mode, the mask for each argument. The mask is a tuple of unsigned integers from `1` - `8`. Each number in the mask configures the amount of range shrink. [`Tuple(UInt8/16/32/64)`](/docs/sql-reference/data-types/tuple)

**Returned value**

Returns a `UInt64` code. [`UInt64`](/docs/sql-reference/data-types/int-uint)

**Examples**

**Simple mode**

```
SELECT mortonEncode(1, 2, 3)
```

```
53
```

**Expanded mode**

```
-- Range expansion can be beneficial when you need a similar distribution for
-- arguments with wildly different ranges (or cardinality)
-- For example: 'IP Address' (0...FFFFFFFF) and 'Country code' (0...FF).
-- Note: the Tuple size must be equal to the number of the other arguments.
SELECT mortonEncode((1,2), 1024, 16)
```

```
1572864
```

**Single argument**

```
-- Morton encoding for one argument is always the argument itself
SELECT mortonEncode(1)
```

```
1
```

**Expanded single argument**

```
SELECT mortonEncode(tuple(2), 128)
```

```
32768
```

**Column usage**

```
-- First create the table and insert some data
CREATE TABLE morton_numbers(
    n1 UInt32,
    n2 UInt32,
    n3 UInt16,
    n4 UInt16,
    n5 UInt8,
    n6 UInt8,
    n7 UInt8,
    n8 UInt8
)
ENGINE=MergeTree()
ORDER BY n1;
INSERT INTO morton_numbers (*) values(1, 2, 3, 4, 5, 6, 7, 8);

-- Use column names instead of constants as function arguments
SELECT mortonEncode(n1, n2, n3, n4, n5, n6, n7, n8) FROM morton_numbers;
```

```
2155374165
```