mirror of
https://github.com/django/django.git
synced 2025-10-26 15:16:09 +00:00
Fixed #25412 -- Fixed missing PostgreSQL index on Char/TextField when using AlterField.
Thanks to Emanuele Palazzetti for the help.
This commit is contained in:
committed by
Tim Graham
parent
cf546e11ac
commit
3a36c80795
@@ -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))
|
||||
|
||||
Reference in New Issue
Block a user