You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2578 lines
58 KiB

  1. /* Copyright (c) 2016, Monty Program Ab.
  2. This program is free software; you can redistribute it and/or modify
  3. it under the terms of the GNU General Public License as published by
  4. the Free Software Foundation; version 2 of the License.
  5. This program is distributed in the hope that it will be useful,
  6. but WITHOUT ANY WARRANTY; without even the implied warranty of
  7. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  8. GNU General Public License for more details.
  9. You should have received a copy of the GNU General Public License
  10. along with this program; if not, write to the Free Software
  11. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
  12. #include <my_global.h>
  13. #include "sql_priv.h"
  14. #include "sql_class.h"
  15. #include "item.h"
  16. /*
  17. Compare ASCII string against the string with the specified
  18. character set.
  19. Only compares the equality, case insencitive.
  20. */
  21. static bool eq_ascii_string(const CHARSET_INFO *cs,
  22. const char *ascii,
  23. const char *s, uint32 s_len)
  24. {
  25. const char *s_end= s + s_len;
  26. while (*ascii && s < s_end)
  27. {
  28. my_wc_t wc;
  29. int wc_len;
  30. wc_len= cs->cset->mb_wc(cs, &wc, (uchar *) s, (uchar *) s_end);
  31. if (wc_len <= 0 || (wc | 0x20) != (my_wc_t) *ascii)
  32. return 0;
  33. ascii++;
  34. s+= wc_len;
  35. }
  36. return *ascii == 0 && s >= s_end;
  37. }
  38. static bool append_simple(String *s, const char *a, uint a_len)
  39. {
  40. if (!s->realloc_with_extra_if_needed(s->length() + a_len))
  41. {
  42. s->q_append(a, a_len);
  43. return FALSE;
  44. }
  45. return TRUE;
  46. }
  47. static inline bool append_simple(String *s, const uchar *a, uint a_len)
  48. {
  49. return append_simple(s, (const char *) a, a_len);
  50. }
  51. /*
  52. Appends JSON string to the String object taking charsets in
  53. consideration.
  54. static int st_append_json(String *s,
  55. CHARSET_INFO *json_cs, const uchar *js, uint js_len)
  56. {
  57. int str_len= js_len * s->charset()->mbmaxlen;
  58. if (!s->reserve(str_len, 1024) &&
  59. (str_len= json_unescape(json_cs, js, js + js_len,
  60. s->charset(), (uchar *) s->end(), (uchar *) s->end() + str_len)) > 0)
  61. {
  62. s->length(s->length() + str_len);
  63. return 0;
  64. }
  65. return js_len;
  66. }
  67. */
  68. /*
  69. Appends arbitrary String to the JSON string taking charsets in
  70. consideration.
  71. */
  72. static int st_append_escaped(String *s, const String *a)
  73. {
  74. /*
  75. In the worst case one character from the 'a' string
  76. turns into '\uXXXX\uXXXX' which is 12.
  77. */
  78. int str_len= a->length() * 12 * s->charset()->mbmaxlen /
  79. a->charset()->mbminlen;
  80. if (!s->reserve(str_len, 1024) &&
  81. (str_len=
  82. json_escape(a->charset(), (uchar *) a->ptr(), (uchar *)a->end(),
  83. s->charset(),
  84. (uchar *) s->end(), (uchar *)s->end() + str_len)) > 0)
  85. {
  86. s->length(s->length() + str_len);
  87. return 0;
  88. }
  89. return a->length();
  90. }
  91. #define report_json_error(js, je, n_param) \
  92. report_json_error_ex(js, je, func_name(), n_param, \
  93. Sql_condition::WARN_LEVEL_WARN)
  94. void report_json_error_ex(String *js, json_engine_t *je,
  95. const char *fname, int n_param,
  96. Sql_condition::enum_warning_level lv)
  97. {
  98. THD *thd= current_thd;
  99. int position= (const char *) je->s.c_str - js->ptr();
  100. uint code;
  101. n_param++;
  102. switch (je->s.error)
  103. {
  104. case JE_BAD_CHR:
  105. code= ER_JSON_BAD_CHR;
  106. break;
  107. case JE_NOT_JSON_CHR:
  108. code= ER_JSON_NOT_JSON_CHR;
  109. break;
  110. case JE_EOS:
  111. code= ER_JSON_EOS;
  112. break;
  113. case JE_SYN:
  114. case JE_STRING_CONST:
  115. code= ER_JSON_SYNTAX;
  116. break;
  117. case JE_ESCAPING:
  118. code= ER_JSON_ESCAPING;
  119. break;
  120. case JE_DEPTH:
  121. code= ER_JSON_DEPTH;
  122. push_warning_printf(thd, lv, code, ER_THD(thd, code), JSON_DEPTH_LIMIT,
  123. n_param, fname, position);
  124. return;
  125. default:
  126. return;
  127. }
  128. push_warning_printf(thd, lv, code, ER_THD(thd, code),
  129. n_param, fname, position);
  130. }
  131. #define NO_WILDCARD_ALLOWED 1
  132. #define SHOULD_END_WITH_ARRAY 2
  133. #define report_path_error(js, je, n_param) \
  134. report_path_error_ex(js, je, func_name(), n_param,\
  135. Sql_condition::WARN_LEVEL_WARN)
  136. static void report_path_error_ex(String *ps, json_path_t *p,
  137. const char *fname, int n_param,
  138. Sql_condition::enum_warning_level lv)
  139. {
  140. THD *thd= current_thd;
  141. int position= (const char *) p->s.c_str - ps->ptr() + 1;
  142. uint code;
  143. n_param++;
  144. switch (p->s.error)
  145. {
  146. case JE_BAD_CHR:
  147. case JE_NOT_JSON_CHR:
  148. case JE_SYN:
  149. code= ER_JSON_PATH_SYNTAX;
  150. break;
  151. case JE_EOS:
  152. code= ER_JSON_PATH_EOS;
  153. break;
  154. case JE_DEPTH:
  155. code= ER_JSON_PATH_DEPTH;
  156. push_warning_printf(thd, lv, code, ER_THD(thd, code),
  157. JSON_DEPTH_LIMIT, n_param, fname, position);
  158. return;
  159. case NO_WILDCARD_ALLOWED:
  160. code= ER_JSON_PATH_NO_WILDCARD;
  161. break;
  162. default:
  163. return;
  164. }
  165. push_warning_printf(thd, lv, code, ER_THD(thd, code),
  166. n_param, fname, position);
  167. }
  168. /*
  169. Checks if the path has '.*' '[*]' or '**' constructions
  170. and sets the NO_WILDCARD_ALLOWED error if the case.
  171. */
  172. static int path_setup_nwc(json_path_t *p, CHARSET_INFO *i_cs,
  173. const uchar *str, const uchar *end)
  174. {
  175. if (!json_path_setup(p, i_cs, str, end))
  176. {
  177. if ((p->types_used & (JSON_PATH_WILD | JSON_PATH_DOUBLE_WILD)) == 0)
  178. return 0;
  179. p->s.error= NO_WILDCARD_ALLOWED;
  180. }
  181. return 1;
  182. }
  183. longlong Item_func_json_valid::val_int()
  184. {
  185. String *js= args[0]->val_str(&tmp_value);
  186. json_engine_t je;
  187. if ((null_value= args[0]->null_value))
  188. return 0;
  189. json_scan_start(&je, js->charset(), (const uchar *) js->ptr(),
  190. (const uchar *) js->ptr()+js->length());
  191. while (json_scan_next(&je) == 0) {}
  192. return je.s.error == 0;
  193. }
  194. void Item_func_json_exists::fix_length_and_dec()
  195. {
  196. Item_int_func::fix_length_and_dec();
  197. maybe_null= 1;
  198. path.set_constant_flag(args[1]->const_item());
  199. }
  200. longlong Item_func_json_exists::val_int()
  201. {
  202. json_engine_t je;
  203. uint array_counters[JSON_DEPTH_LIMIT];
  204. String *js= args[0]->val_str(&tmp_js);
  205. if (!path.parsed)
  206. {
  207. String *s_p= args[1]->val_str(&tmp_path);
  208. if (s_p &&
  209. json_path_setup(&path.p, s_p->charset(), (const uchar *) s_p->ptr(),
  210. (const uchar *) s_p->ptr() + s_p->length()))
  211. goto err_return;
  212. path.parsed= path.constant;
  213. }
  214. if ((null_value= args[0]->null_value || args[1]->null_value))
  215. {
  216. null_value= 1;
  217. return 0;
  218. }
  219. null_value= 0;
  220. json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
  221. (const uchar *) js->ptr() + js->length());
  222. path.cur_step= path.p.steps;
  223. if (json_find_path(&je, &path.p, &path.cur_step, array_counters))
  224. {
  225. if (je.s.error)
  226. goto err_return;
  227. return 0;
  228. }
  229. return 1;
  230. err_return:
  231. null_value= 1;
  232. return 0;
  233. }
  234. void Item_func_json_value::fix_length_and_dec()
  235. {
  236. collation.set(args[0]->collation);
  237. max_length= args[0]->max_length;
  238. path.set_constant_flag(args[1]->const_item());
  239. }
  240. /*
  241. Returns NULL, not an error if the found value
  242. is not a scalar.
  243. */
  244. String *Item_func_json_value::val_str(String *str)
  245. {
  246. json_engine_t je;
  247. String *js= args[0]->val_str(&tmp_js);
  248. int error= 0;
  249. uint array_counters[JSON_DEPTH_LIMIT];
  250. if (!path.parsed)
  251. {
  252. String *s_p= args[1]->val_str(&tmp_path);
  253. if (s_p &&
  254. json_path_setup(&path.p, s_p->charset(), (const uchar *) s_p->ptr(),
  255. (const uchar *) s_p->ptr() + s_p->length()))
  256. goto err_return;
  257. path.parsed= path.constant;
  258. }
  259. if ((null_value= args[0]->null_value || args[1]->null_value))
  260. return NULL;
  261. json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
  262. (const uchar *) js->ptr() + js->length());
  263. path.cur_step= path.p.steps;
  264. continue_search:
  265. if (json_find_path(&je, &path.p, &path.cur_step, array_counters))
  266. {
  267. if (je.s.error)
  268. goto err_return;
  269. null_value= 1;
  270. return 0;
  271. }
  272. if (json_read_value(&je))
  273. goto err_return;
  274. if (check_and_get_value(&je, str, &error))
  275. {
  276. if (error)
  277. goto err_return;
  278. goto continue_search;
  279. }
  280. return str;
  281. err_return:
  282. null_value= 1;
  283. return 0;
  284. }
  285. bool Item_func_json_value::check_and_get_value(json_engine_t *je, String *res,
  286. int *error)
  287. {
  288. if (!json_value_scalar(je))
  289. {
  290. /* We only look for scalar values! */
  291. if (json_skip_level(je) || json_scan_next(je))
  292. *error= 1;
  293. return true;
  294. }
  295. res->set((const char *) je->value, je->value_len, je->s.cs);
  296. return false;
  297. }
  298. bool Item_func_json_query::check_and_get_value(json_engine_t *je, String *res,
  299. int *error)
  300. {
  301. const uchar *value;
  302. if (json_value_scalar(je))
  303. {
  304. /* We skip scalar values. */
  305. if (json_scan_next(je))
  306. *error= 1;
  307. return true;
  308. }
  309. value= je->value;
  310. if (json_skip_level(je))
  311. {
  312. *error= 1;
  313. return true;
  314. }
  315. res->set((const char *) je->value, je->s.c_str - value, je->s.cs);
  316. return false;
  317. }
  318. void Item_func_json_quote::fix_length_and_dec()
  319. {
  320. collation.set(&my_charset_utf8mb4_bin);
  321. /*
  322. Odd but realistic worst case is when all characters
  323. of the argument turn into '\uXXXX\uXXXX', which is 12.
  324. */
  325. max_length= args[0]->max_length * 12 + 2;
  326. }
  327. String *Item_func_json_quote::val_str(String *str)
  328. {
  329. String *s= args[0]->val_str(&tmp_s);
  330. if ((null_value= (args[0]->null_value ||
  331. args[0]->result_type() != STRING_RESULT)))
  332. return NULL;
  333. str->length(0);
  334. str->set_charset(&my_charset_utf8mb4_bin);
  335. if (str->append("\"", 1) ||
  336. st_append_escaped(str, s) ||
  337. str->append("\"", 1))
  338. {
  339. /* Report an error. */
  340. null_value= 1;
  341. return 0;
  342. }
  343. return str;
  344. }
  345. void Item_func_json_unquote::fix_length_and_dec()
  346. {
  347. collation.set(&my_charset_utf8_general_ci);
  348. max_length= args[0]->max_length;
  349. }
  350. String *Item_func_json_unquote::val_str(String *str)
  351. {
  352. String *js= args[0]->val_str(&tmp_s);
  353. json_engine_t je;
  354. int c_len;
  355. if ((null_value= args[0]->null_value))
  356. return NULL;
  357. json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
  358. (const uchar *) js->ptr() + js->length());
  359. je.value_type= (enum json_value_types) -1; /* To report errors right. */
  360. if (json_read_value(&je))
  361. goto error;
  362. if (je.value_type != JSON_VALUE_STRING)
  363. return js;
  364. str->length(0);
  365. str->set_charset(&my_charset_utf8_general_ci);
  366. if (str->realloc_with_extra_if_needed(je.value_len) ||
  367. (c_len= json_unescape(js->charset(),
  368. je.value, je.value + je.value_len,
  369. &my_charset_utf8_general_ci,
  370. (uchar *) str->ptr(), (uchar *) (str->ptr() + je.value_len))) < 0)
  371. goto error;
  372. str->length(c_len);
  373. return str;
  374. error:
  375. if (je.value_type == JSON_VALUE_STRING)
  376. report_json_error(js, &je, 0);
  377. /* We just return the argument's value in the case of error. */
  378. return js;
  379. }
  380. static int alloc_tmp_paths(THD *thd, uint n_paths,
  381. json_path_with_flags **paths,String **tmp_paths)
  382. {
  383. if (n_paths > 0)
  384. {
  385. *paths= (json_path_with_flags *) alloc_root(thd->mem_root,
  386. sizeof(json_path_with_flags) * n_paths);
  387. *tmp_paths= (String *) alloc_root(thd->mem_root, sizeof(String) * n_paths);
  388. if (*paths == 0 || *tmp_paths == 0)
  389. return 1;
  390. bzero(*tmp_paths, sizeof(String) * n_paths);
  391. return 0;
  392. }
  393. /* n_paths == 0 */
  394. *paths= 0;
  395. *tmp_paths= 0;
  396. return 0;
  397. }
  398. static void mark_constant_paths(json_path_with_flags *p,
  399. Item** args, uint n_args)
  400. {
  401. uint n;
  402. for (n= 0; n < n_args; n++)
  403. p[n].set_constant_flag(args[n]->const_item());
  404. }
  405. bool Item_json_str_multipath::fix_fields(THD *thd, Item **ref)
  406. {
  407. return alloc_tmp_paths(thd, get_n_paths(), &paths, &tmp_paths) ||
  408. Item_str_func::fix_fields(thd, ref);
  409. }
  410. void Item_json_str_multipath::cleanup()
  411. {
  412. if (tmp_paths)
  413. {
  414. for (uint i= get_n_paths(); i>0; i--)
  415. tmp_paths[i-1].free();
  416. tmp_paths= 0;
  417. }
  418. Item_str_func::cleanup();
  419. }
  420. void Item_func_json_extract::fix_length_and_dec()
  421. {
  422. collation.set(args[0]->collation);
  423. max_length= args[0]->max_length * (arg_count - 1);
  424. mark_constant_paths(paths, args+1, arg_count-1);
  425. }
  426. String *Item_func_json_extract::val_str(String *str)
  427. {
  428. String *js= args[0]->val_str(&tmp_js);
  429. json_engine_t je;
  430. bool multiple_values_found= FALSE;
  431. const uchar *value;
  432. const char *first_value= NULL;
  433. uint n_arg, v_len, first_len;
  434. uint array_counters[JSON_DEPTH_LIMIT];
  435. if ((null_value= args[0]->null_value))
  436. return 0;
  437. str->set_charset(js->charset());
  438. str->length(0);
  439. for (n_arg=1; n_arg < arg_count; n_arg++)
  440. {
  441. json_path_with_flags *c_path= paths + n_arg - 1;
  442. if (!c_path->parsed)
  443. {
  444. String *s_p= args[n_arg]->val_str(tmp_paths + (n_arg-1));
  445. if (s_p &&
  446. json_path_setup(&c_path->p,s_p->charset(),(const uchar *) s_p->ptr(),
  447. (const uchar *) s_p->ptr() + s_p->length()))
  448. goto return_null;
  449. c_path->parsed= c_path->constant;
  450. }
  451. if (args[n_arg]->null_value)
  452. goto return_null;
  453. json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
  454. (const uchar *) js->ptr() + js->length());
  455. c_path->cur_step= c_path->p.steps;
  456. while (!json_find_path(&je, &c_path->p, &c_path->cur_step, array_counters))
  457. {
  458. if (json_read_value(&je))
  459. goto error;
  460. value= je.value_begin;
  461. if (json_value_scalar(&je))
  462. v_len= je.value_end - value;
  463. else
  464. {
  465. if (json_skip_level(&je))
  466. goto error;
  467. v_len= je.s.c_str - value;
  468. }
  469. if (!multiple_values_found)
  470. {
  471. if (first_value == NULL)
  472. {
  473. /*
  474. Just remember the first value as we don't know yet
  475. if we need to create an array out of it or not.
  476. */
  477. first_value= (const char *) value;
  478. first_len= v_len;
  479. }
  480. else
  481. {
  482. multiple_values_found= TRUE; /* We have to make an JSON array. */
  483. if (str->append("[", 1) ||
  484. str->append(first_value, first_len))
  485. goto error; /* Out of memory. */
  486. }
  487. }
  488. if (multiple_values_found &&
  489. (str->append(", ", 2) ||
  490. str->append((const char *) value, v_len)))
  491. goto error; /* Out of memory. */
  492. if (json_scan_next(&je))
  493. break;
  494. }
  495. }
  496. if (je.s.error)
  497. goto error;
  498. if (first_value == NULL)
  499. {
  500. /* Nothing was found. */
  501. goto return_null;
  502. }
  503. if (multiple_values_found ?
  504. str->append("]") :
  505. str->append(first_value, first_len))
  506. goto error; /* Out of memory. */
  507. return str;
  508. error:
  509. report_json_error(js, &je, 0);
  510. return_null:
  511. /* TODO: launch error messages. */
  512. null_value= 1;
  513. return 0;
  514. }
  515. longlong Item_func_json_extract::val_int()
  516. {
  517. String *js= args[0]->val_str(&tmp_js);
  518. json_engine_t je;
  519. uint n_arg;
  520. uint array_counters[JSON_DEPTH_LIMIT];
  521. if ((null_value= args[0]->null_value))
  522. return 0;
  523. for (n_arg=1; n_arg < arg_count; n_arg++)
  524. {
  525. json_path_with_flags *c_path= paths + n_arg - 1;
  526. if (!c_path->parsed)
  527. {
  528. String *s_p= args[n_arg]->val_str(tmp_paths+(n_arg-1));
  529. if (s_p &&
  530. json_path_setup(&c_path->p,s_p->charset(),(const uchar *) s_p->ptr(),
  531. (const uchar *) s_p->ptr() + s_p->length()))
  532. goto error;
  533. c_path->parsed= c_path->constant;
  534. }
  535. if (args[n_arg]->null_value)
  536. goto error;
  537. json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
  538. (const uchar *) js->ptr() + js->length());
  539. c_path->cur_step= c_path->p.steps;
  540. if (json_find_path(&je, &c_path->p, &c_path->cur_step, array_counters))
  541. {
  542. /* Path wasn't found. */
  543. if (je.s.error)
  544. goto error;
  545. continue;
  546. }
  547. if (json_read_value(&je))
  548. goto error;
  549. if (json_value_scalar(&je))
  550. {
  551. int err;
  552. char *v_end= (char *) je.value_end;
  553. return (je.s.cs->cset->strtoll10)(je.s.cs, (const char *) je.value_begin,
  554. &v_end, &err);
  555. }
  556. else
  557. break;
  558. }
  559. /* Nothing was found. */
  560. null_value= 1;
  561. return 0;
  562. error:
  563. /* TODO: launch error messages. */
  564. null_value= 1;
  565. return 0;
  566. }
  567. void Item_func_json_contains::fix_length_and_dec()
  568. {
  569. a2_constant= args[1]->const_item();
  570. a2_parsed= FALSE;
  571. if (arg_count > 2)
  572. path.set_constant_flag(args[2]->const_item());
  573. Item_int_func::fix_length_and_dec();
  574. }
  575. static int find_key_in_object(json_engine_t *j, json_string_t *key)
  576. {
  577. const uchar *c_str= key->c_str;
  578. while (json_scan_next(j) == 0 && j->state != JST_OBJ_END)
  579. {
  580. DBUG_ASSERT(j->state == JST_KEY);
  581. if (json_key_matches(j, key))
  582. return TRUE;
  583. if (json_skip_key(j))
  584. return FALSE;
  585. key->c_str= c_str;
  586. }
  587. return FALSE;
  588. }
  589. static int check_contains(json_engine_t *js, json_engine_t *value)
  590. {
  591. json_engine_t loc_js;
  592. bool set_js;
  593. switch (js->value_type)
  594. {
  595. case JSON_VALUE_OBJECT:
  596. {
  597. json_string_t key_name;
  598. if (value->value_type != JSON_VALUE_OBJECT)
  599. return FALSE;
  600. loc_js= *js;
  601. set_js= FALSE;
  602. json_string_set_cs(&key_name, value->s.cs);
  603. while (json_scan_next(value) == 0 && value->state != JST_OBJ_END)
  604. {
  605. const uchar *k_start, *k_end;
  606. DBUG_ASSERT(value->state == JST_KEY);
  607. k_start= value->s.c_str;
  608. while (json_read_keyname_chr(value) == 0)
  609. k_end= value->s.c_str;
  610. if (value->s.error || json_read_value(value))
  611. return FALSE;
  612. if (set_js)
  613. *js= loc_js;
  614. else
  615. set_js= TRUE;
  616. json_string_set_str(&key_name, k_start, k_end);
  617. if (!find_key_in_object(js, &key_name) ||
  618. json_read_value(js) ||
  619. !check_contains(js, value))
  620. return FALSE;
  621. }
  622. return value->state == JST_OBJ_END && !json_skip_level(js);
  623. }
  624. case JSON_VALUE_ARRAY:
  625. if (value->value_type != JSON_VALUE_ARRAY)
  626. {
  627. while (json_scan_next(js) == 0 && js->state != JST_ARRAY_END)
  628. {
  629. json_level_t c_level;
  630. DBUG_ASSERT(js->state == JST_VALUE);
  631. if (json_read_value(js))
  632. return FALSE;
  633. c_level= json_value_scalar(js) ? NULL : json_get_level(js);
  634. if (check_contains(js, value))
  635. {
  636. if (json_skip_level(js))
  637. return FALSE;
  638. return TRUE;
  639. }
  640. if (value->s.error || js->s.error ||
  641. (c_level && json_skip_to_level(js, c_level)))
  642. return FALSE;
  643. }
  644. return FALSE;
  645. }
  646. /* else */
  647. loc_js= *js;
  648. set_js= FALSE;
  649. while (json_scan_next(value) == 0 && value->state != JST_ARRAY_END)
  650. {
  651. DBUG_ASSERT(value->state == JST_VALUE);
  652. if (json_read_value(value))
  653. return FALSE;
  654. if (set_js)
  655. *js= loc_js;
  656. else
  657. set_js= TRUE;
  658. if (!check_contains(js, value))
  659. return FALSE;
  660. }
  661. return value->state == JST_ARRAY_END;
  662. case JSON_VALUE_STRING:
  663. if (value->value_type != JSON_VALUE_STRING)
  664. return FALSE;
  665. /*
  666. TODO: make proper json-json comparison here that takes excapint
  667. into account.
  668. */
  669. return value->value_len == js->value_len &&
  670. memcmp(value->value, js->value, value->value_len) == 0;
  671. case JSON_VALUE_NUMBER:
  672. if (value->value_type == JSON_VALUE_NUMBER)
  673. {
  674. double d_j, d_v;
  675. char *end;
  676. int err;
  677. d_j= my_strntod(js->s.cs, (char *) js->value, js->value_len,
  678. &end, &err);;
  679. d_v= my_strntod(value->s.cs, (char *) value->value, value->value_len,
  680. &end, &err);;
  681. return (fabs(d_j - d_v) < 1e-12);
  682. }
  683. else
  684. return FALSE;
  685. default:
  686. break;
  687. }
  688. /*
  689. We have these not mentioned in the 'switch' above:
  690. case JSON_VALUE_TRUE:
  691. case JSON_VALUE_FALSE:
  692. case JSON_VALUE_NULL:
  693. */
  694. return value->value_type == js->value_type;
  695. }
  696. longlong Item_func_json_contains::val_int()
  697. {
  698. String *js= args[0]->val_str(&tmp_js);
  699. json_engine_t je, ve;
  700. int result;
  701. if ((null_value= args[0]->null_value))
  702. return 0;
  703. if (!a2_parsed)
  704. {
  705. val= args[1]->val_str(&tmp_val);
  706. a2_parsed= a2_constant;
  707. }
  708. if (val == 0)
  709. {
  710. null_value= 1;
  711. return 0;
  712. }
  713. json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
  714. (const uchar *) js->ptr() + js->length());
  715. if (arg_count>2) /* Path specified. */
  716. {
  717. uint array_counters[JSON_DEPTH_LIMIT];
  718. if (!path.parsed)
  719. {
  720. String *s_p= args[2]->val_str(&tmp_path);
  721. if (s_p &&
  722. path_setup_nwc(&path.p,s_p->charset(),(const uchar *) s_p->ptr(),
  723. (const uchar *) s_p->end()))
  724. {
  725. report_path_error(s_p, &path.p, 2);
  726. goto return_null;
  727. }
  728. path.parsed= path.constant;
  729. }
  730. if (args[2]->null_value)
  731. goto return_null;
  732. path.cur_step= path.p.steps;
  733. if (json_find_path(&je, &path.p, &path.cur_step, array_counters))
  734. {
  735. if (je.s.error)
  736. {
  737. ve.s.error= 0;
  738. goto error;
  739. }
  740. return FALSE;
  741. }
  742. }
  743. json_scan_start(&ve, val->charset(),(const uchar *) val->ptr(),
  744. (const uchar *) val->end());
  745. if (json_read_value(&je) || json_read_value(&ve))
  746. goto error;
  747. result= check_contains(&je, &ve);
  748. if (je.s.error || ve.s.error)
  749. goto error;
  750. return result;
  751. error:
  752. if (je.s.error)
  753. report_json_error(js, &je, 0);
  754. if (ve.s.error)
  755. report_json_error(val, &ve, 1);
  756. return_null:
  757. null_value= 1;
  758. return 0;
  759. }
  760. bool Item_func_json_contains_path::fix_fields(THD *thd, Item **ref)
  761. {
  762. return alloc_tmp_paths(thd, arg_count-2, &paths, &tmp_paths) ||
  763. Item_int_func::fix_fields(thd, ref);
  764. }
  765. void Item_func_json_contains_path::fix_length_and_dec()
  766. {
  767. ooa_constant= args[1]->const_item();
  768. ooa_parsed= FALSE;
  769. mark_constant_paths(paths, args+2, arg_count-2);
  770. Item_int_func::fix_length_and_dec();
  771. }
  772. void Item_func_json_contains_path::cleanup()
  773. {
  774. if (tmp_paths)
  775. {
  776. for (uint i= arg_count-2; i>0; i--)
  777. tmp_paths[i-1].free();
  778. tmp_paths= 0;
  779. }
  780. Item_int_func::cleanup();
  781. }
  782. static int parse_one_or_all(const Item_func *f, Item *ooa_arg,
  783. bool *ooa_parsed, bool ooa_constant, bool *mode_one)
  784. {
  785. if (!*ooa_parsed)
  786. {
  787. char buff[20];
  788. String *res, tmp(buff, sizeof(buff), &my_charset_bin);
  789. if ((res= ooa_arg->val_str(&tmp)) == NULL)
  790. return TRUE;
  791. *mode_one=eq_ascii_string(res->charset(), "one",
  792. res->ptr(), res->length());
  793. if (!*mode_one)
  794. {
  795. if (!eq_ascii_string(res->charset(), "all", res->ptr(), res->length()))
  796. {
  797. THD *thd= current_thd;
  798. push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
  799. ER_JSON_ONE_OR_ALL, ER_THD(thd, ER_JSON_ONE_OR_ALL),
  800. f->func_name());
  801. *mode_one= TRUE;
  802. return TRUE;
  803. }
  804. }
  805. *ooa_parsed= ooa_constant;
  806. }
  807. return FALSE;
  808. }
  809. longlong Item_func_json_contains_path::val_int()
  810. {
  811. String *js= args[0]->val_str(&tmp_js);
  812. json_engine_t je;
  813. uint n_arg;
  814. longlong result;
  815. if ((null_value= args[0]->null_value))
  816. return 0;
  817. if (parse_one_or_all(this, args[1], &ooa_parsed, ooa_constant, &mode_one))
  818. goto return_null;
  819. result= !mode_one;
  820. for (n_arg=2; n_arg < arg_count; n_arg++)
  821. {
  822. uint array_counters[JSON_DEPTH_LIMIT];
  823. json_path_with_flags *c_path= paths + n_arg - 2;
  824. if (!c_path->parsed)
  825. {
  826. String *s_p= args[n_arg]->val_str(tmp_paths+(n_arg-2));
  827. if (s_p &&
  828. json_path_setup(&c_path->p,s_p->charset(),(const uchar *) s_p->ptr(),
  829. (const uchar *) s_p->ptr() + s_p->length()))
  830. {
  831. report_path_error(s_p, &c_path->p, n_arg-2);
  832. goto return_null;
  833. }
  834. c_path->parsed= c_path->constant;
  835. }
  836. if (args[n_arg]->null_value)
  837. goto return_null;
  838. json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
  839. (const uchar *) js->ptr() + js->length());
  840. c_path->cur_step= c_path->p.steps;
  841. if (json_find_path(&je, &c_path->p, &c_path->cur_step, array_counters))
  842. {
  843. /* Path wasn't found. */
  844. if (je.s.error)
  845. goto js_error;
  846. if (!mode_one)
  847. {
  848. result= 0;
  849. break;
  850. }
  851. }
  852. else if (mode_one)
  853. {
  854. result= 1;
  855. break;
  856. }
  857. }
  858. return result;
  859. js_error:
  860. report_json_error(js, &je, 0);
  861. return_null:
  862. null_value= 1;
  863. return 0;
  864. }
  865. static int append_json_value(String *str, Item *item, String *tmp_val)
  866. {
  867. if (item->is_bool_type())
  868. {
  869. longlong v_int= item->val_int();
  870. const char *t_f;
  871. int t_f_len;
  872. if (item->null_value)
  873. goto append_null;
  874. if (v_int)
  875. {
  876. t_f= "true";
  877. t_f_len= 4;
  878. }
  879. else
  880. {
  881. t_f= "false";
  882. t_f_len= 5;
  883. }
  884. return str->append(t_f, t_f_len);
  885. }
  886. {
  887. String *sv= item->val_str(tmp_val);
  888. if (item->null_value)
  889. goto append_null;
  890. if (item->is_json_type())
  891. return str->append(sv->ptr(), sv->length());
  892. if (item->result_type() == STRING_RESULT)
  893. {
  894. return str->append("\"", 1) ||
  895. st_append_escaped(str, sv) ||
  896. str->append("\"", 1);
  897. }
  898. return st_append_escaped(str, sv);
  899. }
  900. append_null:
  901. return str->append("null", 4);
  902. }
  903. static int append_json_keyname(String *str, Item *item, String *tmp_val)
  904. {
  905. String *sv= item->val_str(tmp_val);
  906. if (item->null_value)
  907. goto append_null;
  908. return str->append("\"", 1) ||
  909. st_append_escaped(str, sv) ||
  910. str->append("\": ", 3);
  911. append_null:
  912. return str->append("\"\": ", 4);
  913. }
  914. void Item_func_json_array::fix_length_and_dec()
  915. {
  916. ulonglong char_length= 2;
  917. uint n_arg;
  918. if (arg_count == 0)
  919. {
  920. collation.set(&my_charset_utf8_general_ci);
  921. tmp_val.set_charset(&my_charset_utf8_general_ci);
  922. max_length= 2;
  923. return;
  924. }
  925. if (agg_arg_charsets_for_string_result(collation, args, arg_count))
  926. return;
  927. for (n_arg=0 ; n_arg < arg_count ; n_arg++)
  928. char_length+= args[n_arg]->max_char_length() + 4;
  929. fix_char_length_ulonglong(char_length);
  930. tmp_val.set_charset(collation.collation);
  931. }
  932. String *Item_func_json_array::val_str(String *str)
  933. {
  934. DBUG_ASSERT(fixed == 1);
  935. uint n_arg;
  936. str->length(0);
  937. if (str->append("[", 1) ||
  938. ((arg_count > 0) && append_json_value(str, args[0], &tmp_val)))
  939. goto err_return;
  940. for (n_arg=1; n_arg < arg_count; n_arg++)
  941. {
  942. if (str->append(", ", 2) ||
  943. append_json_value(str, args[n_arg], &tmp_val))
  944. goto err_return;
  945. }
  946. if (str->append("]", 1))
  947. goto err_return;
  948. return str;
  949. err_return:
  950. /*TODO: Launch out of memory error. */
  951. null_value= 1;
  952. return NULL;
  953. }
  954. void Item_func_json_array_append::fix_length_and_dec()
  955. {
  956. uint n_arg;
  957. ulonglong char_length;
  958. collation.set(args[0]->collation);
  959. char_length= args[0]->max_char_length();
  960. for (n_arg= 1; n_arg < arg_count; n_arg+= 2)
  961. {
  962. paths[n_arg/2].set_constant_flag(args[n_arg]->const_item());
  963. char_length+= args[n_arg/2+1]->max_char_length() + 4;
  964. }
  965. fix_char_length_ulonglong(char_length);
  966. }
  967. String *Item_func_json_array_append::val_str(String *str)
  968. {
  969. json_engine_t je;
  970. String *js= args[0]->val_str(&tmp_js);
  971. uint n_arg, n_path, str_rest_len;
  972. const uchar *ar_end;
  973. DBUG_ASSERT(fixed == 1);
  974. if ((null_value= args[0]->null_value))
  975. return 0;
  976. for (n_arg=1, n_path=0; n_arg < arg_count; n_arg+=2, n_path++)
  977. {
  978. uint array_counters[JSON_DEPTH_LIMIT];
  979. json_path_with_flags *c_path= paths + n_path;
  980. if (!c_path->parsed)
  981. {
  982. String *s_p= args[n_arg]->val_str(tmp_paths+n_path);
  983. if (s_p &&
  984. path_setup_nwc(&c_path->p,s_p->charset(),(const uchar *) s_p->ptr(),
  985. (const uchar *) s_p->ptr() + s_p->length()))
  986. {
  987. report_path_error(s_p, &c_path->p, n_arg);
  988. goto return_null;
  989. }
  990. c_path->parsed= c_path->constant;
  991. }
  992. if (args[n_arg]->null_value)
  993. goto return_null;
  994. json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
  995. (const uchar *) js->ptr() + js->length());
  996. c_path->cur_step= c_path->p.steps;
  997. if (json_find_path(&je, &c_path->p, &c_path->cur_step, array_counters))
  998. {
  999. if (je.s.error)
  1000. goto js_error;
  1001. goto return_null;
  1002. }
  1003. if (json_read_value(&je))
  1004. goto js_error;
  1005. str->length(0);
  1006. str->set_charset(js->charset());
  1007. if (str->reserve(js->length() + 8, 1024))
  1008. goto return_null; /* Out of memory. */
  1009. if (je.value_type == JSON_VALUE_ARRAY)
  1010. {
  1011. if (json_skip_level(&je))
  1012. goto js_error;
  1013. ar_end= je.s.c_str - je.sav_c_len;
  1014. str_rest_len= js->length() - (ar_end - (const uchar *) js->ptr());
  1015. str->q_append(js->ptr(), ar_end-(const uchar *) js->ptr());
  1016. str->append(", ", 2);
  1017. if (append_json_value(str, args[n_arg+1], &tmp_val))
  1018. goto return_null; /* Out of memory. */
  1019. if (str->reserve(str_rest_len, 1024))
  1020. goto return_null; /* Out of memory. */
  1021. str->q_append((const char *) ar_end, str_rest_len);
  1022. }
  1023. else
  1024. {
  1025. const uchar *c_from, *c_to;
  1026. /* Wrap as an array. */
  1027. str->q_append(js->ptr(), (const char *) je.value_begin - js->ptr());
  1028. c_from= je.value_begin;
  1029. if (je.value_type == JSON_VALUE_OBJECT)
  1030. {
  1031. if (json_skip_level(&je))
  1032. goto js_error;
  1033. c_to= je.s.c_str;
  1034. }
  1035. else
  1036. c_to= je.value_end;
  1037. if (str->append("[", 1) ||
  1038. str->append((const char *) c_from, c_to - c_from) ||
  1039. str->append(", ", 2) ||
  1040. append_json_value(str, args[n_arg+1], &tmp_val) ||
  1041. str->append("]", 1) ||
  1042. str->append((const char *) je.s.c_str,
  1043. js->end() - (const char *) je.s.c_str))
  1044. goto return_null; /* Out of memory. */
  1045. }
  1046. {
  1047. /* Swap str and js. */
  1048. if (str == &tmp_js)
  1049. {
  1050. str= js;
  1051. js= &tmp_js;
  1052. }
  1053. else
  1054. {
  1055. js= str;
  1056. str= &tmp_js;
  1057. }
  1058. }
  1059. }
  1060. return js;
  1061. js_error:
  1062. report_json_error(js, &je, 0);
  1063. return_null:
  1064. null_value= 1;
  1065. return 0;
  1066. }
  1067. String *Item_func_json_array_insert::val_str(String *str)
  1068. {
  1069. json_engine_t je;
  1070. String *js= args[0]->val_str(&tmp_js);
  1071. uint n_arg, n_path;
  1072. DBUG_ASSERT(fixed == 1);
  1073. if ((null_value= args[0]->null_value))
  1074. return 0;
  1075. for (n_arg=1, n_path=0; n_arg < arg_count; n_arg+=2, n_path++)
  1076. {
  1077. uint array_counters[JSON_DEPTH_LIMIT];
  1078. json_path_with_flags *c_path= paths + n_path;
  1079. const char *item_pos;
  1080. uint n_item;
  1081. if (!c_path->parsed)
  1082. {
  1083. String *s_p= args[n_arg]->val_str(tmp_paths+n_path);
  1084. if (s_p &&
  1085. (path_setup_nwc(&c_path->p,s_p->charset(),(const uchar *) s_p->ptr(),
  1086. (const uchar *) s_p->ptr() + s_p->length()) ||
  1087. c_path->p.last_step - 1 < c_path->p.steps ||
  1088. c_path->p.last_step->type != JSON_PATH_ARRAY))
  1089. {
  1090. if (c_path->p.s.error == 0)
  1091. c_path->p.s.error= SHOULD_END_WITH_ARRAY;
  1092. report_path_error(s_p, &c_path->p, n_arg);
  1093. goto return_null;
  1094. }
  1095. c_path->parsed= c_path->constant;
  1096. c_path->p.last_step--;
  1097. }
  1098. if (args[n_arg]->null_value)
  1099. goto return_null;
  1100. json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
  1101. (const uchar *) js->ptr() + js->length());
  1102. c_path->cur_step= c_path->p.steps;
  1103. if (json_find_path(&je, &c_path->p, &c_path->cur_step, array_counters))
  1104. {
  1105. if (je.s.error)
  1106. goto js_error;
  1107. /* Can't find the array to insert. */
  1108. continue;
  1109. }
  1110. if (json_read_value(&je))
  1111. goto js_error;
  1112. if (je.value_type != JSON_VALUE_ARRAY)
  1113. {
  1114. /* Must be an array. */
  1115. continue;
  1116. }
  1117. item_pos= 0;
  1118. n_item= 0;
  1119. while (json_scan_next(&je) == 0 && je.state != JST_ARRAY_END)
  1120. {
  1121. DBUG_ASSERT(je.state == JST_VALUE);
  1122. if (n_item == c_path->p.last_step[1].n_item)
  1123. {
  1124. item_pos= (const char *) je.s.c_str;
  1125. break;
  1126. }
  1127. n_item++;
  1128. if (json_read_value(&je) ||
  1129. (!json_value_scalar(&je) && json_skip_level(&je)))
  1130. goto js_error;
  1131. }
  1132. if (je.s.error)
  1133. goto js_error;
  1134. str->length(0);
  1135. str->set_charset(js->charset());
  1136. if (item_pos)
  1137. {
  1138. if (append_simple(str, js->ptr(), item_pos - js->ptr()) ||
  1139. (n_item > 0 && str->append(" ", 1)) ||
  1140. append_json_value(str, args[n_arg+1], &tmp_val) ||
  1141. str->append(",", 1) ||
  1142. (n_item == 0 && str->append(" ", 1)) ||
  1143. append_simple(str, item_pos, js->end() - item_pos))
  1144. goto return_null; /* Out of memory. */
  1145. }
  1146. else
  1147. {
  1148. /* Insert position wasn't found - append to the array. */
  1149. DBUG_ASSERT(je.state == JST_ARRAY_END);
  1150. item_pos= (const char *) (je.s.c_str - je.sav_c_len);
  1151. if (append_simple(str, js->ptr(), item_pos - js->ptr()) ||
  1152. (n_item > 0 && str->append(", ", 2)) ||
  1153. append_json_value(str, args[n_arg+1], &tmp_val) ||
  1154. append_simple(str, item_pos, js->end() - item_pos))
  1155. goto return_null; /* Out of memory. */
  1156. }
  1157. {
  1158. /* Swap str and js. */
  1159. if (str == &tmp_js)
  1160. {
  1161. str= js;
  1162. js= &tmp_js;
  1163. }
  1164. else
  1165. {
  1166. js= str;
  1167. str= &tmp_js;
  1168. }
  1169. }
  1170. }
  1171. return js;
  1172. js_error:
  1173. report_json_error(js, &je, 0);
  1174. return_null:
  1175. null_value= 1;
  1176. return 0;
  1177. }
  1178. String *Item_func_json_object::val_str(String *str)
  1179. {
  1180. DBUG_ASSERT(fixed == 1);
  1181. uint n_arg;
  1182. str->length(0);
  1183. if (str->append("{", 1) ||
  1184. (arg_count > 0 &&
  1185. (append_json_keyname(str, args[0], &tmp_val) ||
  1186. append_json_value(str, args[1], &tmp_val))))
  1187. goto err_return;
  1188. for (n_arg=2; n_arg < arg_count; n_arg+=2)
  1189. {
  1190. if (str->append(", ", 2) ||
  1191. append_json_keyname(str, args[n_arg], &tmp_val) ||
  1192. append_json_value(str, args[n_arg+1], &tmp_val))
  1193. goto err_return;
  1194. }
  1195. if (str->append("}", 1))
  1196. goto err_return;
  1197. return str;
  1198. err_return:
  1199. /*TODO: Launch out of memory error. */
  1200. null_value= 1;
  1201. return NULL;
  1202. }
  1203. String *Item_func_json_merge::val_str(String *str)
  1204. {
  1205. DBUG_ASSERT(fixed == 1);
  1206. json_engine_t je1, je2;
  1207. String *js1= args[0]->val_str(&tmp_js1), *js2;
  1208. uint n_arg;
  1209. if (args[0]->null_value)
  1210. goto null_return;
  1211. for (n_arg=1; n_arg < arg_count; n_arg++)
  1212. {
  1213. js2= args[n_arg]->val_str(&tmp_js2);
  1214. if (args[n_arg]->null_value)
  1215. goto null_return;
  1216. json_scan_start(&je1, js1->charset(),(const uchar *) js1->ptr(),
  1217. (const uchar *) js1->ptr() + js1->length());
  1218. json_scan_start(&je2, js2->charset(),(const uchar *) js2->ptr(),
  1219. (const uchar *) js2->ptr() + js2->length());
  1220. if (json_read_value(&je1) || json_read_value(&je2))
  1221. goto error_return;
  1222. str->length(0);
  1223. if (je1.value_type == JSON_VALUE_OBJECT &&
  1224. je2.value_type == JSON_VALUE_OBJECT)
  1225. {
  1226. /* Wrap as a single objects. */
  1227. if (json_skip_level(&je1))
  1228. goto error_return;
  1229. if (str->append(js1->ptr(),
  1230. ((const char *)je1.s.c_str - js1->ptr()) - je1.sav_c_len) ||
  1231. str->append(", ", 2) ||
  1232. str->append((const char *)je2.s.c_str,
  1233. js2->length() - ((const char *)je2.s.c_str - js2->ptr())))
  1234. goto error_return;
  1235. }
  1236. else
  1237. {
  1238. const char *end1, *beg2;
  1239. /* Merge as a single array. */
  1240. if (je1.value_type == JSON_VALUE_ARRAY)
  1241. {
  1242. if (json_skip_level(&je1))
  1243. goto error_return;
  1244. end1= (const char *) (je1.s.c_str - je1.sav_c_len);
  1245. }
  1246. else
  1247. {
  1248. if (str->append("[", 1))
  1249. goto error_return;
  1250. end1= js1->end();
  1251. }
  1252. if (str->append(js1->ptr(), end1 - js1->ptr()),
  1253. str->append(", ", 2))
  1254. goto error_return;
  1255. if (je2.value_type == JSON_VALUE_ARRAY)
  1256. beg2= (const char *) je2.s.c_str;
  1257. else
  1258. beg2= js2->ptr();
  1259. if (str->append(beg2, js2->end() - beg2))
  1260. goto error_return;
  1261. if (je2.value_type != JSON_VALUE_ARRAY &&
  1262. str->append("]", 1))
  1263. goto error_return;
  1264. }
  1265. {
  1266. /* Swap str and js1. */
  1267. if (str == &tmp_js1)
  1268. {
  1269. str= js1;
  1270. js1= &tmp_js1;
  1271. }
  1272. else
  1273. {
  1274. js1= str;
  1275. str= &tmp_js1;
  1276. }
  1277. }
  1278. }
  1279. null_value= 0;
  1280. return js1;
  1281. error_return:
  1282. if (je1.s.error)
  1283. report_json_error(js1, &je1, 0);
  1284. if (je2.s.error)
  1285. report_json_error(js2, &je2, n_arg);
  1286. null_return:
  1287. null_value= 1;
  1288. return NULL;
  1289. }
  1290. void Item_func_json_length::fix_length_and_dec()
  1291. {
  1292. if (arg_count > 1)
  1293. path.set_constant_flag(args[1]->const_item());
  1294. }
  1295. longlong Item_func_json_length::val_int()
  1296. {
  1297. String *js= args[0]->val_str(&tmp_js);
  1298. json_engine_t je;
  1299. uint length= 0;
  1300. uint array_counters[JSON_DEPTH_LIMIT];
  1301. if ((null_value= args[0]->null_value))
  1302. return 0;
  1303. json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
  1304. (const uchar *) js->ptr() + js->length());
  1305. if (arg_count > 1)
  1306. {
  1307. /* Path specified - let's apply it. */
  1308. if (!path.parsed)
  1309. {
  1310. String *s_p= args[1]->val_str(&tmp_path);
  1311. if (s_p &&
  1312. json_path_setup(&path.p, s_p->charset(), (const uchar *) s_p->ptr(),
  1313. (const uchar *) s_p->ptr() + s_p->length()))
  1314. {
  1315. report_path_error(s_p, &path.p, 2);
  1316. goto null_return;
  1317. }
  1318. path.parsed= path.constant;
  1319. }
  1320. if (args[1]->null_value)
  1321. goto null_return;
  1322. path.cur_step= path.p.steps;
  1323. if (json_find_path(&je, &path.p, &path.cur_step, array_counters))
  1324. {
  1325. if (je.s.error)
  1326. goto err_return;
  1327. goto null_return;
  1328. }
  1329. }
  1330. if (json_read_value(&je))
  1331. goto err_return;
  1332. if (json_value_scalar(&je))
  1333. return 1;
  1334. while (json_scan_next(&je) == 0 &&
  1335. je.state != JST_OBJ_END && je.state != JST_ARRAY_END)
  1336. {
  1337. switch (je.state)
  1338. {
  1339. case JST_VALUE:
  1340. case JST_KEY:
  1341. length++;
  1342. break;
  1343. case JST_OBJ_START:
  1344. case JST_ARRAY_START:
  1345. if (json_skip_level(&je))
  1346. goto err_return;
  1347. break;
  1348. default:
  1349. break;
  1350. };
  1351. }
  1352. if (!je.s.error)
  1353. return length;
  1354. err_return:
  1355. report_json_error(js, &je, 0);
  1356. null_return:
  1357. null_value= 1;
  1358. return 0;
  1359. }
  1360. longlong Item_func_json_depth::val_int()
  1361. {
  1362. String *js= args[0]->val_str(&tmp_js);
  1363. json_engine_t je;
  1364. uint depth= 0, c_depth= 0;
  1365. bool inc_depth= TRUE;
  1366. if ((null_value= args[0]->null_value))
  1367. return 0;
  1368. json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
  1369. (const uchar *) js->ptr() + js->length());
  1370. do
  1371. {
  1372. switch (je.state)
  1373. {
  1374. case JST_VALUE:
  1375. case JST_KEY:
  1376. if (inc_depth)
  1377. {
  1378. c_depth++;
  1379. inc_depth= FALSE;
  1380. if (c_depth > depth)
  1381. depth= c_depth;
  1382. }
  1383. break;
  1384. case JST_OBJ_START:
  1385. case JST_ARRAY_START:
  1386. inc_depth= TRUE;
  1387. break;
  1388. case JST_OBJ_END:
  1389. case JST_ARRAY_END:
  1390. if (!inc_depth)
  1391. c_depth--;
  1392. inc_depth= FALSE;
  1393. break;
  1394. default:
  1395. break;
  1396. }
  1397. } while (json_scan_next(&je) == 0);
  1398. if (!je.s.error)
  1399. return depth;
  1400. report_json_error(js, &je, 0);
  1401. null_value= 1;
  1402. return 0;
  1403. }
  1404. void Item_func_json_type::fix_length_and_dec()
  1405. {
  1406. collation.set(&my_charset_utf8_general_ci);
  1407. max_length= 12;
  1408. }
  1409. String *Item_func_json_type::val_str(String *str)
  1410. {
  1411. String *js= args[0]->val_str(&tmp_js);
  1412. json_engine_t je;
  1413. const char *type;
  1414. if ((null_value= args[0]->null_value))
  1415. return 0;
  1416. json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
  1417. (const uchar *) js->ptr() + js->length());
  1418. if (json_read_value(&je))
  1419. goto error;
  1420. switch (je.value_type)
  1421. {
  1422. case JSON_VALUE_OBJECT:
  1423. type= "OBJECT";
  1424. break;
  1425. case JSON_VALUE_ARRAY:
  1426. type= "ARRAY";
  1427. break;
  1428. case JSON_VALUE_STRING:
  1429. type= "STRING";
  1430. break;
  1431. case JSON_VALUE_NUMBER:
  1432. type= (je.num_flags & JSON_NUM_FRAC_PART) ? "DOUBLE" : "INTEGER";
  1433. break;
  1434. case JSON_VALUE_TRUE:
  1435. case JSON_VALUE_FALSE:
  1436. type= "BOOLEAN";
  1437. break;
  1438. default:
  1439. type= "NULL";
  1440. break;
  1441. }
  1442. str->set(type, strlen(type), &my_charset_utf8_general_ci);
  1443. return str;
  1444. error:
  1445. report_json_error(js, &je, 0);
  1446. null_value= 1;
  1447. return 0;
  1448. }
  1449. void Item_func_json_insert::fix_length_and_dec()
  1450. {
  1451. uint n_arg;
  1452. ulonglong char_length;
  1453. collation.set(args[0]->collation);
  1454. char_length= args[0]->max_char_length();
  1455. for (n_arg= 1; n_arg < arg_count; n_arg+= 2)
  1456. {
  1457. paths[n_arg/2].set_constant_flag(args[n_arg]->const_item());
  1458. char_length+= args[n_arg/2+1]->max_char_length() + 4;
  1459. }
  1460. fix_char_length_ulonglong(char_length);
  1461. }
  1462. String *Item_func_json_insert::val_str(String *str)
  1463. {
  1464. json_engine_t je;
  1465. String *js= args[0]->val_str(&tmp_js);
  1466. uint n_arg, n_path;
  1467. json_string_t key_name;
  1468. DBUG_ASSERT(fixed == 1);
  1469. if ((null_value= args[0]->null_value))
  1470. return 0;
  1471. str->set_charset(js->charset());
  1472. json_string_set_cs(&key_name, js->charset());
  1473. for (n_arg=1, n_path=0; n_arg < arg_count; n_arg+=2, n_path++)
  1474. {
  1475. uint array_counters[JSON_DEPTH_LIMIT];
  1476. json_path_with_flags *c_path= paths + n_path;
  1477. const char *v_to;
  1478. const json_path_step_t *lp;
  1479. if (!c_path->parsed)
  1480. {
  1481. String *s_p= args[n_arg]->val_str(tmp_paths+n_path);
  1482. if (s_p)
  1483. {
  1484. if (path_setup_nwc(&c_path->p,s_p->charset(),
  1485. (const uchar *) s_p->ptr(),
  1486. (const uchar *) s_p->ptr() + s_p->length()))
  1487. {
  1488. report_path_error(s_p, &c_path->p, n_arg);
  1489. goto return_null;
  1490. }
  1491. /* We search to the last step. */
  1492. c_path->p.last_step--;
  1493. }
  1494. c_path->parsed= c_path->constant;
  1495. }
  1496. if (args[n_arg]->null_value)
  1497. goto return_null;
  1498. json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
  1499. (const uchar *) js->ptr() + js->length());
  1500. c_path->cur_step= c_path->p.steps;
  1501. if (c_path->p.last_step >= c_path->p.steps &&
  1502. json_find_path(&je, &c_path->p, &c_path->cur_step, array_counters))
  1503. {
  1504. if (je.s.error)
  1505. goto js_error;
  1506. }
  1507. if (json_read_value(&je))
  1508. goto js_error;
  1509. lp= c_path->p.last_step+1;
  1510. if (lp->type & JSON_PATH_ARRAY)
  1511. {
  1512. uint n_item= 0;
  1513. if (je.value_type != JSON_VALUE_ARRAY)
  1514. {
  1515. const uchar *v_from= je.value_begin;
  1516. if (!mode_insert)
  1517. continue;
  1518. str->length(0);
  1519. /* Wrap the value as an array. */
  1520. if (append_simple(str, js->ptr(), (const char *) v_from - js->ptr()) ||
  1521. str->append("[", 1))
  1522. goto js_error; /* Out of memory. */
  1523. if (je.value_type == JSON_VALUE_OBJECT)
  1524. {
  1525. if (json_skip_level(&je))
  1526. goto js_error;
  1527. }
  1528. if (append_simple(str, v_from, je.s.c_str - v_from) ||
  1529. str->append(", ", 2) ||
  1530. append_json_value(str, args[n_arg+1], &tmp_val) ||
  1531. str->append("]", 1) ||
  1532. append_simple(str, je.s.c_str, js->end()-(const char *) je.s.c_str))
  1533. goto js_error; /* Out of memory. */
  1534. goto continue_point;
  1535. }
  1536. while (json_scan_next(&je) == 0 && je.state != JST_ARRAY_END)
  1537. {
  1538. switch (je.state)
  1539. {
  1540. case JST_VALUE:
  1541. if (n_item == lp->n_item)
  1542. goto v_found;
  1543. n_item++;
  1544. if (json_skip_array_item(&je))
  1545. goto js_error;
  1546. break;
  1547. default:
  1548. break;
  1549. }
  1550. }
  1551. if (je.s.error)
  1552. goto js_error;
  1553. if (!mode_insert)
  1554. continue;
  1555. v_to= (const char *) (je.s.c_str - je.sav_c_len);
  1556. str->length(0);
  1557. if (append_simple(str, js->ptr(), v_to - js->ptr()) ||
  1558. str->append(", ", 2) ||
  1559. append_json_value(str, args[n_arg+1], &tmp_val) ||
  1560. append_simple(str, v_to, js->end() - v_to))
  1561. goto js_error; /* Out of memory. */
  1562. }
  1563. else /*JSON_PATH_KEY*/
  1564. {
  1565. if (je.value_type != JSON_VALUE_OBJECT)
  1566. continue;
  1567. while (json_scan_next(&je) == 0 && je.state != JST_OBJ_END)
  1568. {
  1569. switch (je.state)
  1570. {
  1571. case JST_KEY:
  1572. json_string_set_str(&key_name, lp->key, lp->key_end);
  1573. if (json_key_matches(&je, &key_name))
  1574. goto v_found;
  1575. if (json_skip_key(&je))
  1576. goto js_error;
  1577. break;
  1578. default:
  1579. break;
  1580. }
  1581. }
  1582. if (je.s.error)
  1583. goto js_error;
  1584. if (!mode_insert)
  1585. continue;
  1586. v_to= (const char *) (je.s.c_str - je.sav_c_len);
  1587. str->length(0);
  1588. if (append_simple(str, js->ptr(), v_to - js->ptr()) ||
  1589. str->append(", \"", 3) ||
  1590. append_simple(str, lp->key, lp->key_end - lp->key) ||
  1591. str->append("\":", 2) ||
  1592. append_json_value(str, args[n_arg+1], &tmp_val) ||
  1593. append_simple(str, v_to, js->end() - v_to))
  1594. goto js_error; /* Out of memory. */
  1595. }
  1596. goto continue_point;
  1597. v_found:
  1598. if (!mode_replace)
  1599. continue;
  1600. if (json_read_value(&je))
  1601. goto js_error;
  1602. v_to= (const char *) je.value_begin;
  1603. str->length(0);
  1604. if (!json_value_scalar(&je))
  1605. {
  1606. if (json_skip_level(&je))
  1607. goto js_error;
  1608. }
  1609. if (append_simple(str, js->ptr(), v_to - js->ptr()) ||
  1610. append_json_value(str, args[n_arg+1], &tmp_val) ||
  1611. append_simple(str, je.s.c_str, js->end()-(const char *) je.s.c_str))
  1612. goto js_error; /* Out of memory. */
  1613. continue_point:
  1614. {
  1615. /* Swap str and js. */
  1616. if (str == &tmp_js)
  1617. {
  1618. str= js;
  1619. js= &tmp_js;
  1620. }
  1621. else
  1622. {
  1623. js= str;
  1624. str= &tmp_js;
  1625. }
  1626. }
  1627. }
  1628. return js;
  1629. js_error:
  1630. report_json_error(js, &je, 0);
  1631. return_null:
  1632. null_value= 1;
  1633. return 0;
  1634. }
  1635. void Item_func_json_remove::fix_length_and_dec()
  1636. {
  1637. collation.set(args[0]->collation);
  1638. max_length= args[0]->max_length;
  1639. mark_constant_paths(paths, args+1, arg_count-1);
  1640. }
  1641. String *Item_func_json_remove::val_str(String *str)
  1642. {
  1643. json_engine_t je;
  1644. String *js= args[0]->val_str(&tmp_js);
  1645. uint n_arg, n_path;
  1646. json_string_t key_name;
  1647. DBUG_ASSERT(fixed == 1);
  1648. if (args[0]->null_value)
  1649. goto null_return;
  1650. str->set_charset(js->charset());
  1651. json_string_set_cs(&key_name, js->charset());
  1652. for (n_arg=1, n_path=0; n_arg < arg_count; n_arg+=2, n_path++)
  1653. {
  1654. uint array_counters[JSON_DEPTH_LIMIT];
  1655. json_path_with_flags *c_path= paths + n_path;
  1656. const char *rem_start, *rem_end;
  1657. const json_path_step_t *lp;
  1658. uint n_item= 0;
  1659. if (!c_path->parsed)
  1660. {
  1661. String *s_p= args[n_arg]->val_str(tmp_paths+n_path);
  1662. if (s_p)
  1663. {
  1664. if (path_setup_nwc(&c_path->p,s_p->charset(),
  1665. (const uchar *) s_p->ptr(),
  1666. (const uchar *) s_p->ptr() + s_p->length()))
  1667. {
  1668. report_path_error(s_p, &c_path->p, n_arg);
  1669. goto null_return;
  1670. }
  1671. /* We search to the last step. */
  1672. c_path->p.last_step--;
  1673. if (c_path->p.last_step < c_path->p.steps)
  1674. goto null_return;
  1675. }
  1676. c_path->parsed= c_path->constant;
  1677. }
  1678. if (args[n_arg]->null_value)
  1679. goto null_return;
  1680. json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
  1681. (const uchar *) js->ptr() + js->length());
  1682. c_path->cur_step= c_path->p.steps;
  1683. if (json_find_path(&je, &c_path->p, &c_path->cur_step, array_counters))
  1684. {
  1685. if (je.s.error)
  1686. goto js_error;
  1687. }
  1688. if (json_read_value(&je))
  1689. goto js_error;
  1690. lp= c_path->p.last_step+1;
  1691. if (lp->type & JSON_PATH_ARRAY)
  1692. {
  1693. if (je.value_type != JSON_VALUE_ARRAY)
  1694. continue;
  1695. while (json_scan_next(&je) == 0 && je.state != JST_ARRAY_END)
  1696. {
  1697. switch (je.state)
  1698. {
  1699. case JST_VALUE:
  1700. if (n_item == lp->n_item)
  1701. {
  1702. rem_start= (const char *) (je.s.c_str -
  1703. (n_item ? je.sav_c_len : 0));
  1704. goto v_found;
  1705. }
  1706. n_item++;
  1707. if (json_skip_array_item(&je))
  1708. goto js_error;
  1709. break;
  1710. default:
  1711. break;
  1712. }
  1713. }
  1714. if (je.s.error)
  1715. goto js_error;
  1716. continue;
  1717. }
  1718. else /*JSON_PATH_KEY*/
  1719. {
  1720. if (je.value_type != JSON_VALUE_OBJECT)
  1721. continue;
  1722. while (json_scan_next(&je) == 0 && je.state != JST_OBJ_END)
  1723. {
  1724. switch (je.state)
  1725. {
  1726. case JST_KEY:
  1727. if (n_item == 0)
  1728. rem_start= (const char *) (je.s.c_str - je.sav_c_len);
  1729. json_string_set_str(&key_name, lp->key, lp->key_end);
  1730. if (json_key_matches(&je, &key_name))
  1731. goto v_found;
  1732. if (json_skip_key(&je))
  1733. goto js_error;
  1734. rem_start= (const char *) je.s.c_str;
  1735. n_item++;
  1736. break;
  1737. default:
  1738. break;
  1739. }
  1740. }
  1741. if (je.s.error)
  1742. goto js_error;
  1743. continue;
  1744. }
  1745. v_found:
  1746. if (json_skip_key(&je) || json_scan_next(&je))
  1747. goto js_error;
  1748. rem_end= (je.state == JST_VALUE && n_item == 0) ?
  1749. (const char *) je.s.c_str : (const char *) (je.s.c_str - je.sav_c_len);
  1750. str->length(0);
  1751. if (append_simple(str, js->ptr(), rem_start - js->ptr()) ||
  1752. append_simple(str, rem_end, js->end() - rem_end))
  1753. goto js_error; /* Out of memory. */
  1754. {
  1755. /* Swap str and js. */
  1756. if (str == &tmp_js)
  1757. {
  1758. str= js;
  1759. js= &tmp_js;
  1760. }
  1761. else
  1762. {
  1763. js= str;
  1764. str= &tmp_js;
  1765. }
  1766. }
  1767. }
  1768. return js;
  1769. js_error:
  1770. report_json_error(js, &je, 0);
  1771. null_return:
  1772. null_value= 1;
  1773. return 0;
  1774. }
  1775. void Item_func_json_keys::fix_length_and_dec()
  1776. {
  1777. collation.set(args[0]->collation);
  1778. max_length= args[0]->max_length;
  1779. if (arg_count > 1)
  1780. path.set_constant_flag(args[1]->const_item());
  1781. }
  1782. String *Item_func_json_keys::val_str(String *str)
  1783. {
  1784. json_engine_t je;
  1785. String *js= args[0]->val_str(&tmp_js);
  1786. uint n_keys= 0;
  1787. uint array_counters[JSON_DEPTH_LIMIT];
  1788. if ((args[0]->null_value))
  1789. goto null_return;
  1790. json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
  1791. (const uchar *) js->ptr() + js->length());
  1792. if (arg_count < 2)
  1793. goto skip_search;
  1794. if (!path.parsed)
  1795. {
  1796. String *s_p= args[1]->val_str(&tmp_path);
  1797. if (s_p &&
  1798. path_setup_nwc(&path.p, s_p->charset(), (const uchar *) s_p->ptr(),
  1799. (const uchar *) s_p->ptr() + s_p->length()))
  1800. {
  1801. report_path_error(s_p, &path.p, 1);
  1802. goto null_return;
  1803. }
  1804. path.parsed= path.constant;
  1805. }
  1806. if (args[1]->null_value)
  1807. goto null_return;
  1808. path.cur_step= path.p.steps;
  1809. if (json_find_path(&je, &path.p, &path.cur_step, array_counters))
  1810. {
  1811. if (je.s.error)
  1812. goto err_return;
  1813. goto null_return;
  1814. }
  1815. skip_search:
  1816. if (json_read_value(&je))
  1817. goto err_return;
  1818. if (je.value_type != JSON_VALUE_OBJECT)
  1819. goto null_return;
  1820. str->length(0);
  1821. if (str->append("[", 1))
  1822. goto err_return; /* Out of memory. */
  1823. /* Parse the OBJECT collecting the keys. */
  1824. while (json_scan_next(&je) == 0 && je.state != JST_OBJ_END)
  1825. {
  1826. const uchar *key_start, *key_end;
  1827. switch (je.state)
  1828. {
  1829. case JST_KEY:
  1830. key_start= je.s.c_str;
  1831. while (json_read_keyname_chr(&je) == 0)
  1832. {
  1833. key_end= je.s.c_str;
  1834. }
  1835. if (je.s.error ||
  1836. (n_keys > 0 && str->append(", ", 2)) ||
  1837. str->append("\"", 1) ||
  1838. append_simple(str, key_start, key_end - key_start) ||
  1839. str->append("\"", 1))
  1840. goto err_return;
  1841. n_keys++;
  1842. break;
  1843. case JST_OBJ_START:
  1844. case JST_ARRAY_START:
  1845. if (json_skip_level(&je))
  1846. break;
  1847. break;
  1848. default:
  1849. break;
  1850. }
  1851. }
  1852. if (je.s.error || str->append("]", 1))
  1853. goto err_return;
  1854. null_value= 0;
  1855. return str;
  1856. err_return:
  1857. report_json_error(js, &je, 0);
  1858. null_return:
  1859. null_value= 1;
  1860. return 0;
  1861. }
  1862. bool Item_func_json_search::fix_fields(THD *thd, Item **ref)
  1863. {
  1864. if (Item_json_str_multipath::fix_fields(thd, ref))
  1865. return TRUE;
  1866. if (arg_count < 4)
  1867. return FALSE;
  1868. return fix_escape_item(thd, args[3], &tmp_js, true,
  1869. args[0]->collation.collation, &escape);
  1870. }
  1871. static const uint SQR_MAX_BLOB_WIDTH= (uint) sqrt(MAX_BLOB_WIDTH);
  1872. void Item_func_json_search::fix_length_and_dec()
  1873. {
  1874. collation.set(args[0]->collation);
  1875. /*
  1876. It's rather difficult to estimate the length of the result.
  1877. I belive arglen^2 is the reasonable upper limit.
  1878. */
  1879. if (args[0]->max_length > SQR_MAX_BLOB_WIDTH)
  1880. max_length= MAX_BLOB_WIDTH;
  1881. else
  1882. {
  1883. max_length= args[0]->max_length;
  1884. max_length*= max_length;
  1885. }
  1886. ooa_constant= args[1]->const_item();
  1887. ooa_parsed= FALSE;
  1888. if (arg_count > 4)
  1889. mark_constant_paths(paths, args+4, arg_count-4);
  1890. }
  1891. int Item_func_json_search::compare_json_value_wild(json_engine_t *je,
  1892. const String *cmp_str)
  1893. {
  1894. return my_wildcmp(collation.collation,
  1895. (const char *) je->value, (const char *) (je->value + je->value_len),
  1896. cmp_str->ptr(), cmp_str->end(), escape, wild_one, wild_many) ? 0 : 1;
  1897. }
  1898. static int append_json_path(String *str, const json_path_t *p)
  1899. {
  1900. const json_path_step_t *c;
  1901. if (str->append("\"$", 2))
  1902. return TRUE;
  1903. for (c= p->steps+1; c <= p->last_step; c++)
  1904. {
  1905. if (c->type & JSON_PATH_KEY)
  1906. {
  1907. if (str->append(".", 1) ||
  1908. append_simple(str, c->key, c->key_end-c->key))
  1909. return TRUE;
  1910. }
  1911. else /*JSON_PATH_ARRAY*/
  1912. {
  1913. if (str->append("[", 1) ||
  1914. str->append_ulonglong(c->n_item) ||
  1915. str->append("]", 1))
  1916. return TRUE;
  1917. }
  1918. }
  1919. return str->append("\"", 1);
  1920. }
  1921. static int json_path_compare(const json_path_t *a, const json_path_t *b)
  1922. {
  1923. const json_path_step_t *sa= a->steps + 1;
  1924. const json_path_step_t *sb= b->steps + 1;
  1925. if (a->last_step - sa > b->last_step - sb)
  1926. return -2;
  1927. while (sa <= a->last_step)
  1928. {
  1929. if (sb > b->last_step)
  1930. return -2;
  1931. if (!((sa->type & sb->type) & JSON_PATH_KEY_OR_ARRAY))
  1932. goto step_failed;
  1933. if (sa->type & JSON_PATH_ARRAY)
  1934. {
  1935. if (!(sa->type & JSON_PATH_WILD) && sa->n_item != sb->n_item)
  1936. goto step_failed;
  1937. }
  1938. else /* JSON_PATH_KEY */
  1939. {
  1940. if (!(sa->type & JSON_PATH_WILD) &&
  1941. (sa->key_end - sa->key != sb->key_end - sb->key ||
  1942. memcmp(sa->key, sb->key, sa->key_end - sa->key) != 0))
  1943. goto step_failed;
  1944. }
  1945. sb++;
  1946. sa++;
  1947. continue;
  1948. step_failed:
  1949. if (!(sa->type & JSON_PATH_DOUBLE_WILD))
  1950. return -1;
  1951. sb++;
  1952. }
  1953. return sb <= b->last_step;
  1954. }
  1955. static bool path_ok(const json_path_with_flags *paths_list, int n_paths,
  1956. const json_path_t *p)
  1957. {
  1958. for (; n_paths > 0; n_paths--, paths_list++)
  1959. {
  1960. if (json_path_compare(&paths_list->p, p) >= 0)
  1961. return TRUE;
  1962. }
  1963. return FALSE;
  1964. }
  1965. String *Item_func_json_search::val_str(String *str)
  1966. {
  1967. String *js= args[0]->val_str(&tmp_js);
  1968. String *s_str= args[2]->val_str(&tmp_js);
  1969. json_engine_t je;
  1970. json_path_t p, sav_path;
  1971. uint n_arg;
  1972. if (args[0]->null_value || args[2]->null_value)
  1973. goto null_return;
  1974. if (parse_one_or_all(this, args[1], &ooa_parsed, ooa_constant, &mode_one))
  1975. goto null_return;
  1976. n_path_found= 0;
  1977. str->set_charset(js->charset());
  1978. str->length(0);
  1979. for (n_arg=4; n_arg < arg_count; n_arg++)
  1980. {
  1981. json_path_with_flags *c_path= paths + n_arg - 4;
  1982. if (!c_path->parsed)
  1983. {
  1984. String *s_p= args[n_arg]->val_str(tmp_paths + (n_arg-1));
  1985. if (s_p &&
  1986. json_path_setup(&c_path->p,s_p->charset(),(const uchar *) s_p->ptr(),
  1987. (const uchar *) s_p->ptr() + s_p->length()))
  1988. {
  1989. report_path_error(s_p, &c_path->p, n_arg);
  1990. goto null_return;
  1991. }
  1992. c_path->parsed= c_path->constant;
  1993. }
  1994. if (args[n_arg]->null_value)
  1995. goto null_return;
  1996. }
  1997. json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
  1998. (const uchar *) js->ptr() + js->length());
  1999. p.last_step= p.steps;
  2000. p.steps[0].type= JSON_PATH_ARRAY_WILD;
  2001. p.steps[0].n_item= 0;
  2002. do
  2003. {
  2004. switch (je.state)
  2005. {
  2006. case JST_KEY:
  2007. p.last_step->key= je.s.c_str;
  2008. while (json_read_keyname_chr(&je) == 0)
  2009. p.last_step->key_end= je.s.c_str;
  2010. if (je.s.error)
  2011. goto js_error;
  2012. /* Now we have je.state == JST_VALUE, so let's handle it. */
  2013. case JST_VALUE:
  2014. if (json_read_value(&je))
  2015. goto js_error;
  2016. if (json_value_scalar(&je))
  2017. {
  2018. if ((arg_count < 5 || path_ok(paths, n_arg - 4, &p)) &&
  2019. compare_json_value_wild(&je, s_str) != 0)
  2020. {
  2021. ++n_path_found;
  2022. if (n_path_found == 1)
  2023. {
  2024. sav_path= p;
  2025. sav_path.last_step= sav_path.steps + (p.last_step - p.steps);
  2026. }
  2027. else
  2028. {
  2029. if (n_path_found == 2)
  2030. {
  2031. if (str->append("[", 1) ||
  2032. append_json_path(str, &sav_path))
  2033. goto js_error;
  2034. }
  2035. if (str->append(", ", 2) || append_json_path(str, &p))
  2036. goto js_error;
  2037. }
  2038. if (mode_one)
  2039. goto end;
  2040. }
  2041. if (p.last_step->type & JSON_PATH_ARRAY)
  2042. p.last_step->n_item++;
  2043. }
  2044. else
  2045. {
  2046. p.last_step++;
  2047. p.last_step->type= (enum json_path_step_types) je.value_type;
  2048. p.last_step->n_item= 0;
  2049. }
  2050. break;
  2051. case JST_OBJ_END:
  2052. case JST_ARRAY_END:
  2053. p.last_step--;
  2054. if (p.last_step->type & JSON_PATH_ARRAY)
  2055. p.last_step->n_item++;
  2056. break;
  2057. default:
  2058. break;
  2059. }
  2060. } while (json_scan_next(&je) == 0);
  2061. if (je.s.error)
  2062. goto js_error;
  2063. end:
  2064. if (n_path_found == 0)
  2065. goto null_return;
  2066. if (n_path_found == 1)
  2067. {
  2068. if (append_json_path(str, &sav_path))
  2069. goto js_error;
  2070. }
  2071. else
  2072. {
  2073. if (str->append("]", 1))
  2074. goto js_error;
  2075. }
  2076. null_value= 0;
  2077. return str;
  2078. js_error:
  2079. report_json_error(js, &je, 0);
  2080. null_return:
  2081. /* TODO: launch error messages. */
  2082. null_value= 1;
  2083. return 0;
  2084. }
  2085. void Item_json_typecast::fix_length_and_dec()
  2086. {
  2087. maybe_null= args[0]->maybe_null;
  2088. max_length= args[0]->max_length;
  2089. }
  2090. String *Item_json_typecast::val_str(String *str)
  2091. {
  2092. String *vs= args[0]->val_str(str);
  2093. null_value= args[0]->null_value;
  2094. return vs;
  2095. }