Details
-
Bug
-
Status: Open (View Workflow)
-
Major
-
Resolution: Unresolved
-
10.11, 11.4, 11.8, 12.3, 13.0
-
None
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
- split from
-
MDEV-40642 Project "JSON Phoenix" (placeholder)
-
- Open
-