Функции
В данном разделе собраны специфичные для CHYT функции.
Функции для работы с YSON
YPathType (простые типы и массивы)
YPath<Type>[Strict](yson, ypath)
— извлечь из строки yson
значение типа Type
по пути ypath
.
Type
может принимать одно из следующих значений: Int64
, UInt64
, Boolean
, Double
, String
, ArrayInt64
, ArrayUInt64
, ArrayBoolean
, ArrayDouble
.
Опциональный суффикс Strict
обозначает строгость функции.
Примеры называний функций: YPathInt64
, YPathStringStrict
, YPathArrayDouble
.
Принцип работы функций состоит в следующем:
- Переданная строка
yson
интерпретируется как YSON-документ; - Происходит адресация в этом документе по пути
ypath
относительно корня документа; - Происходит интерпретация содержимого документа по пути
ypath
к типуType
.
На каждом из этапов работы данной функции могут возникнуть ошибки:
- Строка может не представлять собой YSON-документ (такое возможно при указании строковой константы в качестве аргумента функции, но не при чтении реальных Any-колонок из YTsaurus);
- Данный путь может отсутствовать в документе;
- Данный путь может соответствовать иному типу данных, отличному от
Type
(например, вместо числового значения находится строковый литерал).
Отличие строгой версии функции (с суффиксом Strict
) от нестрогой версии заключается в режиме обработки данных ошибок: строгая версия аварийно завершит работу запроса, тогда как нестрогая версия вернет в качестве результата значение по умолчанию для соответствующего типа колонки (Null
, 0
, пустую строку или пустой список) и продолжит работу.
Примеры использования (в качестве первого аргумента везде фигурирует строковый литерал, содержащий YSON, но на его месте может быть любая any-колонка таблицы):
SELECT YPathInt64('{key1=42; key2=57; key3=29}', '/key2');
57
SELECT YPathInt64('[3;4;5]', '/1');
4
SELECT YPathString('["aa";"bb";"cc"]', '/1');
"bb"
SELECT YPathString('{a=[{c=xyz}; {c=qwe}]}', '/a/1/c');
"qwe"
SELECT YPathInt64('{key=xyz}', '/key');
0
SELECT YPathInt64Strict('{key=xyz}', '/key');
std::exception. Code: 1001, type: NYT::TErrorException, e.what() = Node /key2 has invalid type: expected one of {"int64", "uint64"}, actual "string"
code 500
origin ...
SELECT YPathString('{key=3u}', '/nonexistentkey');
""
SELECT YPathArrayInt64('[1;2;3]', '');
[1, 2, 3]
SELECT YPathUInt64('42u', '');
42
Предположим, что в таблице есть две колонки lhs
и rhs
, представляющие собой any
-колонки, содержащие списки чисел одинаковой длины.
Таблица 1 — Пример таблицы с any
колонками
lhs | rhs |
---|---|
[1, 2, 3] | [5, 6, 7] |
[-1, 1] | [1, 3] |
[] | [] |
Тогда можно построить скалярное произведение векторов lhs
и rhs
с помощью следующей конструкции:
SELECT arraySum((x, y) -> x*y, YPathArrayInt64(lhs, ''), YPathArrayInt64(rhs, '')) FROM "//path/to/table"
38
2
0
YPathExtract (сложные типы)
YPathExtract[Strict](yson, ypath, type)
— извлечь из строки yson
значение произвольного типа type
по пути ypath
.
Функция аналогична функциям YPath<Type>
, но позволяет задать произвольный тип возвращаемого значения с помощью дополнительного аргумента type
. Поддерживаются в том числе сложные составные типы, для которых нет аналога YPath<Type>
.
Внимание
С помощью функции YPathExtract
можно извлекать и простые типы. Например, результат выполнения YPathExtract(yson, ypath, 'Int64')
будет эквивалентен результату YPathInt64(yson, ypath)
. Однако функции YPath<Type>
более специализированы и имеют более оптимальную реализацию, поэтому рекомендуется использовать функцию YPathExtract
только в случае, когда для извлекаемого типа нет специализированной функции.
Пример:
SELECT YPathExtract('[[1;2];[2;3]]', '', 'Array(Array(Int64))');
[[1, 2], [2, 3]]
SELECT YPathExtract('{a=1;b="abc"}', '', 'Tuple(a Int64, b String)');
("a": 1, "b": "abc")
SELECT YPathExtract('{x=["abc";"bbc"]}', '/x', 'Array(String)')
["abc", "bbc"]
YPathRaw (необработанный yson)
YPathRaw[Strict](yson, ypath, [format])
— извлечь из строки yson
по пути ypath
необработанное значение в формате yson.
Функция может быть применена, когда тип результируемого значения неизвестен, либо различается в разных строках одной колонки.
Опциональный параметр format
позволяет задать формат представления возвращаемого yson значения и может быть одним из следующих: binary
(по умолчанию), text
, pretty
, unescaped_text
, unescaped_pretty
.
Примеры:
SELECT YPathRaw('{x={key=[1]}}', '/x', 'text');
'{"key"=[1;];}'
SELECT YPathRaw('{a=1}', '/b', 'text');
NULL
Семейство функций YSON*
Для работы с форматом json в ClickHouse присутсвуют функции семейства JSON*
. Для более схожей работы с обычным ClickHouse, в CHYT поддержаны полные аналоги этих функций, работающие с форматом yson.
Значение аргументов функций и их возвращаемое значение можно посмотреть в документации ClickHouse.
Поддержанные аналоги на данный момент:
YSONHas
, YSONLength
, YSONKey
, YSONType
, YSONExtractInt
, YSONExtractUInt
, YSONExtractFloat
, YSONExtractBool
, YSONExtractString
, YSONExtract
, YSONExtractKeysAndValues
, YSONExtractRaw
, YSONExtractArrayRaw
, YSONExtractKeysAndValuesRaw
.
Примечание
В отличие от функций YPath
, в которых нумерация элементов в массиве начинается с 0, нумерация элементов в функциях YSON*
c единицы.
Внимание
Данные функции реализованы общим с ClickHouse кодом и не являются оптимальными. Для ускорения вычислений на большом количестве данных рекомендуется воспользоваться более оптимальными функциями YPath<Type>
.
Пример:
-- Эквивалентно YPathString('["aa";"bb";"cc"]', '/0')
-- Обратите внимание, нумерация начинается с 1
SELECT YSONExtractString('["aa";"bb";"cc"]', 1);
"aa"
-- Эквивалентно YPathString('{a=[{c=xyz}; {c=qwe}]}', '/a/1/c')
SELECT YSONExtractString('{a=[{c=xyz}; {c=qwe}]}', 'a', 2, 'c');
"qwe"
Форматы представления YSON
Данные из колонок типа any
могут храниться в бинарном представлении yson
. Поскольку читать такие данные не всегда удобно, в CHYT имеется функция ConvertYson
, которая преобразует разные представления yson
между собой.
ConvertYson(yson, format)
— преобразовать строку с yson документом в указанный формат.
Всего существует пять возможных форматов представления:
binary
text
pretty
unescaped_text
*unescaped_pretty
*
* Примечание
В системе YTsaurus предусмотрено 3 формата представления — binary
, text
и pretty
.
В форматах представления text
и pretty
в значениях строк экранируются все символы, выходящие за пределы ascii, в том числе кириллица и различные символы в кодировке utf-8. Чтобы результирующий yson, содержащий строки с символами кириллицы, был более человекочитаемым, в CHYT были добавлены два дополнительных формата - unescaped_text
и unescaped_pretty
. Эти форматы отличаются от text
и pretty
только тем, что в строковых значениях экранируются только служебные для формата yson символы. Остальные символы сохраняются в строках без изменений.
Примеры:
SELECT ConvertYson('{x=1}', 'text');
'{"x"=1;}'
SELECT ConvertYson('{x=1}', 'pretty');
'{
"x" = 1;
}'
SELECT ConvertYson('{x=1}', 'binary');
'{\u0001\u0002x=\u0002\u0002;}'
SELECT ConvertYson('{x="Пример"}', 'text');
'{"x"="\xD0\x9F\xD1\x80\xD0\xB8\xD0\xBC\xD0\xB5\xD1\x80";}'
SELECT ConvertYson('{x="Пример"}', 'unescaped_text');
'{"x"="Пример";}'
Пример работы с YSON
SELECT operation_id, task_id, YPathInt64(task_spec, '/gpu_limit') as gpu_limit, YPathInt64(task_spec, '/job_count') as job_count FROM (
SELECT tupleElement(tasks, 1) as task_id, tupleElement(tasks, 2) as task_spec, operation_id FROM (
SELECT operation_id, tasks FROM (
Select YSONExtractKeysAndValuesRaw(COALESCE(tasks, '')) as tasks, operation_id FROM (
SELECT YSONExtractRaw(spec, 'tasks') as tasks, operation_id
FROM `//home/dev/chyt_examples/completed_ops`
WHERE YSONHas(spec, 'tasks')
)
)
ARRAY JOIN tasks
)
)
ORDER BY gpu_limit DESC;
Получение версии клики
Получение версии CHYT
chytVersion()
— получить строковое представление версии CHYT сервера.
Пример:
SELECT chytVersion()
Получение версии YTsaurus
ytVersion()
— получить строковое представление версии кода YTsaurus, используемого в текущей версии CHYT.
Пример:
SELECT ytVersion()
Работа с кипарисом
Примечание
Все функции для работы с кипарисом являются табличными в терминах ClickHouse. Это означает, что их возвращаемое значение может использоваться вместо таблицы, например, в секции FROM
запроса SELECT
.
ytListNodes
ytListNodes[L](dir_path, [from, [to]])
— получить список всех узлов и их атрибутов в директории dir_path
.
Результат содержит по одной строке на каждый узел из директории dir_path
. Каждая строка содержит:
-
Две встроеных колонки
$key
и$path
, хранящие имя и полный путь до узла (всегда начинается сdir_path
). Значение в данных колонках могут отличаться от атрибутовkey
иpath
, если узел является ссылкой (типlink
) на другой узел. -
3 колонки, соответствующие полям атрибута
resource_usage
:disk_space
,tablet_count
иmaster_memory
. -
Большое количество колонок, название которых соответствует названию атрибута узла:
key
,path
,account
,owner
,erasure_codec
,id
,acl
и другие. Колонки включают практически все системные атрибуты.
Примечание
Так как обычно пользователям не нужны все атрибуты узла, большинство колонок являются виртуальными в терминах ClickHouse. Это означает, что по умолчанию они не возвращаются через выражения SELECT * FROM ytListNodes(...)
и DESCRIBE ytListNodes(...)
, но могут быть запрошены явно:
SELECT id, key_columns, * FROM ytListNodes(...)
По умолчанию функция ytListNodes
не раскрывает ссылки (узлы типа link
). Это означает, что для таких узлов в результате будут возвращены атрибуты самого узла ссылки, а не узла, на который она ссылается. Что бы изменить это поведение и раскрыть все ссылки, можно воспользоваться модификатором функции L
(ytListNodesL
). При этом если ссылка ведет в несуществующий узел, то она останется нераскрытой, поэтому в результате все равно могут присутсвовать строки с типом link
, соответствующие нераскрытым ссылкам.
Внимание
Раскрытие каждой ссылки требует дополнительного запроса к мастер серверу, поэтому исполнение функции ytListNodeL
может быть дольше и ресурсозатратнее, чем ytListNode
. Использование ytListNodeL
для директорий с большим количеством ссылок крайне не рекомендуется.
С помощью двух опциональных строковых аргументов from
и to
можно задать фильтрацию возвращаемых узлов по названию (колонке $key
). Сравнение лексикографическое.
Пример:
SELECT * FROM ytListNodes('//some/dir/path');
SELECT sum(disk_space), sum(chunk_count) FROM ytListNodes('//some/dir/path');
SELECT * FROM ytListNodesL('//some/dir/path');
ytListTables
ytListTables[L](dir_path, [from, [to]])
— получить список всех таблиц и их атрибутов в директории.
Аргументы функции и структура возвращаемого значения аналогичны функции ytListNodes[L]
.
Рузультат функции эквивалентен результату вызова ytListNodes[L]
с последующей фильтрацией WHERE type = 'table'
.
Суффикс L
имеет аналогичное значение и расскрывает все ссылки перед фильтрацией. Таким образом, результат выполнения ytListTables
будет содержать только таблицы, непосредственно находящиеся в указанной директории, а результат выполнения ytListTablesL
будет дополнительно содержать таблицы, на которые указывают ссылки из указанной директории.
SELECT path, chunk_count FROM ytListTables('//dome/dir/path');
ytListLogTables
ytListLogTables(project_name_or_path, [from_datetime, [to_datetime]])
— получить непересекающийся по времени список таблиц с логами и их атрибуты из указанного проекта.
project_name_or_path
может содержать либо название проекта с логами (если проект лежит в директории //logs
), либо полный путь до директории с логами.
Функция рассмотрит таблицы с логами в четырех поддиректориях (1h
, 30m
, 1d
и stream/5m
), после чего объединит множества этих таблиц так, что бы интервалы времени таблиц не пересекались.
С помощью двух опциональных аргументов from_datetime
и to_datetime
можно задать интересующий временной интервал логов. Таблицы с логами, которые не пересекаются по времени с указанным интервалом, будут отфильтрованы.
Примечание
Фильтрация по временному интервалу происходит только на уровне таблиц. Таблицы с логами из результата работы функции могут покрывать больший временной интервал, чем указанный в аргументах.
Пример:
SELECT * FROM ytListLogTables('chyt-structured-http-proxy-log', today() - 1);
SELECT * FROM ytListLogTables('//logs/chyt-structured-http-proxy-log', today() - 5, today() - 4);
ytNodeAttributes
ytNodeAttributes(path1, [path2, [...]])
— получить атрибуты всех узлов, указанных в аргументах.
Возвращаемое значение будет содержать по 1 строке с атрибутами на каждый указанный в аргументах путь. Если указан некоректный или несуществующий путь, будет сгенерирована ошибка.
Структура возвращаемого значения аналогична функции ytListNodes
.
Пример:
SELECT * FROM ytNodeAttributes('//sys', '//sys/clickhouse')
Чтение множества таблиц
Примечание
Все функции для чтения множества таблиц являются табличными в терминах ClickHouse. Это означает, что их возвращаемое значение может использоваться вместо таблицы, например, в секции FROM
запроса SELECT
.
ytTables
ytTables(arg1, [arg2, ...])
— прочитать объединение множества таблиц, указанного в аргументах.
Каждый аргумент может быть одним из следующих:
- Строка, представляющая собой путь до конкретной таблицы
- Одна из функций
ytListNodes[L]
,ytListTables[L]
,ytListLogTables
- Подзапрос, возвращающий произвольное множество путей таблиц*
* Внимание
Передача в качестве аргумента функции подзапроса, возвращающего несколько путей, не соответствует синтаксису ClickHouse. Данная конструкция работает в текущей версии CHYT/ClickHouse, но может перестать работать в будущих версиях. Более правильным способом передачи такого подзапроса является использование функции view
.
Также на данный момент известно о баге оптимизатора ClickHouse, который может некоретно переносить внешнее условие WHERE
внутрь такого подзапроса, в результате чего может возникать ошибка Missing columns: '<column_name>' while processing query
. Обойти данную ошибку можно с помощью настройки enable_optimize_predicate_expression=0
.
Функция возвращает объединение множества всех таблиц, заданных в аргументах. Работа функции аналогичная функции merge из ClickHouse, но она предоставляет более гибкую систему указания множества таблиц и оптимизирована для работы с таблицами YTsaurus.
Если таблицы из заданного множества таблиц имеют различные схемы, то будет выведена общая схема, с помощью которой можно прочитать все заданные таблицы.
Алгоритм вывода общей схемы
Совместимые типы
- Для каждой колонки выбирается "наиболее общий тип", к которому можно привести все типы.
- Пример: для типов
optional<int32>
иint64
"наиболее общим типом" будетoptional<i64>
. - Обратите внимание, что ввиду особенностей хранения данных в YTsaurus, беззнаковые числовые типы являются несовместимыми со знаковыми (т.е. типы
int32
иuint32
несовместимы).
Несовместимые типы
- Если типы колонки несовместимы в разных таблицах, то chyt будет действовать согласно опции
chyt.concat_tables.type_mismatch_mode
. - Пример: типы
string
иint64
несовместимы. - Возможные значения опции:
drop
,throw
,read_as_any
. - По умолчанию произойдет ошибка исполнения запроса (значение
throw
). - Колонки разных типов можно прочитать как yson-строки, указав значение опции
read_as_any
. Это может быть неэффективно, поэтому рекомендуется структурировать свои таблицы правильно. - Если такие колонки не нужны для исполнения запроса, их можно отбросить, указав значение опции
drop
.
Отсутствующая колонка
- Если колонка отсуствует в одной или в нескольких входных таблицах, то chyt будет действовать согласно опции
chyt.concat_tables.missing_column_mode
. - Возможные значения:
drop
,throw
,read_as_null
. - По умолчанию колонка станет опциональной, а значения из таблиц, где колонка пропущена, будут прочитаны как
NULL
(значениеread_as_null
). - Если отсутствие колонок в некоторых таблицах неожидаемо, в таком случае можно генерировать ошибку исполнения запроса, указав значение опции
throw
. - Как и в случае с несовместимыми типами, такие колонки можно отбросить, указав значение опции
drop
. - Обратите внимание, опция
missing_column_mode
влияет на поведение только в случае, если колонка пропущена в таблице со строгой схемой. Если колонка пропущена в нестрогой схеме, то она все равно может существовать в самих данных с любым типом. В этом случае делается пессимистичное предположение, что колонка присутствует с несовместимым типом, и дальнейшее поведение регулируется описанной ранее опциейtype_mismatch_mode
.
Примечание
Помимо основных колонок из самих таблиц в результате также всегда присутсвуют виртуальные колонки $table_index
, $table_name
и $table_path
. С помощью данных колонок можно определить, из какой именно таблицы была прочитана каждая строчка. Подробнее про виртуальные колонки можно прочитать в соответствующем разделе.
Пример:
-- Прочитать объединение 2 таблиц:
SELECT * FROM ytTables('//tmp/t1', '//tmp/t2')
-- Прочитать объединение всех таблиц из директории '//tmp/dir':
SELECT * FROM ytTables(ytListTables('//tmp/dir'))
-- Прочитать объединение всех таблиц из директории и их названия:
SELECT *, $table_name FROM ytTables(ytListTables('//tmp/dir'))
-- Прочитать последнюю (лексикографически) таблицу:
SELECT * FROM ytTables((
SELECT max(path) FROM ytListTables('/tmp/dir')
))
-- Прочитать таблицы с определенным суффиксом:
SELECT * FROM ytTables((
SELECT concat(path, '/suffix') FROM ytListNodes('//tmp/dir')
))
concatYtTables
concatYtTables(table1, [table2, [...]])
— прочитать объединение нескольких YTsaurus таблиц.
Устаревший вариант функции ytTables
. В качестве аргументов могут выступать только пути таблиц.
Пример:
SELECT * FROM concatYtTables('//tmp/sample_table', '//tmp/sample_table2');
concatYtTablesRange
concatYtTablesRange(cypress_path, [from, [to]])
— прочитать объединение всех таблиц из директории cypress_path
.
Устаревшая функция, эквивалентная ytTables(ytListTables(cypress_path, from, to))
.
Пример:
SELECT * FROM concatYtTablesRange("//tmp/sample_tables");
SELECT * FROM concatYtTablesRange('//tmp/sample_tables', '2019-01-01');
SELECT * FROM concatYtTablesRange('//tmp/sample_tables', '2019-08-13T11:00:00');