mirror of
				https://github.com/django/django.git
				synced 2025-10-31 09:41:08 +00:00 
			
		
		
		
	Fixed #12234 -- Create additional indexes that use the appropriate operation class for PostgreSQL varchar and text columns when db_index=True.
				
					
				
			git-svn-id: http://code.djangoproject.com/svn/django/trunk@11912 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
		| @@ -35,3 +35,42 @@ class DatabaseCreation(BaseDatabaseCreation): | ||||
|         if settings.TEST_DATABASE_CHARSET: | ||||
|             return "WITH ENCODING '%s'" % settings.TEST_DATABASE_CHARSET | ||||
|         return '' | ||||
|  | ||||
|     def sql_indexes_for_field(self, model, f, style): | ||||
|         if f.db_index and not f.unique: | ||||
|             qn = self.connection.ops.quote_name | ||||
|             db_table = model._meta.db_table | ||||
|             tablespace = f.db_tablespace or model._meta.db_tablespace | ||||
|             if tablespace: | ||||
|                 sql = self.connection.ops.tablespace_sql(tablespace) | ||||
|                 if sql: | ||||
|                     tablespace_sql = ' ' + sql | ||||
|                 else: | ||||
|                     tablespace_sql = '' | ||||
|             else: | ||||
|                 tablespace_sql = '' | ||||
|  | ||||
|             def get_index_sql(index_name, opclass=''): | ||||
|                 return (style.SQL_KEYWORD('CREATE INDEX') + ' ' + | ||||
|                         style.SQL_TABLE(qn(index_name)) + ' ' + | ||||
|                         style.SQL_KEYWORD('ON') + ' ' + | ||||
|                         style.SQL_TABLE(qn(db_table)) + ' ' + | ||||
|                         "(%s%s)" % (style.SQL_FIELD(qn(f.column)), opclass) + | ||||
|                         "%s;" % tablespace_sql) | ||||
|  | ||||
|             output = [get_index_sql('%s_%s' % (db_table, f.column))] | ||||
|  | ||||
|             # 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. | ||||
|             db_type = f.db_type() | ||||
|             if db_type.startswith('varchar'): | ||||
|                 output.append(get_index_sql('%s_%s_like' % (db_table, f.column), | ||||
|                                             ' varchar_pattern_ops')) | ||||
|             elif db_type.startswith('text'): | ||||
|                 output.append(get_index_sql('%s_%s_like' % (db_table, f.column), | ||||
|                                             ' text_pattern_ops')) | ||||
|         else: | ||||
|             output = [] | ||||
|         return output | ||||
|   | ||||
| @@ -80,6 +80,21 @@ You should also audit your existing code for any instances of this behavior | ||||
| before enabling this feature. It's faster, but it provides less automatic | ||||
| protection for multi-call operations. | ||||
|  | ||||
| Indexes for ``varchar`` and ``text`` columns | ||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
| .. versionadded:: 1.1.2 | ||||
|  | ||||
| When specifying ``db_index=True`` on your model fields, Django typically | ||||
| outputs a single ``CREATE INDEX`` statement.  However, if the database type | ||||
| for the field is either ``varchar`` or ``text`` (e.g., used by ``CharField``, | ||||
| ``FileField``, and ``TextField``), then Django will create | ||||
| an additional index that uses an appropriate `PostgreSQL operator class`_ | ||||
| for the column.  The extra index is necessary to correctly perfrom | ||||
| lookups that use the ``LIKE`` operator in their SQL, as is done with the | ||||
| ``contains`` and ``startswith`` lookup types. | ||||
|  | ||||
| .. _PostgreSQL operator class: http://www.postgresql.org/docs/8.4/static/indexes-opclass.html | ||||
|  | ||||
| .. _mysql-notes: | ||||
|  | ||||
| MySQL notes | ||||
|   | ||||
		Reference in New Issue
	
	Block a user