Разница между нулевым составным типом и составным типом со всеми пустыми столбцами
Есть ли разница между нулевым значением и типом строки, где все столбцы равны нулю? Похоже, что запросы Postgres способны различать (отображая пустые столбцы, а не пустые), и я хочу знать, есть ли что-то, о чем я должен знать. например
CREATE TYPE node AS (
rank integer
, id integer
);
CREATE TABLE hierarchy (
node node
);
INSERT INTO hierarchy (node) VALUES (null);
INSERT INTO hierarchy (node) VALUES ((null, null));
SELECT *, node IS NULL AS check_null FROM hierarchy;
node | check_null ------+------------ | t (,) | t
1 ответ
Есть ли разница между нулевым значением и типом строки, где все столбцы равны нулю?
NULL:node
все еще отличается от (null, null)::node
:
SELECT null::node IS DISTINCT FROM (null, null)::node AS dist;
dist ---- t
Я согласен, что это сбивает с толку. И руководство может быть также заточено здесь:
Для ненулевых входов
IS DISTINCT FROM
такой же, как<>
оператор. Однако, если оба входа имеют значение null, он возвращает false, а если только один вход имеет значение null, он возвращает true.
Оказывается, немного неверно перед лицом выше демо. Хотя есть подсказка ниже:
Если
expression
является строкой, тоIS NULL
Значение true, если само выражение строки равно нулю или когда все поля строки равны нулю.
Итак, у нас есть два разных случая, в которых значение строки равно нулю:
- Само выражение является нулевым.
- все поля строки равны нулю.
Следует отметить, что эти два случая все еще считаются различными по сравнению с IS DISTINCT FROM
, Может быть, стоит сообщение об ошибке документации...
что-нибудь, о чем я должен знать?
Да. Где бы DISTINCT
вступает в игру, оба варианта рассматриваются, ну, четко:
SELECT DISTINCT * FROM hierarchy;
node1 ------ (,) (2 rows)
Обратите внимание на 2-ю невидимую строку, потому что psql отображает нулевые значения таким образом.
Чтобы остановить случай (,)?
Обращаясь к вашему комментарию:
CREATE TABLE hierarchy (
node node CHECK (node IS DISTINCT FROM (null, null)::node)
);
Обратите внимание на две вещи:
- Явное приведение
(null, null)::node
является необходимым. - Простые значения NULL все еще разрешены, только строка со всеми нулевыми значениями нарушает ограничение.