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

gustavodemorais 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 a678a2ad869 [FLINK-41109][table] Add guidelines for query-controlled 
strings in generated code to planner AGENTS.md
a678a2ad869 is described below

commit a678a2ad869b994c50c25f9ed85785eb1b63f058
Author: Gustavo de Morais <[email protected]>
AuthorDate: Fri Oct 23 18:24:52 2026 +0200

    [FLINK-41109][table] Add guidelines for query-controlled strings in 
generated code to planner AGENTS.md
    
    This fixes #29578.
---
 flink-table/flink-table-planner/AGENTS.md | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/flink-table/flink-table-planner/AGENTS.md 
b/flink-table/flink-table-planner/AGENTS.md
index 8b45353ecbf..875ec320302 100644
--- a/flink-table/flink-table-planner/AGENTS.md
+++ b/flink-table/flink-table-planner/AGENTS.md
@@ -93,6 +93,15 @@ Then:
 - Custom call generators for functions live in `codegen/calls/` (e.g., 
`JsonCallGen.scala`). Simple scalar functions typically don't need these; the 
planner handles them uniformly through the function definition.
 - Immutables library is used for rule configs (`@Value.Immutable`, 
`@Value.Enclosing`). See [README.md](README.md).
 
+**Query-controlled strings in generated code.** Generated code is compiled 
with Janino and executed in the job, so a query-controlled string that is 
embedded unescaped changes the code that runs. This includes identifiers and 
ROW field names (may contain `"` and `\`, and line breaks when they come from 
the Table API or a catalog), string literals, LIKE/regex/JSON path/format 
patterns, MATCH_RECOGNIZE pattern variables, and type names.
+
+- Prefer `ctx.addReusableObject(value, "prefix")` for serializable values. It 
passes them to the generated class through `references[]`, so nothing needs 
escaping.
+- Otherwise embed a string only inside `"..."`, escaped with 
`EncodingUtils.escapeJava`, for example via `GenerateUtils.generateLiteral`, 
`ctx.addReusablePreEscapedStringConstant(EncodingUtils.escapeJava(value))`, or 
`CastRuleUtils.strLiteral` in cast rules. This also applies to text in 
generated exception messages. The escaped output is not safe in a char literal 
(`'` is not escaped), nor as an identifier, type, or expression.
+- Name members with `newName(ctx, "prefix")` and reference classes with 
`className[...]`, never with names taken from the query.
+- `GeneratedExpression.literalValue` holds the raw, unescaped value. Use it 
for planning decisions only and reference the value in code through 
`resultTerm`.
+- Never put query-controlled text into generated comments, including 
`ctx.addReusableHeaderComment`. Janino resolves `\uXXXX` before lexing, so 
`\u000a` ends a `//` comment, and `escapeJava` does not escape `*/`.
+- Test with values containing `"`, `\`, `'`, a line break, and a literal 
`\u000a` (written `"\\u000a"` in Java), and assert the exact result. See the 
field name and pattern cases in `JsonFunctionsITCase` and `LikeFunctionITCase`.
+
 ### Plan serialization changes
 
 - ExecNode specs use Jackson for JSON serialization. Source/sink specs should 
use `@JsonIgnoreProperties(ignoreUnknown = true)` for forward compatibility.

Reply via email to