Приведение к типам MAP
Тип MAP используется для хранения и обработки данных в виде пар «ключ-значение», в которых ключи и значения могут иметь различные базовые типы, а также позволяет вкладывать другие сложные типы.
Приведение к MAP
Из String
До версии 4.0 некоторые строки, не соответствующие формату MAP, могли успешно преобразовываться (например, '{1:1,2}'). Начиная с версии 4.0, при преобразовании строк, не соответствующих формату MAP, в строгом режиме возникает ошибка, а в нестрогом режиме возвращается NULL.
Строгий режим
Определение BNF
<map> ::= "{" <map-content>? "}" | <empty-map>
<empty-map> ::= "{}"
<map-content> ::= <key-token> <map_key_delimiter> <value-token>
(<collection-delim> <key-token> <map_key_delimiter> <value-token>)*
<key-token> ::= <whitespace>* "\"" <inner-sequence> "\"" <whitespace>*
| <whitespace>* "'" <inner-sequence> "'" <whitespace>*
| <whitespace>* <inner-sequence> <whitespace>*
<value-token> ::= <key-token>
<inner-sequence> ::= .*
<collection-delim> ::= ","
<map_key_delimiter> ::= ":"
Описание правил
- Текстовое представление MAP должно начинаться с открывающей фигурной скобки
{и заканчиваться закрывающей фигурной скобкой}. - Пустые значения MAP представляются непосредственно как
{}. - Пары «ключ-значение» внутри MAP разделяются запятыми
,. - Каждая пара состоит из ключа, двоеточия
:и значения, расположенных в порядке "key:value". - Ключи и значения можно заключать в парные одинарные (
') или двойные (") кавычки. Содержимое кавычек обрабатывается как единое целое. - До и после элементов внутри MAP допускаются пробельные символы.
- При разборе к частям, соответствующим
<key-token>, далее применяются правила разбора типа K; к частям, соответствующим<value-token>, далее применяются правила разбора типа V. Применяемые правила BNF и логика разбора также считаются частью BNF и логики разбора текущего MAP<K, V>, а соответствующая обработка ошибок и передача результатов определяют поведение и результаты текущего MAP<K, V>. - В элементах можно использовать "null" для обозначения значения null.
Если значение не соответствует формату MAP или ключ либо значение в паре не соответствует формату своего типа, возникает ошибка.
Примеры
| Исходная строка | Результат приведения | Примечание |
|---|---|---|
| "{}" | {} | Корректное пустое значение MAP |
| " {}" | Ошибка | Не начинается с фигурной скобки, разбор завершается ошибкой |
| '{123:456}' | Приведение к MAP<int,int>: {123:456} | Корректное значение MAP |
| '{123:null}' | Приведение к MAP<int,int>: {123:null} | Корректное значение MAP, содержащее значение null |
| '{ 123 : 456 }' | Приведение к MAP<int,int>: {123:456} | Корректное значение MAP с пробелами |
| '{"123":"456"}' | Приведение к MAP<int,int>: {123:456} | Корректное значение MAP с кавычками |
| '{ "123":"abc" }' | Ошибка | "abc" нельзя преобразовать в тип int |
| '{ 1:2 ,34, 5:6}' | Ошибка | Не соответствует формату MAP |
Нестрогий режим
Определение BNF
<map> ::= "{" <map-content>? "}" | <empty-map>
<empty-map> ::= "{}"
<map-content> ::= <key-token> <map_key_delimiter> <value-token>
(<collection-delim> <key-token> <map_key_delimiter> <value-token>)*
<key-token> ::= <whitespace>* "\"" <inner-sequence> "\"" <whitespace>*
| <whitespace>* "'" <inner-sequence> "'" <whitespace>*
| <whitespace>* <inner-sequence> <whitespace>*
<value-token> ::= <key-token>
<inner-sequence> ::= .*
<collection-delim> ::= ","
<map_key_delimiter> ::= ":"
Описание правил
- Текстовое представление MAP должно начинаться с открывающей фигурной скобки
{и заканчиваться закрывающей фигурной скобкой}. - Пустые значения MAP представляются непосредственно как
{}. - Пары «ключ-значение» внутри MAP разделяются запятыми
,. - Каждая пара состоит из ключа, двоеточия
:и значения, расположенных в порядке "key:value". - Ключи и значения можно заключать в парные одинарные (
') или двойные (") кавычки. Содержимое кавычек обрабатывается как единое целое. - До и после элементов внутри MAP допускаются пробельные символы.
- При разборе к частям, соответствующим
<key-token>, далее применяются правила разбора типа K; к частям, соответствующим<value-token>, далее применяются правила разбора типа V. Применяемые правила BNF и логика разбора также считаются частью BNF и логики разбора текущего MAP<K, V>, а соответствующая обработка ошибок и передача результатов определяют поведение и результаты текущего MAP<K, V>. - В элементах можно использовать "null" для обозначения значения null.
Если значение MAP не соответствует приведённому выше формату BNF, возвращается NULL. Если ключ или значение в паре не соответствует формату своего типа, в соответствующую позицию записывается null.
Примеры
| Исходная строка | Результат приведения | Примечание |
|---|---|---|
| "{}" | {} | Корректное пустое значение MAP |
| " {}" | NULL | Не начинается с фигурной скобки, разбор завершается ошибкой |
| '{123:456}' | Приведение к MAP<int,int>: {123:456} | Корректное значение MAP |
| '{123:null}' | Приведение к MAP<int,int>: {123:null} | Корректное значение MAP, содержащее значение null |
| '{ 123 : 456 }' | Приведение к MAP<int,int>: {123:456} | Корректное значение MAP с пробелами |
| '{"123":"456"}' | Приведение к MAP<int,int>: {123:456} | Корректное значение MAP с кавычками |
| '{ "123":"abc" }' | Приведение к MAP<int,int>: {123:null} | "abc" нельзя преобразовать в тип int, поэтому оно преобразуется в null |
| '{ 1:2 ,34, 5:6}' | NULL | Не соответствует формату MAP |
Повторяющиеся ключи во вложенных MAP
При приведении строки к MAP, ARRAY или STRUCT Doris удаляет повторяющиеся ключи из каждого MAP в результате преобразования, включая MAP, вложенные в ARRAY, STRUCT или значение MAP. Если ключ встречается несколько раз, сохраняется последнее значение.
SELECT CAST('{"outer":[{"a":1,"a":2}]}' AS MAP<STRING, ARRAY<MAP<STRING, INT>>>);
SELECT CAST('[{"a":1,"a":2}]' AS ARRAY<MAP<STRING, INT>>);
SELECT CAST('{"m":{"a":1,"a":2}}' AS STRUCT<m:MAP<STRING, INT>>);
{"outer":[{"a":2}]}
[{"a":2}]
{"m":{"a":2}}
Из MAP<другого типа>
Строгий режим
Описание правил
Для каждого элемента MAP выполняется приведение из другого типа к целевому типу. Это приведение также выполняется в строгом режиме.
Примеры
| Исходный MAP | Результат приведения | Примечание |
|---|---|---|
| {"123":"456"} | Приведение к MAP<int,int>: {123:456} | "123" и "456" можно преобразовать в Int |
| {"abc":"123"} | Ошибка | "abc" нельзя преобразовать в Int |
| {"123":null} | Приведение к MAP<int,int>: {123:null} | Результат приведения null остаётся null |
Нестрогий режим
Описание правил
Для каждого элемента MAP выполняется приведение из другого типа к целевому типу. Это приведение также выполняется в нестрогом режиме.
Примеры
| Исходный MAP | Результат приведения | Примечание |
|---|---|---|
| {"123":"456"} | Приведение к MAP<int,int>: {123:456} | "123" и "456" можно преобразовать в Int |
| {"abc":"123"} | Приведение к MAP<int,int>: {null:123} | "abc" нельзя преобразовать в Int, поэтому оно преобразуется в null |
| {"123":null} | Приведение к MAP<int,int>: {123:null} | Результат приведения null остаётся null |