@@ -127,44 +127,108 @@ def _contains_datetime(self, node: CqlNode) -> bool:
127127def extract_from_ast (node : CqlNode , field_name : str ):
128128 """Extract values from AST for a given field."""
129129 values = []
130- datetime_start = None
131- datetime_end = None
132130
133131 def recurse (n ):
134- nonlocal datetime_start , datetime_end
135-
132+ """Run field extraction in recursion."""
136133 if hasattr (n , "children" ):
137134 for child in n .children :
138135 recurse (child )
139136
140137 if hasattr (n , "field" ) and hasattr (n , "value" ):
141138 if n .field == field_name :
142- if field_name == "datetime" :
143- op = getattr (n , "op" , None )
144- if op == ComparisonOp .GTE :
145- datetime_start = n .value
146- elif op == ComparisonOp .LTE :
147- datetime_end = n .value
148- else :
149- values .append (n .value )
139+ if isinstance (n .value , list ):
140+ values .extend (n .value )
150141 else :
151- if isinstance (n .value , list ):
152- values .extend (n .value )
153- else :
154- values .append (n .value )
142+ values .append (n .value )
143+ # Handle datetime range optimization
144+ elif hasattr (n , "op" ) and n .op == LogicalOp .AND and hasattr (n , "children" ):
145+ # Check if this is a datetime range (GTE and LTE on datetime field)
146+ datetime_nodes = []
147+ for child in n .children :
148+ if (
149+ hasattr (child , "field" )
150+ and child .field == "datetime"
151+ and hasattr (child , "op" )
152+ and hasattr (child , "value" )
153+ ):
154+ datetime_nodes .append (child )
155+
156+ if len (datetime_nodes ) == 2 :
157+ # Check if we have both GTE and LTE for datetime
158+ gte_node = None
159+ lte_node = None
160+ for d_node in datetime_nodes :
161+ if d_node .op == ComparisonOp .GTE :
162+ gte_node = d_node
163+ elif d_node .op == ComparisonOp .LTE :
164+ lte_node = d_node
165+
166+ if gte_node and lte_node :
167+ values .append (
168+ {
169+ "type" : "range" ,
170+ "start" : gte_node .value ,
171+ "end" : lte_node .value ,
172+ }
173+ )
155174
156175 recurse (node )
157176
158- if field_name == "datetime" :
159- if datetime_start and datetime_end :
160- return f"{ datetime_start } /{ datetime_end } "
161- elif datetime_start :
162- return f"{ datetime_start } /.."
163- elif datetime_end :
164- return f"../{ datetime_end } "
165- elif values :
166- return values [0 ]
167- else :
168- return None
169-
170- return values
177+ return values if values else None
178+
179+
180+ def extract_collection_datetime (node ):
181+ """Get (collection, datetime_range) pairs from node."""
182+ pairs = []
183+
184+ def recurse (n ):
185+ # Check if this is an AND node (we're looking for AND clauses)
186+ if hasattr (n , "op" ) and hasattr (n .op , "value" ) and n .op .value == "and" :
187+ collection = None
188+ gte_date = None
189+ lte_date = None
190+
191+ # Look through all children of this AND node
192+ if hasattr (n , "children" ):
193+ for child in n .children :
194+ # Check if it's a comparison node
195+ if (
196+ hasattr (child , "op" )
197+ and hasattr (child , "field" )
198+ and hasattr (child , "value" )
199+ ):
200+ if child .field == "collection" :
201+ collection = child .value
202+ elif child .field in [
203+ "datetime" ,
204+ "start_datetime" ,
205+ "end_datetime" ,
206+ ]: # Handle all datetime fields
207+ if hasattr (child .op , "value" ):
208+ if child .op .value == ">=" :
209+ gte_date = child .value
210+ elif child .op .value == "<=" :
211+ lte_date = child .value
212+
213+ # If we found dates, add to pairs (even without collection)
214+ if gte_date or lte_date :
215+ if gte_date and lte_date :
216+ date_range = f"{ gte_date } /{ lte_date } "
217+ elif gte_date :
218+ date_range = f"{ gte_date } /.."
219+ elif lte_date :
220+ date_range = f"../{ lte_date } "
221+
222+ # Add to pairs - if no collection, use empty string
223+ pairs .append ((collection or "" , date_range ))
224+ # If we found a collection but no dates
225+ elif collection is not None :
226+ pairs .append ((collection , "" ))
227+
228+ # Continue searching through children
229+ if hasattr (n , "children" ):
230+ for child in n .children :
231+ recurse (child )
232+
233+ recurse (node )
234+ return pairs
0 commit comments