[
https://issues.apache.org/jira/browse/CAMEL-24826?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18117210#comment-18117210
]
Adriano Machado commented on CAMEL-24826:
-----------------------------------------
Investigated this. Reproduced the reported behaviour exactly, but the framing
needs a correction, and I found two adjacent bugs while probing.
h3. Simple *does* have a ternary operator
CAMEL-22873 added it in 4.18 (commit 8089af56cf44): there is a
{{TernaryExpression}} AST node, a {{TERNARY = "? :"}} entry in
{{SimpleOperatorConstants}} (precedence 25), and a documented section in
{{simple-operators.adoc}}. So a message saying "Simple has no ternary operator;
use a choice" would be false, and would steer users away from something that
works.
h3. The real rule: the ternary is wired into the predicate parser, not the
expression parser
{{SimplePredicateParser.parseTokens()}} calls {{ternaryOperator()}} and
{{prepareTernaryExpressions()}}. {{SimpleExpressionParser.parseTokens()}} calls
neither. Inside {{$}}{{{...}}} it is handled separately by
{{SimpleFunctionStart}}. Measured against 4.23.0-SNAPSHOT:
|| expression || expression context || predicate context ||
| {{$}}{{{body.size()} == 0 ? $}}{{{null} : $}}{{{body[0]}}} | {{1 == 0 ? :
\{sku=CAMEL-MUG, qty=42\}}} (silent literal) | parses as a real ternary |
| {{$}}{{{body.size() == 0 ? $}}{{{null} : $}}{{{body[0]}}}} |
{{\{sku=CAMEL-MUG, qty=42\}}} (correct) | correct |
| {{Is it ok ? yes : no}} | literal text (correct) | rejected |
So the ternary works *only inside one* {{$}}{{{ }}}, or at top level in a
predicate. The reported expression is the top-level form.
h3. The documentation teaches the broken form
{{simple-operators.adoc}} states the syntax as:
{noformat}
${leftValue} OP rightValue ? trueValue : falseValue
{noformat}
That is exactly the top-level form that silently degrades to text; the examples
underneath then use the enclosed form. This is very likely where both the model
and a human copying it got the shape. I will fix this line as part of the
change.
h3. Two adjacent bugs found while probing
1. An *unquoted number or boolean* in a ternary branch fails to parse, even in
the fully supported enclosed form:
{noformat}
${header.foo == 5 ? 0 : 1} -> Unknown function: 0
${header.foo == 5 ? ${header.foo} : true} -> Unknown function: true (did you
mean ${type}?)
${header.foo == 5 ? ${header.foo} : 'x'} -> ok
${header.foo == 5 ? ${header.foo} : null} -> ok
{noformat}
Quoted literals, {{null}} and nested functions work; bare numbers and booleans
do not.
2. A validate/runtime divergence on the mixed shape:
{noformat}
${header.foo == 5 ? ${header.foo} : 0}
catalog validate : ACCEPTED
runtime : FAIL Unknown function: 0
{noformat}
{{camel validate}} passes an expression the route rejects at startup.
h3. Why this belongs in validate and not in the parser
CAMEL-22904 (4.18.0) and CAMEL-23035 (4.18.1/4.19.0) were both regressions
caused by the ternary parser firing on literal text containing {{?}} or {{:}}
-- the {{>>> Message received from WebSocket Client : $}}{{{body}}} case, with
{{SimpleOperatorTest.testTernaryLog}} left as the guard. Therefore:
* making the *expression parser support* a top-level ternary re-opens both
tickets;
* making the *parser throw* on a top-level {{" ? " ... " : "}} re-opens them
too, and would break working routes at startup.
So the check goes in {{SimpleChecks.validateYamlSimple}}, which is the one edit
point reaching {{camel validate yaml}}, {{camel validate source}}, the MCP
write-time checks, the TUI editor and {{AnswerChecks}} -- so the MCP validate
tool gets the same message for free. A rule keyed on "contains a function, plus
a top-level {{" ? "}} followed by a later {{" : ""}}" produces zero hits across
the whole Camel repo, and the CAMEL-22904 string has a {{:}} but no {{?}}, so
it stays clean.
Proposed message:
{noformat}
Line N: Simple has no top-level ternary: ? and : outside ${...} are literal
text.
Write the whole ternary inside one function: ${body.size() == 0 ? ${null} :
${body[0]}}
{noformat}
Scope I am taking: the validate check, the doc fix, the bare number/boolean
branch fix, and the validate/runtime divergence. Shout if you would rather the
two parser bugs went to their own ticket.
_Claude Code on behalf of Adriano Machado (@ammachado)_
_This was generated by an AI agent and may contain inaccuracies. Please verify
before relying on it._
> camel validate: flag a ternary operator in a Simple expression, it is not
> supported and comes out as literal text
> -----------------------------------------------------------------------------------------------------------------
>
> Key: CAMEL-24826
> URL: https://issues.apache.org/jira/browse/CAMEL-24826
> Project: Camel
> Issue Type: Improvement
> Components: camel-core, camel-jbang
> Reporter: Claus Ibsen
> Assignee: Adriano Machado
> Priority: Major
>
> Found twice while writing examples for CAMEL-24808 and in the local-model
> benchmark.
> Simple has no ternary operator, but a model, and a human copying from another
> language, writes one:
> {code}
> setBody:
> expression:
> simple:
> expression: "${body.size()} == 0 ? ${null} : ${body[0]}"
> {code}
> At runtime this evaluates to the literal text "1 == 0 ? : {sku=CAMEL-MUG,
> qty=42}" and is silently used as the body; a nested form inside a function
> fails at runtime with "Unknown function". *camel validate yaml* (and the
> validate tool of the MCP server) accepts both.
> Proposal: the Simple language validator (parse or a dedicated check) reports
> a " ? " with a " : " at the top level of an expression as "Simple has no
> ternary operator; use a choice, or a jsonpath/groovy expression", with the
> position. Same message from the MCP validate tool.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)