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

The JSON constructors and both aggregates splice a value that is not a document verbatim, producing unbalanced brackets

    XMLWordPrintable

Details

    • Bug
    • Status: Open (View Workflow)
    • Major
    • Resolution: Unresolved
    • 10.11, 11.4, 11.8, 12.3, 13.0
    • None
    • JSON

    Description

      JSON_ARRAY, JSON_OBJECT, JSON_ARRAYAGG and JSON_OBJECTAGG copy a
      JSON-typed argument into the result as it stands. Where the argument is
      not a document, what comes out is not one either - and where the
      argument's own brackets are unbalanced, the constructor's closing
      bracket is consumed as if it closed the argument's.

      SET SESSION check_constraint_checks=OFF;
      CREATE TABLE tj (id INT, c JSON);
      INSERT INTO tj VALUES (1,'{"a":1 "b":2}'),(2,'[1,2');
      SET SESSION check_constraint_checks=ON;
       
      SELECT id, JSON_ARRAY(c) AS v, JSON_VALID(JSON_ARRAY(c)) AS ok
      FROM tj ORDER BY id;
      id  v                  ok
      1   [{"a":1 "b":2}]    0
      2   [[1,2]             0

      Row 2 is the sharp one. The array constructor opened one bracket and
      wrote one closing bracket, and what came back has two opening brackets
      and one closing: the argument's dangling bracket has eaten the
      constructor's own.

      How to repeat

      SET SESSION check_constraint_checks=OFF;
      CREATE TABLE tj (id INT, c JSON);
      INSERT INTO tj VALUES (1,'{"a":1 "b":2}'),(2,'[1,2');
      SET SESSION check_constraint_checks=ON;
       
      SELECT id, JSON_ARRAY(c),        JSON_VALID(JSON_ARRAY(c))        FROM tj;
      SELECT id, JSON_OBJECT('k', c),  JSON_VALID(JSON_OBJECT('k', c))  FROM tj;
      SELECT JSON_ARRAYAGG(c),         JSON_VALID(JSON_ARRAYAGG(c))     FROM tj;
      SELECT JSON_OBJECTAGG(id, c),    JSON_VALID(JSON_OBJECTAGG(id,c)) FROM tj;
      DROP TABLE tj;

      JSON_ARRAY(c)         [{"a":1 "b":2}]                  0 ;  [[1,2]         0
      JSON_OBJECT('k',c)    {"k": {"a":1 "b":2}}             0 ;  {"k": [1,2}    0
      JSON_ARRAYAGG(c)      [{"a":1 "b":2},[1,2]             0
      JSON_OBJECTAGG(id,c)  {"1":{"a":1 "b":2}, "2":[1,2}    0

      Root cause

      A JSON-typed argument is spliced into the composed result without being
      read, on the reasoning that a JSON column holds a document. Where it
      does not - which needs check_constraint_checks to have been off when the
      row was written, or a column mistyped as JSON - nothing reads it on the
      way out either.

      Contract, `scripts/fill_help_tables.sql:429` (topic 355): *"Returns a
      JSON array containing the listed values."* And `:451` (topic 377):
      "Returns a JSON object containing the given key/value pairs." A
      string with unbalanced brackets is neither.

      Why it matters

      The result is handed on as a document. Anything that splices it again
      compounds the imbalance, and the row that caused it is not named.

      Affected versions

      JSON_ARRAY and JSON_OBJECT were added in 10.2.3, the two
      aggregates in 10.5.0.

      Verified on 10.11 only (10.11.19-MariaDB-debug, commit 1dab253482d).
      Other branches were not tested.

      Note

      Found while auditing the JSON functions against their documented
      contracts. Pinned as the deviation rather than the contract:
      func_json_embed.test:56-61 records the spliced result with JSON_VALID
      = 0. No test asserts an error or a NULL.

      Attachments

        Issue Links

          Activity

            People

              Unassigned Unassigned
              arcivanov Arcadiy Ivanov
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

                Created:
                Updated:

                Git Integration

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