~ubuntu-branches/ubuntu/quantal/python-django/quantal-security

« back to all changes in this revision

Viewing changes to django/db/models/sql/query.py

  • Committer: Bazaar Package Importer
  • Author(s): Chris Lamb
  • Date: 2010-05-21 07:52:55 UTC
  • mfrom: (1.3.6 upstream)
  • mto: This revision was merged to the branch mainline in revision 28.
  • Revision ID: james.westby@ubuntu.com-20100521075255-ii78v1dyfmyu3uzx
Tags: upstream-1.2
ImportĀ upstreamĀ versionĀ 1.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
7
7
all about the internals of models in order to get the information it needs.
8
8
"""
9
9
 
10
 
from copy import deepcopy
11
 
 
 
10
from django.utils.copycompat import deepcopy
12
11
from django.utils.tree import Node
13
12
from django.utils.datastructures import SortedDict
14
13
from django.utils.encoding import force_unicode
15
 
from django.db.backends.util import truncate_name
16
 
from django.db import connection
 
14
from django.db import connections, DEFAULT_DB_ALIAS
17
15
from django.db.models import signals
18
16
from django.db.models.fields import FieldDoesNotExist
19
 
from django.db.models.query_utils import select_related_descend
 
17
from django.db.models.query_utils import select_related_descend, InvalidQuery
20
18
from django.db.models.sql import aggregates as base_aggregates_module
 
19
from django.db.models.sql.constants import *
 
20
from django.db.models.sql.datastructures import EmptyResultSet, Empty, MultiJoin
21
21
from django.db.models.sql.expressions import SQLEvaluator
22
 
from django.db.models.sql.where import WhereNode, Constraint, EverythingNode, AND, OR
 
22
from django.db.models.sql.where import (WhereNode, Constraint, EverythingNode,
 
23
    ExtraWhere, AND, OR)
23
24
from django.core.exceptions import FieldError
24
 
from datastructures import EmptyResultSet, Empty, MultiJoin
25
 
from constants import *
26
 
 
27
 
try:
28
 
    set
29
 
except NameError:
30
 
    from sets import Set as set     # Python 2.3 fallback
31
 
 
32
 
__all__ = ['Query', 'BaseQuery']
33
 
 
34
 
class BaseQuery(object):
 
25
 
 
26
__all__ = ['Query', 'RawQuery']
 
27
 
 
28
class RawQuery(object):
 
29
    """
 
30
    A single raw SQL query
 
31
    """
 
32
 
 
33
    def __init__(self, sql, using, params=None):
 
34
        self.validate_sql(sql)
 
35
        self.params = params or ()
 
36
        self.sql = sql
 
37
        self.using = using
 
38
        self.cursor = None
 
39
 
 
40
        # Mirror some properties of a normal query so that
 
41
        # the compiler can be used to process results.
 
42
        self.low_mark, self.high_mark = 0, None  # Used for offset/limit
 
43
        self.extra_select = {}
 
44
        self.aggregate_select = {}
 
45
 
 
46
    def clone(self, using):
 
47
        return RawQuery(self.sql, using, params=self.params)
 
48
 
 
49
    def convert_values(self, value, field, connection):
 
50
        """Convert the database-returned value into a type that is consistent
 
51
        across database backends.
 
52
 
 
53
        By default, this defers to the underlying backend operations, but
 
54
        it can be overridden by Query classes for specific backends.
 
55
        """
 
56
        return connection.ops.convert_values(value, field)
 
57
 
 
58
    def get_columns(self):
 
59
        if self.cursor is None:
 
60
            self._execute_query()
 
61
        converter = connections[self.using].introspection.table_name_converter
 
62
        return [converter(column_meta[0])
 
63
                for column_meta in self.cursor.description]
 
64
 
 
65
    def validate_sql(self, sql):
 
66
        if not sql.lower().strip().startswith('select'):
 
67
            raise InvalidQuery('Raw queries are limited to SELECT queries. Use '
 
68
                               'connection.cursor directly for other types of queries.')
 
69
 
 
70
    def __iter__(self):
 
71
        # Always execute a new query for a new iterator.
 
72
        # This could be optimized with a cache at the expense of RAM.
 
73
        self._execute_query()
 
74
        if not connections[self.using].features.can_use_chunked_reads:
 
75
            # If the database can't use chunked reads we need to make sure we
 
76
            # evaluate the entire query up front.
 
77
            result = list(self.cursor)
 
78
        else:
 
79
            result = self.cursor
 
80
        return iter(result)
 
81
 
 
82
    def __repr__(self):
 
83
        return "<RawQuery: %r>" % (self.sql % self.params)
 
84
 
 
85
    def _execute_query(self):
 
86
        self.cursor = connections[self.using].cursor()
 
87
        self.cursor.execute(self.sql, self.params)
 
88
 
 
89
 
 
90
class Query(object):
35
91
    """
36
92
    A single SQL query.
37
93
    """
44
100
    query_terms = QUERY_TERMS
45
101
    aggregates_module = base_aggregates_module
46
102
 
47
 
    def __init__(self, model, connection, where=WhereNode):
 
103
    compiler = 'SQLCompiler'
 
104
 
 
105
    def __init__(self, model, where=WhereNode):
48
106
        self.model = model
49
 
        self.connection = connection
50
107
        self.alias_refcount = {}
51
108
        self.alias_map = {}     # Maps alias to join information
52
109
        self.table_map = {}     # Maps table names to list of aliases.
93
150
        self._extra_select_cache = None
94
151
 
95
152
        self.extra_tables = ()
96
 
        self.extra_where = ()
97
 
        self.extra_params = ()
98
153
        self.extra_order_by = ()
99
154
 
100
155
        # A tuple that is a set of model field names and either True, if these
110
165
        Parameter values won't necessarily be quoted correctly, since that is
111
166
        done by the database interface at execution time.
112
167
        """
113
 
        sql, params = self.as_sql()
 
168
        sql, params = self.get_compiler(DEFAULT_DB_ALIAS).as_sql()
114
169
        return sql % params
115
170
 
116
171
    def __deepcopy__(self, memo):
117
 
        result= self.clone()
 
172
        result = self.clone(memo=memo)
118
173
        memo[id(self)] = result
119
174
        return result
120
175
 
125
180
        obj_dict = self.__dict__.copy()
126
181
        obj_dict['related_select_fields'] = []
127
182
        obj_dict['related_select_cols'] = []
