From 77cce99b1274fb34fef46c2555d374c9ed287811 Mon Sep 17 00:00:00 2001 From: Colin Le Nost <23076617+clenost@users.noreply.github.com> Date: Tue, 9 Jul 2024 18:25:27 +0200 Subject: [PATCH] feat(join-lint): handle left anti join (#607) --- CHANGELOG.md | 5 +++++ src/sqlfmt/rules/__init__.py | 5 ++++- tests/data/fast/unformatted/104_joins.sql | 6 ++++-- tests/data/unformatted/104_joins.sql | 6 ++++-- tests/unit_tests/test_rule.py | 2 ++ 5 files changed, 19 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3a025983..54b78a9a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,11 @@ All notable changes to this project will be documented in this file. ## [Unreleased] +### Formatting Changes and Bug Fixes + +- Databricks `left anti` & `right anti` joins are now supported. + + ## [0.21.3] - 2024-04-25 ### Bug Fixes diff --git a/src/sqlfmt/rules/__init__.py b/src/sqlfmt/rules/__init__.py index a714f02b..c98ff7c7 100644 --- a/src/sqlfmt/rules/__init__.py +++ b/src/sqlfmt/rules/__init__.py @@ -123,7 +123,10 @@ r"delete\s+from", r"from", r"((cross|positional|semi|anti)\s+)?join", - (r"((natural|asof)\s+)?" r"((inner|(left|right|full)(\s+outer)?)\s+)?join"), + ( + r"((natural|asof)\s+)?" + r"((inner|(left|right|full)(\s+(outer|anti))?)\s+)?join" + ), # this is the USING following DELETE, not the join operator # (see above) r"using", diff --git a/tests/data/fast/unformatted/104_joins.sql b/tests/data/fast/unformatted/104_joins.sql index 4e932035..ed226e26 100644 --- a/tests/data/fast/unformatted/104_joins.sql +++ b/tests/data/fast/unformatted/104_joins.sql @@ -1,5 +1,5 @@ select one.one, two.two, -three.three, four.four, five.five, six.six +three.three, four.four, five.five, six.six, seven.seven from one join two on one.two = two.one inner join "my_database"."my_schema".three as three on one.three = three.one @@ -12,9 +12,10 @@ right join ( from my_table where some_filter is true ) as five using(five.id) natural full outer join six +left anti join seven on one.seven = seven.one cross join {{ ref('bar_bar_bar') }} as bar )))))__SQLFMT_OUTPUT__((((( -select one.one, two.two, three.three, four.four, five.five, six.six +select one.one, two.two, three.three, four.four, five.five, six.six, seven.seven from one join two on one.two = two.one inner join "my_database"."my_schema".three as three on one.three = three.one @@ -29,4 +30,5 @@ right join select id, five, six, seven, eight, nine from my_table where some_filter is true ) as five using (five.id) natural full outer join six +left anti join seven on one.seven = seven.one cross join {{ ref("bar_bar_bar") }} as bar diff --git a/tests/data/unformatted/104_joins.sql b/tests/data/unformatted/104_joins.sql index 4e932035..ed226e26 100644 --- a/tests/data/unformatted/104_joins.sql +++ b/tests/data/unformatted/104_joins.sql @@ -1,5 +1,5 @@ select one.one, two.two, -three.three, four.four, five.five, six.six +three.three, four.four, five.five, six.six, seven.seven from one join two on one.two = two.one inner join "my_database"."my_schema".three as three on one.three = three.one @@ -12,9 +12,10 @@ right join ( from my_table where some_filter is true ) as five using(five.id) natural full outer join six +left anti join seven on one.seven = seven.one cross join {{ ref('bar_bar_bar') }} as bar )))))__SQLFMT_OUTPUT__((((( -select one.one, two.two, three.three, four.four, five.five, six.six +select one.one, two.two, three.three, four.four, five.five, six.six, seven.seven from one join two on one.two = two.one inner join "my_database"."my_schema".three as three on one.three = three.one @@ -29,4 +30,5 @@ right join select id, five, six, seven, eight, nine from my_table where some_filter is true ) as five using (five.id) natural full outer join six +left anti join seven on one.seven = seven.one cross join {{ ref("bar_bar_bar") }} as bar diff --git a/tests/unit_tests/test_rule.py b/tests/unit_tests/test_rule.py index 6610239d..ae1dfbff 100644 --- a/tests/unit_tests/test_rule.py +++ b/tests/unit_tests/test_rule.py @@ -182,6 +182,8 @@ def get_rule(ruleset: List[Rule], rule_name: str) -> Rule: (MAIN, "unterm_keyword", "asof left join"), (MAIN, "unterm_keyword", "asof right\n outer\n join"), (MAIN, "unterm_keyword", "semi join"), + (MAIN, "unterm_keyword", "left anti join"), + (MAIN, "unterm_keyword", "right anti join"), (MAIN, "unterm_keyword", "anti join"), (MAIN, "unterm_keyword", "join"), (MAIN, "unterm_keyword", "values"),