Django

Code

Ticket #5223 (closed: fixed)

Opened 1 year ago

Last modified 7 months ago

Bug on sqlite __year comparison

Reported by: Manuel Saelices <msaelices@yaco.es> Assigned to: nobody
Milestone: Component: Database wrapper
Version: SVN Keywords: sqlite orm sq-rf sprintsept14
Cc: Triage Stage: Accepted
Has patch: 1 Needs documentation: 0
Needs tests: 1 Patch needs improvement: 0

Description

This code:

  >>> from myapp.models import FooModel
  >>> FooModel.objects.filter(pub_date__year=2007)

produces this SQL:

SELECT "myapp_foomodel"."id", ... FROM "myapp_foomodel" WHERE ("myapp_foomodel"."pub_date" BETWEEN '2006-01-01 00:00:00' AND '2006-12-31 23:59:59.999999');

but I think sqlite doesn't support this notation (at least in sqlite 3.3.5). It prefers something like that:

SELECT "myapp_foomodel"."id", ... FROM "myapp_foomodel" WHERE ("myapp_foomodel"."pub_date" BETWEEN '2006-01-01' AND '2006-12-31');

I've attached a patch that fixes this bug.

Attachments

sqlite_year_lookup_fix.diff (0.7 kB) - added by Manuel Saelices <msaelices@yaco.es> on 08/21/07 11:25:26.
A patch that fixes sqlite year lookup
tests_report_07_09_16.log (203.9 kB) - added by msaelices on 09/16/07 04:58:15.
sqlite_year.diff (1.3 kB) - added by raminf on 09/16/07 13:46:15.
I started working on this during the sprint and was trying to be more conservative to avoid problems with other backends. Thought I'd go ahead and toss it in as an alternative.
test.diff (1.1 kB) - added by Doug Van Horn on 12/06/07 09:55:30.
Adds a test to identify the problem.

Change History

08/21/07 11:25:26 changed by Manuel Saelices <msaelices@yaco.es>

  • attachment sqlite_year_lookup_fix.diff added.

A patch that fixes sqlite year lookup

08/21/07 21:26:44 changed by mtredinnick

  • needs_better_patch changed.
  • summary changed from [patch] Bug on sqlite __year comparison to Bug on sqlite __year comparison.
  • needs_tests changed.
  • needs_docs changed.

09/02/07 18:25:44 changed by SmileyChris

  • needs_tests set to 1.
  • stage changed from Unreviewed to Accepted.

(follow-up: ↓ 4 ) 09/11/07 08:25:37 changed by jarek.zgoda@gmail.com

Shouldn't the format modifier after converting to int (line 512) to be %d, not %s on line 515?

(in reply to: ↑ 3 ) 09/11/07 10:00:43 changed by Manuel Saelices <msaelices@yaco.es>

Replying to jarek.zgoda@gmail.com:

Shouldn't the format modifier after converting to int (line 512) to be %d, not %s on line 515?

Maybe, but I cut code from base classes, and I think it was for a reason

09/11/07 13:41:50 changed by Jarek Zgoda <jarek.zgoda@gmail.com>

For no apparent reason. Python does str() on the int object in such case so this doesn't end with ValueError?.

09/13/07 16:44:22 changed by mtredinnick

  • keywords changed from sqlite orm to sqlite orm, sq-rf.

09/15/07 05:48:03 changed by Fredrik Lundh <fredrik@pythonware.com>

  • keywords changed from sqlite orm, sq-rf to sqlite orm sq-rf sprintsept14.
  • stage changed from Accepted to Ready for checkin.

09/15/07 10:39:21 changed by Fredrik Lundh <fredrik@pythonware.com>

  • stage changed from Ready for checkin to Accepted.

Pulling this back; not clear if we can repeat this without the patch on current trunk, really.

09/15/07 10:52:43 changed by Fredrik Lundh <fredrik@pythonware.com>

