commit 645f5dda46705b4c403f2cab0ff634abf92d92d8
Author: Honza Kral <honza.kral@gmail.com>
Date: Thu May 27 17:35:32 2010 +0200
fixed #2495
diff --git a/django/db/backends/creation.py b/django/db/backends/creation.py
index 492ac1e..06df548 100644
|
a
|
b
|
class BaseDatabaseCreation(object):
|
| 253 | 253 | output.extend(self.sql_indexes_for_field(model, f, style)) |
| 254 | 254 | return output |
| 255 | 255 | |
| 256 | | def sql_indexes_for_field(self, model, f, style): |
| 257 | | "Return the CREATE INDEX SQL statements for a single model field" |
| | 256 | def compile_sql_index_for_field(self, db_table, f, style, tablespace_sql): |
| | 257 | "Compile CREATE INDEX SQL statements for sql_indexes_for_field" |
| 258 | 258 | from django.db.backends.util import truncate_name |
| 259 | 259 | |
| | 260 | qn = self.connection.ops.quote_name |
| | 261 | index_name = '%s_%s' % (db_table, self._digest(f.column)) |
| | 262 | return [style.SQL_KEYWORD('CREATE INDEX') + ' ' + |
| | 263 | style.SQL_TABLE(qn(truncate_name(index_name, self.connection.ops.max_name_length()))) + ' ' + |
| | 264 | style.SQL_KEYWORD('ON') + ' ' + |
| | 265 | style.SQL_TABLE(qn(db_table)) + ' ' + |
| | 266 | "(%s)" % style.SQL_FIELD(qn(f.column)) + |
| | 267 | "%s;" % tablespace_sql] |
| | 268 | |
| | 269 | def sql_indexes_for_field(self, model, f, style): |
| | 270 | "Return the CREATE INDEX SQL statements for a single model field" |
| 260 | 271 | if f.db_index and not f.unique: |
| 261 | | qn = self.connection.ops.quote_name |
| 262 | 272 | tablespace = f.db_tablespace or model._meta.db_tablespace |
| 263 | 273 | if tablespace: |
| 264 | 274 | sql = self.connection.ops.tablespace_sql(tablespace) |
| … |
… |
class BaseDatabaseCreation(object):
|
| 268 | 278 | tablespace_sql = '' |
| 269 | 279 | else: |
| 270 | 280 | tablespace_sql = '' |
| 271 | | i_name = '%s_%s' % (model._meta.db_table, self._digest(f.column)) |
| 272 | | output = [style.SQL_KEYWORD('CREATE INDEX') + ' ' + |
| 273 | | style.SQL_TABLE(qn(truncate_name(i_name, self.connection.ops.max_name_length()))) + ' ' + |
| 274 | | style.SQL_KEYWORD('ON') + ' ' + |
| 275 | | style.SQL_TABLE(qn(model._meta.db_table)) + ' ' + |
| 276 | | "(%s)" % style.SQL_FIELD(qn(f.column)) + |
| 277 | | "%s;" % tablespace_sql] |
| | 281 | output = self.compile_sql_index_for_field(model._meta.db_table, f, style, tablespace_sql) |
| 278 | 282 | else: |
| 279 | 283 | output = [] |
| 280 | 284 | return output |
diff --git a/django/db/backends/mysql/creation.py b/django/db/backends/mysql/creation.py
index 8b026a9..a3ef8df 100644
|
a
|
b
|
class DatabaseCreation(BaseDatabaseCreation):
|
| 63 | 63 | field.rel.to._meta.db_table, field.rel.to._meta.pk.column) |
| 64 | 64 | ] |
| 65 | 65 | return table_output, deferred |
| | 66 | |
| | 67 | def compile_sql_index_for_field(self, db_table, f, style, tablespace_sql): |
| | 68 | """ |
| | 69 | Adds a prefix length to the TextField which is currently represented |
| | 70 | by MySQL's 'longtext' type -- which requires a prefix-length parameter |
| | 71 | in order to install an index. |
| | 72 | |
| | 73 | Use largest possible value allowed - 255 characters. |
| | 74 | """ |
| | 75 | from django.db.backends.util import truncate_name |
| | 76 | |
| | 77 | qn = self.connection.ops.quote_name |
| | 78 | index_name = '%s_%s' % (db_table, self._digest(f.column)) |
| | 79 | |
| | 80 | if f.db_type() == self.data_types['TextField']: |
| | 81 | field_name = style.SQL_FIELD(qn(f.column)) + '(255)' |
| | 82 | else: |
| | 83 | field_name = style.SQL_FIELD(qn(f.column)) |
| | 84 | |
| | 85 | return [style.SQL_KEYWORD('CREATE INDEX') + ' ' + |
| | 86 | style.SQL_TABLE(qn(truncate_name(index_name, self.connection.ops.max_name_length()))) + ' ' + |
| | 87 | style.SQL_KEYWORD('ON') + ' ' + |
| | 88 | style.SQL_TABLE(qn(db_table)) + ' ' + |
| | 89 | "(%s)" % field_name + |
| | 90 | "%s;" % tablespace_sql] |
| | 91 | |
diff --git a/django/db/backends/postgresql/creation.py b/django/db/backends/postgresql/creation.py
index af26d0b..3db1506 100644
|
a
|
b
|
class DatabaseCreation(BaseDatabaseCreation):
|
| 35 | 35 | return "WITH ENCODING '%s'" % self.connection.settings_dict['TEST_CHARSET'] |
| 36 | 36 | return '' |
| 37 | 37 | |
| 38 | | def sql_indexes_for_field(self, model, f, style): |
| 39 | | if f.db_index and not f.unique: |
| 40 | | qn = self.connection.ops.quote_name |
| 41 | | db_table = model._meta.db_table |
| 42 | | tablespace = f.db_tablespace or model._meta.db_tablespace |
| 43 | | if tablespace: |
| 44 | | sql = self.connection.ops.tablespace_sql(tablespace) |
| 45 | | if sql: |
| 46 | | tablespace_sql = ' ' + sql |
| 47 | | else: |
| 48 | | tablespace_sql = '' |
| 49 | | else: |
| 50 | | tablespace_sql = '' |
| | 38 | def compile_sql_index_for_field(self, db_table, f, style, tablespace_sql): |
| | 39 | def _get_index_sql(index_name, opclass=''): |
| | 40 | from django.db.backends.util import truncate_name |
| 51 | 41 | |
| 52 | | def get_index_sql(index_name, opclass=''): |
| 53 | | return (style.SQL_KEYWORD('CREATE INDEX') + ' ' + |
| 54 | | style.SQL_TABLE(qn(index_name)) + ' ' + |
| 55 | | style.SQL_KEYWORD('ON') + ' ' + |
| 56 | | style.SQL_TABLE(qn(db_table)) + ' ' + |
| 57 | | "(%s%s)" % (style.SQL_FIELD(qn(f.column)), opclass) + |
| 58 | | "%s;" % tablespace_sql) |
| | 42 | qn = self.connection.ops.quote_name |
| | 43 | return (style.SQL_KEYWORD('CREATE INDEX') + ' ' + |
| | 44 | style.SQL_TABLE(qn(truncate_name(index_name, self.connection.ops.max_name_length()))) + ' ' + |
| | 45 | style.SQL_KEYWORD('ON') + ' ' + |
| | 46 | style.SQL_TABLE(qn(db_table)) + ' ' + |
| | 47 | "(%s%s)" % (style.SQL_FIELD(qn(f.column)), opclass) + |
| | 48 | "%s;" % tablespace_sql) |
| 59 | 49 | |
| 60 | | output = [get_index_sql('%s_%s' % (db_table, f.column))] |
| | 50 | output = [_get_index_sql('%s_%s' % (db_table, f.column))] |
| 61 | 51 | |
| 62 | | # Fields with database column types of `varchar` and `text` need |
| 63 | | # a second index that specifies their operator class, which is |
| 64 | | # needed when performing correct LIKE queries outside the |
| 65 | | # C locale. See #12234. |
| 66 | | db_type = f.db_type() |
| 67 | | if db_type.startswith('varchar'): |
| 68 | | output.append(get_index_sql('%s_%s_like' % (db_table, f.column), |
| 69 | | ' varchar_pattern_ops')) |
| 70 | | elif db_type.startswith('text'): |
| 71 | | output.append(get_index_sql('%s_%s_like' % (db_table, f.column), |
| 72 | | ' text_pattern_ops')) |
| 73 | | else: |
| 74 | | output = [] |
| | 52 | # Fields with database column types of `varchar` and `text` need |
| | 53 | # a second index that specifies their operator class, which is |
| | 54 | # needed when performing correct LIKE queries outside the |
| | 55 | # C locale. See #12234. |
| | 56 | db_type = f.db_type() |
| | 57 | if db_type.startswith('varchar'): |
| | 58 | output.append(_get_index_sql('%s_%s_like' % (db_table, f.column), |
| | 59 | ' varchar_pattern_ops')) |
| | 60 | elif db_type.startswith('text'): |
| | 61 | output.append(_get_index_sql('%s_%s_like' % (db_table, f.column), |
| | 62 | ' text_pattern_ops')) |
| 75 | 63 | return output |
diff --git a/tests/regressiontests/bug2495/__init__.py b/tests/regressiontests/bug2495/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/tests/regressiontests/bug2495/models.py b/tests/regressiontests/bug2495/models.py
new file mode 100644
index 0000000..91661b3
|
-
|
+
|
|
| | 1 | from unittest import TestCase |
| | 2 | |
| | 3 | from django.db import models, connection |
| | 4 | |
| | 5 | class IndexedTextModel(models.Model): |
| | 6 | indexed_text = models.TextField(db_index=True) |
| | 7 | |
| | 8 | class TestTextFieldIndices(TestCase): |
| | 9 | def test_indexed_text_has_an_index(self): |
| | 10 | try: |
| | 11 | indexes = connection.introspection.get_indexes(connection.cursor(), IndexedTextModel._meta.db_table) |
| | 12 | except NotImplementedError: |
| | 13 | indexes = {} |
| | 14 | assert 'indexed_text' in indexes |
| | 15 | |