Skip to content
Browse files

Fixed the inconsistent ordering or where clauses by sorting by alias.

  • Loading branch information...
1 parent 372e09b commit 8f768c6ba764a402ff6e5ec48f0217705f224180 @coleifer committed
Showing with 49 additions and 54 deletions.
  1. +48 −54 peewee.py
  2. +1 −0 tests.py
View
102 peewee.py
@@ -650,64 +650,60 @@ def combine_field(self, alias, field_name):
return '%s.%s' % (alias, field_name)
return field_name
+ def follow_joins(self, current, alias_map, alias_required, alias_count, seen=None):
+ computed = []
+ seen = seen or set()
+
+ if current not in self._joins:
+ return computed
+
+ for i, (model, join_type, on) in enumerate(self._joins[current]):
+ seen.add(model)
+
+ if alias_required:
+ alias_count += 1
+ alias_map[model] = 't%d' % alias_count
+ else:
+ alias_map[model] = ''
+
+ from_model = current
+ field = from_model._meta.get_related_field_for_model(model, on)
+ if field:
+ left_field = field.name
+ right_field = model._meta.pk_name
+ else:
+ field = from_model._meta.get_reverse_related_field_for_model(model, on)
+ left_field = from_model._meta.pk_name
+ right_field = field.name
+
+ if join_type is None:
+ if field.null and model not in self._where:
+ join_type = 'LEFT OUTER'
+ else:
+ join_type = 'INNER'
+
+ computed.append(
+ '%s JOIN %s AS %s ON %s = %s' % (
+ join_type,
+ model._meta.db_table,
+ alias_map[model],
+ self.combine_field(alias_map[from_model], left_field),
+ self.combine_field(alias_map[model], right_field),
+ )
+ )
+
+ computed.extend(self.follow_joins(model, alias_map, alias_required, alias_count, seen))
+
+ return computed
+
def compile_where(self):
alias_count = 0
alias_map = {}
alias_required = self.use_aliases()
- #joins = list(self._joins)
- #if self._where or len(joins):
- # joins.insert(0, (self.model, None, None))
where_with_alias = []
where_data = []
- computed_joins = []
-
- def follow_joins(current, alias_map, alias_required, alias_count, seen=None):
- computed = []
- seen = seen or set()
-
- if current not in self._joins:
- return computed
-
- for i, (model, join_type, on) in enumerate(self._joins[current]):
- seen.add(model)
-
- if alias_required:
- alias_count += 1
- alias_map[model] = 't%d' % alias_count
- else:
- alias_map[model] = ''
-
- from_model = current
- field = from_model._meta.get_related_field_for_model(model, on)
- if field:
- left_field = field.name
- right_field = model._meta.pk_name
- else:
- field = from_model._meta.get_reverse_related_field_for_model(model, on)
- left_field = from_model._meta.pk_name
- right_field = field.name
-
- if join_type is None:
- if field.null and model not in self._where:
- join_type = 'LEFT OUTER'
- else:
- join_type = 'INNER'
-
- computed.append(
- '%s JOIN %s AS %s ON %s = %s' % (
- join_type,
- model._meta.db_table,
- alias_map[model],
- self.combine_field(alias_map[from_model], left_field),
- self.combine_field(alias_map[model], right_field),
- )
- )
-
- computed.extend(follow_joins(model, alias_map, alias_required, alias_count, seen))
-
- return computed
if alias_required:
alias_count += 1
@@ -715,11 +711,9 @@ def follow_joins(current, alias_map, alias_required, alias_count, seen=None):
else:
alias_map[self.model] = ''
- computed_joins = follow_joins(self.model, alias_map, alias_required, alias_count)
-
-
+ computed_joins = self.follow_joins(self.model, alias_map, alias_required, alias_count)
- for model in self._where:
+ for model in sorted(self._where, key=lambda m: alias_map[m]):
for node in self._where[model]:
query, data = self.parse_node(node, model, alias_map)
where_with_alias.append(query)
View
1 tests.py
@@ -263,6 +263,7 @@ def test_select_with_models(self):
def test_selecting_across_joins(self):
sq = SelectQuery(Entry, '*').where(title='a1').join(Blog).where(title='a')
+
self.assertEqual(sq._joins, {Entry: [(Blog, None, None)]})
self.assertSQLEqual(sq.sql(), ('SELECT t1.* FROM entry AS t1 INNER JOIN blog AS t2 ON t1.blog_id = t2.id WHERE t1.title = ? AND t2.title = ?', ['a1', 'a']))

0 comments on commit 8f768c6

Please sign in to comment.
Something went wrong with that request. Please try again.