msaelices, it looks as if your suggested patch breaks the standard test suite under sqlite 3.4.X, in the current trunk. I cannot seem to repeat that with sqlite 3.3.X (I've tested both 3.3.4 and 3.3.7), but I cannot seem to repeat your bug either :-(

If you still have access to 3.3.5, can you check what the standard "basic" test, if used with and without your patch:

./runtests.py --settings ... basic

09/15/07 11:03:07 changed by anonymous

Ok I'll try with sqlite 3.3.5

09/15/07 17:54:41 changed by msaelices

I run all tests with sqlite 3.3.5 with this command:

  ./runtests.py

The result is patch doesn't break any tests. There are seven tests failed but no from django.db.

(follow-ups: ↓ 13 ↓ 15 ) 09/15/07 20:21:25 changed by mtredinnick

Firstly, there should be no tests failing. Otherwise you might be having other problems.

Secondly, do any extra tests (particularly the "basic" one -- just run that on its own as Fredrik indicated) fail when you do not have the patch in place?

The problem we are trying to work through is that without this patch, we can't get the existing tests to fail on the SQLite version Fredrik and I have tried, so it isn't clear that this is fixing a real problem. It may turn out to be tied to some particular bug in 3.3.5, in which case that's going to be hard cheese for users of 3.3.5. Or it might be something else, but right now, we don't have a clear demonstration of something that fails before the patch is applied and then starts working afterwards.

(in reply to: ↑ 12 ; follow-up: ↓ 14 ) 09/16/07 04:56:51 changed by anonymous

Replying to mtredinnick:

Firstly, there should be no tests failing. Otherwise you might be having other problems.

Ok. I consider it's a Django problem, because many failed tests refers (I think) to have differents locales that people that usually runs all tests (things like Expected: July, Got: Julio. Other fails test refer to new file session backend, and I've considered as usual in a sprint like this, with many changes in a little time.

It's another question, but I attached this tests report on this ticket.

Secondly, do any extra tests (particularly the "basic" one -- just run that on its own as Fredrik indicated) fail when you do not have the patch in place?

Here I know that you said to locate patch lines in another situation Field.get_db_prep_lookup. But, I thought previous comments of failing tests was made with my patch and possibly location doesn't matter. Sorry If I was wrong.

The problem we are trying to work through is that without this patch, we can't get the existing tests to fail on the SQLite version Fredrik and I have tried, so it isn't clear that this is fixing a real problem. It may turn out to be tied to some particular bug in 3.3.5, in which case that's going to be hard cheese for users of 3.3.5. Or it might be something else, but right now, we don't have a clear demonstration of something that fails before the patch is applied and then starts working afterwards.

(in reply to: ↑ 13 ) 09/16/07 04:57:42 changed by msaelices

Sorry, I havent logged before posting my comment

Replying to anonymous:

Replying to mtredinnick:

Firstly, there should be no tests failing. Otherwise you might be having other problems.

Ok. I consider it's a Django problem, because many failed tests refers (I think) to have differents locales that people that usually runs all tests (things like Expected: July, Got: Julio. Other fails test refer to new file session backend, and I've considered as usual in a sprint like this, with many changes in a little time. It's another question, but I attached this tests report on this ticket.

Secondly, do any extra tests (particularly the "basic" one -- just run that on its own as Fredrik indicated) fail when you do not have the patch in place?

Here I know that you said to locate patch lines in another situation Field.get_db_prep_lookup. But, I thought previous comments of failing tests was made with my patch and possibly location doesn't matter. Sorry If I was wrong.

The problem we are trying to work through is that without this patch, we can't get the existing tests to fail on the SQLite version Fredrik and I have tried, so it isn't clear that this is fixing a real problem. It may turn out to be tied to some particular bug in 3.3.5, in which case that's going to be hard cheese for users of 3.3.5. Or it might be something else, but right now, we don't have a clear demonstration of something that fails before the patch is applied and then starts working afterwards.

09/16/07 04:58:15 changed by msaelices

  • attachment tests_report_07_09_16.log added.

09/16/07 13:46:15 changed by raminf

  • attachment sqlite_year.diff added.

I started working on this during the sprint and was trying to be more conservative to avoid problems with other backends. Thought I'd go ahead and toss it in as an alternative.

(in reply to: ↑ 12 ) 12/06/07 09:54:54 changed by Doug Van Horn

Replying to mtredinnick:

Firstly, there should be no tests failing. Otherwise you might be having other problems. Secondly, do any extra tests (particularly the "basic" one -- just run that on its own as Fredrik indicated) fail when you do not have the patch in place? The problem we are trying to work through is that without this patch, we can't get the existing tests to fail on the SQLite version Fredrik and I have tried, so it isn't clear that this is fixing a real problem. It may turn out to be tied to some particular bug in 3.3.5, in which case that's going to be hard cheese for users of 3.3.5. Or it might be something else, but right now, we don't have a clear demonstration of something that fails before the patch is applied and then starts working afterwards.

I posted a duplicate of this problem and my own patches at #6141. The issue here is that when you store a date in SQLite, it's being stored as a string:

sqlite> create table foo( d date null );
sqlite> insert into foo(d) values( '2008-01-01' );
sqlite> select d, typeof(d) from foo;
2008-01-01|text

See the SQLite documentation and my post to the SQLite forum.

Since dates are stored as text in SQLite and '2008-01-01' is lexigraphicly less than '2008-01-01 00:00:00', the record in question falls outside the bounds of the query.

No tests are failing because they're not testing the problem, which lies with 'date' columns in SQLite, not datetime columns. I'm attaching a patch call test.diff that will expose the problem when run against SQLite. It patches tests/modeltests/basic/models.py, adding a class and a test at the bottom of the file.

Hope this helps clarify why this is a problem on SQLite.

12/06/07 09:55:30 changed by Doug Van Horn

  • attachment test.diff added.

Adds a test to identify the problem.

02/23/08 02:36:41 changed by mtredinnick

  • status changed from new to closed.
  • resolution set to fixed.

(In [7150]) Fixed #3689, #5223 -- Fixed "1st of January" comparisons for SQLite without breaking the other backends.

Based on a patch from raminf and tests from Nebojsa Djordjevic.


Add/Change #5223 (Bug on sqlite __year comparison)




Change Properties
Action