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

Prevent L019 plus L034 corrupting SQL #1803

Conversation

barrywhart
Copy link
Member

Brief summary of the change made

Fixes #1734

Are there any other side effects of this change that we should be aware of?

No.

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 in test/fixtures/rules/std_rule_cases.
    • .sql/.yml parser test cases in test/fixtures/dialects (note YML files can be auto generated with python test/generate_parse_fixture_yml.py or by running tox locally).
    • Full autofix test cases in test/fixtures/linter/autofix.
    • Other.
  • Added appropriate documentation for the change.

  • Created GitHub issues for any relevant followup/future enhancements if appropriate.

# Reuse the previous leading comma violation to
# create a new trailing comma
[last_code_seg, last_leading_comma_seg],
"create",
Copy link
Member Author

@barrywhart barrywhart Nov 1, 2021

Choose a reason for hiding this comment

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

This is the fix. If we "edit", it corrupts the parse tree by making the newly placed comma segment a child of the code segment. This is wrong. It should be a sibling. We achieve this by using "create" instead. This requires using a different anchor: the segment following the last code segment, not the last code segment itself.

This bug is a bit similar to the #1304 bug from a month or so ago where lint fixes end up placing whitespace segments in weird places they don't belong. Noting this because there's an open question whether the core linter could help detect or avoid such issues. I suggest we continue fixing the individual rules while we can, but this deeper improvement may prove necessary at some point.

@@ -67,7 +66,7 @@ def _last_comment_seg(raw_stack):
return None

@staticmethod
def _last_code_seg(raw_stack):
def _last_code_seg(raw_stack: Tuple[RawSegment, ...]) -> Optional[RawSegment]:
Copy link
Member Author

Choose a reason for hiding this comment

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

Just adding type hints; no change in functionality.

@@ -77,6 +76,17 @@ def _last_code_seg(raw_stack):
return segment
return None

@staticmethod
Copy link
Member Author

Choose a reason for hiding this comment

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

New helper function.

@@ -0,0 +1,5 @@
SELECT
Copy link
Member Author

Choose a reason for hiding this comment

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

Previously, the bug was corrupting the SQL, leaving commas in the wrong place.

@@ -123,7 +133,7 @@ def _eval(self, context: RuleContext) -> Optional[LintResult]:
# A comma preceded by a new line == a leading comma
if context.segment.is_type("comma"):
last_seg = self._last_code_seg(context.raw_stack)
if last_seg.is_type("newline"):
if last_seg and last_seg.is_type("newline"):
Copy link
Member Author

Choose a reason for hiding this comment

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

Checking that last_seg is not None. mypy wanted this, and this may have fixed a bug (I didn't study closely).

@codecov
Copy link

codecov bot commented Nov 1, 2021

Codecov Report

Merging #1803 (223d04e) into main (ef29e8e) will not change coverage.
The diff coverage is 100.00%.

Impacted file tree graph

@@            Coverage Diff            @@
##              main     #1803   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files          138       138           
  Lines         9800      9819   +19     
=========================================
+ Hits          9800      9819   +19     
Impacted Files Coverage Δ
src/sqlfluff/dialects/dialect_bigquery_keywords.py 100.00% <ø> (ø)
src/sqlfluff/dialects/dialect_bigquery.py 100.00% <100.00%> (ø)
src/sqlfluff/rules/L019.py 100.00% <100.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update ef29e8e...223d04e. Read the comment docs.

Copy link
Member

@tunetheweb tunetheweb left a comment

Choose a reason for hiding this comment

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

One suggestion. But maybe this is the convention in Python so happy to go with that you have if you think it's right as is.

@@ -77,6 +76,16 @@ def _last_code_seg(raw_stack):
return segment
return None

@staticmethod
def _follows_seg(
Copy link
Member

@tunetheweb tunetheweb Nov 1, 2021

Choose a reason for hiding this comment

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

Not loving the name here. I'm not a Python developer but is there a better name? Like _get_following_seg or _get_next_seg?

Copy link
Member Author

Choose a reason for hiding this comment

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

👍 I'll change it to _get_following_seg.

@barrywhart barrywhart merged commit 2e10f94 into sqlfluff:main Nov 2, 2021
@tunetheweb tunetheweb changed the title L019 plus L034 corrupts SQL Prevent L019 plus L034 corrupts SQL Nov 6, 2021
@tunetheweb tunetheweb changed the title Prevent L019 plus L034 corrupts SQL Prevent L019 plus L034 corrupting SQL Nov 6, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

TSQL linting fix: L019+L034 breaks the code
2 participants