Esta função usada para mesclar 2 JSONB
e excluir determinada chave quando o valor é nulo, consulte esta questão.
CREATE FUNCTION jsonb_merge(JSONB, JSONB)
RETURNS JSONB AS $$
WITH json_union AS (
SELECT * FROM JSONB_EACH($1)
UNION ALL
SELECT * FROM JSONB_EACH($2)
) SELECT JSON_OBJECT_AGG(key, value)::JSONB
FROM json_union
WHERE key NOT IN (SELECT key FROM json_union WHERE value ='null');
$$ LANGUAGE SQL;
Primeira pergunta , por que value = 'null'
funciona, mas value IS NULL
não é?
Segunda pergunta , há alguma razão ruim para usar WHERE value <> 'null'
em vez de WHERE key NOT IN (SELECT key FROM ...)
?
CREATE FUNCTION jsonb_merge(JSONB, JSONB)
RETURNS JSONB AS $$
WITH json_union AS (
SELECT * FROM JSONB_EACH($1)
UNION ALL
SELECT * FROM JSONB_EACH($2)
) SELECT JSON_OBJECT_AGG(key, value)::JSONB
FROM json_union
WHERE value <> 'null';
$$ LANGUAGE SQL;
Terceira pergunta , por que essa função também está incorreta (sempre retorna NULL
)? É porque UNION ALL altera todos os registros resultantes para TEXT
?
CREATE FUNCTION jsonb_merge(JSONB, JSONB)
RETURNS JSONB AS $$
WITH json_union AS (
SELECT * FROM JSONB_EACH($1)
UNION ALL
SELECT * FROM JSONB_EACH($2)
) SELECT JSON_OBJECT_AGG(key, value)::JSONB
FROM json_union
WHERE value <> (NULL::JSONB)
$$ LANGUAGE SQL;
-- check function:
SELECT COALESCE(jsonb_merge('{}','{"b":null}'),'{"x":"its empty"}'::JSONB) FROM xxx;
coalesce
--------------------
{"x": "its empty"}
Questão 1
Da documentação do PostgreSQL Tabela 8.23 - Tipos primitivos JSON e tipos PostgreSQL correspondentes :
Portanto, você não deve confundir o
NULL
valor SQL comJSON
o tipo nulo.Questão 2
Em sua pergunta anterior, você queria que o valor JSON nulo agisse como uma espécie de tipo DELETE. Se você tiver ambos
{"b": 3}
e{"b": null}
noUNION
e você não será excluídovalue <> 'null'
.{"b": 3}
Quando você fizer isso,NOT IN
o parb:3
também será deixado de fora do novo conjunto (o tipo nulo é encontrado para a chave "b" na subconsulta).Pergunta 3
Relacionada à pergunta 1:
NULL::JSONB
significa um valor SQL NULL do tipo de dados JSONB, não um tipo nulo JSON.