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

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


The following commit(s) were added to refs/heads/master by this push:
     new 2c768cde3ba [FLINK-40852][table] Treat `NULL` allowDuplicateKeys as 
false in `PARSE_JSON` and `TRY_PARSE_JSON`
2c768cde3ba is described below

commit 2c768cde3bacf9e09b9791fdd91e4f3731614c36
Author: Moritz Manner <[email protected]>
AuthorDate: Wed Oct 7 13:25:24 2026 +0200

    [FLINK-40852][table] Treat `NULL` allowDuplicateKeys as false in 
`PARSE_JSON` and `TRY_PARSE_JSON`
---
 docs/data/sql_functions.yml                        | 10 ++---
 docs/data/sql_functions_zh.yml                     | 14 ++++---
 .../functions/BuiltInFunctionDefinitions.java      |  4 +-
 .../planner/functions/JsonFunctionsITCase.java     | 44 +++++++++++++++++++---
 .../functions/scalar/ParseJsonFunction.java        |  7 +++-
 .../functions/scalar/TryParseJsonFunction.java     |  7 +++-
 6 files changed, 65 insertions(+), 21 deletions(-)

diff --git a/docs/data/sql_functions.yml b/docs/data/sql_functions.yml
index ee94bf1794f..c53b6767ade 100644
--- a/docs/data/sql_functions.yml
+++ b/docs/data/sql_functions.yml
@@ -1371,7 +1371,7 @@ variant:
       If there are duplicate keys in the input JSON string, when 
`allowDuplicateKeys` is true, the
       parser will keep the last occurrence of all fields with the same key, 
otherwise when
       `allowDuplicateKeys` is false it will throw an error. The default value 
of
-      `allowDuplicateKeys` is false.
+      `allowDuplicateKeys` is false. A NULL `allowDuplicateKeys` is treated as 
false.
 
       See the `VARIANT` data type documentation for how JSON values are mapped 
to variant kinds.
   - sql: TRY_PARSE_JSON(json_string[, allow_duplicate_keys])
@@ -1380,10 +1380,10 @@ variant:
       Try to parse a JSON string into a Variant if possible. If the JSON 
string is invalid, return
       NULL. To throw an error instead of returning NULL, use the `PARSE_JSON` 
function.
 
-      If there are duplicate keys in the input JSON string, when 
`allowDuplicateKeys` is true, the 
-      parser will keep the last occurrence of all fields with the same key, 
otherwise when 
-      `allowDuplicateKeys` is false it will throw an error. The default value 
of 
-      `allowDuplicateKeys` is false.
+      If there are duplicate keys in the input JSON string, when 
`allowDuplicateKeys` is true, the
+      parser will keep the last occurrence of all fields with the same key, 
otherwise when
+      `allowDuplicateKeys` is false it will return NULL. The default value of
+      `allowDuplicateKeys` is false. A NULL `allowDuplicateKeys` is treated as 
false.
 
       See the `VARIANT` data type documentation for how JSON values are mapped 
to variant kinds.
   - sql: JSON_STRING(variant)
diff --git a/docs/data/sql_functions_zh.yml b/docs/data/sql_functions_zh.yml
index a6c6fa074b3..7c0a4e95d15 100644
--- a/docs/data/sql_functions_zh.yml
+++ b/docs/data/sql_functions_zh.yml
@@ -1461,9 +1461,10 @@ variant:
       将 JSON 字符串解析为 Variant。如果 JSON 字符串无效,将抛出错误。如果希望返回 NULL 而不是抛出错误,
       请使用 `TRY_PARSE_JSON` 函数。  
       
-      如果输入的 JSON 字符串中存在重复的键,当 allowDuplicateKeys 为 true 时,解析器会保留最后一个出现的具有相
-      同键的字段,否则当 allowDuplicateKeys 为 false 时,它会抛出一个错误。默认情况下,
-      allowDuplicateKeys 的值为 false。
+      If there are duplicate keys in the input JSON string, when 
`allowDuplicateKeys` is true, the
+      parser will keep the last occurrence of all fields with the same key, 
otherwise when
+      `allowDuplicateKeys` is false it will throw an error. The default value 
of
+      `allowDuplicateKeys` is false. A NULL `allowDuplicateKeys` is treated as 
false.
 
       See the `VARIANT` data type documentation for how JSON values are mapped 
to variant kinds.
 
@@ -1473,9 +1474,10 @@ variant:
       尽可能将 JSON 字符串解析为 Variant。如果 JSON 字符串无效,则返回 NULL。如果希望抛出错误而不是返回 NULL,
       请使用 `PARSE_JSON` 函数。  
       
