diff options
author | Alexey Botchkov <holyfoot@askmonty.org> | 2017-01-26 16:35:05 +0400 |
---|---|---|
committer | Alexey Botchkov <holyfoot@askmonty.org> | 2017-01-26 16:35:05 +0400 |
commit | d96ee168a1f87c090421fb593930515ae8db3d7f (patch) | |
tree | 7eb78889644c1bc4eb32ab4274a0840a1622cfd4 /strings/json_lib.c | |
parent | 71495a1748784a887f42888a2a7b8cac5e088ff6 (diff) | |
download | mariadb-git-d96ee168a1f87c090421fb593930515ae8db3d7f.tar.gz |
MDEV-11557 port MySQL-5.7 JSON tests to MariaDB.
paths ending on [0]..[0] should be handled in conforming manner.
Diffstat (limited to 'strings/json_lib.c')
-rw-r--r-- | strings/json_lib.c | 43 |
1 files changed, 37 insertions, 6 deletions
diff --git a/strings/json_lib.c b/strings/json_lib.c index 66b075a997b..18bdce2613f 100644 --- a/strings/json_lib.c +++ b/strings/json_lib.c @@ -1187,6 +1187,8 @@ int json_skip_key(json_engine_t *j) } +#define SKIPPED_STEP_MARK ((uint) ~0) + /* Current step of the patch matches the JSON construction. Now we should either stop the search or go to the next @@ -1195,24 +1197,48 @@ int json_skip_key(json_engine_t *j) static int handle_match(json_engine_t *je, json_path_t *p, json_path_step_t **p_cur_step, uint *array_counters) { + json_path_step_t *next_step= *p_cur_step + 1; + DBUG_ASSERT(*p_cur_step < p->last_step); if (json_read_value(je)) return 1; if (json_value_scalar(je)) + { + while (next_step->type == JSON_PATH_ARRAY && next_step->n_item == 0) + { + if (++next_step > p->last_step) + { + je->s.c_str= je->value_begin; + return 1; + } + } return 0; + } + + if (next_step->type == JSON_PATH_ARRAY && next_step->n_item == 0 && + je->value_type & JSON_VALUE_OBJECT) + { + do + { + array_counters[next_step - p->steps]= SKIPPED_STEP_MARK; + if (++next_step > p->last_step) + { + je->s.c_str= je->value_begin; + return 1; + } + } while (next_step->type == JSON_PATH_ARRAY && next_step->n_item == 0); + } - (*p_cur_step)++; - array_counters[*p_cur_step - p->steps]= 0; + + array_counters[next_step - p->steps]= 0; if ((int) je->value_type != - (int) ((*p_cur_step)->type & JSON_PATH_KEY_OR_ARRAY)) - { - (*p_cur_step)--; + (int) (next_step->type & JSON_PATH_KEY_OR_ARRAY)) return json_skip_level(je); - } + *p_cur_step= next_step; return 0; } @@ -1277,6 +1303,11 @@ int json_find_path(json_engine_t *je, json_skip_array_item(je); break; case JST_OBJ_END: + do + { + (*p_cur_step)--; + } while (array_counters[(*p_cur_step) - p->steps] == SKIPPED_STEP_MARK); + break; case JST_ARRAY_END: (*p_cur_step)--; break; |