Permalink
Browse files

Removed relabel_aliases() from ORM

Instead aliases are tracked by alias_id which can be mapped back to
the real alias.

This also fixed #19964
  • Loading branch information...
1 parent 7e26f4c commit 22c6136adb7eec3cca366511d3b4d29ff7509282 @akaariai committed Mar 12, 2013
@@ -344,9 +344,8 @@ def get_db_prep_lookup(self, lookup_type, value, connection,
if hasattr(value, 'get_compiler'):
value = value.get_compiler(connection=connection)
if hasattr(value, 'as_sql') or hasattr(value, '_as_sql'):
- # If the value has a relabel_aliases method, it will need to
- # be invoked before the final SQL is evaluated
- if hasattr(value, 'relabel_aliases'):
+ # Why this is needed?
+ if hasattr(value, 'evaluate_node'):
return value
if hasattr(value, 'as_sql'):
sql, params = value.as_sql()
@@ -153,9 +153,7 @@ def get_db_prep_lookup(self, lookup_type, value, connection, prepared=False):
if hasattr(value, 'get_compiler'):
value = value.get_compiler(connection=connection)
if hasattr(value, 'as_sql') or hasattr(value, '_as_sql'):
- # If the value has a relabel_aliases method, it will need to
- # be invoked before the final SQL is evaluated
- if hasattr(value, 'relabel_aliases'):
+ if hasattr(value, 'evaluate_leaf'):
return value
if hasattr(value, 'as_sql'):
sql, params = value.as_sql()
@@ -1,8 +1,6 @@
"""
Classes to represent the default SQL aggregate functions
"""
-import copy
-
from django.db.models.fields import IntegerField, FloatField
# Fake fields used to identify aggregate types in data-conversion operations.
@@ -63,15 +61,6 @@ def __init__(self, col, source=None, is_summary=False, **extra):
self.field = tmp
- def clone(self):
- # Different aggregates have different init methods, so use copy here
- # deepcopy is not needed, as self.col is only changing variable.
- return copy.copy(self)
-
- def relabel_aliases(self, change_map):
- if isinstance(self.col, (list, tuple)):
- self.col = (change_map.get(self.col[0], self.col[0]), self.col[1])
-
def as_sql(self, qn, connection):
"Return the aggregate, rendered as SQL with parameters."
params = []
@@ -2,7 +2,6 @@
from django.conf import settings
from django.core.exceptions import FieldError
-from django.db import transaction
from django.db.backends.util import truncate_name
from django.db.models.constants import LOOKUP_SEP
from django.db.models.query_utils import select_related_descend
@@ -46,6 +45,8 @@ def quote_name_unless_alias(self, name):
for table names. This avoids problems with some SQL dialects that treat
quoted strings specially (e.g. PostgreSQL).
"""
+ if isinstance(name, int):
+ name = self.query.alias_redirects[name]
if name in self.quote_cache:
return self.quote_cache[name]
if ((name in self.query.alias_map and name not in self.query.table_map) or
@@ -187,11 +188,12 @@ def get_columns(self, with_aliases=False):
only_load = self.deferred_to_columns()
for col, _ in self.query.select:
if isinstance(col, (list, tuple)):
- alias, column = col
+ alias_id, column = col
+ alias = self.query.alias_redirects[alias_id]
table = self.query.alias_map[alias].table_name
if table in only_load and column not in only_load[table]:
continue
- r = '%s.%s' % (qn(alias), qn(column))
+ r = '%s.%s' % (qn(alias_id), qn(column))
if with_aliases:
if col[1] in col_aliases:
c_alias = 'Col%d' % len(col_aliases)
@@ -266,7 +268,7 @@ def get_default_columns(self, with_aliases=False, col_aliases=None,
aliases = set()
only_load = self.deferred_to_columns()
if not start_alias:
- start_alias = self.query.get_initial_alias()
+ start_alias, _ = self.query.get_initial_alias()
# The 'seen_models' is used to optimize checking the needed parent
# alias for a given field. This also includes None -> start_alias to
# be used by local fields.
@@ -444,7 +446,7 @@ def _setup_joins(self, pieces, opts, alias):
must match. Executing SQL where this is not true is an error.
"""
if not alias:
- alias = self.query.get_initial_alias()
+ alias, _ = self.query.get_initial_alias()
field, target, opts, joins, _ = self.query.setup_joins(
pieces, opts, alias)
# We will later on need to promote those joins that were added to the
@@ -503,7 +505,7 @@ def get_from_clause(self):
if not self.query.alias_refcount[alias]:
continue
try:
- name, alias, join_type, lhs, lhs_col, col, _, join_field = self.query.alias_map[alias]
+ name, alias, join_type, lhs, lhs_col, col, _, join_field, _ = self.query.alias_map[alias]
except KeyError:
# Extra tables can end up in self.tables, but not in the
# alias_map if they aren't in a join. That's OK. We skip them.
@@ -524,7 +526,7 @@ def get_from_clause(self):
result.append('%s%s%s' % (connector, qn(name), alias_str))
first = False
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()
# calls increments the refcount, so an alias refcount of one means
# this is the only reference.
@@ -598,7 +600,7 @@ def fill_related_selections(self, opts=None, root_alias=None, cur_depth=1,
if not opts:
opts = self.query.get_meta()
- root_alias = self.query.get_initial_alias()
+ root_alias, _ = self.query.get_initial_alias()
self.query.related_select_cols = []
only_load = self.query.get_loaded_field_names()
@@ -25,7 +25,7 @@
# dictionary in the Query class).
JoinInfo = namedtuple('JoinInfo',
'table_name rhs_alias join_type lhs_alias '
- 'lhs_join_col rhs_join_col nullable join_field')
+ 'lhs_join_col rhs_join_col nullable join_field alias_id')
# Pairs of column clauses to select, and (possibly None) field for the clause.
SelectInfo = namedtuple('SelectInfo', 'col field')
@@ -32,11 +32,6 @@ def __init__(self, col, lookup_type):
self.col = col
self.lookup_type = lookup_type
- def relabel_aliases(self, change_map):
- c = self.col
- if isinstance(c, (list, tuple)):
- self.col = (change_map.get(c[0], c[0]), c[1])
-
def as_sql(self, qn, connection):
if isinstance(self.col, (list, tuple)):
col = '%s.%s' % tuple([qn(c) for c in self.col])
@@ -53,11 +48,6 @@ def __init__(self, col, lookup_type, tzname):
self.lookup_type = lookup_type
self.tzname = tzname
- def relabel_aliases(self, change_map):
- c = self.col
- if isinstance(c, (list, tuple)):
- self.col = (change_map.get(c[0], c[0]), c[1])
-
def as_sql(self, qn, connection):
if isinstance(self.col, (list, tuple)):
col = '%s.%s' % tuple([qn(c) for c in self.col])
@@ -18,17 +18,6 @@ def prepare(self):
def as_sql(self, qn, connection):
return self.expression.evaluate(self, qn, connection)
- def relabel_aliases(self, change_map):
- new_cols = []
- for node, col in self.cols:
- if hasattr(col, "relabel_aliases"):
- col.relabel_aliases(change_map)
- new_cols.append((node, col))
- else:
- new_cols.append((node,
- (change_map.get(col[0], col[0]), col[1])))
- self.cols = new_cols
-
#####################################################
# Vistor methods for initial expression preparation #
#####################################################
@@ -51,11 +40,11 @@ def prepare_leaf(self, node, query, allow_joins):
try:
field, source, opts, join_list, path = query.setup_joins(
field_list, query.get_meta(),
- query.get_initial_alias(), self.reuse)
+ query.get_initial_alias()[0], self.reuse)
target, _, join_list = query.trim_joins(source, join_list, path)
if self.reuse is not None:
self.reuse.update(join_list)
- self.cols.append((node, (join_list[-1], target.column)))
+ self.cols.append((node, (query.alias_map[join_list[-1]].alias_id, target.column)))
except FieldDoesNotExist:
raise FieldError("Cannot resolve keyword %r into field. "
"Choices are: %s" % (self.name,
Oops, something went wrong.

0 comments on commit 22c6136

Please sign in to comment.