128
 
        del obj_dict['connection']
129
183
 
130
184
        # Fields can't be pickled, so if a field list has been
131
185
        # specified, we pickle the list of field names instead.
147
201
        ]
148
202
 
149
203
        self.__dict__.update(obj_dict)
150
 
        # XXX: Need a better solution for this when multi-db stuff is
151
 
        # supported. It's the only class-reference to the module-level
152
 
        # connection variable.
153
 
        self.connection = connection
 
204
 
 
205
    def prepare(self):
 
206
        return self
 
207
 
 
208
    def get_compiler(self, using=None, connection=None):
 
209
        if using is None and connection is None:
 
210
            raise ValueError("Need either using or connection")
 
211
        if using:
 
212
            connection = connections[using]
 
213
 
 
214
        # Check that the compiler will be able to execute the query
 
215
        for alias, aggregate in self.aggregate_select.items():
 
216
            connection.ops.check_aggregate_support(aggregate)
 
217
 
 
218
        return connection.ops.compiler(self.compiler)(self, connection, using)
154
219
 
155
220
    def get_meta(self):
156
221
        """
160
225
        """
161
226
        return self.model._meta
162
227
 
163
 
    def quote_name_unless_alias(self, name):
164
 
        """
165
 
        A wrapper around connection.ops.quote_name that doesn't quote aliases
166
 
        for table names. This avoids problems with some SQL dialects that treat
167
 
        quoted strings specially (e.g. PostgreSQL).
168
 
        """
169
 
        if name in self.quote_cache:
170
 
            return self.quote_cache[name]
171
 
        if ((name in self.alias_map and name not in self.table_map) or
172
 
                name in self.extra_select):
173
 
            self.quote_cache[name] = name
174
 
            return name
175
 
        r = self.connection.ops.quote_name(name)
176
 
        self.quote_cache[name] = r
177
 
        return r
178
 
 
179
 
    def clone(self, klass=None, **kwargs):
 
228
    def clone(self, klass=None, memo=None, **kwargs):
180
229
        """
181
230
        Creates a copy of the current instance. The 'kwargs' parameter can be
182
231
        used by clients to update attributes after copying has taken place.
184
233
        obj = Empty()
185
234
        obj.__class__ = klass or self.__class__
186
235
        obj.model = self.model
187
 
        obj.connection = self.connection
188
236
        obj.alias_refcount = self.alias_refcount.copy()
189
237
        obj.alias_map = self.alias_map.copy()
190
238
        obj.table_map = self.table_map.copy()
201
249
        obj.dupe_avoidance = self.dupe_avoidance.copy()
202
250
        obj.select = self.select[:]
203
251
        obj.tables = self.tables[:]
204
 
        obj.where = deepcopy(self.where)
 
252
        obj.where = deepcopy(self.where, memo=memo)
205
253
        obj.where_class = self.where_class
206
254
        if self.group_by is None:
207
255
            obj.group_by = None
208
256
        else:
209
257
            obj.group_by = self.group_by[:]
210
 
        obj.having = deepcopy(self.having)
 
258
        obj.having = deepcopy(self.having, memo=memo)
211
259
        obj.order_by = self.order_by[:]
212
260
        obj.low_mark, obj.high_mark = self.low_mark, self.high_mark
213
261
        obj.distinct = self.distinct
214
262
        obj.select_related = self.select_related
215
263
        obj.related_select_cols = []
216
 
        obj.aggregates = deepcopy(self.aggregates)
 
264
        obj.aggregates = deepcopy(self.aggregates, memo=memo)
217
265
        if self.aggregate_select_mask is None:
218
266
            obj.aggregate_select_mask = None
219
267
        else:
220
268
            obj.aggregate_select_mask = self.aggregate_select_mask.copy()
221
 
        if self._aggregate_select_cache is None:
222
 
            obj._aggregate_select_cache = None
223
 
        else:
224
 
            obj._aggregate_select_cache = self._aggregate_select_cache.copy()
 
269
        # _aggregate_select_cache cannot be copied, as doing so breaks the
 
270
        # (necessary) state in which both aggregates and
 
271
        # _aggregate_select_cache point to the same underlying objects.
 
272
        # It will get re-populated in the cloned queryset the next time it's
 
273
        # used.
 
274
        obj._aggregate_select_cache = None
225
275
        obj.max_depth = self.max_depth
226
276
        obj.extra = self.extra.copy()
227
277
        if self.extra_select_mask is None:
233
283
        else:
234
284
            obj._extra_select_cache = self._extra_select_cache.copy()
235
285
        obj.extra_tables = self.extra_tables
236
 
        obj.extra_where = self.extra_where
237
 
        obj.extra_params = self.extra_params
238
286
        obj.extra_order_by = self.extra_order_by
239
 
        obj.deferred_loading = deepcopy(self.deferred_loading)
 
287
        obj.deferred_loading = deepcopy(self.deferred_loading, memo=memo)
240
288
        if self.filter_is_sticky and self.used_aliases:
241
289
            obj.used_aliases = self.used_aliases.copy()
242
290
        else:
247
295
            obj._setup_query()
248
296
        return obj
249
297
 
250
 
    def convert_values(self, value, field):
 
298
    def convert_values(self, value, field, connection):
251
299
        """Convert the database-returned value into a type that is consistent
252
300
        across database backends.
253
301
 
254
302
        By default, this defers to the underlying backend operations, but
255
303
        it can be overridden by Query classes for specific backends.
256
304
        """
257
 
        return self.connection.ops.convert_values(value, field)
 
305
        return connection.ops.convert_values(value, field)
258
306
 
259
 
    def resolve_aggregate(self, value, aggregate):
 
307
    def resolve_aggregate(self, value, aggregate, connection):
260
308
        """Resolve the value of aggregates returned by the database to
261
309
        consistent (and reasonable) types.
262
310
 
276
324
            return float(value)
277
325
        else:
278
326
            # Return value depends on the type of the field being processed.
279
 
            return self.convert_values(value, aggregate.field)
280
 
 
281
 
    def results_iter(self):
282
 
        """
283
 
        Returns an iterator over the results from executing this query.
284
 
        """
285
 
        resolve_columns = hasattr(self, 'resolve_columns')
286
 
        fields = None
287
 
        for rows in self.execute_sql(MULTI):
288
 
            for row in rows:
289
 
                if resolve_columns:
290
 
                    if fields is None:
291
 
                        # We only set this up here because
