diff --git a/query-grammar/src/query_grammar.rs b/query-grammar/src/query_grammar.rs index 6fabff8cea..41f6f3303f 100644 --- a/query-grammar/src/query_grammar.rs +++ b/query-grammar/src/query_grammar.rs @@ -374,6 +374,25 @@ pub fn parse_to_ast<'a>() -> impl Parser<&'a str, Output = UserInputAst> { spaces() .with(optional(ast()).skip(eof())) .map(|opt_ast| opt_ast.unwrap_or_else(UserInputAst::empty_query)) + .map(|ast| rewrite_ast(ast)) +} + +/// Removes unnecessary children clauses in AST +/// +/// Motivated by [issue #1433](https://github.com/quickwit-oss/tantivy/issues/1433) +fn rewrite_ast(input: UserInputAst) -> UserInputAst { + if let UserInputAst::Clause(terms) = input { + UserInputAst::Clause(terms.into_iter().map(rewrite_ast_clause).collect()) + } else { + input + } +} + +fn rewrite_ast_clause(input: (Option, UserInputAst)) -> (Option, UserInputAst) { + match input { + (None, UserInputAst::Clause(mut clauses)) if clauses.len() == 1 => clauses.remove(0), + other => other, + } } #[cfg(test)] @@ -749,4 +768,10 @@ mod test { test_parse_query_to_ast_helper("foo:\"a b\"~300", "\"foo\":\"a b\"~300"); test_parse_query_to_ast_helper("\"a b\"~300^2", "(\"a b\"~300)^2"); } + + #[test] + fn test_not_queries_are_consistent() { + test_parse_query_to_ast_helper("tata -toto", "(*\"tata\" -\"toto\")"); + test_parse_query_to_ast_helper("tata NOT toto", "(*\"tata\" -\"toto\")"); + } }