From 4a9262cd2c42993a8028b8d809a41b747c09a526 Mon Sep 17 00:00:00 2001 From: Pascal Seitz Date: Fri, 6 Dec 2024 09:14:01 +0100 Subject: [PATCH] accept * as field name --- query-grammar/src/query_grammar.rs | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/query-grammar/src/query_grammar.rs b/query-grammar/src/query_grammar.rs index d58ccc8173..ba87e1c4e4 100644 --- a/query-grammar/src/query_grammar.rs +++ b/query-grammar/src/query_grammar.rs @@ -6,7 +6,7 @@ use nom::bytes::complete::tag; use nom::character::complete::{ anychar, char, digit1, multispace0, multispace1, none_of, one_of, satisfy, u32, }; -use nom::combinator::{eof, map, map_res, opt, peek, recognize, value, verify}; +use nom::combinator::{eof, map, map_res, not, opt, peek, recognize, value, verify}; use nom::error::{Error, ErrorKind}; use nom::multi::{many0, many1, separated_list0}; use nom::sequence::{delimited, preceded, separated_pair, terminated, tuple}; @@ -20,7 +20,7 @@ use crate::Occur; // Note: '-' char is only forbidden at the beginning of a field name, would be clearer to add it to // special characters. const SPECIAL_CHARS: &[char] = &[ - '+', '^', '`', ':', '{', '}', '"', '\'', '[', ']', '(', ')', '!', '\\', '*', ' ', + '+', '^', '`', ':', '{', '}', '"', '\'', '[', ']', '(', ')', '!', '\\', ' ', ]; /// consume a field name followed by colon. Return the field name with escape sequence @@ -679,7 +679,10 @@ fn negate(expr: UserInputAst) -> UserInputAst { fn leaf(inp: &str) -> IResult<&str, UserInputAst> { alt(( delimited(char('('), ast, char(')')), - map(char('*'), |_| UserInputAst::from(UserInputLeaf::All)), + preceded( + peek(not(tag("*:"))), + map(char('*'), |_| UserInputAst::from(UserInputLeaf::All)), + ), map(preceded(tuple((tag("NOT"), multispace1)), leaf), negate), literal, ))(inp) @@ -700,7 +703,13 @@ fn leaf_infallible(inp: &str) -> JResult<&str, Option> { ), ), ( - value((), char('*')), + value( + (), + preceded( + peek(not(tag("*:"))), // Fail if `*:` is detected + char('*'), // Match standalone `*` + ), + ), map(nothing, |_| { (Some(UserInputAst::from(UserInputLeaf::All)), Vec::new()) }), @@ -1222,6 +1231,7 @@ mod test { #[test] fn test_field_name() { + assert_eq!(super::field_name("*:a"), Ok(("a", "*".to_string()))); assert_eq!( super::field_name(".my.field.name:a"), Ok(("a", ".my.field.name".to_string())) @@ -1527,6 +1537,11 @@ mod test { test_parse_query_to_ast_helper("abc:toto", "\"abc\":toto"); } + #[test] + fn all_field_star() { + test_parse_query_to_ast_helper("*:toto", "\"*\":toto"); + } + #[test] fn test_phrase_with_field() { test_parse_query_to_ast_helper("abc:\"happy tax payer\"", "\"abc\":\"happy tax payer\"");