You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by ch...@apache.org on 2020/06/28 08:20:39 UTC

[calcite] branch master updated: [CALCITE-3941] Add the default strict mode to the path in the Json functions

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

chunwei pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/calcite.git


The following commit(s) were added to refs/heads/master by this push:
     new 057186d  [CALCITE-3941] Add the default strict mode to the path in the Json functions
057186d is described below

commit 057186d1c462ce06f72ed296d50e2836fe0d35df
Author: XuQianJin-Stars <fo...@apache.com>
AuthorDate: Fri May 1 15:04:02 2020 +0800

    [CALCITE-3941] Add the default strict mode to the path in the Json functions
---
 .../org/apache/calcite/runtime/JsonFunctions.java  | 24 ++++++++++++++++------
 .../calcite/sql/test/SqlOperatorBaseTest.java      | 15 ++++++++++++++
 .../apache/calcite/test/SqlJsonFunctionsTest.java  |  3 +++
 3 files changed, 36 insertions(+), 6 deletions(-)

diff --git a/core/src/main/java/org/apache/calcite/runtime/JsonFunctions.java b/core/src/main/java/org/apache/calcite/runtime/JsonFunctions.java
index 75cce8a..21d42d7 100644
--- a/core/src/main/java/org/apache/calcite/runtime/JsonFunctions.java
+++ b/core/src/main/java/org/apache/calcite/runtime/JsonFunctions.java
@@ -29,6 +29,7 @@ import com.fasterxml.jackson.core.util.DefaultIndenter;
 import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
 import com.jayway.jsonpath.Configuration;
 import com.jayway.jsonpath.DocumentContext;
+import com.jayway.jsonpath.InvalidPathException;
 import com.jayway.jsonpath.JsonPath;
 import com.jayway.jsonpath.Option;
 import com.jayway.jsonpath.spi.json.JacksonJsonProvider;
@@ -112,18 +113,22 @@ public class JsonFunctions {
   }
 
   public static JsonPathContext jsonApiCommonSyntax(JsonValueContext input, String pathSpec) {
+    PathMode mode;
+    String pathStr;
     try {
       Matcher matcher = JSON_PATH_BASE.matcher(pathSpec);
       if (!matcher.matches()) {
-        throw RESOURCE.illegalJsonPathSpec(pathSpec).ex();
+        mode = PathMode.STRICT;
+        pathStr = pathSpec;
+      } else {
+        mode = PathMode.valueOf(matcher.group(1).toUpperCase(Locale.ROOT));
+        pathStr = matcher.group(2);
       }
-      PathMode mode = PathMode.valueOf(matcher.group(1).toUpperCase(Locale.ROOT));
-      String pathWff = matcher.group(2);
       DocumentContext ctx;
       switch (mode) {
       case STRICT:
         if (input.hasException()) {
-          return JsonPathContext.withStrictException(input.exc);
+          return JsonPathContext.withStrictException(pathSpec, input.exc);
         }
         ctx = JsonPath.parse(input.obj,
             Configuration
@@ -148,9 +153,9 @@ public class JsonFunctions {
         throw RESOURCE.illegalJsonPathModeInPathSpec(mode.toString(), pathSpec).ex();
       }
       try {
-        return JsonPathContext.withJavaObj(mode, ctx.read(pathWff));
+        return JsonPathContext.withJavaObj(mode, ctx.read(pathStr));
       } catch (Exception e) {
-        return JsonPathContext.withStrictException(e);
+        return JsonPathContext.withStrictException(pathSpec, e);
       }
     } catch (Exception e) {
       return JsonPathContext.withUnknownException(e);
@@ -715,6 +720,13 @@ public class JsonFunctions {
       return new JsonPathContext(PathMode.STRICT, null, exc);
     }
 
+    public static JsonPathContext withStrictException(String pathSpec, Exception exc) {
+      if (exc.getClass() == InvalidPathException.class) {
+        exc = RESOURCE.illegalJsonPathSpec(pathSpec).ex();
+      }
+      return withStrictException(exc);
+    }
+
     public static JsonPathContext withJavaObj(PathMode mode, Object obj) {
       if (mode == PathMode.UNKNOWN) {
         throw RESOURCE.illegalJsonPathMode(mode.toString()).ex();
diff --git a/core/src/test/java/org/apache/calcite/sql/test/SqlOperatorBaseTest.java b/core/src/test/java/org/apache/calcite/sql/test/SqlOperatorBaseTest.java
index 18a3313..f4e055a 100644
--- a/core/src/test/java/org/apache/calcite/sql/test/SqlOperatorBaseTest.java
+++ b/core/src/test/java/org/apache/calcite/sql/test/SqlOperatorBaseTest.java
@@ -4655,6 +4655,10 @@ public abstract class SqlOperatorBaseTest {
   }
 
   @Test void testJsonExists() {
+    // default pathmode the default is: strict mode
+    tester.checkBoolean("json_exists('{\"foo\":\"bar\"}', "
+        + "'$.foo')", Boolean.TRUE);
+
     tester.checkBoolean("json_exists('{\"foo\":\"bar\"}', "
         + "'strict $.foo' false on error)", Boolean.TRUE);
     tester.checkBoolean("json_exists('{\"foo\":\"bar\"}', "
@@ -4707,6 +4711,9 @@ public abstract class SqlOperatorBaseTest {
           true);
     }
 
+    // default pathmode the default is: strict mode
+    tester.checkString("json_value('{\"foo\":100}', '$.foo')",
+        "100", "VARCHAR(2000)");
     // type casting test
     tester.checkString("json_value('{\"foo\":100}', 'strict $.foo')",
         "100", "VARCHAR(2000)");
@@ -4786,6 +4793,10 @@ public abstract class SqlOperatorBaseTest {
   }
 
   @Test void testJsonQuery() {
+    // default pathmode the default is: strict mode
+    tester.checkString("json_query('{\"foo\":100}', '$' null on empty)",
+        "{\"foo\":100}", "VARCHAR(2000)");
+
     // lax test
     tester.checkString("json_query('{\"foo\":100}', 'lax $' null on empty)",
         "{\"foo\":100}", "VARCHAR(2000)");
@@ -4993,6 +5004,10 @@ public abstract class SqlOperatorBaseTest {
     tester.checkString("json_length('[1, 2, {\"a\": 3}]')",
         "3", "INTEGER");
 
+    // default pathmode the default is: strict mode
+    tester.checkString("json_length('{\"foo\":100}', '$')",
+        "1", "INTEGER");
+
     // lax test
     tester.checkString("json_length('{}', 'lax $')",
         "0", "INTEGER");
diff --git a/core/src/test/java/org/apache/calcite/test/SqlJsonFunctionsTest.java b/core/src/test/java/org/apache/calcite/test/SqlJsonFunctionsTest.java
index b8758d5..0b019d2 100644
--- a/core/src/test/java/org/apache/calcite/test/SqlJsonFunctionsTest.java
+++ b/core/src/test/java/org/apache/calcite/test/SqlJsonFunctionsTest.java
@@ -62,6 +62,9 @@ class SqlJsonFunctionsTest {
   }
 
   @Test void testJsonApiCommonSyntax() {
+    assertJsonApiCommonSyntax("{\"foo\": \"bar\"}", "$.foo",
+        contextMatches(
+            JsonFunctions.JsonPathContext.withJavaObj(JsonFunctions.PathMode.STRICT, "bar")));
     assertJsonApiCommonSyntax("{\"foo\": \"bar\"}", "lax $.foo",
         contextMatches(
             JsonFunctions.JsonPathContext.withJavaObj(JsonFunctions.PathMode.LAX, "bar")));