1
0
mirror of https://github.com/MariaDB/server.git synced 2026-10-23 18:49:29 +03:00

MDEV-40174 Remove unnecessary double parsing JSON document in json_normalize

`json_normalize`/`json_equals` unnecessary
double parsing JSON document

Removed the redundant `json_valid_engine` pre-check to eliminate
double-parsing, and integrated error handling directly into the
normalization engine:

* Catch Empty Strings: Return an error directly in
  `json_normalize_engine` if the root type is `JSON_VALUE_UNINITIALIZED`.

* Catch Trailing Garbage on Scalars: Updated `json_norm_build`
  to enforce a full scan to the end of the document for scalar values.
  This prevents edge cases (e.g., raw date strings like 2026-07-17...)
  from being falsely accepted as a valid JSON number without checking
  the remainder of the string for syntax errors.

* Propagate Syntax Errors: Updated `json_normalize_engine` to
  explicitly check the engine's error flag after the build phase.

* Add Edge Case Tests: Added tests in `json_normalize.test` for
  empty strings, whitespace, and trailing garbage on scalars to
  ensure correct error generation.

Testing:
Verified locally using MTR
(`main.json_normalize` and `main.json_equals`).

Signed-off-by: VasuBhakt <cpswastik31@gmail.com>
This commit is contained in:
VasuBhakt
2026-07-17 17:13:07 +00:00
committed by Daniel Black
parent 23367c88cd
commit a9094a6ec1
3 changed files with 25 additions and 8 deletions

View File

@@ -45,6 +45,21 @@ json_normalize('{ "invalid": "no_close"')
NULL
Warnings:
Warning 4037 Unexpected end of JSON text in argument 1 to function 'json_normalize'
select json_normalize('');
json_normalize('')
NULL
Warnings:
Warning 4037 Unexpected end of JSON text in argument 1 to function 'json_normalize'
select json_normalize(' ');
json_normalize(' ')
NULL
Warnings:
Warning 4037 Unexpected end of JSON text in argument 1 to function 'json_normalize'
select json_normalize('123 garbage');
json_normalize('123 garbage')
NULL
Warnings:
Warning 4038 Syntax error in JSON text in argument 1 to function 'json_normalize' at position 5
drop table t1;
drop view v1;
create table t1 (text varchar(200) character set 'latin1');

View File

@@ -25,6 +25,9 @@ order by json;
select json_normalize(NULL);
select json_normalize('{ "invalid": "no_close"');
select json_normalize('');
select json_normalize(' ');
select json_normalize('123 garbage');
drop table t1;
drop view v1;

View File

@@ -829,7 +829,7 @@ json_norm_parse(struct json_norm_value *root, json_engine_t *je)
json_norm_parse_end:
dynstr_free(&key);
return err;
return err || je->s.error;
}
@@ -860,6 +860,10 @@ json_norm_build(json_engine_t *je, struct json_norm_value *root,
if (err)
return err;
}
else
{
while(json_scan_next(je) == 0) /*no-op*/;
}
return err;
}
@@ -908,14 +912,9 @@ json_normalize_engine(json_engine_t *je, DYNAMIC_STRING *result,
in_size= strlen(s_utf8);
}
if (!json_valid_engine(je, in, in_size, &my_charset_utf8mb4_bin))
{
err= 1;
goto json_normalize_end;
}
err= json_norm_build(je, &root, in, in_size, &my_charset_utf8mb4_bin);
if (root.type == JSON_VALUE_UNINITIALIZED || je->s.error)
err= 1;
if (err)
goto json_normalize_end;