Errors
Trino

Trino: Checking if key exists in Presto value map

Ты пишешь запрос, ждешь. И тут — бац — `Key not present in map: element`. Знакомо? Такое чувство, что данные просто издеваются. Ты же явно просил ключ `element`

Ты пишешь запрос, ждешь. И тут — бац — Key not present in map: element. Знакомо? Такое чувство, что данные просто издеваются. Ты же явно просил ключ element, он же должен быть там.

Ты идешь логичным путем: AND contains(value_map, 'element'). Не работает. Тип данных говорит varchar(9). Начинаешь подозревать, что map — это не map. Или map, но не совсем. Замкнутый круг.

Почему contains не сработал

Функция contains работает с массивами. Map — это не массив. Это ключ-значение. Если в твоем случае typeof возвращает varchar, это уже тревожный звоночек. Значит, в колонке value_map у тебя может быть и JSON в виде строки, и настоящая map, приведенная к тексту. Нужно смотреть глубже.

Но допустим, это все-таки map. В Trino (ранее Presto) есть жесткое правило: попытка доступа к несуществующему ключу через квадратные скобки map['key'] немедленно вызывает ошибку. Это не NULL, это STOP.

Именно это и случилось в твоем запросе. Scheduler не при чем, тут логика исполнения запроса.

Правильный способ: element_at

Нужно использовать функцию element_at. Она делает две вещи: находит значение по ключу и, если ключа нет, возвращает NULL. Без взрывов и ошибок.

SELECT element_at(value_map, 'element')
FROM mytable
WHERE name = 'foobar'

Но этого мало. Чтобы выбрать только записи, где ключ присутствует, нужно отфильтровать по NOT NULL.

SELECT element_at(value_map, 'element')
FROM mytable
WHERE name = 'foobar'
  AND element_at(value_map, 'element') IS NOT NULL

Вот так. Запрос спокойно выполнится, а в результате будут только строки с существующим ключом element.

А если это все-таки строка?

Если typeof упорно показывает varchar, то перед тобой не map, а строка. Скорее всего, JSON. Тогда нужно привести ее к типу map с помощью CAST или распарсить JSON-функциями. Но это уже другая история.

Порядок отладки такой: проверь реальный тип данных через SELECT typeof(value_map) FROM mytable LIMIT 1. Если это map — переходи на element_at. Если varchar — готовься к касту.

В 90% случаев проблема в попытке доступа через скобки. Остальные 10% — это загадочные строки вместо map. И лишь 0.1% — виноваты квазары. Но с ними, увы, не поспоришь.