Skip to content

Conversation

@costin
Copy link
Member

@costin costin commented Feb 5, 2019

Aliases defined in SELECT (Project or Aggregate) are now resolved in the
following WHERE clause. The Analyzer has been enhanced to identify this
rule and replace the field accordingly so that queries such as:

SELECT int AS i FROM t WHERE i > 10

Do not fail anymore (as i was unresolved inside the WHERE clause).

Close #29983

Aliases defined in SELECT (Project or Aggregate) are now resolved in the
following WHERE clause. The Analyzer has been enhanced to identify this
rule and replace the field accordingly.

Close elastic#29983
@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.

LGTM. Nice, this typically is not supported by RDBMS (MySQL, PostgreSQL, etc.)

postgres=# SELECT emp_no AS a FROM test_emp WHERE a > 10;
ERROR:  column "a" does not exist
LINE 1: SELECT emp_no AS a FROM test_emp WHERE a > 10;                                        ^

The reason is that SELECT is supposed to wrap the FROM t WHERE... so WHERE is unaware of the projection. But anyway, it's handy for the user to have it.

import static java.util.Collections.emptyMap;
import static java.util.Collections.singletonMap;

@TestLogging("org.elasticsearch.xpack.sql:TRACE")
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this on purpose?

Copy link
Member Author

Choose a reason for hiding this comment

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

No, leftover.

}

private Expression replaceAliases(Expression condition, List<? extends NamedExpression> named) {
List<Alias> aliases = new ArrayList<>();
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 more efficient to have a Map<String, Alias> where the key is the alias.name() and avoid iteration over a list?

Copy link
Member Author

Choose a reason for hiding this comment

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

It is; will update.

Copy link
Member Author

Choose a reason for hiding this comment

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

Actually scratch that - it's not that easy due to the qualifier which might be present or not. I'll update the resolution though.

Copy link
Contributor

@astefan astefan left a comment

Choose a reason for hiding this comment

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

LGTM


return condition.transformDown(u -> {
for (Alias alias : aliases) {
if (alias.name().equals(u.name()) || Objects.equals(alias.qualifiedName(), u.qualifiedName())) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there a case where the names are not equal but the qualifiedName() are equal?
Couldn't we check just the qualifiedName()?
If there is such case can we have it in a test?

Copy link
Member Author

Choose a reason for hiding this comment

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

An alias can be qualified as part of a subquery - the qualifiedName doesn't work in cases where one side is qualified the other isn't (the names are equal by one of the qualifier is missing).
I couldn't come up with a test case however I've updated the comparison to be in sync with that of the identifier resolution (in simplified form).

@costin
Copy link
Member Author

costin commented Feb 5, 2019

@elasticmachine run elasticsearch-ci/2

@costin costin merged commit 1a02445 into elastic:master Feb 6, 2019
@costin costin deleted the fix-29983 branch February 6, 2019 10:09
@costin
Copy link
Member Author

costin commented Feb 6, 2019

@gingerwizard FYI

costin added a commit that referenced this pull request Feb 6, 2019
Aliases defined in SELECT (Project or Aggregate) are now resolved in the
following WHERE clause. The Analyzer has been enhanced to identify this
rule and replace the field accordingly.

Close #29983

(cherry picked from commit 1a02445)
jasontedor added a commit to jasontedor/elasticsearch that referenced this pull request Feb 6, 2019
…on-leases-recovery

* elastic/master:
  SQL: Allow look-ahead resolution of aliases for WHERE clause (elastic#38450)
  Add API key settings documentation (elastic#38490)
  Remove support for maxRetryTimeout from low-level REST client (elastic#38085)
  Update IndexTemplateMetaData to allow unknown fields (elastic#38448)
  Mute testRetentionLeasesSyncOnRecovery (elastic#38488)
  Change the min supported version to 6.7.0 for API keys (elastic#38481)
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: WHERE clause doesn't utilise alias of SELECT expression/func successfully

5 participants