fhueske commented on code in PR #24967:
URL: https://github.com/apache/flink/pull/24967#discussion_r1669010333


##########
docs/data/sql_functions.yml:
##########
@@ -377,6 +377,12 @@ string:
   - sql: SUBSTR(string, integer1[, integer2])
     table: STRING.substr(INTEGER1[, INTEGER2])
     description: Returns a substring of string starting from position integer1 
with length integer2 (to the end by default).
+  - sql: JSON_QUOTE(string)
+    table: STRING.JsonQuote()
+    description: Quotes a string as a JSON value by wrapping it with double 
quote characters, escaping interior quote and special characters ('"', '\', 
'/', 'b', 'f', 'n', 'r', 't'), and returning the result as a string. If the 
argument is NULL, the function returns NULL.
+  - sql: JSON_UNQUOTE(string)
+    table: STRING.JsonUnquote()
+    description: Unquotes JSON value, escapes special characters ('"', '\', 
'/', 'b', 'f', 'n', 'r', 't', 'u' hex hex hex hex), and returns the result as a 
string. If the argument is NULL, returns NULL. If the value starts and ends 
with double quotes but is not a valid JSON string literal, the value is passed 
through unmodified.

Review Comment:
   ```suggestion
       description: Unquotes JSON value, unescapes escaped special characters 
('"', '\', '/', 'b', 'f', 'n', 'r', 't', 'u' hex hex hex hex), and returns the 
result as a string. If the argument is NULL, returns NULL. If the value starts 
and ends with double quotes but is not a valid JSON string literal, the value 
is passed through unmodified.
   ```
   
   we are unescaping (previously) escaped characters, right?



##########
flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/functions/JsonFunctionsITCase.java:
##########
@@ -794,6 +795,196 @@ private static List<TestSetSpec> jsonObjectSpec() {
                                 STRING().notNull()));
     }
 
