null复合类型与具有所有空列的复合类型之间的差异

时间:2017-04-03 14:27:48

标签: postgresql null distinct postgresql-9.6 row-value-expression

null值和所有列为null的行类型之间是否有任何区别? Postgres查询似乎能够区分(显示空列而不是空白),我想知道是否有任何我应该注意的事项。 e.g。

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 个答案:

答案 0 :(得分:4)

  

null值和所有列都为null的rowtype之间有什么区别吗?

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

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

我同意这令人困惑。还有the manual might be sharpened here

  

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

面对上面的演示,结果有点不正确。即使有进一步的暗示:

  

如果expression是行值,则行IS NULL为真   表达式本身为null或者所有行的字段都为空。

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

  1. 表达式本身为空。
  2. 所有行的字段都为空。
  3. 应该提到的是,与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值,只有包含所有空值的行才会违反约束。