Por que x IS NOT NULL
não é igual a NOT x IS NULL
?
Este código:
CREATE TABLE bug_test (
id int,
name text
);
INSERT INTO bug_test
VALUES (1, NULL);
DO $$
DECLARE
v_bug_test bug_test;
BEGIN
RAISE NOTICE '%: %', v_bug_test, (v_bug_test IS NULL);
RAISE NOTICE '%: %', v_bug_test, (v_bug_test IS NOT NULL);
RAISE NOTICE '%: %', v_bug_test, (NOT v_bug_test IS NULL);
SELECT *
INTO v_bug_test
FROM bug_test
WHERE id = 1;
RAISE NOTICE '%: %', v_bug_test, (v_bug_test IS NULL);
RAISE NOTICE '%: %', v_bug_test, (v_bug_test IS NOT NULL);
RAISE NOTICE '%: %', v_bug_test, (NOT v_bug_test IS NULL);
END
$$;
DROP TABLE bug_test;
dá a seguinte saída:
(,): t
(,): f
(,): f
(1,): f
(1,): f ???
(1,): t
enquanto eu esperaria obter esta saída:
(,): t
(,): f
(,): f
(1,): f
(1,): t <<<
(1,): t
Você tem que distinguir duas situações: você compara uma COLUMN com NULL, ou você compara toda a ROW (RECORD) com NULL.
Considere a seguinte consulta:
Você consegue isso:
Isso é, eu acho, o que você e eu esperaríamos. Você está verificando uma COLUNA contra NULL e obtém "txt IS NOT NULL" e "NOT txt IS NULL" são equivalentes.
No entanto, se você fizer uma verificação diferente:
Então você consegue
Isso pode ser surpreendente. Uma coisa parece razoável (x IS NULL) e (NOT x IS NULL) são o oposto um do outro. A outra coisa (o fato de que nem "x IS NULL" nem "x IS NOT NULL" são verdadeiros) parece estranho.
No entanto, é isso que a documentação do PostgreSQL diz que deve acontecer:
Devo confessar que acho que nunca usei uma comparação de valor de linha contra nulo, mas acho que, se houver essa possibilidade, pode haver algum caso de uso para isso. Eu não acho que é comum, de qualquer maneira.