summaryrefslogtreecommitdiff
path: root/strings/json_lib.c
diff options
context:
space:
mode:
authorAlexey Botchkov <holyfoot@askmonty.org>2017-01-26 16:35:05 +0400
committerAlexey Botchkov <holyfoot@askmonty.org>2017-01-26 16:35:05 +0400
commitd96ee168a1f87c090421fb593930515ae8db3d7f (patch)
tree7eb78889644c1bc4eb32ab4274a0840a1622cfd4 /strings/json_lib.c
parent71495a1748784a887f42888a2a7b8cac5e088ff6 (diff)
downloadmariadb-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.c43
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;