Skip to content

Commit e5a2c78

Browse files
JPDSousalogston
authored andcommitted
Use exact Django operator on equality checks against empty strings
1 parent 129b12b commit e5a2c78

3 files changed

Lines changed: 26 additions & 0 deletions

File tree

CHANGELOG.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
CHANGE LOG
22
==========
33

4+
0.7.0
5+
----
6+
- Use "exact" on equality checks against empty strings. #51
7+
48
0.6.0
59
----
610
- Use "exact" on equality checks against boolean values. #53

src/scim2_filter_parser/transpilers/django_q_object.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,5 +236,13 @@ def lookup_op(node_value, comp_value):
236236
# "<field> iexact true/false" to "UPPER(field::text) = UPPER(true/false), which fails.
237237
# UPPER requires a string.
238238
return "exact"
239+
if comp_value == "" and op == "iexact":
240+
# In Oracle iexact + empty string will never evaluate to true. I.e., TRIM(' ') != '' and
241+
# UPPER(TRIM('')) != UPPER(''). Furthermore, case-insensitive search against an empty
242+
# string has no added value over a case-sensitive search. Hence, whenever the SCIM
243+
# path is '<field> eq ""', rather than doing field__iexact='', we do field=''. The
244+
# oracle Django driver will then convert field='' into "field" IS NULL, which is the
245+
# correct way to do it in Oracle.
246+
return "exact"
239247

240248
return op or node_value

tests/test_transpiler_django.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,3 +354,17 @@ def test_parse_simple_email_filter_with_uuid(self):
354354
scim = 'emails.value eq "001750ca-8202-47cd-b553-c63f4f245940"'
355355
django = Q(emails__value__iexact="001750ca-8202-47cd-b553-c63f4f245940")
356356
self.assert_q(scim, django)
357+
358+
359+
class TestOracleQueries(TestCase):
360+
attr_map = {
361+
("externalId", None, None): "externalid",
362+
}
363+
364+
def assert_q(self, input, expected):
365+
self.assertEqual(expected, get_query(input, self.attr_map))
366+
367+
def test_empty_string_equality_transpiles_to_exact(self):
368+
scim = 'externalId eq ""'
369+
django = Q(externalid__exact="")
370+
self.assert_q(scim, django)

0 commit comments

Comments
 (0)