-      如果输入的 JSON 字符串中存在重复的键,当 allowDuplicateKeys 为 true 时,解析器会保留最后一个出现的具有相
-      同键的字段,否则当 allowDuplicateKeys 为 false 时,它会抛出一个错误。默认情况下,
-      allowDuplicateKeys 的值为 false。
+      If there are duplicate keys in the input JSON string, when 
`allowDuplicateKeys` is true, the
+      parser will keep the last occurrence of all fields with the same key, 
otherwise when
+      `allowDuplicateKeys` is false it will return NULL. The default value of
+      `allowDuplicateKeys` is false. A NULL `allowDuplicateKeys` is treated as 
false.
 
       See the `VARIANT` data type documentation for how JSON values are mapped 
to variant kinds.
 
diff --git 
a/flink-table/flink-table-common/src/main/java/org/apache/flink/table/functions/BuiltInFunctionDefinitions.java
 
b/flink-table/flink-table-common/src/main/java/org/apache/flink/table/functions/BuiltInFunctionDefinitions.java
index 08cc761375b..0bcb4c56649 100644
--- 
a/flink-table/flink-table-common/src/main/java/org/apache/flink/table/functions/BuiltInFunctionDefinitions.java
+++ 
b/flink-table/flink-table-common/src/main/java/org/apache/flink/table/functions/BuiltInFunctionDefinitions.java
@@ -3190,7 +3190,9 @@ public final class BuiltInFunctionDefinitions {
                                     sequence(
                                             
logical(LogicalTypeFamily.CHARACTER_STRING),
                                             logical(LogicalTypeRoot.BOOLEAN))))
-                    
.outputTypeStrategy(nullableIfArgs(explicit(DataTypes.VARIANT())))
+                    .outputTypeStrategy(
+                            nullableIfArgs(
+                                    ConstantArgumentCount.of(0), 
explicit(DataTypes.VARIANT())))
                     .runtimeClass(
                             
"org.apache.flink.table.runtime.functions.scalar.ParseJsonFunction")
                     .build();
diff --git 
a/flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/functions/JsonFunctionsITCase.java
 
