You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by GitBox <gi...@apache.org> on 2019/06/04 09:34:10 UTC

[GitHub] [calcite] zhztheplayer commented on a change in pull request #1143: [CALCITE-2884] Implement JSON_INSERT, JSON_REPLACE, JSON_SET

zhztheplayer commented on a change in pull request #1143: [CALCITE-2884] Implement JSON_INSERT, JSON_REPLACE, JSON_SET
URL: https://github.com/apache/calcite/pull/1143#discussion_r290204919
 
 

 ##########
 File path: core/src/main/java/org/apache/calcite/runtime/JsonFunctions.java
 ##########
 @@ -606,41 +608,160 @@ public static String jsonKeys(JsonPathContext context) {
     return jsonize(list);
   }
 
-  public static String jsonRemove(String input, String... pathSpecs) {
-    return jsonRemove(jsonValueExpression(input), pathSpecs);
+  public static Integer jsonStorageSize(String input) {
+    return jsonStorageSize(jsonValueExpression(input));
   }
 
-  public static String jsonRemove(JsonValueContext input, String... pathSpecs) {
+  public static Integer jsonStorageSize(JsonValueContext input) {
     try {
-      DocumentContext ctx = JsonPath.parse(input.obj,
-          Configuration
-              .builder()
-              .options(Option.SUPPRESS_EXCEPTIONS)
-              .jsonProvider(JSON_PATH_JSON_PROVIDER)
-              .mappingProvider(JSON_PATH_MAPPING_PROVIDER)
-              .build());
-      for (String pathSpec : pathSpecs) {
+      return JSON_PATH_JSON_PROVIDER.getObjectMapper()
+          .writeValueAsBytes(input.obj).length;
+    } catch (Exception e) {
+      throw RESOURCE.invalidInputForJsonStorageSize(Objects.toString(input.obj)).ex();
+    }
+  }
+
+  private static String jsonModify(JsonValueContext jsonDoc, String type, Object... kvs) {
+    JsonModifyMode jsonPairsType = JsonModifyMode.getType(type);
+    if (jsonPairsType != JsonModifyMode.REMOVE) {
+        assert kvs.length % 2 == 0;
+    }
+    String result = "";
+    DocumentContext ctx = JsonPath.parse(jsonDoc.obj,
+        Configuration
+            .builder()
+            .options(Option.SUPPRESS_EXCEPTIONS)
+            .jsonProvider(JSON_PATH_JSON_PROVIDER)
+            .mappingProvider(JSON_PATH_MAPPING_PROVIDER)
+            .build());
+
+    if (jsonPairsType == JsonModifyMode.REMOVE) {
+      for (Object kv : kvs) {
+        String pathSpec = (String) kv;
         if ((pathSpec != null) && (ctx.read(pathSpec) != null)) {
           ctx.delete(pathSpec);
         }
       }
-      return ctx.jsonString();
+    } else {
+      Map<String, Object> map = new HashMap<>();
+      for (int i = 0; i < kvs.length; i += 2) {
+        String k = (String) kvs[i];
+        Object v = kvs[i + 1];
+        if (JsonPath.isPathDefinite(k) && k.contains(JSON_ROOT_PATH)) {
+          map.put(k, v);
+        } else {
+          throw RESOURCE.validationError(k).ex();
+        }
+      }
+
+      for (Map.Entry<String, Object> entry : map.entrySet()) {
+        String k = entry.getKey();
+        Object v = entry.getValue();
+        switch (jsonPairsType) {
+        case REPLACE:
+          if (k.equals(JSON_ROOT_PATH)) {
+            result = jsonize(v);
+          } else {
+            if (ctx.read(k) != null) {
+              ctx.set(k, v);
+            }
+          }
+          break;
+        case INSERT:
+          if ((!k.equals(JSON_ROOT_PATH)) && (ctx.read(k) == null)) {
+            insertToJson(ctx, k, v);
+          }
+          break;
+        case SET:
+          if (k.equals(JSON_ROOT_PATH)) {
+            result = jsonize(v);
+          } else {
+            if (ctx.read(k) != null) {
+              ctx.set(k, v);
+            } else {
+              insertToJson(ctx, k, v);
+            }
+          }
+          break;
+        }
+      }
+    }
+    result = Strings.isNullOrEmpty(result) ?  ctx.jsonString() : result;
+    return result;
+  }
+
+  private static void insertToJson(DocumentContext ctx, String path, Object value) {
+    final String preantPath;
+    final String key;
+    Integer dotIndex = path.lastIndexOf(".");
+    Integer leftBracketIndex = path.lastIndexOf("[");
+    if (dotIndex.equals(-1) && leftBracketIndex.equals(-1)) {
 
 Review comment:
   The block of if...else if...else if... is hard to understand. I see you were trying to parse the jsonpath specification by your self. Can we avoid such a implementation? Or could you please explain a bit how it works?

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services