3939 Upper ,
4040)
4141
42+ from  .lookups  import  is_constant_value 
4243from  .query_utils  import  process_lhs 
4344
4445MONGO_OPERATORS  =  {
@@ -84,18 +85,18 @@ def cast(self, compiler, connection, **extra): # noqa: ARG001
8485 return  lhs_mql 
8586
8687
87- def  concat (self , compiler , connection ):
88-  return  self .get_source_expressions ()[0 ].as_mql (compiler , connection )
88+ def  concat (self , compiler , connection ,  as_path = False ):
89+  return  self .get_source_expressions ()[0 ].as_mql (compiler , connection ,  as_path = as_path )
8990
9091
91- def  concat_pair (self , compiler , connection ): 
92+ def  concat_pair (self , compiler , connection ,  as_path = False ):  # noqa: ARG001 
9293 # null on either side results in null for expression, wrap with coalesce. 
9394 coalesced  =  self .coalesce ()
94-  return  super (ConcatPair , coalesced ).as_mql (compiler , connection )
95+  return  super (ConcatPair , coalesced ).as_mql (compiler , connection ,  as_path = False )
9596
9697
97- def  cot (self , compiler , connection ): 
98-  lhs_mql  =  process_lhs (self , compiler , connection )
98+ def  cot (self , compiler , connection ,  as_path = False ):  # noqa: ARG001 
99+  lhs_mql  =  process_lhs (self , compiler , connection ,  as_path = False )
99100 return  {"$divide" : [1 , {"$tan" : lhs_mql }]}
100101
101102
@@ -117,8 +118,8 @@ def func(self, compiler, connection, **extra): # noqa: ARG001
117118 return  {f"${ operator }  : lhs_mql }
118119
119120
120- def  left (self , compiler , connection ): 
121-  return  self .get_substr ().as_mql (compiler , connection )
121+ def  left (self , compiler , connection ,  as_path = False ):  # noqa: ARG001 
122+  return  self .get_substr ().as_mql (compiler , connection ,  as_path = False )
122123
123124
124125def  length (self , compiler , connection , as_path = False ): # noqa: ARG001 
@@ -127,28 +128,35 @@ def length(self, compiler, connection, as_path=False): # noqa: ARG001
127128 return  {"$cond" : {"if" : {"$eq" : [lhs_mql , None ]}, "then" : None , "else" : {"$strLenCP" : lhs_mql }}}
128129
129130
130- def  log (self , compiler , connection ): 
131+ def  log (self , compiler , connection ,  as_path = False ):  # noqa: ARG001 
131132 # This function is usually log(base, num) but on MongoDB it's log(num, base). 
132133 clone  =  self .copy ()
133134 clone .set_source_expressions (self .get_source_expressions ()[::- 1 ])
134135 return  func (clone , compiler , connection )
135136
136137
137- def  now (self , compiler , connection ): # noqa: ARG001 
138+ def  now (self , compiler , connection ,  as_path = False ): # noqa: ARG001 
138139 return  "$$NOW" 
139140
140141
141- def  null_if (self , compiler , connection ): 
142+ def  null_if (self , compiler , connection ,  as_path = False ):  # noqa: ARG001 
142143 """Return None if expr1==expr2 else expr1.""" 
143-  expr1 , expr2  =  (expr .as_mql (compiler , connection ) for  expr  in  self .get_source_expressions ())
144+  expr1 , expr2  =  (
145+  expr .as_mql (compiler , connection , as_path = False ) for  expr  in  self .get_source_expressions ()
146+  )
144147 return  {"$cond" : {"if" : {"$eq" : [expr1 , expr2 ]}, "then" : None , "else" : expr1 }}
145148
146149
147150def  preserve_null (operator ):
148151 # If the argument is null, the function should return null, not 
149152 # $toLower/Upper's behavior of returning an empty string. 
150-  def  wrapped (self , compiler , connection ):
151-  lhs_mql  =  process_lhs (self , compiler , connection )
153+  def  wrapped (self , compiler , connection , as_path = False ):
154+  if  is_constant_value (self .lhs ) and  as_path :
155+  if  self .lhs  is  None :
156+  return  None 
157+  lhs_mql  =  process_lhs (self , compiler , connection , as_path = True )
158+  return  lhs_mql .upper ()
159+  lhs_mql  =  process_lhs (self , compiler , connection , as_path = False )
152160 return  {
153161 "$expr" : {
154162 "$cond" : {
@@ -162,24 +170,29 @@ def wrapped(self, compiler, connection):
162170 return  wrapped 
163171
164172
165- def  replace (self , compiler , connection ):
166-  expression , text , replacement  =  process_lhs (self , compiler , connection )
173+ def  replace (self , compiler , connection ,  as_path = False ):
174+  expression , text , replacement  =  process_lhs (self , compiler , connection ,  as_path = as_path )
167175 return  {"$replaceAll" : {"input" : expression , "find" : text , "replacement" : replacement }}
168176
169177
170- def  round_ (self , compiler , connection ): 
178+ def  round_ (self , compiler , connection ,  as_path = False ):  # noqa: ARG001 
171179 # Round needs its own function because it's a special case that inherits 
172180 # from Transform but has two arguments. 
173-  return  {"$round" : [expr .as_mql (compiler , connection ) for  expr  in  self .get_source_expressions ()]}
181+  return  {
182+  "$round" : [
183+  expr .as_mql (compiler , connection , as_path = False )
184+  for  expr  in  self .get_source_expressions ()
185+  ]
186+  }
174187
175188
176- def  str_index (self , compiler , connection ): 
189+ def  str_index (self , compiler , connection ,  as_path = False ):  # noqa: ARG001 
177190 lhs  =  process_lhs (self , compiler , connection )
178191 # StrIndex should be 0-indexed (not found) but it's -1-indexed on MongoDB. 
179192 return  {"$add" : [{"$indexOfCP" : lhs }, 1 ]}
180193
181194
182- def  substr (self , compiler , connection , ** extra ): # noqa: ARG001 
195+ def  substr (self , compiler , connection , as_path = False ): # noqa: ARG001 
183196 lhs  =  process_lhs (self , compiler , connection )
184197 # The starting index is zero-indexed on MongoDB rather than one-indexed. 
185198 lhs [1 ] =  {"$add" : [lhs [1 ], - 1 ]}
@@ -191,14 +204,14 @@ def substr(self, compiler, connection, **extra): # noqa: ARG001
191204
192205
193206def  trim (operator ):
194-  def  wrapped (self , compiler , connection ): 
207+  def  wrapped (self , compiler , connection ,  as_path = False ):  # noqa: ARG001 
195208 lhs  =  process_lhs (self , compiler , connection )
196209 return  {f"${ operator }  : {"input" : lhs }}
197210
198211 return  wrapped 
199212
200213
201- def  trunc (self , compiler , connection , ** extra ): # noqa: ARG001 
214+ def  trunc (self , compiler , connection , as_path = False ): # noqa: ARG001 
202215 lhs_mql  =  process_lhs (self , compiler , connection )
203216 lhs_mql  =  {"date" : lhs_mql , "unit" : self .kind , "startOfWeek" : "mon" }
204217 if  timezone  :=  self .get_tzname ():
@@ -257,11 +270,11 @@ def trunc_date(self, compiler, connection, **extra): # noqa: ARG001
257270 }
258271
259272
260- def  trunc_time (self , compiler , connection ): 
273+ def  trunc_time (self , compiler , connection ,  as_path = False ):  # noqa: ARG001 
261274 tzname  =  self .get_tzname ()
262275 if  tzname  and  tzname  !=  "UTC" :
263276 raise  NotSupportedError (f"TruncTime with tzinfo ({ tzname }  )
264-  lhs_mql  =  process_lhs (self , compiler , connection )
277+  lhs_mql  =  process_lhs (self , compiler , connection ,  as_path = False )
265278 return  {
266279 "$dateFromString" : {
267280 "dateString" : {
0 commit comments