twalthr commented on a change in pull request #16776:
URL: https://github.com/apache/flink/pull/16776#discussion_r687632062



##########
File path: flink-python/pyflink/table/expression.py
##########
@@ -1393,6 +1414,47 @@ def json_exists(self, path: str, on_error: 
JsonExistsOnError = None) -> 'Express
         else:
             return _ternary_op("jsonExists")(self, path, 
on_error._to_j_json_exists_on_error())
 
+    def json_value(self,
+                   path: str,
+                   returning_type: DataType = None,
+                   on_empty: JsonValueOnEmptyOrError = None,
+                   default_on_empty: Any = None,
+                   on_error: JsonValueOnEmptyOrError = None,
+                   default_on_error: Any = None) -> 'Expression':
+        """
+        Extracts a scalar from a JSON string.
+
+        This method searches a JSON string for a given path expression and 
returns the value if the
+        value at that path is scalar. Non-scalar values cannot be returned. By 
default, the value is
+        returned as `DataTypes.STRING()`. Using `returningType` a different 
type can be chosen, with
+        types with the following type roots being supported:
+
+        * `VARCHAR`
+        * `BOOLEAN`
+        * `INTEGER`
+        * `DOUBLE`
+
+        For empty path expressions or errors a behavior can be defined to 
either return `null`,
+        raise an error or return a defined default value instead.
+
+        Examples:
+        ::
+
+            >>> lit('{"a": true}').json_value('$.a')
+            >>> lit('{"a": true}').json_value('$.a', DataTypes.BOOLEAN())
+            >>> lit('{"a": true}').json_value('lax $.b', \

Review comment:
       `JsonValueOnEmptyOrError.NULL, null` is not required in Python, right?

##########
File path: docs/data/sql_functions.yml
##########
@@ -596,6 +596,41 @@ json:
         'strict $.b' FALSE ON ERROR);
       ```
 
+  - sql: JSON_VALUE(jsonValue, path [RETURNING <expr>] [ { NULL | ERROR | 
DEFAULT <defaultExpr> } ON EMPTY ] [ { NULL | ERROR | DEFAULT <defaultExpr> } 
ON ERROR ])

Review comment:
       `RETURNING <dataType>`

##########
File path: 
flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/api/internal/BaseExpressions.java
##########
@@ -1323,4 +1327,209 @@ public OutType jsonExists(String path, 
JsonExistsOnError onError) {
     public OutType jsonExists(String path) {
         return toApiSpecificExpression(unresolvedCall(JSON_EXISTS, toExpr(), 
valueLiteral(path)));
     }
+
+    /**
+     * Extracts a scalar from a JSON string.
+     *
+     * <p>This method searches a JSON string for a given path expression and 
returns the value if
+     * the value at that path is scalar. Non-scalar values cannot be returned. 
By default, the value
+     * is returned as {@link DataTypes#STRING()}. Using {@param returningType} 
a different type can
+     * be chosen, with the following types being supported:
+     *
+     * <ul>
+     *   <li>{@link LogicalTypeRoot#VARCHAR}
+     *   <li>{@link LogicalTypeRoot#BOOLEAN}
+     *   <li>{@link LogicalTypeRoot#INTEGER}
+     *   <li>{@link LogicalTypeRoot#DOUBLE}
+     * </ul>
+     *
+     * <p>For empty path expressions or errors a behavior can be defined to 
either return {@code
+     * null}, raise an error or return a defined default value instead.
+     *
+     * <p>Examples:
+     *
+     * <pre>{@code
+     * // STRING: "true"
+     * lit("{\"a\": true}").jsonValue("$.a")
+     *
+     * // BOOLEAN: true
+     * lit("{\"a\": true}").jsonValue("$.a", DataTypes.BOOLEAN())
+     *
+     * // BOOLEAN: "false"
+     * lit("{\"a\": true}").jsonValue("lax $.b",
+     *     JsonValueOnEmptyOrError.DEFAULT, false, 
JsonValueOnEmptyOrError.NULL, null)
+     *
+     * // BOOLEAN: "false"
+     * lit("{\"a\": true}").jsonValue("strict $.b",
+     *     JsonValueOnEmptyOrError.NULL, null, 
JsonValueOnEmptyOrError.DEFAULT, false)
+     * }</pre>
+     *
+     * @param path JSON path to extract.
+     * @param returningType Type to convert the extracted scalar to, otherwise 
defaults to {@link
+     *     DataTypes#STRING()}.
+     * @param onEmpty Behavior in case the path expression is empty.
+     * @param defaultOnEmpty Default value to return if the path expression is 
empty and {@param
+     *     onEmpty} is set to {@link JsonValueOnEmptyOrError#DEFAULT}.
+     * @param onError Behavior in case of an error.
+     * @param defaultOnError Default value to return if there is an error and 
{@param onError} is
+     *     set to {@link JsonValueOnEmptyOrError#DEFAULT}.
+     * @return The extracted scalar value.
+     */
+    public OutType jsonValue(
+            String path,
+            DataType returningType,
+            JsonValueOnEmptyOrError onEmpty,
+            InType defaultOnEmpty,
+            JsonValueOnEmptyOrError onError,
+            InType defaultOnError) {
+        return toApiSpecificExpression(
+                unresolvedCall(
+                        JSON_VALUE,
+                        toExpr(),
+                        valueLiteral(path),
+                        typeLiteral(returningType),
+                        valueLiteral(onEmpty),
+                        objectToExpression(defaultOnEmpty),
+                        valueLiteral(onError),
+                        objectToExpression(defaultOnError)));
+    }
+
+    /**
+     * Extracts a scalar from a JSON string.
+     *
+     * <p>This method searches a JSON string for a given path expression and 
returns the value if
+     * the value at that path is scalar. Non-scalar values cannot be returned. 
By default, the value
+     * is returned as {@link DataTypes#STRING()}.
+     *
+     * <p>For empty path expressions or errors a behavior can be defined to 
either return {@code
+     * null}, raise an error or return a defined default value instead.
+     *
+     * <p>See also {@link #jsonValue(String, DataType, 
JsonValueOnEmptyOrError, Object,
+     * JsonValueOnEmptyOrError, Object)}.
+     *
+     * <p>Examples:
+     *
+     * <pre>{@code
+     * // STRING: "true"
+     * lit("{\"a\": true}").jsonValue("$.a")
+     *
+     * // BOOLEAN: true
+     * lit("{\"a\": true}").jsonValue("$.a", DataTypes.BOOLEAN())
+     *
+     * // BOOLEAN: "false"
+     * lit("{\"a\": true}").jsonValue("lax $.b",
+     *     JsonValueOnEmptyOrError.DEFAULT, false, 
JsonValueOnEmptyOrError.NULL, null)
+     *
+     * // BOOLEAN: "false"
+     * lit("{\"a\": true}").jsonValue("strict $.b",
+     *     JsonValueOnEmptyOrError.NULL, null, 
JsonValueOnEmptyOrError.DEFAULT, false)
+     * }</pre>
+     *
+     * @param path JSON path to extract.
+     * @param onEmpty Behavior in case the path expression is empty.
+     * @param defaultOnEmpty Default value to return if the path expression is 
empty and {@param
+     *     onEmpty} is set to {@link JsonValueOnEmptyOrError#DEFAULT}.
+     * @param onError Behavior in case of an error.
+     * @param defaultOnError Default value to return if there is an error and 
{@param onError} is
+     *     set to {@link JsonValueOnEmptyOrError#DEFAULT}.
+     * @return The extracted scalar value.
+     */
+    public OutType jsonValue(

Review comment:
       Keep the first paragraph of the JavaDoc but then link to the full 
signature for explanation in the second paragraph and only explain the 
difference in the third paragraph. Also for other methods below.

##########
File path: docs/data/sql_functions.yml
##########
@@ -596,6 +596,41 @@ json:
         'strict $.b' FALSE ON ERROR);
       ```
 
+  - sql: JSON_VALUE(jsonValue, path [RETURNING <expr>] [ { NULL | ERROR | 
DEFAULT <defaultExpr> } ON EMPTY ] [ { NULL | ERROR | DEFAULT <defaultExpr> } 
ON ERROR ])
+    table: STRING.jsonValue(STRING path [, returnType, onEmpty, 
defaultOnEmpty, onError, defaultOnError])
+    description: |
+      Extracts a scalar from a JSON string.
+
+      This method searches a JSON string for a given path expression and 
returns the value if the
+      value at that path is scalar. Non-scalar values cannot be returned. By 
default, the value is
+      returned as `DataTypes#STRING()`. Using `returningType` a different type 
can be chosen, with

Review comment:
       you can simple use `STRING` here as the SQL user has no access to 
`DataTypes#`

##########
File path: flink-python/pyflink/table/expression.py
##########
@@ -1393,6 +1414,47 @@ def json_exists(self, path: str, on_error: 
JsonExistsOnError = None) -> 'Express
         else:
             return _ternary_op("jsonExists")(self, path, 
on_error._to_j_json_exists_on_error())
 
+    def json_value(self,
+                   path: str,
+                   returning_type: DataType = None,
+                   on_empty: JsonValueOnEmptyOrError = None,
+                   default_on_empty: Any = None,

Review comment:
       looking at `between(self, lower_bound, upper_bound)` I see that others 
have omitted the `Any`, is it necessary?

##########
File path: 
flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/functions/BuiltInFunctionTestBase.java
##########
@@ -295,8 +295,17 @@ TestSpec testResult(
                 String sqlExpression,
                 Object result,
                 AbstractDataType<?> dataType) {
-            testItems.add(new TableApiResultTestItem(expression, result, 
dataType));
-            testItems.add(new SqlResultTestItem(sqlExpression, result, 
dataType));
+            return testResult(expression, sqlExpression, result, dataType, 
dataType);

Review comment:
       can be a hotfix commit

##########
File path: 
flink-table/flink-table-common/src/main/java/org/apache/flink/table/types/inference/strategies/JsonValueInputTypeStrategy.java
##########
@@ -0,0 +1,129 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.types.inference.strategies;
+
+import org.apache.flink.annotation.Internal;
+import org.apache.flink.table.api.ValidationException;
+import org.apache.flink.table.functions.BuiltInFunctionDefinitions;
+import org.apache.flink.table.functions.FunctionDefinition;
+import org.apache.flink.table.types.DataType;
+import org.apache.flink.table.types.inference.ArgumentCount;
+import org.apache.flink.table.types.inference.CallContext;
+import org.apache.flink.table.types.inference.InputTypeStrategy;
+import org.apache.flink.table.types.inference.Signature;
+import org.apache.flink.table.types.logical.LogicalTypeFamily;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+
+import static org.apache.flink.table.types.inference.Signature.Argument.of;
+
+/** {@link InputTypeStrategy} specific for {@link 
BuiltInFunctionDefinitions#JSON_VALUE}. */
+@Internal
+class JsonValueInputTypeStrategy implements InputTypeStrategy {
+
+    @Override
+    public ArgumentCount getArgumentCount() {
+        return new ArgumentCount() {
+            @Override
+            public boolean isValidCount(int count) {
+                return true;
+            }
+
+            @Override
+            public Optional<Integer> getMinCount() {
+                return Optional.of(2);
+            }
+
+            @Override
+            public Optional<Integer> getMaxCount() {
+                return Optional.of(7);
+            }
+        };
+    }
+
+    @Override
+    public Optional<List<DataType>> inferInputTypes(
+            CallContext callContext, boolean throwOnFailure) {
+        try {
+            validateJsonValueArgument(callContext);
+            validateJsonPathArgument(callContext);
+            validateExplicitReturnArgument(callContext);
+
+            return Optional.of(callContext.getArgumentDataTypes());
+        } catch (ValidationException e) {
+            if (throwOnFailure) {
+                throw e;
+            } else {
+                return Optional.empty();
+            }
+        }
+    }
+
+    @Override
+    public List<Signature> getExpectedSignatures(FunctionDefinition 
definition) {
+        return Collections.singletonList(Signature.of(of("*")));
+    }
+
+    // 
---------------------------------------------------------------------------------------------
+
+    private void validateJsonValueArgument(CallContext callContext) {

Review comment:
       this logic is error prone, it would be safer to rely on already 
available strategies. since we only expose 3 variants in Table API, maybe it 
would be better to just list those as a couple of `sequence()` instead.

##########
File path: 
flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/planner/codegen/calls/FunctionGenerator.scala
##########
@@ -854,7 +854,7 @@ class FunctionGenerator private(config: TableConfig) {
     operandTypes: Seq[LogicalType],
     resultType: LogicalType)
   : Option[CallGenerator] = sqlOperator match {
-    // built-in scalar function
+    case JSON_VALUE => Some(new JsonValueCallGen())

Review comment:
       this is hard to find, wouldn't be the layer above be more appropriate 
where CAST and other custom one are? or would that be more than a single line 
change then?

##########
File path: 
flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/planner/codegen/calls/BuiltInMethods.scala
##########
@@ -18,16 +18,16 @@
 
 package org.apache.flink.table.planner.codegen.calls
 
-import org.apache.flink.table.data.{DecimalData, TimestampData}
-import org.apache.flink.table.runtime.functions._
-import org.apache.calcite.avatica.util.{DateTimeUtils, TimeUnitRange}
-import org.apache.calcite.linq4j.tree.Types
-import org.apache.calcite.runtime.{JsonFunctions, SqlFunctions}
 import java.lang.reflect.Method
 import java.lang.{Byte => JByte, Integer => JInteger, Long => JLong, Short => 
JShort}
 import java.util.TimeZone
 
-import org.apache.calcite.sql.SqlJsonExistsErrorBehavior
+import org.apache.calcite.avatica.util.{DateTimeUtils, TimeUnitRange}

Review comment:
       Are you imports correctly configured? 

##########
File path: docs/data/sql_functions.yml
##########
@@ -596,6 +596,41 @@ json:
         'strict $.b' FALSE ON ERROR);
       ```
 
+  - sql: JSON_VALUE(jsonValue, path [RETURNING <expr>] [ { NULL | ERROR | 
DEFAULT <defaultExpr> } ON EMPTY ] [ { NULL | ERROR | DEFAULT <defaultExpr> } 
ON ERROR ])
+    table: STRING.jsonValue(STRING path [, returnType, onEmpty, 
defaultOnEmpty, onError, defaultOnError])
+    description: |
+      Extracts a scalar from a JSON string.
+
+      This method searches a JSON string for a given path expression and 
returns the value if the
+      value at that path is scalar. Non-scalar values cannot be returned. By 
default, the value is
+      returned as `DataTypes#STRING()`. Using `returningType` a different type 
can be chosen, with

Review comment:
       ```
   Using `returningType` a different data type can be chosen, currently 
supported are:
   STRING
   ```
   type roots are more an internal thing

##########
File path: docs/data/sql_functions.yml
##########
@@ -596,6 +596,41 @@ json:
         'strict $.b' FALSE ON ERROR);
       ```
 
+  - sql: JSON_VALUE(jsonValue, path [RETURNING <expr>] [ { NULL | ERROR | 
DEFAULT <defaultExpr> } ON EMPTY ] [ { NULL | ERROR | DEFAULT <defaultExpr> } 
ON ERROR ])
+    table: STRING.jsonValue(STRING path [, returnType, onEmpty, 
defaultOnEmpty, onError, defaultOnError])
+    description: |
+      Extracts a scalar from a JSON string.
+
+      This method searches a JSON string for a given path expression and 
returns the value if the
+      value at that path is scalar. Non-scalar values cannot be returned. By 
default, the value is
+      returned as `DataTypes#STRING()`. Using `returningType` a different type 
can be chosen, with
+      types with the following type roots being supported:
+
+      * `VARCHAR`
+      * `BOOLEAN`
+      * `INTEGER`
+      * `DOUBLE`
+
+      For empty path expressions or errors a behavior can be defined to either 
return `null`, raise
+      an error or return a defined default value instead. When omitted, the 
default is
+      `NULL ON EMPTY` or `NULL ON ERROR`, respectively.
+
+      ```
+      // STRING: "true"
+      JSON_VALUE('{"a": true}', '$.a')
+
+      // BOOLEAN: true
+      JSON_VALUE('{"a": true}', '$.a' RETURNING BOOLEAN)
+
+      // BOOLEAN: 'false'

Review comment:
       Some questions by just reading the docs:
   - Is this still boolean? Derived from the default value or how does this 
work?
   - `'false'` vs. `true` above?
   - Does the default/error value need to be the same type as return type?
   - Does the default/error value need to be a literal?

##########
File path: 
flink-table/flink-table-common/src/main/java/org/apache/flink/table/types/inference/strategies/JsonValueInputTypeStrategy.java
##########
@@ -0,0 +1,129 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.types.inference.strategies;
+
+import org.apache.flink.annotation.Internal;
+import org.apache.flink.table.api.ValidationException;
+import org.apache.flink.table.functions.BuiltInFunctionDefinitions;
+import org.apache.flink.table.functions.FunctionDefinition;
+import org.apache.flink.table.types.DataType;
+import org.apache.flink.table.types.inference.ArgumentCount;
+import org.apache.flink.table.types.inference.CallContext;
+import org.apache.flink.table.types.inference.InputTypeStrategy;
+import org.apache.flink.table.types.inference.Signature;
+import org.apache.flink.table.types.logical.LogicalTypeFamily;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+
+import static org.apache.flink.table.types.inference.Signature.Argument.of;
+
+/** {@link InputTypeStrategy} specific for {@link 
BuiltInFunctionDefinitions#JSON_VALUE}. */
+@Internal
+class JsonValueInputTypeStrategy implements InputTypeStrategy {
+
+    @Override
+    public ArgumentCount getArgumentCount() {
+        return new ArgumentCount() {

Review comment:
       Use `ConstantArgumentCount.between`

##########
File path: 
flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/functions/JsonValueITCase.java
##########
@@ -0,0 +1,167 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.table.planner.functions;
+
+import org.apache.flink.table.api.DataTypes;
+import org.apache.flink.table.api.JsonValueOnEmptyOrError;
+import org.apache.flink.table.functions.BuiltInFunctionDefinitions;
+import org.apache.flink.table.types.DataType;
+
+import org.apache.commons.io.IOUtils;
+import org.junit.runners.Parameterized;
+
+import java.io.InputStream;
+import java.nio.charset.Charset;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.apache.flink.table.api.Expressions.$;
+import static org.apache.flink.table.api.Expressions.lit;
+
+/** Tests for {@link BuiltInFunctionDefinitions#JSON_VALUE}. */
+public class JsonValueITCase extends BuiltInFunctionTestBase {

Review comment:
       we should group ITCases for efficiency, we can merge all JSON functions 
in one class

##########
File path: 
flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/api/internal/BaseExpressions.java
##########
@@ -1323,4 +1327,209 @@ public OutType jsonExists(String path, 
JsonExistsOnError onError) {
     public OutType jsonExists(String path) {
         return toApiSpecificExpression(unresolvedCall(JSON_EXISTS, toExpr(), 
valueLiteral(path)));
     }
+
+    /**
+     * Extracts a scalar from a JSON string.
+     *
+     * <p>This method searches a JSON string for a given path expression and 
returns the value if
+     * the value at that path is scalar. Non-scalar values cannot be returned. 
By default, the value
+     * is returned as {@link DataTypes#STRING()}. Using {@param returningType} 
a different type can
+     * be chosen, with the following types being supported:
+     *
+     * <ul>
+     *   <li>{@link LogicalTypeRoot#VARCHAR}
+     *   <li>{@link LogicalTypeRoot#BOOLEAN}
+     *   <li>{@link LogicalTypeRoot#INTEGER}
+     *   <li>{@link LogicalTypeRoot#DOUBLE}
+     * </ul>
+     *
+     * <p>For empty path expressions or errors a behavior can be defined to 
either return {@code
+     * null}, raise an error or return a defined default value instead.
+     *
+     * <p>Examples:
+     *
+     * <pre>{@code
+     * // STRING: "true"
+     * lit("{\"a\": true}").jsonValue("$.a")
+     *
+     * // BOOLEAN: true
+     * lit("{\"a\": true}").jsonValue("$.a", DataTypes.BOOLEAN())
+     *
+     * // BOOLEAN: "false"
+     * lit("{\"a\": true}").jsonValue("lax $.b",
+     *     JsonValueOnEmptyOrError.DEFAULT, false, 
JsonValueOnEmptyOrError.NULL, null)
+     *
+     * // BOOLEAN: "false"
+     * lit("{\"a\": true}").jsonValue("strict $.b",
+     *     JsonValueOnEmptyOrError.NULL, null, 
JsonValueOnEmptyOrError.DEFAULT, false)
+     * }</pre>
+     *
+     * @param path JSON path to extract.
+     * @param returningType Type to convert the extracted scalar to, otherwise 
defaults to {@link
+     *     DataTypes#STRING()}.
+     * @param onEmpty Behavior in case the path expression is empty.
+     * @param defaultOnEmpty Default value to return if the path expression is 
empty and {@param
+     *     onEmpty} is set to {@link JsonValueOnEmptyOrError#DEFAULT}.
+     * @param onError Behavior in case of an error.
+     * @param defaultOnError Default value to return if there is an error and 
{@param onError} is
+     *     set to {@link JsonValueOnEmptyOrError#DEFAULT}.
+     * @return The extracted scalar value.
+     */
+    public OutType jsonValue(
+            String path,
+            DataType returningType,
+            JsonValueOnEmptyOrError onEmpty,
+            InType defaultOnEmpty,
+            JsonValueOnEmptyOrError onError,
+            InType defaultOnError) {
+        return toApiSpecificExpression(
+                unresolvedCall(
+                        JSON_VALUE,
+                        toExpr(),
+                        valueLiteral(path),
+                        typeLiteral(returningType),
+                        valueLiteral(onEmpty),
+                        objectToExpression(defaultOnEmpty),
+                        valueLiteral(onError),
+                        objectToExpression(defaultOnError)));
+    }
+
+    /**
+     * Extracts a scalar from a JSON string.
+     *
+     * <p>This method searches a JSON string for a given path expression and 
returns the value if
+     * the value at that path is scalar. Non-scalar values cannot be returned. 
By default, the value
+     * is returned as {@link DataTypes#STRING()}.
+     *
+     * <p>For empty path expressions or errors a behavior can be defined to 
either return {@code
+     * null}, raise an error or return a defined default value instead.
+     *
+     * <p>See also {@link #jsonValue(String, DataType, 
JsonValueOnEmptyOrError, Object,
+     * JsonValueOnEmptyOrError, Object)}.
+     *
+     * <p>Examples:
+     *
+     * <pre>{@code
+     * // STRING: "true"
+     * lit("{\"a\": true}").jsonValue("$.a")
+     *
+     * // BOOLEAN: true
+     * lit("{\"a\": true}").jsonValue("$.a", DataTypes.BOOLEAN())
+     *
+     * // BOOLEAN: "false"
+     * lit("{\"a\": true}").jsonValue("lax $.b",
+     *     JsonValueOnEmptyOrError.DEFAULT, false, 
JsonValueOnEmptyOrError.NULL, null)
+     *
+     * // BOOLEAN: "false"
+     * lit("{\"a\": true}").jsonValue("strict $.b",
+     *     JsonValueOnEmptyOrError.NULL, null, 
JsonValueOnEmptyOrError.DEFAULT, false)
+     * }</pre>
+     *
+     * @param path JSON path to extract.
+     * @param onEmpty Behavior in case the path expression is empty.
+     * @param defaultOnEmpty Default value to return if the path expression is 
empty and {@param
+     *     onEmpty} is set to {@link JsonValueOnEmptyOrError#DEFAULT}.
+     * @param onError Behavior in case of an error.
+     * @param defaultOnError Default value to return if there is an error and 
{@param onError} is
+     *     set to {@link JsonValueOnEmptyOrError#DEFAULT}.
+     * @return The extracted scalar value.
+     */
+    public OutType jsonValue(

Review comment:
       How about we drop this method and only offer a single "if error or empty 
take this default value" method? I think this is the most common case.




-- 
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: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


Reply via email to