3

空值和所有列都为空的行类型之间有什么区别吗?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
4

1 回答 1

7

空值和所有列都为空的行类型之间有什么区别吗?

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当行表达式本身为空或所有行的字段为空时,则为真。

所以我们有两种不同的情况,其中行值为空:

  1. 表达式本身为空。
  2. 所有行的字段都为空。

应该提到的是,与 相比,这两种情况仍然被认为是不同IS DISTINCT FROM的。可能值得一个文档错误报告...

我应该注意什么?

是的。无论在哪里DISTINCT发挥作用,两种变体都被认为是不同的:

SELECT DISTINCT * FROM hierarchy;
 node1
------
 (,)  

(2 rows)

注意第二个不可见行,因为 psql 以这种方式显示空值。

阻止 (,) 案例的发生?

处理您的评论:

CREATE TABLE hierarchy (
  node node CHECK (node IS DISTINCT FROM (null, null)::node)
);

注意两点:

  1. 显式演员表(null, null)::node是必要的。
  2. 仍然允许使用简单的 NULL 值,只有具有所有空值的行违反了约束。
于 2017-04-03T16:37:31.067 回答