@@ -29,7 +29,7 @@ use quickwit_proto::search::{
29
29
CountHits , LeafSearchRequest , LeafSearchResponse , PartialHit , ResourceStats , SearchRequest ,
30
30
SortOrder , SortValue , SplitIdAndFooterOffsets , SplitSearchError ,
31
31
} ;
32
- use quickwit_query:: query_ast:: { BoolQuery , QueryAst , QueryAstTransformer , RangeQuery , TermQuery } ;
32
+ use quickwit_query:: query_ast:: { BoolQuery , QueryAst , QueryAstTransformer , RangeQuery } ;
33
33
use quickwit_query:: tokenizers:: TokenizerManager ;
34
34
use quickwit_storage:: {
35
35
BundleStorage , ByteRangeCache , MemorySizedCache , OwnedBytes , SplitCache , Storage ,
@@ -45,6 +45,7 @@ use tokio::task::JoinError;
45
45
use tracing:: * ;
46
46
47
47
use crate :: collector:: { IncrementalCollector , make_collector_for_split, make_merge_collector} ;
48
+ use crate :: extract_timestamp_range:: ExtractTimestampRange ;
48
49
use crate :: metrics:: SEARCH_METRICS ;
49
50
use crate :: root:: is_metadata_count_request_with_ast;
50
51
use 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> {
639
640
}
640
641
}
641
642
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
-
694
643
/// remove timestamp range that would be present both in QueryAst and SearchRequest
695
644
///
696
645
/// 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(
716
665
. map ( Bound :: Excluded )
717
666
. unwrap_or ( Bound :: Unbounded ) ;
718
667
719
- let mut visitor = RemoveTimestampRange {
668
+ let mut visitor = ExtractTimestampRange {
720
669
timestamp_field,
721
670
start_timestamp,
722
671
end_timestamp,
@@ -810,106 +759,6 @@ fn remove_redundant_timestamp_range(
810
759
search_request. end_timestamp = None ;
811
760
}
812
761
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
-
913
762
pub ( crate ) fn rewrite_start_end_time_bounds (
914
763
start_timestamp_opt : & mut Option < i64 > ,
915
764
end_timestamp_opt : & mut Option < i64 > ,
0 commit comments