-
Notifications
You must be signed in to change notification settings - Fork 24.9k
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
QL: Turn eager query translations lazy #69205
Conversation
Before the `ExpressionTranslators` did some unnecessary `Expression` -> `Query` translations, where the result queries were thrown away by later translations (by the `wrapFunctionQuery`). This change adds laziness, so translations don't execute unnecessarily. Follows elastic#68783
* SqlTranslatorHandler dead code removal * Pushed the common `wrapFunctionQuery` implementation into the TranslatorHandler
@elasticmachine run elasticsearch-ci/2 |
Pinging @elastic/es-ql (Team:QL) |
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 - however I'd like a few more tests. The changes are small but somewhat subtle and since some code is removed and as you pointed, unused, it would help to have more tests on the front (in this case geo) to avoid ending in a similar situation in the future as we're blind on that front.
@@ -1334,6 +1334,7 @@ public void testTranslateStDistanceToQuery() { | |||
assertEquals(20.0, gq.lat(), 0.00001); | |||
assertEquals(10.0, gq.lon(), 0.00001); | |||
assertEquals(25.0, gq.distance(), 0.00001); | |||
optimizeAndPlan(p); |
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.
? - there are no extra assertions after this call.
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.
The optimizeAndPlan(p)
was introduced as part of the 9fc11a5 commit to make sure we exercise the SqlTranslationHandler
(the translate()
does not do that) and check if it will produce a RuntimeException
. Added an extra check on the generated query.
Added a test for the Verifier to capture the current behaviour: the WHERE ST_Distance(nested.point, ...) < X
is not even allowed today (WHERE isn't (yet) compatible with scalar functions on nested fields
).
|
||
private static Query translate(IsNotNull isNotNull, TranslatorHandler handler) { |
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.
Use a different name to avoid confusion, it's counter intuitive for doTranslate
to call translate
, I would have expected it to be the other way around.
Maybe createQuery
or internalTranslate
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.
+1
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.
Might be a tad confusing, but this "doTranslate -> translate" pattern seems to be a pre-existing one.
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.
As @bpintea pointed out the doTranslate / translate
methods are pre-existing. I would do the renames in a separate PR across the all the translators and keep this PR focused only on laziness.
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.
Also fine for me, to address this later!
@@ -265,7 +271,7 @@ public static void checkBinaryComparison(BinaryComparison bc) { | |||
|
|||
public static Query doTranslate(BinaryComparison bc, TranslatorHandler handler) { | |||
checkBinaryComparison(bc); | |||
return handler.wrapFunctionQuery(bc, bc.left(), translate(bc, handler)); | |||
return handler.wrapFunctionQuery(bc, bc.left(), () -> translate(bc, handler)); |
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.
Same here even though translate
existed before it should be renamed.
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
|
||
private static Query translate(IsNotNull isNotNull, TranslatorHandler handler) { |
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.
Might be a tad confusing, but this "doTranslate -> translate" pattern seems to be a pre-existing one.
return ExpressionTranslator.wrapIfNested(querySupplier.get(), field); | ||
} | ||
return new ScriptQuery(sf.source(), sf.asScript()); | ||
} | ||
|
||
String nameOf(Expression e); |
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.
Loosely coupled to this refactoring, but: couldn't nameOf()
also be offered a static implementation here? All implementations could actually have it as a static method and SQL's (whose implementation lives actually in QueryTranslator
) only treats the DateTimeFunction
case additionally, compared to QL's.
So a bit more duplication could be stripped away.
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.
Removing "dead" code without any good reason doesn't sound great from my side. The code has been added there with a good reason, hopefully; removing it should have an equally good reason, beside being "dead". I'd like a bit more investigation put into this issue to try and track down any refactoring (I'm mainly looking here at the split from one SQL project to QL/SQL/EQL) that could have led to this "dead" code now.
Maybe test the same 9fc11a5 commit in an older branch (before ql/sql/eql refactoring), or in the same commit that added the GEO part to SQL project. Maybe the code was added for no good reason since the beginning, maybe its utility faded with subsequent refactoring, but I think it's important to know why this code is dead now.
@astefan See below.
I'd open a separate issue if we decide to make this particular optimization work on nested fields again. |
Sounds good to me! |
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. Thank you @palesz
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, delayed sorry :)
Before the `ExpressionTranslators` did some unnecessary `Expression` -> `Query` translations, where the result queries were thrown away by later translations (by the `wrapFunctionQuery`). This change adds laziness, so translations don't execute unnecessarily. Follows elastic#68783 and elastic#68788
Before the
ExpressionTranslators
did some unnecessaryExpression
->Query
translations, where the result queries were thrownaway by later translations (by the
wrapFunctionQuery
).This change adds laziness, so translations don't execute unnecessarily.
Follows #68783 and #68788
Note: #68788 (comment) requested more
SqlTranslatorHandler
tests, but the 9fc11a5 commit shows that the code is unreachable. Can only be reached whenGeoDistanceQuery
is generated and the test that generates aGeoDistanceQuery
does not hit the line, so decided to remove it.