Ticket #2495: 2495-against-15801.2.diff

File 2495-against-15801.2.diff, 7.9 KB (added by salgado, 4 years ago)
  • tests/regressiontests/bug2495/models.py

     
     1from unittest import TestCase
     2
     3from django.db import models, connection
     4
     5class IndexedTextModel(models.Model):
     6    indexed_text = models.TextField(db_index=True)
     7
     8class 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
  • django/db/backends/postgresql/creation.py

     
    3636            return "WITH ENCODING '%s'" % self.connection.settings_dict['TEST_CHARSET']
    3737        return ''
    3838
    39     def sql_indexes_for_field(self, model, f, style):
    40         if f.db_index and not f.unique:
     39    def compile_sql_index_for_field(self, db_table, f, style, tablespace_sql):
     40        def _get_index_sql(index_name, opclass=''):
    4141            qn = self.connection.ops.quote_name
    42             db_table = model._meta.db_table
    43             tablespace = f.db_tablespace or model._meta.db_tablespace
    44             if tablespace:
    45                 sql = self.connection.ops.tablespace_sql(tablespace)
    46                 if sql:
    47                     tablespace_sql = ' ' + sql
    48                 else:
    49                     tablespace_sql = ''
    50             else:
    51                 tablespace_sql = ''
     42            return (style.SQL_KEYWORD('CREATE INDEX') + ' ' +
     43                    style.SQL_TABLE(qn(truncate_name(
     44                        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)
    5249
    53             def get_index_sql(index_name, opclass=''):
    54                 return (style.SQL_KEYWORD('CREATE INDEX') + ' ' +
    55                         style.SQL_TABLE(qn(truncate_name(index_name,self.connection.ops.max_name_length()))) + ' ' +
    56                         style.SQL_KEYWORD('ON') + ' ' +
    57                         style.SQL_TABLE(qn(db_table)) + ' ' +
    58                         "(%s%s)" % (style.SQL_FIELD(qn(f.column)), opclass) +
    59                         "%s;" % tablespace_sql)
     50        output = [_get_index_sql('%s_%s' % (db_table, f.column))]
    6051
    61             output = [get_index_sql('%s_%s' % (db_table, f.column))]
    62 
    63             # Fields with database column types of `varchar` and `text` need
    64             # a second index that specifies their operator class, which is
    65             # needed when performing correct LIKE queries outside the
    66             # C locale. See #12234.
    67             db_type = f.db_type(connection=self.connection)
    68             if db_type.startswith('varchar'):
    69                 output.append(get_index_sql('%s_%s_like' % (db_table, f.column),
    70                                             ' varchar_pattern_ops'))
    71             elif db_type.startswith('text'):
    72                 output.append(get_index_sql('%s_%s_like' % (db_table, f.column),
    73                                             ' text_pattern_ops'))
    74         else:
    75             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(connection=self.connection)
     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'))
    7663        return output
  • django/db/backends/mysql/creation.py

     
    6363                field.rel.to._meta.db_table, field.rel.to._meta.pk.column)
    6464            ]
    6565        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
  • django/db/backends/creation.py

     
    250250            output.extend(self.sql_indexes_for_field(model, f, style))
    251251        return output
    252252
     253    def compile_sql_index_for_field(self, db_table, f, style, tablespace_sql):
     254        "Compile CREATE INDEX SQL statements for sql_indexes_for_field"
     255        from django.db.backends.util import truncate_name
     256
     257        qn = self.connection.ops.quote_name
     258        index_name = '%s_%s' % (db_table, self._digest(f.column))
     259        return [style.SQL_KEYWORD('CREATE INDEX') + ' ' +
     260                style.SQL_TABLE(qn(truncate_name(index_name, self.connection.ops.max_name_length()))) + ' ' +
     261                style.SQL_KEYWORD('ON') + ' ' +
     262                style.SQL_TABLE(qn(db_table)) + ' ' +
     263                "(%s)" % style.SQL_FIELD(qn(f.column)) +
     264                "%s;" % tablespace_sql]
     265
    253266    def sql_indexes_for_field(self, model, f, style):
    254267        "Return the CREATE INDEX SQL statements for a single model field"
    255         from django.db.backends.util import truncate_name
    256 
    257268        if f.db_index and not f.unique:
    258             qn = self.connection.ops.quote_name
    259269            tablespace = f.db_tablespace or model._meta.db_tablespace
    260270            if tablespace:
    261271                sql = self.connection.ops.tablespace_sql(tablespace)
     
    265275                    tablespace_sql = ''
    266276            else:
    267277                tablespace_sql = ''
    268             i_name = '%s_%s' % (model._meta.db_table, self._digest(f.column))
    269             output = [style.SQL_KEYWORD('CREATE INDEX') + ' ' +
    270                 style.SQL_TABLE(qn(truncate_name(i_name, self.connection.ops.max_name_length()))) + ' ' +
    271                 style.SQL_KEYWORD('ON') + ' ' +
    272                 style.SQL_TABLE(qn(model._meta.db_table)) + ' ' +
    273                 "(%s)" % style.SQL_FIELD(qn(f.column)) +
    274                 "%s;" % tablespace_sql]
     278            output = self.compile_sql_index_for_field(model._meta.db_table, f, style, tablespace_sql)
    275279        else:
    276280            output = []
    277281        return output
Back to Top