77from django_mongodb_backend .query_conversion .expression_converters import convert_expression
88
99
10+ def _wrap_condition_if_null (_type , condition , path ):
11+ if _type is None :
12+ return {"$and" : [{path : {"$exists" : True }}, condition ]}
13+ return condition
14+
15+
1016class ConversionTestCase (SimpleTestCase ):
1117 CONVERTIBLE_TYPES = {
1218 "int" : 42 ,
@@ -53,10 +59,14 @@ def test_no_conversion_dict_value(self):
5359 self .assertNotOptimizable ({"$eq" : ["$status" , {"$gt" : 5 }]})
5460
5561 def _test_conversion_valid_type (self , _type ):
56- self .assertConversionEqual ({"$eq" : ["$age" , _type ]}, {"age" : _type })
62+ self .assertConversionEqual (
63+ {"$eq" : ["$age" , _type ]}, _wrap_condition_if_null (_type , {"age" : _type }, "age" )
64+ )
5765
5866 def _test_conversion_valid_array_type (self , _type ):
59- self .assertConversionEqual ({"$eq" : ["$age" , _type ]}, {"age" : _type })
67+ self .assertConversionEqual (
68+ {"$eq" : ["$age" , _type ]}, _wrap_condition_if_null (_type , {"age" : _type }, "age" )
69+ )
6070
6171 def test_conversion_various_types (self ):
6272 self ._test_conversion_various_types (self ._test_conversion_valid_type )
@@ -78,7 +88,10 @@ def test_no_conversion_dict_value(self):
7888 self .assertNotOptimizable ({"$in" : ["$status" , [{"bad" : "val" }]]})
7989
8090 def _test_conversion_valid_type (self , _type ):
81- self .assertConversionEqual ({"$in" : ["$age" , [_type ]]}, {"age" : {"$in" : [_type ]}})
91+ self .assertConversionEqual (
92+ {"$in" : ["$age" , [_type ]]},
93+ _wrap_condition_if_null (_type , {"age" : {"$in" : [_type ]}}, "age" ),
94+ )
8295
8396 def test_conversion_various_types (self ):
8497 for _type , val in self .CONVERTIBLE_TYPES .items ():
@@ -170,7 +183,10 @@ def test_no_conversion_dict_value(self):
170183 self .assertNotOptimizable ({"$gt" : ["$price" , {}]})
171184
172185 def _test_conversion_valid_type (self , _type ):
173- self .assertConversionEqual ({"$gt" : ["$price" , _type ]}, {"price" : {"$gt" : _type }})
186+ self .assertConversionEqual (
187+ {"$gt" : ["$price" , _type ]},
188+ _wrap_condition_if_null (_type , {"price" : {"$gt" : _type }}, "price" ),
189+ )
174190
175191 def test_conversion_various_types (self ):
176192 self ._test_conversion_various_types (self ._test_conversion_valid_type )
@@ -193,7 +209,7 @@ def test_no_conversion_dict_value(self):
193209 def _test_conversion_valid_type (self , _type ):
194210 expr = {"$gte" : ["$price" , _type ]}
195211 expected = {"price" : {"$gte" : _type }}
196- self .assertConversionEqual (expr , expected )
212+ self .assertConversionEqual (expr , _wrap_condition_if_null ( _type , expected , "price" ) )
197213
198214 def test_conversion_various_types (self ):
199215 self ._test_conversion_various_types (self ._test_conversion_valid_type )
@@ -210,7 +226,10 @@ def test_no_conversion_dict_value(self):
210226 self .assertNotOptimizable ({"$lt" : ["$price" , {}]})
211227
212228 def _test_conversion_valid_type (self , _type ):
213- self .assertConversionEqual ({"$lt" : ["$price" , _type ]}, {"price" : {"$lt" : _type }})
229+ self .assertConversionEqual (
230+ {"$lt" : ["$price" , _type ]},
231+ _wrap_condition_if_null (_type , {"price" : {"$lt" : _type }}, "price" ),
232+ )
214233
215234 def test_conversion_various_types (self ):
216235 self ._test_conversion_various_types (self ._test_conversion_valid_type )
@@ -227,7 +246,10 @@ def test_no_conversion_dict_value(self):
227246 self .assertNotOptimizable ({"$lte" : ["$price" , {}]})
228247
229248 def _test_conversion_valid_type (self , _type ):
230- self .assertConversionEqual ({"$lte" : ["$price" , _type ]}, {"price" : {"$lte" : _type }})
249+ self .assertConversionEqual (
250+ {"$lte" : ["$price" , _type ]},
251+ _wrap_condition_if_null (_type , {"price" : {"$lte" : _type }}, "price" ),
252+ )
231253
232254 def test_conversion_various_types (self ):
233255 self ._test_conversion_various_types (self ._test_conversion_valid_type )
0 commit comments