diff --git a/CHANGELOG.md b/CHANGELOG.md index dbc7f80..3b09358 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ All notable changes to this project will be documented in this file. ### Formatting Changes and Bug Fixes -- sqlfmt no longer adds a space between the function name and parens for `filter()` and `isnull()` (but it also permits `filter ()` and `isnull ()` to support dialects where those are operators, not function names) ([#641](https://github.com/tconbeer/sqlfmt/issues/641) - thank you [@williamscs](https://github.com/williamscs) and [@hongtron](https://github.com/hongtron)!). +- sqlfmt no longer adds a space between the function name and parens for `filter()`, `isnull()`, and `rlike('foo', 'bar')` (but it also permits `filter ()`, `isnull ()`, and `rlike ('foo')` to support dialects where those are operators, not function names) ([#641](https://github.com/tconbeer/sqlfmt/issues/641), [#478](https://github.com/tconbeer/sqlfmt/issues/478) - thank you [@williamscs](https://github.com/williamscs), [@hongtron](https://github.com/hongtron), and [@chwiese](https://github.com/chwiese)!). - sqlfmt now supports Spark type-hinted numeric literals like `32y` and `+3.2e6bd` and will not introduce a space between the digits and their type suffix ([#640](https://github.com/tconbeer/sqlfmt/issues/640) - thank you [@ShaneMazur](https://github.com/ShaneMazur)!). - sqlfmt now supports Databricks query hint comments like `/*+ COALESCE(3) */` ([#639](https://github.com/tconbeer/sqlfmt/issues/639) - thank you [@wr-atlas](https://github.com/wr-atlas)!). diff --git a/src/sqlfmt/rules/__init__.py b/src/sqlfmt/rules/__init__.py index 23c6dea..9204240 100644 --- a/src/sqlfmt/rules/__init__.py +++ b/src/sqlfmt/rules/__init__.py @@ -55,6 +55,7 @@ pattern=group( r"filter", r"isnull", + r"(r|i)?like", ) + group(r"\("), action=partial( @@ -76,7 +77,7 @@ r"interval", r"is(\s+not)?(\s+distinct\s+from)?", r"isnull", - r"(not\s+)?i?like(\s+(any|all))?", + r"(not\s+)?(r|i)?like(\s+(any|all))?", r"over", r"(un)?pivot", r"notnull", diff --git a/tests/unit_tests/test_rule.py b/tests/unit_tests/test_rule.py index d69cd04..30c07d3 100644 --- a/tests/unit_tests/test_rule.py +++ b/tests/unit_tests/test_rule.py @@ -158,6 +158,8 @@ def get_rule(ruleset: List[Rule], rule_name: str) -> Rule: (MAIN, "word_operator", "not like"), (MAIN, "word_operator", "ilike"), (MAIN, "word_operator", "not ilike"), + (MAIN, "word_operator", "rlike"), + (MAIN, "word_operator", "not rlike"), (MAIN, "word_operator", "like any"), (MAIN, "word_operator", "not like any"), (MAIN, "word_operator", "like all"), @@ -429,13 +431,36 @@ def test_regex_anti_match( (MAIN, "frame_clause", "range 1 following", "range "), (MAIN, "frame_clause", "range current row", "range "), (MAIN, "frame_clause", "groups between 1 preceding", "groups "), - (MAIN, "functions_that_overlap_with_word_operators", "filter(foo)", "filter"), + ( + MAIN, + "functions_that_overlap_with_word_operators", + "filter(foo)", + "filter", + ), ( MAIN, "functions_that_overlap_with_word_operators", "isnull(bar, baz)", "isnull", ), + ( + MAIN, + "functions_that_overlap_with_word_operators", + "like('foo', 'bar')", + "like", + ), + ( + MAIN, + "functions_that_overlap_with_word_operators", + "rlike('foo', 'bar')", + "rlike", + ), + ( + MAIN, + "functions_that_overlap_with_word_operators", + "ilike('foo', 'bar')", + "ilike", + ), ], ) def test_regex_partial_match(