From e0aed58cc195f72495ac44b645c9f0e4375b37dc Mon Sep 17 00:00:00 2001
From: Henrik Levkowetz <henrik@levkowetz.com>
Date: Wed, 14 Mar 2018 17:41:11 +0000
Subject: [PATCH] Updated a django patch to add origin information to query
 sets.  - Legacy-Id: 14792

---
 patch/trace-django-queryset-origin.patch | 64 +++++++++---------------
 1 file changed, 24 insertions(+), 40 deletions(-)

diff --git a/patch/trace-django-queryset-origin.patch b/patch/trace-django-queryset-origin.patch
index 32e834fff..6d20480c3 100644
--- a/patch/trace-django-queryset-origin.patch
+++ b/patch/trace-django-queryset-origin.patch
@@ -1,5 +1,5 @@
---- django/db/models/query.py	2017-04-07 15:10:29.426831000 -0700
-+++ django/db/models/query.py	2017-04-12 08:23:20.061651277 -0700
+--- /home/henrik/src/db/latest/env/lib/python2.7/site-packages/django/db/models/query.py	2018-03-13 07:07:54.156249000 -0700
++++ /home/henrik/src/db/trunk/env/lib/python2.7/site-packages/django/db/models/query.py	2018-03-14 09:06:43.378819023 -0700
 @@ -5,6 +5,7 @@
  import copy
  import sys
@@ -8,24 +8,8 @@
  from collections import OrderedDict, deque
  
  from django.conf import settings
-@@ -34,7 +35,6 @@
- # Pull into this namespace for backwards compatibility.
- EmptyResultSet = sql.EmptyResultSet
- 
--
- class BaseIterable(object):
-     def __init__(self, queryset):
-         self.queryset = queryset
-@@ -51,6 +51,7 @@
-         compiler = queryset.query.get_compiler(using=db)
-         # Execute the query. This will also fill compiler.select, klass_info,
-         # and annotations.
-+
-         results = compiler.execute_sql()
-         select, klass_info, annotation_col_map = (compiler.select, compiler.klass_info,
-                                                   compiler.annotation_col_map)
-@@ -174,6 +175,8 @@
-         self._known_related_objects = {}  # {rel_field, {pk: rel_obj}}
+@@ -171,6 +172,8 @@
+         self._known_related_objects = {}  # {rel_field: {pk: rel_obj}}
          self._iterable_class = ModelIterable
          self._fields = None
 +        self._origin = []
@@ -33,7 +17,7 @@
  
      def as_manager(cls):
          # Address the circular dependency between `Queryset` and `Manager`.
-@@ -316,6 +319,31 @@
+@@ -310,6 +313,31 @@
          combined.query.combine(other.query, sql.OR)
          return combined
  
@@ -65,7 +49,7 @@
      ####################################
      # METHODS THAT DO DATABASE QUERIES #
      ####################################
-@@ -793,6 +821,7 @@
+@@ -781,6 +809,7 @@
          Returns a new QuerySet instance with the args ANDed to the existing
          set.
          """
@@ -73,7 +57,7 @@
          return self._filter_or_exclude(False, *args, **kwargs)
  
      def exclude(self, *args, **kwargs):
-@@ -800,6 +829,7 @@
+@@ -788,6 +817,7 @@
          Returns a new QuerySet instance with NOT (args) ANDed to the existing
          set.
          """
@@ -81,7 +65,7 @@
          return self._filter_or_exclude(True, *args, **kwargs)
  
      def _filter_or_exclude(self, negate, *args, **kwargs):
-@@ -824,6 +854,7 @@
+@@ -812,6 +842,7 @@
          This exists to support framework features such as 'limit_choices_to',
          and usually it will be more natural to use other methods.
          """
@@ -89,15 +73,15 @@
          if isinstance(filter_obj, Q) or hasattr(filter_obj, 'add_to_query'):
              clone = self._clone()
              clone.query.add_q(filter_obj)
-@@ -836,6 +867,7 @@
-         Returns a new QuerySet instance that will select objects with a
-         FOR UPDATE lock.
+@@ -866,6 +897,7 @@
          """
