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

pvillard pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/nifi.git


The following commit(s) were added to refs/heads/main by this push:
     new 1191b9254f NIFI-14873 - Support unquoted parameter references with 
spaces in their names within expression language
1191b9254f is described below

commit 1191b9254fbbc6590bbe2c150b2478ef193cfce9
Author: Rob Fellows <[email protected]>
AuthorDate: Mon Aug 18 13:38:52 2025 -0400

    NIFI-14873 - Support unquoted parameter references with spaces in their 
names within expression language
    
    Signed-off-by: Pierre Villard <[email protected]>
    
    This closes #10215.
---
 .../language/antlr/AttributeExpressionLexer.g      | 25 ++++++++++++++++++++++
 .../language/antlr/AttributeExpressionParser.g     | 13 +++++++++--
 .../attribute/expression/language/TestQuery.java   |  8 +++++++
 3 files changed, 44 insertions(+), 2 deletions(-)

diff --git 
a/nifi-commons/nifi-expression-language/src/main/antlr3/org/apache/nifi/attribute/expression/language/antlr/AttributeExpressionLexer.g
 
b/nifi-commons/nifi-expression-language/src/main/antlr3/org/apache/nifi/attribute/expression/language/antlr/AttributeExpressionLexer.g
index 3b62311334..0905f4119a 100644
--- 
a/nifi-commons/nifi-expression-language/src/main/antlr3/org/apache/nifi/attribute/expression/language/antlr/AttributeExpressionLexer.g
+++ 
b/nifi-commons/nifi-expression-language/src/main/antlr3/org/apache/nifi/attribute/expression/language/antlr/AttributeExpressionLexer.g
@@ -69,6 +69,31 @@ WHITESPACE : (' '|'\t'|'\n'|'\r')+ { $channel = HIDDEN; };
 COMMENT : '#' ( ~('{') ) ( ~('\n') )* '\n' { $channel = HIDDEN; };
 
 // PARAMETERS
+// Capture the entire parameter reference (e.g., #{Batch Size}) as a single 
token so that
+// parameter names may contain spaces without requiring quotes. The lexer 
action normalizes
+// the token text to contain only the inner parameter name (without the 
surrounding "#{" and
+// "}"), and if the inner text itself is quoted (e.g., #{"Batch Size"}), the 
surrounding quotes
+// are also stripped. This preserves backward compatibility and ensures the 
parser/AST consumer
+// (ExpressionCompiler) receives a consistent parameter name string.
+PARAMETER_REFERENCE
+    : '#{' (~('}'))+ '}'
+      {
+        final String full = getText();
+        if (full != null && full.length() >= 3) {
+            String inner = full.substring(2, full.length() - 1);
+            if (inner.length() >= 2) {
+                final char first = inner.charAt(0);
+                final char last = inner.charAt(inner.length() - 1);
+                if ((first == '\'' && last == '\'') || (first == '"' && last 
== '"')) {
+                    inner = inner.substring(1, inner.length() - 1);
+                }
+            }
+            setText(inner);
+        }
+      }
+    ;
+// Retained for legacy form where the parameter name is parsed as a separate 
token sequence
+// (e.g., #{'Batch Size'}) and rewritten by the parser rule below.
 PARAMETER_REFERENCE_START : '#{';
 
 DOLLAR : '$';
diff --git 
a/nifi-commons/nifi-expression-language/src/main/antlr3/org/apache/nifi/attribute/expression/language/antlr/AttributeExpressionParser.g
 
b/nifi-commons/nifi-expression-language/src/main/antlr3/org/apache/nifi/attribute/expression/language/antlr/AttributeExpressionParser.g
index 4533d250f1..6c8226eda5 100644
--- 
a/nifi-commons/nifi-expression-language/src/main/antlr3/org/apache/nifi/attribute/expression/language/antlr/AttributeExpressionParser.g
+++ 
b/nifi-commons/nifi-expression-language/src/main/antlr3/org/apache/nifi/attribute/expression/language/antlr/AttributeExpressionParser.g
@@ -145,8 +145,17 @@ attributeRefOrFunctionCall : (attributeRef | 
standaloneFunction | parameterRefer
 referenceOrFunction : DOLLAR LBRACE attributeRefOrFunctionCall (COLON 
functionCall)* RBRACE ->
                        ^(EXPRESSION attributeRefOrFunctionCall functionCall*);
 
-parameterReference : PARAMETER_REFERENCE_START singleAttrRef RBRACE ->
-    ^(PARAMETER_REFERENCE singleAttrRef);
+// Parameter reference rule
+// Supports two forms:
+//   1) Legacy: "#{" singleAttrRef "}" where the name is either ATTRIBUTE_NAME 
or STRING_LITERAL
+//   2) New: a single PARAMETER_REFERENCE token produced by the lexer that 
already contains the
+//      normalized inner name (surrounding #{ } removed and optional inner 
quotes stripped).
+// Both forms are rewritten to the same AST shape: ^(PARAMETER_REFERENCE 
<child-token-with-name>)
+// so downstream consumers (ExpressionCompiler) can read child(0).getText() 
for the parameter name.
+parameterReference
+    : PARAMETER_REFERENCE_START singleAttrRef RBRACE -> ^(PARAMETER_REFERENCE 
singleAttrRef)
+    | p=PARAMETER_REFERENCE -> ^(PARAMETER_REFERENCE $p)
+    ;
 
 expression : referenceOrFunction;
 
diff --git 
a/nifi-commons/nifi-expression-language/src/test/java/org/apache/nifi/attribute/expression/language/TestQuery.java
 
b/nifi-commons/nifi-expression-language/src/test/java/org/apache/nifi/attribute/expression/language/TestQuery.java
index 07beec7196..30eeb8160c 100644
--- 
a/nifi-commons/nifi-expression-language/src/test/java/org/apache/nifi/attribute/expression/language/TestQuery.java
+++ 
b/nifi-commons/nifi-expression-language/src/test/java/org/apache/nifi/attribute/expression/language/TestQuery.java
@@ -447,6 +447,14 @@ public class TestQuery {
         verifyEquals("${#{'test param'}:append(' - '):append(#{'test 
param'})}", attributes, stateValues, parameters, "unit - unit");
 
         verifyEquals("${#{\"test param\"}}", attributes, stateValues, 
parameters, "unit");
+
+        // Unquoted parameter reference with spaces should also work
+        verifyEquals("${#{test param}}", attributes, stateValues, parameters, 
"unit");
+
+        // Unquoted parameter used within a function argument
+        parameters.put("Date Format", "yyyy");
+        final String expectedYear = 
String.valueOf(java.time.LocalDate.now().getYear());
+        verifyEquals("${now():format(#{Date Format})}", attributes, 
stateValues, parameters, expectedYear);
     }
 
     @Test

Reply via email to