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% — виноваты квазары. Но с ними, увы, не поспоришь.