#21643 closed Bug (fixed)
QuerySets that use F() + timedelta() crash when compiling their query more than once
Reported by: | Owned by: | nobody | |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 1.6 |
Severity: | Normal | Keywords: | |
Cc: | 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
Attachments (2)
Change History (14)
by , 11 years ago
Attachment: | fix_ftimedelta_querysets.patch added |
---|
comment:1 by , 11 years ago
Needs tests: | set |
---|
comment:2 by , 11 years ago
Needs tests: | unset |
---|---|
Triage Stage: | Unreviewed → Ready for checkin |
Verified the test and the rest of the test suite on SQlite.
comment:4 by , 11 years ago
I've thought about that, but then the datetime value gets put in the query the second time (and incorrectly) in evaluate_node. There's probably a better way to do this, but I'm not exactly knowledgeable enough about Django internals to figure it out. The patch attached works as a quick-and-easy fix.
comment:6 by , 11 years ago
OK, good enough for me. Is this a regression in 1.6 or has this bug existed for a longer time (that is, does this need to be backpatched to 1.6)?
comment:7 by , 11 years ago
Google seems to find reports of the error from way back in December 2011. The code in question hasn't been touched since it appeared with the introduction of support for F() + timedelta(). Looks like it's been this way for years.
comment:8 by , 11 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
comment:9 by , 11 years ago
This is a regression in 1.6, I believe due to the deep copy changes when cloning querysets. I confirmed that F() + timedelta()
does work in 1.5.
Previously, the DateModifierNode
expression would have been deep copied every time a queryset was cloned, so it would never have been evaluated twice.
So I think this should be backported.
Also #22101 was a duplicate.
comment:10 by , 11 years ago
The test from the fix already applied also fails in 1.5, but the following test passes in 1.5 and fails in 1.6 showing that this is a regression.
def test_query_clone(self): # Ticket #21643 qs = Experiment.objects.filter(end__lt=F('start') + datetime.timedelta(hours=1)) qs2 = qs.all() list(qs) list(qs2)
Is it enough to back port the existing commit, or should this new test also be committed and back ported?
Could you write a regression test that demonstrates the problem and proves it's fixed?