---
metadata:
  - name: generator
    content: Diplodoc Platform v5.50.4
alternate:
  - https://ydb.tech/docs/en/yql/reference/types/cast.md
  - https://ydb.tech/docs/ru/yql/reference/types/cast.md
sourcePath: ru/core/yql/reference/types/cast.md
---
> **Documentation Index:** Fetch the complete configuration index at https://ydb.tech/docs/ru/llms.txt

# Правила преобразования типов через оператор [CAST](https://ydb.tech/docs/ru/yql/reference/syntax/expressions.md#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` описаны [тут](https://ydb.tech/docs/ru/yql/reference/types/primitive.md).

## Правила преобразований для контейнеров

### Правила для Optional

* Если для целевого типа задан больший уровень `Optional` чем для исходного то это эквивалентно добавлению `Just` поверх `CAST` с меньшим уровнем `Optional`.
* Если же больший уровень `Optional` у исходного типа, то `NULL` на любом уровне больше целевого приводит к `NULL` в результате.
* При равных уровнях `Optional` значение `NULL` остаётся на том же уровне.

```yql
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` для ключей и значений.

```yql
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` для всего результата.

```yql
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`.

### Вложенные контейнеры

* Все вышеперечисленные правила работают рекурсивно для вложенных контейнеров.
