#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 django-updates+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/django-updates/052.5270c831d73fff5db89a530965d16a9e%40djangoproject.com.