MySQL – JSON Functions Adding Double Quotes Through Variable

jsonmariadbmariadb-10.2MySQL

Im stuck with what it seems simple question, when I create a JSON using the MariaDB/MySQL json functions going through variables, it adds double quotes which is annoying. However, if I don't go through variables, it works fine. Unfortunately I have to go through variables as I'm building my JSON using a recursive function:

  1. without variables:

    declare temp_json JSON;
    set temp_json = json_object('data',json_object("jsonapi",json_object("version", "1.0")));
    select temp_json
    

    OUTPUT

    {"data": {"jsonapi": {"version": "1.0"}}}
    
  2. with variables

    declare temp_json JSON;
    declare jsonapiheader JSON;
    set jsonapiheader = json_object("jsonapi",json_object("version", "1.0"));
    set temp_json = json_object('data',jsonapiheader);
    select temp_json
    

    OUTPUT

    {"data": "{\"jsonapi\": {\"version\": \"1.0\"}}"}` 
    

So how do I do like 2) but with the output of 1) ?

my system:
MariaDB 10.2.9

Best Answer

First, generally speaking, there are two types of JSON,

  1. JSON-validated text.
  2. Binary JSON (Mongo calls it BSON, PostgreSQL calls it JSONB, also Apache Avro).

For reference MariaDB has neither of these. It has a JSON type, but that type is nothing more than un-validated text, from the docs

JSON is an alias for LONGTEXT introduced for compatibility reasons with MySQL's JSON data type. MariaDB implements this as a LONGTEXT rather, as the JSON data type contradicts the SQL standard, and MariaDB's benchmarks indicate that performance is at least equivalent.

If you need a validated column, you need to use a CHECK constraint. So essentially, internally all the functions that "do JSON", essentially read text process it internally and output text.

So the problem you're running into is that json_object doesn't know that the value is JSON-text. There isn't an easy around that. The only option from a MariaDB's perspective is to implement each function as accepting a value, and another one as accepting a jdoc, or doing it right and implementing a real type for JSON.

As a side note, there is one function that does accept two jdocs, one to operate on, and one as an argument. That function is JSON_MERGE.

See also,

I would highly suggest migrating to PostgreSQL if it's not too late. Not just do you get a binary JSON type but you get a rich library of functions, and operators, and indexes for that type.