1 /* Copyright (c) 2016, Monty Program Ab.
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; version 2 of the License.
6
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
11
12 You should have received a copy of the GNU General Public License
13 along with this program; if not, write to the Free Software
14 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
15
16
17 #include "mariadb.h"
18 #include "sql_priv.h"
19 #include "sql_class.h"
20 #include "item.h"
21
22
23 /*
24 Compare ASCII string against the string with the specified
25 character set.
26 Only compares the equality, case insencitive.
27 */
eq_ascii_string(const CHARSET_INFO * cs,const char * ascii,const char * s,uint32 s_len)28 static bool eq_ascii_string(const CHARSET_INFO *cs,
29 const char *ascii,
30 const char *s, uint32 s_len)
31 {
32 const char *s_end= s + s_len;
33
34 while (*ascii && s < s_end)
35 {
36 my_wc_t wc;
37 int wc_len;
38
39 wc_len= cs->cset->mb_wc(cs, &wc, (uchar *) s, (uchar *) s_end);
40 if (wc_len <= 0 || (wc | 0x20) != (my_wc_t) *ascii)
41 return 0;
42
43 ascii++;
44 s+= wc_len;
45 }
46
47 return *ascii == 0 && s >= s_end;
48 }
49
50
append_simple(String * s,const char * a,size_t a_len)51 static bool append_simple(String *s, const char *a, size_t a_len)
52 {
53 if (!s->realloc_with_extra_if_needed(s->length() + a_len))
54 {
55 s->q_append(a, a_len);
56 return FALSE;
57 }
58
59 return TRUE;
60 }
61
62
append_simple(String * s,const uchar * a,size_t a_len)63 static inline bool append_simple(String *s, const uchar *a, size_t a_len)
64 {
65 return append_simple(s, (const char *) a, a_len);
66 }
67
68
69 /*
70 Appends JSON string to the String object taking charsets in
71 consideration.
72 */
st_append_json(String * s,CHARSET_INFO * json_cs,const uchar * js,uint js_len)73 static int st_append_json(String *s,
74 CHARSET_INFO *json_cs, const uchar *js, uint js_len)
75 {
76 int str_len= js_len * s->charset()->mbmaxlen;
77
78 if (!s->reserve(str_len, 1024) &&
79 (str_len= json_unescape(json_cs, js, js + js_len,
80 s->charset(), (uchar *) s->end(), (uchar *) s->end() + str_len)) > 0)
81 {
82 s->length(s->length() + str_len);
83 return 0;
84 }
85
86 return str_len;
87 }
88
89
90 /*
91 Appends arbitrary String to the JSON string taking charsets in
92 consideration.
93 */
st_append_escaped(String * s,const String * a)94 static int st_append_escaped(String *s, const String *a)
95 {
96 /*
97 In the worst case one character from the 'a' string
98 turns into '\uXXXX\uXXXX' which is 12.
99 */
100 int str_len= a->length() * 12 * s->charset()->mbmaxlen /
101 a->charset()->mbminlen;
102 if (!s->reserve(str_len, 1024) &&
103 (str_len=
104 json_escape(a->charset(), (uchar *) a->ptr(), (uchar *)a->end(),
105 s->charset(),
106 (uchar *) s->end(), (uchar *)s->end() + str_len)) > 0)
107 {
108 s->length(s->length() + str_len);
109 return 0;
110 }
111
112 return a->length();
113 }
114
115
116 static const int TAB_SIZE_LIMIT= 8;
117 static const char tab_arr[TAB_SIZE_LIMIT+1]= " ";
118
append_tab(String * js,int depth,int tab_size)119 static int append_tab(String *js, int depth, int tab_size)
120 {
121 if (js->append("\n", 1))
122 return 1;
123 for (int i=0; i<depth; i++)
124 {
125 if (js->append(tab_arr, tab_size))
126 return 1;
127 }
128 return 0;
129 }
130
131
json_nice(json_engine_t * je,String * nice_js,Item_func_json_format::formats mode,int tab_size=4)132 static int json_nice(json_engine_t *je, String *nice_js,
133 Item_func_json_format::formats mode, int tab_size=4)
134 {
135 int depth= 0;
136 const char *comma, *colon;
137 uint comma_len, colon_len;
138 int first_value= 1;
139
140 DBUG_ASSERT(je->s.cs == nice_js->charset());
141 DBUG_ASSERT(mode != Item_func_json_format::DETAILED ||
142 (tab_size >= 0 && tab_size <= TAB_SIZE_LIMIT));
143
144 comma= ", ";
145 colon= "\": ";
146 if (mode == Item_func_json_format::LOOSE)
147 {
148 comma_len= 2;
149 colon_len= 3;
150 }
151 else if (mode == Item_func_json_format::DETAILED)
152 {
153 comma_len= 1;
154 colon_len= 3;
155 }
156 else
157 {
158 comma_len= 1;
159 colon_len= 2;
160 }
161
162 do
163 {
164 switch (je->state)
165 {
166 case JST_KEY:
167 {
168 const uchar *key_start= je->s.c_str;
169 const uchar *key_end;
170
171 do
172 {
173 key_end= je->s.c_str;
174 } while (json_read_keyname_chr(je) == 0);
175
176 if (unlikely(je->s.error))
177 goto error;
178
179 if (!first_value)
180 nice_js->append(comma, comma_len);
181
182 if (mode == Item_func_json_format::DETAILED &&
183 append_tab(nice_js, depth, tab_size))
184 goto error;
185
186 nice_js->append("\"", 1);
187 append_simple(nice_js, key_start, key_end - key_start);
188 nice_js->append(colon, colon_len);
189 }
190 /* now we have key value to handle, so no 'break'. */
191 DBUG_ASSERT(je->state == JST_VALUE);
192 goto handle_value;
193
194 case JST_VALUE:
195 if (!first_value)
196 nice_js->append(comma, comma_len);
197
198 if (mode == Item_func_json_format::DETAILED &&
199 depth > 0 &&
200 append_tab(nice_js, depth, tab_size))
201 goto error;
202
203 handle_value:
204 if (json_read_value(je))
205 goto error;
206 if (json_value_scalar(je))
207 {
208 if (append_simple(nice_js, je->value_begin,
209 je->value_end - je->value_begin))
210 goto error;
211
212 first_value= 0;
213 }
214 else
215 {
216 if (mode == Item_func_json_format::DETAILED &&
217 depth > 0 &&
218 append_tab(nice_js, depth, tab_size))
219 goto error;
220 nice_js->append((je->value_type == JSON_VALUE_OBJECT) ? "{" : "[", 1);
221 first_value= 1;
222 depth++;
223 }
224
225 break;
226
227 case JST_OBJ_END:
228 case JST_ARRAY_END:
229 depth--;
230 if (mode == Item_func_json_format::DETAILED &&
231 append_tab(nice_js, depth, tab_size))
232 goto error;
233 nice_js->append((je->state == JST_OBJ_END) ? "}": "]", 1);
234 first_value= 0;
235 break;
236
237 default:
238 break;
239 };
240 } while (json_scan_next(je) == 0);
241
242 return je->s.error;
243
244 error:
245 return 1;
246 }
247
248
249 #define report_json_error(js, je, n_param) \
250 report_json_error_ex(js, je, func_name(), n_param, \
251 Sql_condition::WARN_LEVEL_WARN)
252
report_json_error_ex(String * js,json_engine_t * je,const char * fname,int n_param,Sql_condition::enum_warning_level lv)253 void report_json_error_ex(String *js, json_engine_t *je,
254 const char *fname, int n_param,
255 Sql_condition::enum_warning_level lv)
256 {
257 THD *thd= current_thd;
258 int position= (int)((const char *) je->s.c_str - js->ptr());
259 uint code;
260
261 n_param++;
262
263 switch (je->s.error)
264 {
265 case JE_BAD_CHR:
266 code= ER_JSON_BAD_CHR;
267 break;
268
269 case JE_NOT_JSON_CHR:
270 code= ER_JSON_NOT_JSON_CHR;
271 break;
272
273 case JE_EOS:
274 code= ER_JSON_EOS;
275 break;
276
277 case JE_SYN:
278 case JE_STRING_CONST:
279 code= ER_JSON_SYNTAX;
280 break;
281
282 case JE_ESCAPING:
283 code= ER_JSON_ESCAPING;
284 break;
285
286 case JE_DEPTH:
287 code= ER_JSON_DEPTH;
288 push_warning_printf(thd, lv, code, ER_THD(thd, code), JSON_DEPTH_LIMIT,
289 n_param, fname, position);
290 return;
291
292 default:
293 return;
294 }
295
296 push_warning_printf(thd, lv, code, ER_THD(thd, code),
297 n_param, fname, position);
298 }
299
300
301
302 #define NO_WILDCARD_ALLOWED 1
303 #define SHOULD_END_WITH_ARRAY 2
304 #define TRIVIAL_PATH_NOT_ALLOWED 3
305
306 #define report_path_error(js, je, n_param) \
307 report_path_error_ex(js, je, func_name(), n_param,\
308 Sql_condition::WARN_LEVEL_WARN)
309
report_path_error_ex(String * ps,json_path_t * p,const char * fname,int n_param,Sql_condition::enum_warning_level lv)310 static void report_path_error_ex(String *ps, json_path_t *p,
311 const char *fname, int n_param,
312 Sql_condition::enum_warning_level lv)
313 {
314 THD *thd= current_thd;
315 int position= (int)((const char *) p->s.c_str - ps->ptr() + 1);
316 uint code;
317
318 n_param++;
319
320 switch (p->s.error)
321 {
322 case JE_BAD_CHR:
323 case JE_NOT_JSON_CHR:
324 case JE_SYN:
325 code= ER_JSON_PATH_SYNTAX;
326 break;
327
328 case JE_EOS:
329 code= ER_JSON_PATH_EOS;
330 break;
331
332 case JE_DEPTH:
333 code= ER_JSON_PATH_DEPTH;
334 push_warning_printf(thd, lv, code, ER_THD(thd, code),
335 JSON_DEPTH_LIMIT, n_param, fname, position);
336 return;
337
338 case NO_WILDCARD_ALLOWED:
339 code= ER_JSON_PATH_NO_WILDCARD;
340 break;
341
342 case TRIVIAL_PATH_NOT_ALLOWED:
343 code= ER_JSON_PATH_EMPTY;
344 break;
345
346
347 default:
348 return;
349 }
350 push_warning_printf(thd, lv, code, ER_THD(thd, code),
351 n_param, fname, position);
352 }
353
354
355
356 /*
357 Checks if the path has '.*' '[*]' or '**' constructions
358 and sets the NO_WILDCARD_ALLOWED error if the case.
359 */
path_setup_nwc(json_path_t * p,CHARSET_INFO * i_cs,const uchar * str,const uchar * end)360 static int path_setup_nwc(json_path_t *p, CHARSET_INFO *i_cs,
361 const uchar *str, const uchar *end)
362 {
363 if (!json_path_setup(p, i_cs, str, end))
364 {
365 if ((p->types_used & (JSON_PATH_WILD | JSON_PATH_DOUBLE_WILD)) == 0)
366 return 0;
367 p->s.error= NO_WILDCARD_ALLOWED;
368 }
369
370 return 1;
371 }
372
373
val_int()374 longlong Item_func_json_valid::val_int()
375 {
376 String *js= args[0]->val_json(&tmp_value);
377 json_engine_t je;
378
379 if ((null_value= args[0]->null_value))
380 return 0;
381
382 json_scan_start(&je, js->charset(), (const uchar *) js->ptr(),
383 (const uchar *) js->ptr()+js->length());
384
385 while (json_scan_next(&je) == 0) {}
386
387 return je.s.error == 0;
388 }
389
390
fix_length_and_dec()391 bool Item_func_json_exists::fix_length_and_dec()
392 {
393 if (Item_bool_func::fix_length_and_dec())
394 return TRUE;
395 maybe_null= 1;
396 path.set_constant_flag(args[1]->const_item());
397 return FALSE;
398 }
399
400
val_int()401 longlong Item_func_json_exists::val_int()
402 {
403 json_engine_t je;
404 uint array_counters[JSON_DEPTH_LIMIT];
405
406 String *js= args[0]->val_json(&tmp_js);
407
408 if (!path.parsed)
409 {
410 String *s_p= args[1]->val_str(&tmp_path);
411 if (s_p &&
412 json_path_setup(&path.p, s_p->charset(), (const uchar *) s_p->ptr(),
413 (const uchar *) s_p->ptr() + s_p->length()))
414 goto err_return;
415 path.parsed= path.constant;
416 }
417
418 if ((null_value= args[0]->null_value || args[1]->null_value))
419 {
420 null_value= 1;
421 return 0;
422 }
423
424 null_value= 0;
425 json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
426 (const uchar *) js->ptr() + js->length());
427
428 path.cur_step= path.p.steps;
429 if (json_find_path(&je, &path.p, &path.cur_step, array_counters))
430 {
431 if (je.s.error)
432 goto err_return;
433 return 0;
434 }
435
436 return 1;
437
438 err_return:
439 null_value= 1;
440 return 0;
441 }
442
443
fix_length_and_dec()444 bool Item_func_json_value::fix_length_and_dec()
445 {
446 collation.set(args[0]->collation);
447 max_length= args[0]->max_length;
448 path.set_constant_flag(args[1]->const_item());
449 maybe_null= 1;
450 return FALSE;
451 }
452
453
454 /*
455 Returns NULL, not an error if the found value
456 is not a scalar.
457 */
val_str(String * str)458 String *Item_func_json_value::val_str(String *str)
459 {
460 json_engine_t je;
461 String *js= args[0]->val_json(&tmp_js);
462 int error= 0;
463 uint array_counters[JSON_DEPTH_LIMIT];
464
465 if (!path.parsed)
466 {
467 String *s_p= args[1]->val_str(&tmp_path);
468 if (s_p &&
469 json_path_setup(&path.p, s_p->charset(), (const uchar *) s_p->ptr(),
470 (const uchar *) s_p->ptr() + s_p->length()))
471 goto err_return;
472 path.parsed= path.constant;
473 }
474
475 if ((null_value= args[0]->null_value || args[1]->null_value))
476 return NULL;
477
478 json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
479 (const uchar *) js->ptr() + js->length());
480
481 str->length(0);
482 str->set_charset(collation.collation);
483
484 path.cur_step= path.p.steps;
485 continue_search:
486 if (json_find_path(&je, &path.p, &path.cur_step, array_counters))
487 {
488 if (je.s.error)
489 goto err_return;
490
491 null_value= 1;
492 return 0;
493 }
494
495 if (json_read_value(&je))
496 goto err_return;
497
498 if (unlikely(check_and_get_value(&je, str, &error)))
499 {
500 if (error)
501 goto err_return;
502 goto continue_search;
503 }
504
505 return str;
506
507 err_return:
508 null_value= 1;
509 return 0;
510 }
511
512
check_and_get_value(json_engine_t * je,String * res,int * error)513 bool Item_func_json_value::check_and_get_value(json_engine_t *je, String *res,
514 int *error)
515 {
516 CHARSET_INFO *json_cs;
517 const uchar *js;
518 uint js_len;
519
520 if (!json_value_scalar(je))
521 {
522 /* We only look for scalar values! */
523 if (json_skip_level(je) || json_scan_next(je))
524 *error= 1;
525 return true;
526 }
527
528 if (je->value_type == JSON_VALUE_TRUE ||
529 je->value_type == JSON_VALUE_FALSE)
530 {
531 json_cs= &my_charset_utf8mb4_bin;
532 js= (const uchar *) ((je->value_type == JSON_VALUE_TRUE) ? "1" : "0");
533 js_len= 1;
534 }
535 else
536 {
537 json_cs= je->s.cs;
538 js= je->value;
539 js_len= je->value_len;
540 }
541
542
543 return st_append_json(res, json_cs, js, js_len);
544 }
545
546
check_and_get_value(json_engine_t * je,String * res,int * error)547 bool Item_func_json_query::check_and_get_value(json_engine_t *je, String *res,
548 int *error)
549 {
550 const uchar *value;
551 if (json_value_scalar(je))
552 {
553 /* We skip scalar values. */
554 if (json_scan_next(je))
555 *error= 1;
556 return true;
557 }
558
559 value= je->value;
560 if (json_skip_level(je))
561 {
562 *error= 1;
563 return true;
564 }
565
566 res->set((const char *) je->value, (uint32)(je->s.c_str - value), je->s.cs);
567 return false;
568 }
569
570
fix_length_and_dec()571 bool Item_func_json_quote::fix_length_and_dec()
572 {
573 collation.set(&my_charset_utf8mb4_bin);
574 /*
575 Odd but realistic worst case is when all characters
576 of the argument turn into '\uXXXX\uXXXX', which is 12.
577 */
578 fix_char_length_ulonglong((ulonglong) args[0]->max_char_length() * 12 + 2);
579 return FALSE;
580 }
581
582
val_str(String * str)583 String *Item_func_json_quote::val_str(String *str)
584 {
585 String *s= args[0]->val_str(&tmp_s);
586
587 if ((null_value= (args[0]->null_value ||
588 args[0]->result_type() != STRING_RESULT)))
589 return NULL;
590
591 str->length(0);
592 str->set_charset(&my_charset_utf8mb4_bin);
593
594 if (str->append("\"", 1) ||
595 st_append_escaped(str, s) ||
596 str->append("\"", 1))
597 {
598 /* Report an error. */
599 null_value= 1;
600 return 0;
601 }
602
603 return str;
604 }
605
606
fix_length_and_dec()607 bool Item_func_json_unquote::fix_length_and_dec()
608 {
609 collation.set(&my_charset_utf8_general_ci,
610 DERIVATION_COERCIBLE, MY_REPERTOIRE_ASCII);
611 max_length= args[0]->max_length;
612 maybe_null= 1;
613 return FALSE;
614 }
615
616
read_json(json_engine_t * je)617 String *Item_func_json_unquote::read_json(json_engine_t *je)
618 {
619 String *js= args[0]->val_json(&tmp_s);
620
621 if ((null_value= args[0]->null_value))
622 return 0;
623
624 json_scan_start(je, js->charset(),(const uchar *) js->ptr(),
625 (const uchar *) js->ptr() + js->length());
626
627 je->value_type= (enum json_value_types) -1; /* To report errors right. */
628
629 if (json_read_value(je))
630 goto error;
631
632 return js;
633
634 error:
635 if (je->value_type == JSON_VALUE_STRING)
636 report_json_error(js, je, 0);
637 return js;
638 }
639
640
val_str(String * str)641 String *Item_func_json_unquote::val_str(String *str)
642 {
643 json_engine_t je;
644 int c_len;
645 String *js;
646
647 if (!(js= read_json(&je)))
648 return NULL;
649
650 if (unlikely(je.s.error) || je.value_type != JSON_VALUE_STRING)
651 return js;
652
653 str->length(0);
654 str->set_charset(&my_charset_utf8_general_ci);
655
656 if (str->realloc_with_extra_if_needed(je.value_len) ||
657 (c_len= json_unescape(js->charset(),
658 je.value, je.value + je.value_len,
659 &my_charset_utf8_general_ci,
660 (uchar *) str->ptr(), (uchar *) (str->ptr() + je.value_len))) < 0)
661 goto error;
662
663 str->length(c_len);
664 return str;
665
666 error:
667 report_json_error(js, &je, 0);
668 return js;
669 }
670
671
alloc_tmp_paths(THD * thd,uint n_paths,json_path_with_flags ** paths,String ** tmp_paths)672 static int alloc_tmp_paths(THD *thd, uint n_paths,
673 json_path_with_flags **paths, String **tmp_paths)
674 {
675 if (n_paths > 0)
676 {
677 if (*tmp_paths == 0)
678 {
679 MEM_ROOT *root= thd->stmt_arena->mem_root;
680
681 *paths= (json_path_with_flags *) alloc_root(root,
682 sizeof(json_path_with_flags) * n_paths);
683
684 *tmp_paths= new (root) String[n_paths];
685 if (*paths == 0 || *tmp_paths == 0)
686 return 1;
687
688 for (uint c_path=0; c_path < n_paths; c_path++)
689 (*tmp_paths)[c_path].set_charset(&my_charset_utf8_general_ci);
690 }
691
692 return 0;
693 }
694
695 /* n_paths == 0 */
696 *paths= 0;
697 *tmp_paths= 0;
698 return 0;
699 }
700
701
mark_constant_paths(json_path_with_flags * p,Item ** args,uint n_args)702 static void mark_constant_paths(json_path_with_flags *p,
703 Item** args, uint n_args)
704 {
705 uint n;
706 for (n= 0; n < n_args; n++)
707 p[n].set_constant_flag(args[n]->const_item());
708 }
709
710
fix_fields(THD * thd,Item ** ref)711 bool Item_json_str_multipath::fix_fields(THD *thd, Item **ref)
712 {
713 return alloc_tmp_paths(thd, get_n_paths(), &paths, &tmp_paths) ||
714 Item_str_func::fix_fields(thd, ref);
715 }
716
717
cleanup()718 void Item_json_str_multipath::cleanup()
719 {
720 if (tmp_paths)
721 {
722 for (uint i= get_n_paths(); i>0; i--)
723 tmp_paths[i-1].free();
724 }
725 Item_str_func::cleanup();
726 }
727
728
fix_length_and_dec()729 bool Item_func_json_extract::fix_length_and_dec()
730 {
731 collation.set(args[0]->collation);
732 max_length= args[0]->max_length * (arg_count - 1);
733
734 mark_constant_paths(paths, args+1, arg_count-1);
735 maybe_null= 1;
736 return FALSE;
737 }
738
739
path_exact(const json_path_with_flags * paths_list,int n_paths,const json_path_t * p,json_value_types vt)740 static bool path_exact(const json_path_with_flags *paths_list, int n_paths,
741 const json_path_t *p, json_value_types vt)
742 {
743 for (; n_paths > 0; n_paths--, paths_list++)
744 {
745 if (json_path_compare(&paths_list->p, p, vt) == 0)
746 return TRUE;
747 }
748 return FALSE;
749 }
750
751
path_ok(const json_path_with_flags * paths_list,int n_paths,const json_path_t * p,json_value_types vt)752 static bool path_ok(const json_path_with_flags *paths_list, int n_paths,
753 const json_path_t *p, json_value_types vt)
754 {
755 for (; n_paths > 0; n_paths--, paths_list++)
756 {
757 if (json_path_compare(&paths_list->p, p, vt) >= 0)
758 return TRUE;
759 }
760 return FALSE;
761 }
762
763
read_json(String * str,json_value_types * type,char ** out_val,int * value_len)764 String *Item_func_json_extract::read_json(String *str,
765 json_value_types *type,
766 char **out_val, int *value_len)
767 {
768 String *js= args[0]->val_json(&tmp_js);
769 json_engine_t je, sav_je;
770 json_path_t p;
771 const uchar *value;
772 int not_first_value= 0;
773 uint n_arg;
774 size_t v_len;
775 int possible_multiple_values;
776
777 if ((null_value= args[0]->null_value))
778 return 0;
779
780 for (n_arg=1; n_arg < arg_count; n_arg++)
781 {
782 json_path_with_flags *c_path= paths + n_arg - 1;
783 if (!c_path->parsed)
784 {
785 String *s_p= args[n_arg]->val_str(tmp_paths + (n_arg-1));
786 if (s_p &&
787 json_path_setup(&c_path->p,s_p->charset(),(const uchar *) s_p->ptr(),
788 (const uchar *) s_p->ptr() + s_p->length()))
789 {
790 report_path_error(s_p, &c_path->p, n_arg);
791 goto return_null;
792 }
793 c_path->parsed= c_path->constant;
794 }
795
796 if (args[n_arg]->null_value)
797 goto return_null;
798 }
799
800 possible_multiple_values= arg_count > 2 ||
801 (paths[0].p.types_used & (JSON_PATH_WILD | JSON_PATH_DOUBLE_WILD));
802
803 *type= possible_multiple_values ? JSON_VALUE_ARRAY : JSON_VALUE_NULL;
804
805 if (str)
806 {
807 str->set_charset(js->charset());
808 str->length(0);
809
810 if (possible_multiple_values && str->append("[", 1))
811 goto error;
812 }
813
814 json_get_path_start(&je, js->charset(),(const uchar *) js->ptr(),
815 (const uchar *) js->ptr() + js->length(), &p);
816
817 while (json_get_path_next(&je, &p) == 0)
818 {
819 if (!path_exact(paths, arg_count-1, &p, je.value_type))
820 continue;
821
822 value= je.value_begin;
823
824 if (*type == JSON_VALUE_NULL)
825 {
826 *type= je.value_type;
827 *out_val= (char *) je.value;
828 *value_len= je.value_len;
829 }
830 if (!str)
831 {
832 /* If str is NULL, we only care about the first found value. */
833 goto return_ok;
834 }
835
836 if (json_value_scalar(&je))
837 v_len= je.value_end - value;
838 else
839 {
840 if (possible_multiple_values)
841 sav_je= je;
842 if (json_skip_level(&je))
843 goto error;
844 v_len= je.s.c_str - value;
845 if (possible_multiple_values)
846 je= sav_je;
847 }
848
849 if ((not_first_value && str->append(", ", 2)) ||
850 str->append((const char *) value, v_len))
851 goto error; /* Out of memory. */
852
853 not_first_value= 1;
854
855 if (!possible_multiple_values)
856 {
857 /* Loop to the end of the JSON just to make sure it's valid. */
858 while (json_get_path_next(&je, &p) == 0) {}
859 break;
860 }
861 }
862
863 if (unlikely(je.s.error))
864 goto error;
865
866 if (!not_first_value)
867 {
868 /* Nothing was found. */
869 goto return_null;
870 }
871
872 if (possible_multiple_values && str->append("]", 1))
873 goto error; /* Out of memory. */
874
875 js= str;
876 json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
877 (const uchar *) js->ptr() + js->length());
878 tmp_js.length(0);
879 tmp_js.set_charset(js->charset());
880 if (json_nice(&je, &tmp_js, Item_func_json_format::LOOSE))
881 goto error;
882
883 return_ok:
884 return &tmp_js;
885
886 error:
887 report_json_error(js, &je, 0);
888 return_null:
889 null_value= 1;
890 return 0;
891 }
892
893
val_str(String * str)894 String *Item_func_json_extract::val_str(String *str)
895 {
896 json_value_types type;
897 char *value;
898 int value_len;
899 return read_json(str, &type, &value, &value_len);
900 }
901
902
val_int()903 longlong Item_func_json_extract::val_int()
904 {
905 json_value_types type;
906 char *value;
907 int value_len;
908 longlong i= 0;
909
910 if (read_json(NULL, &type, &value, &value_len) != NULL)
911 {
912 switch (type)
913 {
914 case JSON_VALUE_NUMBER:
915 case JSON_VALUE_STRING:
916 {
917 char *end;
918 int err;
919 i= my_strntoll(collation.collation, value, value_len, 10, &end, &err);
920 break;
921 }
922 case JSON_VALUE_TRUE:
923 i= 1;
924 break;
925 default:
926 i= 0;
927 break;
928 };
929 }
930 return i;
931 }
932
933
val_real()934 double Item_func_json_extract::val_real()
935 {
936 json_value_types type;
937 char *value;
938 int value_len;
939 double d= 0.0;
940
941 if (read_json(NULL, &type, &value, &value_len) != NULL)
942 {
943 switch (type)
944 {
945 case JSON_VALUE_STRING:
946 case JSON_VALUE_NUMBER:
947 {
948 char *end;
949 int err;
950 d= my_strntod(collation.collation, value, value_len, &end, &err);
951 break;
952 }
953 case JSON_VALUE_TRUE:
954 d= 1.0;
955 break;
956 default:
957 break;
958 };
959 }
960
961 return d;
962 }
963
964
val_decimal(my_decimal * to)965 my_decimal *Item_func_json_extract::val_decimal(my_decimal *to)
966 {
967 json_value_types type;
968 char *value;
969 int value_len;
970
971 if (read_json(NULL, &type, &value, &value_len) != NULL)
972 {
973 switch (type)
974 {
975 case JSON_VALUE_STRING:
976 case JSON_VALUE_NUMBER:
977 {
978 my_decimal *res= decimal_from_string_with_check(to, collation.collation,
979 value,
980 value + value_len);
981 null_value= res == NULL;
982 return res;
983 }
984 case JSON_VALUE_TRUE:
985 int2my_decimal(E_DEC_FATAL_ERROR, 1, false/*unsigned_flag*/, to);
986 return to;
987 case JSON_VALUE_OBJECT:
988 case JSON_VALUE_ARRAY:
989 case JSON_VALUE_FALSE:
990 case JSON_VALUE_NULL:
991 break;
992 };
993 }
994 int2my_decimal(E_DEC_FATAL_ERROR, 0, false/*unsigned_flag*/, to);
995 return to;
996 }
997
998
999
fix_length_and_dec()1000 bool Item_func_json_contains::fix_length_and_dec()
1001 {
1002 a2_constant= args[1]->const_item();
1003 a2_parsed= FALSE;
1004 maybe_null= 1;
1005 if (arg_count > 2)
1006 path.set_constant_flag(args[2]->const_item());
1007 return Item_bool_func::fix_length_and_dec();
1008 }
1009
1010
find_key_in_object(json_engine_t * j,json_string_t * key)1011 static int find_key_in_object(json_engine_t *j, json_string_t *key)
1012 {
1013 const uchar *c_str= key->c_str;
1014
1015 while (json_scan_next(j) == 0 && j->state != JST_OBJ_END)
1016 {
1017 DBUG_ASSERT(j->state == JST_KEY);
1018 if (json_key_matches(j, key))
1019 return TRUE;
1020 if (json_skip_key(j))
1021 return FALSE;
1022 key->c_str= c_str;
1023 }
1024
1025 return FALSE;
1026 }
1027
1028
check_contains(json_engine_t * js,json_engine_t * value)1029 static int check_contains(json_engine_t *js, json_engine_t *value)
1030 {
1031 json_engine_t loc_js;
1032 bool set_js;
1033
1034 switch (js->value_type)
1035 {
1036 case JSON_VALUE_OBJECT:
1037 {
1038 json_string_t key_name;
1039
1040 if (value->value_type != JSON_VALUE_OBJECT)
1041 return FALSE;
1042
1043 loc_js= *js;
1044 set_js= FALSE;
1045 json_string_set_cs(&key_name, value->s.cs);
1046 while (json_scan_next(value) == 0 && value->state != JST_OBJ_END)
1047 {
1048 const uchar *k_start, *k_end;
1049
1050 DBUG_ASSERT(value->state == JST_KEY);
1051 k_start= value->s.c_str;
1052 do
1053 {
1054 k_end= value->s.c_str;
1055 } while (json_read_keyname_chr(value) == 0);
1056
1057 if (unlikely(value->s.error) || json_read_value(value))
1058 return FALSE;
1059
1060 if (set_js)
1061 *js= loc_js;
1062 else
1063 set_js= TRUE;
1064
1065 json_string_set_str(&key_name, k_start, k_end);
1066 if (!find_key_in_object(js, &key_name) ||
1067 json_read_value(js) ||
1068 !check_contains(js, value))
1069 return FALSE;
1070 }
1071
1072 return value->state == JST_OBJ_END && !json_skip_level(js);
1073 }
1074 case JSON_VALUE_ARRAY:
1075 if (value->value_type != JSON_VALUE_ARRAY)
1076 {
1077 loc_js= *value;
1078 set_js= FALSE;
1079 while (json_scan_next(js) == 0 && js->state != JST_ARRAY_END)
1080 {
1081 int c_level, v_scalar;
1082 DBUG_ASSERT(js->state == JST_VALUE);
1083 if (json_read_value(js))
1084 return FALSE;
1085
1086 if (!(v_scalar= json_value_scalar(js)))
1087 c_level= json_get_level(js);
1088
1089 if (set_js)
1090 *value= loc_js;
1091 else
1092 set_js= TRUE;
1093
1094 if (check_contains(js, value))
1095 {
1096 if (json_skip_level(js))
1097 return FALSE;
1098 return TRUE;
1099 }
1100 if (unlikely(value->s.error) || unlikely(js->s.error) ||
1101 (!v_scalar && json_skip_to_level(js, c_level)))
1102 return FALSE;
1103 }
1104 return FALSE;
1105 }
1106 /* else */
1107 loc_js= *js;
1108 set_js= FALSE;
1109 while (json_scan_next(value) == 0 && value->state != JST_ARRAY_END)
1110 {
1111 DBUG_ASSERT(value->state == JST_VALUE);
1112 if (json_read_value(value))
1113 return FALSE;
1114
1115 if (set_js)
1116 *js= loc_js;
1117 else
1118 set_js= TRUE;
1119 if (!check_contains(js, value))
1120 return FALSE;
1121 }
1122
1123 return value->state == JST_ARRAY_END;
1124
1125 case JSON_VALUE_STRING:
1126 if (value->value_type != JSON_VALUE_STRING)
1127 return FALSE;
1128 /*
1129 TODO: make proper json-json comparison here that takes excapint
1130 into account.
1131 */
1132 return value->value_len == js->value_len &&
1133 memcmp(value->value, js->value, value->value_len) == 0;
1134 case JSON_VALUE_NUMBER:
1135 if (value->value_type == JSON_VALUE_NUMBER)
1136 {
1137 double d_j, d_v;
1138 char *end;
1139 int err;
1140
1141 d_j= my_strntod(js->s.cs, (char *) js->value, js->value_len,
1142 &end, &err);;
1143 d_v= my_strntod(value->s.cs, (char *) value->value, value->value_len,
1144 &end, &err);;
1145
1146 return (fabs(d_j - d_v) < 1e-12);
1147 }
1148 else
1149 return FALSE;
1150
1151 default:
1152 break;
1153 }
1154
1155 /*
1156 We have these not mentioned in the 'switch' above:
1157
1158 case JSON_VALUE_TRUE:
1159 case JSON_VALUE_FALSE:
1160 case JSON_VALUE_NULL:
1161 */
1162 return value->value_type == js->value_type;
1163 }
1164
1165
val_int()1166 longlong Item_func_json_contains::val_int()
1167 {
1168 String *js= args[0]->val_json(&tmp_js);
1169 json_engine_t je, ve;
1170 int result;
1171
1172 if ((null_value= args[0]->null_value))
1173 return 0;
1174
1175 if (!a2_parsed)
1176 {
1177 val= args[1]->val_json(&tmp_val);
1178 a2_parsed= a2_constant;
1179 }
1180
1181 if (val == 0)
1182 {
1183 null_value= 1;
1184 return 0;
1185 }
1186
1187 json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
1188 (const uchar *) js->ptr() + js->length());
1189
1190 if (arg_count>2) /* Path specified. */
1191 {
1192 uint array_counters[JSON_DEPTH_LIMIT];
1193 if (!path.parsed)
1194 {
1195 String *s_p= args[2]->val_str(&tmp_path);
1196 if (s_p &&
1197 path_setup_nwc(&path.p,s_p->charset(),(const uchar *) s_p->ptr(),
1198 (const uchar *) s_p->end()))
1199 {
1200 report_path_error(s_p, &path.p, 2);
1201 goto return_null;
1202 }
1203 path.parsed= path.constant;
1204 }
1205 if (args[2]->null_value)
1206 goto return_null;
1207
1208 path.cur_step= path.p.steps;
1209 if (json_find_path(&je, &path.p, &path.cur_step, array_counters))
1210 {
1211 if (je.s.error)
1212 {
1213 ve.s.error= 0;
1214 goto error;
1215 }
1216
1217 return FALSE;
1218 }
1219 }
1220
1221 json_scan_start(&ve, val->charset(),(const uchar *) val->ptr(),
1222 (const uchar *) val->end());
1223
1224 if (json_read_value(&je) || json_read_value(&ve))
1225 goto error;
1226
1227 result= check_contains(&je, &ve);
1228 if (unlikely(je.s.error || ve.s.error))
1229 goto error;
1230
1231 return result;
1232
1233 error:
1234 if (je.s.error)
1235 report_json_error(js, &je, 0);
1236 if (ve.s.error)
1237 report_json_error(val, &ve, 1);
1238 return_null:
1239 null_value= 1;
1240 return 0;
1241 }
1242
1243
fix_fields(THD * thd,Item ** ref)1244 bool Item_func_json_contains_path::fix_fields(THD *thd, Item **ref)
1245 {
1246 return alloc_tmp_paths(thd, arg_count-2, &paths, &tmp_paths) ||
1247 (p_found= (bool *) alloc_root(thd->mem_root,
1248 (arg_count-2)*sizeof(bool))) == NULL ||
1249 Item_int_func::fix_fields(thd, ref);
1250 }
1251
1252
fix_length_and_dec()1253 bool Item_func_json_contains_path::fix_length_and_dec()
1254 {
1255 ooa_constant= args[1]->const_item();
1256 ooa_parsed= FALSE;
1257 maybe_null= 1;
1258 mark_constant_paths(paths, args+2, arg_count-2);
1259 return Item_bool_func::fix_length_and_dec();
1260 }
1261
1262
cleanup()1263 void Item_func_json_contains_path::cleanup()
1264 {
1265 if (tmp_paths)
1266 {
1267 for (uint i= arg_count-2; i>0; i--)
1268 tmp_paths[i-1].free();
1269 tmp_paths= 0;
1270 }
1271 Item_int_func::cleanup();
1272 }
1273
1274
parse_one_or_all(const Item_func * f,Item * ooa_arg,bool * ooa_parsed,bool ooa_constant,bool * mode_one)1275 static int parse_one_or_all(const Item_func *f, Item *ooa_arg,
1276 bool *ooa_parsed, bool ooa_constant, bool *mode_one)
1277 {
1278 if (!*ooa_parsed)
1279 {
1280 char buff[20];
1281 String *res, tmp(buff, sizeof(buff), &my_charset_bin);
1282 if ((res= ooa_arg->val_str(&tmp)) == NULL)
1283 return TRUE;
1284
1285 *mode_one=eq_ascii_string(res->charset(), "one",
1286 res->ptr(), res->length());
1287 if (!*mode_one)
1288 {
1289 if (!eq_ascii_string(res->charset(), "all", res->ptr(), res->length()))
1290 {
1291 THD *thd= current_thd;
1292 push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
1293 ER_JSON_ONE_OR_ALL, ER_THD(thd, ER_JSON_ONE_OR_ALL),
1294 f->func_name());
1295 *mode_one= TRUE;
1296 return TRUE;
1297 }
1298 }
1299 *ooa_parsed= ooa_constant;
1300 }
1301 return FALSE;
1302 }
1303
1304
1305 #ifdef DUMMY
val_int()1306 longlong Item_func_json_contains_path::val_int()
1307 {
1308 String *js= args[0]->val_json(&tmp_js);
1309 json_engine_t je;
1310 uint n_arg;
1311 longlong result;
1312
1313 if ((null_value= args[0]->null_value))
1314 return 0;
1315
1316 if (parse_one_or_all(this, args[1], &ooa_parsed, ooa_constant, &mode_one))
1317 goto return_null;
1318
1319 result= !mode_one;
1320 for (n_arg=2; n_arg < arg_count; n_arg++)
1321 {
1322 uint array_counters[JSON_DEPTH_LIMIT];
1323 json_path_with_flags *c_path= paths + n_arg - 2;
1324 if (!c_path->parsed)
1325 {
1326 String *s_p= args[n_arg]->val_str(tmp_paths+(n_arg-2));
1327 if (s_p &&
1328 json_path_setup(&c_path->p,s_p->charset(),(const uchar *) s_p->ptr(),
1329 (const uchar *) s_p->ptr() + s_p->length()))
1330 {
1331 report_path_error(s_p, &c_path->p, n_arg-2);
1332 goto return_null;
1333 }
1334 c_path->parsed= c_path->constant;
1335 }
1336
1337 if (args[n_arg]->null_value)
1338 goto return_null;
1339
1340 json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
1341 (const uchar *) js->ptr() + js->length());
1342
1343 c_path->cur_step= c_path->p.steps;
1344 if (json_find_path(&je, &c_path->p, &c_path->cur_step, array_counters))
1345 {
1346 /* Path wasn't found. */
1347 if (je.s.error)
1348 goto js_error;
1349
1350 if (!mode_one)
1351 {
1352 result= 0;
1353 break;
1354 }
1355 }
1356 else if (mode_one)
1357 {
1358 result= 1;
1359 break;
1360 }
1361 }
1362
1363
1364 return result;
1365
1366 js_error:
1367 report_json_error(js, &je, 0);
1368 return_null:
1369 null_value= 1;
1370 return 0;
1371 }
1372 #endif /*DUMMY*/
1373
val_int()1374 longlong Item_func_json_contains_path::val_int()
1375 {
1376 String *js= args[0]->val_json(&tmp_js);
1377 json_engine_t je;
1378 uint n_arg;
1379 longlong result;
1380 json_path_t p;
1381 int n_found;
1382 LINT_INIT(n_found);
1383
1384 if ((null_value= args[0]->null_value))
1385 return 0;
1386
1387 if (parse_one_or_all(this, args[1], &ooa_parsed, ooa_constant, &mode_one))
1388 goto null_return;;
1389
1390 for (n_arg=2; n_arg < arg_count; n_arg++)
1391 {
1392 json_path_with_flags *c_path= paths + n_arg - 2;
1393 if (!c_path->parsed)
1394 {
1395 String *s_p= args[n_arg]->val_str(tmp_paths + (n_arg-2));
1396 if (s_p &&
1397 json_path_setup(&c_path->p,s_p->charset(),(const uchar *) s_p->ptr(),
1398 (const uchar *) s_p->ptr() + s_p->length()))
1399 {
1400 report_path_error(s_p, &c_path->p, n_arg);
1401 goto null_return;
1402 }
1403 c_path->parsed= c_path->constant;
1404 }
1405 if (args[n_arg]->null_value)
1406 goto null_return;
1407 }
1408
1409 json_get_path_start(&je, js->charset(),(const uchar *) js->ptr(),
1410 (const uchar *) js->ptr() + js->length(), &p);
1411
1412
1413 if (!mode_one)
1414 {
1415 bzero(p_found, (arg_count-2) * sizeof(bool));
1416 n_found= arg_count - 2;
1417 }
1418 else
1419 n_found= 0; /* Jost to prevent 'uninitialized value' warnings */
1420
1421 result= 0;
1422 while (json_get_path_next(&je, &p) == 0)
1423 {
1424 int n_path= arg_count - 2;
1425 json_path_with_flags *c_path= paths;
1426 for (; n_path > 0; n_path--, c_path++)
1427 {
1428 if (json_path_compare(&c_path->p, &p, je.value_type) >= 0)
1429 {
1430 if (mode_one)
1431 {
1432 result= 1;
1433 break;
1434 }
1435 /* mode_all */
1436 if (p_found[n_path-1])
1437 continue; /* already found */
1438 if (--n_found == 0)
1439 {
1440 result= 1;
1441 break;
1442 }
1443 p_found[n_path-1]= TRUE;
1444 }
1445 }
1446 }
1447
1448 if (likely(je.s.error == 0))
1449 return result;
1450
1451 report_json_error(js, &je, 0);
1452 null_return:
1453 null_value= 1;
1454 return 0;
1455 }
1456
1457
append_json_value(String * str,Item * item,String * tmp_val)1458 static int append_json_value(String *str, Item *item, String *tmp_val)
1459 {
1460 if (item->is_bool_type())
1461 {
1462 longlong v_int= item->val_int();
1463 const char *t_f;
1464 int t_f_len;
1465
1466 if (item->null_value)
1467 goto append_null;
1468
1469 if (v_int)
1470 {
1471 t_f= "true";
1472 t_f_len= 4;
1473 }
1474 else
1475 {
1476 t_f= "false";
1477 t_f_len= 5;
1478 }
1479
1480 return str->append(t_f, t_f_len);
1481 }
1482 {
1483 String *sv= item->val_json(tmp_val);
1484 if (item->null_value)
1485 goto append_null;
1486 if (item->is_json_type())
1487 return str->append(sv->ptr(), sv->length());
1488
1489 if (item->result_type() == STRING_RESULT)
1490 {
1491 return str->append("\"", 1) ||
1492 st_append_escaped(str, sv) ||
1493 str->append("\"", 1);
1494 }
1495 return st_append_escaped(str, sv);
1496 }
1497
1498 append_null:
1499 return str->append("null", 4);
1500 }
1501
1502
append_json_keyname(String * str,Item * item,String * tmp_val)1503 static int append_json_keyname(String *str, Item *item, String *tmp_val)
1504 {
1505 String *sv= item->val_str(tmp_val);
1506 if (item->null_value)
1507 goto append_null;
1508
1509 return str->append("\"", 1) ||
1510 st_append_escaped(str, sv) ||
1511 str->append("\": ", 3);
1512
1513 append_null:
1514 return str->append("\"\": ", 4);
1515 }
1516
1517
fix_length_and_dec()1518 bool Item_func_json_array::fix_length_and_dec()
1519 {
1520 ulonglong char_length= 2;
1521 uint n_arg;
1522
1523 result_limit= 0;
1524
1525 if (arg_count == 0)
1526 {
1527 THD* thd= current_thd;
1528 collation.set(thd->variables.collation_connection,
1529 DERIVATION_COERCIBLE, MY_REPERTOIRE_ASCII);
1530 tmp_val.set_charset(thd->variables.collation_connection);
1531 max_length= 2;
1532 return FALSE;
1533 }
1534
1535 if (agg_arg_charsets_for_string_result(collation, args, arg_count))
1536 return TRUE;
1537
1538 for (n_arg=0 ; n_arg < arg_count ; n_arg++)
1539 char_length+= args[n_arg]->max_char_length() + 4;
1540
1541 fix_char_length_ulonglong(char_length);
1542 tmp_val.set_charset(collation.collation);
1543 return FALSE;
1544 }
1545
1546
val_str(String * str)1547 String *Item_func_json_array::val_str(String *str)
1548 {
1549 DBUG_ASSERT(fixed == 1);
1550 uint n_arg;
1551
1552 str->length(0);
1553 str->set_charset(collation.collation);
1554
1555 if (str->append("[", 1) ||
1556 ((arg_count > 0) && append_json_value(str, args[0], &tmp_val)))
1557 goto err_return;
1558
1559 for (n_arg=1; n_arg < arg_count; n_arg++)
1560 {
1561 if (str->append(", ", 2) ||
1562 append_json_value(str, args[n_arg], &tmp_val))
1563 goto err_return;
1564 }
1565
1566 if (str->append("]", 1))
1567 goto err_return;
1568
1569 if (result_limit == 0)
1570 result_limit= current_thd->variables.max_allowed_packet;
1571
1572 if (str->length() <= result_limit)
1573 return str;
1574
1575 push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
1576 ER_WARN_ALLOWED_PACKET_OVERFLOWED,
1577 ER_THD(current_thd, ER_WARN_ALLOWED_PACKET_OVERFLOWED),
1578 func_name(), result_limit);
1579
1580 err_return:
1581 /*TODO: Launch out of memory error. */
1582 null_value= 1;
1583 return NULL;
1584 }
1585
1586
fix_length_and_dec()1587 bool Item_func_json_array_append::fix_length_and_dec()
1588 {
1589 uint n_arg;
1590 ulonglong char_length;
1591
1592 collation.set(args[0]->collation);
1593 char_length= args[0]->max_char_length();
1594
1595 for (n_arg= 1; n_arg < arg_count; n_arg+= 2)
1596 {
1597 paths[n_arg/2].set_constant_flag(args[n_arg]->const_item());
1598 char_length+= args[n_arg/2+1]->max_char_length() + 4;
1599 }
1600
1601 fix_char_length_ulonglong(char_length);
1602 maybe_null= 1;
1603 return FALSE;
1604 }
1605
1606
val_str(String * str)1607 String *Item_func_json_array_append::val_str(String *str)
1608 {
1609 json_engine_t je;
1610 String *js= args[0]->val_json(&tmp_js);
1611 uint n_arg, n_path;
1612 size_t str_rest_len;
1613 const uchar *ar_end;
1614
1615 DBUG_ASSERT(fixed == 1);
1616
1617 if ((null_value= args[0]->null_value))
1618 return 0;
1619
1620 for (n_arg=1, n_path=0; n_arg < arg_count; n_arg+=2, n_path++)
1621 {
1622 uint array_counters[JSON_DEPTH_LIMIT];
1623 json_path_with_flags *c_path= paths + n_path;
1624 if (!c_path->parsed)
1625 {
1626 String *s_p= args[n_arg]->val_str(tmp_paths+n_path);
1627 if (s_p &&
1628 path_setup_nwc(&c_path->p,s_p->charset(),(const uchar *) s_p->ptr(),
1629 (const uchar *) s_p->ptr() + s_p->length()))
1630 {
1631 report_path_error(s_p, &c_path->p, n_arg);
1632 goto return_null;
1633 }
1634 c_path->parsed= c_path->constant;
1635 }
1636 if (args[n_arg]->null_value)
1637 goto return_null;
1638
1639 json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
1640 (const uchar *) js->ptr() + js->length());
1641
1642 c_path->cur_step= c_path->p.steps;
1643
1644 if (json_find_path(&je, &c_path->p, &c_path->cur_step, array_counters))
1645 {
1646 if (je.s.error)
1647 goto js_error;
1648
1649 goto return_null;
1650 }
1651
1652 if (json_read_value(&je))
1653 goto js_error;
1654
1655 str->length(0);
1656 str->set_charset(js->charset());
1657 if (str->reserve(js->length() + 8, 1024))
1658 goto return_null; /* Out of memory. */
1659
1660 if (je.value_type == JSON_VALUE_ARRAY)
1661 {
1662 int n_items;
1663 if (json_skip_level_and_count(&je, &n_items))
1664 goto js_error;
1665
1666 ar_end= je.s.c_str - je.sav_c_len;
1667 str_rest_len= js->length() - (ar_end - (const uchar *) js->ptr());
1668 str->q_append(js->ptr(), ar_end-(const uchar *) js->ptr());
1669 if (n_items)
1670 str->append(", ", 2);
1671 if (append_json_value(str, args[n_arg+1], &tmp_val))
1672 goto return_null; /* Out of memory. */
1673
1674 if (str->reserve(str_rest_len, 1024))
1675 goto return_null; /* Out of memory. */
1676 str->q_append((const char *) ar_end, str_rest_len);
1677 }
1678 else
1679 {
1680 const uchar *c_from, *c_to;
1681
1682 /* Wrap as an array. */
1683 str->q_append(js->ptr(), (const char *) je.value_begin - js->ptr());
1684 c_from= je.value_begin;
1685
1686 if (je.value_type == JSON_VALUE_OBJECT)
1687 {
1688 if (json_skip_level(&je))
1689 goto js_error;
1690 c_to= je.s.c_str;
1691 }
1692 else
1693 c_to= je.value_end;
1694
1695 if (str->append("[", 1) ||
1696 str->append((const char *) c_from, c_to - c_from) ||
1697 str->append(", ", 2) ||
1698 append_json_value(str, args[n_arg+1], &tmp_val) ||
1699 str->append("]", 1) ||
1700 str->append((const char *) je.s.c_str,
1701 js->end() - (const char *) je.s.c_str))
1702 goto return_null; /* Out of memory. */
1703 }
1704 {
1705 /* Swap str and js. */
1706 if (str == &tmp_js)
1707 {
1708 str= js;
1709 js= &tmp_js;
1710 }
1711 else
1712 {
1713 js= str;
1714 str= &tmp_js;
1715 }
1716 }
1717 }
1718
1719 json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
1720 (const uchar *) js->ptr() + js->length());
1721 str->length(0);
1722 str->set_charset(js->charset());
1723 if (json_nice(&je, str, Item_func_json_format::LOOSE))
1724 goto js_error;
1725
1726 return str;
1727
1728 js_error:
1729 report_json_error(js, &je, 0);
1730
1731 return_null:
1732 null_value= 1;
1733 return 0;
1734 }
1735
1736
val_str(String * str)1737 String *Item_func_json_array_insert::val_str(String *str)
1738 {
1739 json_engine_t je;
1740 String *js= args[0]->val_json(&tmp_js);
1741 uint n_arg, n_path;
1742
1743 DBUG_ASSERT(fixed == 1);
1744
1745 if ((null_value= args[0]->null_value))
1746 return 0;
1747
1748 for (n_arg=1, n_path=0; n_arg < arg_count; n_arg+=2, n_path++)
1749 {
1750 uint array_counters[JSON_DEPTH_LIMIT];
1751 json_path_with_flags *c_path= paths + n_path;
1752 const char *item_pos;
1753 uint n_item;
1754
1755 if (!c_path->parsed)
1756 {
1757 String *s_p= args[n_arg]->val_str(tmp_paths+n_path);
1758 if (s_p &&
1759 (path_setup_nwc(&c_path->p,s_p->charset(),(const uchar *) s_p->ptr(),
1760 (const uchar *) s_p->ptr() + s_p->length()) ||
1761 c_path->p.last_step - 1 < c_path->p.steps ||
1762 c_path->p.last_step->type != JSON_PATH_ARRAY))
1763 {
1764 if (c_path->p.s.error == 0)
1765 c_path->p.s.error= SHOULD_END_WITH_ARRAY;
1766
1767 report_path_error(s_p, &c_path->p, n_arg);
1768
1769 goto return_null;
1770 }
1771 c_path->parsed= c_path->constant;
1772 c_path->p.last_step--;
1773 }
1774 if (args[n_arg]->null_value)
1775 goto return_null;
1776
1777 json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
1778 (const uchar *) js->ptr() + js->length());
1779
1780 c_path->cur_step= c_path->p.steps;
1781
1782 if (json_find_path(&je, &c_path->p, &c_path->cur_step, array_counters))
1783 {
1784 if (je.s.error)
1785 goto js_error;
1786
1787 /* Can't find the array to insert. */
1788 continue;
1789 }
1790
1791 if (json_read_value(&je))
1792 goto js_error;
1793
1794 if (je.value_type != JSON_VALUE_ARRAY)
1795 {
1796 /* Must be an array. */
1797 continue;
1798 }
1799
1800 item_pos= 0;
1801 n_item= 0;
1802
1803 while (json_scan_next(&je) == 0 && je.state != JST_ARRAY_END)
1804 {
1805 DBUG_ASSERT(je.state == JST_VALUE);
1806 if (n_item == c_path->p.last_step[1].n_item)
1807 {
1808 item_pos= (const char *) je.s.c_str;
1809 break;
1810 }
1811 n_item++;
1812
1813 if (json_read_value(&je) ||
1814 (!json_value_scalar(&je) && json_skip_level(&je)))
1815 goto js_error;
1816 }
1817
1818 if (unlikely(je.s.error))
1819 goto js_error;
1820
1821 str->length(0);
1822 str->set_charset(js->charset());
1823 if (item_pos)
1824 {
1825 if (append_simple(str, js->ptr(), item_pos - js->ptr()) ||
1826 (n_item > 0 && str->append(" ", 1)) ||
1827 append_json_value(str, args[n_arg+1], &tmp_val) ||
1828 str->append(",", 1) ||
1829 (n_item == 0 && str->append(" ", 1)) ||
1830 append_simple(str, item_pos, js->end() - item_pos))
1831 goto return_null; /* Out of memory. */
1832 }
1833 else
1834 {
1835 /* Insert position wasn't found - append to the array. */
1836 DBUG_ASSERT(je.state == JST_ARRAY_END);
1837 item_pos= (const char *) (je.s.c_str - je.sav_c_len);
1838 if (append_simple(str, js->ptr(), item_pos - js->ptr()) ||
1839 (n_item > 0 && str->append(", ", 2)) ||
1840 append_json_value(str, args[n_arg+1], &tmp_val) ||
1841 append_simple(str, item_pos, js->end() - item_pos))
1842 goto return_null; /* Out of memory. */
1843 }
1844
1845 {
1846 /* Swap str and js. */
1847 if (str == &tmp_js)
1848 {
1849 str= js;
1850 js= &tmp_js;
1851 }
1852 else
1853 {
1854 js= str;
1855 str= &tmp_js;
1856 }
1857 }
1858 }
1859
1860 json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
1861 (const uchar *) js->ptr() + js->length());
1862 str->length(0);
1863 str->set_charset(js->charset());
1864 if (json_nice(&je, str, Item_func_json_format::LOOSE))
1865 goto js_error;
1866
1867 return str;
1868
1869 js_error:
1870 report_json_error(js, &je, 0);
1871 return_null:
1872 null_value= 1;
1873 return 0;
1874 }
1875
1876
val_str(String * str)1877 String *Item_func_json_object::val_str(String *str)
1878 {
1879 DBUG_ASSERT(fixed == 1);
1880 uint n_arg;
1881
1882 str->length(0);
1883 str->set_charset(collation.collation);
1884
1885 if (str->append("{", 1) ||
1886 (arg_count > 0 &&
1887 (append_json_keyname(str, args[0], &tmp_val) ||
1888 append_json_value(str, args[1], &tmp_val))))
1889 goto err_return;
1890
1891 for (n_arg=2; n_arg < arg_count; n_arg+=2)
1892 {
1893 if (str->append(", ", 2) ||
1894 append_json_keyname(str, args[n_arg], &tmp_val) ||
1895 append_json_value(str, args[n_arg+1], &tmp_val))
1896 goto err_return;
1897 }
1898
1899 if (str->append("}", 1))
1900 goto err_return;
1901
1902 if (result_limit == 0)
1903 result_limit= current_thd->variables.max_allowed_packet;
1904
1905 if (str->length() <= result_limit)
1906 return str;
1907
1908 push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
1909 ER_WARN_ALLOWED_PACKET_OVERFLOWED,
1910 ER_THD(current_thd, ER_WARN_ALLOWED_PACKET_OVERFLOWED),
1911 func_name(), result_limit);
1912
1913 err_return:
1914 /*TODO: Launch out of memory error. */
1915 null_value= 1;
1916 return NULL;
1917 }
1918
1919
do_merge(String * str,json_engine_t * je1,json_engine_t * je2)1920 static int do_merge(String *str, json_engine_t *je1, json_engine_t *je2)
1921 {
1922 if (json_read_value(je1) || json_read_value(je2))
1923 return 1;
1924
1925 if (je1->value_type == JSON_VALUE_OBJECT &&
1926 je2->value_type == JSON_VALUE_OBJECT)
1927 {
1928 json_engine_t sav_je1= *je1;
1929 json_engine_t sav_je2= *je2;
1930
1931 int first_key= 1;
1932 json_string_t key_name;
1933
1934 json_string_set_cs(&key_name, je1->s.cs);
1935
1936 if (str->append("{", 1))
1937 return 3;
1938 while (json_scan_next(je1) == 0 &&
1939 je1->state != JST_OBJ_END)
1940 {
1941 const uchar *key_start, *key_end;
1942 /* Loop through the Json_1 keys and compare with the Json_2 keys. */
1943 DBUG_ASSERT(je1->state == JST_KEY);
1944 key_start= je1->s.c_str;
1945 do
1946 {
1947 key_end= je1->s.c_str;
1948 } while (json_read_keyname_chr(je1) == 0);
1949
1950 if (unlikely(je1->s.error))
1951 return 1;
1952
1953 if (first_key)
1954 first_key= 0;
1955 else
1956 {
1957 if (str->append(", ", 2))
1958 return 3;
1959 *je2= sav_je2;
1960 }
1961
1962 if (str->append("\"", 1) ||
1963 append_simple(str, key_start, key_end - key_start) ||
1964 str->append("\":", 2))
1965 return 3;
1966
1967 while (json_scan_next(je2) == 0 &&
1968 je2->state != JST_OBJ_END)
1969 {
1970 int ires;
1971 DBUG_ASSERT(je2->state == JST_KEY);
1972 json_string_set_str(&key_name, key_start, key_end);
1973 if (!json_key_matches(je2, &key_name))
1974 {
1975 if (je2->s.error || json_skip_key(je2))
1976 return 2;
1977 continue;
1978 }
1979
1980 /* Json_2 has same key as Json_1. Merge them. */
1981 if ((ires= do_merge(str, je1, je2)))
1982 return ires;
1983 goto merged_j1;
1984 }
1985 if (unlikely(je2->s.error))
1986 return 2;
1987
1988 key_start= je1->s.c_str;
1989 /* Just append the Json_1 key value. */
1990 if (json_skip_key(je1))
1991 return 1;
1992 if (append_simple(str, key_start, je1->s.c_str - key_start))
1993 return 3;
1994
1995 merged_j1:
1996 continue;
1997 }
1998
1999 *je2= sav_je2;
2000 /*
2001 Now loop through the Json_2 keys.
2002 Skip if there is same key in Json_1
2003 */
2004 while (json_scan_next(je2) == 0 &&
2005 je2->state != JST_OBJ_END)
2006 {
2007 const uchar *key_start, *key_end;
2008 DBUG_ASSERT(je2->state == JST_KEY);
2009 key_start= je2->s.c_str;
2010 do
2011 {
2012 key_end= je2->s.c_str;
2013 } while (json_read_keyname_chr(je2) == 0);
2014
2015 if (unlikely(je2->s.error))
2016 return 1;
2017
2018 *je1= sav_je1;
2019 while (json_scan_next(je1) == 0 &&
2020 je1->state != JST_OBJ_END)
2021 {
2022 DBUG_ASSERT(je1->state == JST_KEY);
2023 json_string_set_str(&key_name, key_start, key_end);
2024 if (!json_key_matches(je1, &key_name))
2025 {
2026 if (unlikely(je1->s.error || json_skip_key(je1)))
2027 return 2;
2028 continue;
2029 }
2030 if (json_skip_key(je2) ||
2031 json_skip_level(je1))
2032 return 1;
2033 goto continue_j2;
2034 }
2035
2036 if (unlikely(je1->s.error))
2037 return 2;
2038
2039 if (first_key)
2040 first_key= 0;
2041 else if (str->append(", ", 2))
2042 return 3;
2043
2044 if (json_skip_key(je2))
2045 return 1;
2046
2047 if (str->append("\"", 1) ||
2048 append_simple(str, key_start, je2->s.c_str - key_start))
2049 return 3;
2050
2051 continue_j2:
2052 continue;
2053 }
2054
2055 if (str->append("}", 1))
2056 return 3;
2057 }
2058 else
2059 {
2060 const uchar *end1, *beg1, *end2, *beg2;
2061 int n_items1=1, n_items2= 1;
2062
2063 beg1= je1->value_begin;
2064
2065 /* Merge as a single array. */
2066 if (je1->value_type == JSON_VALUE_ARRAY)
2067 {
2068 if (json_skip_level_and_count(je1, &n_items1))
2069 return 1;
2070
2071 end1= je1->s.c_str - je1->sav_c_len;
2072 }
2073 else
2074 {
2075 if (str->append("[", 1))
2076 return 3;
2077 if (je1->value_type == JSON_VALUE_OBJECT)
2078 {
2079 if (json_skip_level(je1))
2080 return 1;
2081 end1= je1->s.c_str;
2082 }
2083 else
2084 end1= je1->value_end;
2085 }
2086
2087 if (str->append((const char*) beg1, end1 - beg1))
2088 return 3;
2089
2090 if (json_value_scalar(je2))
2091 {
2092 beg2= je2->value_begin;
2093 end2= je2->value_end;
2094 }
2095 else
2096 {
2097 if (je2->value_type == JSON_VALUE_OBJECT)
2098 {
2099 beg2= je2->value_begin;
2100 if (json_skip_level(je2))
2101 return 2;
2102 }
2103 else
2104 {
2105 beg2= je2->s.c_str;
2106 if (json_skip_level_and_count(je2, &n_items2))
2107 return 2;
2108 }
2109 end2= je2->s.c_str;
2110 }
2111
2112 if ((n_items1 && n_items2 && str->append(", ", 2)) ||
2113 str->append((const char*) beg2, end2 - beg2))
2114 return 3;
2115
2116 if (je2->value_type != JSON_VALUE_ARRAY &&
2117 str->append("]", 1))
2118 return 3;
2119 }
2120
2121 return 0;
2122 }
2123
2124
val_str(String * str)2125 String *Item_func_json_merge::val_str(String *str)
2126 {
2127 DBUG_ASSERT(fixed == 1);
2128 json_engine_t je1, je2;
2129 String *js1= args[0]->val_json(&tmp_js1), *js2=NULL;
2130 uint n_arg;
2131 LINT_INIT(js2);
2132
2133 if (args[0]->null_value)
2134 goto null_return;
2135
2136 for (n_arg=1; n_arg < arg_count; n_arg++)
2137 {
2138 str->set_charset(js1->charset());
2139 str->length(0);
2140
2141 js2= args[n_arg]->val_json(&tmp_js2);
2142 if (args[n_arg]->null_value)
2143 goto null_return;
2144
2145 json_scan_start(&je1, js1->charset(),(const uchar *) js1->ptr(),
2146 (const uchar *) js1->ptr() + js1->length());
2147
2148 json_scan_start(&je2, js2->charset(),(const uchar *) js2->ptr(),
2149 (const uchar *) js2->ptr() + js2->length());
2150
2151 if (do_merge(str, &je1, &je2))
2152 goto error_return;
2153
2154 {
2155 /* Swap str and js1. */
2156 if (str == &tmp_js1)
2157 {
2158 str= js1;
2159 js1= &tmp_js1;
2160 }
2161 else
2162 {
2163 js1= str;
2164 str= &tmp_js1;
2165 }
2166 }
2167 }
2168
2169 json_scan_start(&je1, js1->charset(),(const uchar *) js1->ptr(),
2170 (const uchar *) js1->ptr() + js1->length());
2171 str->length(0);
2172 str->set_charset(js1->charset());
2173 if (json_nice(&je1, str, Item_func_json_format::LOOSE))
2174 goto error_return;
2175
2176 null_value= 0;
2177 return str;
2178
2179 error_return:
2180 if (je1.s.error)
2181 report_json_error(js1, &je1, 0);
2182 if (je2.s.error)
2183 report_json_error(js2, &je2, n_arg);
2184 null_return:
2185 null_value= 1;
2186 return NULL;
2187 }
2188
2189
copy_value_patch(String * str,json_engine_t * je)2190 static int copy_value_patch(String *str, json_engine_t *je)
2191 {
2192 int first_key= 1;
2193
2194 if (je->value_type != JSON_VALUE_OBJECT)
2195 {
2196 const uchar *beg, *end;
2197
2198 beg= je->value_begin;
2199
2200 if (!json_value_scalar(je))
2201 {
2202 if (json_skip_level(je))
2203 return 1;
2204 end= je->s.c_str;
2205 }
2206 else
2207 end= je->value_end;
2208
2209 if (append_simple(str, beg, end-beg))
2210 return 1;
2211
2212 return 0;
2213 }
2214 /* JSON_VALUE_OBJECT */
2215
2216 if (str->append("{", 1))
2217 return 1;
2218 while (json_scan_next(je) == 0 && je->state != JST_OBJ_END)
2219 {
2220 const uchar *key_start;
2221 /* Loop through the Json_1 keys and compare with the Json_2 keys. */
2222 DBUG_ASSERT(je->state == JST_KEY);
2223 key_start= je->s.c_str;
2224
2225 if (json_read_value(je))
2226 return 1;
2227
2228 if (je->value_type == JSON_VALUE_NULL)
2229 continue;
2230
2231 if (!first_key)
2232 {
2233 if (str->append(", ", 2))
2234 return 3;
2235 }
2236 else
2237 first_key= 0;
2238
2239 if (str->append("\"", 1) ||
2240 append_simple(str, key_start, je->value_begin - key_start) ||
2241 copy_value_patch(str, je))
2242 return 1;
2243 }
2244 if (str->append("}", 1))
2245 return 1;
2246
2247 return 0;
2248 }
2249
2250
do_merge_patch(String * str,json_engine_t * je1,json_engine_t * je2,bool * empty_result)2251 static int do_merge_patch(String *str, json_engine_t *je1, json_engine_t *je2,
2252 bool *empty_result)
2253 {
2254 if (json_read_value(je1) || json_read_value(je2))
2255 return 1;
2256
2257 if (je1->value_type == JSON_VALUE_OBJECT &&
2258 je2->value_type == JSON_VALUE_OBJECT)
2259 {
2260 json_engine_t sav_je1= *je1;
2261 json_engine_t sav_je2= *je2;
2262
2263 int first_key= 1;
2264 json_string_t key_name;
2265 size_t sav_len;
2266 bool mrg_empty;
2267
2268 *empty_result= FALSE;
2269 json_string_set_cs(&key_name, je1->s.cs);
2270
2271 if (str->append("{", 1))
2272 return 3;
2273 while (json_scan_next(je1) == 0 &&
2274 je1->state != JST_OBJ_END)
2275 {
2276 const uchar *key_start, *key_end;
2277 /* Loop through the Json_1 keys and compare with the Json_2 keys. */
2278 DBUG_ASSERT(je1->state == JST_KEY);
2279 key_start= je1->s.c_str;
2280 do
2281 {
2282 key_end= je1->s.c_str;
2283 } while (json_read_keyname_chr(je1) == 0);
2284
2285 if (je1->s.error)
2286 return 1;
2287
2288 sav_len= str->length();
2289
2290 if (!first_key)
2291 {
2292 if (str->append(", ", 2))
2293 return 3;
2294 *je2= sav_je2;
2295 }
2296
2297 if (str->append("\"", 1) ||
2298 append_simple(str, key_start, key_end - key_start) ||
2299 str->append("\":", 2))
2300 return 3;
2301
2302 while (json_scan_next(je2) == 0 &&
2303 je2->state != JST_OBJ_END)
2304 {
2305 int ires;
2306 DBUG_ASSERT(je2->state == JST_KEY);
2307 json_string_set_str(&key_name, key_start, key_end);
2308 if (!json_key_matches(je2, &key_name))
2309 {
2310 if (je2->s.error || json_skip_key(je2))
2311 return 2;
2312 continue;
2313 }
2314
2315 /* Json_2 has same key as Json_1. Merge them. */
2316 if ((ires= do_merge_patch(str, je1, je2, &mrg_empty)))
2317 return ires;
2318
2319 if (mrg_empty)
2320 str->length(sav_len);
2321 else
2322 first_key= 0;
2323
2324 goto merged_j1;
2325 }
2326
2327 if (je2->s.error)
2328 return 2;
2329
2330 key_start= je1->s.c_str;
2331 /* Just append the Json_1 key value. */
2332 if (json_skip_key(je1))
2333 return 1;
2334 if (append_simple(str, key_start, je1->s.c_str - key_start))
2335 return 3;
2336 first_key= 0;
2337
2338 merged_j1:
2339 continue;
2340 }
2341
2342 *je2= sav_je2;
2343 /*
2344 Now loop through the Json_2 keys.
2345 Skip if there is same key in Json_1
2346 */
2347 while (json_scan_next(je2) == 0 &&
2348 je2->state != JST_OBJ_END)
2349 {
2350 const uchar *key_start, *key_end;
2351 DBUG_ASSERT(je2->state == JST_KEY);
2352 key_start= je2->s.c_str;
2353 do
2354 {
2355 key_end= je2->s.c_str;
2356 } while (json_read_keyname_chr(je2) == 0);
2357
2358 if (je2->s.error)
2359 return 1;
2360
2361 *je1= sav_je1;
2362 while (json_scan_next(je1) == 0 &&
2363 je1->state != JST_OBJ_END)
2364 {
2365 DBUG_ASSERT(je1->state == JST_KEY);
2366 json_string_set_str(&key_name, key_start, key_end);
2367 if (!json_key_matches(je1, &key_name))
2368 {
2369 if (je1->s.error || json_skip_key(je1))
2370 return 2;
2371 continue;
2372 }
2373 if (json_skip_key(je2) ||
2374 json_skip_level(je1))
2375 return 1;
2376 goto continue_j2;
2377 }
2378
2379 if (je1->s.error)
2380 return 2;
2381
2382
2383 sav_len= str->length();
2384
2385 if (!first_key && str->append(", ", 2))
2386 return 3;
2387
2388 if (str->append("\"", 1) ||
2389 append_simple(str, key_start, key_end - key_start) ||
2390 str->append("\":", 2))
2391 return 3;
2392
2393 if (json_read_value(je2))
2394 return 1;
2395
2396 if (je2->value_type == JSON_VALUE_NULL)
2397 str->length(sav_len);
2398 else
2399 {
2400 if (copy_value_patch(str, je2))
2401 return 1;
2402 first_key= 0;
2403 }
2404
2405 continue_j2:
2406 continue;
2407 }
2408
2409 if (str->append("}", 1))
2410 return 3;
2411 }
2412 else
2413 {
2414 if (!json_value_scalar(je1) && json_skip_level(je1))
2415 return 1;
2416
2417 *empty_result= je2->value_type == JSON_VALUE_NULL;
2418 if (!(*empty_result) && copy_value_patch(str, je2))
2419 return 1;
2420 }
2421
2422 return 0;
2423 }
2424
2425
val_str(String * str)2426 String *Item_func_json_merge_patch::val_str(String *str)
2427 {
2428 DBUG_ASSERT(fixed == 1);
2429 json_engine_t je1, je2;
2430 String *js1= args[0]->val_json(&tmp_js1), *js2=NULL;
2431 uint n_arg;
2432 bool empty_result, merge_to_null;
2433
2434 /* To report errors properly if some JSON is invalid. */
2435 je1.s.error= je2.s.error= 0;
2436 merge_to_null= args[0]->null_value;
2437
2438 for (n_arg=1; n_arg < arg_count; n_arg++)
2439 {
2440 js2= args[n_arg]->val_json(&tmp_js2);
2441 if (args[n_arg]->null_value)
2442 {
2443 merge_to_null= true;
2444 goto cont_point;
2445 }
2446
2447 json_scan_start(&je2, js2->charset(),(const uchar *) js2->ptr(),
2448 (const uchar *) js2->ptr() + js2->length());
2449
2450 if (merge_to_null)
2451 {
2452 if (json_read_value(&je2))
2453 goto error_return;
2454 if (je2.value_type == JSON_VALUE_OBJECT)
2455 {
2456 merge_to_null= true;
2457 goto cont_point;
2458 }
2459 merge_to_null= false;
2460 str->set(js2->ptr(), js2->length(), js2->charset());
2461 goto cont_point;
2462 }
2463
2464 str->set_charset(js1->charset());
2465 str->length(0);
2466
2467
2468 json_scan_start(&je1, js1->charset(),(const uchar *) js1->ptr(),
2469 (const uchar *) js1->ptr() + js1->length());
2470
2471 if (do_merge_patch(str, &je1, &je2, &empty_result))
2472 goto error_return;
2473
2474 if (empty_result)
2475 str->append("null");
2476
2477 cont_point:
2478 {
2479 /* Swap str and js1. */
2480 if (str == &tmp_js1)
2481 {
2482 str= js1;
2483 js1= &tmp_js1;
2484 }
2485 else
2486 {
2487 js1= str;
2488 str= &tmp_js1;
2489 }
2490 }
2491 }
2492
2493 if (merge_to_null)
2494 goto null_return;
2495
2496 json_scan_start(&je1, js1->charset(),(const uchar *) js1->ptr(),
2497 (const uchar *) js1->ptr() + js1->length());
2498 str->length(0);
2499 str->set_charset(js1->charset());
2500 if (json_nice(&je1, str, Item_func_json_format::LOOSE))
2501 goto error_return;
2502
2503 null_value= 0;
2504 return str;
2505
2506 error_return:
2507 if (je1.s.error)
2508 report_json_error(js1, &je1, 0);
2509 if (je2.s.error)
2510 report_json_error(js2, &je2, n_arg);
2511 null_return:
2512 null_value= 1;
2513 return NULL;
2514 }
2515
2516
fix_length_and_dec()2517 bool Item_func_json_length::fix_length_and_dec()
2518 {
2519 if (arg_count > 1)
2520 path.set_constant_flag(args[1]->const_item());
2521 maybe_null= 1;
2522 max_length= 10;
2523 return FALSE;
2524 }
2525
2526
val_int()2527 longlong Item_func_json_length::val_int()
2528 {
2529 String *js= args[0]->val_json(&tmp_js);
2530 json_engine_t je;
2531 uint length= 0;
2532 uint array_counters[JSON_DEPTH_LIMIT];
2533 int err;
2534
2535 if ((null_value= args[0]->null_value))
2536 return 0;
2537
2538 json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
2539 (const uchar *) js->ptr() + js->length());
2540
2541 if (arg_count > 1)
2542 {
2543 /* Path specified - let's apply it. */
2544 if (!path.parsed)
2545 {
2546 String *s_p= args[1]->val_str(&tmp_path);
2547 if (s_p &&
2548 path_setup_nwc(&path.p, s_p->charset(), (const uchar *) s_p->ptr(),
2549 (const uchar *) s_p->ptr() + s_p->length()))
2550 {
2551 report_path_error(s_p, &path.p, 1);
2552 goto null_return;
2553 }
2554 path.parsed= path.constant;
2555 }
2556 if (args[1]->null_value)
2557 goto null_return;
2558
2559 path.cur_step= path.p.steps;
2560 if (json_find_path(&je, &path.p, &path.cur_step, array_counters))
2561 {
2562 if (je.s.error)
2563 goto err_return;
2564 goto null_return;
2565 }
2566 }
2567
2568
2569 if (json_read_value(&je))
2570 goto err_return;
2571
2572 if (json_value_scalar(&je))
2573 return 1;
2574
2575 while (!(err= json_scan_next(&je)) &&
2576 je.state != JST_OBJ_END && je.state != JST_ARRAY_END)
2577 {
2578 switch (je.state)
2579 {
2580 case JST_VALUE:
2581 case JST_KEY:
2582 length++;
2583 break;
2584 case JST_OBJ_START:
2585 case JST_ARRAY_START:
2586 if (json_skip_level(&je))
2587 goto err_return;
2588 break;
2589 default:
2590 break;
2591 };
2592 }
2593
2594 if (!err)
2595 {
2596 /* Parse to the end of the JSON just to check it's valid. */
2597 while (json_scan_next(&je) == 0) {}
2598 }
2599
2600 if (likely(!je.s.error))
2601 return length;
2602
2603 err_return:
2604 report_json_error(js, &je, 0);
2605 null_return:
2606 null_value= 1;
2607 return 0;
2608 }
2609
2610
val_int()2611 longlong Item_func_json_depth::val_int()
2612 {
2613 String *js= args[0]->val_json(&tmp_js);
2614 json_engine_t je;
2615 uint depth= 0, c_depth= 0;
2616 bool inc_depth= TRUE;
2617
2618 if ((null_value= args[0]->null_value))
2619 return 0;
2620
2621
2622 json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
2623 (const uchar *) js->ptr() + js->length());
2624
2625 do
2626 {
2627 switch (je.state)
2628 {
2629 case JST_VALUE:
2630 case JST_KEY:
2631 if (inc_depth)
2632 {
2633 c_depth++;
2634 inc_depth= FALSE;
2635 if (c_depth > depth)
2636 depth= c_depth;
2637 }
2638 break;
2639 case JST_OBJ_START:
2640 case JST_ARRAY_START:
2641 inc_depth= TRUE;
2642 break;
2643 case JST_OBJ_END:
2644 case JST_ARRAY_END:
2645 if (!inc_depth)
2646 c_depth--;
2647 inc_depth= FALSE;
2648 break;
2649 default:
2650 break;
2651 }
2652 } while (json_scan_next(&je) == 0);
2653
2654 if (likely(!je.s.error))
2655 return depth;
2656
2657 report_json_error(js, &je, 0);
2658 null_value= 1;
2659 return 0;
2660 }
2661
2662
fix_length_and_dec()2663 bool Item_func_json_type::fix_length_and_dec()
2664 {
2665 collation.set(&my_charset_utf8_general_ci);
2666 max_length= 12;
2667 maybe_null= 1;
2668 return FALSE;
2669 }
2670
2671
val_str(String * str)2672 String *Item_func_json_type::val_str(String *str)
2673 {
2674 String *js= args[0]->val_json(&tmp_js);
2675 json_engine_t je;
2676 const char *type;
2677
2678 if ((null_value= args[0]->null_value))
2679 return 0;
2680
2681
2682 json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
2683 (const uchar *) js->ptr() + js->length());
2684
2685 if (json_read_value(&je))
2686 goto error;
2687
2688 switch (je.value_type)
2689 {
2690 case JSON_VALUE_OBJECT:
2691 type= "OBJECT";
2692 break;
2693 case JSON_VALUE_ARRAY:
2694 type= "ARRAY";
2695 break;
2696 case JSON_VALUE_STRING:
2697 type= "STRING";
2698 break;
2699 case JSON_VALUE_NUMBER:
2700 type= (je.num_flags & JSON_NUM_FRAC_PART) ? "DOUBLE" : "INTEGER";
2701 break;
2702 case JSON_VALUE_TRUE:
2703 case JSON_VALUE_FALSE:
2704 type= "BOOLEAN";
2705 break;
2706 default:
2707 type= "NULL";
2708 break;
2709 }
2710
2711 str->set(type, strlen(type), &my_charset_utf8_general_ci);
2712 return str;
2713
2714 error:
2715 report_json_error(js, &je, 0);
2716 null_value= 1;
2717 return 0;
2718 }
2719
2720
fix_length_and_dec()2721 bool Item_func_json_insert::fix_length_and_dec()
2722 {
2723 uint n_arg;
2724 ulonglong char_length;
2725
2726 collation.set(args[0]->collation);
2727 char_length= args[0]->max_char_length();
2728
2729 for (n_arg= 1; n_arg < arg_count; n_arg+= 2)
2730 {
2731 paths[n_arg/2].set_constant_flag(args[n_arg]->const_item());
2732 char_length+= args[n_arg/2+1]->max_char_length() + 4;
2733 }
2734
2735 fix_char_length_ulonglong(char_length);
2736 maybe_null= 1;
2737 return FALSE;
2738 }
2739
2740
val_str(String * str)2741 String *Item_func_json_insert::val_str(String *str)
2742 {
2743 json_engine_t je;
2744 String *js= args[0]->val_json(&tmp_js);
2745 uint n_arg, n_path;
2746 json_string_t key_name;
2747
2748 DBUG_ASSERT(fixed == 1);
2749
2750 if ((null_value= args[0]->null_value))
2751 return 0;
2752
2753 str->set_charset(collation.collation);
2754 tmp_js.set_charset(collation.collation);
2755 json_string_set_cs(&key_name, collation.collation);
2756
2757 for (n_arg=1, n_path=0; n_arg < arg_count; n_arg+=2, n_path++)
2758 {
2759 uint array_counters[JSON_DEPTH_LIMIT];
2760 json_path_with_flags *c_path= paths + n_path;
2761 const char *v_to;
2762 const json_path_step_t *lp;
2763
2764 if (!c_path->parsed)
2765 {
2766 String *s_p= args[n_arg]->val_str(tmp_paths+n_path);
2767 if (s_p)
2768 {
2769 if (path_setup_nwc(&c_path->p,s_p->charset(),
2770 (const uchar *) s_p->ptr(),
2771 (const uchar *) s_p->ptr() + s_p->length()))
2772 {
2773 report_path_error(s_p, &c_path->p, n_arg);
2774 goto return_null;
2775 }
2776
2777 /* We search to the last step. */
2778 c_path->p.last_step--;
2779 }
2780 c_path->parsed= c_path->constant;
2781 }
2782 if (args[n_arg]->null_value)
2783 goto return_null;
2784
2785 json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
2786 (const uchar *) js->ptr() + js->length());
2787
2788 if (c_path->p.last_step < c_path->p.steps)
2789 goto v_found;
2790
2791 c_path->cur_step= c_path->p.steps;
2792
2793 if (c_path->p.last_step >= c_path->p.steps &&
2794 json_find_path(&je, &c_path->p, &c_path->cur_step, array_counters))
2795 {
2796 if (je.s.error)
2797 goto js_error;
2798 continue;
2799 }
2800
2801 if (json_read_value(&je))
2802 goto js_error;
2803
2804 lp= c_path->p.last_step+1;
2805 if (lp->type & JSON_PATH_ARRAY)
2806 {
2807 uint n_item= 0;
2808
2809 if (je.value_type != JSON_VALUE_ARRAY)
2810 {
2811 const uchar *v_from= je.value_begin;
2812 int do_array_autowrap;
2813
2814 if (mode_insert)
2815 {
2816 if (mode_replace)
2817 do_array_autowrap= lp->n_item > 0;
2818 else
2819 {
2820 if (lp->n_item == 0)
2821 continue;
2822 do_array_autowrap= 1;
2823 }
2824 }
2825 else
2826 {
2827 if (lp->n_item)
2828 continue;
2829 do_array_autowrap= 0;
2830 }
2831
2832
2833 str->length(0);
2834 /* Wrap the value as an array. */
2835 if (append_simple(str, js->ptr(), (const char *) v_from - js->ptr()) ||
2836 (do_array_autowrap && str->append("[", 1)))
2837 goto js_error; /* Out of memory. */
2838
2839 if (je.value_type == JSON_VALUE_OBJECT)
2840 {
2841 if (json_skip_level(&je))
2842 goto js_error;
2843 }
2844
2845 if ((do_array_autowrap &&
2846 (append_simple(str, v_from, je.s.c_str - v_from) ||
2847 str->append(", ", 2))) ||
2848 append_json_value(str, args[n_arg+1], &tmp_val) ||
2849 (do_array_autowrap && str->append("]", 1)) ||
2850 append_simple(str, je.s.c_str, js->end()-(const char *) je.s.c_str))
2851 goto js_error; /* Out of memory. */
2852
2853 goto continue_point;
2854 }
2855
2856 while (json_scan_next(&je) == 0 && je.state != JST_ARRAY_END)
2857 {
2858 switch (je.state)
2859 {
2860 case JST_VALUE:
2861 if (n_item == lp->n_item)
2862 goto v_found;
2863 n_item++;
2864 if (json_skip_array_item(&je))
2865 goto js_error;
2866 break;
2867 default:
2868 break;
2869 }
2870 }
2871
2872 if (unlikely(je.s.error))
2873 goto js_error;
2874
2875 if (!mode_insert)
2876 continue;
2877
2878 v_to= (const char *) (je.s.c_str - je.sav_c_len);
2879 str->length(0);
2880 if (append_simple(str, js->ptr(), v_to - js->ptr()) ||
2881 (n_item > 0 && str->append(", ", 2)) ||
2882 append_json_value(str, args[n_arg+1], &tmp_val) ||
2883 append_simple(str, v_to, js->end() - v_to))
2884 goto js_error; /* Out of memory. */
2885 }
2886 else /*JSON_PATH_KEY*/
2887 {
2888 uint n_key= 0;
2889
2890 if (je.value_type != JSON_VALUE_OBJECT)
2891 continue;
2892
2893 while (json_scan_next(&je) == 0 && je.state != JST_OBJ_END)
2894 {
2895 switch (je.state)
2896 {
2897 case JST_KEY:
2898 json_string_set_str(&key_name, lp->key, lp->key_end);
2899 if (json_key_matches(&je, &key_name))
2900 goto v_found;
2901 n_key++;
2902 if (json_skip_key(&je))
2903 goto js_error;
2904 break;
2905 default:
2906 break;
2907 }
2908 }
2909
2910 if (unlikely(je.s.error))
2911 goto js_error;
2912
2913 if (!mode_insert)
2914 continue;
2915
2916 v_to= (const char *) (je.s.c_str - je.sav_c_len);
2917 str->length(0);
2918 if (append_simple(str, js->ptr(), v_to - js->ptr()) ||
2919 (n_key > 0 && str->append(", ", 2)) ||
2920 str->append("\"", 1) ||
2921 append_simple(str, lp->key, lp->key_end - lp->key) ||
2922 str->append("\":", 2) ||
2923 append_json_value(str, args[n_arg+1], &tmp_val) ||
2924 append_simple(str, v_to, js->end() - v_to))
2925 goto js_error; /* Out of memory. */
2926 }
2927
2928 goto continue_point;
2929
2930 v_found:
2931
2932 if (!mode_replace)
2933 continue;
2934
2935 if (json_read_value(&je))
2936 goto js_error;
2937
2938 v_to= (const char *) je.value_begin;
2939 str->length(0);
2940 if (!json_value_scalar(&je))
2941 {
2942 if (json_skip_level(&je))
2943 goto js_error;
2944 }
2945
2946 if (append_simple(str, js->ptr(), v_to - js->ptr()) ||
2947 append_json_value(str, args[n_arg+1], &tmp_val) ||
2948 append_simple(str, je.s.c_str, js->end()-(const char *) je.s.c_str))
2949 goto js_error; /* Out of memory. */
2950 continue_point:
2951 {
2952 /* Swap str and js. */
2953 if (str == &tmp_js)
2954 {
2955 str= js;
2956 js= &tmp_js;
2957 }
2958 else
2959 {
2960 js= str;
2961 str= &tmp_js;
2962 }
2963 }
2964 }
2965
2966 json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
2967 (const uchar *) js->ptr() + js->length());
2968 str->length(0);
2969 if (json_nice(&je, str, Item_func_json_format::LOOSE))
2970 goto js_error;
2971
2972 return str;
2973
2974 js_error:
2975 report_json_error(js, &je, 0);
2976 return_null:
2977 null_value= 1;
2978 return 0;
2979 }
2980
2981
fix_length_and_dec()2982 bool Item_func_json_remove::fix_length_and_dec()
2983 {
2984 collation.set(args[0]->collation);
2985 max_length= args[0]->max_length;
2986
2987 mark_constant_paths(paths, args+1, arg_count-1);
2988 maybe_null= 1;
2989 return FALSE;
2990 }
2991
2992
val_str(String * str)2993 String *Item_func_json_remove::val_str(String *str)
2994 {
2995 json_engine_t je;
2996 String *js= args[0]->val_json(&tmp_js);
2997 uint n_arg, n_path;
2998 json_string_t key_name;
2999
3000 DBUG_ASSERT(fixed == 1);
3001
3002 if (args[0]->null_value)
3003 goto null_return;
3004
3005 str->set_charset(js->charset());
3006 json_string_set_cs(&key_name, js->charset());
3007
3008 for (n_arg=1, n_path=0; n_arg < arg_count; n_arg++, n_path++)
3009 {
3010 uint array_counters[JSON_DEPTH_LIMIT];
3011 json_path_with_flags *c_path= paths + n_path;
3012 const char *rem_start= 0, *rem_end;
3013 const json_path_step_t *lp;
3014 uint n_item= 0;
3015
3016 if (!c_path->parsed)
3017 {
3018 String *s_p= args[n_arg]->val_str(tmp_paths+n_path);
3019 if (s_p)
3020 {
3021 if (path_setup_nwc(&c_path->p,s_p->charset(),
3022 (const uchar *) s_p->ptr(),
3023 (const uchar *) s_p->ptr() + s_p->length()))
3024 {
3025 report_path_error(s_p, &c_path->p, n_arg);
3026 goto null_return;
3027 }
3028
3029 /* We search to the last step. */
3030 c_path->p.last_step--;
3031 if (c_path->p.last_step < c_path->p.steps)
3032 {
3033 c_path->p.s.error= TRIVIAL_PATH_NOT_ALLOWED;
3034 report_path_error(s_p, &c_path->p, n_arg);
3035 goto null_return;
3036 }
3037 }
3038 c_path->parsed= c_path->constant;
3039 }
3040 if (args[n_arg]->null_value)
3041 goto null_return;
3042
3043 json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
3044 (const uchar *) js->ptr() + js->length());
3045
3046 c_path->cur_step= c_path->p.steps;
3047
3048 if (json_find_path(&je, &c_path->p, &c_path->cur_step, array_counters))
3049 {
3050 if (je.s.error)
3051 goto js_error;
3052 }
3053
3054 if (json_read_value(&je))
3055 goto js_error;
3056
3057 lp= c_path->p.last_step+1;
3058 if (lp->type & JSON_PATH_ARRAY)
3059 {
3060 if (je.value_type != JSON_VALUE_ARRAY)
3061 continue;
3062
3063 while (json_scan_next(&je) == 0 && je.state != JST_ARRAY_END)
3064 {
3065 switch (je.state)
3066 {
3067 case JST_VALUE:
3068 if (n_item == lp->n_item)
3069 {
3070 rem_start= (const char *) (je.s.c_str -
3071 (n_item ? je.sav_c_len : 0));
3072 goto v_found;
3073 }
3074 n_item++;
3075 if (json_skip_array_item(&je))
3076 goto js_error;
3077 break;
3078 default:
3079 break;
3080 }
3081 }
3082
3083 if (unlikely(je.s.error))
3084 goto js_error;
3085
3086 continue;
3087 }
3088 else /*JSON_PATH_KEY*/
3089 {
3090 if (je.value_type != JSON_VALUE_OBJECT)
3091 continue;
3092
3093 while (json_scan_next(&je) == 0 && je.state != JST_OBJ_END)
3094 {
3095 switch (je.state)
3096 {
3097 case JST_KEY:
3098 if (n_item == 0)
3099 rem_start= (const char *) (je.s.c_str - je.sav_c_len);
3100 json_string_set_str(&key_name, lp->key, lp->key_end);
3101 if (json_key_matches(&je, &key_name))
3102 goto v_found;
3103
3104 if (json_skip_key(&je))
3105 goto js_error;
3106
3107 rem_start= (const char *) je.s.c_str;
3108 n_item++;
3109 break;
3110 default:
3111 break;
3112 }
3113 }
3114
3115 if (unlikely(je.s.error))
3116 goto js_error;
3117
3118 continue;
3119 }
3120
3121 v_found:
3122
3123 if (json_skip_key(&je) || json_scan_next(&je))
3124 goto js_error;
3125
3126 rem_end= (je.state == JST_VALUE && n_item == 0) ?
3127 (const char *) je.s.c_str : (const char *) (je.s.c_str - je.sav_c_len);
3128
3129 str->length(0);
3130
3131 if (append_simple(str, js->ptr(), rem_start - js->ptr()) ||
3132 (je.state == JST_KEY && n_item > 0 && str->append(",", 1)) ||
3133 append_simple(str, rem_end, js->end() - rem_end))
3134 goto js_error; /* Out of memory. */
3135
3136 {
3137 /* Swap str and js. */
3138 if (str == &tmp_js)
3139 {
3140 str= js;
3141 js= &tmp_js;
3142 }
3143 else
3144 {
3145 js= str;
3146 str= &tmp_js;
3147 }
3148 }
3149 }
3150
3151 json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
3152 (const uchar *) js->ptr() + js->length());
3153 str->length(0);
3154 str->set_charset(js->charset());
3155 if (json_nice(&je, str, Item_func_json_format::LOOSE))
3156 goto js_error;
3157
3158 null_value= 0;
3159 return str;
3160
3161 js_error:
3162 report_json_error(js, &je, 0);
3163 null_return:
3164 null_value= 1;
3165 return 0;
3166 }
3167
3168
fix_length_and_dec()3169 bool Item_func_json_keys::fix_length_and_dec()
3170 {
3171 collation.set(args[0]->collation);
3172 max_length= args[0]->max_length;
3173 maybe_null= 1;
3174 if (arg_count > 1)
3175 path.set_constant_flag(args[1]->const_item());
3176 return FALSE;
3177 }
3178
3179
3180 /*
3181 That function is for Item_func_json_keys::val_str exclusively.
3182 It utilizes the fact the resulting string is in specific format:
3183 ["key1", "key2"...]
3184 */
check_key_in_list(String * res,const uchar * key,int key_len)3185 static int check_key_in_list(String *res,
3186 const uchar *key, int key_len)
3187 {
3188 const uchar *c= (const uchar *) res->ptr() + 2; /* beginning '["' */
3189 const uchar *end= (const uchar *) res->end() - 1; /* ending '"' */
3190
3191 while (c < end)
3192 {
3193 int n_char;
3194 for (n_char=0; c[n_char] != '"' && n_char < key_len; n_char++)
3195 {
3196 if (c[n_char] != key[n_char])
3197 break;
3198 }
3199 if (c[n_char] == '"')
3200 {
3201 if (n_char == key_len)
3202 return 1;
3203 }
3204 else
3205 {
3206 while (c[n_char] != '"')
3207 n_char++;
3208 }
3209 c+= n_char + 4; /* skip ', "' */
3210 }
3211 return 0;
3212 }
3213
3214
val_str(String * str)3215 String *Item_func_json_keys::val_str(String *str)
3216 {
3217 json_engine_t je;
3218 String *js= args[0]->val_json(&tmp_js);
3219 uint n_keys= 0;
3220 uint array_counters[JSON_DEPTH_LIMIT];
3221
3222 if ((args[0]->null_value))
3223 goto null_return;
3224
3225 json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
3226 (const uchar *) js->ptr() + js->length());
3227
3228 if (arg_count < 2)
3229 goto skip_search;
3230
3231 if (!path.parsed)
3232 {
3233 String *s_p= args[1]->val_str(&tmp_path);
3234 if (s_p &&
3235 path_setup_nwc(&path.p, s_p->charset(), (const uchar *) s_p->ptr(),
3236 (const uchar *) s_p->ptr() + s_p->length()))
3237 {
3238 report_path_error(s_p, &path.p, 1);
3239 goto null_return;
3240 }
3241 path.parsed= path.constant;
3242 }
3243
3244 if (args[1]->null_value)
3245 goto null_return;
3246
3247 path.cur_step= path.p.steps;
3248
3249 if (json_find_path(&je, &path.p, &path.cur_step, array_counters))
3250 {
3251 if (je.s.error)
3252 goto err_return;
3253
3254 goto null_return;
3255 }
3256
3257 skip_search:
3258 if (json_read_value(&je))
3259 goto err_return;
3260
3261 if (je.value_type != JSON_VALUE_OBJECT)
3262 goto null_return;
3263
3264 str->length(0);
3265 if (str->append("[", 1))
3266 goto err_return; /* Out of memory. */
3267 /* Parse the OBJECT collecting the keys. */
3268 while (json_scan_next(&je) == 0 && je.state != JST_OBJ_END)
3269 {
3270 const uchar *key_start, *key_end;
3271 int key_len;
3272
3273 switch (je.state)
3274 {
3275 case JST_KEY:
3276 key_start= je.s.c_str;
3277 do
3278 {
3279 key_end= je.s.c_str;
3280 } while (json_read_keyname_chr(&je) == 0);
3281 if (unlikely(je.s.error))
3282 goto err_return;
3283 key_len= (int)(key_end - key_start);
3284
3285 if (!check_key_in_list(str, key_start, key_len))
3286 {
3287 if ((n_keys > 0 && str->append(", ", 2)) ||
3288 str->append("\"", 1) ||
3289 append_simple(str, key_start, key_len) ||
3290 str->append("\"", 1))
3291 goto err_return;
3292 n_keys++;
3293 }
3294 break;
3295 case JST_OBJ_START:
3296 case JST_ARRAY_START:
3297 if (json_skip_level(&je))
3298 break;
3299 break;
3300 default:
3301 break;
3302 }
3303 }
3304
3305 if (unlikely(je.s.error || str->append("]", 1)))
3306 goto err_return;
3307
3308 null_value= 0;
3309 return str;
3310
3311 err_return:
3312 report_json_error(js, &je, 0);
3313 null_return:
3314 null_value= 1;
3315 return 0;
3316 }
3317
3318
fix_fields(THD * thd,Item ** ref)3319 bool Item_func_json_search::fix_fields(THD *thd, Item **ref)
3320 {
3321 if (Item_json_str_multipath::fix_fields(thd, ref))
3322 return TRUE;
3323
3324 if (arg_count < 4)
3325 {
3326 escape= '\\';
3327 return FALSE;
3328 }
3329
3330 return fix_escape_item(thd, args[3], &tmp_js, true,
3331 args[0]->collation.collation, &escape);
3332 }
3333
3334
3335 static const uint SQR_MAX_BLOB_WIDTH= (uint) sqrt(MAX_BLOB_WIDTH);
3336
fix_length_and_dec()3337 bool Item_func_json_search::fix_length_and_dec()
3338 {
3339 collation.set(args[0]->collation);
3340
3341 /*
3342 It's rather difficult to estimate the length of the result.
3343 I belive arglen^2 is the reasonable upper limit.
3344 */
3345 if (args[0]->max_length > SQR_MAX_BLOB_WIDTH)
3346 max_length= MAX_BLOB_WIDTH;
3347 else
3348 {
3349 max_length= args[0]->max_length;
3350 max_length*= max_length;
3351 }
3352
3353 ooa_constant= args[1]->const_item();
3354 ooa_parsed= FALSE;
3355
3356 if (arg_count > 4)
3357 mark_constant_paths(paths, args+4, arg_count-4);
3358 maybe_null= 1;
3359 return FALSE;
3360 }
3361
3362
compare_json_value_wild(json_engine_t * je,const String * cmp_str)3363 int Item_func_json_search::compare_json_value_wild(json_engine_t *je,
3364 const String *cmp_str)
3365 {
3366 if (je->value_type != JSON_VALUE_STRING || !je->value_escaped)
3367 return my_wildcmp(collation.collation,
3368 (const char *) je->value, (const char *) (je->value + je->value_len),
3369 cmp_str->ptr(), cmp_str->end(), escape, wild_one, wild_many) ? 0 : 1;
3370
3371 {
3372 int esc_len;
3373 if (esc_value.alloced_length() < (uint) je->value_len &&
3374 esc_value.alloc((je->value_len / 1024 + 1) * 1024))
3375 return 0;
3376
3377 esc_len= json_unescape(je->s.cs, je->value, je->value + je->value_len,
3378 je->s.cs, (uchar *) esc_value.ptr(),
3379 (uchar *) (esc_value.ptr() +
3380 esc_value.alloced_length()));
3381 if (esc_len <= 0)
3382 return 0;
3383
3384 return my_wildcmp(collation.collation,
3385 esc_value.ptr(), esc_value.ptr() + esc_len,
3386 cmp_str->ptr(), cmp_str->end(), escape, wild_one, wild_many) ? 0 : 1;
3387 }
3388 }
3389
3390
append_json_path(String * str,const json_path_t * p)3391 static int append_json_path(String *str, const json_path_t *p)
3392 {
3393 const json_path_step_t *c;
3394
3395 if (str->append("\"$", 2))
3396 return TRUE;
3397
3398 for (c= p->steps+1; c <= p->last_step; c++)
3399 {
3400 if (c->type & JSON_PATH_KEY)
3401 {
3402 if (str->append(".", 1) ||
3403 append_simple(str, c->key, c->key_end-c->key))
3404 return TRUE;
3405 }
3406 else /*JSON_PATH_ARRAY*/
3407 {
3408
3409 if (str->append("[", 1) ||
3410 str->append_ulonglong(c->n_item) ||
3411 str->append("]", 1))
3412 return TRUE;
3413 }
3414 }
3415
3416 return str->append("\"", 1);
3417 }
3418
3419
val_str(String * str)3420 String *Item_func_json_search::val_str(String *str)
3421 {
3422 String *js= args[0]->val_json(&tmp_js);
3423 String *s_str= args[2]->val_str(&tmp_path);
3424 json_engine_t je;
3425 json_path_t p, sav_path;
3426 uint n_arg;
3427
3428 if (args[0]->null_value || args[2]->null_value)
3429 goto null_return;
3430
3431 if (parse_one_or_all(this, args[1], &ooa_parsed, ooa_constant, &mode_one))
3432 goto null_return;
3433
3434 n_path_found= 0;
3435 str->set_charset(js->charset());
3436 str->length(0);
3437
3438 for (n_arg=4; n_arg < arg_count; n_arg++)
3439 {
3440 json_path_with_flags *c_path= paths + n_arg - 4;
3441 if (!c_path->parsed)
3442 {
3443 String *s_p= args[n_arg]->val_str(tmp_paths + (n_arg-4));
3444 if (s_p &&
3445 json_path_setup(&c_path->p,s_p->charset(),(const uchar *) s_p->ptr(),
3446 (const uchar *) s_p->ptr() + s_p->length()))
3447 {
3448 report_path_error(s_p, &c_path->p, n_arg);
3449 goto null_return;
3450 }
3451 c_path->parsed= c_path->constant;
3452 }
3453 if (args[n_arg]->null_value)
3454 goto null_return;
3455 }
3456
3457 json_get_path_start(&je, js->charset(),(const uchar *) js->ptr(),
3458 (const uchar *) js->ptr() + js->length(), &p);
3459
3460 while (json_get_path_next(&je, &p) == 0)
3461 {
3462 if (json_value_scalar(&je))
3463 {
3464 if ((arg_count < 5 || path_ok(paths, arg_count - 4, &p, je.value_type)) &&
3465 compare_json_value_wild(&je, s_str) != 0)
3466 {
3467 ++n_path_found;
3468 if (n_path_found == 1)
3469 {
3470 sav_path= p;
3471 sav_path.last_step= sav_path.steps + (p.last_step - p.steps);
3472 }
3473 else
3474 {
3475 if (n_path_found == 2)
3476 {
3477 if (str->append("[", 1) ||
3478 append_json_path(str, &sav_path))
3479 goto js_error;
3480 }
3481 if (str->append(", ", 2) || append_json_path(str, &p))
3482 goto js_error;
3483 }
3484 if (mode_one)
3485 goto end;
3486 }
3487 }
3488 }
3489
3490 if (unlikely(je.s.error))
3491 goto js_error;
3492
3493 end:
3494 if (n_path_found == 0)
3495 goto null_return;
3496 if (n_path_found == 1)
3497 {
3498 if (append_json_path(str, &sav_path))
3499 goto js_error;
3500 }
3501 else
3502 {
3503 if (str->append("]", 1))
3504 goto js_error;
3505 }
3506
3507 null_value= 0;
3508 return str;
3509
3510
3511 js_error:
3512 report_json_error(js, &je, 0);
3513 null_return:
3514 null_value= 1;
3515 return 0;
3516 }
3517
3518
func_name() const3519 const char *Item_func_json_format::func_name() const
3520 {
3521 switch (fmt)
3522 {
3523 case COMPACT:
3524 return "json_compact";
3525 case LOOSE:
3526 return "json_loose";
3527 case DETAILED:
3528 return "json_detailed";
3529 default:
3530 DBUG_ASSERT(0);
3531 };
3532
3533 return "";
3534 }
3535
3536
fix_length_and_dec()3537 bool Item_func_json_format::fix_length_and_dec()
3538 {
3539 decimals= 0;
3540 collation.set(args[0]->collation);
3541 max_length= args[0]->max_length;
3542 maybe_null= 1;
3543 return FALSE;
3544 }
3545
3546
val_str(String * str)3547 String *Item_func_json_format::val_str(String *str)
3548 {
3549 String *js= args[0]->val_json(&tmp_js);
3550 json_engine_t je;
3551 int tab_size= 4;
3552
3553 if ((null_value= args[0]->null_value))
3554 return 0;
3555
3556 if (fmt == DETAILED)
3557 {
3558 if (arg_count > 1)
3559 {
3560 tab_size= (int)args[1]->val_int();
3561 if (args[1]->null_value)
3562 {
3563 null_value= 1;
3564 return 0;
3565 }
3566 }
3567 if (tab_size < 0)
3568 tab_size= 0;
3569 else if (tab_size > TAB_SIZE_LIMIT)
3570 tab_size= TAB_SIZE_LIMIT;
3571 }
3572
3573 json_scan_start(&je, js->charset(), (const uchar *) js->ptr(),
3574 (const uchar *) js->ptr()+js->length());
3575
3576 str->length(0);
3577 str->set_charset(js->charset());
3578 if (json_nice(&je, str, fmt, tab_size))
3579 {
3580 null_value= 1;
3581 report_json_error(js, &je, 0);
3582 return 0;
3583 }
3584
3585 return str;
3586 }
3587
3588
val_json(String * str)3589 String *Item_func_json_format::val_json(String *str)
3590 {
3591 String *js= args[0]->val_json(&tmp_js);
3592 if ((null_value= args[0]->null_value))
3593 return 0;
3594 return js;
3595 }
3596
compare_json_str_basic(Item * j,Item * s)3597 int Arg_comparator::compare_json_str_basic(Item *j, Item *s)
3598 {
3599 String *js,*str;
3600 int c_len;
3601 json_engine_t je;
3602
3603 if ((js= j->val_str(&value1)))
3604 {
3605 json_scan_start(&je, js->charset(), (const uchar *) js->ptr(),
3606 (const uchar *) js->ptr()+js->length());
3607 if (json_read_value(&je))
3608 goto error;
3609 if (je.value_type == JSON_VALUE_STRING)
3610 {
3611 if (value2.realloc_with_extra_if_needed(je.value_len) ||
3612 (c_len= json_unescape(js->charset(), je.value,
3613 je.value + je.value_len,
3614 &my_charset_utf8_general_ci,
3615 (uchar *) value2.ptr(),
3616 (uchar *) (value2.ptr() + je.value_len))) < 0)
3617 goto error;
3618
3619 value2.length(c_len);
3620 js= &value2;
3621 str= &value1;
3622 }
3623 else
3624 {
3625 str= &value2;
3626 }
3627
3628
3629 if ((str= s->val_str(str)))
3630 {
3631 if (set_null)
3632 owner->null_value= 0;
3633 return sortcmp(js, str, compare_collation());
3634 }
3635 }
3636
3637 error:
3638 if (set_null)
3639 owner->null_value= 1;
3640 return -1;
3641 }
3642
3643
compare_e_json_str_basic(Item * j,Item * s)3644 int Arg_comparator::compare_e_json_str_basic(Item *j, Item *s)
3645 {
3646 String *res1,*res2;
3647 json_value_types type;
3648 char *value;
3649 int value_len, c_len;
3650 Item_func_json_extract *e= (Item_func_json_extract *) j;
3651
3652 res1= e->read_json(&value1, &type, &value, &value_len);
3653 res2= s->val_str(&value2);
3654
3655 if (!res1 || !res2)
3656 return MY_TEST(res1 == res2);
3657
3658 if (type == JSON_VALUE_STRING)
3659 {
3660 if (value1.realloc_with_extra_if_needed(value_len) ||
3661 (c_len= json_unescape(value1.charset(), (uchar *) value,
3662 (uchar *) value+value_len,
3663 &my_charset_utf8_general_ci,
3664 (uchar *) value1.ptr(),
3665 (uchar *) (value1.ptr() + value_len))) < 0)
3666 return 1;
3667 value1.length(c_len);
3668 res1= &value1;
3669 }
3670
3671 return MY_TEST(sortcmp(res1, res2, compare_collation()) == 0);
3672 }
3673