snuyanzin commented on code in PR #28113:
URL: https://github.com/apache/flink/pull/28113#discussion_r3196480696
##########
flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/functions/JsonFunctionsITCase.java:
##########
@@ -1540,6 +1540,166 @@ private static List<TestSetSpec> jsonArraySpec() {
STRING().notNull()));
}
+ /**
+ * Pins the local-ref / common-sub-expression handling for JSON
construction calls.
+ *
+ * <p>When two projections share a JSON-producing sub-expression, the
planner deduplicates them
+ * into a {@link org.apache.calcite.rex.RexLocalRef} that points at the
shared {@link
+ * org.apache.calcite.rex.RexCall}. The codegen helpers in {@code
JsonGenerateUtils} must
+ * dereference that local ref through the surrounding {@code RexProgram}
to recognize it as a
+ * JSON / JSON_OBJECT / JSON_ARRAY operand and embed the value as a raw
JSON node. Without that
+ * dereference the helpers see a plain {@code RexLocalRef}, fall back to
the string-quoting
+ * branch, and produce wrong output (e.g. {@code "{\"k\":\"[1,2,3]\"}"}
instead of {@code
+ * "{\"k\":[1,2,3]}"}).
+ *
+ * <p>The scenarios below cover each callsite — {@code JsonObjectCallGen},
{@code
+ * JsonArrayCallGen}, {@code JsonStringCallGen} — and each branch of the
inspection helpers
+ * ({@code JSON}, {@code JSON_OBJECT}, {@code JSON_ARRAY}).
+ */
+ private static List<TestSetSpec> jsonLocalRefReuseSpec() {
+ return List.of(
+ // Shared JSON(f) inside two JSON_OBJECT projections.
+ TestSetSpec.forFunction(
+ BuiltInFunctionDefinitions.JSON_OBJECT,
+ "Shared JSON(f) sub-expression across
JSON_OBJECT projections")
+ .onFieldsWithData("[1,2,3]")
+ .andDataTypes(STRING())
+ .testResult(
+ resultSpec(
+ jsonObject(JsonOnNull.NULL, "k1",
json($("f0"))),
+ "JSON_OBJECT(KEY 'k1' VALUE JSON(f0))",
+ "{\"k1\":[1,2,3]}",
+ STRING().notNull(),
+ STRING().notNull()),
+ resultSpec(
+ jsonObject(JsonOnNull.NULL, "k2",
json($("f0"))),
+ "JSON_OBJECT(KEY 'k2' VALUE JSON(f0))",
+ "{\"k2\":[1,2,3]}",
+ STRING().notNull(),
+ STRING().notNull())),
+ // Shared JSON_ARRAY(...) inside two JSON_OBJECT projections.
+ TestSetSpec.forFunction(
+ BuiltInFunctionDefinitions.JSON_OBJECT,
+ "Shared JSON_ARRAY sub-expression across
JSON_OBJECT projections")
+ .onFieldsWithData(1, 2, 3)
+ .andDataTypes(INT(), INT(), INT())
+ .testResult(
+ resultSpec(
+ jsonObject(
+ JsonOnNull.NULL,
+ "a",
+ jsonArray(
+ JsonOnNull.NULL,
+ $("f0"),
+ $("f1"),
+ $("f2"))),
+ "JSON_OBJECT(KEY 'a' VALUE
JSON_ARRAY(f0, f1, f2))",
+ "{\"a\":[1,2,3]}",
+ STRING().notNull(),
+ STRING().notNull()),
+ resultSpec(
+ jsonObject(
+ JsonOnNull.NULL,
+ "b",
+ jsonArray(
+ JsonOnNull.NULL,
+ $("f0"),
+ $("f1"),
+ $("f2"))),
+ "JSON_OBJECT(KEY 'b' VALUE
JSON_ARRAY(f0, f1, f2))",
+ "{\"b\":[1,2,3]}",
+ STRING().notNull(),
+ STRING().notNull())),
+ // Shared inner JSON_OBJECT inside two outer JSON_OBJECT
projections.
+ TestSetSpec.forFunction(
+ BuiltInFunctionDefinitions.JSON_OBJECT,
+ "Shared inner JSON_OBJECT across outer
JSON_OBJECT projections")
+ .onFieldsWithData("V")
+ .andDataTypes(STRING())
+ .testResult(
+ resultSpec(
+ jsonObject(
+ JsonOnNull.NULL,
+ "outer1",
+ jsonObject(JsonOnNull.NULL,
"inner", $("f0"))),
+ "JSON_OBJECT(KEY 'outer1' VALUE
JSON_OBJECT(KEY 'inner' VALUE f0))",
+ "{\"outer1\":{\"inner\":\"V\"}}",
+ STRING().notNull(),
+ STRING().notNull()),
+ resultSpec(
+ jsonObject(
+ JsonOnNull.NULL,
+ "outer2",
+ jsonObject(JsonOnNull.NULL,
"inner", $("f0"))),
+ "JSON_OBJECT(KEY 'outer2' VALUE
JSON_OBJECT(KEY 'inner' VALUE f0))",
+ "{\"outer2\":{\"inner\":\"V\"}}",
+ STRING().notNull(),
+ STRING().notNull())),
+ // Shared JSON_OBJECT inside two JSON_ARRAY projections.
+ TestSetSpec.forFunction(
+ BuiltInFunctionDefinitions.JSON_ARRAY,
+ "Shared JSON_OBJECT inside JSON_ARRAY across
projections")
+ .onFieldsWithData("V")
+ .andDataTypes(STRING())
+ .testResult(
+ resultSpec(
+ jsonArray(
+ JsonOnNull.NULL,
+ jsonObject(JsonOnNull.NULL,
"k", $("f0"))),
+ "JSON_ARRAY(JSON_OBJECT(KEY 'k' VALUE
f0))",
+ "[{\"k\":\"V\"}]",
+ STRING().notNull(),
+ STRING().notNull()),
+ resultSpec(
+ jsonArray(
+ JsonOnNull.NULL,
+ jsonObject(JsonOnNull.NULL,
"k", $("f0"))),
+ "JSON_ARRAY(JSON_OBJECT(KEY 'k' VALUE
f0))",
+ "[{\"k\":\"V\"}]",
+ STRING().notNull(),
+ STRING().notNull())),
+ // Shared JSON(f) inside two JSON_ARRAY projections.
Review Comment:
yeah, switched to sql only and added second projection
--
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]