Skip to content

Commit

Permalink
feat: add missing join query builder methods
Browse files Browse the repository at this point in the history
Added the following methods:

* left_outer_join
* right_outer_join
* full_outer_join
  • Loading branch information
lyz-code committed Jan 22, 2021
1 parent 566006b commit ea1588e
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 30 deletions.
3 changes: 3 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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) \
...
Expand Down
9 changes: 9 additions & 0 deletions pypika/queries.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
82 changes: 52 additions & 30 deletions pypika/tests/test_joins.py
Original file line number Diff line number Diff line change
Expand Up @@ -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("*")
Expand Down

0 comments on commit ea1588e

Please sign in to comment.