MDEV-22224: Support JSON Path negative index

This patch can be viewed as combination of two parts:
1) Enabling '-' in the path so that the parser does not give out a warning.
2) Setting the negative index to a correct value and returning the
   appropriate value.

1) To enable using the negative index in the path:
To make the parser not return warning when negative index is used in path
'-' needs to be allowed in json path characters. P_NEG is added
to enable this and is made recognizable by setting the 45th index of
json_path_chr_map[] to P_NEG (instead of previous P_ETC)
because 45 corresponds to '-' in unicode.
When the path is being parsed and '-' is encountered, the parser should
recognize it as parsing '-' sign, so a new json state PS_NEG is required.
When the state is PS_NEG, it means that a negative integer is
going to be parsed so set is_negative_index of current step to 1 and
n_item is set accordingly when integer is encountered after '-'.
Next proceed with parsing rest of the path and get the correct path.
Next thing is parsing the json and returning correct value.

2) Setting the negative index to a correct value and returning the value:
While parsing json if we encounter array and the path step for the array
is a negative index (n_item < 0), then we can count the number of elements
in the array and set n_item to correct corresponding value. This is done in
json_skip_array_and_count.
This commit is contained in:
Rucha Deodhar
2021-11-22 22:59:30 +05:30
parent e98013cb5c
commit dfcbb30a92
7 changed files with 682 additions and 76 deletions

View File

@ -312,7 +312,8 @@ handle_new_nested:
while (!json_get_path_next(&m_engine, &m_cur_path))
{
if (json_path_compare(&m_path, &m_cur_path, m_engine.value_type))
if (json_path_compare(&m_path, &m_cur_path, m_engine.value_type,
NULL))
continue;
/* path found. */
++m_ordinality_counter;
@ -501,7 +502,7 @@ int ha_json_table::fill_column_values(THD *thd, uchar * buf, uchar *pos)
{
json_engine_t je;
json_path_step_t *cur_step;
uint array_counters[JSON_DEPTH_LIMIT];
int array_counters[JSON_DEPTH_LIMIT];
int not_found;
const uchar* node_start;
const uchar* node_end;