YPATH
В данном разделе собрана информация про YPath — язык, описывающий пути к объектам в системе YTsaurus.
YPath представляет собой язык описания путей, которые идентифицируют объекты в системе YTsaurus. Язык позволяет обращаться к узлам и указывать аннотации, которые могут быть полезны при совершении операций над узлами, например, при записи в таблицу. При помощи аннотаций можно определить, будут ли новые данные дописаны в конце таблицы, или таблица будет полностью перезаписана.
Например:
//home/user/table
— путь к таблицеtable
в домашнем каталоге пользователя;#0-25-3ec012f-406daf5c/@type
— путь к атрибутуtype
объекта с идентификатором0-25-3ec012f-406daf5c
;//home/user/table[#10:#20]
— строки с 10-ю по 19-ю включительно таблицыtable
в домашнем каталоге пользователя.
Существует несколько разновидностей YPath. В самом простом случае YPath представляет собой строку, кодирующую путь.
Простой YPath
Лексика
Строка, кодирующая простой YPath, разбивается на следующие токены:
- Специальные символы: прямой слеш (
/
), «собака» (@
), амперсанд (&
), звёздочка (*
); - Литералы: максимальная непустая последовательность неспециальных символов. В литералах разрешен escaping вида
\<escape-sequence>
, где в качестве<escape-sequence>
может выступать один из символов\
,/
,@
,&
,*
,[
,{
, а также выражение видаx<hex1><hex2>
, где<hex1>
и<hex2>
— шестнадцатеричные цифры.
Синтаксис и семантика
Структурно YPath имеет вид <root-designator><relative-path>
. Здесь <root-designator>
бывает двух видов:
- Корень Кипариса: токен
/
.
Пример://home/user
; здесь<root-designator>
равен/
, а<relative-path>
равен/home/user
; - Объектный корень: токен-литерал, кодирующий строку вида
#<id>
.
Пример:#1-2-3-4/@type
; здесь<root-designator>
равен#1-2-3-4
, а<relative-path>
равен/@type
.
Тем самым, <root-designator>
определяет начальную точку отсчета, к которой применяется <relative-path>
. Последний разбирается последовательно слева направо, в результате чего возникают шаги перемещения по дереву следующих видов:
- Переход к потомку: последовательность из токена
/
и литерала.
Данный тип шагов применим к словарям и спискам. В случае словаря литерал должен содержать имя потомка. Пример:/child
— переход к потомку с именемchild
.
В случае списка литерал должен содержать целое число в десятичной системе счисления — номер потомка. Потомки в списке нумеруются с нуля. Разрешены также отрицательные номера, которые нумеруют потомков с конца списка. Примеры:/1
— переход ко второму потомку в списке,/-1
— переход к последнему потомку в списке; - Переход к атрибуту: последовательность из токенов
/@
и литерала.
Данный тип шагов применим в любой точке пути и означает переход к атрибуту с данными именем. Пример:/@attr
— переход к атрибуту с именемattr
.
Примечание
В YPath относительные пути начинаются со слешей. Тем самым, слеш служит не разделителем как в случае файловых систем, а полноправным членом команды перемещения по дереву метаинформации. В частности, для склейки двух YPath достаточно обычной конкатенации строк.
Примеры
% Корень Кипариса
/
% В корневой директории узел home, в ней — узел user.
//home/user
% Начальный элемент в списке //home/user/list
//home/user/list/0
% Последний элемент в списке //home/user/list
//home/user/list/-1
% Атрибут attr узла //home/user
//home/user/@attr
% Объект с идентификатором 1-2-a-b
#1-2-a-b
% Потомок child объекта с идентификатором 1-2-a-b
#1-2-a-b/child
% Атрибут attr объекта с идентификатором 1-2-a-b
#1-2-a-b/@attr
Особенности поведения
Помимо указанных выше правил действует ряд специальных соглашений. Большинство из них связано с тем, что YPath может идентифицировать не только уже существующие метаинформационные сущности, но и новые, создаваемые в момент выполнения команды, аргументом которой служит данный YPath.
-
Указание всех потомков: в команде
remove_node
есть возможность удалить всех потомков словаря или списка, для этого следует использовать вместо имени токен*
.
Пример:% Очистить домашний каталог пользователя yt remove //home/user/*
-
Указание всех атрибутов: в командах чтения (
get_node
,list_nodes
), а также изменения (set_node
) есть возможность обратиться к коллекции всех атрибутов объекта, для чего в качестве пути надо использовать путь вида/@
. При этом изменение черезset_node
распространяется лишь на пользовательские атрибуты.Примеры:
% Получить значения всех атрибутов домашнего каталога пользователя yt get //home/user/@ % Получить имена всех атрибутов домашнего каталога пользователя yt list //home/user/@ % Удалить все пользовательские атрибуты yt set //home/user/@ '{}' % Выставить один пользовательский атрибут, удалив все остальные имеющиеся yt set //home/user/@ '{attr=value}' % Выставить один пользовательский атрибут, не трогать остальные yt set //home/user/@attr value % Выставить вложенный пользовательский атрибут yt set //home/user/@attr/some/key value
-
Указание позиции вставки в список: в командах, создающих новые узлы (например
set_node
) есть возможность указать положение создаваемого узла в списке относительно уже имеющихся. Для этого нужно вместо номера потомка использовать специальные строкиbegin
(начало списка),end
(конец списка),before:<index>
(позиция перед потомком с номером<index>
), а такжеafter:<index>
(позиция после потомка с номером<index>
). Примеры:% Добавить элемент "value" в конец списка //home/user/list yt set //home/user/list/end value % Вставить элемент "value" в начало списка //home/user/list yt set //home/user/list/before:0 value % Или yt set //home/user/list/begin value % Вставить элемент "value" перед вторым элементом списка //home/user/list yt set //home/user/list/before:2 value % Вставить элемент "value" после пятого элемента списка //home/user/list yt set //home/user/list/after:5 value
-
Отключение перенаправления: токен
&
может использоваться для подавления перенаправления по символической ссылке.
Примеры:% Узнать идентификатор самого объекта-ссылки, а не объекта, на который ссылка указывает yt get //home/user/link&/@id
Сложный YPath
Сложный (rich) YPath представляет собой расширенный YPath, имеющий вид строки с дополнительными аннотациями. Эти аннотации могут быть заданы двумя способами: в виде атрибутов (пар вида ключ-значение), а также синтаксически с помощью добавления специальных префиксов и суффиксов к простому YPath, из-за чего он превращается в строку вида <prefix><simple-ypath><suffix>
.
При отсутствии префикса <prefix>
и суффикса <suffix>
сложный YPath может иметь, например, такой вид:
<
append = %true;
compression_codec = lz4;
>
//home/user/table
Данный путь указывает на домашний каталог пользователя и несет в себе два атрибута.
На любом пути можно указать произвольный набор атрибутов. Точный их смысл зависит от того, как данный путь используется в системе. Например, при записи в таблицу имеет смысл атрибут append
, позволяющий дописывать в конец, а не перезаписать результат. Для входных таблиц некоторых mapreduce-операций можно указать флаг foreign
, означающий, что данная таблица является вторичной (таблицей-справочником), поэтому системе необходимо выполнять join специального вида.
Атрибуты, имена которых системе неизвестны, или которые не имеют смысла в заданном контексте, системой игнорируются.
Префикс и суффикс пути позволяют закодировать атрибуты в более компактном виде. Обе эти части используют лексику YSON. Подробнее об их устройстве:
Префикс
Часть <prefix>
либо пуста, либо задает атрибуты в виде map-fragment в формате YSON.
Пример: <append=%true>//home/user/table
задает путь к таблице в домашнем каталоге пользователя, а также сообщает нам дополнительный атрибут append
.
Основное предназначение префикса — упростить передачу атрибутов при использовании команд из консоли.
Суффикс
Часть <suffix>
либо пуста, либо указывает колонки и/или диапазоны строк обрабатываемой таблицы.
Сначала всегда указываются модификатор выбора колонок, если он есть, а затем модификатор выбора строк, если он есть.
Модификатор выбора колонок представляет собой разделенный запятыми и взятый в фигурные скобки набор имен колонок. Каждое имя представлено YSON-строкой.
Примеры модификаторов выбора колонок: {a}
, {a,b}
, {}
.
Формальная грамматика модификаторов выбора колонок:
<column-selector> = '{' { <column-selector-item> ',' } [ <column-selector-item> ] '}'
<column-selector-item> = <string>
Модификатор выбора строк представляет собой разделенный запятыми и взятый в квадратные скобки набор диапазонов строк таблицы. Каждый диапазон — пара из нижней и верхней границы диапазона, разделенных двоеточием, либо точное значение границы, которую нужно прочитать. В случае пары одна или обе границы могут отсутствовать.
Граница может быть либо числом с приписанным слева символом #
— тогда это номер строки в таблице, либо списком значений — тогда это граница по значениям ключевых колонок, по которым таблица отсортирована. Указанный список может быть короче, чем количество полей, по котором отсортирована таблица. В случае, если список состоит из одного элемента, его можно не обрамлять в круглые скобки. Элемент должен быть корректным YSON-значением скалярного типа int64
, uint64
, string
, double
, bool
.
Семантика модификатора выбора строк описана в разделе.
Примеры модификаторов выбора строк: [:]
, [#10:#100]
, [a:m]
, [(abc,8):(xyz,5)]
, [:5.0,10.0:]
, [#10]
, [a,#100,#1:#2]
, [100u:200u]
. В последнем случае данные содержат беззнаковые числа.
Формальная грамматика модификаторов выбора строк:
<row-selector> = '[' { <row-range> ',' } [ <row-range> ] ']'
<row-range> = <row-index-range-selector> | <row-key-range-selector> | <row-index> | <row-composite-key> | ''
<row-index-range-selector> = [ <row-index> ] ':' [ <row-index> ]
<row-index> = '#' <int64>
<row-key-range-selector> = [ <row-composite-key> ] ':' [ <row-composite-key> ]
<row-composite-key> = <row-key> | <row-key-tuple>
<row-key-tuple> = '(' { <row-key> ',' } [ <row-key> ] ')'
<row-key> = <string> | <int64> | <uint64> | <bool> | <double>
Примеры
Примечание
Сложные пути взяты в одинарные кавычки для надлежащего парсинга шеллом.
% Прочитать целиком таблицу '//home/user/table'
yt read '//home/user/table'
% Прочитать все строки таблицы '//home/user/table', но не выбрать ни одной колонки
yt read '//home/user/table{}'
% Прочитать колонку 'a'
yt read '//home/user/table{a}'
% Прочитать колонки 'a', 'b'
yt read '//home/user/table{a,b}'
% Прочитать первые 100 строк таблицы '//home/user/table' (и выбрать все колонки)
yt read '//home/user/table[#0:#100]'
% Прочитать все строки, пропустив первые 100
yt read '//home/user/table[#100:]'
% Прочитать строку с номером 100 (считая с 0)
yt read '//home/user/table[#100]'
% Прочитать строки с ключом (или первой координатой ключа) 'abc'
yt read '//home/user/table["abc":"abc\x00"]'
% Запрос выше можно также выразить короче:
yt read '//home/user/table["abc"]'
% Прочитать строки с ключами, не меньшими '(a,1)'
yt read '//home/user/table[(a,1):]'
% Прочитать строки у которых первые две компоненты ключа равны 'a' и '1' соответственно
yt read '//home/user/table[(a,1)]'
% Прочитать строки, у которых первый ключ 'a', второй ключ начинается с 'b', и, если второй ключ равен 'b', то третий ключ не меньше '1'.
yt read '//home/user/table[(a,b,1):(a,c)]'
% Прочитать строки, у которых первый ключ начинается с 'a', а также строки, у которых первый ключ 'b', а второй - меньше '1'.
yt read '//home/user/table[a:(b,1)]'
% Прочитать строки, у которых первый ключ начинается с 'a', а также строки, у которых первый ключ 'b', а второй - меньше '1', а также строки, у которых первый ключ 'b', второй ключ - '1', а третий - отрицательный типа double. Выбрать колонки 'ab', 'ac'
yt read '//home/user/table{ab,ac}[a:(b,1,0.0)]'
% Преобразовать table1 со столбцами a,b,c,d в table2 со столбцами a,b,c и сортировкой по полям a,b
yt sort --src '//home/users/table1{a,b,c}' --dst //home/users/table2 --sort-by a --sort-by b --spec '{schema_inference_mode = from_output}'
% Преобразовать table1 со столбцами a,b,c,d в table2 со столбцами a,b,c
yt merge --src '//home/users/table1{a,b,c}' --dst //home/users/table2 --spec '{schema_inference_mode = from_output}'
Каноническая форма YPath
Сложный YPath может быть приведен к канонической форме, в которой отсутствуют префикс и суффикс, вся информация из которых явно вынесена в атрибуты, назначенные строке — простому YPath.
Пример: после канонизации пути <append=true>//home/user/table[#10:#20]
получается следующая YSON-структура:
<
append = true;
ranges = [
{
lower_limit = {row_index = 10};
upper_limit = {row_index = 20}
}
]
>
"//home/user/table"
Внутри система YTsaurus предпочитает работать с канонической формой путей. Эта форма более громоздка, поэтому во всех путях, принимаемых системой на вход, разрешается использовать более удобную форму с префиксом и суффиксом:
<append=true>//home/user/table[#10:#20]
Префикс — <append=true>
;
Суффикс — [#10:#20]
.
Внутри системы это будет развернуто в широкую запись:
ranges = [
{
lower_limit = {row_index = 10};
upper_limit = {row_index = 20}
}
]
Существует команда parse_ypath
драйвера, позволяющая канонизировать сложный YPath.
Поддерживаемые атрибуты
Сложный YPath может быть проаннотирован произвольными атрибутами, что дает возможность расширения. В таблице представлен список атрибутов, которые поддерживает система.
Атрибут | Тип | Описание |
---|---|---|
append |
bool |
Распознается командами записи данных (write_table и write_file ) и означает, что новые данные дописываются в конец существующих, а не перезаписывают их. Также распознается на выходных путях таблиц в спецификациях всех операций планировщика и имеет аналогичную семантику. |
sorted_by |
array<string> |
Распознается командой записи табличных данных ( write_table ). При указании этого атрибута пользователь обещает, что записываемые данные упорядочены по указанному набору колонок. Система проверяет это свойство. Ключи должны идти в порядке неубывания, а в случае записи с добавлением проверяется также, что первый записываемый ключ не меньше последнего уже существующего. Атрибут также распознается системой на выходных путях таблиц в спецификациях всех операций планировщика и имеет там аналогичную семантику. В последнем случае также дополнительно требуется, чтобы диапазоны ключей, порождаемые различными джобами, не имели пересечения по внутренней точке, пересечения по границам разрешаются. |
ranges |
array<ReadRange> |
Распознается командами чтения данных (read_table и read_file ) и задает список читаемых диапазонов. Если отсутствует, читаются данные целиком. Также распознается на входных путях таблиц в спецификациях всех операций планировщика. Описание структуры словаря ReadRange представлено в таблице ниже. |
columns |
array<string> |
Распознается командой чтения табличных данных ( read_table ) и задает список имен читаемых колонок. Если отсутствует, то читаются все колонки. Также распознается на входных путях таблиц в спецификациях всех операций планировщика. |
optimize_for |
string |
Устанавливает формат хранения для создаваемой таблицы. Атрибут можно указывать c командой write_table и на выходных путях операций. Данный атрибут не совместим с <append=true> . |
compression_codec |
string |
Устанавливает формат сжатия для создаваемой таблицы. Атрибут можно указывать с командами write_file , write_table и на выходных путях операций. Данный атрибут несовместим с <append=true> . |
erasure_codec |
string |
Выключает erasure-кодирование для создаваемой таблицы. Атрибут можно указывать с командами write_file , write_table и на выходных путях операций. Данный атрибут несовместим с <append=true> . |
schema |
yson-list с валидной схемой |
Валидирует данные относительно указанной схемы и проставляет данную схему на таблицу по окончании операции. Атрибут можно указывать с командой write_table и на выходных путях операций. Данный атрибут несовместим с <append=true> . |
transaction_id |
string вида id |
Указание планировщику, под какой транзакцией необходимо обращаться к входной таблице, если на ней указан данный атрибут. |
rename_columns |
yson-map |
Распознается на входящих путях таблиц. Переименовывает названия колонок согласно маппингу перед подачей таблицы на вход операции. Данный атрибут несовместим с teleport таблицами. |
Атрибут ranges
указывает, какие диапазоны строк таблицы следует прочитать. Указанные диапазоны будут читаться последовательно, в том порядке, в котором они указаны в атрибутах команды. В частности, если диапазоны пересекаются, то на выходе строки будут повторены соответствующее число раз.
Атрибут | Тип | Описание |
---|---|---|
lower_limit |
ReadLimit |
Нижняя граница чтения |
upper_limit |
ReadLimit |
Верхняя граница чтения |
exact |
ReadLimit |
Точное значение границы чтения (не может быть указано вместе с lower_limit или upper_limit) |
За исключением ограничений типа key_bound
все виды ограничений в lower_limit
являются включительными, а все виды ограничений в upper_limit
— исключительными. Включительность или исключительность ограничения типа key_bound
указывается явно в самом key bound. См. также раздел, посвящённый срезам по ключам.
ReadLimit
описывает отдельную границу чтения. Граница может определяться одним из шести селекторов: ключом, ключевым ограничением (key bound), номером строки, номером чанка, номером таблета или байтовым смещением. В границе может быть указано несколько селекторов, при этом они все действуют одновременно, усиливая друг друга.
Атрибут | Тип | Описание |
---|---|---|
key |
list |
Список значений, образующих ключ (только для сортированных таблиц). См. подробнее в разделе |
key_bound |
list |
Включительное либо невключительное ограничение на префикс ключа; не может присутствовать в exact-границе. См. подробнее в разделе |
row_index |
int |
Номер строки (только для таблиц) |
offset |
int |
Байтовое смещение (только для файлов) |
chunk_index |
int |
Номер чанка |
tablet_index |
int |
Номер таблета (только для упорядоченных динамических таблиц) |
Поддерживаемые системой YTsaurus YPath атрибуты на путях файлов
Атрибут | Тип | Описание |
---|---|---|
file_name |
string |
Распознается при заказе файла в sandbox джоба. Атрибут задает относительный путь, по которому надо положить файл. |
executable |
bool |
Распознается при заказе файла в sandbox джоба. Атрибут указывает системе необходимость проставить executable-бит на заказанный файл. |
bypass_artifact_cache |
bool |
Распознается при заказе файла в sandbox джоба. Атрибут включает прямое скачивание файла в sandbox джоба минуя файловый кэш на ноде. |
format |
string |
Распознается при заказе табличного файла в sandbox джоба. Атрибут обозначает формат, в котором надо сформатировать таблицу при её скачивании в sandbox джоба. |
Срезы сортированных таблиц по ключам
Система поддерживает два вида селекторов по значениям ключевых колонок таблицы, которые внешне напоминают друг друга, но отличаются по поведению. Первый вид является исторически более старым и реализуется селектором key
, а также возможен для указания в суффиксе YPath. Второй вид является более новым и реализуется селектору key_bound
; он доступен только через атрибут ranges
в префиксе YPath.
В новых приложениях рекомендуется использовать селектор типа key_bound
, так как он обладает большей прозрачностью в поведении и гибкостью в использовании, хотя и более многословен.
Примечание
Напомним, что YTsaurus задаёт некоторый линейный порядок сравнения на всевозможных значениях, которые могут встретиться в таблице. В частности, значения типов int64, uint64, double, boolean внутри каждого из этих типов упорядочены естественным образом, значения типа string упорядочены лексикографически, а два значения разных типов данных сравниваются так, как сравниваются их типы в некотором implementation defined порядке. Например, любой int64 меньше любого uint64, а любой null меньше любого не null (#
) значения.
Поэтому при сравнении значений всегда обязательно следить за типом данных; в частности, беззнаковые целые числа нужно указывать с суфииксом u
, а дробные числа с десятичной точкой.
key
Селектор Селектор key
доступен к использованию только для сортированных таблиц, у которых все ключевые колонки отсортированы по возрастанию. Селектор key
имеет тип "список значений", а его поведение определяется следующим образом.
Рассмотрим множество всевозможных кортежей, состоящих из значений системы типов YTsaurus. Определим на этих кортежах линейный порядок по лексикографическому принципу, например:
[] < ["a"] < ["a"; 3] < ["a"; 4] < ["b"] < ["b"; 2]
В таком порядке можно сравнивать между собой два кортежа любой длины. Порядок сравнения определяется тем, как сравниваются первые различающиеся компоненты кортежей, если такие есть; в противном случае меньшим является более короткий кортеж.
Если селектор key
указан как часть ограничения lower_limit
(или в качестве нижней границы перед двоеточием в модификаторе выбора строк в суффиксе YPath), то он оставляет из множества всех строк только те, у которых полный ключ как кортеж больше либо равен кортежу key
в смысле порядка сравнения выше. В частности, это означает, что селектор key
может содержать кортеж, состоящий из меньшего или большего числа значений, чем число ключевых колонок в таблице, и это не нарушает корректности определения.
Если селектор key
указан как часть ограничения upper_limit
(или в качестве верхней границы после двоеточия в модификаторе выбора строк в суффиксе YPath), то он оставляет из множества всех строк только те, у которых полный ключ как кортеж строго меньше кортежа key
.
Если селектор key
указан как часть ограничения exact
(или в качестве единственной границы без двоеточия в модификаторе выбора строк в суффиксе YPath), то он оставляет из множества всех строк только те, у которых полный ключ содержит кортеж key
в качестве префикса.
Примеры
Пусть таблица //tmp/t
имеет две ключевые колонки и содержит следующие ключи:
["a"; 1];
["a"; 3];
["a"; 5];
["b"; 2];
["b"; 4];
["c"; 0];
Срез //tmp/t[(b):]
, он же <ranges = [{lower_limit = {key = [b]}}]>//tmp/t
:
["b"; 2];
["b"; 4];
["c"; 0];
Срез //tmp/t[(b, 2, 56):]
(обратите внимание, что ключ в срезе может иметь больше значений, чем количество ключевых колонок в таблице):
["b"; 4];
["c"; 0];
Срез //tmp/t[:(c, 0)]
:
["a"; 1];
["a"; 3];
["a"; 5];
["b"; 2];
["b"; 4];
Срез //tmp/t[(b)]
:
["b"; 2];
["b"; 4];
Примечание
Для того, чтобы с использованием селектора типа key
получить исключительную нижнюю границу или включительную верхнюю, необходимо вместо соответствующего кортежа указывать его последователя (successor) в смысле линейного порядка, определённого на кортежах выше, что в общем случае может быть непростой задачей. Данное обстоятельство послужило мотивацией для появления селектора типа key_bound
, который обсуждается в следующем разделе.
key_bound
Селектор Селектор key_bound
доступен к использованию в сортированных таблицах, ключевые колонки которых могут быть сортированы как по убыванию, так и по возрастанию. Значение селектора типа key_bound
имеет вид списка, состоящего из двух значений, первое из которых задаёт отношение и представляется одной из четырёх строк ">", ">=", "<", "<="
, а второе задаёт префикс ключа и является списком значений. Отношения >
и >=
могут встречаться только в ограничении lower_limit
, а <
и <=
только в ограничении upper_limit
; в ограничении exact
селекторы типа key_bound
не допускаются.
Примеры селекторов типа key_bound
:
[">"; ["a"; 3]]
["<="; ["b"]]
[">="; []]
Семантика данного селектора следующая. Рассмотрим таблицу, содержащую N
ключевых колонок, а также некоторый key bound. Пусть длина префикса ключа в key bound равна K
. Для использования key bound в применении к данной таблице, K
должно находиться в пределах 0 до N
; попытка указать более длинный префикс в key bound приведёт к ошибке.
Для того, чтобы понять, подходит ли строка с некоторым ключом под селектор, необходимо оставить от ключа префикс длины K
, и сравнить результат с префиксом ключа из key bound лексикографически. Если результат сравнения соответствует указанному отношению, то строка попадает в результат, в противном случае нет.
Примечание
Если некоторая колонка является ключевой и отсортирована в обратном порядке (sort_order = descending
), то результаты всех сравнений соответствующей компоненты кортежа ключа инвертируются; в частности, будут верны соотношения 5u < 2u
и "foo" < #
.
Также обратите внимание, что в определении поведения селектора key_bound
сравниваются только кортежи одинаковой длины K
, поэтому вопрос определения сравнения кортежей разной длины в присутствии обратного порядка сортировки не возникает.
В частности, по определению выше селекторы [">="; []]
, ["<="; []]
допускают любую строку (так как после оставления префикса ключа длины 0 получается кортеж []
), а селекторы [">"; []]
, ["<"; []]
не допускают никакую строку.
Примеры
Рассмотрим таблицу //tmp/t
с теми же ключами, что и в примере выше:
["a"; 1];
["a"; 3];
["a"; 5];
["b"; 2];
["b"; 4];
["c"; 0];
Срез <ranges = [{lower_limit = {key_bound = [">"; ["a"; 3]]}}]>//tmp/t
:
["a"; 5];
["b"; 2];
["b"; 4];
["c"; 0];
Срез <ranges = [{upper_limit = {key_bound = ["<="; ["b"]]}}]>//tmp/t
:
["a"; 1];
["a"; 3];
["a"; 5];
["b"; 2];
["b"; 4];
Примечание
Обратите внимание, что несмотря на то, что кортеж ["b"; 2]
лексикографически превосходит кортеж ["b"]
, ключ ["b"; 2]
при усечении до длины 1 превращается в кортеж ["b"]
, и поэтому он допускается key bound ["<="; ["b"]]
. Это отличает поведение селектора key_bound
в от селектора key
, и расширяет возможности первого по сравнению со вторым, так как с помощью селектора key
задать аналогичный срез нетривиально.
Срез <ranges = [{lower_limits = {key_bound = [">="; ["b"; 2; 56]]}}]>//tmp/t
не является допустимым, и его использованием приведёт к ошибке Key bound length must not exceed schema key prefix length
.