Commit d5c7f9ef authored by Anssi Kääriäinen's avatar Anssi Kääriäinen
Browse files

Fixed #18304 -- Optimized save() when update_can_self_select=False

Databases with update_can_self_select = False (MySQL for example)
generated non-necessary queries when saving a multitable inherited
model, and when the save resulted in update.
parent 6219591f
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -1015,6 +1015,12 @@ class SQLUpdateCompiler(SQLCompiler):
        query.extra = {}
        query.select = []
        query.add_fields([query.model._meta.pk.name])
        # Recheck the count - it is possible that fiddling with the select
        # fields above removes tables from the query. Refs #18304.
        count = query.count_active_tables()
        if not self.query.related_updates and count == 1:
            return

        must_pre_select = count > 1 and not self.connection.features.update_can_self_select

        # Now we adjust the current query: reset the where clause and get rid
+18 −0
Original line number Diff line number Diff line
@@ -275,3 +275,21 @@ class ModelInheritanceTests(TestCase):
    def test_mixin_init(self):
        m = MixinModel()
        self.assertEqual(m.other_attr, 1)

    def test_update_query_counts(self):
        """
        Test that update queries do not generate non-necessary queries.
        Refs #18304.
        """
        c = Chef.objects.create(name="Albert")
        ir = ItalianRestaurant.objects.create(
            name="Ristorante Miron",
            address="1234 W. Ash",
            serves_hot_dogs=False,
            serves_pizza=False,
            serves_gnocchi=True,
            rating=4,
            chef=c
        )
        with self.assertNumQueries(6):
            ir.save()
+1 −4
Original line number Diff line number Diff line
from __future__ import absolute_import

from django.test import TestCase, skipUnlessDBFeature
from django.test import TestCase
from django.db.models.signals import pre_save, post_save
from .models import Person, Employee, ProxyEmployee, Profile, Account

@@ -123,9 +123,6 @@ class UpdateOnlyFieldsTests(TestCase):
        self.assertEqual(len(pre_save_data), 0)
        self.assertEqual(len(post_save_data), 0)

    # A bug in SQLUpdateCompiler prevents this test from succeeding on MySQL
    # Require update_can_self_select for this test for now. Refs #18304.
    @skipUnlessDBFeature('update_can_self_select')
    def test_num_queries_inheritance(self):
        s = Employee.objects.create(name='Sara', gender='F')
        s.employee_num = 1