#33260: Crash when using query set select_for_update(of=(...)) with exists()
-------------------------------------+-------------------------------------
Reporter: Hannes | Owner: Hannes Ljungberg
Ljungberg |
Type: Bug | Status: assigned
Component: Database | Version: dev
layer (models, ORM) |
Severity: Normal | Keywords:
Triage Stage: | Has patch: 0
Unreviewed |
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-------------------------------------+-------------------------------------
For example specifying `(self,)` as an argument to `of`:
{{{
Person.objects.select_for_update(of=("self",)).exists()
}}}
Will crash with the following traceback:
{{{
Traceback (most recent call last):
File "/tests/django/django/test/testcases.py", line 1305, in
skip_wrapper
return test_func(*args, **kwargs)
File "/tests/django/tests/select_for_update/tests.py", line 599, in
test_select_for_update_with_exists
self.assertIs(Person.objects.select_for_update(of=("self",)).exists(),
True)
File "/tests/django/django/db/models/query.py", line 818, in exists
return self.query.has_results(using=self.db)
File "/tests/django/django/db/models/sql/query.py", line 546, in
has_results
return compiler.has_results()
File "/tests/django/django/db/models/sql/compiler.py", line 1174, in
has_results
return bool(self.execute_sql(SINGLE))
File "/tests/django/django/db/models/sql/compiler.py", line 1191, in
execute_sql
sql, params = self.as_sql()
File "/tests/django/django/db/models/sql/compiler.py", line 612, in
as_sql
of=self.get_select_for_update_of_arguments(),
File "/tests/django/django/db/models/sql/compiler.py", line 1087, in
get_select_for_update_of_arguments
col = _get_first_selected_col_from_model(klass_info)
File "/tests/django/django/db/models/sql/compiler.py", line 1053, in
_get_first_selected_col_from_model
concrete_model = klass_info['model']._meta.concrete_model
TypeError: 'NoneType' object is not subscriptable
}}}
Selecting a related model like:
{{{
Person.objects.select_for_update(of=("born",)).exists()
}}}
Will crash with the following traceback:
{{{
Traceback (most recent call last):
File "/tests/django/django/test/testcases.py", line 1305, in
skip_wrapper
return test_func(*args, **kwargs)
File "/tests/django/tests/select_for_update/tests.py", line 599, in
test_select_for_update_with_exists
self.assertIs(Person.objects.select_for_update(of=("born")).exists(),
True)
File "/tests/django/django/db/models/query.py", line 818, in exists
return self.query.has_results(using=self.db)
File "/tests/django/django/db/models/sql/query.py", line 546, in
has_results
return compiler.has_results()
File "/tests/django/django/db/models/sql/compiler.py", line 1174, in
has_results
return bool(self.execute_sql(SINGLE))
File "/tests/django/django/db/models/sql/compiler.py", line 1191, in
execute_sql
sql, params = self.as_sql()
File "/tests/django/django/db/models/sql/compiler.py", line 612, in
as_sql
of=self.get_select_for_update_of_arguments(),
File "/tests/django/django/db/models/sql/compiler.py", line 1091, in
get_select_for_update_of_arguments
*klass_info.get('related_klass_infos', []),
AttributeError: 'NoneType' object has no attribute 'get'
}}}
With https://code.djangoproject.com/ticket/32888 in consideration we
should probably just drop locking anything as no table columns are
selected.
Thinking something like:
{{{
diff --git a/django/db/models/sql/compiler.py
b/django/db/models/sql/compiler.py
index d1009847e7..7f6251aa34 100644
--- a/django/db/models/sql/compiler.py
+++ b/django/db/models/sql/compiler.py
@@ -1081,6 +1081,8 @@ class SQLCompiler:
invalid_names = []
for name in self.query.select_for_update_of:
klass_info = self.klass_info
+ if not klass_info:
+ continue
if name == 'self':
col = _get_first_selected_col_from_model(klass_info)
else:
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/33260>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/052.5270c831d73fff5db89a530965d16a9e%40djangoproject.com.