Details
-
Task
-
Status: Open (View Workflow)
-
Major
-
Resolution: Unresolved
-
None
Description
There are some problems with the way general json functions are implemented that impact their performance.
Problems
Problem 1: JSON functions with JSON inputs
These function take args[x]->val_str(), construct an json_engine and process.
Functions using val_json() are the same as there is only one implementation:
Item::val_json(String *str) { return val_str(str); } |
If the argument was another json function, like:
SELECT JSON_OBJECT_FILTER_KEYS (@obj1, JSON_ARRAY_INTERSECT(JSON_KEYS(@obj1), JSON_KEYS(@obj2))) |
...any parsing within the inner function gets lost as it returns a string, and the next function re-parses it.
In many ways the the json_engine_t implementation includes similar boilerplate around kill_ptr and error reporting that could be have added consistency.
Problem 2: Complete parsing of JSON document inputs is not always required
In many cases this is already done in the val_xxx function. Some cases like JSON_EQUALS in MDEV-40180 can quickly answer false if and inequality if found early.
Others include:
- JSON_ARRAY_INTERSECT
- JSON_CONTAINS
- JSON_CONTAINS_PATH
- JSON_EXISTS
- JSON_EXTRACT
- JSON_KEY_VALUE

- JSON_LENGTH
- JSON_OBJECT_FILTER_KEYS
- JSON_OVERLAPS
- JSON_QUERY
- JSON_SEARCH
- JSON_TABLE
- JSON_TYPE
- JSON_VALUE
- IS JSON
Note some the processing of a result may occur early, but will need to make sure the result of the input is valid before returning that result (or NULL if invalid).
Problem 3: chained json function
Once functions are chained, there's often no need to have a fully parsed JSON document for the outer json function, so memory can be reduced. With exposed iteration functions used by json functions the amount of memory can be reduced.
When ::val_str is used there is a copy of the document
.
Problem 4: JSON functions with JSON outputs
Like above, the structured output is a bunch of string appends, which get reparsed if this functions output is passed to another Json_function
Solution
json_interator
A json iterator class that forms as a wrapper of similar exposed methods of json_engine_t is introduced. There will be a method that totally wraps the json_engine_t. This is a forwards only parsing and any state that need to preserved will be cached by the JSON Item class.
Additions methods:
- json_normalize_next would seem useful as an addition for a number of json functions.
- is_valid - though some functions can have a result early in their iteration, many still require that the rest of the input is valid before returning. This can be called at any time in the processing as the last and final step on the iterator only.
Top Item::val_json_interator
This returns a json_interator object based on the val_str() allowing JSON functions to just use this iterator rather than val_str()) or val_json() directly.
Some non-JSON functions in hierarchy without a val_str()) could also implement val_json_interator as a quick no-op.
Incrementally replace Item_json_function_xxx::val_xxx() that take json arguments to use val_json_iterator
These functions where already iterating over their input args[x]->val_str() in some way so a similar pattern is used. They just need to use the json_interator class instead of json_engine_t but used interfaces should be roughly 1:1.
json output functions replace their val_str() function with a val_json_interator function
This will likely be a stateful helper class of the used by the Item implementing similar mechanisms to json_engine.
Once val_str is replaced, there need to be a val_str at this Item level to make it clear that the str return is based on val_json_iterator rather than the top level item that maps its implementation other way. Except for JSON beautification this is likely to be a simple method of iterating over this->val_json_iterator and appending to string.
val_str would also be implemented for json beautification functions (json_nice, json_detailed)). These beautifications could have a passthrough val_json_iterator so that when called in silly ways like JSON_ARRAY_APPEND(JSON_DETAILED(@json_doc1), @jsoc_doc2) there is no wasted processing on formatting.
Field_json_XXX class functions can implement val_json_iterator
MDEV-38740. And probably consume the val_json_iterator of other Items too.
Attachments
Issue Links
- relates to
-
MDEV-38740 Implement a distinct data type for JSON
-
- Open
-
-
MDEV-40180 json_equals / json_overlaps (compare_nested_object) inefficient
-
- Open
-