Merge pull request #2806 from jorgecarleitao/issue22826

Fixed #22826 -- Improved internal usage of Query.setup_joins.
This commit is contained in:
Marc Tamlyn 2014-06-15 10:16:33 +01:00
commit dd57b89fcb
4 changed files with 18 additions and 20 deletions

View File

@ -96,7 +96,7 @@ class SQLCompiler(object):
# However we do not want to get rid of stuff done in pre_sql_setup(), # However we do not want to get rid of stuff done in pre_sql_setup(),
# as the pre_sql_setup will modify query state in a way that forbids # as the pre_sql_setup will modify query state in a way that forbids
# another run of it. # another run of it.
self.refcounts_before = self.query.alias_refcount.copy() refcounts_before = self.query.alias_refcount.copy()
out_cols, s_params = self.get_columns(with_col_aliases) out_cols, s_params = self.get_columns(with_col_aliases)
ordering, o_params, ordering_group_by = self.get_ordering() ordering, o_params, ordering_group_by = self.get_ordering()
@ -169,7 +169,7 @@ class SQLCompiler(object):
result.append(self.connection.ops.for_update_sql(nowait=nowait)) result.append(self.connection.ops.for_update_sql(nowait=nowait))
# Finally do cleanup - get rid of the joins we created above. # Finally do cleanup - get rid of the joins we created above.
self.query.reset_refcounts(self.refcounts_before) self.query.reset_refcounts(refcounts_before)
return ' '.join(result), tuple(params) return ' '.join(result), tuple(params)
@ -546,7 +546,7 @@ class SQLCompiler(object):
result.append('%s%s%s' % (connector, qn(name), alias_str)) result.append('%s%s%s' % (connector, qn(name), alias_str))
first = False first = False
for t in self.query.extra_tables: for t in self.query.extra_tables:
alias, unused = self.query.table_alias(t) alias, _ = self.query.table_alias(t)
# Only add the alias if it's not already present (the table_alias() # Only add the alias if it's not already present (the table_alias()
# calls increments the refcount, so an alias refcount of one means # calls increments the refcount, so an alias refcount of one means
# this is the only reference. # this is the only reference.

View File

@ -57,9 +57,9 @@ class SQLEvaluator(object):
self.cols.append((node, query.aggregate_select[node.name])) self.cols.append((node, query.aggregate_select[node.name]))
else: else:
try: try:
field, sources, opts, join_list, path = query.setup_joins( _, sources, _, join_list, path = query.setup_joins(
field_list, query.get_meta(), field_list, query.get_meta(), query.get_initial_alias(),
query.get_initial_alias(), self.reuse) can_reuse=self.reuse)
self._used_joins = join_list self._used_joins = join_list
targets, _, join_list = query.trim_joins(sources, join_list, path) targets, _, join_list = query.trim_joins(sources, join_list, path)
if self.reuse is not None: if self.reuse is not None:

View File

@ -664,16 +664,16 @@ class Query(object):
If 'create' is true, a new alias is always created. Otherwise, the If 'create' is true, a new alias is always created. Otherwise, the
most recently created alias for the table (if one exists) is reused. most recently created alias for the table (if one exists) is reused.
""" """
current = self.table_map.get(table_name) alias_list = self.table_map.get(table_name)
if not create and current: if not create and alias_list:
alias = current[0] alias = alias_list[0]
self.alias_refcount[alias] += 1 self.alias_refcount[alias] += 1
return alias, False return alias, False
# Create a new alias for this table. # Create a new alias for this table.
if current: if alias_list:
alias = '%s%d' % (self.alias_prefix, len(self.alias_map) + 1) alias = '%s%d' % (self.alias_prefix, len(self.alias_map) + 1)
current.append(alias) alias_list.append(alias)
else: else:
# The first occurrence of a table uses the table name directly. # The first occurrence of a table uses the table name directly.
alias = table_name alias = table_name
@ -900,7 +900,7 @@ class Query(object):
return alias return alias
# No reuse is possible, so we need a new alias. # No reuse is possible, so we need a new alias.
alias, _ = self.table_alias(table, True) alias, _ = self.table_alias(table, create=True)
if not lhs: if not lhs:
# Not all tables need to be joined to anything. No join type # Not all tables need to be joined to anything. No join type
# means the later columns are ignored. # means the later columns are ignored.
@ -1008,7 +1008,7 @@ class Query(object):
# Join promotion note - we must not remove any rows here, so use # Join promotion note - we must not remove any rows here, so use
# outer join if there isn't any existing join. # outer join if there isn't any existing join.
field, sources, opts, join_list, path = self.setup_joins( _, sources, opts, join_list, path = self.setup_joins(
field_list, opts, self.get_initial_alias()) field_list, opts, self.get_initial_alias())
# Process the join chain to see if it can be trimmed # Process the join chain to see if it can be trimmed
@ -1158,7 +1158,7 @@ class Query(object):
try: try:
field, sources, opts, join_list, path = self.setup_joins( field, sources, opts, join_list, path = self.setup_joins(
parts, opts, alias, can_reuse, allow_many) parts, opts, alias, can_reuse=can_reuse, allow_many=allow_many)
# split_exclude() needs to know which joins were generated for the # split_exclude() needs to know which joins were generated for the
# lookup parts # lookup parts
self._lookup_joins = join_list self._lookup_joins = join_list
@ -1605,9 +1605,8 @@ class Query(object):
for name in field_names: for name in field_names:
# Join promotion note - we must not remove any rows here, so # Join promotion note - we must not remove any rows here, so
# if there is no existing joins, use outer join. # if there is no existing joins, use outer join.
field, targets, u2, joins, path = self.setup_joins( _, targets, _, joins, path = self.setup_joins(
name.split(LOOKUP_SEP), opts, alias, can_reuse=None, name.split(LOOKUP_SEP), opts, alias, allow_many=allow_m2m)
allow_many=allow_m2m)
targets, final_alias, joins = self.trim_joins(targets, joins, path) targets, final_alias, joins = self.trim_joins(targets, joins, path)
for target in targets: for target in targets:
self.select.append(SelectInfo((final_alias, target.column), target)) self.select.append(SelectInfo((final_alias, target.column), target))

View File

@ -215,7 +215,7 @@ class DateQuery(Query):
Converts the query into an extraction query. Converts the query into an extraction query.
""" """
try: try:
result = self.setup_joins( field, _, _, joins, _ = self.setup_joins(
field_name.split(LOOKUP_SEP), field_name.split(LOOKUP_SEP),
self.get_meta(), self.get_meta(),
self.get_initial_alias(), self.get_initial_alias(),
@ -224,9 +224,8 @@ class DateQuery(Query):
raise FieldDoesNotExist("%s has no field named '%s'" % ( raise FieldDoesNotExist("%s has no field named '%s'" % (
self.get_meta().object_name, field_name self.get_meta().object_name, field_name
)) ))
field = result[0]
self._check_field(field) # overridden in DateTimeQuery self._check_field(field) # overridden in DateTimeQuery
alias = result[3][-1] alias = joins[-1]
select = self._get_select((alias, field.column), lookup_type) select = self._get_select((alias, field.column), lookup_type)
self.clear_select_clause() self.clear_select_clause()
self.select = [SelectInfo(select, None)] self.select = [SelectInfo(select, None)]