introduce the reserved keywords in the filters

This commit is contained in:
Tamo 2021-09-06 18:15:20 +02:00
parent 6d5762a6c8
commit 7ae2a7341c
No known key found for this signature in database
GPG Key ID: 20CD8020AFA88D69
2 changed files with 23 additions and 3 deletions

View File

@ -595,6 +595,18 @@ fn field_id(
) -> StdResult<Option<FieldId>, PestError<Rule>> { ) -> StdResult<Option<FieldId>, PestError<Rule>> {
// lexing ensures that we at least have a key // lexing ensures that we at least have a key
let key = items.next().unwrap(); let key = items.next().unwrap();
if key.as_rule() == Rule::reserved {
return Err(PestError::new_from_span(
ErrorVariant::CustomError {
message: format!(
"`{}` is a reserved keyword and thus can't be used as a filter expression. Available filterable attributes are: {}",
key.as_str(),
filterable_fields.iter().join(", "),
),
},
key.as_span(),
));
}
if !filterable_fields.contains(key.as_str()) { if !filterable_fields.contains(key.as_str()) {
return Err(PestError::new_from_span( return Err(PestError::new_from_span(
@ -671,6 +683,13 @@ mod tests {
let condition = FilterCondition::from_str(&rtxn, &index, "NOT channel = ponce").unwrap(); let condition = FilterCondition::from_str(&rtxn, &index, "NOT channel = ponce").unwrap();
let expected = Operator(0, Operator::NotEqual(None, S("ponce"))); let expected = Operator(0, Operator::NotEqual(None, S("ponce")));
assert_eq!(condition, expected); assert_eq!(condition, expected);
let result = FilterCondition::from_str(&rtxn, &index, "_geo = France");
assert!(result.is_err());
let error = result.unwrap_err();
assert!(error.to_string().contains(
"`_geo` is a reserved keyword and thus can't be used as a filter expression."
));
} }
#[test] #[test]

View File

@ -1,4 +1,4 @@
key = _{quoted | word} key = _{reserved | quoted | word }
value = _{quoted | word } value = _{quoted | word }
quoted = _{ (PUSH("'") | PUSH("\"")) ~ string ~ POP } quoted = _{ (PUSH("'") | PUSH("\"")) ~ string ~ POP }
string = {char*} string = {char*}
@ -8,6 +8,7 @@ char = _{ !(PEEK | "\\") ~ ANY
| "\\" ~ (PEEK | "\\" | "/" | "b" | "f" | "n" | "r" | "t") | "\\" ~ (PEEK | "\\" | "/" | "b" | "f" | "n" | "r" | "t")
| "\\" ~ ("u" ~ ASCII_HEX_DIGIT{4})} | "\\" ~ ("u" ~ ASCII_HEX_DIGIT{4})}
reserved = { "_geo" | "_geoDistance" | "_geoPoint" | ("_geoPoint" ~ parameters) }
// we deliberately choose to allow empty parameters to generate more specific error message later // we deliberately choose to allow empty parameters to generate more specific error message later
parameters = {("(" ~ (value ~ ",")* ~ value? ~ ")") | ""} parameters = {("(" ~ (value ~ ",")* ~ value? ~ ")") | ""}
condition = _{between | eq | greater | less | geq | leq | neq} condition = _{between | eq | greater | less | geq | leq | neq}