Merge pull request #2806 from jorgecarleitao/issue22826
Fixed #22826 -- Improved internal usage of Query.setup_joins.
This commit is contained in:
commit
dd57b89fcb
|
@ -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.
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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)]
|
||||||
|
|
Loading…
Reference in New Issue