292
 
                        # related_select_fields isn't populated until
293
 
                        # execute_sql() has been called.
294
 
                        if self.select_fields:
295
 
                            fields = self.select_fields + self.related_select_fields
296
 
                        else:
297
 
                            fields = self.model._meta.fields
298
 
                    row = self.resolve_columns(row, fields)
299
 
 
300
 
                if self.aggregate_select:
301
 
                    aggregate_start = len(self.extra_select.keys()) + len(self.select)
302
 
                    aggregate_end = aggregate_start + len(self.aggregate_select)
303
 
                    row = tuple(row[:aggregate_start]) + tuple([
304
 
                        self.resolve_aggregate(value, aggregate)
305
 
                        for (alias, aggregate), value
306
 
                        in zip(self.aggregate_select.items(), row[aggregate_start:aggregate_end])
307
 
                    ]) + tuple(row[aggregate_end:])
308
 
 
309
 
                yield row
310
 
 
311
 
    def get_aggregation(self):
 
327
            return self.convert_values(value, aggregate.field, connection)
 
328
 
 
329
    def get_aggregation(self, using):
312
330
        """
313
331
        Returns the dictionary with the values of the existing aggregations.
314
332
        """
320
338
        # over the subquery instead.
321
339
        if self.group_by is not None:
322
340
            from subqueries import AggregateQuery
323
 
            query = AggregateQuery(self.model, self.connection)
 
341
            query = AggregateQuery(self.model)
324
342
 
325
343
            obj = self.clone()
326
344
 
331
349
                    query.aggregate_select[alias] = aggregate
332
350
                    del obj.aggregate_select[alias]
333
351
 
334
 
            query.add_subquery(obj)
 
352
            query.add_subquery(obj, using)
335
353
        else:
336
354
            query = self
337
355
            self.select = []
345
363
        query.related_select_cols = []
346
364
        query.related_select_fields = []
347
365
 
348
 
        result = query.execute_sql(SINGLE)
 
366
        result = query.get_compiler(using).execute_sql(SINGLE)
349
367
        if result is None:
350
368
            result = [None for q in query.aggregate_select.items()]
351
369
 
352
370
        return dict([
353
 
            (alias, self.resolve_aggregate(val, aggregate))
 
371
            (alias, self.resolve_aggregate(val, aggregate, connection=connections[using]))
354
372
            for (alias, aggregate), val
355
373
            in zip(query.aggregate_select.items(), result)
356
374
        ])
357
375
 
358
 
    def get_count(self):
 
376
    def get_count(self, using):
359
377
        """
360
378
        Performs a COUNT() query using the current filter constraints.
361
379
        """
369
387
            subquery.clear_ordering(True)
370
388
            subquery.clear_limits()
371
389
 
372
 
            obj = AggregateQuery(obj.model, obj.connection)
373
 
            obj.add_subquery(subquery)
 
390
            obj = AggregateQuery(obj.model)
 
391
            obj.add_subquery(subquery, using=using)
374
392
 
375
393
        obj.add_count_column()
376
 
        number = obj.get_aggregation()[None]
 
394
        number = obj.get_aggregation(using=using)[None]
377
395
 
378
396
        # Apply offset and limit constraints manually, since using LIMIT/OFFSET
379
397
        # in SQL (in variants that provide them) doesn't change the COUNT
384
402
 
385
403
        return number
386
404
 
387
 
    def as_sql(self, with_limits=True, with_col_aliases=False):
388
 
        """
389
 
        Creates the SQL for this query. Returns the SQL string and list of
390
 
        parameters.
391
 
 
392
 
        If 'with_limits' is False, any limit/offset information is not included
393
 
        in the query.
394
 
        """
395
 
        self.pre_sql_setup()
396
 
        out_cols = self.get_columns(with_col_aliases)
397
 
        ordering, ordering_group_by = self.get_ordering()
398
 
 
399
 
        # This must come after 'select' and 'ordering' -- see docstring of
400
 
        # get_from_clause() for details.
401
 
        from_, f_params = self.get_from_clause()
402
 
 
403
 
        qn = self.quote_name_unless_alias
404
 
        where, w_params = self.where.as_sql(qn=qn)
405
 
        having, h_params = self.having.as_sql(qn=qn)
406
 
        params = []
407
 
        for val in self.extra_select.itervalues():
408
 
            params.extend(val[1])
409
 
 
410
 
        result = ['SELECT']
411
 
        if self.distinct:
412
 
            result.append('DISTINCT')
413
 
        result.append(', '.join(out_cols + self.ordering_aliases))
414
 
 
415
 
        result.append('FROM')
416
 
        result.extend(from_)
417
 
        params.extend(f_params)
418
 
 
419
 
        if where:
420
 
            result.append('WHERE %s' % where)
421
 
            params.extend(w_params)
422
 
        if self.extra_where:
423
 
            if not where:
424
 
                result.append('WHERE')
425
 
            else:
426
 
                result.append('AND')
427
 
            result.append(' AND '.join(self.extra_where))
428
 
 
429
 
        grouping, gb_params = self.get_grouping()
430
 
        if grouping:
431
 
            if ordering:
432
 
                # If the backend can't group by PK (i.e., any database
433
 
                # other than MySQL), then any fields mentioned in the
434
 
                # ordering clause needs to be in the group by clause.
435
 
                if not self.connection.features.allows_group_by_pk:
436
 
                    for col, col_params in ordering_group_by:
437
 
                        if col not in grouping:
438
 
                            grouping.append(str(col))
439
 
                            gb_params.extend(col_params)
440
 
            else:
441
 
                ordering = self.connection.ops.force_no_ordering()
442
 
            result.append('GROUP BY %s' % ', '.join(grouping))
443
 
            params.extend(gb_params)
444
 
 
445
 
        if having:
446
 
            result.append('HAVING %s' % having)
447
 
            params.extend(h_params)
448
 
 
449
 
        if ordering:
450
 
            result.append('ORDER BY %s' % ', '.join(ordering))
451
 
 
452
 
        if with_limits:
453
 
            if self.high_mark is not None:
454
 
                result.append('LIMIT %d' % (self.high_mark - self.low_mark))
455
 
            if self.low_mark:
456
 
                if self.high_mark is None:
457
 
                    val = self.connection.ops.no_limit_value()
458
 
                    if val:
459
 
                        result.append('LIMIT %d' % val)
460
 
                result.append('OFFSET %d' % self.low_mark)
461
 
 
462
 
        params.extend(self.extra_params)
463
 
        return ' '.join(result), tuple(params)
464
 
 
465
 
    def as_nested_sql(self):
466
 
        """
467
 
        Perform the same functionality as the as_sql() method, returning an
468
 
        SQL string and parameters. However, the alias prefixes are bumped
469
 
        beforehand (in a copy -- the current query isn't changed) and any
470
 
        ordering is removed.
471
 
 
472
 
        Used when nesting this query inside another.
473
 
        """
474
 
        obj = self.clone()
475
 
        obj.clear_ordering(True)
476
 
        obj.bump_prefix()
477
 
        return obj.as_sql()
 
405
    def has_results(self, using):
 
406
        q = self.clone()
 
407
        q.add_extra({'a': 1}, None, None, None, None, None)
 
408
        q.select = []
 
409
        q.select_fields = []
 
410
        q.default_cols = False
 
411
        q.select_related = False
 
412
        q.set_extra_mask(('a',))
 
413
        q.set_aggregate_mask(())
 
414
        q.clear_ordering(True)
 
415
        q.set_limits(high=1)
 
416
        compiler = q.get_compiler(using=using)
 
417
        return bool(compiler.execute_sql(SINGLE))
478
418
 
479
419
    def combine(self, rhs, connector):
480
420
        """
554
494
            if self.extra and rhs.extra:
555
495
                raise ValueError("When merging querysets using 'or', you "
556
496
                        "cannot have extra(select=...) on both sides.")
557
 
            if self.extra_where and rhs.extra_where:
558
 
                raise ValueError("When merging querysets using 'or', you "
559
 
                        "cannot have extra(where=...) on both sides.")
560
497
        self.extra.update(rhs.extra)
561
498
        extra_select_mask = set()
562
499
        if self.extra_select_mask is not None:
566
503
        if extra_select_mask:
567
504
            self.set_extra_mask(extra_select_mask)
568
505
        self.extra_tables += rhs.extra_tables
569
 
        self.extra_where += rhs.extra_where
570
 
        self.extra_params += rhs.extra_params
571
506
 
572
507
        # Ordering uses the 'rhs' ordering, unless it has none, in which case
573
508
        # the current ordering is used.
574
509
        self.order_by = rhs.order_by and rhs.order_by[:] or self.order_by
575
510
        self.extra_order_by = rhs.extra_order_by or self.extra_order_by
576
511
 
577
 
    def pre_sql_setup(self):
578
 
        """
579
 
        Does any necessary class setup immediately prior to producing SQL. This
580
 
        is for things that can't necessarily be done in __init__ because we
581
 
        might not have all the pieces in place at that time.
582
 
        """
583
 
        if not self.tables:
584
 
            self.join((None, self.model._meta.db_table, None, None))
585
 
        if (not self.select and self.default_cols and not
586
 
                self.included_inherited_models):
587
 
            self.setup_inherited_models()
588
 
        if self.select_related and not self.related_select_cols:
589
 
            self.fill_related_selections()
590
 
 
591
512
    def deferred_to_data(self, target, callback):
592
513
        """
593
514
        Converts the self.deferred_loading data structure to an alternate data
635
556
            # models.
636
557
            workset = {}
637
558
            for model, values in seen.iteritems():
638
 
                for field in model._meta.local_fields:
 
559
                for field, m in model._meta.get_fields_with_model():
639
560
                    if field in values:
640
561
                        continue
641
 
                    add_to_dict(workset, model, field)
 
562
                    add_to_dict(workset, m or model, field)
642
563
            for model, values in must_include.iteritems():
643
564
                # If we haven't included a model in workset, we don't add the
644
565
                # corresponding must_include fields for that model, since an
666
587
            for model, values in seen.iteritems():
667
588
                callback(target, model, values)
668
589
 
669
 
    def deferred_to_columns(self):
670
 
        """
671
 
        Converts the self.deferred_loading data structure to mapping of table
672
 
        names to sets of column names which are to be loaded. Returns the
673
 
        dictionary.
674
 
        """
675
 
        columns = {}
676
 
        self.deferred_to_data(columns, self.deferred_to_columns_cb)
677
 
        return columns
678
590
 
679
591
    def deferred_to_columns_cb(self, target, model, fields):
680
592
        """
687
599
        for field in fields:
688
600
            target[table].add(field.column)
689
601
 
690
 
    def get_columns(self, with_aliases=False):
691
 
        """
692
 
        Returns the list of columns to use in the select statement. If no
693
 
        columns have been specified, returns all columns relating to fields in
694
 
        the model.
695
 
 
696
 
        If 'with_aliases' is true, any column names that are duplicated
697
 
        (without the table names) are given unique aliases. This is needed in
698
 
        some cases to avoid ambiguity with nested queries.
699
 
        """
700
 
        qn = self.quote_name_unless_alias
701
 
        qn2 = self.connection.ops.quote_name
702
 
        result = ['(%s) AS %s' % (col[0], qn2(alias)) for alias, col in self.extra_select.iteritems()]
703
 
        aliases = set(self.extra_select.keys())
704
 
        if with_aliases:
705
 
            col_aliases = aliases.copy()
706
 
        else:
707
 
            col_aliases = set()
708
 
        if self.select:
709
 
            only_load = self.deferred_to_columns()
710
 
            for col in self.select:
711
 
                if isinstance(col, (list, tuple)):
712
 
                    alias, column = col
713
 
                    table = self.alias_map[alias][TABLE_NAME]
714
 
                    if table in only_load and col not in only_load[table]:
715
 
                        continue
716
 
                    r = '%s.%s' % (qn(alias), qn(column))
717
 
                    if with_aliases:
718
 
                        if col[1] in col_aliases:
719
 
                            c_alias = 'Col%d' % len(col_aliases)
720
 
                            result.append('%s AS %s' % (r, c_alias))
721
 
                            aliases.add(c_alias)
722
 
                            col_aliases.add(c_alias)
723
 
                        else:
724
 
                            result.append('%s AS %s' % (r, qn2(col[1])))
725
 
                            aliases.add(r)
726
 
                            col_aliases.add(col[1])
727
 
                    else:
728
 
                        result.append(r)
729
 
                        aliases.add(r)
730
 
                        col_aliases.add(col[1])
731
 
                else:
732
 
                    result.append(col.as_sql(quote_func=qn))
733
 
 
734
 
                    if hasattr(col, 'alias'):
735
 
                        aliases.add(col.alias)
736
 
                        col_aliases.add(col.alias)
737
 
 
738
 
        elif self.default_cols:
739
 
            cols, new_aliases = self.get_default_columns(with_aliases,
740
 
                    col_aliases)
741
 
            result.extend(cols)
742
 
            aliases.update(new_aliases)
743
 
 
744
 
        result.extend([
745
 
            '%s%s' % (
746
 
                aggregate.as_sql(quote_func=qn),
747
 
                alias is not None and ' AS %s' % qn(alias) or ''
748
 
            )
749
 
            for alias, aggregate in self.aggregate_select.items()
750
 
        ])
751
 
 
752
 
        for table, col in self.related_select_cols:
753
 
            r = '%s.%s' % (qn(table), qn(col))
754
 
            if with_aliases and col in col_aliases:
755
 
                c_alias = 'Col%d' % len(col_aliases)
756
 
                result.append('%s AS %s' % (r, c_alias))
757
 
                aliases.add(c_alias)
758
 
                col_aliases.add(c_alias)
759
 
            else:
760
 
                result.append(r)
761
 
                aliases.add(r)
762
 
                col_aliases.add(col)
763
 
 
764
 
        self._select_aliases = aliases
765
 
        return result
766
 
 
767
 
    def get_default_columns(self, with_aliases=False, col_aliases=None,
768
 
            start_alias=None, opts=None, as_pairs=False):
769
 
        """
770
 
        Computes the default columns for selecting every field in the base
771
 
        model. Will sometimes be called to pull in related models (e.g. via
772
 
        select_related), in which case "opts" and "start_alias" will be given
773
 
        to provide a starting point for the traversal.
774
 
 
775
 
        Returns a list of strings, quoted appropriately for use in SQL
776
 
        directly, as well as a set of aliases used in the select statement (if
777
 
        'as_pairs' is True, returns a list of (alias, col_name) pairs instead
778
 
        of strings as the first component and None as the second component).
779
 
        """
780
 
        result = []
781
 
        if opts is None:
782
 
            opts = self.model._meta
783
 
        qn = self.quote_name_unless_alias
784
 
        qn2 = self.connection.ops.quote_name
785
 
        aliases = set()
786
 
        only_load = self.deferred_to_columns()
787
 
        # Skip all proxy to the root proxied model
788
 
        proxied_model = get_proxied_model(opts)
789
 
 
790
 
        if start_alias:
791
 
            seen = {None: start_alias}
792
 
        for field, model in opts.get_fields_with_model():
793
 
            if start_alias:
794
 
                try:
795
 
                    alias = seen[model]
796
 
                except KeyError:
797
 
                    if model is proxied_model:
798
 
                        alias = start_alias
799
 
                    else:
800
 
                        link_field = opts.get_ancestor_link(model)
801
 
                        alias = self.join((start_alias, model._meta.db_table,
802
 
                                link_field.column, model._meta.pk.column))
803
 
                    seen[model] = alias
804
 
            else:
805
 
                # If we're starting from the base model of the queryset, the
806
 
                # aliases will have already been set up in pre_sql_setup(), so
807
 
                # we can save time here.
808
 
                alias = self.included_inherited_models[model]
809
 
            table = self.alias_map[alias][TABLE_NAME]
810
 
            if table in only_load and field.column not in only_load[table]:
811
 
                continue
812
 
            if as_pairs:
813
 
                result.append((alias, field.column))
814
 
                aliases.add(alias)
815
 
                continue
816
 
            if with_aliases and field.column in col_aliases:
817
 
                c_alias = 'Col%d' % len(col_aliases)
818
 
                result.append('%s.%s AS %s' % (qn(alias),
819
 
                    qn2(field.column), c_alias))
820
 
                col_aliases.add(c_alias)
821
 
                aliases.add(c_alias)
822
 
            else:
823
 
                r = '%s.%s' % (qn(alias), qn2(field.column))
824
 
                result.append(r)
825
 
                aliases.add(r)
826
 
                if with_aliases:
827
 
                    col_aliases.add(field.column)
828
 
        return result, aliases
829
 
 
830
 
    def get_from_clause(self):
831
 
        """
832
 
        Returns a list of strings that are joined together to go after the
833
 
        "FROM" part of the query, as well as a list any extra parameters that
834
 
        need to be included. Sub-classes, can override this to create a
835
 
        from-clause via a "select".
836
 
 
837
 
        This should only be called after any SQL construction methods that
838
 
        might change the tables we need. This means the select columns and
839
 
        ordering must be done first.
840
 
        """
841
 
        result = []
842
 
        qn = self.quote_name_unless_alias
843
 
        qn2 = self.connection.ops.quote_name
844
 
        first = True
845
 
        for alias in self.tables:
846
 
            if not self.alias_refcount[alias]:
847
 
                continue
848
 
            try:
849
 
                name, alias, join_type, lhs, lhs_col, col, nullable = self.alias_map[alias]
850
 
            except KeyError:
851
 
                # Extra tables can end up in self.tables, but not in the
852
 
                # alias_map if they aren't in a join. That's OK. We skip them.
853
 
                continue
854
 
            alias_str = (alias != name and ' %s' % alias or '')
855
 
            if join_type and not first:
856
 
                result.append('%s %s%s ON (%s.%s = %s.%s)'
857
 
                        % (join_type, qn(name), alias_str, qn(lhs),
858
 
                           qn2(lhs_col), qn(alias), qn2(col)))
859
 
            else:
860
 
                connector = not first and ', ' or ''
861
 
                result.append('%s%s%s' % (connector, qn(name), alias_str))
862
 
            first = False
863
 
        for t in self.extra_tables:
864
 
            alias, unused = self.table_alias(t)
865
 
            # Only add the alias if it's not already present (the table_alias()
866
 
            # calls increments the refcount, so an alias refcount of one means
867
 
            # this is the only reference.
868
 
            if alias not in self.alias_map or self.alias_refcount[alias] == 1:
869
 
                connector = not first and ', ' or ''
870
 
                result.append('%s%s' % (connector, qn(alias)))
871
 
                first = False
872
 
        return result, []
873
 
 
874
 
    def get_grouping(self):
875
 
        """
876
 
        Returns a tuple representing the SQL elements in the "group by" clause.
877
 
        """
878
 
        qn = self.quote_name_unless_alias
879
 
        result, params = [], []
880
 
        if self.group_by is not None:
881
 
            group_by = self.group_by or []
882
 
 
883
 
            extra_selects = []
884
 
            for extra_select, extra_params in self.extra_select.itervalues():
885
 
                extra_selects.append(extra_select)
886
 
                params.extend(extra_params)
887
 
            for col in group_by + self.related_select_cols + extra_selects:
888
 
                if isinstance(col, (list, tuple)):
889
 
                    result.append('%s.%s' % (qn(col[0]), qn(col[1])))
890
 
                elif hasattr(col, 'as_sql'):
891
 
                    result.append(col.as_sql(qn))
892
 
                else:
893
 
                    result.append(str(col))
894
 
        return result, params
895
 
 
896
 
    def get_ordering(self):
897
 
        """
898
 
        Returns a tuple containing a list representing the SQL elements in the
899
 
        "order by" clause, and the list of SQL elements that need to be added
900
 
        to the GROUP BY clause as a result of the ordering.
901
 
 
902
 
        Also sets the ordering_aliases attribute on this instance to a list of
903
 
        extra aliases needed in the select.
904
 
 
905
 
        Determining the ordering SQL can change the tables we need to include,
906
 
        so this should be run *before* get_from_clause().
907
 
        """
908
 
        if self.extra_order_by:
909
 
            ordering = self.extra_order_by
910
 
        elif not self.default_ordering:
911
 
            ordering = self.order_by
912
 
        else:
913
 
            ordering = self.order_by or self.model._meta.ordering
914
 
        qn = self.quote_name_unless_alias
915
 
        qn2 = self.connection.ops.quote_name
916
 
        distinct = self.distinct
917
 
        select_aliases = self._select_aliases
918
 
        result = []
919
 
        group_by = []
920
 
        ordering_aliases = []
921
 
        if self.standard_ordering:
922
 
            asc, desc = ORDER_DIR['ASC']
923
 
        else:
924
 
            asc, desc = ORDER_DIR['DESC']
925
 
 
926
 
        # It's possible, due to model inheritance, that normal usage might try
927
 
        # to include the same field more than once in the ordering. We track
928
 
        # the table/column pairs we use and discard any after the first use.
929
 
        processed_pairs = set()
930
 
 
931
 
        for field in ordering:
932
 
            if field == '?':
933
 
                result.append(self.connection.ops.random_function_sql())
934
 
                continue
935
 
            if isinstance(field, int):
936
 
                if field < 0:
937
 
                    order = desc
938
 
                    field = -field
939
 
                else:
940
 
                    order = asc
941
 
                result.append('%s %s' % (field, order))
942
 
                group_by.append((field, []))
943
 
                continue
944
 
            col, order = get_order_dir(field, asc)
945
 
            if col in self.aggregate_select:
946
 
                result.append('%s %s' % (col, order))
947
 
                continue
948
 
            if '.' in field:
949
 
                # This came in through an extra(order_by=...) addition. Pass it
950
 
                # on verbatim.
951
 
                table, col = col.split('.', 1)
952
 
                if (table, col) not in processed_pairs:
953
 
                    elt = '%s.%s' % (qn(table), col)
954
 
                    processed_pairs.add((table, col))
955
 
                    if not distinct or elt in select_aliases:
956
 
                        result.append('%s %s' % (elt, order))
957
 
                        group_by.append((elt, []))
958
 
            elif get_order_dir(field)[0] not in self.extra_select:
959
 
                # 'col' is of the form 'field' or 'field1__field2' or
960
 
                # '-field1__field2__field', etc.
961
 
                for table, col, order in self.find_ordering_name(field,
962
 
                        self.model._meta, default_order=asc):
963
 
                    if (table, col) not in processed_pairs:
964
 
                        elt = '%s.%s' % (qn(table), qn2(col))
965
 
                        processed_pairs.add((table, col))
966
 
                        if distinct and elt not in select_aliases:
967
 
                            ordering_aliases.append(elt)
968
 
                        result.append('%s %s' % (elt, order))
969
 
                        group_by.append((elt, []))
970
 
            else:
971
 
                elt = qn2(col)
972
 
                if distinct and col not in select_aliases:
973
 
                    ordering_aliases.append(elt)
974
 
                result.append('%s %s' % (elt, order))
975
 
                group_by.append(self.extra_select[col])
976
 
        self.ordering_aliases = ordering_aliases
977
 
        return result, group_by
978
 
 
979
 
    def find_ordering_name(self, name, opts, alias=None, default_order='ASC',
980
 
            already_seen=None):
981
 
        """
982
 
        Returns the table alias (the name might be ambiguous, the alias will
983
 
        not be) and column name for ordering by the given 'name' parameter.
984
 
        The 'name' is of the form 'field1__field2__...__fieldN'.
985
 
        """
986
 
        name, order = get_order_dir(name, default_order)
987
 
        pieces = name.split(LOOKUP_SEP)
988
 
        if not alias:
989
 
            alias = self.get_initial_alias()
990
 
        field, target, opts, joins, last, extra = self.setup_joins(pieces,
991
 
                opts, alias, False)
992
 
        alias = joins[-1]
993
 
        col = target.column
994
 
        if not field.rel:
995
 
            # To avoid inadvertent trimming of a necessary alias, use the
996
 
            # refcount to show that we are referencing a non-relation field on
997
 
            # the model.
998
 
            self.ref_alias(alias)
999
 
 
1000
 
        # Must use left outer joins for nullable fields and their relations.
1001
 
        self.promote_alias_chain(joins,
1002
 
                self.alias_map[joins[0]][JOIN_TYPE] == self.LOUTER)
1003
 
 
1004
 
        # If we get to this point and the field is a relation to another model,
1005
 
        # append the default ordering for that model.
1006
 
        if field.rel and len(joins) > 1 and opts.ordering:
1007
 
            # Firstly, avoid infinite loops.
1008
 
            if not already_seen:
1009
 
                already_seen = set()
1010
 
            join_tuple = tuple([self.alias_map[j][TABLE_NAME] for j in joins])
1011
 
            if join_tuple in already_seen:
1012
 
                raise FieldError('Infinite loop caused by ordering.')
1013
 
            already_seen.add(join_tuple)
1014
 
 
1015
 
            results = []
1016
 
            for item in opts.ordering:
1017
 
                results.extend(self.find_ordering_name(item, opts, alias,
1018
 
                        order, already_seen))
1019
 
            return results
1020
 
 
1021
 
        if alias:
1022
 
            # We have to do the same "final join" optimisation as in
1023
 
            # add_filter, since the final column might not otherwise be part of
1024
 
            # the select set (so we can't order on it).
1025
 
            while 1:
1026
 
                join = self.alias_map[alias]
1027
 
                if col != join[RHS_JOIN_COL]:
1028
 
                    break
1029
 
                self.unref_alias(alias)
1030
 
                alias = join[LHS_ALIAS]
1031
 
                col = join[LHS_JOIN_COL]
1032
 
        return [(alias, col, order)]
1033
602
 
1034
603
    def table_alias(self, table_name, create=False):
1035
604
        """
