mirror of
				https://github.com/django/django.git
				synced 2025-10-31 09:41:08 +00:00 
			
		
		
		
	Fixed #5087 -- Fixed support for TextField filtering with Oracle. Thanks, Ian Kelly.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@5943 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
		| @@ -181,6 +181,12 @@ def get_date_trunc_sql(lookup_type, field_name): | |||||||
| def get_datetime_cast_sql(): | def get_datetime_cast_sql(): | ||||||
|     return "TO_TIMESTAMP(%s, 'YYYY-MM-DD HH24:MI:SS.FF')" |     return "TO_TIMESTAMP(%s, 'YYYY-MM-DD HH24:MI:SS.FF')" | ||||||
|  |  | ||||||
|  | def get_field_cast_sql(db_type): | ||||||
|  |     if db_type.endswith('LOB'): | ||||||
|  |         return "DBMS_LOB.SUBSTR(%s%s)" | ||||||
|  |     else: | ||||||
|  |         return "%s%s" | ||||||
|  |  | ||||||
| def get_limit_offset_sql(limit, offset=None): | def get_limit_offset_sql(limit, offset=None): | ||||||
|     # Limits and offset are too complicated to be handled here. |     # Limits and offset are too complicated to be handled here. | ||||||
|     # Instead, they are handled in django/db/backends/oracle/query.py. |     # Instead, they are handled in django/db/backends/oracle/query.py. | ||||||
|   | |||||||
| @@ -777,7 +777,7 @@ class QNot(Q): | |||||||
|             return SortedDict(), [], [] |             return SortedDict(), [], [] | ||||||
|         return joins, where2, params |         return joins, where2, params | ||||||
|  |  | ||||||
| def get_where_clause(lookup_type, table_prefix, field_name, value): | def get_where_clause(lookup_type, table_prefix, field_name, value, db_type): | ||||||
|     if table_prefix.endswith('.'): |     if table_prefix.endswith('.'): | ||||||
|         table_prefix = backend.quote_name(table_prefix[:-1])+'.' |         table_prefix = backend.quote_name(table_prefix[:-1])+'.' | ||||||
|     field_name = backend.quote_name(field_name) |     field_name = backend.quote_name(field_name) | ||||||
| @@ -785,36 +785,41 @@ def get_where_clause(lookup_type, table_prefix, field_name, value): | |||||||
|         cast_sql = backend.get_datetime_cast_sql() |         cast_sql = backend.get_datetime_cast_sql() | ||||||
|     else: |     else: | ||||||
|         cast_sql = '%s' |         cast_sql = '%s' | ||||||
|     if lookup_type in ('iexact', 'icontains', 'istartswith', 'iendswith') and backend.needs_upper_for_iops: |     if db_type and hasattr(backend, 'get_field_cast_sql'): | ||||||
|         format = 'UPPER(%s%s) %s' |         field_cast_sql = backend.get_field_cast_sql(db_type) | ||||||
|     else: |     else: | ||||||
|         format = '%s%s %s' |         field_cast_sql = '%s%s' | ||||||
|  |     field_sql = field_cast_sql % (table_prefix, field_name) | ||||||
|  |     if lookup_type in ('iexact', 'icontains', 'istartswith', 'iendswith') and backend.needs_upper_for_iops: | ||||||
|  |         format = 'UPPER(%s) %s' | ||||||
|  |     else: | ||||||
|  |         format = '%s %s' | ||||||
|     try: |     try: | ||||||
|         return format % (table_prefix, field_name, |         return format % (field_sql, | ||||||
|                          backend.OPERATOR_MAPPING[lookup_type] % cast_sql) |                          backend.OPERATOR_MAPPING[lookup_type] % cast_sql) | ||||||
|     except KeyError: |     except KeyError: | ||||||
|         pass |         pass | ||||||
|     if lookup_type == 'in': |     if lookup_type == 'in': | ||||||
|         in_string = ','.join(['%s' for id in value]) |         in_string = ','.join(['%s' for id in value]) | ||||||
|         if in_string: |         if in_string: | ||||||
|             return '%s%s IN (%s)' % (table_prefix, field_name, in_string) |             return '%s IN (%s)' % (field_sql, in_string) | ||||||
|         else: |         else: | ||||||
|             raise EmptyResultSet |             raise EmptyResultSet | ||||||
|     elif lookup_type in ('range', 'year'): |     elif lookup_type in ('range', 'year'): | ||||||
|         return '%s%s BETWEEN %%s AND %%s' % (table_prefix, field_name) |         return '%s BETWEEN %%s AND %%s' % field_sql | ||||||
|     elif lookup_type in ('month', 'day'): |     elif lookup_type in ('month', 'day'): | ||||||
|         return "%s = %%s" % backend.get_date_extract_sql(lookup_type, table_prefix + field_name) |         return "%s = %%s" % backend.get_date_extract_sql(lookup_type, field_sql) | ||||||
|     elif lookup_type == 'isnull': |     elif lookup_type == 'isnull': | ||||||
|         return "%s%s IS %sNULL" % (table_prefix, field_name, (not value and 'NOT ' or '')) |         return "%s IS %sNULL" % (field_sql, (not value and 'NOT ' or '')) | ||||||
|     elif lookup_type == 'search': |     elif lookup_type == 'search': | ||||||
|         return backend.get_fulltext_search_sql(table_prefix + field_name) |         return backend.get_fulltext_search_sql(field_sql) | ||||||
|     elif lookup_type in ('regex', 'iregex'): |     elif lookup_type in ('regex', 'iregex'): | ||||||
|         if settings.DATABASE_ENGINE == 'oracle': |         if settings.DATABASE_ENGINE == 'oracle': | ||||||
|             if lookup_type == 'regex': |             if lookup_type == 'regex': | ||||||
|                 match_option = 'c' |                 match_option = 'c' | ||||||
|             else: |             else: | ||||||
|                 match_option = 'i' |                 match_option = 'i' | ||||||
|             return "REGEXP_LIKE(%s%s, %s, '%s')" % (table_prefix, field_name, cast_sql, match_option) |             return "REGEXP_LIKE(%s, %s, '%s')" % (field_sql, cast_sql, match_option) | ||||||
|         else: |         else: | ||||||
|             raise NotImplementedError |             raise NotImplementedError | ||||||
|     raise TypeError, "Got invalid lookup_type: %s" % repr(lookup_type) |     raise TypeError, "Got invalid lookup_type: %s" % repr(lookup_type) | ||||||
| @@ -1071,6 +1076,7 @@ def lookup_inner(path, lookup_type, value, opts, table, column): | |||||||
|     else: |     else: | ||||||
|         # No elements left in path. Current element is the element on which |         # No elements left in path. Current element is the element on which | ||||||
|         # the search is being performed. |         # the search is being performed. | ||||||
|  |         db_type = None | ||||||
|  |  | ||||||
|         if join_required: |         if join_required: | ||||||
|             # Last query term is a RelatedObject |             # Last query term is a RelatedObject | ||||||
| @@ -1100,8 +1106,9 @@ def lookup_inner(path, lookup_type, value, opts, table, column): | |||||||
|         else: |         else: | ||||||
|             # Last query term was a normal field. |             # Last query term was a normal field. | ||||||
|             column = field.column |             column = field.column | ||||||
|  |             db_type = field.db_type() | ||||||
|  |  | ||||||
|         where.append(get_where_clause(lookup_type, current_table + '.', column, value)) |         where.append(get_where_clause(lookup_type, current_table + '.', column, value, db_type)) | ||||||
|         params.extend(field.get_db_prep_lookup(lookup_type, value)) |         params.extend(field.get_db_prep_lookup(lookup_type, value)) | ||||||
|  |  | ||||||
|     return joins, where, params |     return joins, where, params | ||||||
|   | |||||||
| @@ -36,6 +36,13 @@ class Base(models.Model): | |||||||
|     def __unicode__(self): |     def __unicode__(self): | ||||||
|         return "Base %s" % self.name |         return "Base %s" % self.name | ||||||
|  |  | ||||||
|  | class Article(models.Model): | ||||||
|  |     name = models.CharField(maxlength = 50) | ||||||
|  |     text = models.TextField() | ||||||
|  |  | ||||||
|  |     def __str__(self): | ||||||
|  |         return "Article %s" % self.name | ||||||
|  |  | ||||||
| __test__ = {'API_TESTS': ur""" | __test__ = {'API_TESTS': ur""" | ||||||
| # Regression test for #1661 and #1662: Check that string form referencing of | # Regression test for #1661 and #1662: Check that string form referencing of | ||||||
| # models works, both as pre and post reference, on all RelatedField types. | # models works, both as pre and post reference, on all RelatedField types. | ||||||
| @@ -82,4 +89,13 @@ __test__ = {'API_TESTS': ur""" | |||||||
| # We can also do the above query using UTF-8 strings. | # We can also do the above query using UTF-8 strings. | ||||||
| >>> Foo.objects.get(friend__contains='\xc3\xa7') | >>> Foo.objects.get(friend__contains='\xc3\xa7') | ||||||
| <Foo: Foo Bjorn> | <Foo: Foo Bjorn> | ||||||
|  |  | ||||||
|  | # Regression tests for #5087: make sure we can perform queries on TextFields. | ||||||
|  | >>> a = Article(name='Test', text='The quick brown fox jumps over the lazy dog.') | ||||||
|  | >>> a.save() | ||||||
|  | >>> Article.objects.get(text__exact='The quick brown fox jumps over the lazy dog.') | ||||||
|  | <Article: Article Test> | ||||||
|  |  | ||||||
|  | >>> Article.objects.get(text__contains='quick brown fox') | ||||||
|  | <Article: Article Test> | ||||||
| """} | """} | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user