diff --git a/django/db/models/sql/aggregates.py b/django/db/models/sql/aggregates.py
index 207bc0c..7328660 100644
|
a
|
b
|
|
| 1 | 1 | """ |
| 2 | 2 | Classes to represent the default SQL aggregate functions |
| 3 | 3 | """ |
| | 4 | import copy |
| 4 | 5 | |
| 5 | 6 | class AggregateField(object): |
| 6 | 7 | """An internal field mockup used to identify aggregates in the |
| … |
… |
class Aggregate(object):
|
| 69 | 70 | |
| 70 | 71 | self.field = tmp |
| 71 | 72 | |
| | 73 | def clone(self): |
| | 74 | # Different aggregates have different init methods, so use copy here |
| | 75 | # deepcopy is not needed, as self.col is only changing variable. |
| | 76 | return copy.copy(self) |
| | 77 | |
| 72 | 78 | def relabel_aliases(self, change_map): |
| 73 | 79 | if isinstance(self.col, (list, tuple)): |
| 74 | 80 | self.col = (change_map.get(self.col[0], self.col[0]), self.col[1]) |
diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py
index ed2bc06..b669673 100644
|
a
|
b
|
class Query(object):
|
| 256 | 256 | obj.dupe_avoidance = self.dupe_avoidance.copy() |
| 257 | 257 | obj.select = self.select[:] |
| 258 | 258 | obj.tables = self.tables[:] |
| 259 | | obj.where = copy.deepcopy(self.where, memo=memo) |
| | 259 | obj.where = self.where.clone() |
| 260 | 260 | obj.where_class = self.where_class |
| 261 | 261 | if self.group_by is None: |
| 262 | 262 | obj.group_by = None |
| 263 | 263 | else: |
| 264 | 264 | obj.group_by = self.group_by[:] |
| 265 | | obj.having = copy.deepcopy(self.having, memo=memo) |
| | 265 | obj.having = self.having.clone() |
| 266 | 266 | obj.order_by = self.order_by[:] |
| 267 | 267 | obj.low_mark, obj.high_mark = self.low_mark, self.high_mark |
| 268 | 268 | obj.distinct = self.distinct |
| … |
… |
class Query(object):
|
| 271 | 271 | obj.select_for_update_nowait = self.select_for_update_nowait |
| 272 | 272 | obj.select_related = self.select_related |
| 273 | 273 | obj.related_select_cols = [] |
| 274 | | obj.aggregates = copy.deepcopy(self.aggregates, memo=memo) |
| | 274 | obj.aggregates = SortedDict((k, v.clone()) |
| | 275 | for k, v in self.aggregates.items()) |
| 275 | 276 | if self.aggregate_select_mask is None: |
| 276 | 277 | obj.aggregate_select_mask = None |
| 277 | 278 | else: |
| … |
… |
class Query(object):
|
| 294 | 295 | obj._extra_select_cache = self._extra_select_cache.copy() |
| 295 | 296 | obj.extra_tables = self.extra_tables |
| 296 | 297 | obj.extra_order_by = self.extra_order_by |
| 297 | | obj.deferred_loading = copy.deepcopy(self.deferred_loading, memo=memo) |
| | 298 | obj.deferred_loading = copy.copy(self.deferred_loading[0]), self.deferred_loading[1] |
| 298 | 299 | if self.filter_is_sticky and self.used_aliases: |
| 299 | 300 | obj.used_aliases = self.used_aliases.copy() |
| 300 | 301 | else: |
| … |
… |
class Query(object):
|
| 508 | 509 | # Now relabel a copy of the rhs where-clause and add it to the current |
| 509 | 510 | # one. |
| 510 | 511 | if rhs.where: |
| 511 | | w = copy.deepcopy(rhs.where) |
| | 512 | w = rhs.where.clone() |
| 512 | 513 | w.relabel_aliases(change_map) |
| 513 | 514 | if not self.where: |
| 514 | 515 | # Since 'self' matches everything, add an explicit "include |
| … |
… |
class Query(object):
|
| 529 | 530 | if isinstance(col, (list, tuple)): |
| 530 | 531 | self.select.append((change_map.get(col[0], col[0]), col[1])) |
| 531 | 532 | else: |
| 532 | | item = copy.deepcopy(col) |
| | 533 | item = col.clone() |
| 533 | 534 | item.relabel_aliases(change_map) |
| 534 | 535 | self.select.append(item) |
| 535 | 536 | self.select_fields = rhs.select_fields[:] |
diff --git a/django/db/models/sql/where.py b/django/db/models/sql/where.py
index 1455ba6..631fc6b 100644
|
a
|
b
|
class WhereNode(tree.Node):
|
| 251 | 251 | # Check if the query value also requires relabelling |
| 252 | 252 | if hasattr(child[3], 'relabel_aliases'): |
| 253 | 253 | child[3].relabel_aliases(change_map) |
| | 254 | |
| | 255 | def clone(self): |
| | 256 | """ |
| | 257 | Creates a clone of the tree. Must only be called on root nodes (nodes |
| | 258 | with empty subtree_parents). Childs must be either Contraint, lookup, |
| | 259 | value tuples, or objects supporting .clone(). |
| | 260 | """ |
| | 261 | assert not self.subtree_parents, '.clone() can only be called on root nodes' |
| | 262 | clone = self.__class__._new_instance( |
| | 263 | children=[], connector=self.connector, negated=self.negated) |
| | 264 | for child in self.children: |
| | 265 | if isinstance(child, tuple): |
| | 266 | clone.children.append( |
| | 267 | (child[0].clone(), child[1], child[2], child[3])) |
| | 268 | else: |
| | 269 | clone.children.append(child.clone()) |
| | 270 | return clone |
| 254 | 271 | |
| 255 | 272 | class EverythingNode(object): |
| 256 | 273 | """ |
| … |
… |
class EverythingNode(object):
|
| 263 | 280 | def relabel_aliases(self, change_map, node=None): |
| 264 | 281 | return |
| 265 | 282 | |
| | 283 | def clone(self): |
| | 284 | return self |
| | 285 | |
| 266 | 286 | class NothingNode(object): |
| 267 | 287 | """ |
| 268 | 288 | A node that matches nothing. |
| … |
… |
class NothingNode(object):
|
| 273 | 293 | def relabel_aliases(self, change_map, node=None): |
| 274 | 294 | return |
| 275 | 295 | |
| | 296 | def clone(self): |
| | 297 | return self |
| | 298 | |
| 276 | 299 | class ExtraWhere(object): |
| 277 | 300 | def __init__(self, sqls, params): |
| 278 | 301 | self.sqls = sqls |
| … |
… |
class ExtraWhere(object):
|
| 281 | 304 | def as_sql(self, qn=None, connection=None): |
| 282 | 305 | return " AND ".join(self.sqls), tuple(self.params or ()) |
| 283 | 306 | |
| | 307 | def clone(self): |
| | 308 | return self |
| | 309 | |
| 284 | 310 | class Constraint(object): |
| 285 | 311 | """ |
| 286 | 312 | An object that can be passed to WhereNode.add() and knows how to |
| … |
… |
class Constraint(object):
|
| 345 | 371 | def relabel_aliases(self, change_map): |
| 346 | 372 | if self.alias in change_map: |
| 347 | 373 | self.alias = change_map[self.alias] |
| | 374 | |
| | 375 | def clone(self): |
| | 376 | return Constraint(self.alias, self.col, self.field) |