1515use std:: collections:: { HashMap , HashSet } ;
1616use std:: convert:: Infallible ;
1717use std:: ops:: Bound ;
18+ use std:: sync:: Arc ;
1819
20+ use quickwit_proto:: types:: SplitId ;
1921use quickwit_query:: query_ast:: {
20- FieldPresenceQuery , FullTextQuery , PhrasePrefixQuery , QueryAst , QueryAstVisitor , RangeQuery ,
21- RegexQuery , TermSetQuery , WildcardQuery ,
22+ BuildTantivyAstContext , FieldPresenceQuery , FullTextQuery , PhrasePrefixQuery , QueryAst ,
23+ QueryAstTransformer , QueryAstVisitor , RangeQuery , RegexQuery , TermSetQuery , WildcardQuery ,
2224} ;
2325use quickwit_query:: tokenizers:: TokenizerManager ;
2426use quickwit_query:: { InvalidQuery , find_field_or_hit_dynamic} ;
@@ -154,17 +156,24 @@ impl<'a, 'f> QueryAstVisitor<'a> for ExistsQueryFastFields<'f> {
154156
155157/// Build a `Query` with field resolution & forbidding range clauses.
156158pub ( crate ) fn build_query (
157- query_ast : & QueryAst ,
158- schema : Schema ,
159- tokenizer_manager : & TokenizerManager ,
160- search_fields : & [ String ] ,
161- with_validation : bool ,
159+ query_ast : QueryAst ,
160+ context : & BuildTantivyAstContext ,
161+ cache_context : Option < ( Arc < dyn quickwit_query:: query_ast:: PredicateCache > , SplitId ) > ,
162162) -> Result < ( Box < dyn Query > , WarmupInfo ) , QueryParserError > {
163163 let mut fast_fields: HashSet < FastFieldWarmupInfo > = HashSet :: new ( ) ;
164164
165+ let query_ast = if let Some ( ( cache, split_id) ) = cache_context {
166+ let Ok ( query_ast) = quickwit_query:: query_ast:: PredicateCacheInjector { cache, split_id }
167+ . transform ( query_ast) ;
168+ // this transformer isn't supposed to ever remove a node
169+ query_ast. unwrap_or ( QueryAst :: MatchAll )
170+ } else {
171+ query_ast
172+ } ;
173+
165174 let mut range_query_fields = RangeQueryFields :: default ( ) ;
166175 // This cannot fail. The error type is Infallible.
167- let Ok ( _) = range_query_fields. visit ( query_ast) ;
176+ let Ok ( _) = range_query_fields. visit ( & query_ast) ;
168177 let range_query_fast_fields =
169178 range_query_fields
170179 . range_query_field_names
@@ -177,31 +186,30 @@ pub(crate) fn build_query(
177186
178187 let Ok ( _) = TermSearchOnColumnar {
179188 fields : & mut fast_fields,
180- schema : schema. clone ( ) ,
189+ schema : context . schema . clone ( ) ,
181190 }
182- . visit ( query_ast) ;
191+ . visit ( & query_ast) ;
183192
184193 let Ok ( _) = ExistsQueryFastFields {
185194 fields : & mut fast_fields,
186- schema : schema. clone ( ) ,
195+ schema : context . schema . clone ( ) ,
187196 }
188- . visit ( query_ast) ;
197+ . visit ( & query_ast) ;
189198
190- let query = query_ast. build_tantivy_query (
191- & schema,
192- tokenizer_manager,
193- search_fields,
194- with_validation,
195- ) ?;
199+ let query = query_ast. build_tantivy_query ( context) ?;
196200
197- let term_set_query_fields = extract_term_set_query_fields ( query_ast, & schema) ?;
201+ let term_set_query_fields = extract_term_set_query_fields ( & query_ast, context . schema ) ?;
198202 let ( term_ranges_grouped_by_field, automatons_grouped_by_field) =
199- extract_prefix_term_ranges_and_automaton ( query_ast, & schema, tokenizer_manager) ?;
203+ extract_prefix_term_ranges_and_automaton (
204+ & query_ast,
205+ context. schema ,
206+ context. tokenizer_manager ,
207+ ) ?;
200208
201209 let mut terms_grouped_by_field: HashMap < Field , HashMap < _ , bool > > = Default :: default ( ) ;
202210 query. query_terms ( & mut |term, need_position| {
203211 let field = term. field ( ) ;
204- if !schema. get_field_entry ( field) . is_indexed ( ) {
212+ if !context . schema . get_field_entry ( field) . is_indexed ( ) {
205213 return ;
206214 }
207215 * terms_grouped_by_field
@@ -419,8 +427,8 @@ mod test {
419427
420428 use quickwit_common:: shared_consts:: FIELD_PRESENCE_FIELD_NAME ;
421429 use quickwit_query:: query_ast:: {
422- FullTextMode , FullTextParams , PhrasePrefixQuery , QueryAstVisitor , UserInputQuery ,
423- query_ast_from_user_text,
430+ BuildTantivyAstContext , FullTextMode , FullTextParams , PhrasePrefixQuery , QueryAstVisitor ,
431+ UserInputQuery , query_ast_from_user_text,
424432 } ;
425433 use quickwit_query:: {
426434 BooleanOperand , MatchAllOrNone , create_default_quickwit_tokenizer_manager,
@@ -506,13 +514,7 @@ mod test {
506514 . parse_user_query ( & [ ] )
507515 . map_err ( |err| err. to_string ( ) ) ?;
508516 let schema = make_schema ( dynamic_mode) ;
509- let query_result = build_query (
510- & query_ast,
511- schema,
512- & create_default_quickwit_tokenizer_manager ( ) ,
513- & [ ] ,
514- true ,
515- ) ;
517+ let query_result = build_query ( query_ast, & BuildTantivyAstContext :: for_test ( & schema) , None ) ;
516518 query_result
517519 . map ( |query| format ! ( "{query:?}" ) )
518520 . map_err ( |err| err. to_string ( ) )
@@ -886,29 +888,18 @@ mod test {
886888 . parse_user_query ( & [ ] )
887889 . unwrap ( ) ;
888890
889- let ( _, warmup_info) = build_query (
890- & query_with_set,
891- make_schema ( true ) ,
892- & create_default_quickwit_tokenizer_manager ( ) ,
893- & [ ] ,
894- true ,
895- )
896- . unwrap ( ) ;
891+ let schema = make_schema ( true ) ;
892+ let context = BuildTantivyAstContext :: for_test ( & schema) ;
893+
894+ let ( _, warmup_info) = build_query ( query_with_set, & context, None ) . unwrap ( ) ;
897895 assert_eq ! ( warmup_info. term_dict_fields. len( ) , 1 ) ;
898896 assert ! (
899897 warmup_info
900898 . term_dict_fields
901899 . contains( & tantivy:: schema:: Field :: from_field_id( 2 ) )
902900 ) ;
903901
904- let ( _, warmup_info) = build_query (
905- & query_without_set,
906- make_schema ( true ) ,
907- & create_default_quickwit_tokenizer_manager ( ) ,
908- & [ ] ,
909- true ,
910- )
911- . unwrap ( ) ;
902+ let ( _, warmup_info) = build_query ( query_without_set, & context, None ) . unwrap ( ) ;
912903 assert ! ( warmup_info. term_dict_fields. is_empty( ) ) ;
913904 }
914905
0 commit comments