#18247 closed Bug (fixed)
Filtering on aggregate annotations with a Decimal value doesn't work
| Reported by: | Owned by: | Michael Tänzer | |
|---|---|---|---|
| Component: | Database layer (models, ORM) | Version: | dev |
| Severity: | Normal | Keywords: | decimal filter annotate having |
| Cc: | zbyte64, dylan@…, Michael Tänzer | Triage Stage: | Ready for checkin |
| Has patch: | yes | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
When I run
$ python manage.py version
1.4
$ python manage.py shell
[...]
>>> for r in StoreBill.objects.annotate( amount = Sum('parts__amount') ).filter( date = '2012-03-28' ): r.amount
...
Decimal('1.05')
>>> for r in StoreBill.objects.annotate( amount = Sum('parts__amount') ).filter( date = '2012-03-28', amount = Decimal("1.05") ): a = r.amount
...
>>> print connection.queries[-1]
{'time': '0.002', 'sql': u'SELECT "spendings_storebill"."id", "spendings_storebill"."name", "spendings_storebill"."date", SUM("spendings_cost"."amount") AS "amount" FROM "spendings_storebill" LEFT OUTER JOIN "spendings_storebillpart" ON ("spendings_storebill"."id" = "spendings_storebillpart"."bill_id") LEFT OUTER JOIN "spendings_cost" ON ("spendings_storebillpart"."cost_ptr_id" = "spendings_cost"."id") WHERE ("spendings_storebill"."date" = 2012-03-28 ) GROUP BY "spendings_storebill"."id", "spendings_storebill"."name", "spendings_storebill"."date" HAVING SUM("spendings_cost"."amount") = 1.05 '}
As you can see from first query there is a result matching second one, yet I get no results for latter. If I run the generated query I get expected result (left only "amount" column):
sqlite> SELECT SUM("spendings_cost"."amount") AS "amount" FROM "spendings_storebill" LEFT OUTER JOIN "spendings_storebillpart" ON ("spendings_storebill"."id" = "spendings_storebillpart"."bill_id") LEFT OUTER JOIN "spendings_cost" ON ("spendings_storebillpart"."cost_ptr_id" = "spendings_cost"."id") GROUP BY "spendings_storebill"."id", "spendings_storebill"."name", "spendings_storebill"."date" HAVING SUM("spendings_cost"."amount") = 1.05 LIMIT 21;
1.05
Change History (18)
comment:1 by , 14 years ago
| Cc: | added |
|---|---|
| Type: | Uncategorized → Bug |
comment:2 by , 14 years ago
| Resolution: | → invalid |
|---|---|
| Status: | new → closed |
I was able to replicate that on just sqlite3 (C API), so it is not a bug with Django or driver.
Marking as invalid, as the bug is outside Django itself.
comment:3 by , 13 years ago
| Resolution: | invalid |
|---|---|
| Status: | closed → reopened |
Per http://article.gmane.org/gmane.comp.db.sqlite.general/75696 , aggregate functions should not have affinity so typecasting Decimal into a string will never have matching values.
I think changing the typecast of Decimal into float is "good enough". Internally, sqlite3 already represents these values as floats so I don't think there would be too detrimental to make it slightly more explicit. Otherwise, we would need separate casting engines depending on whether aggregation is used.
comment:4 by , 13 years ago
| Triage Stage: | Unreviewed → Design decision needed |
|---|
comment:5 by , 13 years ago
| Status: | reopened → new |
|---|
comment:6 by , 13 years ago
| Triage Stage: | Design decision needed → Accepted |
|---|
follow-up: 9 comment:8 by , 12 years ago
| Cc: | added |
|---|---|
| Version: | 1.4 → master |
comment:9 by , 12 years ago
Replying to dylan@…:
As noted in #22117 this is still an issue: https://code.djangoproject.com/ticket/22117#comment:1
comment:10 by , 12 years ago
#22128 asked for the limitation to be documented; I closed it as a duplicate of this. If this bug is wontfix'd, we should then add appropriate warnings on the SQLite-specific notes.
comment:11 by , 10 years ago
| Cc: | added |
|---|---|
| Keywords: | annotate having added |
| Owner: | changed from to |
| Status: | new → assigned |
comment:12 by , 10 years ago
| Has patch: | set |
|---|
On sqlite the SUM() of a decimal column doesn't have a NUMERIC type so when comparing it to a string literal (which a Decimal gets converted to in django) it is not compared as NUMERIC as may be expected but as something else (maybe string?).
I added a CAST to NUMERIC type when using a SQL function that is expected to return a Decimal.
All tests pass under SQLite.
comment:13 by , 10 years ago
| Summary: | filter and Decimal equality doesn't work → Filtering on aggregate annotations with a Decimal value doesn't work |
|---|---|
| Triage Stage: | Accepted → Ready for checkin |
comment:15 by , 9 years ago
Shouldn't this be backported to the current LTS release (1.8) too? The commit seems to cherry-pick cleanly to stable/1.8.x branch.
I believe I have experienced the same issue and it only seems to apply to Django 1.4 with sqlite.