diff options
| author | Malcolm Tredinnick <malcolm.tredinnick@gmail.com> | 2007-10-14 02:14:53 +0000 |
|---|---|---|
| committer | Malcolm Tredinnick <malcolm.tredinnick@gmail.com> | 2007-10-14 02:14:53 +0000 |
| commit | 142e400c5cbff91ba70d3636a4429a48131a2edd (patch) | |
| tree | 2a4c2618324e70519b90c1309981e3bc7e711291 /django | |
| parent | 8926b431eda3a7b031e10beb6963bf2d26e4039b (diff) | |
queryset-refactor: Create a new join when merging two QuerySets that use a 1-m
field.
git-svn-id: http://code.djangoproject.com/svn/django/branches/queryset-refactor@6492 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'django')
| -rw-r--r-- | django/db/models/sql/query.py | 26 |
1 files changed, 19 insertions, 7 deletions
diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py index c9ae75a414..505f7124db 100644 --- a/django/db/models/sql/query.py +++ b/django/db/models/sql/query.py @@ -48,6 +48,7 @@ RHS_JOIN_COL = 5 ALIAS_TABLE = 0 ALIAS_REFCOUNT = 1 ALIAS_JOIN = 2 +ALIAS_MERGE_SEP = 3 # How many results to expect from a cursor.execute call MULTI = 'multi' @@ -252,8 +253,10 @@ class Query(object): continue promote = (rhs.alias_map[alias][ALIAS_JOIN][JOIN_TYPE] == self.LOUTER) + merge_separate = (connection == AND) new_alias = self.join(rhs.rev_join_map[alias], exclusions=used, - promote=promote, outer_if_first=True) + promote=promote, outer_if_first=True, + merge_separate=merge_separate) if self.alias_map[alias][ALIAS_REFCOUNT] == 1: first_new_join = False used[new_alias] = None @@ -417,7 +420,7 @@ class Query(object): alias = table_name else: alias = '%s%d' % (self.alias_prefix, len(self.alias_map) + 1) - self.alias_map[alias] = [table_name, 1, None] + self.alias_map[alias] = [table_name, 1, None, False] self.table_map.setdefault(table_name, []).append(alias) self.tables.append(alias) return alias, True @@ -435,7 +438,8 @@ class Query(object): self.alias_map[alias][ALIAS_JOIN][JOIN_TYPE] = self.LOUTER def join(self, (lhs, table, lhs_col, col), always_create=False, - exclusions=(), promote=False, outer_if_first=False): + exclusions=(), promote=False, outer_if_first=False, + merge_separate=False): """ Returns an alias for a join between 'table' and 'lhs' on the given columns, either reusing an existing alias for that join or creating a @@ -456,6 +460,10 @@ class Query(object): If 'outer_if_first' is True and a new join is created, it will have the LOUTER join type. This is used when joining certain types of querysets and Q-objects together. + + If the 'merge_separate' parameter is True, we create a new alias if we + would otherwise reuse an alias that also had 'merge_separate' set to + True when it was created. """ if lhs not in self.alias_map: lhs_table = lhs @@ -467,7 +475,9 @@ class Query(object): aliases = self.join_map.get(t_ident) if aliases and not always_create: for alias in aliases: - if alias not in exclusions: + if (alias not in exclusions and + not (merge_separate and + self.alias_map[alias][ALIAS_MERGE_SEP])): self.ref_alias(alias) if promote: self.alias_map[alias][ALIAS_JOIN][JOIN_TYPE] = \ @@ -487,6 +497,7 @@ class Query(object): # means the later columns are ignored. join[JOIN_TYPE] = None self.alias_map[alias][ALIAS_JOIN] = join + self.alias_map[alias][ALIAS_MERGE_SEP] = merge_separate self.join_map.setdefault(t_ident, []).append(alias) self.rev_join_map[alias] = t_ident return alias @@ -647,7 +658,7 @@ class Query(object): opts.pk.column, field.m2m_column_name()), dupe_multis) far_alias = self.join((int_alias, remote_opts.db_table, field.m2m_reverse_name(), remote_opts.pk.column), - dupe_multis) + dupe_multis, merge_separate=True) return ([int_alias, far_alias], remote_opts, field, remote_opts.pk, None) @@ -661,7 +672,7 @@ class Query(object): opts.pk.column, field.m2m_reverse_name()), dupe_multis) far_alias = self.join((int_alias, remote_opts.db_table, field.m2m_column_name(), remote_opts.pk.column), - dupe_multis) + dupe_multis, merge_separate=True) # XXX: Why is the final component able to be None here? return ([int_alias, far_alias], remote_opts, field, remote_opts.pk, None) @@ -673,7 +684,8 @@ class Query(object): field = field.field local_field = opts.get_field(field.rel.field_name) alias = self.join((root_alias, remote_opts.db_table, - local_field.column, field.column), dupe_multis) + local_field.column, field.column), dupe_multis, + merge_separate=True) return ([alias], remote_opts, field, field, remote_opts.pk.column) |
