This is an automated email from the ASF dual-hosted git repository.
snuyanzin pushed a commit to branch release-2.1
in repository https://gitbox.apache.org/repos/asf/flink.git
The following commit(s) were added to refs/heads/release-2.1 by this push:
new 5db7d948da5 [FLINK-39355][table-planner] Fix field names in code
generation for JSON_OBJECT/ARRAY/STRING
5db7d948da5 is described below
commit 5db7d948da562748b2687d74c97bb174d0f7f53c
Author: Timo Walther <[email protected]>
AuthorDate: Tue Mar 31 12:30:02 2026 +0200
[FLINK-39355][table-planner] Fix field names in code generation for
JSON_OBJECT/ARRAY/STRING
---
.../table/planner/codegen/JsonGenerateUtils.scala | 3 +-
.../planner/functions/JsonFunctionsITCase.java | 46 ++++++++++++++++++++++
2 files changed, 48 insertions(+), 1 deletion(-)
diff --git
a/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/planner/codegen/JsonGenerateUtils.scala
b/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/planner/codegen/JsonGenerateUtils.scala
index 823837d2f5e..f87e2418812 100644
---
a/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/planner/codegen/JsonGenerateUtils.scala
+++
b/flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/planner/codegen/JsonGenerateUtils.scala
@@ -31,6 +31,7 @@ import
org.apache.flink.table.runtime.typeutils.TypeCheckUtils.isCharacterString
import org.apache.flink.table.types.logical._
import org.apache.flink.table.types.logical.LogicalTypeRoot._
import org.apache.flink.table.types.logical.utils.LogicalTypeChecks
+import org.apache.flink.table.utils.EncodingUtils
import org.apache.calcite.rex.{RexCall, RexNode}
@@ -261,7 +262,7 @@ object JsonGenerateUtils {
/** Generates a method to convert rows into [[ObjectNode]]. */
private def generateRowConverter(ctx: CodeGeneratorContext, rowType:
LogicalType): String = {
- val fieldNames = toScala(LogicalTypeChecks.getFieldNames(rowType))
+ val fieldNames =
toScala(LogicalTypeChecks.getFieldNames(rowType)).map(EncodingUtils.escapeJava)
val fieldTypes = toScala(LogicalTypeChecks.getFieldTypes(rowType))
val populateObjectCode = fieldNames.zipWithIndex.map {
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 e26401951c4..02791725aaf 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
@@ -53,6 +53,7 @@ import static org.apache.flink.table.api.DataTypes.BINARY;
import static org.apache.flink.table.api.DataTypes.BOOLEAN;
import static org.apache.flink.table.api.DataTypes.DECIMAL;
import static org.apache.flink.table.api.DataTypes.DOUBLE;
+import static org.apache.flink.table.api.DataTypes.FIELD;
import static org.apache.flink.table.api.DataTypes.INT;
import static org.apache.flink.table.api.DataTypes.MAP;
import static org.apache.flink.table.api.DataTypes.ROW;
@@ -690,6 +691,21 @@ class JsonFunctionsITCase extends BuiltInFunctionTestBase {
jsonString($("f13")),
"JSON_STRING(f13)",
"{\"f0\":[{\"f0\":1,\"f1\":2}]}",
+ STRING().notNull()),
+ TestSetSpec.forFunction(BuiltInFunctionDefinitions.JSON_STRING)
+ .onFieldsWithData(Row.of("val1", "val2", "val3",
"val4", "val5"))
+ .andDataTypes(
+ ROW(
+ FIELD("field\"quote",
STRING()),
+ FIELD("field\\slash",
STRING()),
+ FIELD("field\nline", STRING()),
+ FIELD("field\ttab", STRING()),
+ FIELD("field\rreturn",
STRING()))
+ .notNull())
+ .testResult(
+ jsonString($("f0")),
+ "JSON_STRING(f0)",
+
"{\"field\\ttab\":\"val4\",\"field\\nline\":\"val3\",\"field\\rreturn\":\"val5\",\"field\\\"quote\":\"val1\",\"field\\\\slash\":\"val2\"}",
STRING().notNull()));
}
@@ -1062,6 +1078,21 @@ class JsonFunctionsITCase extends
BuiltInFunctionTestBase {
+ "\"R\":{\"f0\":\"V\",\"f1\":null}"
+ "}",
STRING().notNull(),
+ STRING().notNull()),
+ TestSetSpec.forFunction(BuiltInFunctionDefinitions.JSON_OBJECT)
+ .onFieldsWithData(Row.of("val1", "val2", "val3",
"val4", "val5"))
+ .andDataTypes(
+ ROW(
+ FIELD("field\"quote",
STRING()),
+ FIELD("field\\slash",
STRING()),
+ FIELD("field\nline", STRING()),
+ FIELD("field\ttab", STRING()),
+ FIELD("field\rreturn",
STRING()))
+ .notNull())
+ .testResult(
+ jsonObject(JsonOnNull.NULL, "testRow",
$("f0")),
+ "JSON_OBJECT(KEY 'testRow' VALUE f0 NULL ON
NULL)",
+
"{\"testRow\":{\"field\\ttab\":\"val4\",\"field\\nline\":\"val3\",\"field\\rreturn\":\"val5\",\"field\\\"quote\":\"val1\",\"field\\\\slash\":\"val2\"}}",
STRING().notNull()));
}
@@ -1484,6 +1515,21 @@ class JsonFunctionsITCase extends
BuiltInFunctionTestBase {
+
"{\"age\":1,\"name\":\"V\",\"payload\":{\"M1\":\"V1\",\"M2\":\"V2\"}}"
+ "]",
STRING().notNull(),
+ STRING().notNull()),
+ TestSetSpec.forFunction(BuiltInFunctionDefinitions.JSON_ARRAY)
+ .onFieldsWithData(Row.of("val1", "val2", "val3",
"val4", "val5"))
+ .andDataTypes(
+ ROW(
+ FIELD("field\"quote",
STRING()),
+ FIELD("field\\slash",
STRING()),
+ FIELD("field\nline", STRING()),
+ FIELD("field\ttab", STRING()),
+ FIELD("field\rreturn",
STRING()))
+ .notNull())
+ .testResult(
+ jsonArray(JsonOnNull.NULL, $("f0")),
+ "JSON_ARRAY(f0 NULL ON NULL)",
+
"[{\"field\\ttab\":\"val4\",\"field\\nline\":\"val3\",\"field\\rreturn\":\"val5\",\"field\\\"quote\":\"val1\",\"field\\\\slash\":\"val2\"}]",
STRING().notNull()));
}