空复合类型和具有所有空列的复合类型之间的区别



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

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

NULL:node仍然与(null, null)::node不同:

SELECT null::node IS DISTINCT FROM (null, null)::node AS dist;
dist
----
t

我同意这令人困惑。手册也可能在这里锐化:

对于非空输入,IS DISTINCT FROM<>运算符相同。 但是,如果两个输入都为 null,则返回 false,如果只有一个输入 输入为空,则返回 true。

事实证明,面对上面的演示,有点不正确。即使下面有一个提示:

如果expression是行值,则当行为真时IS NULL为 true。 表达式本身为 null 或当行的所有字段均为 null 时。

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

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

应该提到的是,与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)
);

请注意两件事:

  1. 显式强制转换(null, null)::node是必需的。
  2. 仍然允许简单的 NULL 值,只有包含所有 null 值的行违反约束。

相关内容

  • 没有找到相关文章

最新更新