-
Notifications
You must be signed in to change notification settings - Fork 24.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 Lambdas in Painless to be Able to Use Top-Level Variables Such as params and doc #21635
Conversation
multiple contexts.
So I think this solves #21479 by giving Kibana a fully working way to do text manipulation to build its script fields without choking on normal syntax. The lambda is in the main scope and that closes over all the magic keywords like I think it is nice to have this as a proposal but I don't like it as much as making script query aware of something to compare to or making a built in native script that delegates to the regular script to make the value and does the comparison. Those solutions have the benefit of allowing us to reuse exactly the same script that is used during a scripted terms aggregation, making things like error reporting simpler. On the other hand this is certainly better than what we have now because it works for most script fields. Scripts with functions don't work but that is better than we have now. I'm worried that this amounts to a dodge around the bigger issue in #21479 which is that ES contributors don't believe that kibana should make doing these queries easy at all so any sort of accommodation is a mistake. If we want to give Kibana a way to work around #21479 in 5.1 while we come to a more permanent conclusion then I think this is the right thing to do because painless is experimental and we can remove this is later versions if we decide on a "better" solution. Also, I like the fixes allowing lambdas to close over the magic variables. If we are going to merge this then it need yaml tests that set up the problem and the proposed work around for Kibana exactly to be sure that this makes sense in the context of the rest of the system which tends to have other sneaky stuff that doesn't come up in unit tests. Now that i think about it, I wonder if Kibana actually needs the utility at all once you fix the parameter issue. They could do something like
If we can do that then you have my whole hearted approval to get this in because then this is a pure positive change for painless. Kibana can use it to work around #21479 while we make a decision on it. |
"Those solutions have the benefit of allowing us to reuse exactly the same script that is used during a scripted terms aggregation, making things like error reporting simpler." This is exactly the opposite of the direction we're heading ultimately with per-context signatures. We should not encourage the re-use of scripts across contexts. If two contexts are so similar then they should be they should use the same signature. |
"Now that i think about it, I wonder if Kibana actually needs the utility at all once you fix the parameter issue." This is a good suggestion. I'm updating the PR now. |
I think we should do exactly that and the two solutions I proposed could be made to work that way when script context. I mean, I'm not sure we'll know until we build script contexts, but I think it'd work. I opened #21479 because I'm uncomfortable with any application doing text manipulation on scripts at all. Without this solution Kibana breaks lots of stuff. With this solution Kibana keeps most painless features but breaks function definitions. We could allow you to define function inside of lambdas and maybe they'd work too but I feel like something else is going to come up. And then we've designed the language around this weird text manipulation use case. |
Added yaml tests for Kibana use case.
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.
Left a nit about method naming. Otherwise this is great.
public void testLambdaCaptureFunctionParam() { | ||
assertEquals(5, exec("def foo(int x) { Optional.empty().orElseGet(() -> x) } return foo(5);")); | ||
} | ||
|
||
public void testUtilityCompare() { |
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.
Rename the method to something about captures I think now that the utility is gone.
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.
Done.
@nik9000 Thanks for the reviews. |
this is a bugfix now and can potentially go in to 5.0 branch no? |
@s1monw Yes, I will back port to both 5.1 and 5.0. |
This issue has changed from the original to be a bug fix. Previously, lambdas in the main method were not accepting variables from the outer scope such as ctx, params, etc. Now, they allow those variables to be used inside of a lambda. Example:
|
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
* 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 * DRY it up * Phrase tests * Only include necessary comparators and add tests
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 <mbargar@gmail.com> on 2016-11-21T23:18:20Z **Commit 2:** DRY it up * Original sha: 927de50 * Authored by Matthew Bargar <mbargar@gmail.com> on 2016-11-22T16:21:21Z **Commit 3:** Phrase tests * Original sha: 79e69bd * Authored by Matthew Bargar <mbargar@gmail.com> on 2016-11-22T16:48:12Z **Commit 4:** Only include necessary comparators and add tests * Original sha: 5b9137b * Authored by Matthew Bargar <mbargar@gmail.com> 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 <mbargar@gmail.com> on 2016-11-21T23:18:20Z **Commit 2:** DRY it up * Original sha: 927de50 * Authored by Matthew Bargar <mbargar@gmail.com> on 2016-11-22T16:21:21Z **Commit 3:** Phrase tests * Original sha: 79e69bd * Authored by Matthew Bargar <mbargar@gmail.com> on 2016-11-22T16:48:12Z **Commit 4:** Only include necessary comparators and add tests * Original sha: 5b9137b * Authored by Matthew Bargar <mbargar@gmail.com> 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 <mbargar@gmail.com> on 2016-11-21T23:18:20Z **Commit 2:** DRY it up * Original sha: 927de50 * Authored by Matthew Bargar <mbargar@gmail.com> on 2016-11-22T16:21:21Z **Commit 3:** Phrase tests * Original sha: 79e69bd * Authored by Matthew Bargar <mbargar@gmail.com> on 2016-11-22T16:48:12Z **Commit 4:** Only include necessary comparators and add tests * Original sha: 5b9137b * Authored by Matthew Bargar <mbargar@gmail.com> 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 <mbargar@gmail.com> on 2016-11-21T23:18:20Z **Commit 2:** DRY it up * Original sha: 927de50 * Authored by Matthew Bargar <mbargar@gmail.com> on 2016-11-22T16:21:21Z **Commit 3:** Phrase tests * Original sha: 79e69bd * Authored by Matthew Bargar <mbargar@gmail.com> on 2016-11-22T16:48:12Z **Commit 4:** Only include necessary comparators and add tests * Original sha: 5b9137b * Authored by Matthew Bargar <mbargar@gmail.com> on 2016-11-22T17:38:59Z
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 <mbargar@gmail.com> on 2016-11-21T23:18:20Z **Commit 2:** DRY it up * Original sha: 927de50 * Authored by Matthew Bargar <mbargar@gmail.com> on 2016-11-22T16:21:21Z **Commit 3:** Phrase tests * Original sha: 79e69bd * Authored by Matthew Bargar <mbargar@gmail.com> on 2016-11-22T16:48:12Z **Commit 4:** Only include necessary comparators and add tests * Original sha: 5b9137b * Authored by Matthew Bargar <mbargar@gmail.com> on 2016-11-22T17:38:59Z Former-commit-id: 313794b
As the title says. See the tests for examples.
Relates (#21479)
As a bonus this also fixes a bug related to certain reserved variable names not working in a lambda.
Relates (#20869)
@s1monw I think I'm under the 1.5 hours you said I had :)