Shouldn't a slice projection be "chainable"?
Closed this issue · 4 comments
Slice expressions will do what they say on the tin such that:
search([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "@[0:10:2]")
// OUTPUTS: [1, 3, 5, 7, 9]
However, chaining slices results in some unexpected responses
search([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "@[0:10:2][*]")
// EXPECTED OUTPUT: [1, 3, 5, 7, 9]
// RECEIVED OUTOUT: []
search([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "@[0:10:2] | @[*]")
// EXPECTED OUTPUT: [1, 3, 5, 7, 9]
// RECEIVED OUTOUT: [1, 3, 5, 7, 9] -- fine
search([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "@[0:10:2][0:3]")
// EXPECTED OUTPUT: [1, 3, 5]
// RECEIVED OUTOUT: []
Interesting.
Codesandbox: https://codesandbox.io/s/jmespath-chain-slice-sandbox-5hf5s?file=/src/index.js
The AST that produces the unexpected result from [0:10:2][*]
is:
{
"type": "Projection",
"children": [
{
"type": "IndexExpression",
"children": [
{
"type": "Identity"
},
{
"type": "Slice",
"children": [
0,
10,
2
]
}
]
},
{
"type": "Projection",
"children": [
{
"type": "Identity"
},
{
"type": "Identity"
}
]
}
]
}
But the AST from the working expression of [0:10:2]|[*]
is:
{
"type": "Pipe",
"children": [
{
"type": "Projection",
"children": [
{
"type": "IndexExpression",
"children": [
{
"type": "Identity"
},
{
"type": "Slice",
"children": [
0,
10,
2
]
}
]
},
{
"type": "Identity"
}
]
},
{
"type": "Projection",
"children": [
{
"type": "Identity"
},
{
"type": "Identity"
}
]
}
]
}
Looking at the grammar in the spec, I can't see how the first AST has derived from that input.
https://jmespath.org/specification.html
I might be reading this incorrectly, but I think that in order to chain two slice projections, according to the grammar, then the pipe is required.
I'm going to have to read the spec with greater care.
I've not familiarised myself enough with the spec to explain the following (I'll do that) but it looks like it does indeed chain provided the members are array types so:
search([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "@[0:10:2][*]")
//returns [] as above
// BUT
search([1, 2, [3], 4, 5, 6, 7, 8, 9, 10, 11], "@[0:10:2][*]")
//returns
[
[3]
]
I clearly need to better understand the difference between projections, wildcards, and wildcard projections
so (without the pipe) the second slice is being applied to every item in result of the first.
Yup. That's my reading of it. Thanks for getting back on this. Feels a bit lonely at times with issues in this project. Wish the community around jmespath was a bit more vibrant.