Commit 19e5cd77 authored by Joel Bohman's avatar Joel Bohman Committed by Tim Graham
Browse files

Fixed #21497 -- Forced conversion to bytes for very long index names

parent f88e7608
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -123,6 +123,7 @@ answer newbie questions, and generally made Django that much better:
    David Blewett <david@dawninglight.net>
    Artem Gnilov <boobsd@gmail.com>
    Eric Boersma <eric.boersma@gmail.com>
    Joel Bohman <mail@jbohman.com>
    Matías Bordese
    Nate Bragg <jonathan.bragg@alum.rpi.edu>
    Sean Brant
+2 −1
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@ from django.db.backends.creation import BaseDatabaseCreation
from django.db.backends.utils import truncate_name
from django.db.models.fields.related import ManyToManyField
from django.db.transaction import atomic
from django.utils.encoding import force_bytes
from django.utils.log import getLogger
from django.utils.six.moves import reduce
from django.utils.six import callable
@@ -703,7 +704,7 @@ class BaseDatabaseSchemaEditor(object):
            index_name = index_name[1:]
        # If it's STILL too long, just hash it down
        if len(index_name) > self.connection.features.max_index_name_length:
            index_name = hashlib.md5(index_name).hexdigest()[:self.connection.features.max_index_name_length]
            index_name = hashlib.md5(force_bytes(index_name)).hexdigest()[:self.connection.features.max_index_name_length]
        # It can't start with a number on Oracle, so prepend D if we need to
        if index_name[0].isdigit():
            index_name = "D%s" % index_name[:-1]
+7 −0
Original line number Diff line number Diff line
@@ -95,3 +95,10 @@ class UniqueTest(models.Model):
    class Meta:
        app_cache = new_app_cache
        unique_together = ["year", "slug"]


class BookWithLongName(models.Model):
    author_foreign_key_with_really_long_field_name = models.ForeignKey(Author)

    class Meta:
        app_cache = new_app_cache
+22 −2
Original line number Diff line number Diff line
@@ -7,7 +7,9 @@ from django.db import connection, DatabaseError, IntegrityError
from django.db.models.fields import IntegerField, TextField, CharField, SlugField
from django.db.models.fields.related import ManyToManyField, ForeignKey
from django.db.transaction import atomic
from .models import Author, AuthorWithM2M, Book, BookWithSlug, BookWithM2M, Tag, TagIndexed, TagM2MTest, TagUniqueRename, UniqueTest
from .models import (Author, AuthorWithM2M, Book, BookWithLongName,
    BookWithSlug, BookWithM2M, Tag, TagIndexed, TagM2MTest, TagUniqueRename,
    UniqueTest)


class SchemaTests(TransactionTestCase):
@@ -21,7 +23,10 @@ class SchemaTests(TransactionTestCase):

    available_apps = []

    models = [Author, AuthorWithM2M, Book, BookWithSlug, BookWithM2M, Tag, TagIndexed, TagM2MTest, TagUniqueRename, UniqueTest]
    models = [
        Author, AuthorWithM2M, Book, BookWithLongName, BookWithSlug,
        BookWithM2M, Tag, TagIndexed, TagM2MTest, TagUniqueRename, UniqueTest,
    ]

    # Utility functions

@@ -659,3 +664,18 @@ class SchemaTests(TransactionTestCase):
                raise SomeError
        except SomeError:
            self.assertFalse(connection.in_atomic_block)

    def test_foreign_key_index_long_names_regression(self):
        """
        Regression test for #21497. Only affects databases that supports
        foreign keys.
        """
        # Create the table
        with connection.schema_editor() as editor:
            editor.create_model(Author)
            editor.create_model(BookWithLongName)
        # Ensure the table is there and has the right index
        self.assertIn(
            "author_foreign_key_with_really_long_field_name_id",
            connection.introspection.get_indexes(connection.cursor(), BookWithLongName._meta.db_table),
        )