A sub-expression is very similar to a pipe-expression with a few key differences:
A sub-expression restricts the kinds of expressions allowed on its right-hand-side.
A pipe-expression stops a projection on the left-hand-side from propagating to the right-hand-side.
However, when none of the left and right expressions involve projections, those two constructs are effectively identical.
Some library implementations return different results in thoses cases.
search( `null`.[@], {} ) -> null
search( `null` | [@], {} ) -> [ null ]
Given those expressions do not involve any projection, they should have the same result.
This calls into question which is the correct result.
Compliance tests suggests the correct result is null and not [ null ].
The canonical JavaScript implementation hosted in https://jmespath.org and https://jmespath.site agrees with this.
However, the specification calls out how a sub-expression (and thus, by extension) a pipe-expression should be implemented.
left-evaluation = search(left-expression, original-json-document)
result = search(right-expression, left-evaluation)
However, compliance tests cannot succeed by following this guideline.
For instance, this compliance test looks like so:
Left evaluates identifierfoo which cannot be found in the original json document. Thus returns null.
Right evaluates the multi-select-list[ a || b] against the value null.
Inside this list, an or-expression evaluates identifiers a, then b as none can be found in the current value null. Thus returns null.
Therefore, the final result is a JSON array with a single element being the null value.
Compliance tests disagrees and stops evaluation when the left-hand-side evaluation returns null.
This PR clarifies the pseudo-code evaluation instructions for sub-expression to align with the compliance tests and the behaviour of the canonical JavaScript implementation. It changes the text to:
left-evaluation = search(left-expression, original-json-document)
if left-evaluation is `null` then result = `null`
else result = search(right-expression, left-evaluation)
A
sub-expression
is very similar to apipe-expression
with a few key differences:sub-expression
restricts the kinds of expressions allowed on its right-hand-side.pipe-expression
stops a projection on the left-hand-side from propagating to the right-hand-side.However, when none of the left and right expressions involve projections, those two constructs are effectively identical. Some library implementations return different results in thoses cases.
search( `null`.[@], {} ) -> null
search( `null` | [@], {} ) -> [ null ]
Given those expressions do not involve any projection, they should have the same result. This calls into question which is the correct result.
Compliance tests suggests the correct result is
null
and not[ null ]
. The canonical JavaScript implementation hosted in https://jmespath.org and https://jmespath.site agrees with this.However, the specification calls out how a
sub-expression
(and thus, by extension) apipe-expression
should be implemented.However, compliance tests cannot succeed by following this guideline. For instance, this compliance test looks like so:
search( foo.[a || b], {"type": "object"} ) -> null
Which evaluates to:
identifier
foo
which cannot be found in the original json document. Thus returnsnull
.multi-select-list
[ a || b]
against the valuenull
.or-expression
evaluates identifiersa
, thenb
as none can be found in the current valuenull
. Thus returnsnull
.null
value.null
.This PR clarifies the pseudo-code evaluation instructions for
sub-expression
to align with the compliance tests and the behaviour of the canonical JavaScript implementation. It changes the text to: