This function used to merge 2 JSONB
and delete certain key when the value is null, refer to this question.
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;
First question, why value = 'null'
works, but value IS NULL
is not?
Second question, is there any bad reason to use WHERE value <> 'null'
instead of 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;
Third question, why this function also incorrect (always returns NULL
)? Is it because UNION ALL change all resulting record into 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"}