Opened 12 years ago
Closed 12 years ago
#20002 closed Bug (fixed)
Model inheritance depth may result in invalid SQL queries
Reported by: | Owned by: | nobody | |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 1.5 |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
This is an example pulled out of the test case I was writing as a baseline for something kind of crazy, and on 1.4 to boot.
Using
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': None, } }
for settings (to get an in-memory database for tests), and the following models:
class A(Model): subcontent_type = models.ForeignKey(ContentType, null=True, related_name='+', editable=False) objects = Manager() def __unicode__(self): return unicode(self.pk) class Meta: ordering = ('pk',) class B(A): pass class C(B): pass class D(C): pass
The following test case fails at evaluating D:
from django.test import TestCase as DjangoTestCase class PolymorphTestCase(DjangoTestCase): def setUp(self): self.objects = [A.objects.create(), B.objects.create(), C.objects.create(), D.objects.create(), C.objects.create(), B.objects.create()] def test_default_manager(self): with self.assertNumQueries(4): all = list(A.objects.all()) self.assertEqual(all, [ A(pk=1), A(pk=2), A(pk=3), A(pk=4), A(pk=5), A(pk=6), ]) all = list(B.objects.all()) self.assertEqual(all, [ B(pk=2), B(pk=3), B(pk=4), B(pk=5), B(pk=6), ]) all = list(C.objects.all()) self.assertEqual(all, [C(pk=3), C(pk=4), C(pk=5)]) import pdb; pdb.set_trace() all = list(D.objects.all()) self.assertEqual(all, [D(pk=4)])
The stack trace is:
Traceback (most recent call last): File "/path/to/tests.py", line 411, in test_default_manager all = list(D.objects.all()) File "/path/python2.7/site-packages/Django-1.4.5-py2.7.egg/django/db/models/query.py", line 87, in __len__ self._result_cache.extend(self._iter) File "/path/python2.7/site-packages/Django-1.4.5-py2.7.egg/django/db/models/query.py", line 291, in iterator for row in compiler.results_iter(): File "/path/python2.7/site-packages/Django-1.4.5-py2.7.egg/django/db/models/sql/compiler.py", line 763, in results_iter for rows in self.execute_sql(MULTI): File "/path/python2.7/site-packages/Django-1.4.5-py2.7.egg/django/db/models/sql/compiler.py", line 818, in execute_sql cursor.execute(sql, params) File "/path/python2.7/site-packages/Django-1.4.5-py2.7.egg/django/db/backends/util.py", line 40, in execute return self.cursor.execute(sql, params) File "/path/python2.7/site-packages/Django-1.4.5-py2.7.egg/django/db/backends/sqlite3/base.py", line 344, in execute return Database.Cursor.execute(self, query, params) DatabaseError: no such column: T5.a_ptr_id
the query used for D.objects.all() is:
'SELECT "testmodel_a"."id", "testmodel_a"."subcontent_type_id", "testmodel_b"."a_ptr_id", "testmodel_c"."b_ptr_id", "testmodel_d"."c_ptr_id" FROM "testmodel_d" INNER JOIN "testmodel_a" ON ("testmodel_d"."c_ptr_id" = "testmodel_a"."id") INNER JOIN "testmodel_b" ON ("testmodel_d"."c_ptr_id" = "testmodel_b"."a_ptr_id") INNER JOIN "testmodel_c" ON ("testmodel_d"."c_ptr_id" = "testmodel_c"."b_ptr_id") INNER JOIN "testmodel_a" T6 ON (T5."a_ptr_id" = T6."id") ORDER BY "testmodel_d"."c_ptr_id" ASC'
I had a look at the model_inheritance tests, and couldn't see any that were testing to the depth I'm doing there, so either I'm doing something wrong, SQlite is (as always) being a pain, or the tests may not go far enough.
Change History (2)
comment:1 by , 12 years ago
Version: | 1.4 → 1.5 |
---|
comment:2 by , 12 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
Thanks for attempting to reproduce with master. Indeed there's been some cleanup in this area.
Our policy is to close bugs that aren't reproducible on master, but of course feel free to re-open if you find a variant that isn't addressed yet!
I've since tested this on 1.5 and 1.6 (master at 477d737e1e6bdf93950c8a381906925c594fac2f)
Looking around Trac, I'd guess tickets #16572 and #13781 were probably where the underlying problem got fixed.
I'm not sure if there are tests for the depth I've demonstrated in 1.6, so there might be value in doing so, but otherwise, I think this can be marked as invalid/duplicate/shutup-its-fixed.