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