#30246: Using an annotated field calculated with 
django.db.models.functions.Extract
in aggregate results in ProgrammingError
-------------------------------------+-------------------------------------
     Reporter:  Jan BaryƂa           |                    Owner:  nobody
         Type:  Bug                  |                   Status:  new
    Component:  Database layer       |                  Version:  2.1
  (models, ORM)                      |
     Severity:  Normal               |               Resolution:
     Keywords:  query, aggregate,    |             Triage Stage:  Accepted
  extract, annotate, postgresql      |
    Has patch:  0                    |      Needs documentation:  0
  Needs tests:  0                    |  Patch needs improvement:  0
Easy pickings:  0                    |                    UI/UX:  0
-------------------------------------+-------------------------------------

Comment (by Simon Charette):

 Alright, I think you test assertions are wrong but I got the query
 generated correctly by applying the following patch on top of
 [https://github.com/django/django/pull/11062 my aforementioned PR]

 {{{
 diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py
 index 7ac1b136e9..f61955d53a 100644
 --- a/django/db/models/sql/query.py
 +++ b/django/db/models/sql/query.py
 @@ -379,22 +379,24 @@ class Query(BaseExpression):
                  # before the contains_aggregate/is_summary condition
 below.
                  new_expr, col_cnt = self.rewrite_cols(expr, col_cnt)
                  new_exprs.append(new_expr)
 -            elif isinstance(expr, (Col, Subquery)) or
 (expr.contains_aggregate and not expr.is_summary):
 -                # Reference to column, subquery or another aggregate.
 Make sure
 -                # the expression is selected and reuse its alias if it's
 the case.
 +            else:
                  for col_alias, selected_annotation in
 self.annotation_select.items():
                      if selected_annotation == expr:
 +                        new_expr = Ref(col_alias, expr)
                          break
                  else:
 -                    col_cnt += 1
 -                    col_alias = '__col%d' % col_cnt
 -                    self.annotations[col_alias] = expr
 -                    self.append_annotation_mask([col_alias])
 -                new_exprs.append(Ref(col_alias, expr))
 -            else:
 -                # Some other expression not referencing database values
 -                # directly. Its subexpression might contain Cols.
 -                new_expr, col_cnt = self.rewrite_cols(expr, col_cnt)
 +                    # Reference to column or another aggregate. Make sure
 +                    # the expression is selected and reuse its alias if
 it's the case.
 +                    if isinstance(expr, Col) or (expr.contains_aggregate
 and not expr.is_summary):
 +                        col_cnt += 1
 +                        col_alias = '__col%d' % col_cnt
 +                        self.annotations[col_alias] = expr
 +                        self.append_annotation_mask([col_alias])
 +                        new_expr = Ref(col_alias, expr)
 +                    else:
 +                        # Some other expression not referencing database
 values
 +                        # directly. Its subexpression might contain Cols.
 +                        new_expr, col_cnt = self.rewrite_cols(expr,
 col_cnt)
                  new_exprs.append(new_expr)
          annotation.set_source_expressions(new_exprs)
          return annotation, col_cnt
 }}}

-- 
Ticket URL: <https://code.djangoproject.com/ticket/30246#comment:5>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-updates+unsubscr...@googlegroups.com.
To post to this group, send email to django-updates@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/067.a48abb8b624ae9427efc22327c595ae9%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to