Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
D
django
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
Batuhan Osman TASKAYA
django
Commits
3f32154f
Kaydet (Commit)
3f32154f
authored
Mar 08, 2019
tarafından
Simon Charette
Kaydeden (comit)
Tim Graham
Mar 23, 2019
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
Refs #30188 -- Avoided GROUP BY when aggregating over non-aggregates.
üst
d1e9c251
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
16 additions
and
6 deletions
+16
-6
query.py
django/db/models/sql/query.py
+11
-4
tests.py
tests/expressions/tests.py
+5
-2
No files found.
django/db/models/sql/query.py
Dosyayı görüntüle @
3f32154f
...
...
@@ -409,11 +409,11 @@ class Query(BaseExpression):
if
not
self
.
annotation_select
:
return
{}
has_limit
=
self
.
low_mark
!=
0
or
self
.
high_mark
is
not
None
has_existing_annotations
=
any
(
existing_annotations
=
[
annotation
for
alias
,
annotation
in
self
.
annotations
.
items
()
if
alias
not
in
added_aggregate_names
)
]
# Decide if we need to use a subquery.
#
# Existing annotations would cause incorrect results as get_aggregation()
...
...
@@ -425,13 +425,14 @@ class Query(BaseExpression):
# those operations must be done in a subquery so that the query
# aggregates on the limit and/or distinct results instead of applying
# the distinct and limit after the aggregation.
if
(
isinstance
(
self
.
group_by
,
tuple
)
or
has_limit
or
has_
existing_annotations
or
if
(
isinstance
(
self
.
group_by
,
tuple
)
or
has_limit
or
existing_annotations
or
self
.
distinct
or
self
.
combinator
):
from
django.db.models.sql.subqueries
import
AggregateQuery
outer_query
=
AggregateQuery
(
self
.
model
)
inner_query
=
self
.
clone
()
inner_query
.
select_for_update
=
False
inner_query
.
select_related
=
False
inner_query
.
set_annotation_mask
(
self
.
annotation_select
)
if
not
has_limit
and
not
self
.
distinct_fields
:
# Queries with distinct_fields need ordering and when a limit
# is applied we must take the slice from the ordered query.
...
...
@@ -443,7 +444,11 @@ class Query(BaseExpression):
# query is grouped by the main model's primary key. However,
# clearing the select clause can alter results if distinct is
# used.
if
inner_query
.
default_cols
and
has_existing_annotations
:
has_existing_aggregate_annotations
=
any
(
annotation
for
annotation
in
existing_annotations
if
getattr
(
annotation
,
'contains_aggregate'
,
True
)
)
if
inner_query
.
default_cols
and
has_existing_aggregate_annotations
:
inner_query
.
group_by
=
(
self
.
model
.
_meta
.
pk
.
get_col
(
inner_query
.
get_initial_alias
()),)
inner_query
.
default_cols
=
False
...
...
@@ -453,10 +458,12 @@ class Query(BaseExpression):
# and move them to the outer AggregateQuery.
col_cnt
=
0
for
alias
,
expression
in
list
(
inner_query
.
annotation_select
.
items
()):
annotation_select_mask
=
inner_query
.
annotation_select_mask
if
expression
.
is_summary
:
expression
,
col_cnt
=
inner_query
.
rewrite_cols
(
expression
,
col_cnt
)
outer_query
.
annotations
[
alias
]
=
expression
.
relabeled_clone
(
relabels
)
del
inner_query
.
annotations
[
alias
]
annotation_select_mask
.
remove
(
alias
)
# Make sure the annotation_select wont use cached results.
inner_query
.
set_annotation_mask
(
inner_query
.
annotation_select_mask
)
if
inner_query
.
select
==
()
and
not
inner_query
.
default_cols
and
not
inner_query
.
annotation_select_mask
:
...
...
tests/expressions/tests.py
Dosyayı görüntüle @
3f32154f
...
...
@@ -551,7 +551,6 @@ class BasicExpressionsTests(TestCase):
)
self
.
assertEqual
(
qs
.
get
()
.
float
,
1.2
)
@skipUnlessDBFeature
(
'supports_subqueries_in_group_by'
)
def
test_aggregate_subquery_annotation
(
self
):
with
self
.
assertNumQueries
(
1
)
as
ctx
:
aggregate
=
Company
.
objects
.
annotate
(
...
...
@@ -566,7 +565,11 @@ class BasicExpressionsTests(TestCase):
self
.
assertEqual
(
aggregate
,
{
'ceo_salary_gt_20'
:
1
})
# Aggregation over a subquery annotation doesn't annotate the subquery
# twice in the inner query.
self
.
assertLessEqual
(
ctx
.
captured_queries
[
0
][
'sql'
]
.
count
(
'SELECT'
),
4
,)
sql
=
ctx
.
captured_queries
[
0
][
'sql'
]
self
.
assertLessEqual
(
sql
.
count
(
'SELECT'
),
3
)
# GROUP BY isn't required to aggregate over a query that doesn't
# contain nested aggregates.
self
.
assertNotIn
(
'GROUP BY'
,
sql
)
def
test_explicit_output_field
(
self
):
class
FuncA
(
Func
):
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment