From ba0af84c75e60828e282a94595fc1e0e7e8f1202 Mon Sep 17 00:00:00 2001 From: Ted Conbeer Date: Fri, 22 Nov 2024 10:56:32 -0700 Subject: [PATCH 1/2] fix: allow filter() and isnull() with no space --- src/sqlfmt/rules/__init__.py | 18 ++++++++++++++++++ tests/unit_tests/test_rule.py | 2 ++ 2 files changed, 20 insertions(+) diff --git a/src/sqlfmt/rules/__init__.py b/src/sqlfmt/rules/__init__.py index 490808c..b0adfb8 100644 --- a/src/sqlfmt/rules/__init__.py +++ b/src/sqlfmt/rules/__init__.py @@ -44,6 +44,24 @@ ), ), ), + Rule( + # There are some function names in some dialects that are the same as + # word operators in other dialects. Here we lex those as function + # names IFF the name is immediately followed by a `(` (with no space + # after the name. Otherwise they are lexed as word_operators by the + # next rule. + name="functions_that_overlap_with_word_operators", + priority=1099, + pattern=group( + r"filter", + r"isnull", + ) + + group(r"\("), + action=partial( + actions.handle_reserved_keyword, + action=partial(actions.add_node_to_buffer, token_type=TokenType.NAME), + ), + ), Rule( name="word_operator", priority=1100, diff --git a/tests/unit_tests/test_rule.py b/tests/unit_tests/test_rule.py index cd03258..d684a2a 100644 --- a/tests/unit_tests/test_rule.py +++ b/tests/unit_tests/test_rule.py @@ -419,6 +419,8 @@ 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", "isnull(bar, baz)", "isnull"), ], ) def test_regex_partial_match( From be9be0599346b17885b7e2d824c03fc86dfc2a62 Mon Sep 17 00:00:00 2001 From: Ted Conbeer Date: Fri, 22 Nov 2024 10:58:59 -0700 Subject: [PATCH 2/2] fix: format --- src/sqlfmt/rules/__init__.py | 2 +- tests/unit_tests/test_rule.py | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/sqlfmt/rules/__init__.py b/src/sqlfmt/rules/__init__.py index b0adfb8..23c6dea 100644 --- a/src/sqlfmt/rules/__init__.py +++ b/src/sqlfmt/rules/__init__.py @@ -48,7 +48,7 @@ # There are some function names in some dialects that are the same as # word operators in other dialects. Here we lex those as function # names IFF the name is immediately followed by a `(` (with no space - # after the name. Otherwise they are lexed as word_operators by the + # after the name. Otherwise they are lexed as word_operators by the # next rule. name="functions_that_overlap_with_word_operators", priority=1099, diff --git a/tests/unit_tests/test_rule.py b/tests/unit_tests/test_rule.py index d684a2a..3af0ae3 100644 --- a/tests/unit_tests/test_rule.py +++ b/tests/unit_tests/test_rule.py @@ -420,7 +420,12 @@ def test_regex_anti_match( (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", "isnull(bar, baz)", "isnull"), + ( + MAIN, + "functions_that_overlap_with_word_operators", + "isnull(bar, baz)", + "isnull", + ), ], ) def test_regex_partial_match(