This is an automated email from the ASF dual-hosted git repository.

twice pushed a commit to branch unstable
in repository https://gitbox.apache.org/repos/asf/kvrocks.git


The following commit(s) were added to refs/heads/unstable by this push:
     new c17a8cb2 Improve the command JSON.MERGE via jsonpath::remove (#1919)
c17a8cb2 is described below

commit c17a8cb2b484a004f4188bfb66692f05507f0c3f
Author: 2rueSid <[email protected]>
AuthorDate: Tue Dec 5 05:30:29 2023 -0500

    Improve the command JSON.MERGE via jsonpath::remove (#1919)
---
 src/types/json.h                 | 36 +++++++++++++++++++-----------------
 tests/cppunit/types/json_test.cc |  8 +++++++-
 2 files changed, 26 insertions(+), 18 deletions(-)

diff --git a/src/types/json.h b/src/types/json.h
index 672437e9..854a1d7d 100644
--- a/src/types/json.h
+++ b/src/types/json.h
@@ -31,6 +31,8 @@
 #include <jsoncons_ext/jsonpath/flatten.hpp>
 #include <jsoncons_ext/jsonpath/json_query.hpp>
 #include <jsoncons_ext/jsonpath/jsonpath_error.hpp>
+#include <jsoncons_ext/jsonpointer/jsonpointer.hpp>
+#include <jsoncons_ext/jsonpointer/jsonpointer_error.hpp>
 #include <jsoncons_ext/mergepatch/mergepatch.hpp>
 #include <limits>
 #include <string>
@@ -362,11 +364,20 @@ struct JsonValue {
       bool not_exists = jsoncons::jsonpath::json_query(value, path).empty();
 
       if (not_exists) {
-        // TODO:: Add ability to create an object from path.
-        return {Status::NotOK, "Path does not exist."};
-      }
+        jsoncons::jsonpath::json_location location = 
jsoncons::jsonpath::json_location::parse(path);
+        jsoncons::jsonpointer::json_pointer ptr{};
+
+        for (const auto &element : location) {
+          if (element.has_name())
+            ptr /= element.name();
+          else {
+            ptr /= element.index();
+          }
+        }
+        jsoncons::jsonpointer::replace(value, ptr, patch_value, true);
 
-      if (path == json_root_path) {
+        is_updated = true;
+      } else if (path == json_root_path) {
         // Merge with the root. Patch function complies with RFC7396 Json 
Merge Patch
         jsoncons::mergepatch::apply_merge_patch(value, patch_value);
         is_updated = true;
@@ -379,20 +390,11 @@ struct JsonValue {
             });
       } else {
         // Handle null case
-        // Unify path expression.
-        auto expr = jsoncons::jsonpath::make_expression<jsoncons::json>(path);
-        std::string converted_path;
-        expr.evaluate(
-            value, [&](const jsoncons::string_view &p, const jsoncons::json 
&val) { converted_path = p; },
-            jsoncons::jsonpath::result_options::path);
-        // Unify object state
-        jsoncons::json flattened = jsoncons::jsonpath::flatten(value);
-        if (flattened.contains(converted_path)) {
-          flattened.erase(converted_path);
-          value = jsoncons::jsonpath::unflatten(flattened);
-          is_updated = true;
-        }
+        jsoncons::jsonpath::remove(value, path);
+        is_updated = true;
       }
+    } catch (const jsoncons::jsonpointer::jsonpointer_error &e) {
+      return {Status::NotOK, e.what()};
     } catch (const jsoncons::jsonpath::jsonpath_error &e) {
       return {Status::NotOK, e.what()};
     } catch (const jsoncons::ser_error &e) {
diff --git a/tests/cppunit/types/json_test.cc b/tests/cppunit/types/json_test.cc
index 56290451..4ba08fe9 100644
--- a/tests/cppunit/types/json_test.cc
+++ b/tests/cppunit/types/json_test.cc
@@ -192,10 +192,16 @@ TEST_F(RedisJsonTest, Merge) {
   ASSERT_EQ(json_val_.Dump().GetValue(), "{\"a\":3}");
   ASSERT_EQ(result, true);
 
+  ASSERT_TRUE(json_->Set(key_, "$", R"({"a":2})").ok());
+  ASSERT_TRUE(json_->Merge(key_, "$.b", "3", result).ok());
+  ASSERT_TRUE(json_->Get(key_, {}, &json_val_).ok());
+  ASSERT_EQ(json_val_.Dump().GetValue(), "{\"a\":2,\"b\":3}");
+  ASSERT_EQ(result, true);
+
   ASSERT_TRUE(json_->Set(key_, "$", R"({"v": {"b": "cc"}})").ok());
   ASSERT_TRUE(json_->Merge(key_, "$.v.b", "null", result).ok());
   ASSERT_TRUE(json_->Get(key_, {}, &json_val_).ok());
-  ASSERT_EQ(json_val_.Dump().GetValue(), "{}");
+  ASSERT_EQ(json_val_.Dump().GetValue(), "{\"v\":{}}");
   ASSERT_EQ(result, true);
 
   ASSERT_TRUE(json_->Set(key_, "$", R"({"arr":[2,4,6,8]})").ok());

Reply via email to