Opened 10 years ago

Closed 4 years ago

Last modified 4 years ago

#11104 closed Bug (wontfix)

HAVING filter screws with extra() SQL parameter ordering

Reported by: miracle2k Owned by:
Component: Database layer (models, ORM) Version: master
Severity: Normal Keywords: QuerySet.extra
Cc: bas@…, shaunc@… Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no


>>> qs = Model.objects.extra(where=['foo>%s'], params=[2]).annotate(count=Count('bar')).filter(bar=99)
>>> qs.query.as_sql()
('SELECT `site_publication`.`id`, ..., FROM ... WHERE foo > %s GROUP BY ... HAVING bar > %s',
 (99, 2))

As you can see, the parameters (99 and 2) are in the wrong order. "foo", the first filter, should be evaluated against 2, and bar, the second one, against 99.

If "bar" is not an aggregate, it works, because apparently the filter would be placed in the WHERE clause *before* the "extra()" where.

Using rev. 10743.

Attachments (1)

django.db.models.sql.query.diff (804 bytes) - added by paluh 9 years ago.
changing grouping generation from values to keys of extra selects

Download all attachments as: .zip

Change History (14)

comment:1 Changed 10 years ago by Russell Keith-Magee

Triage Stage: UnreviewedAccepted

A related use case, reported in #11117:

    select={'date': "DATE_FORMAT(timestamp, '%s')"}, 
    where=["DATE_FORMAT(timestamp, '%%H:%%i') > '%s'"],

the resulting sql query is:

SELECT DATE_FORMAT(timestamp, '%H') AS `date`, COUNT(id) AS `cnt` 
FROM `books`
WHERE DATE_FORMAT(timestamp, '%H:%i') > '%H' 
GROUP BY DATE_FORMAT(timestamp, '22:00') 
ORDER BY timestamp ASC

The placeholder values '%H' and '22:00' are interchanged, which is obviously a result of using the GROUP BY here on a user-defined variable with placeholder (--> 'date')

comment:2 Changed 10 years ago by Marco Paolini

I think all filters on annotated queryset should end up in HAVING clause, not in WHERE

imagine you want to do something like:

SELECT * FROM blog group by location, rating having count(id) > 10 OR rating >1 

right now (r11199) you can ony add HAVING clauses using if you filter using an aggregate. Does this make sense to you?

comment:3 Changed 9 years ago by Alex Gaynor

#11916 was closed as a dupe of this, it has a patch.

Changed 9 years ago by paluh

changing grouping generation from values to keys of extra selects

comment:4 Changed 9 years ago by paluh

I think that I've found bug related to this ticket. When generating list for grouping values (not keys) are taken from extra selects.

--- django/db/models/sql/	(revision 11729)
+++ django/db/models/sql/	(working copy)
@@ -885,9 +885,9 @@
             group_by = self.group_by or []
             extra_selects = []
-            for extra_select, extra_params in self.extra_select.itervalues():
-                extra_selects.append(extra_select)
-                params.extend(extra_params)
+            for extra_select_key in self.extra_select.iterkeys():
+                extra_selects.append(extra_select_key)
             for col in group_by + self.related_select_cols + extra_selects:
                 if isinstance(col, (list, tuple)):
                     result.append('%s.%s' % (qn(col[0]), qn(col[1])))

comment:5 Changed 9 years ago by paluh

sorry for my previous post and attachment - it's related to #11916 which I've reopened.

comment:6 Changed 9 years ago by anonymous

Cc: bas@… added

comment:7 Changed 9 years ago by Shaun Cutts

Cc: shaunc@… added

comment:8 Changed 8 years ago by Julien Phalip

Severity: Normal
Type: Bug

comment:9 Changed 7 years ago by Aymeric Augustin

UI/UX: unset

Change UI/UX from NULL to False.

comment:10 Changed 7 years ago by Aymeric Augustin

Easy pickings: unset

Change Easy pickings from NULL to False.

comment:11 Changed 6 years ago by Anssi Kääriäinen

Component: ORM aggregationDatabase layer (models, ORM)

comment:12 Changed 4 years ago by Tim Graham

Resolution: wontfix
Status: newclosed

We are no longer fixing bugs with QuerySet.extra() per discussion on django-developers.

comment:13 Changed 4 years ago by Tim Graham

Keywords: QuerySet.extra added
Note: See TracTickets for help on using tickets.
Back to Top