-
-
Notifications
You must be signed in to change notification settings - Fork 653
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
L042: Enable autofix for some tricky cases #3700
L042: Enable autofix for some tricky cases #3700
Conversation
Codecov ReportBase: 100.00% // Head: 100.00% // No change to project coverage 👍
Additional details and impacted files@@ Coverage Diff @@
## main #3700 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 179 179
Lines 13729 13752 +23
=========================================
+ Hits 13729 13752 +23
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. ☔ View full report at Codecov. |
@barrywhart - are you ok incorporating #3717 into this or do you need a hand? |
@alanmcruickshank: I'm okay, thanks! This is a slow-moving, slightly experimental PR anyway. |
Failures: FAILED test/rules/yaml_test_cases_test.py::test__rule_test_case[L042_with_fail] FAILED test/rules/yaml_test_cases_test.py::test__rule_test_case[L042_issue_3572_correlated_subquery_3] FAILED test/rules/yaml_test_cases_test.py::test__rule_test_case[L042_issue_3598_avoid_looping_2] - AssertionError: assert 'WITH prep_1 ...* FROM cte1\n' == 'WITH temp AS...* FROM cte1\n'
FROM (SELECT a) | ||
) | ||
SELECT a FROM cte1 | ||
fix_str: | |
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.
Fixes previously unfixable issue that had previously triggered linter looping
src/sqlfluff/rules/L028.py
Outdated
children = list(query.children) | ||
# 'query.children' includes CTEs and "main" queries, but not queries in | ||
# the "FROM" list. We want to visit those as well. | ||
for a in select_info.table_aliases if select_info else []: |
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.
This additional code is now required because of the SelectCrawler
improvements. Previously, the behavior of SelectCrawler
was inconsistent about whether it returned queries in the FROM
list.
…thub.com/barrywhart/sqlfluff into bhart-issue_3598_l042_fix_tricky_queries
violations_after_fix: | ||
- description: select_statement clauses should not contain subqueries. Use CTEs instead | ||
line_no: 2 | ||
line_pos: 20 |
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.
violations_after_fix
because the two as b
aliases collide, preventing autofix from fixing the second 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.
LGTM - mostly style comments
src/sqlfluff/rules/L028.py
Outdated
children = list(query.children) | ||
# 'query.children' includes CTEs and "main" queries, but not queries in | ||
# the "FROM" list. We want to visit those as well. | ||
for a in select_info.table_aliases if select_info else []: |
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.
for a in select_info.table_aliases if select_info else []: | |
for a in (select_info.table_aliases if select_info else []): |
perhaps brackets or a variable, the turnary in line with a loop is an overload for 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.
I'll change it. Probably will add an if
around it.
src/sqlfluff/rules/L028.py
Outdated
if isinstance(q, Query): | ||
# Check for previously visited selectables to avoid possible |
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.
if isinstance(q, Query): | |
# Check for previously visited selectables to avoid possible | |
if not isinstance(q, Query): | |
continue | |
# Check for previously visited selectables to avoid possible |
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.
Will do
src/sqlfluff/rules/L028.py
Outdated
if not any(s.selectable in visited for s in q.selectables): | ||
visited.update(s.selectable for s in q.selectables) |
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.
if not any(s.selectable in visited for s in q.selectables): | |
visited.update(s.selectable for s in q.selectables) | |
if any(s.selectable in visited for s in q.selectables): | |
continue | |
visited.update(s.selectable for s in q.selectables) |
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.
Will do
src/sqlfluff/rules/L042.py
Outdated
"""Given the root query, compute lint warnings.""" | ||
parent_types = self._config_mapping[self.forbid_subquery_in] | ||
for q in [query] + list(query.ctes.values()): | ||
for selectable in q.selectables: | ||
if not selectable.select_info: | ||
continue |
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.
This method feels quite dense, I can't really make my way through it. Is there any code splitting possible?
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.
Probably. I'll take a look.
Brief summary of the change made
SelectCrawler
and is a bit shorter/simpler as a result.SelectCrawler
, especially involving nested queries and consistency around handling of subqueries inFROM
clauses. Adds automated tests forSelectCrawler
, which previously had none.Fixes #3598
Are there any other side effects of this change that we should be aware of?
The changes to
SelectCrawler
could surface some issues (e.g. I had to update L028 to get a test to pass).Pull Request checklist
Please confirm you have completed any of the necessary steps below.
Included test cases to demonstrate any code changes, which may be one or more of the following:
.yml
rule test cases intest/fixtures/rules/std_rule_cases
..sql
/.yml
parser test cases intest/fixtures/dialects
(note YML files can be auto generated withtox -e generate-fixture-yml
).test/fixtures/linter/autofix
.Added appropriate documentation for the change.
Created GitHub issues for any relevant followup/future enhancements if appropriate.