-
Notifications
You must be signed in to change notification settings - Fork 8.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix filters for complex painless scripted fields #9171
Conversation
Painless scripted fields that consisted of more than a single expression would break when the user attempted to filter on them in Discover or Visualize because of the naive way we were building them. We now wrap the user's script in a lambda so that it can be as complex at they need it to be. The only special exception is that the user cannot define named functions since those cannot go inside a Painless lambda. Fixes elastic#9024 Related elastic/elasticsearch#21635
@nik9000 any chance you could glance over the painless I wrote in here and make sure I'm not doing anything stupid? Things seem to be working but I'm not a painless guru. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense to me. I left a super minor thing.
}).join(' && '); | ||
|
||
// We must wrap painless scripts in a lambda in case they're more than a simple expression | ||
if (field.lang === 'painless') { | ||
const comparators = `boolean gt(Supplier s, def v) {return s.get() > v;} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Technically you don't need a ;
before a }
in painless ever. Mad lexer hax.
Anyway, maybe only emit the one of these comparators that you need? It doesn't seem worth it to go through the trouble of building these methods if you aren't going to use them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool, thanks for the quick feedback!
@Bargs I tried out a couple of scripts Filtering works for this script
But not for this
Resulting filter copied from UI
|
What about
? |
@nik9000 That works! So is it paramount that a well-defined return value is provided for every execution path? |
Yeah, at least it is in methods. Maybe @jdconrad can talk about that? I On Mon, Nov 21, 2016, 7:53 PM Tanya Bragin [email protected] wrote:
|
So modifying the substring script to be what @nik9000 recommended, namely to ensure the substrings script always returned something, I was able to run all the script examples in the painless blog and filter by them with no problems using this PR on top of Kibana master against latest ES master: |
As to the functions -- there isn't necessarily an obvious default return value for functions, unfortunately, as they can be void and return nothing or return a primitive type and maybe a default of 0 makes sense? But maybe that breaks some things. I'm not actually 100% sure as to the behavior of lambdas since Robert Muir did that work, but I would guess it's similar for them. They use something called LambdaMetaFactory (a Java class) that has an insane rule set that I can take a look at tomorrow. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
refactor suggestion, but otherwise, lgtm
if (field.lang === 'painless') { | ||
script = `boolean compare(Supplier s, def v) {return s.get() == v;} | ||
compare(() -> { ${field.script} }, params.value);`; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe this could be refactored? getInlineScriptForPhraseFilter
, or similar helper function on the field object, perhaps? Then it won't have to be written out three times. I was toying with the idea when I first wrote this fix, but it was going in right before the release so I opted for minimal changes, but now there's a bit more content to be refactored so might be worth it.
@stacey-gammon Since this logic is highly specific to the phrase filter I was worried about spreading it to the field class, so I exported it as a separate function in the phrase module which can be reused in all three places. A nice side effect is that the test is no longer whitespace dependent, which I didn't like. I also added some additional tests and included Nik's suggestion. Please take another look and let me know what you think. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm
Backports PR #9171 **Commit 1:** Fix filters for complex painless scripted fields Painless scripted fields that consisted of more than a single expression would break when the user attempted to filter on them in Discover or Visualize because of the naive way we were building them. We now wrap the user's script in a lambda so that it can be as complex at they need it to be. The only special exception is that the user cannot define named functions since those cannot go inside a Painless lambda. Fixes #9024 Related elastic/elasticsearch#21635 * Original sha: b2a86bb * Authored by Matthew Bargar <[email protected]> on 2016-11-21T23:18:20Z **Commit 2:** DRY it up * Original sha: 927de50 * Authored by Matthew Bargar <[email protected]> on 2016-11-22T16:21:21Z **Commit 3:** Phrase tests * Original sha: 79e69bd * Authored by Matthew Bargar <[email protected]> on 2016-11-22T16:48:12Z **Commit 4:** Only include necessary comparators and add tests * Original sha: 5b9137b * Authored by Matthew Bargar <[email protected]> on 2016-11-22T17:38:59Z
Backports PR #9171 **Commit 1:** Fix filters for complex painless scripted fields Painless scripted fields that consisted of more than a single expression would break when the user attempted to filter on them in Discover or Visualize because of the naive way we were building them. We now wrap the user's script in a lambda so that it can be as complex at they need it to be. The only special exception is that the user cannot define named functions since those cannot go inside a Painless lambda. Fixes #9024 Related elastic/elasticsearch#21635 * Original sha: b2a86bb * Authored by Matthew Bargar <[email protected]> on 2016-11-21T23:18:20Z **Commit 2:** DRY it up * Original sha: 927de50 * Authored by Matthew Bargar <[email protected]> on 2016-11-22T16:21:21Z **Commit 3:** Phrase tests * Original sha: 79e69bd * Authored by Matthew Bargar <[email protected]> on 2016-11-22T16:48:12Z **Commit 4:** Only include necessary comparators and add tests * Original sha: 5b9137b * Authored by Matthew Bargar <[email protected]> on 2016-11-22T17:38:59Z
Backports PR #9171 **Commit 1:** Fix filters for complex painless scripted fields Painless scripted fields that consisted of more than a single expression would break when the user attempted to filter on them in Discover or Visualize because of the naive way we were building them. We now wrap the user's script in a lambda so that it can be as complex at they need it to be. The only special exception is that the user cannot define named functions since those cannot go inside a Painless lambda. Fixes #9024 Related elastic/elasticsearch#21635 * Original sha: b2a86bb * Authored by Matthew Bargar <[email protected]> on 2016-11-21T23:18:20Z **Commit 2:** DRY it up * Original sha: 927de50 * Authored by Matthew Bargar <[email protected]> on 2016-11-22T16:21:21Z **Commit 3:** Phrase tests * Original sha: 79e69bd * Authored by Matthew Bargar <[email protected]> on 2016-11-22T16:48:12Z **Commit 4:** Only include necessary comparators and add tests * Original sha: 5b9137b * Authored by Matthew Bargar <[email protected]> on 2016-11-22T17:38:59Z
Backports PR #9171 **Commit 1:** Fix filters for complex painless scripted fields Painless scripted fields that consisted of more than a single expression would break when the user attempted to filter on them in Discover or Visualize because of the naive way we were building them. We now wrap the user's script in a lambda so that it can be as complex at they need it to be. The only special exception is that the user cannot define named functions since those cannot go inside a Painless lambda. Fixes #9024 Related elastic/elasticsearch#21635 * Original sha: b2a86bb * Authored by Matthew Bargar <[email protected]> on 2016-11-21T23:18:20Z **Commit 2:** DRY it up * Original sha: 927de50 * Authored by Matthew Bargar <[email protected]> on 2016-11-22T16:21:21Z **Commit 3:** Phrase tests * Original sha: 79e69bd * Authored by Matthew Bargar <[email protected]> on 2016-11-22T16:48:12Z **Commit 4:** Only include necessary comparators and add tests * Original sha: 5b9137b * Authored by Matthew Bargar <[email protected]> on 2016-11-22T17:38:59Z
We made a mistake in opening up Kibana scripted fields to any and all langs enabled in Elasticsearch. Kibana needs to do some magic to get certain scripted field features to work (elastic#9171) and we can't commit to supporting anything beyond expression and painless scripts. On top of that, the other languages are being removed in ES 6.0 anyway. This commit makes that stance explicit by disallowing anything other than those two choices.
We made a mistake in opening up Kibana scripted fields to any and all langs enabled in Elasticsearch. Kibana needs to do some magic to get certain scripted field features to work (#9171) and we can't commit to supporting anything beyond expression and painless scripts. On top of that, the other languages are being removed in ES 6.0 anyway. This commit makes that stance explicit by disallowing anything other than those two choices.
Backports PR elastic#9171 **Commit 1:** Fix filters for complex painless scripted fields Painless scripted fields that consisted of more than a single expression would break when the user attempted to filter on them in Discover or Visualize because of the naive way we were building them. We now wrap the user's script in a lambda so that it can be as complex at they need it to be. The only special exception is that the user cannot define named functions since those cannot go inside a Painless lambda. Fixes elastic#9024 Related elastic/elasticsearch#21635 * Original sha: b2a86bb * Authored by Matthew Bargar <[email protected]> on 2016-11-21T23:18:20Z **Commit 2:** DRY it up * Original sha: 927de50 * Authored by Matthew Bargar <[email protected]> on 2016-11-22T16:21:21Z **Commit 3:** Phrase tests * Original sha: 79e69bd * Authored by Matthew Bargar <[email protected]> on 2016-11-22T16:48:12Z **Commit 4:** Only include necessary comparators and add tests * Original sha: 5b9137b * Authored by Matthew Bargar <[email protected]> on 2016-11-22T17:38:59Z Former-commit-id: 313794b
Painless scripted fields that consisted of more than a single expression
would break when the user attempted to filter on them in Discover or
Visualize because of the naive way we were building them. We now wrap
the user's script in a lambda so that it can be as complex at they need
it to be. The only special exception is that the user cannot define
named functions since those cannot go inside a Painless lambda.
Note Make sure to use a recent build of ES when testing, you'll get an error if the ES PR referenced below isn't included in your build. ESVM's build is currently out of date.
Fixes #9024
Related elastic/elasticsearch#21635