Skip to content

Commit 138f5ff

Browse files
committed
prevent Upper/Lower from converting null to an empty string
1 parent 2f86210 commit 138f5ff

File tree

2 files changed

+18
-4
lines changed

2 files changed

+18
-4
lines changed

django_mongodb/features.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,6 @@ class DatabaseFeatures(BaseDatabaseFeatures):
5656
# the result back to UTC.
5757
"db_functions.datetime.test_extract_trunc.DateFunctionWithTimeZoneTests.test_trunc_func_with_timezone",
5858
"db_functions.datetime.test_extract_trunc.DateFunctionWithTimeZoneTests.test_trunc_timezone_applied_before_truncation",
59-
# Coalesce() with expressions doesn't generate correct query.
60-
"db_functions.comparison.test_coalesce.CoalesceTests.test_mixed_values",
6159
# $and must be an array
6260
"db_functions.tests.FunctionTests.test_function_as_filter",
6361
# pk__in=queryset doesn't work because subqueries aren't a thing in

django_mongodb/functions.py

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,9 @@
3939
Degrees: "radiansToDegrees",
4040
Greatest: "max",
4141
Least: "min",
42-
Lower: "toLower",
4342
Power: "pow",
4443
Radians: "degreesToRadians",
4544
Random: "rand",
46-
Upper: "toUpper",
4745
}
4846
EXTRACT_OPERATORS = {
4947
ExtractDay.lookup_name: "dayOfMonth",
@@ -124,6 +122,22 @@ def null_if(self, compiler, connection):
124122
return {"$cond": {"if": {"$eq": [expr1, expr2]}, "then": None, "else": expr1}}
125123

126124

125+
def perserve_null(operator):
126+
# If the argument is null, the function should return null, not
127+
# $toLower/Upper's behavior of returning an empty string.
128+
def wrapped(self, compiler, connection):
129+
lhs_mql = process_lhs(self, compiler, connection)
130+
return {
131+
"$cond": {
132+
"if": {"$eq": [lhs_mql, None]},
133+
"then": None,
134+
"else": {f"${operator}": lhs_mql},
135+
}
136+
}
137+
138+
return wrapped
139+
140+
127141
def replace(self, compiler, connection):
128142
expression, text, replacement = process_lhs(self, compiler, connection)
129143
return {"$replaceAll": {"input": expression, "find": text, "replacement": replacement}}
@@ -178,6 +192,7 @@ def register_functions():
178192
Left.as_mql = left
179193
Length.as_mql = length
180194
Log.as_mql = log
195+
Lower.as_mql = perserve_null("toLower")
181196
LTrim.as_mql = trim("ltrim")
182197
NullIf.as_mql = null_if
183198
Replace.as_mql = replace
@@ -187,3 +202,4 @@ def register_functions():
187202
Substr.as_mql = substr
188203
Trim.as_mql = trim("trim")
189204
TruncBase.as_mql = trunc
205+
Upper.as_mql = perserve_null("toUpper")

0 commit comments

Comments
 (0)