@@ -29,7 +29,7 @@ use quickwit_proto::search::{
2929    CountHits ,  LeafSearchRequest ,  LeafSearchResponse ,  PartialHit ,  ResourceStats ,  SearchRequest , 
3030    SortOrder ,  SortValue ,  SplitIdAndFooterOffsets ,  SplitSearchError , 
3131} ; 
32- use  quickwit_query:: query_ast:: { BoolQuery ,  QueryAst ,  QueryAstTransformer ,  RangeQuery ,   TermQuery } ; 
32+ use  quickwit_query:: query_ast:: { BoolQuery ,  QueryAst ,  QueryAstTransformer ,  RangeQuery } ; 
3333use  quickwit_query:: tokenizers:: TokenizerManager ; 
3434use  quickwit_storage:: { 
3535    BundleStorage ,  ByteRangeCache ,  MemorySizedCache ,  OwnedBytes ,  SplitCache ,  Storage , 
@@ -45,6 +45,7 @@ use tokio::task::JoinError;
4545use  tracing:: * ; 
4646
4747use  crate :: collector:: { IncrementalCollector ,  make_collector_for_split,  make_merge_collector} ; 
48+ use  crate :: extract_timestamp_range:: ExtractTimestampRange ; 
4849use  crate :: metrics:: SEARCH_METRICS ; 
4950use  crate :: root:: is_metadata_count_request_with_ast; 
5051use  crate :: search_permit_provider:: { SearchPermit ,  compute_initial_memory_allocation} ; 
@@ -639,58 +640,6 @@ pub fn map_bound<T, U>(bound: Bound<T>, f: impl FnOnce(T) -> U) -> Bound<U> {
639640    } 
640641} 
641642
642- // returns the max of left and right, that isn't unbounded. Useful for making 
643- // the intersection of lower bound of ranges 
644- fn  max_bound < T :  Ord  + Copy > ( left :  Bound < T > ,  right :  Bound < T > )  -> Bound < T >  { 
645-     use  Bound :: * ; 
646-     match  ( left,  right)  { 
647-         ( Unbounded ,  right)  => right, 
648-         ( left,  Unbounded )  => left, 
649-         ( Included ( left) ,  Included ( right) )  => Included ( left. max ( right) ) , 
650-         ( Excluded ( left) ,  Excluded ( right) )  => Excluded ( left. max ( right) ) , 
651-         ( excluded_total @ Excluded ( excluded) ,  included_total @ Included ( included) )  => { 
652-             if  included > excluded { 
653-                 included_total
654-             }  else  { 
655-                 excluded_total
656-             } 
657-         } 
658-         ( included_total @ Included ( included) ,  excluded_total @ Excluded ( excluded) )  => { 
659-             if  included > excluded { 
660-                 included_total
661-             }  else  { 
662-                 excluded_total
663-             } 
664-         } 
665-     } 
666- } 
667- 
668- // returns the min of left and right, that isn't unbounded. Useful for making 
669- // the intersection of upper bound of ranges 
670- fn  min_bound < T :  Ord  + Copy > ( left :  Bound < T > ,  right :  Bound < T > )  -> Bound < T >  { 
671-     use  Bound :: * ; 
672-     match  ( left,  right)  { 
673-         ( Unbounded ,  right)  => right, 
674-         ( left,  Unbounded )  => left, 
675-         ( Included ( left) ,  Included ( right) )  => Included ( left. min ( right) ) , 
676-         ( Excluded ( left) ,  Excluded ( right) )  => Excluded ( left. min ( right) ) , 
677-         ( excluded_total @ Excluded ( excluded) ,  included_total @ Included ( included) )  => { 
678-             if  included < excluded { 
679-                 included_total
680-             }  else  { 
681-                 excluded_total
682-             } 
683-         } 
684-         ( included_total @ Included ( included) ,  excluded_total @ Excluded ( excluded) )  => { 
685-             if  included < excluded { 
686-                 included_total
687-             }  else  { 
688-                 excluded_total
689-             } 
690-         } 
691-     } 
692- } 
693- 
694643/// remove timestamp range that would be present both in QueryAst and SearchRequest 
695644/// 
696645/// this can save us from doing double the work in some cases, and help with the partial request 
@@ -716,7 +665,7 @@ fn remove_redundant_timestamp_range(
716665        . map ( Bound :: Excluded ) 
717666        . unwrap_or ( Bound :: Unbounded ) ; 
718667
719-     let  mut  visitor = RemoveTimestampRange  { 
668+     let  mut  visitor = ExtractTimestampRange  { 
720669        timestamp_field, 
721670        start_timestamp, 
722671        end_timestamp, 
@@ -810,106 +759,6 @@ fn remove_redundant_timestamp_range(
810759    search_request. end_timestamp  = None ; 
811760} 
812761
813- /// Remove all `must` and `filter timestamp ranges, and summarize them 
814- #[ derive( Debug ,  Clone ) ]  
815- struct  RemoveTimestampRange < ' a >  { 
816-     timestamp_field :  & ' a  str , 
817-     start_timestamp :  Bound < DateTime > , 
818-     end_timestamp :  Bound < DateTime > , 
819- } 
820- 
821- impl  RemoveTimestampRange < ' _ >  { 
822-     fn  update_start_timestamp ( 
823-         & mut  self , 
824-         lower_bound :  & quickwit_query:: JsonLiteral , 
825-         included :  bool , 
826-     )  { 
827-         use  quickwit_query:: InterpretUserInput ; 
828-         let  Some ( lower_bound)  = DateTime :: interpret_json ( lower_bound)  else  { 
829-             // we shouldn't be able to get here, we would have errored much earlier in root search 
830-             warn ! ( "unparsable time bound in leaf search: {lower_bound:?}" ) ; 
831-             return ; 
832-         } ; 
833-         let  bound = if  included { 
834-             Bound :: Included ( lower_bound) 
835-         }  else  { 
836-             Bound :: Excluded ( lower_bound) 
837-         } ; 
838- 
839-         self . start_timestamp  = max_bound ( self . start_timestamp ,  bound) ; 
840-     } 
841- 
842-     fn  update_end_timestamp ( & mut  self ,  upper_bound :  & quickwit_query:: JsonLiteral ,  included :  bool )  { 
843-         use  quickwit_query:: InterpretUserInput ; 
844-         let  Some ( upper_bound)  = DateTime :: interpret_json ( upper_bound)  else  { 
845-             // we shouldn't be able to get here, we would have errored much earlier in root search 
846-             warn ! ( "unparsable time bound in leaf search: {upper_bound:?}" ) ; 
847-             return ; 
848-         } ; 
849-         let  bound = if  included { 
850-             Bound :: Included ( upper_bound) 
851-         }  else  { 
852-             Bound :: Excluded ( upper_bound) 
853-         } ; 
854- 
855-         self . end_timestamp  = min_bound ( self . end_timestamp ,  bound) ; 
856-     } 
857- } 
858- 
859- impl  QueryAstTransformer  for  RemoveTimestampRange < ' _ >  { 
860-     type  Err  = std:: convert:: Infallible ; 
861- 
862-     fn  transform_bool ( & mut  self ,  mut  bool_query :  BoolQuery )  -> Result < Option < QueryAst > ,  Self :: Err >  { 
863-         // we only want to visit sub-queries which are strict (positive) requirements 
864-         bool_query. must  = bool_query
865-             . must 
866-             . into_iter ( ) 
867-             . filter_map ( |query_ast| self . transform ( query_ast) . transpose ( ) ) 
868-             . collect :: < Result < Vec < _ > ,  _ > > ( ) ?; 
869-         bool_query. filter  = bool_query
870-             . filter 
871-             . into_iter ( ) 
872-             . filter_map ( |query_ast| self . transform ( query_ast) . transpose ( ) ) 
873-             . collect :: < Result < Vec < _ > ,  _ > > ( ) ?; 
874- 
875-         Ok ( Some ( QueryAst :: Bool ( bool_query) ) ) 
876-     } 
877- 
878-     fn  transform_range ( & mut  self ,  range_query :  RangeQuery )  -> Result < Option < QueryAst > ,  Self :: Err >  { 
879-         if  range_query. field  == self . timestamp_field  { 
880-             match  range_query. lower_bound  { 
881-                 Bound :: Included ( lower_bound)  => { 
882-                     self . update_start_timestamp ( & lower_bound,  true ) ; 
883-                 } 
884-                 Bound :: Excluded ( lower_bound)  => { 
885-                     self . update_start_timestamp ( & lower_bound,  false ) ; 
886-                 } 
887-                 Bound :: Unbounded  => ( ) , 
888-             } ; 
889- 
890-             match  range_query. upper_bound  { 
891-                 Bound :: Included ( upper_bound)  => { 
892-                     self . update_end_timestamp ( & upper_bound,  true ) ; 
893-                 } 
894-                 Bound :: Excluded ( upper_bound)  => { 
895-                     self . update_end_timestamp ( & upper_bound,  false ) ; 
896-                 } 
897-                 Bound :: Unbounded  => ( ) , 
898-             } ; 
899- 
900-             Ok ( Some ( QueryAst :: MatchAll ) ) 
901-         }  else  { 
902-             Ok ( Some ( range_query. into ( ) ) ) 
903-         } 
904-     } 
905- 
906-     fn  transform_term ( & mut  self ,  term_query :  TermQuery )  -> Result < Option < QueryAst > ,  Self :: Err >  { 
907-         // TODO we could remove query bounds, this point query surely is more precise, and it 
908-         // doesn't require loading a fastfield 
909-         Ok ( Some ( QueryAst :: Term ( term_query) ) ) 
910-     } 
911- } 
912- 
913762pub ( crate )  fn  rewrite_start_end_time_bounds ( 
914763    start_timestamp_opt :  & mut  Option < i64 > , 
915764    end_timestamp_opt :  & mut  Option < i64 > , 
0 commit comments