Refs #25809, #28990 -- Added PostgreSQL version check for BrinIndex support.

This commit is contained in:
Nick Pope 2017-12-05 09:15:22 +00:00 committed by Tim Graham
parent 6b4d1ec8ff
commit ff9543b351
2 changed files with 33 additions and 0 deletions

View File

@ -1,4 +1,5 @@
from django.db.models import Index from django.db.models import Index
from django.db.utils import NotSupportedError
from django.utils.functional import cached_property from django.utils.functional import cached_property
__all__ = [ __all__ = [
@ -18,6 +19,7 @@ class PostgresIndex(Index):
return Index.max_name_length - len(Index.suffix) + len(self.suffix) return Index.max_name_length - len(Index.suffix) + len(self.suffix)
def create_sql(self, model, schema_editor, using=''): def create_sql(self, model, schema_editor, using=''):
self.check_supported(schema_editor)
statement = super().create_sql(model, schema_editor, using=' USING %s' % self.suffix) statement = super().create_sql(model, schema_editor, using=' USING %s' % self.suffix)
with_params = self.get_with_params() with_params = self.get_with_params()
if with_params: if with_params:
@ -27,6 +29,9 @@ class PostgresIndex(Index):
) )
return statement return statement
def check_supported(self, schema_editor):
pass
def get_with_params(self): def get_with_params(self):
return [] return []
@ -49,6 +54,12 @@ class BrinIndex(PostgresIndex):
kwargs['pages_per_range'] = self.pages_per_range kwargs['pages_per_range'] = self.pages_per_range
return path, args, kwargs return path, args, kwargs
def check_supported(self, schema_editor):
if not schema_editor.connection.features.has_brin_index_support:
raise NotSupportedError('BRIN indexes require PostgreSQL 9.5+.')
if self.autosummarize and not schema_editor.connection.features.has_brin_autosummarize:
raise NotSupportedError('BRIN option autosummarize requires PostgreSQL 10+.')
def get_with_params(self): def get_with_params(self):
with_params = [] with_params = []
if self.autosummarize is not None: if self.autosummarize is not None:

View File

@ -1,7 +1,10 @@
from unittest import mock
from django.contrib.postgres.indexes import ( from django.contrib.postgres.indexes import (
BrinIndex, BTreeIndex, GinIndex, GistIndex, HashIndex, SpGistIndex, BrinIndex, BTreeIndex, GinIndex, GistIndex, HashIndex, SpGistIndex,
) )
from django.db import connection from django.db import connection
from django.db.utils import NotSupportedError
from django.test import skipUnlessDBFeature from django.test import skipUnlessDBFeature
from . import PostgreSQLTestCase from . import PostgreSQLTestCase
@ -208,6 +211,25 @@ class SchemaTests(PostgreSQLTestCase):
editor.remove_index(CharFieldModel, index) editor.remove_index(CharFieldModel, index)
self.assertNotIn(index_name, self.get_constraints(CharFieldModel._meta.db_table)) self.assertNotIn(index_name, self.get_constraints(CharFieldModel._meta.db_table))
def test_brin_index_not_supported(self):
index_name = 'brin_index_exception'
index = BrinIndex(fields=['field'], name=index_name)
with self.assertRaisesMessage(NotSupportedError, 'BRIN indexes require PostgreSQL 9.5+.'):
with mock.patch('django.db.connection.features.has_brin_index_support', False):
with connection.schema_editor() as editor:
editor.add_index(CharFieldModel, index)
self.assertNotIn(index_name, self.get_constraints(CharFieldModel._meta.db_table))
@skipUnlessDBFeature('has_brin_index_support')
def test_brin_autosummarize_not_supported(self):
index_name = 'brin_options_exception'
index = BrinIndex(fields=['field'], name=index_name, autosummarize=True)
with self.assertRaisesMessage(NotSupportedError, 'BRIN option autosummarize requires PostgreSQL 10+.'):
with mock.patch('django.db.connection.features.has_brin_autosummarize', False):
with connection.schema_editor() as editor:
editor.add_index(CharFieldModel, index)
self.assertNotIn(index_name, self.get_constraints(CharFieldModel._meta.db_table))
def test_btree_index(self): def test_btree_index(self):
# Ensure the table is there and doesn't have an index. # Ensure the table is there and doesn't have an index.
self.assertNotIn('field', self.get_constraints(CharFieldModel._meta.db_table)) self.assertNotIn('field', self.get_constraints(CharFieldModel._meta.db_table))