Skip to content

Commit

Permalink
fix #468: support snowflake // comments
Browse files Browse the repository at this point in the history
  • Loading branch information
tconbeer committed Sep 20, 2023
1 parent 781ff3d commit deb8469
Show file tree
Hide file tree
Showing 8 changed files with 76 additions and 14 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ All notable changes to this project will be documented in this file.
### Formatting Changes and Bug Fixes

- `any()` and `all()` will no longer get spaces between the function name and the parenthesis, unless they are a part of a `like any ()` or `like all ()` operator ([#483](https://github.com/tconbeer/sqlfmt/issues/483) - thank you [@damirbk](https://github.com/damirbk)!).
- Snowflake's `//` comment markers are now parsed as comments and rewritten to `--` on formatting ([#468](https://github.com/tconbeer/sqlfmt/issues/468) - thank you [@nilsonavp](https://github.com/nilsonavp)!).

## [0.19.2] - 2023-07-31

Expand Down
12 changes: 4 additions & 8 deletions src/sqlfmt/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -374,17 +374,13 @@ def _perform_safety_check(analyzer: Analyzer, raw_query: Query, result: str) ->
)

raw_comments = [
comment.token.token for line in raw_query.lines for comment in line.comments
comment.body for line in raw_query.lines for comment in line.comments
]
result_comments = [
comment.token.token for line in result_query.lines for comment in line.comments
comment.body for line in result_query.lines for comment in line.comments
]
stripped_raw = "".join(
["".join(c.split()).replace("--", "").replace("#", "") for c in raw_comments]
)
stripped_res = "".join(
["".join(c.split()).replace("--", "").replace("#", "") for c in result_comments]
)
stripped_raw = "".join(["".join(c.split()) for c in raw_comments])
stripped_res = "".join(["".join(c.split()) for c in result_comments])
try:
assert stripped_raw == stripped_res
except AssertionError:
Expand Down
23 changes: 21 additions & 2 deletions src/sqlfmt/comment.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class Comment:
token: Token
is_standalone: bool
previous_node: Optional[Node]
comment_marker: ClassVar[re.Pattern] = re.compile(r"(--|#|/\*|\{#-?)([^\S\n]*)")
comment_marker: ClassVar[re.Pattern] = re.compile(r"(--|#|//|/\*|\{#-?)([^\S\n]*)")

def __str__(self) -> str:
"""
Expand Down Expand Up @@ -52,6 +52,18 @@ def _get_marker(self) -> Tuple[str, int]:
_, len = match.span(2)
return self.token.token[:epos], len

def _rewrite_marker(self, marker: str) -> str:
"""
Rewrites the comment marker to the standard --
The following markers are rewritten:
//
"""
if marker == "//":
return "--"
else:
return marker

def _comment_parts(self) -> Tuple[str, str]:
"""
For a comment, returns a tuple of the comment's marker and its contents
Expand All @@ -60,7 +72,7 @@ def _comment_parts(self) -> Tuple[str, str]:
assert not self.is_multiline
marker, skipchars = self._get_marker()
comment_text = self.token.token[skipchars:]
return marker, comment_text
return self._rewrite_marker(marker), comment_text

@property
def is_multiline(self) -> bool:
Expand All @@ -77,6 +89,13 @@ def is_c_style(self) -> bool:
def is_inline(self) -> bool:
return not self.is_standalone and not self.is_multiline and not self.is_c_style

@property
def body(self) -> str:
if self.is_multiline:
return self.token.token.strip()
else:
return self._comment_parts()[1].strip()

@property
def formatting_disabled(self) -> bool:
if self.previous_node is None:
Expand Down
1 change: 1 addition & 0 deletions src/sqlfmt/rules/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ def group(*choices: str) -> str:
SQL_COMMENT = group(
r"--[^\r\n]*",
r"#[^\r\n]*",
r"//[^\r\n]*", # snowflake's js-style double-slash comment
r"/\*[^*]*\*+(?:[^/*][^*]*\*+)*/", # simple block comment
)

Expand Down
17 changes: 17 additions & 0 deletions tests/data/unformatted/128_double_slash_comments.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
-- source: https://github.com/tconbeer/sqlfmt/issues/468
select * from {{ ref("events") }} e
// join from events table
left join {{ ref("users") }} u
on u.id = e.user_id
;
select "https://sqlfmt.com" as url_not_a_comment
from foo
)))))__SQLFMT_OUTPUT__(((((
-- source: https://github.com/tconbeer/sqlfmt/issues/468
select *
from {{ ref("events") }} e
-- join from events table
left join {{ ref("users") }} u on u.id = e.user_id
;
select "https://sqlfmt.com" as url_not_a_comment
from foo
1 change: 1 addition & 0 deletions tests/functional_tests/test_general_formatting.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
"unformatted/125_numeric_constants.sql",
"unformatted/126_blank_lines.sql",
"unformatted/127_more_comments.sql",
"unformatted/128_double_slash_comments.sql",
"unformatted/200_base_model.sql",
"unformatted/201_basic_snapshot.sql",
"unformatted/202_unpivot_macro.sql",
Expand Down
33 changes: 29 additions & 4 deletions tests/unit_tests/test_comment.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,15 @@ def short_mysql_comment() -> Comment:
return comment


@pytest.fixture
def short_js_comment() -> Comment:
t = Token(
type=TokenType.COMMENT, prefix=" ", token="// short comment", spos=0, epos=16
)
comment = Comment(t, is_standalone=False, previous_node=None)
return comment


@pytest.fixture
def nospace_comment() -> Comment:
t = Token(
Expand Down Expand Up @@ -69,38 +78,54 @@ def fmt_disabled_comment() -> Comment:


def test_get_marker(
short_comment: Comment, short_mysql_comment: Comment, nospace_comment: Comment
short_comment: Comment,
short_mysql_comment: Comment,
nospace_comment: Comment,
short_js_comment: Comment,
) -> None:
assert short_comment._get_marker() == ("--", 3)
assert short_mysql_comment._get_marker() == ("#", 2)
assert short_js_comment._get_marker() == ("//", 3)
assert nospace_comment._get_marker() == ("--", 2)


def test_comment_parts(
short_comment: Comment, short_mysql_comment: Comment, nospace_comment: Comment
short_comment: Comment,
short_mysql_comment: Comment,
nospace_comment: Comment,
short_js_comment: Comment,
) -> None:
assert short_comment._comment_parts() == ("--", "short comment")
assert short_mysql_comment._comment_parts() == ("#", "short comment")
assert short_js_comment._comment_parts() == ("--", "short comment")
assert nospace_comment._comment_parts() == ("--", "short comment")


def test_str_len(
short_comment: Comment, short_mysql_comment: Comment, nospace_comment: Comment
short_comment: Comment,
short_mysql_comment: Comment,
nospace_comment: Comment,
short_js_comment: Comment,
) -> None:
assert str(short_comment) == short_comment.token.token
assert str(short_mysql_comment) == short_mysql_comment.token.token
assert str(short_js_comment) == f"-- {short_js_comment.body}"
assert str(nospace_comment) == str(short_comment)

assert len(short_comment) == 16
assert len(short_mysql_comment) == 15
assert len(short_js_comment) == 16
assert len(nospace_comment) == 16


def test_render_inline(
short_comment: Comment, nospace_comment: Comment, standalone_comment: Comment
short_comment: Comment,
nospace_comment: Comment,
short_js_comment: Comment,
) -> None:
expected = " -- short comment"
assert short_comment.render_inline() == expected
assert short_js_comment.render_inline() == expected
assert nospace_comment.render_inline() == expected


Expand Down
2 changes: 2 additions & 0 deletions tests/unit_tests/test_rule.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ def get_rule(ruleset: List[Rule], rule_name: str) -> Rule:
(CORE, "comment", "--no-space comment"),
(CORE, "comment", "# mysql-style # comments"),
(CORE, "comment", "#nospace"),
(CORE, "comment", "// why is this a comment??!"),
(CORE, "comment", "//whywhywhy??"),
(CORE, "comment_start", "/*"),
(CORE, "comment_end", "*/"),
(MAIN, "statement_start", "case"),
Expand Down

0 comments on commit deb8469

Please sign in to comment.