Description
Hi, I've noticed that calling the mt_jsonb_fix_null_parent
SQL function as follows does not work properly:
Test with PostgreSQL version: PostgreSQL 14.17
Actual output:
SELECT mt_jsonb_fix_null_parent('{"a": null}'::jsonb, ARRAY['a', 'b', 'x']);
result
-----------
{"a": {}}
Expected output:
SELECT mt_jsonb_fix_null_parent('{"a": null}'::jsonb, ARRAY['a', 'b', 'x']);
result
------------------
{"a": {"b": {}}}
When looking at the source code, it seems to me that the if condition checking for NULL is at fault;
IF retval #> dst_path_segment = 'null'::jsonb THEN
CREATE OR REPLACE FUNCTION mt_jsonb_fix_null_parent(jsonb, text[])
RETURNS jsonb
LANGUAGE plpgsql
AS $function$
DECLARE
retval ALIAS FOR $1;
dst_path ALIAS FOR $2;
dst_path_segment text[] = ARRAY[]::text[];
dst_path_array_length integer;
i integer = 1;
BEGIN
dst_path_array_length = array_length(dst_path, 1);
WHILE i <=(dst_path_array_length - 1)
LOOP
dst_path_segment = dst_path_segment || ARRAY[dst_path[i]];
IF retval #> dst_path_segment = 'null'::jsonb THEN
retval = jsonb_set(retval, dst_path_segment, '{}'::jsonb, TRUE);
END IF;
i = i + 1;
END LOOP;
RETURN retval;
END;
$function$;
I tried changing this condition to the following, which seems to resolve the issue:
IF retval #> dst_path_segment IS NULL THEN
.
Looking forward to your feedback, I'm more than happy to do a PR with a fix for this, but would need some guidance whether this change might back-fire in some edge cases.
I've created a simple SQLFiddle with both versions of the functions (current and "fixed" showing difference in output): https://sqlfiddle.com/postgresql/online-compiler?id=55c69de0-082f-46ab-86da-54a0c4ad97d5