Fixed #28944 -- Fixed crash when chaining values()/values_list() after QuerySet.select_for_update(of=()).
This commit is contained in:
parent
5778b5701d
commit
c21f158295
|
@ -190,7 +190,7 @@ class SQLCompiler:
|
||||||
"AS alias" for the column (possibly None).
|
"AS alias" for the column (possibly None).
|
||||||
|
|
||||||
The klass_info structure contains the following information:
|
The klass_info structure contains the following information:
|
||||||
- Which model to instantiate
|
- The base model of the query.
|
||||||
- Which columns for that model are present in the query (by
|
- Which columns for that model are present in the query (by
|
||||||
position of the select clause).
|
position of the select clause).
|
||||||
- related_klass_infos: [f, klass_info] to descent into
|
- related_klass_infos: [f, klass_info] to descent into
|
||||||
|
@ -207,20 +207,21 @@ class SQLCompiler:
|
||||||
select_idx += 1
|
select_idx += 1
|
||||||
assert not (self.query.select and self.query.default_cols)
|
assert not (self.query.select and self.query.default_cols)
|
||||||
if self.query.default_cols:
|
if self.query.default_cols:
|
||||||
|
cols = self.get_default_columns()
|
||||||
|
else:
|
||||||
|
# self.query.select is a special case. These columns never go to
|
||||||
|
# any model.
|
||||||
|
cols = self.query.select
|
||||||
|
if cols:
|
||||||
select_list = []
|
select_list = []
|
||||||
for c in self.get_default_columns():
|
for col in cols:
|
||||||
select_list.append(select_idx)
|
select_list.append(select_idx)
|
||||||
select.append((c, None))
|
select.append((col, None))
|
||||||
select_idx += 1
|
select_idx += 1
|
||||||
klass_info = {
|
klass_info = {
|
||||||
'model': self.query.model,
|
'model': self.query.model,
|
||||||
'select_fields': select_list,
|
'select_fields': select_list,
|
||||||
}
|
}
|
||||||
# self.query.select is a special case. These columns never go to
|
|
||||||
# any model.
|
|
||||||
for col in self.query.select:
|
|
||||||
select.append((col, None))
|
|
||||||
select_idx += 1
|
|
||||||
for alias, annotation in self.query.annotation_select.items():
|
for alias, annotation in self.query.annotation_select.items():
|
||||||
annotations[alias] = select_idx
|
annotations[alias] = select_idx
|
||||||
select.append((annotation, alias))
|
select.append((annotation, alias))
|
||||||
|
|
|
@ -37,3 +37,6 @@ Bugfixes
|
||||||
|
|
||||||
* Fixed crash on SQLite when renaming a field in a model referenced by a
|
* Fixed crash on SQLite when renaming a field in a model referenced by a
|
||||||
``ManyToManyField`` (:ticket:`28884`).
|
``ManyToManyField`` (:ticket:`28884`).
|
||||||
|
|
||||||
|
* Fixed a crash when chaining ``values()`` or ``values_list()`` after
|
||||||
|
``QuerySet.select_for_update(of=(...))`` (:ticket:`28944`).
|
||||||
|
|
|
@ -120,6 +120,28 @@ class SelectForUpdateTests(TransactionTestCase):
|
||||||
expected = [value.upper() for value in expected]
|
expected = [value.upper() for value in expected]
|
||||||
self.assertTrue(self.has_for_update_sql(ctx.captured_queries, of=expected))
|
self.assertTrue(self.has_for_update_sql(ctx.captured_queries, of=expected))
|
||||||
|
|
||||||
|
@skipUnlessDBFeature('has_select_for_update_of')
|
||||||
|
def test_for_update_of_followed_by_values(self):
|
||||||
|
with transaction.atomic():
|
||||||
|
values = list(Person.objects.select_for_update(of=('self',)).values('pk'))
|
||||||
|
self.assertEqual(values, [{'pk': self.person.pk}])
|
||||||
|
|
||||||
|
@skipUnlessDBFeature('has_select_for_update_of')
|
||||||
|
def test_for_update_of_followed_by_values_list(self):
|
||||||
|
with transaction.atomic():
|
||||||
|
values = list(Person.objects.select_for_update(of=('self',)).values_list('pk'))
|
||||||
|
self.assertEqual(values, [(self.person.pk,)])
|
||||||
|
|
||||||
|
@skipUnlessDBFeature('has_select_for_update_of')
|
||||||
|
def test_for_update_of_self_when_self_is_not_selected(self):
|
||||||
|
"""
|
||||||
|
select_for_update(of=['self']) when the only columns selected are from
|
||||||
|
related tables.
|
||||||
|
"""
|
||||||
|
with transaction.atomic():
|
||||||
|
values = list(Person.objects.select_related('born').select_for_update(of=('self',)).values('born__name'))
|
||||||
|
self.assertEqual(values, [{'born__name': self.city1.name}])
|
||||||
|
|
||||||
@skipUnlessDBFeature('has_select_for_update_nowait')
|
@skipUnlessDBFeature('has_select_for_update_nowait')
|
||||||
def test_nowait_raises_error_on_block(self):
|
def test_nowait_raises_error_on_block(self):
|
||||||
"""
|
"""
|
||||||
|
|
Loading…
Reference in New Issue