+    private static List<TestSetSpec> jsonQuoteSpec() {
+
+        return Arrays.asList(
+                TestSetSpec.forFunction(BuiltInFunctionDefinitions.JSON_QUOTE)
+                        .onFieldsWithData(0)
+                        .testResult(
+                                nullOf(STRING()).jsonQuote(),
+                                "JSON_QUOTE(CAST(NULL AS STRING))",
+                                null,
+                                STRING().nullable()),
+                TestSetSpec.forFunction(BuiltInFunctionDefinitions.JSON_QUOTE)
+                        .onFieldsWithData(
+                                "V",
+                                "\"null\"",
+                                "[1, 2, 3]",
+                                "This is a \t test \n with special characters: 
\" \\ \b \f \r \u0041",
+                                "\"kv_pair_test\": \"\\b\\f\\r\"",
+                                "\ttab and fwd slash /",
+                                "this will not be quoted \\u006z",
+                                "this will be quoted ≠",
+                                null)
+                        .andDataTypes(
+                                STRING().notNull(),
+                                STRING().notNull(),
+                                STRING().notNull(),
+                                STRING().notNull(),
+                                STRING().notNull(),
+                                STRING().notNull(),
+                                STRING().notNull(),
+                                STRING().notNull(),
+                                STRING().nullable())
+                        .testResult(
+                                $("f0").jsonQuote(), "JSON_QUOTE(f0)", 
"\"V\"", STRING().notNull())
+                        .testResult(
+                                $("f1").jsonQuote(),
+                                "JSON_QUOTE(f1)",
+                                "\"\\\"null\\\"\"",
+                                STRING().notNull())
+                        .testResult(
+                                $("f2").jsonQuote(),
+                                "JSON_QUOTE(f2)",
+                                "\"[1, 2, 3]\"",
+                                STRING().notNull())
+                        .testResult(
+                                $("f3").jsonQuote(),
+                                "JSON_QUOTE(f3)",
+                                "\"This is a \\t test \\n with special 
characters: \\\" \\\\ \\b \\f \\r A\"",
+                                STRING().notNull())
+                        .testResult(
+                                $("f4").jsonQuote(),
+                                "JSON_QUOTE(f4)",
+                                "\"\\\"kv_pair_test\\\": 
\\\"\\\\b\\\\f\\\\r\\\"\"",
+                                STRING().notNull())
+                        .testResult(
+                                $("f5").jsonQuote(),
+                                "JSON_QUOTE(f5)",
+                                "\"\\ttab and fwd slash \\/\"",
+                                STRING().notNull())
+                        .testResult(
+                                $("f6").jsonQuote(),
+                                "JSON_QUOTE(f6)",
+                                "\"this will not be quoted \\\\u006z\"",
+                                STRING().notNull())
+                        .testResult(
+                                $("f7").jsonQuote(),
+                                "JSON_QUOTE(f7)",
+                                "\"this will be quoted \\u2260\"",
+                                STRING().notNull())
+                        .testResult(
+                                $("f8").jsonQuote(), "JSON_QUOTE(f8)", null, 
STRING().nullable()));
+    }
+
+    private static List<TestSetSpec> jsonUnquoteSpec() {
+
+        return Arrays.asList(
+                
TestSetSpec.forFunction(BuiltInFunctionDefinitions.JSON_UNQUOTE)
+                        .onFieldsWithData(0)
+                        .testResult(
+                                nullOf(STRING()).jsonQuote(),
+                                "JSON_UNQUOTE(CAST(NULL AS STRING))",
+                                null,
+                                STRING().nullable()),
+                
TestSetSpec.forFunction(BuiltInFunctionDefinitions.JSON_UNQUOTE)

Review Comment:
   can we split the TestSetSpec into two specs, one with valid Json input and 
the other with invalid (for which the input is returned)?



##########
flink-table/flink-table-planner/src/test/scala/org/apache/flink/table/planner/expressions/ScalarFunctionsTest.scala:
##########
@@ -604,6 +604,49 @@ class ScalarFunctionsTest extends ScalarTypesTestBase {
       "foothebar")
   }
 
+  @Test
+  def testJsonQuote(): Unit = {
+    testSqlApi("JSON_QUOTE('null')", "\"null\"")
+    testSqlApi("JSON_QUOTE('\"null\"')", "\"\\\"null\\\"\"")
+    testSqlApi("JSON_QUOTE('[1,2,3]')", "\"[1,2,3]\"")
+    testSqlApi("JSON_UNQUOTE(JSON_QUOTE('[1,2,3]'))", "[1,2,3]")
+    testSqlApi(
+      "JSON_QUOTE('This is a \\t test \\n with special characters: \" \\ \\b 
\\f \\r \\u0041')",
+      "\"This is a \\\\t test \\\\n with special characters: \\\" \\\\ \\\\b 
\\\\f \\\\r \\\\u0041\""
+    )
+    testSqlApi(
+      "JSON_QUOTE('\"special\": \"\\b\\f\\r\"')",
+      "\"\\\"special\\\": \\\"\\\\b\\\\f\\\\r\\\"\"")
+    testSqlApi(
+      "JSON_QUOTE('skipping backslash \')",
+      "\"skipping backslash \""
+    )
+    testSqlApi(
+      "JSON_QUOTE('this will be quoted ≠')",
+      "\"this will be quoted \\u2260\""
+    )
+  }
+
+  @Test
+  def testJsonUnquote(): Unit = {

Review Comment:
   Add some test cases with invalid JSON input?



##########
flink-python/pyflink/table/expression.py:
##########
@@ -1954,6 +1956,25 @@ def json_query(self, path: str, 
wrapping_behavior=JsonQueryWrapper.WITHOUT_ARRAY
                                         
on_empty._to_j_json_query_on_error_or_empty(),
                                         
on_error._to_j_json_query_on_error_or_empty())
 
+    def json_quote(self) -> 'Expression':
+        """
+        Quotes a string as a JSON value by wrapping it with double quote 
characters,
+        escaping interior quote and special characters
+        ('"', '\', '/', 'b', 'f', 'n', 'r', 't'), and returning
+        the result as a string. If the argument is NULL, the function returns 
NULL.
+        """
+        return _unary_op("jsonQuote")(self)
+
+    def json_unquote(self) -> 'Expression':
+        """
+        Unquotes JSON value, escapes spacial characters

Review Comment:
   ```suggestion
           Unquotes JSON value, unescapes escaped spacial characters
   ```



-- 
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.

To unsubscribe, e-mail: issues-unsubscr...@flink.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org

Reply via email to