[Commits] 08b6ec2: MDEV-9143 JSON_xxx functions.

Alexey Botchkov holyfoot at askmonty.org
Sat Oct 1 13:27:19 EEST 2016


revision-id: 08b6ec293ca8fda730c42cc7a08ef96bdc8433ef (mariadb-10.2.2-3-g08b6ec2)
parent(s): 098f0aedac6f57ca5ceec4e00d1e074d399ab082
committer: Alexey Botchkov
timestamp: 2016-10-01 14:26:32 +0400
message:

MDEV-9143 JSON_xxx functions.

        unittest added.

---
 CMakeLists.txt                   |   1 +
 unittest/json_lib/CMakeLists.txt |  23 +++++
 unittest/json_lib/json_lib-t.cc  | 185 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 209 insertions(+)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index e461141..4272699 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -356,6 +356,7 @@ IF(WITH_UNIT_TESTS)
  ADD_SUBDIRECTORY(unittest/examples)
  ADD_SUBDIRECTORY(unittest/mysys)
  ADD_SUBDIRECTORY(unittest/my_decimal)
+ ADD_SUBDIRECTORY(unittest/json_lib)
  IF(NOT WITHOUT_SERVER)
    ADD_SUBDIRECTORY(unittest/sql)
  ENDIF()
diff --git a/unittest/json_lib/CMakeLists.txt b/unittest/json_lib/CMakeLists.txt
new file mode 100644
index 0000000..fa1f5a9
--- /dev/null
+++ b/unittest/json_lib/CMakeLists.txt
@@ -0,0 +1,23 @@
+# Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
+# 
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include
+                    ${CMAKE_SOURCE_DIR}/sql
+                    ${CMAKE_SOURCE_DIR}/regex
+                    ${CMAKE_SOURCE_DIR}/extra/yassl/include
+                    ${CMAKE_SOURCE_DIR}/unittest/mytap)
+
+#
+MY_ADD_TESTS(json_lib EXT "cc" LINK_LIBRARIES strings dbug)
diff --git a/unittest/json_lib/json_lib-t.cc b/unittest/json_lib/json_lib-t.cc
new file mode 100644
index 0000000..fe4921d
--- /dev/null
+++ b/unittest/json_lib/json_lib-t.cc
@@ -0,0 +1,185 @@
+/* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; version 2 of the License.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
+
+#include "my_config.h"
+#include "config.h"
+#include <tap.h>
+#include <my_global.h>
+#include <my_sys.h>
+#include <json_lib.h>
+
+/* The character set used for JSON all over this test. */
+static CHARSET_INFO *ci;
+
+#define s_e(j) j, j + strlen((const char *) j)
+
+
+struct st_parse_result
+{
+  int n_keys;
+  int n_values;
+  int n_arrays;
+  int n_objects;
+  int n_steps;
+  int error;
+  uchar keyname_csum;
+};
+
+
+static void parse_json(const uchar *j, struct st_parse_result *result)
+{
+  json_engine_t je;
+
+  bzero(result, sizeof(*result));
+
+  if (json_scan_start(&je, ci, s_e(j)))
+    return;
+
+  do
+  {
+    result->n_steps++;
+    switch (je.state)
+    {
+    case JST_KEY:
+      result->n_keys++;
+      while (json_read_keyname_chr(&je) == 0)
+      {
+        result->keyname_csum^= je.s.c_next;
+      }
+      if (je.s.error)
+        return;
+      break;
+    case JST_VALUE:
+      result->n_values++;
+      break;
+    case JST_OBJ_START:
+      result->n_objects++;
+      break;
+    case JST_ARRAY_START:
+      result->n_arrays++;
+      break;
+    default:
+      break;
+    };
+  } while (json_scan_next(&je) == 0);
+
+  result->error= je.s.error;
+}
+
+
+static const uchar *js0= (const uchar *) "123";
+static const uchar *js1= (const uchar *) "[123, \"text\"]";
+static const uchar *js2= (const uchar *) "{\"key1\":123, \"key2\":\"text\"}";
+static const uchar *js3= (const uchar *) "{\"key1\":{\"ikey1\":321},"
+                                          "\"key2\":[\"text\", 321]}";
+
+/*
+  Test json_lib functions to parse JSON.
+*/
+static void
+test_json_parsing()
+{
+  struct st_parse_result r;
+  parse_json(js0, &r);
+  ok(r.n_steps == 1 && r.n_values == 1, "simple value");
+  parse_json(js1, &r);
+  ok(r.n_steps == 5 && r.n_values == 3 && r.n_arrays == 1, "array");
+  parse_json(js2, &r);
+  ok(r.n_steps == 5 && r.n_keys == 2 && r.n_objects == 1 && r.keyname_csum == 3,
+     "object");
+  parse_json(js3, &r);
+  ok(r.n_steps == 12 && r.n_keys == 3 && r.n_objects == 2 &&
+     r.n_arrays == 1 && r.keyname_csum == 44,
+     "complex json");
+}
+
+
+static const uchar *p0= (const uchar *) "$.key1[12].*[*]";
+/*
+  Test json_lib functions to parse JSON path.
+*/
+static void
+test_path_parsing()
+{
+  json_path_t p;
+  if (json_path_setup(&p, ci, s_e(p0)))
+    return;
+  ok(p.last_step - p.steps == 4 && 
+     p.steps[0].type == JSON_PATH_ARRAY && p.steps[0].wild == 1 &&
+     p.steps[1].type == JSON_PATH_KEY && p.steps[1].wild == 0 &&
+     p.steps[2].type == JSON_PATH_ARRAY && p.steps[2].n_item == 12 &&
+     p.steps[3].type == JSON_PATH_KEY && p.steps[3].wild == 1 &&
+     p.steps[4].type == JSON_PATH_ARRAY && p.steps[4].wild == 1,
+     "path");
+}
+
+
+static const uchar *fj0=(const uchar *) "[{\"k0\":123, \"k1\":123, \"k1\":123},"
+                                        " {\"k3\":321, \"k4\":\"text\"},"
+                                        " {\"k1\":[\"text\"], \"k2\":123}]";
+static const uchar *fp0= (const uchar *) "$[*].k1";
+/*
+  Test json_lib functions to search through JSON.
+*/
+static void
+test_search()
+{
+  json_engine_t je;
+  json_path_t p;
+  json_path_step_t *cur_step;
+  int n_matches, scal_values;;
+
+  if (json_scan_start(&je, ci, s_e(fj0)) ||
+      json_path_setup(&p, ci, s_e(fp0)))
+    return;
+
+  cur_step= p.steps;
+  n_matches= scal_values= 0;
+  while (json_find_value(&je, &p, &cur_step) == 0)
+  {
+    n_matches++;
+    if (json_read_value(&je))
+      return;
+    if (json_value_scalar(&je))
+    {
+      scal_values++;
+      if (json_scan_next(&je))
+        return;
+    }
+    else
+    {
+      if (json_skip_level(&je) || json_scan_next(&je))
+        return;
+    }
+
+  }
+
+  ok(n_matches == 3, "search");
+}
+
+
+int main()
+{
+  ci= &my_charset_utf8_general_ci;
+
+  plan(6);
+  diag("Testing json_lib functions.");
+
+  test_json_parsing();
+  test_path_parsing();
+  test_search();
+
+  return exit_status();
+}


More information about the commits mailing list