Commit f46a1661 authored by Claude Paroz's avatar Claude Paroz
Browse files

[1.7.x] Fixed #24015 -- Factorized create_index_sql expression

Backport of 6072f17d from master, with one test reinforced.
Thanks Tim Graham for the review.
parent 2f13a48f
Loading
Loading
Loading
Loading
+8 −25
Original line number Diff line number Diff line
@@ -322,14 +322,9 @@ class BaseDatabaseSchemaEditor(object):
                ))
            self.execute(self._delete_constraint_sql(self.sql_delete_index, model, constraint_names[0]))
        # Created indexes
        for fields in news.difference(olds):
            columns = [model._meta.get_field_by_name(field)[0].column for field in fields]
            self.execute(self.sql_create_index % {
                "table": self.quote_name(model._meta.db_table),
                "name": self._create_index_name(model, columns, suffix="_idx"),
                "columns": ", ".join(self.quote_name(column) for column in columns),
                "extra": "",
            })
        for field_names in news.difference(olds):
            fields = [model._meta.get_field_by_name(field)[0] for field in field_names]
            self.execute(self._create_index_sql(model, fields, suffix="_idx"))

    def alter_db_table(self, model, old_db_table, new_db_table):
        """
@@ -389,14 +384,7 @@ class BaseDatabaseSchemaEditor(object):
            self.execute(sql)
        # Add an index, if required
        if field.db_index and not field.unique:
            self.deferred_sql.append(
                self.sql_create_index % {
                    "name": self._create_index_name(model, [field.column], suffix=""),
                    "table": self.quote_name(model._meta.db_table),
                    "columns": self.quote_name(field.column),
                    "extra": "",
                }
            )
            self.deferred_sql.append(self._create_index_sql(model, [field]))
        # Add any FK constraints later
        if field.rel and self.connection.features.supports_foreign_keys and field.db_constraint:
            self.deferred_sql.append(self._create_fk_sql(model, field, "_fk_%(to_table)s_%(to_column)s"))
@@ -637,15 +625,10 @@ class BaseDatabaseSchemaEditor(object):
        if not old_field.unique and new_field.unique:
            self.execute(self._create_unique_sql(model, [new_field.column]))
        # Added an index?
        if not old_field.db_index and new_field.db_index and not new_field.unique and not (not old_field.unique and new_field.unique):
            self.execute(
                self.sql_create_index % {
                    "table": self.quote_name(model._meta.db_table),
                    "name": self._create_index_name(model, [new_field.column], suffix="_uniq"),
                    "columns": self.quote_name(new_field.column),
                    "extra": "",
                }
            )
        if (not old_field.db_index and new_field.db_index and
                not new_field.unique and not
                (not old_field.unique and new_field.unique)):
            self.execute(self._create_index_sql(model, [new_field], suffix="_uniq"))
        # Type alteration on primary key? Then we need to alter the column
        # referring to us.
        rels_to_update = []
+3 −0
Original line number Diff line number Diff line
@@ -155,3 +155,6 @@ Bugfixes
* Ensured the app registry is fully populated when unpickling models. When an
  external script (like a queueing infrastructure) reloads pickled models, it
  could crash with an ``AppRegistryNotReady`` exception (:ticket:`24007`).

* Added quoting to field indexes in the SQL generated by migrations to prevent
  a crash when the index name requires it (:ticket:`#24015`).
+9 −1
Original line number Diff line number Diff line
@@ -46,8 +46,16 @@ class SchemaIndexesTests(TestCase):
    Test index handling by the db.backends.schema infrastructure.
    """
    def test_index_together(self):
        index_sql = connection.schema_editor()._model_indexes_sql(Article)
        editor = connection.schema_editor()
        index_sql = editor._model_indexes_sql(Article)
        self.assertEqual(len(index_sql), 1)
        # Ensure the index name is properly quoted
        self.assertIn(
            connection.ops.quote_name(
                editor._create_index_name(Article, ['headline', 'pub_date'], suffix='_idx')
            ),
            index_sql[0]
        )

    def test_index_together_single_list(self):
        # Test for using index_together with a single list (#22172)