Code

Ticket #5087: oracle_textfield_lookup.2.diff

File oracle_textfield_lookup.2.diff, 5.4 KB (added by ian.g.kelly@…, 7 years ago)

New version that doesn't break everything -- I should know better than to submit patches when I don't have a test environment available

Line 
1Index: django/db/models/query.py
2===================================================================
3--- django/db/models/query.py   (revision 5821)
4+++ django/db/models/query.py   (working copy)
5@@ -777,7 +777,7 @@
6             return SortedDict(), [], []
7         return joins, where2, params
8 
9-def get_where_clause(lookup_type, table_prefix, field_name, value):
10+def get_where_clause(lookup_type, table_prefix, field_name, value, db_type):
11     if table_prefix.endswith('.'):
12         table_prefix = backend.quote_name(table_prefix[:-1])+'.'
13     field_name = backend.quote_name(field_name)
14@@ -785,36 +785,41 @@
15         cast_sql = backend.get_datetime_cast_sql()
16     else:
17         cast_sql = '%s'
18+    if db_type and hasattr(backend, 'get_field_cast_sql'):
19+        field_cast_sql = backend.get_field_cast_sql(db_type)
20+    else:
21+        field_cast_sql = '%s%s'
22+    field_sql = field_cast_sql % (table_prefix, field_name)
23     if lookup_type in ('iexact', 'icontains', 'istartswith', 'iendswith') and backend.needs_upper_for_iops:
24-        format = 'UPPER(%s%s) %s'
25+        format = 'UPPER(%s) %s'
26     else:
27-        format = '%s%s %s'
28+        format = '%s %s'
29     try:
30-        return format % (table_prefix, field_name,
31+        return format % (field_sql,
32                          backend.OPERATOR_MAPPING[lookup_type] % cast_sql)
33     except KeyError:
34         pass
35     if lookup_type == 'in':
36         in_string = ','.join(['%s' for id in value])
37         if in_string:
38-            return '%s%s IN (%s)' % (table_prefix, field_name, in_string)
39+            return '%s IN (%s)' % (field_sql, in_string)
40         else:
41             raise EmptyResultSet
42     elif lookup_type in ('range', 'year'):
43-        return '%s%s BETWEEN %%s AND %%s' % (table_prefix, field_name)
44+        return '%s BETWEEN %%s AND %%s' % field_sql
45     elif lookup_type in ('month', 'day'):
46-        return "%s = %%s" % backend.get_date_extract_sql(lookup_type, table_prefix + field_name)
47+        return "%s = %%s" % backend.get_date_extract_sql(lookup_type, field_sql)
48     elif lookup_type == 'isnull':
49-        return "%s%s IS %sNULL" % (table_prefix, field_name, (not value and 'NOT ' or ''))
50+        return "%s IS %sNULL" % (field_sql, (not value and 'NOT ' or ''))
51     elif lookup_type == 'search':
52-        return backend.get_fulltext_search_sql(table_prefix + field_name)
53+        return backend.get_fulltext_search_sql(field_sql)
54     elif lookup_type in ('regex', 'iregex'):
55         if settings.DATABASE_ENGINE == 'oracle':
56             if lookup_type == 'regex':
57                 match_option = 'c'
58             else:
59                 match_option = 'i'
60-            return "REGEXP_LIKE(%s%s, %s, '%s')" % (table_prefix, field_name, cast_sql, match_option)
61+            return "REGEXP_LIKE(%s, %s, '%s')" % (field_sql, cast_sql, match_option)
62         else:
63             raise NotImplementedError
64     raise TypeError, "Got invalid lookup_type: %s" % repr(lookup_type)
65@@ -1071,6 +1076,7 @@
66     else:
67         # No elements left in path. Current element is the element on which
68         # the search is being performed.
69+        db_type = None
70 
71         if join_required:
72             # Last query term is a RelatedObject
73@@ -1100,8 +1106,9 @@
74         else:
75             # Last query term was a normal field.
76             column = field.column
77+            db_type = field.db_type()
78 
79-        where.append(get_where_clause(lookup_type, current_table + '.', column, value))
80+        where.append(get_where_clause(lookup_type, current_table + '.', column, value, db_type))
81         params.extend(field.get_db_prep_lookup(lookup_type, value))
82 
83     return joins, where, params
84Index: django/db/backends/oracle/base.py
85===================================================================
86--- django/db/backends/oracle/base.py   (revision 5821)
87+++ django/db/backends/oracle/base.py   (working copy)
88@@ -181,6 +181,12 @@
89 def get_datetime_cast_sql():
90     return "TO_TIMESTAMP(%s, 'YYYY-MM-DD HH24:MI:SS.FF')"
91 
92+def get_field_cast_sql(db_type):
93+    if db_type.endswith('LOB'):
94+        return "DBMS_LOB.SUBSTR(%s%s)"
95+    else:
96+        return "%s%s"
97+
98 def get_limit_offset_sql(limit, offset=None):
99     # Limits and offset are too complicated to be handled here.
100     # Instead, they are handled in django/db/backends/oracle/query.py.
101Index: tests/regressiontests/string_lookup/models.py
102===================================================================
103--- tests/regressiontests/string_lookup/models.py       (revision 5821)
104+++ tests/regressiontests/string_lookup/models.py       (working copy)
105@@ -36,6 +36,13 @@
106     def __unicode__(self):
107         return "Base %s" % self.name
108 
109+class Article(models.Model):
110+    name = models.CharField(maxlength = 50)
111+    text = models.TextField()
112+
113+    def __str__(self):
114+        return "Article %s" % self.name
115+
116 __test__ = {'API_TESTS': ur"""
117 # Regression test for #1661 and #1662: Check that string form referencing of
118 # models works, both as pre and post reference, on all RelatedField types.
119@@ -82,4 +89,13 @@
120 # We can also do the above query using UTF-8 strings.
121 >>> Foo.objects.get(friend__contains='\xc3\xa7')
122 <Foo: Foo Bjorn>
123+
124+# Regression tests for #5087: make sure we can perform queries on TextFields.
125+>>> a = Article(name='Test', text='The quick brown fox jumps over the lazy dog.')
126+>>> a.save()
127+>>> Article.objects.get(text__exact='The quick brown fox jumps over the lazy dog.')
128+<Article: Article Test>
129+
130+>>> Article.objects.get(text__contains='quick brown fox')
131+<Article: Article Test>
132 """}