From 3f76d1402dac9c2993d588f996dc1c331edbc9a7 Mon Sep 17 00:00:00 2001
From: Jon Dufresne <jon.dufresne@gmail.com>
Date: Fri, 15 Jul 2016 07:34:37 -0700
Subject: [PATCH] Refs #26889 -- Refactored SchemaEditor to allow backend
 specific indexes.

---
 django/db/backends/base/schema.py       | 15 +++++++++++----
 django/db/backends/postgresql/schema.py | 16 +++-------------
 tests/indexes/tests.py                  |  2 +-
 3 files changed, 15 insertions(+), 18 deletions(-)

diff --git a/django/db/backends/base/schema.py b/django/db/backends/base/schema.py
index 63775c981b..b936b61fb8 100644
--- a/django/db/backends/base/schema.py
+++ b/django/db/backends/base/schema.py
@@ -430,8 +430,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._create_index_sql(model, [field]))
+        self.deferred_sql.extend(self._field_indexes_sql(model, field))
         # Add any FK constraints later
         if field.remote_field 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"))
@@ -897,14 +896,22 @@ class BaseDatabaseSchemaEditor(object):
             return []
         output = []
         for field in model._meta.local_fields:
-            if self._field_should_be_indexed(model, field):
-                output.append(self._create_index_sql(model, [field], suffix=""))
+            output.extend(self._field_indexes_sql(model, field))
 
         for field_names in model._meta.index_together:
             fields = [model._meta.get_field(field) for field in field_names]
             output.append(self._create_index_sql(model, fields, suffix="_idx"))
         return output
 
+    def _field_indexes_sql(self, model, field):
+        """
+        Return a list of all index SQL statements for the specified field.
+        """
+        output = []
+        if self._field_should_be_indexed(model, field):
+            output.append(self._create_index_sql(model, [field]))
+        return output
+
     def _field_should_be_indexed(self, model, field):
         return field.db_index and not field.unique
 
diff --git a/django/db/backends/postgresql/schema.py b/django/db/backends/postgresql/schema.py
index c21c35c815..16f2003196 100644
--- a/django/db/backends/postgresql/schema.py
+++ b/django/db/backends/postgresql/schema.py
@@ -17,21 +17,11 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
     def quote_value(self, value):
         return psycopg2.extensions.adapt(value)
 
-    def add_field(self, model, field):
-        super(DatabaseSchemaEditor, self).add_field(model, field)
+    def _field_indexes_sql(self, model, field):
+        output = super(DatabaseSchemaEditor, self)._field_indexes_sql(model, field)
         like_index_statement = self._create_like_index_sql(model, field)
         if like_index_statement is not None:
-            self.deferred_sql.append(like_index_statement)
-
-    def _model_indexes_sql(self, model):
-        output = super(DatabaseSchemaEditor, self)._model_indexes_sql(model)
-        if not model._meta.managed or model._meta.proxy or model._meta.swapped:
-            return output
-
-        for field in model._meta.local_fields:
-            like_index_statement = self._create_like_index_sql(model, field)
-            if like_index_statement is not None:
-                output.append(like_index_statement)
+            output.append(like_index_statement)
         return output
 
     def _create_like_index_sql(self, model, field):
diff --git a/tests/indexes/tests.py b/tests/indexes/tests.py
index dfc503e15d..4bd2332674 100644
--- a/tests/indexes/tests.py
+++ b/tests/indexes/tests.py
@@ -46,7 +46,7 @@ class SchemaIndexesTests(TestCase):
         from .models import IndexedArticle
         index_sql = connection.schema_editor()._model_indexes_sql(IndexedArticle)
         self.assertEqual(len(index_sql), 5)
-        self.assertIn('("headline" varchar_pattern_ops)', index_sql[2])
+        self.assertIn('("headline" varchar_pattern_ops)', index_sql[1])
         self.assertIn('("body" text_pattern_ops)', index_sql[3])
         # unique=True and db_index=True should only create the varchar-specific
         # index (#19441).