Errors
Trino

Trino: How to cast varchar to MAP(VARCHAR,VARCHAR) in presto

Ты пишешь запрос в Trino, пытаешься превратить строку с JSON в MAP и получаешь какую-нибудь классическую ошибку `Cannot cast varchar to map(varchar,varchar)`. П

Ты пишешь запрос в Trino, пытаешься превратить строку с JSON в MAP и получаешь какую-нибудь классическую ошибку Cannot cast varchar to map(varchar,varchar). Потому что так нельзя.

Trino не умеет кастить текст напрямую в MAP, даже если этот текст — валидный JSON. Для него это просто строка. Сначала нужно распарсить JSON, а уже потом привести его к нужному типу.

JSON -> MAP, правильный путь

Всё решается в два шага. Сначала функция json_parse, которая превращает строку в структурированный JSON-тип Trino. Потом — явный каст к MAP(VARCHAR, VARCHAR).

SELECT CAST(json_parse(mappings) AS MAP(VARCHAR, VARCHAR)) AS my_map
FROM hello;

Вот и всё. Если в колонке mappings лежит {"foo": "baar", "foo1": "bar1"}, то на выходе получишь настоящий MAP, с которым можно работать: обращаться по ключам, использовать функции вроде element_at или map_keys.

Почему нельзя просто CAST?

Потому что типизация. VARCHAR — это текст, а MAP(...) — сложный тип. Прямого преобразования нет. Нужен явный парсинг, который проверит валидность JSON и его структуру.

Если попробовать SELECT CAST('{"a":1}' AS MAP(VARCHAR, VARCHAR)); — будет ошибка. А вот SELECT CAST(json_parse('{"a":1}') AS MAP(VARCHAR, VARCHAR)); сработает.

Что делать, если в данных есть мусор или NULL?

Оберни в TRY, чтобы запрос не падал.

SELECT TRY(CAST(json_parse(mappings) AS MAP(VARCHAR, VARCHAR))) AS my_map
FROM hello;

Если встретится невалидный JSON или тип не совпадёт (например, число вместо строки в значении) — в my_map получишь NULL. Идеально для продакшена, где данные неидеальны.

Итог

Запомни схему: строка -> json_parse() -> CAST(... AS MAP(...)). Это единственный чистый способ. Если часто нужно, вынеси в UDF или вьюху, чтобы не писать каждый раз.

Проверяй данные на валидность через TRY и спи спокойно.