Skip to content

Commit cbdfaa3

Browse files
author
Daniel Townsend
committed
now performing joins for where clauses
1 parent 0c530eb commit cbdfaa3

File tree

4 files changed

+53
-26
lines changed

4 files changed

+53
-26
lines changed

piccolo/columns/base.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,31 @@ def __ne__(self, value) -> Where: # type: ignore
7575
def __hash__(self):
7676
return hash(self._name)
7777

78+
def get_full_name(self, just_alias=False) -> str:
79+
"""
80+
Returns the full column name, taking into account joins.
81+
"""
82+
column_name = self._name
83+
84+
if not self.call_chain:
85+
return f"{self.table.Meta.tablename}.{column_name}"
86+
87+
column_name = (
88+
"$".join([i._name for i in self.call_chain])
89+
+ f"${column_name}"
90+
)
91+
92+
alias = f"{self.call_chain[-1].table_alias}.{self._name}"
93+
if just_alias:
94+
return alias
95+
else:
96+
return f'{alias} AS "{column_name}"'
97+
7898
@property
7999
def querystring(self) -> QueryString:
100+
"""
101+
Used when creating tables.
102+
"""
80103
name = getattr(self, '_name', '')
81104
column_type = getattr(
82105
self,

piccolo/columns/combination.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ def querystring(self) -> QueryString:
7777

7878
# TODO Want something cleaner than this.
7979
template = self.operator.template.format(
80-
name=self.column._name,
80+
name=self.column.get_full_name(just_alias=True),
8181
value='{}',
8282
values='{}'
8383
)

piccolo/query/methods/select.py

Lines changed: 11 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -82,34 +82,21 @@ def querystring(self) -> QueryString:
8282
if len(self.selected_columns) == 0:
8383
columns_str = "*"
8484
else:
85-
###################################################################
86-
# JOIN
87-
88-
self.check_valid_call_chain(self.selected_columns)
89-
90-
joins = self.get_joins(self.selected_columns)
91-
92-
###################################################################
93-
94-
column_names: t.List[str] = []
95-
for column in self.selected_columns:
96-
column_name = column._name
85+
column_names: t.List[str] = [
86+
c.get_full_name() for c in self.selected_columns
87+
]
88+
columns_str = ", ".join(column_names)
9789

98-
if not column.call_chain:
99-
column_names.append(
100-
f"{self.table.Meta.tablename}.{column_name}"
101-
)
102-
continue
90+
#######################################################################
91+
# JOIN
10392

104-
column_name = (
105-
"$".join([i._name for i in column.call_chain])
106-
+ f"${column_name}"
107-
)
93+
self.check_valid_call_chain(self.selected_columns)
10894

109-
alias = f"{column.call_chain[-1].table_alias}.{column._name}"
110-
column_names.append(f'{alias} AS "{column_name}"')
95+
select_joins = self.get_joins(self.selected_columns)
96+
where_joins = self.get_joins(self.get_where_columns())
11197

112-
columns_str = ", ".join(column_names)
98+
# Combine all joins, and remove duplicates
99+
joins = list(OrderedDict.fromkeys(select_joins + where_joins))
113100

114101
#######################################################################
115102

piccolo/query/mixins.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import dataclasses
33
import typing as t
44

5-
from piccolo.columns import And, Column
5+
from piccolo.columns import And, Column, Where, Or
66
from piccolo.custom_types import Combinable
77
from piccolo.querystring import QueryString
88

@@ -56,6 +56,23 @@ class WhereMixin():
5656
def __init__(self):
5757
super().__init__()
5858
self._where: t.Optional[Combinable] = []
59+
self._where_columns: t.List[Column] = []
60+
61+
def get_where_columns(self):
62+
"""
63+
Retrieves all columns used in the where clause - in case joins are
64+
needed.
65+
"""
66+
self._where_columns = []
67+
self.extract_columns(self._where)
68+
return self._where_columns
69+
70+
def extract_columns(self, combinable: Combinable):
71+
if isinstance(combinable, Where):
72+
self._where_columns.append(combinable.column)
73+
elif isinstance(combinable, And) or isinstance(combinable, Or):
74+
self.extract_columns(combinable.first)
75+
self.extract_columns(combinable.second)
5976

6077
def where(self, where: Combinable):
6178
if self._where:

0 commit comments

Comments
 (0)