Skip to content
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

SQL: rewrite ROUND and TRUNCATE functions with a different optional parameter handling method #40242

Merged
merged 8 commits into from
Mar 21, 2019

Conversation

astefan
Copy link
Contributor

@astefan astefan commented Mar 20, 2019

The optional parameter for these two functions was handled in the constructor by passing the value of 0 whenever the parameter was missing. This had an apparently minor implication of defining a second child for the function (the second parameter). If the value was kept as null (missing) the function would have had a single child (the first parameter).

This affected the comparison operation from the Analyzer and the same function that was already resolved wouldn't match the new function found because the new one had no second parameter while the resolved one had the parameter 0. Because of this comparison failing, a GROUP BY the same function would fail.

This PR also fixes a bug with ATAN2 and POWER functions which didn't have any Painless methods.

Fixes #40001.

astefan added 2 commits March 20, 2019 08:51
approach to handling the optional parameter in the constructor. Until now
the optional parameter was considered 0 if the value was missing and the
constructor was filling in this value. The current solution is to have
the optional parameter as null right until the actual calculation is done.
@elasticmachine
Copy link
Collaborator

Pinging @elastic/es-search

Copy link
Contributor

@matriv matriv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice refactoring. Left some comments.


}

return right == null ? TypeResolution.TYPE_RESOLVED : isNumeric(right, sourceText(), ParamOrdinal.SECOND);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The right should be of integer type (not rational), so we should catch it here before the execution time.

public DataType dataType() {
return left().dataType();
public Expression replaceChildren(List<Expression> newChildren) {
if (right() != null && newChildren.size() != 2) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd extract this to the parent method and leave here only the instance creation, as it's duplicated also in Round.

}

private ScriptTemplate asScriptFrom(ScriptTemplate leftScript, ScriptTemplate rightScript) {
if (right == null) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't be possible to avoid the "double" methods in painless and just have one with both args where null is passed for the right arg?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gave it a try, but failed. If you have any ideas, I'd love to hear them. Otherwise, I'll try later today or tomorrow.

Copy link
Contributor

@matriv matriv Mar 20, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I took some time here and it works like that: matriv@b35090e

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed. Nice one. I've incorporated it in the PR. Thanks.

import java.util.function.BiFunction;

/**
* Processor for binary mathematical operations that can have the second parameter optional.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe rephrase: ... that have a second optional parameter.

@@ -200,6 +200,23 @@ ROUND(SQRT(CAST(EXP(languages) AS SMALLINT)),2):d| COUNT(*):l
null |10
;

groupByRoundWithTwoParams
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't this be tested in QueryTranslatorTests?

@astefan
Copy link
Contributor Author

astefan commented Mar 20, 2019

@elasticmachine run elasticsearch-ci/1

@astefan
Copy link
Contributor Author

astefan commented Mar 20, 2019

@elasticmachine run elasticsearch-ci/default-distro

3 similar comments
@astefan
Copy link
Contributor Author

astefan commented Mar 20, 2019

@elasticmachine run elasticsearch-ci/default-distro

@astefan
Copy link
Contributor Author

astefan commented Mar 20, 2019

@elasticmachine run elasticsearch-ci/default-distro

@astefan
Copy link
Contributor Author

astefan commented Mar 21, 2019

@elasticmachine run elasticsearch-ci/default-distro

Copy link
Contributor

@matriv matriv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link
Member

@costin costin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Considering the timing and everything, I'm fine with the approach.
Going forward I think we need a more generic way of dealing with optional arguments - whether that requires updates in the Analyzer or/and the functions remains to be determined.

@astefan astefan merged commit 3e314f8 into elastic:master Mar 21, 2019
@astefan astefan deleted the 40001_fix branch March 21, 2019 19:32
astefan added a commit that referenced this pull request Mar 22, 2019
…arameter handling method (#40242)

* Rewrite Round and Truncate functions to have a slightly different
approach to handling the optional parameter in the constructor. Until now
the optional parameter was considered 0 if the value was missing and the
constructor was filling in this value. The current solution is to have
the optional parameter as null right until the actual calculation is done.

(cherry picked from commit 3e314f8)
astefan added a commit that referenced this pull request Mar 22, 2019
…arameter handling method (#40242)

* Rewrite Round and Truncate functions to have a slightly different
approach to handling the optional parameter in the constructor. Until now
the optional parameter was considered 0 if the value was missing and the
constructor was filling in this value. The current solution is to have
the optional parameter as null right until the actual calculation is done.

(cherry picked from commit 3e314f8)
astefan added a commit that referenced this pull request Mar 22, 2019
…arameter handling method (#40242)

* Rewrite Round and Truncate functions to have a slightly different
approach to handling the optional parameter in the constructor. Until now
the optional parameter was considered 0 if the value was missing and the
constructor was filling in this value. The current solution is to have
the optional parameter as null right until the actual calculation is done.

(cherry picked from commit 3e314f8)
astefan added a commit that referenced this pull request Mar 22, 2019
…arameter handling method (#40242)

* Rewrite Round and Truncate functions to have a slightly different
approach to handling the optional parameter in the constructor. Until now
the optional parameter was considered 0 if the value was missing and the
constructor was filling in this value. The current solution is to have
the optional parameter as null right until the actual calculation is done.

(cherry picked from commit 3e314f8)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

SQL: GROUP BY with function group returns error
7 participants