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: SubSelect unresolved bugfix #55956

Merged
merged 6 commits into from Apr 30, 2020

Conversation

astefan
Copy link
Contributor

@astefan astefan commented Apr 29, 2020

This fixes an issue where a sub-query was attempted to be resolved at the wrong time in the analysis, generating an error message similar to org.elasticsearch.xpack.sql.capabilities.UnresolvedException: Invalid call to attribute on an unresolved object ?* AS ?. Bug introduced with #41964.

@elasticmachine
Copy link
Collaborator

Pinging @elastic/es-ql (:Query Languages/SQL)

@elasticmachine elasticmachine added the Team:QL (Deprecated) Meta label for query languages team label Apr 29, 2020
@@ -722,7 +722,7 @@ protected LogicalPlan rule(LogicalPlan plan) {
}

// Try to resolve aggregates and groupings based on the child plan
if (plan instanceof Aggregate) {
if (plan instanceof Aggregate && !plan.resolved() && plan.childrenResolved()) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
if (plan instanceof Aggregate && !plan.resolved() && plan.childrenResolved()) {
if (plan instanceof Aggregate && plan.resolved() == false && plan.childrenResolved()) {

despite my own prefs.

Copy link
Member

Choose a reason for hiding this comment

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

Considering this condition applies for all ifs inside this rule, I would extract it to the top:

        @Override
        protected LogicalPlan rule(LogicalPlan plan) {
            if (plan.resolved() || plan.childrenResolved() == false) {
               return plan;
            }
            if (plan instanceof Filter) {...

In fact the check for children resolution is present I believe in all analyzer rules so it might make to create a subclass that all other rules extend to avoid having to repeat this bit of code which as we can see, introduces some subtle bugs.

I'm fine with doing it in a follow-up PR to get this in (with the if moved to the top level).

Copy link
Contributor

@bpintea bpintea left a comment

Choose a reason for hiding this comment

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

Great set of tests. I'd be great to see some more complex subqueries, but I guess I'm just trying to better understand our own boundaries.
Anyways, 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.

LGTM - thanks for the quick turn-around!

@@ -722,7 +722,7 @@ protected LogicalPlan rule(LogicalPlan plan) {
}

// Try to resolve aggregates and groupings based on the child plan
if (plan instanceof Aggregate) {
if (plan instanceof Aggregate && !plan.resolved() && plan.childrenResolved()) {
Copy link
Member

Choose a reason for hiding this comment

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

Considering this condition applies for all ifs inside this rule, I would extract it to the top:

        @Override
        protected LogicalPlan rule(LogicalPlan plan) {
            if (plan.resolved() || plan.childrenResolved() == false) {
               return plan;
            }
            if (plan instanceof Filter) {...

In fact the check for children resolution is present I believe in all analyzer rules so it might make to create a subclass that all other rules extend to avoid having to repeat this bit of code which as we can see, introduces some subtle bugs.

I'm fine with doing it in a follow-up PR to get this in (with the if moved to the top level).

@astefan astefan requested a review from costin April 30, 2020 00:47
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.

LGTM

@@ -610,9 +600,12 @@ private AggGroupingFailure(List<String> expectedGrouping) {
}

@Override
protected LogicalPlan rule(LogicalPlan plan) {
protected LogicalPlan rulePlan(LogicalPlan plan) {
if (plan.resolved()) {
Copy link
Member

Choose a reason for hiding this comment

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

I don't think this is needed anymore - see AnalyzeRule which takes care of skipping if the node is resolved and skipResolved is true (default).

@@ -1312,4 +1303,17 @@ protected boolean skipResolved() {
return true;
}
}

abstract static class LogicalPlanAnalyzeRule extends AnalyzeRule<LogicalPlan> {
Copy link
Member

Choose a reason for hiding this comment

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

I'd pick a different name - maybe DefaultAnalyzeRule or BaseAnalyzeRule.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I was struggling with the name, indeed. I didn't particularly like LogicalPlanAnalyzeRule, but didn't find any better alternatives.

Copy link
Contributor

Choose a reason for hiding this comment

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

I like BaseAnalyzeRule.

return rulePlan(plan);
}

protected abstract LogicalPlan rulePlan(LogicalPlan plan);
Copy link
Member

Choose a reason for hiding this comment

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

rulePlan is repetitive (the method only accepts LogicalPlans) - how about doRule or analyze?

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 set of tests!

@@ -1312,4 +1303,17 @@ protected boolean skipResolved() {
return true;
}
}

abstract static class LogicalPlanAnalyzeRule extends AnalyzeRule<LogicalPlan> {
Copy link
Contributor

Choose a reason for hiding this comment

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

I like BaseAnalyzeRule.

@@ -0,0 +1,53 @@

Copy link
Contributor

Choose a reason for hiding this comment

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

Please add the following comment in case someone needs to mute a test in the future:
// To mute tests follow example in file: example.sql-spec

@astefan astefan merged commit 10167b1 into elastic:master Apr 30, 2020
@astefan astefan deleted the subselect_unresolved_bugfix branch April 30, 2020 17:30
astefan added a commit to astefan/elasticsearch that referenced this pull request Apr 30, 2020
* Resolve the missing refs only after the aggregate tree is resolved

(cherry picked from commit 10167b1)
astefan added a commit to astefan/elasticsearch that referenced this pull request Apr 30, 2020
* Resolve the missing refs only after the aggregate tree is resolved

(cherry picked from commit 10167b1)
astefan added a commit to astefan/elasticsearch that referenced this pull request Apr 30, 2020
* Resolve the missing refs only after the aggregate tree is resolved

(cherry picked from commit 10167b1)
astefan added a commit that referenced this pull request May 1, 2020
* Resolve the missing refs only after the aggregate tree is resolved

(cherry picked from commit 10167b1)
astefan added a commit that referenced this pull request May 1, 2020
* Resolve the missing refs only after the aggregate tree is resolved

(cherry picked from commit 10167b1)
astefan added a commit that referenced this pull request May 1, 2020
* Resolve the missing refs only after the aggregate tree is resolved

(cherry picked from commit 10167b1)
breskeby pushed a commit that referenced this pull request May 7, 2020
* Resolve the missing refs only after the aggregate tree is resolved
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.

None yet

6 participants