[MDEV-31294] JSON functions act differently depending on CHECK constraint Created: 2023-05-16  Updated: 2023-06-19  Resolved: 2023-06-19

Status: Closed
Project: MariaDB Server
Component/s: JSON
Affects Version/s: 10.6.12
Fix Version/s: N/A

Type: Bug Priority: Major
Reporter: Robert Humphries Assignee: Sergei Golubchik
Resolution: Won't Fix Votes: 0
Labels: None


 Description   

If you create a table using the JSON data-type, it actually creates a LONGTEXT with a CHECK constraint to ensure only valid JSON is entered (https://mariadb.com/kb/en/json-data-type/).

Although I don't believe it is documented anyway, If the CHECK constraint is left exactly as is, JSON functions (at least JSON_OBJECT & JSON_ARRAY) treat the contents of the string as JSON (you don't need to use a function like JSON_COMPACT to stop it being escaped. However if the CHECK constraint is changed in any way (including being made more specific), this breaks.

Example:

CREATE OR REPLACE TABLE `jsonTest`(
  `s` JSON,
  `s2` LONGTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_bin CHECK(JSON_VALID(`s2`) AND JSON_TYPE(`s2`) = "object")
);
INSERT INTO `jsonTest` VALUES('{"x":"y"}', '{"x":"y"}');
SELECT JSON_PRETTY(JSON_OBJECT('a', `s`, 'b', `s2`, 'c', JSON_COMPACT(`s2`))) FROM `jsonTest`;
/* JSON_PRETTY for ease of output only. The SELECT produces:
{
    "a": 
    {
        "x": "y"
    },
    "b": "{\"x\":\"y\"}",
    "c": 
    {
        "x": "y"
    }
}
*/
/*

Not needing to manually use JSON_COMPACT is great, however if you have code that is expecting an escaped string when selecting the column, this causes significant confusion (in my case I had added a new column and not changed the constraint; and then existing code using the new column broke. Ideally the JSON data type would be a true data type, or if not possible then I feel the behaviour with JSON_VALID in the constraint should be consistent.



 Comments   
Comment by Sergei Golubchik [ 2023-06-19 ]

This is not exactly a bug, that is, not a mistake in the code. This is how JSON detection is done, because SQL Standard 2016 postulated that

NOTE 116 — There is no SQL <data type> whose value space is SQL/JSON items or SQL/JSON sequences.

But in the newest SQL Standard 2023 there is JSON as a distinct data type. I believe this is what we'll eventually do, it makes a lot of things much simpler. It'll fix this problem you've reported too, as a side effect. Meanwhile I'll close it as Won't fix — we should get a proper JSON data type, not smarter parsing of CHECK constraints.

Generated at Thu Feb 08 10:22:45 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.