mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-12-16 11:22:12 +00:00
Merge branch 'master' into use-dag-in-key-condition
This commit is contained in:
commit
a45e3d2e4a
2
contrib/h3
vendored
2
contrib/h3
vendored
@ -1 +1 @@
|
||||
Subproject commit 5c44b06c406613b7792a60b11d04b871116f6e30
|
||||
Subproject commit e209086ae1b5477307f545a0f6111780edc59940
|
@ -3079,4 +3079,69 @@ SELECT
|
||||
FROM fuse_tbl
|
||||
```
|
||||
|
||||
## flatten_nested {#flatten-nested}
|
||||
|
||||
Sets the data format of a [nested](../../sql-reference/data-types/nested-data-structures/nested.md) columns.
|
||||
|
||||
Possible values:
|
||||
|
||||
- 1 — Nested column is flattened to separate arrays.
|
||||
- 0 — Nested column stays a single array of tuples.
|
||||
|
||||
Default value: `1`.
|
||||
|
||||
**Usage**
|
||||
|
||||
If the setting is set to `0`, it is possible to use an arbitrary level of nesting.
|
||||
|
||||
**Examples**
|
||||
|
||||
Query:
|
||||
|
||||
``` sql
|
||||
SET flatten_nested = 1;
|
||||
CREATE TABLE t_nest (`n` Nested(a UInt32, b UInt32)) ENGINE = MergeTree ORDER BY tuple();
|
||||
|
||||
SHOW CREATE TABLE t_nest;
|
||||
```
|
||||
|
||||
Result:
|
||||
|
||||
``` text
|
||||
┌─statement───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ CREATE TABLE default.t_nest
|
||||
(
|
||||
`n.a` Array(UInt32),
|
||||
`n.b` Array(UInt32)
|
||||
)
|
||||
ENGINE = MergeTree
|
||||
ORDER BY tuple()
|
||||
SETTINGS index_granularity = 8192 │
|
||||
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
Query:
|
||||
|
||||
``` sql
|
||||
SET flatten_nested = 0;
|
||||
|
||||
CREATE TABLE t_nest (`n` Nested(a UInt32, b UInt32)) ENGINE = MergeTree ORDER BY tuple();
|
||||
|
||||
SHOW CREATE TABLE t_nest;
|
||||
```
|
||||
|
||||
Result:
|
||||
|
||||
``` text
|
||||
┌─statement──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ CREATE TABLE default.t_nest
|
||||
(
|
||||
`n` Nested(a UInt32, b UInt32)
|
||||
)
|
||||
ENGINE = MergeTree
|
||||
ORDER BY tuple()
|
||||
SETTINGS index_granularity = 8192 │
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
[Original article](https://clickhouse.tech/docs/en/operations/settings/settings/) <!-- hide -->
|
||||
|
@ -74,4 +74,26 @@ Received exception from server (version 1.1.54388):
|
||||
Code: 386. DB::Exception: Received from localhost:9000, 127.0.0.1. DB::Exception: There is no supertype for types UInt8, String because some of them are String/FixedString and some of them are not.
|
||||
```
|
||||
|
||||
[Original article](https://clickhouse.tech/docs/en/data_types/array/) <!--hide-->
|
||||
## Array Size {#array-size}
|
||||
|
||||
It is possible to find the size of an array by using the `size0` subcolumn without reading the whole column. For multi-dimensional arrays you can use `sizeN-1`, where `N` is the wanted dimension.
|
||||
|
||||
**Example**
|
||||
|
||||
Query:
|
||||
|
||||
```sql
|
||||
CREATE TABLE t_arr (`arr` Array(Array(Array(UInt32)))) ENGINE = MergeTree ORDER BY tuple();
|
||||
|
||||
INSERT INTO t_arr VALUES ([[[12, 13, 0, 1],[12]]]);
|
||||
|
||||
SELECT arr.size0, arr.size1, arr.size2 FROM t_arr;
|
||||
```
|
||||
|
||||
Result:
|
||||
|
||||
``` text
|
||||
┌─arr.size0─┬─arr.size1─┬─arr.size2─┐
|
||||
│ 1 │ [2] │ [[4,1]] │
|
||||
└───────────┴───────────┴───────────┘
|
||||
```
|
||||
|
@ -34,7 +34,7 @@ CREATE TABLE test.visits
|
||||
|
||||
This example declares the `Goals` nested data structure, which contains data about conversions (goals reached). Each row in the ‘visits’ table can correspond to zero or any number of conversions.
|
||||
|
||||
Only a single nesting level is supported. Columns of nested structures containing arrays are equivalent to multidimensional arrays, so they have limited support (there is no support for storing these columns in tables with the MergeTree engine).
|
||||
When [flatten_nested](../../../operations/settings/settings.md#flatten-nested) is set to `0` (which is not by default), arbitrary levels of nesting are supported.
|
||||
|
||||
In most cases, when working with a nested data structure, its columns are specified with column names separated by a dot. These columns make up an array of matching types. All the column arrays of a single nested data structure have the same length.
|
||||
|
||||
|
@ -20,6 +20,33 @@ To store `Nullable` type values in a table column, ClickHouse uses a separate fi
|
||||
!!! info "Note"
|
||||
Using `Nullable` almost always negatively affects performance, keep this in mind when designing your databases.
|
||||
|
||||
## Finding NULL {#finding-null}
|
||||
|
||||
It is possible to find `NULL` values in a column by using `null` subcolumn without reading the whole column. It returns `1` if the corresponding value is `NULL` and `0` otherwise.
|
||||
|
||||
**Example**
|
||||
|
||||
Query:
|
||||
|
||||
``` sql
|
||||
CREATE TABLE nullable (`n` Nullable(UInt32)) ENGINE = MergeTree ORDER BY tuple();
|
||||
|
||||
INSERT INTO nullable VALUES (1) (NULL) (2) (NULL);
|
||||
|
||||
SELECT n.null FROM nullable;
|
||||
```
|
||||
|
||||
Result:
|
||||
|
||||
``` text
|
||||
┌─n.null─┐
|
||||
│ 0 │
|
||||
│ 1 │
|
||||
│ 0 │
|
||||
│ 1 │
|
||||
└────────┘
|
||||
```
|
||||
|
||||
## Usage Example {#usage-example}
|
||||
|
||||
``` sql
|
||||
|
@ -47,4 +47,32 @@ SELECT tuple(1, NULL) AS x, toTypeName(x)
|
||||
└──────────┴─────────────────────────────────┘
|
||||
```
|
||||
|
||||
## Addressing Tuple Elements {#addressing-tuple-elements}
|
||||
|
||||
It is possible to read elements of named tuples using indexes and names:
|
||||
|
||||
``` sql
|
||||
CREATE TABLE named_tuples (`a` Tuple(s String, i Int64)) ENGINE = Memory;
|
||||
|
||||
INSERT INTO named_tuples VALUES (('y', 10)), (('x',-10));
|
||||
|
||||
SELECT a.s FROM named_tuples;
|
||||
|
||||
SELECT a.2 FROM named_tuples;
|
||||
```
|
||||
|
||||
Result:
|
||||
|
||||
``` text
|
||||
┌─a.s─┐
|
||||
│ y │
|
||||
│ x │
|
||||
└─────┘
|
||||
|
||||
┌─tupleElement(a, 2)─┐
|
||||
│ 10 │
|
||||
│ -10 │
|
||||
└────────────────────┘
|
||||
```
|
||||
|
||||
[Original article](https://clickhouse.tech/docs/en/data_types/tuple/) <!--hide-->
|
||||
|
@ -39,13 +39,44 @@ Accepts zero arguments and returns an empty array of the appropriate type.
|
||||
|
||||
Accepts an empty array and returns a one-element array that is equal to the default value.
|
||||
|
||||
## range(end), range(start, end \[, step\]) {#rangeend-rangestart-end-step}
|
||||
|
||||
Returns an array of numbers from start to end-1 by step.
|
||||
If the argument `start` is not specified, defaults to 0.
|
||||
If the argument `step` is not specified, defaults to 1.
|
||||
It behaviors almost like pythonic `range`. But the difference is that all the arguments type must be `UInt` numbers.
|
||||
Just in case, an exception is thrown if arrays with a total length of more than 100,000,000 elements are created in a data block.
|
||||
## range(end), range(\[start, \] end \[, step\]) {#range}
|
||||
|
||||
Returns an array of `UInt` numbers from `start` to `end - 1` by `step`.
|
||||
|
||||
**Syntax**
|
||||
``` sql
|
||||
range([start, ] end [, step])
|
||||
```
|
||||
|
||||
**Arguments**
|
||||
|
||||
- `start` — The first element of the array. Optional, required if `step` is used. Default value: 0. [UInt](../data-types/int-uint.md)
|
||||
- `end` — The number before which the array is constructed. Required. [UInt](../data-types/int-uint.md)
|
||||
- `step` — Determines the incremental step between each element in the array. Optional. Default value: 1. [UInt](../data-types/int-uint.md)
|
||||
|
||||
**Returned value**
|
||||
|
||||
- Array of `UInt` numbers from `start` to `end - 1` by `step`.
|
||||
|
||||
**Implementation details**
|
||||
|
||||
- All arguments must be positive values: `start`, `end`, `step` are `UInt` data types, as well as elements of the returned array.
|
||||
- An exception is thrown if query results in arrays with a total length of more than 100,000,000 elements.
|
||||
|
||||
|
||||
**Examples**
|
||||
|
||||
Query:
|
||||
``` sql
|
||||
SELECT range(5), range(1, 5), range(1, 5, 2);
|
||||
```
|
||||
Result:
|
||||
```txt
|
||||
┌─range(5)────┬─range(1, 5)─┬─range(1, 5, 2)─┐
|
||||
│ [0,1,2,3,4] │ [1,2,3,4] │ [1,3] │
|
||||
└─────────────┴─────────────┴────────────────┘
|
||||
```
|
||||
|
||||
## array(x1, …), operator \[x1, …\] {#arrayx1-operator-x1}
|
||||
|
||||
|
@ -195,41 +195,6 @@ Result:
|
||||
└────────────────────┘
|
||||
```
|
||||
|
||||
## h3ToGeo {#h3togeo}
|
||||
|
||||
Returns `(lon, lat)` that corresponds to the provided H3 index.
|
||||
|
||||
**Syntax**
|
||||
|
||||
``` sql
|
||||
h3ToGeo(h3Index)
|
||||
```
|
||||
|
||||
**Arguments**
|
||||
|
||||
- `h3Index` — H3 Index. Type: [UInt64](../../../sql-reference/data-types/int-uint.md).
|
||||
|
||||
**Returned values**
|
||||
|
||||
- `lon` — Longitude. Type: [Float64](../../../sql-reference/data-types/float.md).
|
||||
- `lat` — Latitude. Type: [Float64](../../../sql-reference/data-types/float.md).
|
||||
|
||||
|
||||
**Example**
|
||||
|
||||
Query:
|
||||
|
||||
``` sql
|
||||
SELECT h3ToGeo(644325524701193974) coordinates;
|
||||
```
|
||||
|
||||
Result:
|
||||
|
||||
``` text
|
||||
┌─coordinates───────────────────────────┐
|
||||
│ (37.79506616830252,55.71290243145668) │
|
||||
└───────────────────────────────────────┘
|
||||
```
|
||||
## h3kRing {#h3kring}
|
||||
|
||||
Lists all the [H3](#h3index) hexagons in the raduis of `k` from the given hexagon in random order.
|
||||
|
@ -2957,4 +2957,70 @@ SELECT
|
||||
FROM fuse_tbl
|
||||
```
|
||||
|
||||
## flatten_nested {#flatten-nested}
|
||||
|
||||
Устанавливает формат данных у [вложенных](../../sql-reference/data-types/nested-data-structures/nested.md) столбцов.
|
||||
|
||||
Возможные значения:
|
||||
|
||||
- 1 — вложенный столбец преобразуется к отдельным массивам.
|
||||
- 0 — вложенный столбец преобразуется к массиву кортежей.
|
||||
|
||||
Значение по умолчанию: `1`.
|
||||
|
||||
**Использование**
|
||||
|
||||
Если установлено значение `0`, можно использовать любой уровень вложенности.
|
||||
|
||||
**Примеры**
|
||||
|
||||
Запрос:
|
||||
|
||||
``` sql
|
||||
SET flatten_nested = 1;
|
||||
|
||||
CREATE TABLE t_nest (`n` Nested(a UInt32, b UInt32)) ENGINE = MergeTree ORDER BY tuple();
|
||||
|
||||
SHOW CREATE TABLE t_nest;
|
||||
```
|
||||
|
||||
Результат:
|
||||
|
||||
``` text
|
||||
┌─statement───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ CREATE TABLE default.t_nest
|
||||
(
|
||||
`n.a` Array(UInt32),
|
||||
`n.b` Array(UInt32)
|
||||
)
|
||||
ENGINE = MergeTree
|
||||
ORDER BY tuple()
|
||||
SETTINGS index_granularity = 8192 │
|
||||
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
Запрос:
|
||||
|
||||
``` sql
|
||||
SET flatten_nested = 0;
|
||||
|
||||
CREATE TABLE t_nest (`n` Nested(a UInt32, b UInt32)) ENGINE = MergeTree ORDER BY tuple();
|
||||
|
||||
SHOW CREATE TABLE t_nest;
|
||||
```
|
||||
|
||||
Результат:
|
||||
|
||||
``` text
|
||||
┌─statement──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ CREATE TABLE default.t_nest
|
||||
(
|
||||
`n` Nested(a UInt32, b UInt32)
|
||||
)
|
||||
ENGINE = MergeTree
|
||||
ORDER BY tuple()
|
||||
SETTINGS index_granularity = 8192 │
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
[Оригинальная статья](https://clickhouse.tech/docs/ru/operations/settings/settings/) <!--hide-->
|
||||
|
@ -5,11 +5,9 @@ toc_title: Array(T)
|
||||
|
||||
# Array(T) {#data-type-array}
|
||||
|
||||
Массив из элементов типа `T`.
|
||||
Массив из элементов типа `T`. `T` может любым, в том числе массивом. Таким образом поддерживаются многомерные массивы.
|
||||
|
||||
`T` может любым, в том числе, массивом. Таким образом поддержаны многомерные массивы.
|
||||
|
||||
## Создание массива {#sozdanie-massiva}
|
||||
## Создание массива {#creating-an-array}
|
||||
|
||||
Массив можно создать с помощью функции:
|
||||
|
||||
@ -45,7 +43,7 @@ SELECT [1, 2] AS x, toTypeName(x)
|
||||
└───────┴────────────────────┘
|
||||
```
|
||||
|
||||
## Особенности работы с типами данных {#osobennosti-raboty-s-tipami-dannykh}
|
||||
## Особенности работы с типами данных {#working-with-data-types}
|
||||
|
||||
Максимальный размер массива ограничен одним миллионом элементов.
|
||||
|
||||
@ -76,3 +74,26 @@ Received exception from server (version 1.1.54388):
|
||||
Code: 386. DB::Exception: Received from localhost:9000, 127.0.0.1. DB::Exception: There is no supertype for types UInt8, String because some of them are String/FixedString and some of them are not.
|
||||
```
|
||||
|
||||
## Размер массива {#array-size}
|
||||
|
||||
Узнать размер массива можно с помощью подстолбца `size0` без чтения всего столбца. Для многомерных массивов можно использовать подстолбец `sizeN-1`, где `N` — требуемое измерение.
|
||||
|
||||
**Пример**
|
||||
|
||||
Запрос:
|
||||
|
||||
```sql
|
||||
CREATE TABLE t_arr (`arr` Array(Array(Array(UInt32)))) ENGINE = MergeTree ORDER BY tuple();
|
||||
|
||||
INSERT INTO t_arr VALUES ([[[12, 13, 0, 1],[12]]]);
|
||||
|
||||
SELECT arr.size0, arr.size1, arr.size2 FROM t_arr;
|
||||
```
|
||||
|
||||
Результат:
|
||||
|
||||
``` text
|
||||
┌─arr.size0─┬─arr.size1─┬─arr.size2─┐
|
||||
│ 1 │ [2] │ [[4,1]] │
|
||||
└───────────┴───────────┴───────────┘
|
||||
```
|
||||
|
@ -29,7 +29,7 @@ CREATE TABLE test.visits
|
||||
|
||||
В этом примере объявлена вложенная структура данных `Goals`, содержащая данные о достижении целей. Каждой строке таблицы visits может соответствовать от нуля до произвольного количества достижений целей.
|
||||
|
||||
Поддерживается только один уровень вложенности. Столбцы вложенных структур, содержащие массивы, эквивалентны многомерным массивам, поэтому их поддержка ограничена (не поддерживается хранение таких столбцов в таблицах с движком семейства MergeTree).
|
||||
Если настройка [flatten_nested](../../../operations/settings/settings.md#flatten-nested) установлена в значение `0` (что не является значением по умолчанию), поддерживаются любые уровни вложенности.
|
||||
|
||||
В большинстве случаев, при работе с вложенной структурой данных, указываются отдельные её столбцы. Для этого, имена столбцов указываются через точку. Эти столбцы представляют собой массивы соответствующих типов. Все столбцы-массивы одной вложенной структуры данных имеют одинаковые длины.
|
||||
|
||||
|
@ -13,7 +13,7 @@ toc_title: Nullable
|
||||
|
||||
`NULL` — значение по умолчанию для типа `Nullable`, если в конфигурации сервера ClickHouse не указано иное.
|
||||
|
||||
## Особенности хранения {#osobennosti-khraneniia}
|
||||
## Особенности хранения {#storage-features}
|
||||
|
||||
Для хранения значения типа `Nullable` ClickHouse использует:
|
||||
|
||||
@ -27,7 +27,34 @@ toc_title: Nullable
|
||||
!!! info "Info"
|
||||
Почти всегда использование `Nullable` снижает производительность, учитывайте это при проектировании своих баз.
|
||||
|
||||
## Пример использования {#primer-ispolzovaniia}
|
||||
## Поиск NULL {#finding-null}
|
||||
|
||||
Найти в столбце значения `NULL` можно с помощью подстолбца `null`, при этом весь столбец считывать не требуется. Подстолбец содержит `1`, если соответствующее значение равно `NULL`, и `0` если не равно.
|
||||
|
||||
**Пример**
|
||||
|
||||
Запрос:
|
||||
|
||||
``` sql
|
||||
CREATE TABLE nullable (`n` Nullable(UInt32)) ENGINE = MergeTree ORDER BY tuple();
|
||||
|
||||
INSERT INTO nullable VALUES (1) (NULL) (2) (NULL);
|
||||
|
||||
SELECT n.null FROM nullable;
|
||||
```
|
||||
|
||||
Результат:
|
||||
|
||||
``` text
|
||||
┌─n.null─┐
|
||||
│ 0 │
|
||||
│ 1 │
|
||||
│ 0 │
|
||||
│ 1 │
|
||||
└────────┘
|
||||
```
|
||||
|
||||
## Пример использования {#usage-example}
|
||||
|
||||
``` sql
|
||||
CREATE TABLE t_null(x Int8, y Nullable(Int8)) ENGINE TinyLog
|
||||
@ -47,4 +74,3 @@ SELECT x + y from t_null
|
||||
│ 5 │
|
||||
└────────────┘
|
||||
```
|
||||
|
||||
|
@ -47,3 +47,30 @@ SELECT tuple(1,NULL) AS x, toTypeName(x)
|
||||
└──────────┴─────────────────────────────────┘
|
||||
```
|
||||
|
||||
## Адресация элементов кортежа {#addressing-tuple-elements}
|
||||
|
||||
К элементам кортежа можно обращаться по индексу и по имени:
|
||||
|
||||
``` sql
|
||||
CREATE TABLE named_tuples (`a` Tuple(s String, i Int64)) ENGINE = Memory;
|
||||
|
||||
INSERT INTO named_tuples VALUES (('y', 10)), (('x',-10));
|
||||
|
||||
SELECT a.s FROM named_tuples;
|
||||
|
||||
SELECT a.2 FROM named_tuples;
|
||||
```
|
||||
|
||||
Результат:
|
||||
|
||||
``` text
|
||||
┌─a.s─┐
|
||||
│ y │
|
||||
│ x │
|
||||
└─────┘
|
||||
|
||||
┌─tupleElement(a, 2)─┐
|
||||
│ 10 │
|
||||
│ -10 │
|
||||
└────────────────────┘
|
||||
```
|
||||
|
@ -39,10 +39,49 @@ toc_title: "Массивы"
|
||||
|
||||
Принимает пустой массив и возвращает массив из одного элемента, равного значению по умолчанию.
|
||||
|
||||
## range(N) {#rangen}
|
||||
|
||||
Возвращает массив чисел от 0 до N-1.
|
||||
На всякий случай, если на блок данных, создаются массивы суммарной длины больше 100 000 000 элементов, то кидается исключение.
|
||||
## range(end), range(\[start, \] end \[, step\]) {#range}
|
||||
|
||||
Возвращает массив чисел от `start` до `end - 1` с шагом `step`.
|
||||
|
||||
**Синтаксис**
|
||||
|
||||
``` sql
|
||||
range([start, ] end [, step])
|
||||
```
|
||||
|
||||
**Аргументы**
|
||||
|
||||
- `start` — начало диапазона. Обязательно, когда указан `step`. По умолчанию равно `0`. Тип: [UInt](../data-types/int-uint.md)
|
||||
- `end` — конец диапазона. Обязательный аргумент. Должен быть больше, чем `start`. Тип: [UInt](../data-types/int-uint.md)
|
||||
- `step` — шаг обхода. Необязательный аргумент. По умолчанию равен `1`. Тип: [UInt](../data-types/int-uint.md)
|
||||
|
||||
|
||||
**Возвращаемые значения**
|
||||
|
||||
- массив `UInt` чисел от `start` до `end - 1` с шагом `step`
|
||||
|
||||
|
||||
**Особенности реализации**
|
||||
|
||||
- Не поддерживаются отрицательные значения аргументов: `start`, `end`, `step` имеют тип `UInt`.
|
||||
|
||||
- Если в результате запроса создаются массивы суммарной длиной больше 100 000 000 элементов, то генерируется исключение.
|
||||
|
||||
|
||||
**Примеры**
|
||||
|
||||
Запрос:
|
||||
``` sql
|
||||
SELECT range(5), range(1, 5), range(1, 5, 2);
|
||||
```
|
||||
Ответ:
|
||||
```txt
|
||||
┌─range(5)────┬─range(1, 5)─┬─range(1, 5, 2)─┐
|
||||
│ [0,1,2,3,4] │ [1,2,3,4] │ [1,3] │
|
||||
└─────────────┴─────────────┴────────────────┘
|
||||
```
|
||||
|
||||
|
||||
## array(x1, …), оператор \[x1, …\] {#arrayx1-operator-x1}
|
||||
|
||||
|
@ -1,96 +0,0 @@
|
||||
#if !defined(ARCADIA_BUILD)
|
||||
# include "config_functions.h"
|
||||
#endif
|
||||
|
||||
#if USE_H3
|
||||
|
||||
#include <array>
|
||||
#include <math.h>
|
||||
#include <Columns/ColumnArray.h>
|
||||
#include <Columns/ColumnTuple.h>
|
||||
#include <Columns/ColumnsNumber.h>
|
||||
#include <DataTypes/DataTypeTuple.h>
|
||||
#include <DataTypes/DataTypesNumber.h>
|
||||
#include <Functions/FunctionFactory.h>
|
||||
#include <Functions/IFunction.h>
|
||||
#include <Common/typeid_cast.h>
|
||||
#include <ext/range.h>
|
||||
|
||||
#include <h3api.h>
|
||||
|
||||
|
||||
namespace DB
|
||||
{
|
||||
namespace ErrorCodes
|
||||
{
|
||||
extern const int ILLEGAL_TYPE_OF_ARGUMENT;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
/// Implements the function h3ToGeo which takes a single argument (h3Index)
|
||||
/// and returns the longitude and latitude that correspond to the provided h3 index
|
||||
class FunctionH3ToGeo : public IFunction
|
||||
{
|
||||
public:
|
||||
static constexpr auto name = "h3ToGeo";
|
||||
|
||||
static FunctionPtr create(ContextPtr) { return std::make_shared<FunctionH3ToGeo>(); }
|
||||
|
||||
std::string getName() const override { return name; }
|
||||
|
||||
size_t getNumberOfArguments() const override { return 1; }
|
||||
bool useDefaultImplementationForConstants() const override { return true; }
|
||||
|
||||
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
|
||||
{
|
||||
const auto * arg = arguments[0].get();
|
||||
if (!WhichDataType(arg).isUInt64())
|
||||
throw Exception(
|
||||
"Illegal type " + arg->getName() + " of argument " + std::to_string(1) + " of function " + getName() + ". Must be UInt64",
|
||||
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||
|
||||
return std::make_shared<DataTypeTuple>(
|
||||
DataTypes{std::make_shared<DataTypeFloat64>(), std::make_shared<DataTypeFloat64>()},
|
||||
Strings{"longitude", "latitude"});
|
||||
}
|
||||
|
||||
ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const override
|
||||
{
|
||||
const auto * col_index = arguments[0].column.get();
|
||||
|
||||
auto latitude = ColumnFloat64::create(input_rows_count);
|
||||
auto longitude = ColumnFloat64::create(input_rows_count);
|
||||
|
||||
ColumnFloat64::Container & lon_data = longitude->getData();
|
||||
ColumnFloat64::Container & lat_data = latitude->getData();
|
||||
|
||||
|
||||
for (size_t row = 0; row < input_rows_count; ++row)
|
||||
{
|
||||
H3Index h3index = col_index->getUInt(row);
|
||||
GeoCoord coord{};
|
||||
|
||||
h3ToGeo(h3index,&coord);
|
||||
lon_data[row] = radsToDegs(coord.lon);
|
||||
lat_data[row] = radsToDegs(coord.lat);
|
||||
}
|
||||
|
||||
MutableColumns columns;
|
||||
columns.emplace_back(std::move(longitude));
|
||||
columns.emplace_back(std::move(latitude));
|
||||
return ColumnTuple::create(std::move(columns));
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
void registerFunctionH3ToGeo(FunctionFactory & factory)
|
||||
{
|
||||
factory.registerFunction<FunctionH3ToGeo>();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -28,7 +28,6 @@ void registerFunctionSvg(FunctionFactory & factory);
|
||||
|
||||
#if USE_H3
|
||||
void registerFunctionGeoToH3(FunctionFactory &);
|
||||
void registerFunctionH3ToGeo(FunctionFactory &);
|
||||
void registerFunctionH3EdgeAngle(FunctionFactory &);
|
||||
void registerFunctionH3EdgeLengthM(FunctionFactory &);
|
||||
void registerFunctionH3GetResolution(FunctionFactory &);
|
||||
@ -67,7 +66,6 @@ void registerFunctionsGeo(FunctionFactory & factory)
|
||||
|
||||
#if USE_H3
|
||||
registerFunctionGeoToH3(factory);
|
||||
registerFunctionH3ToGeo(factory);
|
||||
registerFunctionH3EdgeAngle(factory);
|
||||
registerFunctionH3EdgeLengthM(factory);
|
||||
registerFunctionH3GetResolution(factory);
|
||||
|
@ -139,7 +139,8 @@ def configure_testcase_args(args, case_file, suite_tmp_dir, stderr_file):
|
||||
testcase_args = copy.deepcopy(args)
|
||||
|
||||
testcase_args.testcase_start_time = datetime.now()
|
||||
testcase_args.testcase_client = f"{testcase_args.client} --log_comment='{case_file}'"
|
||||
testcase_basename = os.path.basename(case_file)
|
||||
testcase_args.testcase_client = f"{testcase_args.client} --log_comment='{testcase_basename}'"
|
||||
|
||||
if testcase_args.database:
|
||||
database = testcase_args.database
|
||||
|
@ -7,4 +7,3 @@ SELECT h3kRing(0xFFFFFFFFFFFFFF, 1000) FORMAT Null;
|
||||
SELECT h3GetBaseCell(0xFFFFFFFFFFFFFF) FORMAT Null;
|
||||
SELECT h3GetResolution(0xFFFFFFFFFFFFFF) FORMAT Null;
|
||||
SELECT h3kRing(0xFFFFFFFFFFFFFF, 10) FORMAT Null;
|
||||
SELECT h3ToGeo(0xFFFFFFFFFFFFFF) FORMAT Null;
|
||||
|
@ -1,32 +0,0 @@
|
||||
(-173.6412167681162,-14.130272474941535)
|
||||
(59.48137613600854,58.020407687755686)
|
||||
(172.68095885060296,-83.6576608516349)
|
||||
(-94.46556851304558,-69.1999982492279)
|
||||
(-8.188263637093279,-55.856179102736284)
|
||||
(77.25594891852249,47.39278564360122)
|
||||
(135.11348004704536,36.60778126579667)
|
||||
(39.28534828967223,49.07710003066973)
|
||||
(124.71163478198051,-27.481172161567258)
|
||||
(-147.4887686066785,76.73237945824442)
|
||||
(86.63291906118863,-25.52526285188784)
|
||||
(23.27751790712118,13.126101362212724)
|
||||
(-70.40163237204142,-63.12562536833242)
|
||||
(15.642428355535966,40.285813505163574)
|
||||
(-76.53411447979884,54.5560449693637)
|
||||
(8.19906334981474,67.69370966550179)
|
||||
ok
|
||||
ok
|
||||
ok
|
||||
ok
|
||||
ok
|
||||
ok
|
||||
ok
|
||||
ok
|
||||
ok
|
||||
ok
|
||||
ok
|
||||
ok
|
||||
ok
|
||||
ok
|
||||
ok
|
||||
ok
|
@ -1,61 +0,0 @@
|
||||
DROP TABLE IF EXISTS h3_indexes;
|
||||
|
||||
CREATE TABLE h3_indexes (h3_index UInt64) ENGINE = Memory;
|
||||
|
||||
-- Random geo coordinates were generated using the H3 tool: https://github.com/ClickHouse-Extras/h3/blob/master/src/apps/testapps/mkRandGeo.c at various resolutions from 0 to 15.
|
||||
-- Corresponding H3 index values were in turn generated with those geo coordinates using `geoToH3(lon, lat, res)` ClickHouse function for the following test.
|
||||
|
||||
INSERT INTO h3_indexes VALUES (579205133326352383);
|
||||
INSERT INTO h3_indexes VALUES (581263419093549055);
|
||||
INSERT INTO h3_indexes VALUES (589753847883235327);
|
||||
INSERT INTO h3_indexes VALUES (594082350283882495);
|
||||
INSERT INTO h3_indexes VALUES (598372386957426687);
|
||||
INSERT INTO h3_indexes VALUES (599542359671177215);
|
||||
INSERT INTO h3_indexes VALUES (604296355086598143);
|
||||
INSERT INTO h3_indexes VALUES (608785214872748031);
|
||||
INSERT INTO h3_indexes VALUES (615732192485572607);
|
||||
INSERT INTO h3_indexes VALUES (617056794467368959);
|
||||
INSERT INTO h3_indexes VALUES (624586477873168383);
|
||||
INSERT INTO h3_indexes VALUES (627882919484481535);
|
||||
INSERT INTO h3_indexes VALUES (634600058503392255);
|
||||
INSERT INTO h3_indexes VALUES (635544851677385791);
|
||||
INSERT INTO h3_indexes VALUES (639763125756281263);
|
||||
INSERT INTO h3_indexes VALUES (644178757620501158);
|
||||
|
||||
|
||||
SELECT h3ToGeo(h3_index) FROM h3_indexes ORDER BY h3_index;
|
||||
|
||||
DROP TABLE h3_indexes;
|
||||
|
||||
DROP TABLE IF EXISTS h3_geo;
|
||||
|
||||
-- compare if the results of h3ToGeo and geoToH3 are the same
|
||||
|
||||
CREATE TABLE h3_geo(lat Float64, lon Float64, res UInt8) ENGINE = Memory;
|
||||
|
||||
INSERT INTO h3_geo VALUES (-173.6412167681162, -14.130272474941535, 0);
|
||||
INSERT INTO h3_geo VALUES (59.48137613600854, 58.020407687755686, 1);
|
||||
INSERT INTO h3_geo VALUES (172.68095885060296, -83.6576608516349, 2);
|
||||
INSERT INTO h3_geo VALUES (-94.46556851304558, -69.1999982492279, 3);
|
||||
INSERT INTO h3_geo VALUES (-8.188263637093279, -55.856179102736284, 4);
|
||||
INSERT INTO h3_geo VALUES (77.25594891852249, 47.39278564360122, 5);
|
||||
INSERT INTO h3_geo VALUES (135.11348004704536, 36.60778126579667, 6);
|
||||
INSERT INTO h3_geo VALUES (39.28534828967223, 49.07710003066973, 7);
|
||||
INSERT INTO h3_geo VALUES (124.71163478198051, -27.481172161567258, 8);
|
||||
INSERT INTO h3_geo VALUES (-147.4887686066785, 76.73237945824442, 9);
|
||||
INSERT INTO h3_geo VALUES (86.63291906118863, -25.52526285188784, 10);
|
||||
INSERT INTO h3_geo VALUES (23.27751790712118, 13.126101362212724, 11);
|
||||
INSERT INTO h3_geo VALUES (-70.40163237204142, -63.12562536833242, 12);
|
||||
INSERT INTO h3_geo VALUES (15.642428355535966, 40.285813505163574, 13);
|
||||
INSERT INTO h3_geo VALUES (-76.53411447979884, 54.5560449693637, 14);
|
||||
INSERT INTO h3_geo VALUES (8.19906334981474, 67.69370966550179, 15);
|
||||
|
||||
SELECT result FROM (
|
||||
SELECT
|
||||
(lat, lon) AS input_geo,
|
||||
h3ToGeo(geoToH3(lat, lon, res)) AS output_geo,
|
||||
if(input_geo = output_geo, 'ok', 'fail') AS result
|
||||
FROM h3_geo
|
||||
);
|
||||
|
||||
DROP TABLE h3_geo;
|
Loading…
Reference in New Issue
Block a user