b/flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/functions/JsonFunctionsITCase.java
index 3d8d6eefa4e..2cd54053210 100644
--- 
a/flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/functions/JsonFunctionsITCase.java
+++ 
b/flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/functions/JsonFunctionsITCase.java
@@ -1036,8 +1036,13 @@ class JsonFunctionsITCase extends 
BuiltInFunctionTestBase {
         // The bulk of parsing behavior is covered by 
BinaryVariantInternalBuilderTest.
         return List.of(
                 TestSetSpec.forFunction(BuiltInFunctionDefinitions.PARSE_JSON)
-                        .onFieldsWithData("{\"a\":1,\"b\":[2,3]}", "1e400", 
"{\"a\":1,\"a\":2}")
-                        .andDataTypes(STRING().notNull(), STRING().notNull(), 
STRING().notNull())
+                        .onFieldsWithData(
+                                "{\"a\":1,\"b\":[2,3]}", "1e400", 
"{\"a\":1,\"a\":2}", null)
+                        .andDataTypes(
+                                STRING().notNull(),
+                                STRING().notNull(),
+                                STRING().notNull(),
+                                BOOLEAN())
                         .testResult(
                                 jsonString($("f0").parseJson()),
                                 "JSON_STRING(PARSE_JSON(f0))",
@@ -1070,10 +1075,28 @@ class JsonFunctionsITCase extends 
BuiltInFunctionTestBase {
                                 jsonString($("f2").parseJson(true)),
                                 "JSON_STRING(PARSE_JSON(f2, true))",
                                 "{\"a\":2}",
-                                STRING().notNull()),
+                                STRING().notNull())
+                        // a NULL allowDuplicateKeys is treated as false
+                        .testResult(
+                                jsonString(call("PARSE_JSON", $("f0"), 
$("f3"))),
+                                "JSON_STRING(PARSE_JSON(f0, f3))",
+                                "{\"a\":1,\"b\":[2,3]}",
+                                STRING().notNull())
+                        .testSqlRuntimeError(
+                                "PARSE_JSON(f2, f3)",
+                                TableRuntimeException.class,
+                                "Failed to parse JSON string")
+                        .testTableApiRuntimeError(
+                                call("PARSE_JSON", $("f2"), $("f3")),
+                                TableRuntimeException.class,
+                                "Failed to parse JSON string"),
                 
TestSetSpec.forFunction(BuiltInFunctionDefinitions.TRY_PARSE_JSON)
-                        .onFieldsWithData("{\"a\":1}", "1e400", 
"{\"a\":1,\"a\":2}")
-                        .andDataTypes(STRING().notNull(), STRING().notNull(), 
STRING().notNull())
+                        .onFieldsWithData("{\"a\":1}", "1e400", 
"{\"a\":1,\"a\":2}", null)
+                        .andDataTypes(
+                                STRING().notNull(),
+                                STRING().notNull(),
+                                STRING().notNull(),
+                                BOOLEAN())
                         .testResult(
                                 jsonString($("f0").tryParseJson()),
                                 "JSON_STRING(TRY_PARSE_JSON(f0))",
@@ -1095,6 +1118,17 @@ class JsonFunctionsITCase extends 
BuiltInFunctionTestBase {
                                 jsonString($("f2").tryParseJson(true)),
                                 "JSON_STRING(TRY_PARSE_JSON(f2, true))",
                                 "{\"a\":2}",
+                                STRING())
+                        // a NULL allowDuplicateKeys is treated as false
+                        .testResult(
+                                jsonString(call("TRY_PARSE_JSON", $("f0"), 
$("f3"))),
+                                "JSON_STRING(TRY_PARSE_JSON(f0, f3))",
+                                "{\"a\":1}",
+                                STRING())
+                        .testResult(
+                                jsonString(call("TRY_PARSE_JSON", $("f2"), 
$("f3"))),
+                                "JSON_STRING(TRY_PARSE_JSON(f2, f3))",
+                                null,
                                 STRING()),
                 // Input is parsed from its UTF-8 bytes. A NUL or a BOM must 
not be read as a
                 // UTF-16 or UTF-32 hint that turns invalid JSON into a value. 
Only input that is
diff --git 
a/flink-table/flink-table-runtime/src/main/java/org/apache/flink/table/runtime/functions/scalar/ParseJsonFunction.java
 
b/flink-table/flink-table-runtime/src/main/java/org/apache/flink/table/runtime/functions/scalar/ParseJsonFunction.java
index 50f758e9b4d..7c2f5789c8f 100644
--- 
a/flink-table/flink-table-runtime/src/main/java/org/apache/flink/table/runtime/functions/scalar/ParseJsonFunction.java
+++ 
b/flink-table/flink-table-runtime/src/main/java/org/apache/flink/table/runtime/functions/scalar/ParseJsonFunction.java
@@ -39,14 +39,17 @@ public class ParseJsonFunction extends 
BuiltInScalarFunction {
         return eval(jsonStr, false);
     }
 
-    public @Nullable Variant eval(@Nullable StringData jsonStr, boolean 
allowDuplicateKeys) {
+    /** A {@code NULL} {@code allowDuplicateKeys} is treated as {@code false}. 
*/
+    public @Nullable Variant eval(
+            @Nullable StringData jsonStr, @Nullable Boolean 
allowDuplicateKeys) {
         if (jsonStr == null) {
             return null;
         }
 
         final byte[] bytes = jsonStr.toBytes();
         try {
-            return BinaryVariantInternalBuilder.parseJson(bytes, 
allowDuplicateKeys);
+            return BinaryVariantInternalBuilder.parseJson(
+                    bytes, Boolean.TRUE.equals(allowDuplicateKeys));
         } catch (Throwable e) {
             final int invalidIndex =
                     StringUtf8Utils.firstInvalidUtf8ByteIndex(bytes, 0, 
bytes.length);
diff --git 
a/flink-table/flink-table-runtime/src/main/java/org/apache/flink/table/runtime/functions/scalar/TryParseJsonFunction.java
 
b/flink-table/flink-table-runtime/src/main/java/org/apache/flink/table/runtime/functions/scalar/TryParseJsonFunction.java
index 161e1c65131..c3e4dc66bef 100644
--- 
a/flink-table/flink-table-runtime/src/main/java/org/apache/flink/table/runtime/functions/scalar/TryParseJsonFunction.java
+++ 
b/flink-table/flink-table-runtime/src/main/java/org/apache/flink/table/runtime/functions/scalar/TryParseJsonFunction.java
@@ -37,13 +37,16 @@ public class TryParseJsonFunction extends 
BuiltInScalarFunction {
         return eval(jsonStr, false);
     }
 
-    public @Nullable Variant eval(@Nullable StringData jsonStr, boolean 
allowDuplicateKeys) {
+    /** A {@code NULL} {@code allowDuplicateKeys} is treated as {@code false}. 
*/
+    public @Nullable Variant eval(
+            @Nullable StringData jsonStr, @Nullable Boolean 
allowDuplicateKeys) {
         if (jsonStr == null) {
             return null;
         }
 
         try {
-            return BinaryVariantInternalBuilder.parseJson(jsonStr.toBytes(), 
allowDuplicateKeys);
+            return BinaryVariantInternalBuilder.parseJson(
+                    jsonStr.toBytes(), 
Boolean.TRUE.equals(allowDuplicateKeys));
         } catch (Throwable e) {
             return null;
         }

Reply via email to