-
-
Notifications
You must be signed in to change notification settings - Fork 755
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
More dialect checking, fixes, inheritance cleanup #2942
More dialect checking, fixes, inheritance cleanup #2942
Conversation
@@ -152,7 +152,28 @@ def replace(self, **kwargs: DialectElementType): | |||
for n in kwargs: | |||
if n not in self._library: # pragma: no cover | |||
raise ValueError(f"{n!r} is not already registered in {self!r}") | |||
self._library[n] = kwargs[n] | |||
|
|||
# To replace a segment, the replacement must either be a |
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 code was in the segment()
decorator I removed in the previous PR. That code is still useful, so I moved it to the still-used replace()
function.
replace()
that were deleted in prior PR
src/sqlfluff/core/dialects/base.py
Outdated
if self._library[n].type != cls.type: | ||
raise ValueError( # pragma: no cover | ||
f"Cannot replace {n!r} because 'type' property does not " | ||
f"match: {cls.type} != {self._library[n].type}" | ||
) |
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.
These lines are actually new. I had wondered if the type
property was always consistent when replacing a parent segment, and I found several cases where it wasn't. This was presumably a mistake/accident. Several, but not all, of these mismatches were in the Exasol dialect.
Note that when using segment inheritance (now the recommended usual practice when replacing segments), the type
property can be inherited and thus mismatches avoided.
type = "select_statement" | ||
match_grammar = ansi_dialect.get_segment( | ||
"UnorderedSelectStatementSegment" | ||
).match_grammar.copy() |
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.
With inheritance, no need to copy if not modifying.
match_grammar = ansi_dialect.get_segment( | ||
"WildcardExpressionSegment" | ||
).match_grammar.copy( | ||
match_grammar = ansi.WildcardExpressionSegment.match_grammar.copy( |
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 PR eliminates dialects using get_segment()
in favor of direct attribute access (cleaner).
@@ -1038,13 +1031,10 @@ class SelectClauseSegment(BaseSegment): | |||
enforce_whitespace_preceding_terminator=True, | |||
) | |||
|
|||
parse_grammar = Ref("SelectClauseSegmentGrammar") |
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 is now inherited from the base class.
OneOf("PRECEDING", "FOLLOWING"), | ||
), | ||
) | ||
_frame_extent = ansi.FrameClauseSegment._frame_extent |
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 confirmed this is identical to ANSI, so I removed the duplication.
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.
Does it not get it automatically then through inheritance? So is this line needed?
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.
Did you answer this one @barrywhart ? Other than that good to go I think.
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.
It's similar to a question you asked previously. Once the class has been created, FrameClauseSegment._frame_extent
exists. But not during the class definition. On line 2754, we need to use it 3 times, so it's shorter to assign it to a variable rather than repeating the full reference 3 times:
OneOf(ansi.FrameClauseSegment._frame_extent, Sequence("BETWEEN", ansi.FrameClauseSegment._frame_extent, "AND", ansi.FrameClauseSegment._frame_extent)),
I think I shared a Stack Overflow link earlier -- if you go back and read that, they explain how this works. It's definitely different than most other OO languages like C++ and Java. The behavior is arguably "simpler", but makes code inside a class more verbose sometimes.
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.
OK gotcha.
@@ -1570,16 +1563,6 @@ class AlterWarehouseStatementSegment(BaseSegment): | |||
) | |||
|
|||
|
|||
class CommentClauseSegment(BaseSegment): |
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 entire segment definition is identical to the base ANSI dialect, so I removed it.
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.
It has a different comment to show it's not used for views or tables. But yeah agreed not needed.
@@ -981,7 +972,7 @@ class InsertStatementSegment(BaseSegment): | |||
https://spark.apache.org/docs/latest/sql-ref-syntax-dml-insert-overwrite-table.html | |||
""" | |||
|
|||
type = "insert_table_statement" | |||
type = "insert_statement" |
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.
Fixed a type
mismatch with the ANSI segment type. Did not use inheritance because ANSI segment uses parse_grammar
but this one doesn't.
Codecov Report
@@ Coverage Diff @@
## main #2942 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 164 164
Lines 11892 11843 -49
=========================================
- Hits 11892 11843 -49
Continue to review full report at Codecov.
|
OneOf("PRECEDING", "FOLLOWING"), | ||
), | ||
) | ||
_frame_extent = ansi.FrameClauseSegment._frame_extent |
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.
Does it not get it automatically then through inheritance? So is this line needed?
@@ -1570,16 +1563,6 @@ class AlterWarehouseStatementSegment(BaseSegment): | |||
) | |||
|
|||
|
|||
class CommentClauseSegment(BaseSegment): |
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.
It has a different comment to show it's not used for views or tables. But yeah agreed not needed.
@tunetheweb: Ok, I added type hints throughout the ANSI dialect, which allowed me to remove almost every use of
|
@tunetheweb: I added the test we discussed. See |
Brief summary of the change made
replace()
that were deleted in prior PRtype
matches base dialect when replacing a segmentmatch_grammar
andparse_grammar
, the replacement must define both of them or neither of themAre there any other side effects of this change that we should be aware of?
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.