From ea1588e544b476059d22f106fec1e50670230499 Mon Sep 17 00:00:00 2001 From: Lyz Date: Fri, 22 Jan 2021 13:27:48 +0100 Subject: [PATCH] feat: add missing join query builder methods Added the following methods: * left_outer_join * right_outer_join * full_outer_join --- README.rst | 3 ++ pypika/queries.py | 9 +++++ pypika/tests/test_joins.py | 82 ++++++++++++++++++++++++-------------- 3 files changed, 64 insertions(+), 30 deletions(-) diff --git a/README.rst b/README.rst index d0cbd90c..6d7a4aae 100644 --- a/README.rst +++ b/README.rst @@ -408,9 +408,12 @@ All join types are supported by |Brand|. .from_(base_table) ... .left_join(join_table) \ + .left_outer_join(join_table) \ .right_join(join_table) \ + .right_outer_join(join_table) \ .inner_join(join_table) \ .outer_join(join_table) \ + .full_outer_join(join_table) \ .cross_join(join_table) \ .hash_join(join_table) \ ... diff --git a/pypika/queries.py b/pypika/queries.py index 9abd6242..ec8db2ef 100644 --- a/pypika/queries.py +++ b/pypika/queries.py @@ -987,12 +987,21 @@ def inner_join(self, item: Union[Table, "QueryBuilder", AliasedQuery]) -> "Joine def left_join(self, item: Union[Table, "QueryBuilder", AliasedQuery]) -> "Joiner": return self.join(item, JoinType.left) + def left_outer_join(self, item: Union[Table, "QueryBuilder", AliasedQuery]) -> "Joiner": + return self.join(item, JoinType.left_outer) + def right_join(self, item: Union[Table, "QueryBuilder", AliasedQuery]) -> "Joiner": return self.join(item, JoinType.right) + def right_outer_join(self, item: Union[Table, "QueryBuilder", AliasedQuery]) -> "Joiner": + return self.join(item, JoinType.right_outer) + def outer_join(self, item: Union[Table, "QueryBuilder", AliasedQuery]) -> "Joiner": return self.join(item, JoinType.outer) + def full_outer_join(self, item: Union[Table, "QueryBuilder", AliasedQuery]) -> "Joiner": + return self.join(item, JoinType.full_outer) + def cross_join(self, item: Union[Table, "QueryBuilder", AliasedQuery]) -> "Joiner": return self.join(item, JoinType.cross) diff --git a/pypika/tests/test_joins.py b/pypika/tests/test_joins.py index 1d3bbdc5..6e54f883 100644 --- a/pypika/tests/test_joins.py +++ b/pypika/tests/test_joins.py @@ -128,43 +128,65 @@ def test_cross_join(self): self.assertEqual(expected, str(query)) def test_left_outer_join(self): - q = ( - Query.from_(self.table0) - .join(self.table1, how=JoinType.left_outer) - .on(self.table0.foo == self.table1.bar) - .select("*") - ) + expected = 'SELECT * FROM "abc" LEFT OUTER JOIN "efg" ON "abc"."foo"="efg"."bar"' + with self.subTest("join with enum"): + query = ( + Query.from_(self.table0) + .join(self.table1, how=JoinType.left_outer) + .on(self.table0.foo == self.table1.bar) + .select("*") + ) - self.assertEqual( - 'SELECT * FROM "abc" LEFT OUTER JOIN "efg" ON "abc"."foo"="efg"."bar"', - str(q), - ) + self.assertEqual(expected, str(query)) + + with self.subTest("join function"): + query = ( + Query.from_(self.table0).left_outer_join(self.table1).on(self.table0.foo == self.table1.bar).select("*") + ) + + self.assertEqual(expected, str(query)) def test_right_outer_join(self): - q = ( - Query.from_(self.table0) - .join(self.table1, how=JoinType.right_outer) - .on(self.table0.foo == self.table1.bar) - .select("*") - ) + expected = 'SELECT * FROM "abc" RIGHT OUTER JOIN "efg" ON "abc"."foo"="efg"."bar"' + with self.subTest("join with enum"): + query = ( + Query.from_(self.table0) + .join(self.table1, how=JoinType.right_outer) + .on(self.table0.foo == self.table1.bar) + .select("*") + ) - self.assertEqual( - 'SELECT * FROM "abc" RIGHT OUTER JOIN "efg" ON "abc"."foo"="efg"."bar"', - str(q), - ) + self.assertEqual(expected, str(query)) + + with self.subTest("join function"): + query = ( + Query.from_(self.table0) + .right_outer_join(self.table1) + .on(self.table0.foo == self.table1.bar) + .select("*") + ) + + self.assertEqual(expected, str(query)) def test_full_outer_join(self): - q = ( - Query.from_(self.table0) - .join(self.table1, how=JoinType.full_outer) - .on(self.table0.foo == self.table1.bar) - .select("*") - ) + expected = 'SELECT * FROM "abc" FULL OUTER JOIN "efg" ON "abc"."foo"="efg"."bar"' - self.assertEqual( - 'SELECT * FROM "abc" FULL OUTER JOIN "efg" ON "abc"."foo"="efg"."bar"', - str(q), - ) + with self.subTest("join with enum"): + query = ( + Query.from_(self.table0) + .join(self.table1, how=JoinType.full_outer) + .on(self.table0.foo == self.table1.bar) + .select("*") + ) + + self.assertEqual(expected, str(query)) + + with self.subTest("join function"): + query = ( + Query.from_(self.table0).full_outer_join(self.table1).on(self.table0.foo == self.table1.bar).select("*") + ) + + self.assertEqual(expected, str(query)) def test_join_on_field_single(self): query = Query.from_(self.table0).join(self.table1).on_field("foo").select("*")