You are right, "no performance difference" has nothing to do with this issue. And we never said that we didn't create JSON type because there was "no performance difference". The internal representation is plain text because there was no performance difference, but I agree, internal representation is internal.
The reason why we don't have a true JSON data type is because SQL Standard explicitly forbids it. In the Part 2 "Foundation" of SQL:2016, in the Section 4.46 "JSON data handling in SQL" it says unambiguously:
NOTE 116 — There is no SQL <data type> whose value space is SQL/JSON items or SQL/JSON sequences.
Note that Oracle, DB2, and SQL Server follow the standard here. For example, here's the manual for the JSON_QUERY function:
Oracle:
For expr, specify an expression that evaluates to a text literal. If expr is a column, then the column must be of data type VARCHAR2, CLOB, or BLOB. If expr is not a text literal of well-formed JSON data using strict or lax syntax, then the function returns null by default.
DB2:
An expression that returns a value that is a built-in string data type. If a character or graphic value is returned, it must contain correctly formatted JSON data.
SQLServer:
An expression. Typically the name of a variable or a column that contains JSON text. If JSON_QUERY finds JSON that is not valid in expression before it finds the value identified by path, the function returns an error.
SQL Server manual doesn't say it must be a text literal, but, like others, it says what happens when the expression is not a valid JSON, which implies it's a text literal, and not a specialized type
So, we've made a conscious decision to follow the SQL Standard (like Oracle, DB2, SQL Server, and others).
But at the moment not everything from the SQL Standard is implemented yet. The Standard specifies that one can optionally specify FORMAT JSON after the value, to specify that it is JSON, not an arbitrary text. In your example it would've been json_object('name',json_column FORMAT JSON) vs json_object('name', longtext_column).
We did not implement it yet, but exactly the same functionality can be achieved with our JSON formatting functions. Compare:
MariaDB [test]> select json_object('foo', '{"bar": 5}') as_text;
|
+-------------------------+
|
| as_text |
|
+-------------------------+
|
| {"foo": "{\"bar\": 5}"} |
|
+-------------------------+
|
1 row in set (0.001 sec)
|
|
MariaDB [test]> select json_object('foo',json_compact('{"bar": 5}')) as_json;
|
+---------------------+
|
| as_json |
|
+---------------------+
|
| {"foo": {"bar": 5}} |
|
+---------------------+
|
1 row in set (0.001 sec)
|
You are right, "no performance difference" has nothing to do with this issue. And we never said that we didn't create JSON type because there was "no performance difference". The internal representation is plain text because there was no performance difference, but I agree, internal representation is internal.
The reason why we don't have a true JSON data type is because SQL Standard explicitly forbids it. In the Part 2 "Foundation" of SQL:2016, in the Section 4.46 "JSON data handling in SQL" it says unambiguously:
Note that Oracle, DB2, and SQL Server follow the standard here. For example, here's the manual for the JSON_QUERY function:
Oracle:
DB2:
SQLServer:
SQL Server manual doesn't say it must be a text literal, but, like others, it says what happens when the expression is not a valid JSON, which implies it's a text literal, and not a specialized type
So, we've made a conscious decision to follow the SQL Standard (like Oracle, DB2, SQL Server, and others).
But at the moment not everything from the SQL Standard is implemented yet. The Standard specifies that one can optionally specify FORMAT JSON after the value, to specify that it is JSON, not an arbitrary text. In your example it would've been json_object('name',json_column FORMAT JSON) vs json_object('name', longtext_column).
We did not implement it yet, but exactly the same functionality can be achieved with our JSON formatting functions. Compare:
MariaDB [test]> select json_object('foo', '{"bar": 5}') as_text;
+-------------------------+
| as_text |
+-------------------------+
| {"foo": "{\"bar\": 5}"} |
+-------------------------+
1 row in set (0.001 sec)
MariaDB [test]> select json_object('foo',json_compact('{"bar": 5}')) as_json;
+---------------------+
| as_json |
+---------------------+
| {"foo": {"bar": 5}} |
+---------------------+
1 row in set (0.001 sec)