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 | |