Under normal conditions, comparing a NULL value to any other value results in another NULL value.
SELECT NULL = NULL;
Returns NULL
This holds (mostly) true when comparing arbitrary rows, as explained in the documentation, 9.23.5. Row Constructor Comparison:
SELECT ROW(1, NULL, 'baz text') = ROW(1, NULL, 'baz text');
Returns NULL
However, when comparing well defined composite types, NULL values are treated as equal.
CREATE TYPE test_type AS (
foo INTEGER,
bar BIGINT,
baz TEXT
);
SELECT (1, NULL, 'baz text')::test_type = (1, NULL, 'baz text')::test_type;
Returns TRUE
This behavior seems to be undocumented (I have looked and found no reference to the behavior).
I would like to use this behavior to implement some business rules and want to make sure it is safe to do so.
- Is this consistent with any SQL specification?
- Is it likely this will change in the future?
SELECT ROW(1, NULL, 'baz text') IS NOT DISTINCT FROM ROW(1, NULL, 'baz text');IS NOT DISTINCT FROMclause; however, I'm interested in the=operator when used with composite types.{ "type": "test_type", "value": "(,,)" }={ "type": "test_type", "value": "(,,)" }=> true(NULL,NULL, NULL)::test_type IS NULLReturnsTRUE- I find that even more interesting asSELECT ARRAY[NULL] IS NULLReturnsFALSE(not relevant to this question, just interesting).If the expression is row-valued, then IS NULL is true when the row expression itself is null or when all the row's fields are null, while IS NOT NULL is true when the row expression itself is non-null and all the row's fields are non-null.