diff options
author | Ian Foote <python@ian.feete.org> | 2017-10-11 22:55:52 +0530 |
---|---|---|
committer | Tim Graham <timograham@gmail.com> | 2018-06-29 17:00:28 -0400 |
commit | 38cada7c94f5f73d2d47a0a730ea5d71d266fa2c (patch) | |
tree | f7cfb69df62a07b0cda4b3c0d1c4a2f6ea5780bf /tests/indexes | |
parent | b4cba4ed625ce7c88675616b3bbb237c28a926d1 (diff) | |
download | django-38cada7c94f5f73d2d47a0a730ea5d71d266fa2c.tar.gz |
Fixed #28077 -- Added support for PostgreSQL opclasses in Index.
Thanks Vinay Karanam for the initial patch.
Diffstat (limited to 'tests/indexes')
-rw-r--r-- | tests/indexes/models.py | 5 | ||||
-rw-r--r-- | tests/indexes/tests.py | 67 |
2 files changed, 66 insertions, 6 deletions
diff --git a/tests/indexes/models.py b/tests/indexes/models.py index 208da32c6e..27bafb9cda 100644 --- a/tests/indexes/models.py +++ b/tests/indexes/models.py @@ -52,3 +52,8 @@ if connection.vendor == 'postgresql': headline = models.CharField(max_length=100, db_index=True) body = models.TextField(db_index=True) slug = models.CharField(max_length=40, unique=True) + + +class IndexedArticle2(models.Model): + headline = models.CharField(max_length=100) + body = models.TextField() diff --git a/tests/indexes/tests.py b/tests/indexes/tests.py index ee2cbd1564..219dfe67b1 100644 --- a/tests/indexes/tests.py +++ b/tests/indexes/tests.py @@ -1,11 +1,14 @@ -from unittest import skipUnless +from unittest import skipIf, skipUnless from django.db import connection +from django.db.models import Index from django.db.models.deletion import CASCADE from django.db.models.fields.related import ForeignKey from django.test import TestCase, TransactionTestCase -from .models import Article, ArticleTranslation, IndexTogetherSingleList +from .models import ( + Article, ArticleTranslation, IndexedArticle2, IndexTogetherSingleList, +) class SchemaIndexesTests(TestCase): @@ -66,8 +69,33 @@ class SchemaIndexesTests(TestCase): index_sql = connection.schema_editor()._model_indexes_sql(IndexTogetherSingleList) self.assertEqual(len(index_sql), 1) - @skipUnless(connection.vendor == 'postgresql', "This is a postgresql-specific issue") - def test_postgresql_text_indexes(self): + +@skipIf(connection.vendor == 'postgresql', 'opclasses are PostgreSQL only') +class SchemaIndexesNotPostgreSQLTests(TransactionTestCase): + available_apps = ['indexes'] + + def test_create_index_ignores_opclasses(self): + index = Index( + name='test_ops_class', + fields=['headline'], + opclasses=['varchar_pattern_ops'], + ) + with connection.schema_editor() as editor: + # This would error if opclasses weren't ingored. + editor.add_index(IndexedArticle2, index) + + +@skipUnless(connection.vendor == 'postgresql', 'PostgreSQL tests') +class SchemaIndexesPostgreSQLTests(TransactionTestCase): + available_apps = ['indexes'] + get_opclass_query = ''' + SELECT opcname, c.relname FROM pg_opclass AS oc + JOIN pg_index as i on oc.oid = ANY(i.indclass) + JOIN pg_class as c on c.oid = i.indexrelid + WHERE c.relname = '%s' + ''' + + def test_text_indexes(self): """Test creation of PostgreSQL-specific text indexes (#12234)""" from .models import IndexedArticle index_sql = [str(statement) for statement in connection.schema_editor()._model_indexes_sql(IndexedArticle)] @@ -78,12 +106,39 @@ class SchemaIndexesTests(TestCase): # index (#19441). self.assertIn('("slug" varchar_pattern_ops)', index_sql[4]) - @skipUnless(connection.vendor == 'postgresql', "This is a postgresql-specific issue") - def test_postgresql_virtual_relation_indexes(self): + def test_virtual_relation_indexes(self): """Test indexes are not created for related objects""" index_sql = connection.schema_editor()._model_indexes_sql(Article) self.assertEqual(len(index_sql), 1) + def test_ops_class(self): + index = Index( + name='test_ops_class', + fields=['headline'], + opclasses=['varchar_pattern_ops'], + ) + with connection.schema_editor() as editor: + editor.add_index(IndexedArticle2, index) + with editor.connection.cursor() as cursor: + cursor.execute(self.get_opclass_query % 'test_ops_class') + self.assertEqual(cursor.fetchall(), [('varchar_pattern_ops', 'test_ops_class')]) + + def test_ops_class_multiple_columns(self): + index = Index( + name='test_ops_class_multiple', + fields=['headline', 'body'], + opclasses=['varchar_pattern_ops', 'text_pattern_ops'], + ) + with connection.schema_editor() as editor: + editor.add_index(IndexedArticle2, index) + with editor.connection.cursor() as cursor: + cursor.execute(self.get_opclass_query % 'test_ops_class_multiple') + expected_ops_classes = ( + ('varchar_pattern_ops', 'test_ops_class_multiple'), + ('text_pattern_ops', 'test_ops_class_multiple'), + ) + self.assertCountEqual(cursor.fetchall(), expected_ops_classes) + @skipUnless(connection.vendor == 'mysql', 'MySQL tests') class SchemaIndexesMySQLTests(TransactionTestCase): |