1333
902
                self.unref_alias(alias)
1334
903
        self.included_inherited_models = {}
1335
904
 
1336
 
    def fill_related_selections(self, opts=None, root_alias=None, cur_depth=1,
1337
 
            used=None, requested=None, restricted=None, nullable=None,
1338
 
            dupe_set=None, avoid_set=None):
1339
 
        """
1340
 
        Fill in the information needed for a select_related query. The current
1341
 
        depth is measured as the number of connections away from the root model
1342
 
        (for example, cur_depth=1 means we are looking at models with direct
1343
 
        connections to the root model).
1344
 
        """
1345
 
        if not restricted and self.max_depth and cur_depth > self.max_depth:
1346
 
            # We've recursed far enough; bail out.
1347
 
            return
1348
 
 
1349
 
        if not opts:
1350
 
            opts = self.get_meta()
1351
 
            root_alias = self.get_initial_alias()
1352
 
            self.related_select_cols = []
1353
 
            self.related_select_fields = []
1354
 
        if not used:
1355
 
            used = set()
1356
 
        if dupe_set is None:
1357
 
            dupe_set = set()
1358
 
        if avoid_set is None:
1359
 
            avoid_set = set()
1360
 
        orig_dupe_set = dupe_set
1361
 
 
1362
 
        # Setup for the case when only particular related fields should be
1363
 
        # included in the related selection.
1364
 
        if requested is None and restricted is not False:
1365
 
            if isinstance(self.select_related, dict):
1366
 
                requested = self.select_related
1367
 
                restricted = True
1368
 
            else:
1369
 
                restricted = False
1370
 
 
1371
 
        for f, model in opts.get_fields_with_model():
1372
 
            if not select_related_descend(f, restricted, requested):
1373
 
                continue
1374
 
            # The "avoid" set is aliases we want to avoid just for this
1375
 
            # particular branch of the recursion. They aren't permanently
1376
 
            # forbidden from reuse in the related selection tables (which is
1377
 
            # what "used" specifies).
1378
 
            avoid = avoid_set.copy()
1379
 
            dupe_set = orig_dupe_set.copy()
1380
 
            table = f.rel.to._meta.db_table
1381
 
            if nullable or f.null:
1382
 
                promote = True
1383
 
            else:
1384
 
                promote = False
1385
 
            if model:
1386
 
                int_opts = opts
1387
 
                alias = root_alias
1388
 
                alias_chain = []
1389
 
                for int_model in opts.get_base_chain(model):
1390
 
                    # Proxy model have elements in base chain
1391
 
                    # with no parents, assign the new options
1392
 
                    # object and skip to the next base in that
1393
 
                    # case
1394
 
                    if not int_opts.parents[int_model]:
1395
 
                        int_opts = int_model._meta
1396
 
                        continue
1397
 
                    lhs_col = int_opts.parents[int_model].column
1398
 
                    dedupe = lhs_col in opts.duplicate_targets
1399
 
                    if dedupe:
1400
 
                        avoid.update(self.dupe_avoidance.get(id(opts), lhs_col),
1401
 
                                ())
1402
 
                        dupe_set.add((opts, lhs_col))
1403
 
                    int_opts = int_model._meta
1404
 
                    alias = self.join((alias, int_opts.db_table, lhs_col,
1405
 
                            int_opts.pk.column), exclusions=used,
1406
 
                            promote=promote)
1407
 
                    alias_chain.append(alias)
1408
 
                    for (dupe_opts, dupe_col) in dupe_set:
1409
 
                        self.update_dupe_avoidance(dupe_opts, dupe_col, alias)
1410
 
                if self.alias_map[root_alias][JOIN_TYPE] == self.LOUTER:
1411
 
                    self.promote_alias_chain(alias_chain, True)
1412
 
            else:
1413
 
                alias = root_alias
1414
 
 
1415
 
            dedupe = f.column in opts.duplicate_targets
1416
 
            if dupe_set or dedupe:
1417
 
                avoid.update(self.dupe_avoidance.get((id(opts), f.column), ()))
1418
 
                if dedupe:
1419
 
                    dupe_set.add((opts, f.column))
1420
 
 
1421
 
            alias = self.join((alias, table, f.column,
1422
 
                    f.rel.get_related_field().column),
1423
 
                    exclusions=used.union(avoid), promote=promote)
1424
 
            used.add(alias)
1425
 
            columns, aliases = self.get_default_columns(start_alias=alias,
1426
 
                    opts=f.rel.to._meta, as_pairs=True)
1427
 
            self.related_select_cols.extend(columns)
1428
 
            if self.alias_map[alias][JOIN_TYPE] == self.LOUTER:
1429
 
                self.promote_alias_chain(aliases, True)
1430
 
            self.related_select_fields.extend(f.rel.to._meta.fields)
1431
 
            if restricted:
1432
 
                next = requested.get(f.name, {})
1433
 
            else:
1434
 
                next = False
1435
 
            if f.null is not None:
1436
 
                new_nullable = f.null
1437
 
            else:
1438
 
                new_nullable = None
1439
 
            for dupe_opts, dupe_col in dupe_set:
1440
 
                self.update_dupe_avoidance(dupe_opts, dupe_col, alias)
1441
 
            self.fill_related_selections(f.rel.to._meta, alias, cur_depth + 1,
1442
 
                    used, next, restricted, new_nullable, dupe_set, avoid)
1443
905
 
1444
906
    def add_aggregate(self, aggregate, model, alias, is_summary):
