summaryrefslogtreecommitdiff
path: root/django/db/backends/postgresql/schema.py
diff options
context:
space:
mode:
authorFederico Frenguelli <synasius@gmail.com>2015-11-07 17:08:03 +0100
committerTim Graham <timograham@gmail.com>2015-12-10 16:12:51 -0500
commit3a36c8079544c83dcdea4e52181efcd2d1e86b9c (patch)
tree22d47c987a2c6738065f7c81572fb6fc5b543d80 /django/db/backends/postgresql/schema.py
parentcf546e11ac76c8dec527e39ff8ce8249a195ab42 (diff)
downloaddjango-3a36c8079544c83dcdea4e52181efcd2d1e86b9c.tar.gz
Fixed #25412 -- Fixed missing PostgreSQL index on Char/TextField when using AlterField.
Thanks to Emanuele Palazzetti for the help.
Diffstat (limited to 'django/db/backends/postgresql/schema.py')
-rw-r--r--django/db/backends/postgresql/schema.py62
1 files changed, 45 insertions, 17 deletions
diff --git a/django/db/backends/postgresql/schema.py b/django/db/backends/postgresql/schema.py
index f34d03ff8c..cc31aadf0a 100644
--- a/django/db/backends/postgresql/schema.py
+++ b/django/db/backends/postgresql/schema.py
@@ -23,25 +23,33 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
return output
for field in model._meta.local_fields:
- db_type = field.db_type(connection=self.connection)
- if db_type is not None and (field.db_index or field.unique):
- # Fields with database column types of `varchar` and `text` need
- # a second index that specifies their operator class, which is
- # needed when performing correct LIKE queries outside the
- # C locale. See #12234.
- #
- # The same doesn't apply to array fields such as varchar[size]
- # and text[size], so skip them.
- if '[' in db_type:
- continue
- if db_type.startswith('varchar'):
- output.append(self._create_index_sql(
- model, [field], suffix='_like', sql=self.sql_create_varchar_index))
- elif db_type.startswith('text'):
- output.append(self._create_index_sql(
- model, [field], suffix='_like', sql=self.sql_create_text_index))
+ like_index_statement = self._create_like_index_sql(model, field)
+ if like_index_statement is not None:
+ output.append(like_index_statement)
return output
+ def _create_like_index_sql(self, model, field):
+ """
+ Return the statement to create an index with varchar operator pattern
+ when the column type is 'varchar' or 'text', otherwise return None.
+ """
+ db_type = field.db_type(connection=self.connection)
+ if db_type is not None and (field.db_index or field.unique):
+ # Fields with database column types of `varchar` and `text` need
+ # a second index that specifies their operator class, which is
+ # needed when performing correct LIKE queries outside the
+ # C locale. See #12234.
+ #
+ # The same doesn't apply to array fields such as varchar[size]
+ # and text[size], so skip them.
+ if '[' in db_type:
+ return None
+ if db_type.startswith('varchar'):
+ return self._create_index_sql(model, [field], suffix='_like', sql=self.sql_create_varchar_index)
+ elif db_type.startswith('text'):
+ return self._create_index_sql(model, [field], suffix='_like', sql=self.sql_create_text_index)
+ return None
+
def _alter_column_type_sql(self, table, old_field, new_field, new_type):
"""
Makes ALTER TYPE with SERIAL make sense.
@@ -94,3 +102,23 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
return super(DatabaseSchemaEditor, self)._alter_column_type_sql(
table, old_field, new_field, new_type
)
+
+ def _alter_field(self, model, old_field, new_field, old_type, new_type,
+ old_db_params, new_db_params, strict=False):
+ super(DatabaseSchemaEditor, self)._alter_field(
+ model, old_field, new_field, old_type, new_type, old_db_params,
+ new_db_params, strict,
+ )
+ # Added an index? Create any PostgreSQL-specific indexes.
+ if ((not old_field.db_index and new_field.db_index) or (not old_field.unique and new_field.unique)):
+ like_index_statement = self._create_like_index_sql(model, new_field)
+ if like_index_statement is not None:
+ self.execute(like_index_statement)
+
+ # Removed an index? Drop any PostgreSQL-specific indexes.
+ if ((not new_field.db_index and old_field.db_index) or (not new_field.unique and old_field.unique)):
+ index_to_remove = self._create_index_name(model, [old_field.column], suffix='_like')
+ index_names = self._constraint_names(model, [old_field.column], index=True)
+ for index_name in index_names:
+ if index_name == index_to_remove:
+ self.execute(self._delete_constraint_sql(self.sql_delete_index, model, index_name))