Uploaded image for project: 'MariaDB Server'
  1. MariaDB Server
  2. MDEV-12877

Wrong result from JSON native function.

Details

    • Bug
    • Status: Closed (View Workflow)
    • Major
    • Resolution: Fixed
    • 10.2.6
    • 10.2.9
    • JSON
    • None
    • Windows 10

    Description

      It seems that JSON functions fail to get returned result from another function:

      select json_extract(json_object('truc',json_array('machin',4,json_object('chose','XML'))),'$.truc[2].chose') as result;
      +--------+
      | result |
      +--------+
      | "XML"  |
      +--------+
       
      select json_search(json_object('truc',json_array('machin',4,json_object('chose','XML'))),'one','XML') as Path;
      +-------------------+
      | Path              |
      +-------------------+
      | "$.truc[2].chose" |
      +-------------------+
       
      select json_extract(json_object('truc',json_array('machin',4,json_object('chose','XML'))),json_search(json_object('truc',json_array('machin',4,json_object('chose','XML'))),'one','XML')) as Result;
      +--------+
      | Result |
      +--------+
      | NULL   |
      +--------+
      

      Sould not the last query return "XML"?

      Attachments

        Issue Links

          Activity

            bertrandop Olivier Bertrand created issue -
            bertrandop Olivier Bertrand added a comment - - edited

            It seems that these functions have a general problem recognizing the type of their argument (JSON or not JSON?) for instance:

            select json_array(5,json_array(1,2));
            +-------------------------------+
            | json_array(5,json_array(1,2)) |
            +-------------------------------+
            | [5, [1, 2]]                   |
            +-------------------------------+
            

            Normal, the return from JSON_ARRAY is a JSON item.

            select json_array(5,'[1,2]');
            +-----------------------+
            | json_array(5,'[1,2]') |
            +-----------------------+
            | [5, "[1,2]"]          |
            +-----------------------+
            

            This time, the function as regarded its second argument as a string.

            select json_query('[1,2]','$');
            +-------------------------+
            | json_query('[1,2]','$') |
            +-------------------------+
            | [1,2]                   |
            +-------------------------+
             
            select json_array(5,json_query('[1,2]','$'));
            +---------------------------------------+
            | json_array(5,json_query('[1,2]','$')) |
            +---------------------------------------+
            | [5, "[1,2]"]                          |
            +---------------------------------------+
            

            This is wrong. The description of the JSON_QUERY function says
            Given a JSON document, returns an object or array specified by the path. Returns NULL if not given a valid JSON document, or if there is no match.

            Here the JSON_QUERY function, unlike the JSON_ARRAY one, has regarded its first argument as a valid JSON item since it did not return NULL. Therefore, according to the function description, it should have returned a JSON item like the JSON_ARRAY function does. But this time, its result has been regarded as a string. All this is not coherent.

            bertrandop Olivier Bertrand added a comment - - edited It seems that these functions have a general problem recognizing the type of their argument (JSON or not JSON?) for instance: select json_array(5,json_array(1,2)); +-------------------------------+ | json_array(5,json_array(1,2)) | +-------------------------------+ | [5, [1, 2]] | +-------------------------------+ Normal, the return from JSON_ARRAY is a JSON item. select json_array(5,'[1,2]'); +-----------------------+ | json_array(5,'[1,2]') | +-----------------------+ | [5, "[1,2]"] | +-----------------------+ This time, the function as regarded its second argument as a string. select json_query('[1,2]','$'); +-------------------------+ | json_query('[1,2]','$') | +-------------------------+ | [1,2] | +-------------------------+   select json_array(5,json_query('[1,2]','$')); +---------------------------------------+ | json_array(5,json_query('[1,2]','$')) | +---------------------------------------+ | [5, "[1,2]"] | +---------------------------------------+ This is wrong. The description of the JSON_QUERY function says Given a JSON document, returns an object or array specified by the path. Returns NULL if not given a valid JSON document, or if there is no match. Here the JSON_QUERY function, unlike the JSON_ARRAY one, has regarded its first argument as a valid JSON item since it did not return NULL. Therefore, according to the function description, it should have returned a JSON item like the JSON_ARRAY function does. But this time, its result has been regarded as a string. All this is not coherent.
            elenst Elena Stepanova made changes -
            Field Original Value New Value
            Status Open [ 1 ] Confirmed [ 10101 ]

            I agree, there is inconsistency here that cannot be justified by "MariaDB doesn't have JSON type" excuse. It wouldn't be surprising if all the above were treating results of nested functions as strings – that could be explained by the absence of JSON type, – but if example 1 works, there is no obvious reason why example 4 does not.

            elenst Elena Stepanova added a comment - I agree, there is inconsistency here that cannot be justified by "MariaDB doesn't have JSON type" excuse. It wouldn't be surprising if all the above were treating results of nested functions as strings – that could be explained by the absence of JSON type, – but if example 1 works, there is no obvious reason why example 4 does not.
            elenst Elena Stepanova made changes -
            Fix Version/s 10.2 [ 14601 ]
            Assignee Alexey Botchkov [ holyfoot ]

            In addition, there is more problems when the argument is the result of a UDF function:

            select
            json_extract(json_object('truc',json_array('machin',4,json_object('chose','XML'))),
            jsonlocate(json_object('truc',json_array('machin',4,json_object('chose','XML'))),'XML'));
            

            This simply ... make the server crash.
            Jsonlocate is a JSON UDF that here returns the string:

            $.truc[2].chose
            

            Given that string as argument the function json_extract works fine.

            bertrandop Olivier Bertrand added a comment - In addition, there is more problems when the argument is the result of a UDF function: select json_extract(json_object('truc',json_array('machin',4,json_object('chose','XML'))), jsonlocate(json_object('truc',json_array('machin',4,json_object('chose','XML'))),'XML')); This simply ... make the server crash. Jsonlocate is a JSON UDF that here returns the string: $.truc[2].chose Given that string as argument the function json_extract works fine.
            holyfoot Alexey Botchkov added a comment - - edited

            What is in the 'Description' part is not a bug. (and yes, MySQL returns just same result.
            Explanation is simple - the json_search returns JSON, and the json_extract expects a string.
            You can fix that using json_unquote().

            MariaDB [(none)]> select json_extract(json_object('truc',json_array('machin',4,json_object('chose','XML'))),json_unquote(json_search(json_object('truc',json_array('machin',4,json_object('chose','XML'))),'one','XML'))) as Result;
            +--------+
            | Result |
            +--------+
            | "XML"  |
            +--------+
            1 row in set (0.00 sec)
            

            holyfoot Alexey Botchkov added a comment - - edited What is in the 'Description' part is not a bug. (and yes, MySQL returns just same result. Explanation is simple - the json_search returns JSON, and the json_extract expects a string. You can fix that using json_unquote(). MariaDB [(none)]> select json_extract(json_object('truc',json_array('machin',4,json_object('chose','XML'))),json_unquote(json_search(json_object('truc',json_array('machin',4,json_object('chose','XML'))),'one','XML'))) as Result; +--------+ | Result | +--------+ | "XML" | +--------+ 1 row in set (0.00 sec)
            holyfoot Alexey Botchkov made changes -
            Status Confirmed [ 10101 ] In Progress [ 3 ]
            holyfoot Alexey Botchkov added a comment - - edited

            select json_array(5,'[1,2]');
            +-----------------------+
            | json_array(5,'[1,2]') |
            +-----------------------+
            | [5, "[1,2]"]          |
            +-----------------------+
            This time, the function as regarded its second argument as a string.
            

            This is also the correct result. Both MariaDB and MySQL return this.
            You need to specify that the second parameter is JSON explicitly.

            MariaDB [(none)]> select json_array(5,json_compact('[1,2]'));
            +-------------------------------------+
            | json_array(5,json_compact('[1,2]')) |
            +-------------------------------------+
            | [5, [1,2]]                          |
            +-------------------------------------+
            1 row in set (0.00 sec)
            

            holyfoot Alexey Botchkov added a comment - - edited select json_array(5,'[1,2]'); +-----------------------+ | json_array(5,'[1,2]') | +-----------------------+ | [5, "[1,2]"] | +-----------------------+ This time, the function as regarded its second argument as a string. This is also the correct result. Both MariaDB and MySQL return this. You need to specify that the second parameter is JSON explicitly. MariaDB [(none)]> select json_array(5,json_compact('[1,2]')); +-------------------------------------+ | json_array(5,json_compact('[1,2]')) | +-------------------------------------+ | [5, [1,2]] | +-------------------------------------+ 1 row in set (0.00 sec)

            select json_array(5,json_query('[1,2]','$'));
            +---------------------------------------+
            | json_array(5,json_query('[1,2]','$')) |
            +---------------------------------------+
            | [5, "[1,2]"]                          |
            +---------------------------------------+
            

            This is indeed wrong. FIxed.

            holyfoot Alexey Botchkov added a comment - select json_array(5,json_query('[1,2]','$')); +---------------------------------------+ | json_array(5,json_query('[1,2]','$')) | +---------------------------------------+ | [5, "[1,2]"] | +---------------------------------------+ This is indeed wrong. FIxed.

            Crashing UDF call also fixed.
            Though for me that jsonlocate call returned ' truc:[2]:chose ' which was not a right path.

            holyfoot Alexey Botchkov added a comment - Crashing UDF call also fixed. Though for me that jsonlocate call returned ' truc: [2] :chose ' which was not a right path.
            holyfoot Alexey Botchkov made changes -
            issue.field.resolutiondate 2017-09-12 21:05:04.0 2017-09-12 21:05:04.939
            holyfoot Alexey Botchkov made changes -
            Fix Version/s 10.2.9 [ 22611 ]
            Fix Version/s 10.2 [ 14601 ]
            Resolution Fixed [ 1 ]
            Status In Progress [ 3 ] Closed [ 6 ]
            bertrandop Olivier Bertrand added a comment - - edited

            Alexey: you probably used a deprecated version of this UDF. Current version returns '$.truc[2].chose'.
            Thanks for fixing it anyway.

            bertrandop Olivier Bertrand added a comment - - edited Alexey: you probably used a deprecated version of this UDF. Current version returns '$.truc [2] .chose'. Thanks for fixing it anyway.
            greenman Ian Gilfillan made changes -
            greenman Ian Gilfillan added a comment -

            MySQL and MariaDB don't behave quite the same in that MariaDB gives a warning, MySQL an error - I've reported this separately as MDEV-13794

            greenman Ian Gilfillan added a comment - MySQL and MariaDB don't behave quite the same in that MariaDB gives a warning, MySQL an error - I've reported this separately as MDEV-13794
            serg Sergei Golubchik made changes -
            Workflow MariaDB v3 [ 80897 ] MariaDB v4 [ 152205 ]

            People

              holyfoot Alexey Botchkov
              bertrandop Olivier Bertrand
              Votes:
              0 Vote for this issue
              Watchers:
              5 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Git Integration

                  Error rendering 'com.xiplink.jira.git.jira_git_plugin:git-issue-webpanel'. Please contact your Jira administrators.