1445
907
        """
1488
950
            col = field_name
1489
951
 
1490
952
        # Add the aggregate to the query
1491
 
        alias = truncate_name(alias, self.connection.ops.max_name_length())
1492
953
        aggregate.add_to_query(self, alias, col=col, source=source, is_summary=is_summary)
1493
954
 
1494
955
    def add_filter(self, filter_expr, connector=AND, negate=False, trim=False,
1539
1000
                raise ValueError("Cannot use None as a query value")
1540
1001
            lookup_type = 'isnull'
1541
1002
            value = True
1542
 
        elif (value == '' and lookup_type == 'exact' and
1543
 
              connection.features.interprets_empty_strings_as_nulls):
1544
 
            lookup_type = 'isnull'
1545
 
            value = True
1546
1003
        elif callable(value):
1547
1004
            value = value()
1548
1005
        elif hasattr(value, 'evaluate'):
1666
1123
            for child in q_object.children:
1667
1124
                if connector == OR:
1668
1125
                    refcounts_before = self.alias_refcount.copy()
 
1126
                self.where.start_subtree(connector)
1669
1127
                if isinstance(child, Node):
1670
 
                    self.where.start_subtree(connector)
1671
1128
                    self.add_q(child, used_aliases)
1672
 
                    self.where.end_subtree()
1673
1129
                else:
1674
1130
                    self.add_filter(child, connector, q_object.negated,
1675
1131
                            can_reuse=used_aliases)
 
1132
                self.where.end_subtree()
1676
1133
                if connector == OR:
1677
1134
                    # Aliases that were newly added or not used at all need to
1678
1135
                    # be promoted to outer joins if they are nullable relations.
1960
1417
        original exclude filter (filter_expr) and the portion up to the first
1961
1418
        N-to-many relation field.
1962
1419
        """
1963
 
        query = Query(self.model, self.connection)
 
1420
        query = Query(self.model)
1964
1421
        query.add_filter(filter_expr, can_reuse=can_reuse)
1965
1422
        query.bump_prefix()
1966
1423
        query.clear_ordering(True)
2099
1556
        will be made automatically.
2100
1557
        """
2101
1558
        self.group_by = []
2102
 
        if self.connection.features.allows_group_by_pk:
2103
 
            if len(self.select) == len(self.model._meta.fields):
2104
 
                self.group_by.append((self.model._meta.db_table,
2105
 
                                      self.model._meta.pk.column))
2106
 
                return
2107
1559
 
2108
1560
        for sel in self.select:
2109
1561
            self.group_by.append(sel)
2182
1634
                select_pairs[name] = (entry, entry_params)
2183
1635
            # This is order preserving, since self.extra_select is a SortedDict.
2184
1636
            self.extra.update(select_pairs)
2185
 
        if where:
2186
 
            self.extra_where += tuple(where)
2187
 
        if params:
2188
 
            self.extra_params += tuple(params)
 
1637
        if where or params:
 
1638
            self.where.add(ExtraWhere(where, params), AND)
2189
1639
        if tables:
2190
1640
            self.extra_tables += tuple(tables)
2191
1641
        if order_by:
2343
1793
        self.select = [(select_alias, select_col)]
2344
1794
        self.remove_inherited_models()
2345
1795
 
2346
 
    def execute_sql(self, result_type=MULTI):
2347
 
        """
2348
 
        Run the query against the database and returns the result(s). The
2349
 
        return value is a single data item if result_type is SINGLE, or an
2350
 
        iterator over the results if the result_type is MULTI.
2351
 
 
2352
 
        result_type is either MULTI (use fetchmany() to retrieve all rows),
2353
 
        SINGLE (only retrieve a single row), or None. In this last case, the
2354
 
        cursor is returned if any query is executed, since it's used by
2355
 
        subclasses such as InsertQuery). It's possible, however, that no query
2356
 
        is needed, as the filters describe an empty set. In that case, None is
2357
 
        returned, to avoid any unnecessary database interaction.
2358
 
        """
2359
 
        try:
2360
 
            sql, params = self.as_sql()
2361
 
            if not sql:
2362
 
                raise EmptyResultSet
2363
 
        except EmptyResultSet:
2364
 
            if result_type == MULTI:
2365
 
                return empty_iter()
2366
 
            else:
2367
 
                return
2368
 
        cursor = self.connection.cursor()
2369
 
        cursor.execute(sql, params)
2370
 
 
2371
 
        if not result_type:
2372
 
            return cursor
2373
 
        if result_type == SINGLE:
2374
 
            if self.ordering_aliases:
2375
 
                return cursor.fetchone()[:-len(self.ordering_aliases)]
2376
 
            return cursor.fetchone()
2377
 
 
2378
 
        # The MULTI case.
2379
 
        if self.ordering_aliases:
2380
 
            result = order_modified_iter(cursor, len(self.ordering_aliases),
2381
 
                    self.connection.features.empty_fetchmany_value)
2382
 
        else:
2383
 
            result = iter((lambda: cursor.fetchmany(GET_ITERATOR_CHUNK_SIZE)),
2384
 
                    self.connection.features.empty_fetchmany_value)
2385
 
        if not self.connection.features.can_use_chunked_reads:
2386
 
            # If we are using non-chunked reads, we return the same data
2387
 
            # structure as normally, but ensure it is all read into memory
2388
 
            # before going any further.
2389
 
            return list(result)
2390
 
        return result
2391
 
 
2392
 
# Use the backend's custom Query class if it defines one. Otherwise, use the
2393
 
# default.
2394
 
if connection.features.uses_custom_query_class:
2395
 
    Query = connection.ops.query_class(BaseQuery)
2396
 
else:
2397
 
    Query = BaseQuery
2398
1796
 
2399
1797
def get_order_dir(field, default='ASC'):
2400
1798
    """
2409
1807
        return field[1:], dirn[1]
2410
1808
    return field, dirn[0]
2411
1809
 
2412
 
def empty_iter():
2413
 
    """
2414
 
    Returns an iterator containing no results.
2415
 
    """
2416
 
    yield iter([]).next()
2417
 
 
2418
 
def order_modified_iter(cursor, trim, sentinel):
2419
 
    """
2420
 
    Yields blocks of rows from a cursor. We use this iterator in the special
2421
 
    case when extra output columns have been added to support ordering
2422
 
    requirements. We must trim those extra columns before anything else can use
2423
 
    the results, since they're only needed to make the SQL valid.
2424
 
    """
2425
 
    for rows in iter((lambda: cursor.fetchmany(GET_ITERATOR_CHUNK_SIZE)),
2426
 
            sentinel):
2427
 
        yield [r[:-trim] for r in rows]
2428
1810
 
2429
1811
def setup_join_cache(sender, **kwargs):
2430
1812
    """