+         if nowait and skip_locked:
+             raise ValueError('The nowait option cannot be used with skip_locked.')
 +        self._add_origin()
          obj = self._clone()
          obj._for_write = True
          obj.query.select_for_update = True
-@@ -855,6 +887,7 @@
+@@ -886,6 +918,7 @@
          if self._fields is not None:
              raise TypeError("Cannot call select_related() after .values() or .values_list()")
  
@@ -105,15 +89,15 @@
          obj = self._clone()
          if fields == (None,):
              obj.query.select_related = False
-@@ -874,6 +907,7 @@
+@@ -905,6 +938,7 @@
          prefetch is appended to. If prefetch_related(None) is called, the list
          is cleared.
          """
 +        self._add_origin()
          clone = self._clone()
          if lookups == (None,):
-             clone._prefetch_related_lookups = []
-@@ -886,6 +920,7 @@
+             clone._prefetch_related_lookups = ()
+@@ -917,6 +951,7 @@
          Return a query set in which the returned objects have been annotated
          with extra data or aggregations.
          """
@@ -121,7 +105,7 @@
          annotations = OrderedDict()  # To preserve ordering of args
          for arg in args:
              # The default_alias property may raise a TypeError, so we use
-@@ -929,6 +964,7 @@
+@@ -960,6 +995,7 @@
          """
          assert self.query.can_filter(), \
              "Cannot reorder a query once a slice has been taken."
@@ -129,7 +113,7 @@
          obj = self._clone()
          obj.query.clear_ordering(force_empty=False)
          obj.query.add_ordering(*field_names)
-@@ -940,6 +976,7 @@
+@@ -971,6 +1007,7 @@
          """
          assert self.query.can_filter(), \
              "Cannot create distinct fields once a slice has been taken."
@@ -137,7 +121,7 @@
          obj = self._clone()
          obj.query.add_distinct_fields(*field_names)
          return obj
-@@ -951,6 +988,7 @@
+@@ -982,6 +1019,7 @@
          """
          assert self.query.can_filter(), \
              "Cannot change a query once a slice has been taken"
@@ -145,7 +129,7 @@
          clone = self._clone()
          clone.query.add_extra(select, select_params, where, params, tables, order_by)
          return clone
-@@ -959,6 +997,7 @@
+@@ -990,6 +1028,7 @@
          """
          Reverses the ordering of the QuerySet.
          """
@@ -153,7 +137,7 @@
          clone = self._clone()
          clone.query.standard_ordering = not clone.query.standard_ordering
          return clone
-@@ -973,6 +1012,7 @@
+@@ -1004,6 +1043,7 @@
          """
          if self._fields is not None:
              raise TypeError("Cannot call defer() after .values() or .values_list()")
@@ -161,7 +145,7 @@
          clone = self._clone()
          if fields == (None,):
              clone.query.clear_deferred_loading()
-@@ -992,6 +1032,7 @@
+@@ -1023,6 +1063,7 @@
              # Can only pass None to defer(), not only(), as the rest option.
              # That won't stop people trying to do this, so let's be explicit.
              raise TypeError("Cannot pass None as an argument to only().")
@@ -169,7 +153,7 @@
          clone = self._clone()
          clone.query.add_immediate_loading(fields)
          return clone
-@@ -1078,6 +1119,7 @@
+@@ -1109,6 +1150,7 @@
          clone._known_related_objects = self._known_related_objects
          clone._iterable_class = self._iterable_class
          clone._fields = self._fields
@@ -177,10 +161,10 @@
  
          clone.__dict__.update(kwargs)
          return clone
-@@ -1085,6 +1127,8 @@
+@@ -1116,6 +1158,8 @@
      def _fetch_all(self):
          if self._result_cache is None:
-             self._result_cache = list(self.iterator())
+             self._result_cache = list(self._iterable_class(self))
 +            if settings.DEBUG:
 +                connections[self.db].queries_log[-1]['origin'] = self._origin
          if self._prefetch_related_lookups and not self._prefetch_done: