Правила преобразования типов через оператор CAST
Правила преобразования примитивных типов данных
- 
В процессе преобразования примитивных типов данных часть исходной информации может быть отброшена, если она не содержится в целевом типе. Например:
- Дробная часть 
Float/Doubleпри преобразовании в целочисленные типы; - Время 
Datetime/Timestampпри преобразовании вDate. - Таймзона при преобразовании из типов с таймзоной к типу даты/времени без таймзоны.
 
 - Дробная часть 
 - 
Если для определённого сочетания исходного и целевого типа преобразование не может быть выполнено для всех возможных значений исходного типа, то при неудачном преобразовании
CASTвернётNULL. В таких случаях к типу возвращаемого значения добавляется один уровеньOptional, если его не было. Например, конструкции:CAST("3.14" AS Float?)иCAST("3.14" AS Float)полностью эквиваленты и возвращаютFloat?. - 
Если же преобразование возможно для всех значений исходного типа, то добавление '?' работает как
Justсверху:CAST(3.14 AS Utf8?)то же, что иJust(CAST(3.14 AS Utf8)) 
Все сочетания примитивных типов, для которых возможен CAST описаны тут.
Правила преобразований для контейнеров
Правила для Optional
- Если для целевого типа задан больший уровень 
Optionalчем для исходного то это эквивалентно добавлениюJustповерхCASTс меньшим уровнемOptional. - Если же больший уровень 
Optionalу исходного типа, тоNULLна любом уровне больше целевого приводит кNULLв результате. - При равных уровнях 
OptionalзначениеNULLостаётся на том же уровне. 
SELECT
    CAST(1 AS Int32?),                  -- тоже что и Just(1)
    CAST(Just(2/1) AS Float??),         -- [2]
    CAST(Just(3/0) AS Float??) IS NULL; -- false: результат Just(NULL)
        
    Правила для List/Dict
- Список формируется путём выполнения 
CASTдля каждого элемента исходного списка в тип элемента целевого типа. - Если тип элемента целевого типа не опциональный, а 
CASTэлемента может быть неуспешным, то такие преобразования отбрасываются. В этом случае список в результате может быть меньшей длины или вовсе пустой, если успешных преобразований не было. - Для словарей преобразование выполняется полностью аналогично спискам, выполняя 
CASTдля ключей и значений. 
SELECT
    CAST([-1, 0, 1] AS List<Uint8?>),             -- [null, 0, 1]
    CAST(["3.14", "bad", "42"] AS List<Float>),   -- [3.14, 42]
    CAST({-1:3.14, 7:1.6} AS Dict<Uint8, Utf8>),  -- {7: "1.6"}
    CAST({-1:3.14, 7:1.6} AS Dict<Uint8?, Utf8>); -- {7: "1.6", null:"3.14"}
        
    Правила для Struct/Tuple
- Структура или кортеж формируется путём выполнения 
CASTдля каждого элемента исходного типа в элемент с тем же именем или индексом целевого типа. - Если какое-то поле отсутствует в целевом типе, оно просто отбрасывается.
 - Если какое-то поле отсутствует в типе исходного значения, то оно может быть добавлено только если является опциональным, и получает значение 
NULL. - Если какое-то поле не является опциональным в целевом типе, но его преобразование может быть неуспешным, то 
CASTдобавляет опциональность на уровень структуры или кортежа и может вернутьNULLдля всего результата. 
SELECT
    CAST((-1, 0, 1) AS Tuple<Uint16?, Uint16?, Utf8>), -- (null, 0, "1")
    CAST((-2, 0) AS Tuple<Uint16, Utf8>),              -- null
    CAST((3, 4) AS Tuple<Uint16, String>),             -- (3, "4") тип Tuple<Uint16, String>?
    CAST(("4",) AS Tuple<Uint16, String?>),            -- (4, null)
    CAST((5, 6, null) AS Tuple<Uint8?>);               -- (5,)  элементы удалены.
SELECT -- Одно поле удалено и одно добавлено: ("three":null, "two": "42")
    CAST(<|one:"8912", two:42|> AS Struct<two:Utf8, three:Date?>);
        
    Правила для Variant
- Для варианта с определёнными именем или индексом выполняется преобразование в вариант с тем же именем или индексом.
 - Если преобразование для варианта может быть неуспешным и тип этого варианта не опциональный, то 
CASTдобавляет опциональность на верхний уровень и может вернутьNULL. - Если какой-то вариант отсутствует в целевом типе, то 
CASTдобавляет опциональность на верхний уровень и для такого значения возвращаетNULL. 
Вложенные контейнеры
- Все вышеперечисленные правила работают рекурсивно для вложенных контейнеров.