Skip to content

mt_jsonb_fix_null_parent is not creating object structure properly #3722

Closed
@marcin-brzozowski

Description

@marcin-brzozowski

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions