Типы данных, допускающие значение NULL
Любые типизированные данные в YQL, включая столбцы таблиц, бывают как гарантированно имеющие значение, так и потенциально пустые (что обозначается как NULL). Типы данных, которые могут содержать значения NULL, называются опциональными или, в терминах SQL, — nullable.
Опциональные типы данных в текстовом виде обозначаются вопросительным знаком в конце (например, String?) или как Optional<...>.
Наиболее часто на опциональных типах данных выполняются следующие операции:
- IS NULL — проверка на пустое значение
- COALESCE — оставить заполненные значения без изменений, а
NULLзаменить на указанное следом значение по умолчанию - UNWRAP — извлечь значение оригинального типа из опционального,
T?преобразуется вT - JUST — добавить опциональность к текущему типу,
Tпреобразуется вT? - NOTHING — создать пустое значение с указанным типом.
Optional (nullable) является не свойством типа данных или колонки, а одним из видов контейнеров, которые могут быть произвольным образом вложены друг в друга. Так, например, столбец с типом Optional<Optional<Boolean>> может принимать 4 значения — NULL всего контейнера, NULL внутреннего контейнера, TRUE и FALSE. Описанный тип отличается от List<List<Boolean>> тем, что роль пустого списка в нем играет NULL и отсутствует возможность положить больше одного содержательного элемента. Также значения типа Optional<Optional<T>> возвращаются в качестве результата поиска по ключу в словаре Dict(k,v) со значениями типа Optional<T>. Такой тип данных результата позволяет отличать лежащий в словаре NULL от ситуации отсутствия ключа.
Пример
$dict = {"a":1, "b":null};
$found = $dict["b"];
select if($found is not null, unwrap($found), -1);
Результат:
# column0
null
Логические и арифметические операции с NULL
Литерал NULL имеет отдельный сингулярный тип Null и может быть неявно сконвертирован к любому опциональному типу (в том числе и вложенному Optional<Optional<...Optional<T>...>>). В ANSI SQL NULL имеет семантику "неизвестное значение" – поэтому логические и арифметические операции с NULL или с незаполненными Optional имеют некоторые особенности.
Примеры
SELECT
True OR NULL, -- Just(True) (работает как True OR <неизвестное значение типа Bool>)
False AND NULL, -- Just(False)
True AND NULL, -- NULL (точнее Nothing<Bool?> – <неизвестное значение типа Bool>)
NULL OR NOT NULL, -- NULL (все NULL-ы "разные")
1 + NULL, -- NULL (Nothing<Int32?>) — результат сложения 1 с
-- неизвестным значением типа Int)
1 == NULL, -- NULL (результат сравнения 1 с неизвестным значением типа Int)
(1, NULL) == (1, 2), -- NULL (сравнение композитных элементов производится покомпонентно
-- через `AND`)
(2, NULL) == (1, 3), -- Just(False) (выражение эквивалентно 2 == 1 AND NULL == 3)