summaryrefslogtreecommitdiff
path: root/django
diff options
context:
space:
mode:
authorMads Jensen <mje@inducks.org>2017-03-17 19:01:25 +0100
committerTim Graham <timograham@gmail.com>2017-03-18 08:12:10 -0400
commit82bb4e684f9d0e5939cb0596c249954df0888e2d (patch)
tree52c5efbb4bd23a159134b3bda654dfcefc6e5098 /django
parent93eca976c15dceaf445ab4739bb2f635a2021db0 (diff)
Fixed #27935 -- Fixed crash with BrinIndex name > 30 characters.
Diffstat (limited to 'django')
-rw-r--r--django/contrib/postgres/indexes.py10
-rw-r--r--django/db/models/indexes.py14
2 files changed, 18 insertions, 6 deletions
diff --git a/django/contrib/postgres/indexes.py b/django/contrib/postgres/indexes.py
index 60578e6c16..feb7053ed8 100644
--- a/django/contrib/postgres/indexes.py
+++ b/django/contrib/postgres/indexes.py
@@ -1,4 +1,6 @@
+from django.db import connection
from django.db.models import Index
+from django.utils.functional import cached_property
__all__ = ['BrinIndex', 'GinIndex']
@@ -34,6 +36,14 @@ class BrinIndex(Index):
schema_editor.quote_value(self.pages_per_range)) + parameters['extra']
return parameters
+ @cached_property
+ def max_name_length(self):
+ # Allow an index name longer than 30 characters since the suffix
+ # is 4 characters (usual limit is 3). Since this index can only be
+ # used on PostgreSQL, the 30 character limit for cross-database
+ # compatibility isn't applicable.
+ return connection.ops.max_name_length()
+
class GinIndex(Index):
suffix = 'gin'
diff --git a/django/db/models/indexes.py b/django/db/models/indexes.py
index 1370463beb..3bb73cf16a 100644
--- a/django/db/models/indexes.py
+++ b/django/db/models/indexes.py
@@ -4,12 +4,12 @@ from django.utils.encoding import force_bytes
__all__ = ['Index']
-# The max length of the names of the indexes (restricted to 30 due to Oracle)
-MAX_NAME_LENGTH = 30
-
class Index:
suffix = 'idx'
+ # The max length of the name of the index (restricted to 30 for
+ # cross-database compatibility with Oracle)
+ max_name_length = 30
def __init__(self, fields=[], name=None):
if not isinstance(fields, list):
@@ -25,8 +25,8 @@ class Index:
self.name = name or ''
if self.name:
errors = self.check_name()
- if len(self.name) > MAX_NAME_LENGTH:
- errors.append('Index names cannot be longer than %s characters.' % MAX_NAME_LENGTH)
+ if len(self.name) > self.max_name_length:
+ errors.append('Index names cannot be longer than %s characters.' % self.max_name_length)
if errors:
raise ValueError(errors)
@@ -100,13 +100,15 @@ class Index:
(('-%s' if order else '%s') % column_name)
for column_name, (field_name, order) in zip(column_names, self.fields_orders)
]
+ # The length of the parts of the name is based on the default max
+ # length of 30 characters.
hash_data = [table_name] + column_names_with_order + [self.suffix]
self.name = '%s_%s_%s' % (
table_name[:11],
column_names[0][:7],
'%s_%s' % (self._hash_generator(*hash_data), self.suffix),
)
- assert len(self.name) <= MAX_NAME_LENGTH, (
+ assert len(self.name) <= self.max_name_length, (
'Index too long for multiple database support. Is self.suffix '
'longer than 3 characters?'
)