diff --git a/filter-parser/src/error.rs b/filter-parser/src/error.rs index 0e416091f..4d9d89859 100644 --- a/filter-parser/src/error.rs +++ b/filter-parser/src/error.rs @@ -156,10 +156,10 @@ impl<'a> Display for Error<'a> { writeln!(f, "The `_geoRadius` filter expects three arguments: `_geoRadius(latitude, longitude, radius)`.")? } ErrorKind::GeoBoundingBox => { - writeln!(f, "The `_geoBoundingBox` filter expects two pairs of arguments: `_geoBoundingBox((latitude, longitude), (latitude, longitude))`.")? + writeln!(f, "The `_geoBoundingBox` filter expects two pairs of arguments: `_geoBoundingBox([latitude, longitude], [latitude, longitude])`.")? } ErrorKind::ReservedGeo(name) => { - writeln!(f, "`{}` is a reserved keyword and thus can't be used as a filter expression. Use the `_geoRadius(latitude, longitude, distance), or _geoBoundingBox((latitude, longitude), (latitude, longitude)) built-in rules to filter on `_geo` coordinates.", name.escape_debug())? + writeln!(f, "`{}` is a reserved keyword and thus can't be used as a filter expression. Use the `_geoRadius(latitude, longitude, distance), or _geoBoundingBox([latitude, longitude], [latitude, longitude]) built-in rules to filter on `_geo` coordinates.", name.escape_debug())? } ErrorKind::MisusedGeoRadius => { writeln!(f, "The `_geoRadius` filter is an operation and can't be used as a value.")? diff --git a/filter-parser/src/lib.rs b/filter-parser/src/lib.rs index 385e6f623..8e21ff6be 100644 --- a/filter-parser/src/lib.rs +++ b/filter-parser/src/lib.rs @@ -18,7 +18,7 @@ //! doubleQuoted = "\"" .* all but double quotes "\"" //! word = (alphanumeric | _ | - | .)+ //! geoRadius = "_geoRadius(" WS* float WS* "," WS* float WS* "," float WS* ")" -//! geoBoundingBox = "_geoBoundingBox((" WS * float WS* "," WS* float WS* "), (" WS* float WS* "," WS* float WS* ")") +//! geoBoundingBox = "_geoBoundingBox([" WS * float WS* "," WS* float WS* "], [" WS* float WS* "," WS* float WS* "]") //! ``` //! //! Other BNF grammar used to handle some specific errors: @@ -337,7 +337,7 @@ fn parse_geo_radius(input: Span) -> IResult { Ok((input, res)) } -/// geoBoundingBox = WS* "_geoBoundingBox((float WS* "," WS* float WS* "), (float WS* "," WS* float WS* ")") +/// geoBoundingBox = WS* "_geoBoundingBox([float WS* "," WS* float WS* "], [float WS* "," WS* float WS* "]") /// If we parse `_geoBoundingBox` we MUST parse the rest of the expression. fn parse_geo_bounding_box(input: Span) -> IResult { // we want to allow space BEFORE the _geoBoundingBox but not after @@ -348,7 +348,7 @@ fn parse_geo_bounding_box(input: Span) -> IResult { char('('), separated_list1( tag(","), - ws(delimited(char('('), separated_list1(tag(","), ws(recognize_float)), char(')'))), + ws(delimited(char('['), separated_list1(tag(","), ws(recognize_float)), char(']'))), ), char(')'), )), @@ -515,9 +515,9 @@ pub mod tests { insta::assert_display_snapshot!(p("_geoRadius(12,13,14)"), @"_geoRadius({12}, {13}, {14})"); // Test geo bounding box - insta::assert_display_snapshot!(p("_geoBoundingBox((12, 13), (14, 15))"), @"_geoBoundingBox(({12}, {13}), ({14}, {15}))"); - insta::assert_display_snapshot!(p("NOT _geoBoundingBox((12, 13), (14, 15))"), @"NOT (_geoBoundingBox(({12}, {13}), ({14}, {15})))"); - insta::assert_display_snapshot!(p("_geoBoundingBox((12,13),(14,15))"), @"_geoBoundingBox(({12}, {13}), ({14}, {15}))"); + insta::assert_display_snapshot!(p("_geoBoundingBox([12, 13], [14, 15])"), @"_geoBoundingBox([{12}, {13}], [{14}, {15}])"); + insta::assert_display_snapshot!(p("NOT _geoBoundingBox([12, 13], [14, 15])"), @"NOT (_geoBoundingBox([{12}, {13}], [{14}, {15}]))"); + insta::assert_display_snapshot!(p("_geoBoundingBox([12,13],[14,15])"), @"_geoBoundingBox([{12}, {13}], [{14}, {15}])"); // Test OR + AND insta::assert_display_snapshot!(p("channel = ponce AND 'dog race' != 'bernese mountain'"), @"AND[{channel} = {ponce}, {dog race} != {bernese mountain}, ]"); @@ -606,27 +606,27 @@ pub mod tests { "###); insta::assert_display_snapshot!(p("_geoBoundingBox"), @r###" - The `_geoBoundingBox` filter expects two pairs of arguments: `_geoBoundingBox((latitude, longitude), (latitude, longitude))`. + The `_geoBoundingBox` filter expects two pairs of arguments: `_geoBoundingBox([latitude, longitude], [latitude, longitude])`. 1:16 _geoBoundingBox "###); insta::assert_display_snapshot!(p("_geoBoundingBox = 12"), @r###" - The `_geoBoundingBox` filter expects two pairs of arguments: `_geoBoundingBox((latitude, longitude), (latitude, longitude))`. + The `_geoBoundingBox` filter expects two pairs of arguments: `_geoBoundingBox([latitude, longitude], [latitude, longitude])`. 1:21 _geoBoundingBox = 12 "###); insta::assert_display_snapshot!(p("_geoBoundingBox(1.0, 1.0)"), @r###" - The `_geoBoundingBox` filter expects two pairs of arguments: `_geoBoundingBox((latitude, longitude), (latitude, longitude))`. + The `_geoBoundingBox` filter expects two pairs of arguments: `_geoBoundingBox([latitude, longitude], [latitude, longitude])`. 1:26 _geoBoundingBox(1.0, 1.0) "###); insta::assert_display_snapshot!(p("_geoPoint(12, 13, 14)"), @r###" - `_geoPoint` is a reserved keyword and thus can't be used as a filter expression. Use the `_geoRadius(latitude, longitude, distance), or _geoBoundingBox((latitude, longitude), (latitude, longitude)) built-in rules to filter on `_geo` coordinates. + `_geoPoint` is a reserved keyword and thus can't be used as a filter expression. Use the `_geoRadius(latitude, longitude, distance), or _geoBoundingBox([latitude, longitude], [latitude, longitude]) built-in rules to filter on `_geo` coordinates. 1:22 _geoPoint(12, 13, 14) "###); insta::assert_display_snapshot!(p("position <= _geoPoint(12, 13, 14)"), @r###" - `_geoPoint` is a reserved keyword and thus can't be used as a filter expression. Use the `_geoRadius(latitude, longitude, distance), or _geoBoundingBox((latitude, longitude), (latitude, longitude)) built-in rules to filter on `_geo` coordinates. + `_geoPoint` is a reserved keyword and thus can't be used as a filter expression. Use the `_geoRadius(latitude, longitude, distance), or _geoBoundingBox([latitude, longitude], [latitude, longitude]) built-in rules to filter on `_geo` coordinates. 13:34 position <= _geoPoint(12, 13, 14) "###); @@ -783,7 +783,7 @@ impl<'a> std::fmt::Display for FilterCondition<'a> { FilterCondition::GeoBoundingBox { top_left_point, bottom_right_point } => { write!( f, - "_geoBoundingBox(({}, {}), ({}, {}))", + "_geoBoundingBox([{}, {}], [{}, {}])", top_left_point[0], top_left_point[1], bottom_right_point[0], diff --git a/milli/src/criterion.rs b/milli/src/criterion.rs index 9a6e2be4a..45cbfe63d 100644 --- a/milli/src/criterion.rs +++ b/milli/src/criterion.rs @@ -161,7 +161,7 @@ mod tests { ("_geoRadius(42, 75, 59):asc", ReservedNameForFilter { name: S("_geoRadius") }), ("_geoBoundingBox:asc", ReservedNameForFilter { name: S("_geoBoundingBox") }), ( - "_geoBoundingBox((42, 75), (75, 59)):asc", + "_geoBoundingBox([42, 75], [75, 59]):asc", ReservedNameForFilter { name: S("_geoBoundingBox") }, ), ]; diff --git a/milli/src/index.rs b/milli/src/index.rs index b166ab2d9..1c0482bca 100644 --- a/milli/src/index.rs +++ b/milli/src/index.rs @@ -1529,63 +1529,63 @@ pub(crate) mod tests { // exact match a document let search_result = search - .filter(Filter::from_str("_geoBoundingBox((0, 0), (0, 0))").unwrap().unwrap()) + .filter(Filter::from_str("_geoBoundingBox([0, 0], [0, 0])").unwrap().unwrap()) .execute() .unwrap(); insta::assert_debug_snapshot!(search_result.candidates, @"RoaringBitmap<[0]>"); // match a document in the middle of the rectangle let search_result = search - .filter(Filter::from_str("_geoBoundingBox((10, -10), (-10, 10))").unwrap().unwrap()) + .filter(Filter::from_str("_geoBoundingBox([10, -10], [-10, 10])").unwrap().unwrap()) .execute() .unwrap(); insta::assert_debug_snapshot!(search_result.candidates, @"RoaringBitmap<[0]>"); // select everything let search_result = search - .filter(Filter::from_str("_geoBoundingBox((90, -180), (-90, 180))").unwrap().unwrap()) + .filter(Filter::from_str("_geoBoundingBox([90, -180], [-90, 180])").unwrap().unwrap()) .execute() .unwrap(); insta::assert_debug_snapshot!(search_result.candidates, @"RoaringBitmap<[0, 1, 2, 3, 4]>"); // go on the edge of the longitude let search_result = search - .filter(Filter::from_str("_geoBoundingBox((0, 180), (0, -170))").unwrap().unwrap()) + .filter(Filter::from_str("_geoBoundingBox([0, 180], [0, -170])").unwrap().unwrap()) .execute() .unwrap(); insta::assert_debug_snapshot!(search_result.candidates, @"RoaringBitmap<[1]>"); // go on the other edge of the longitude let search_result = search - .filter(Filter::from_str("_geoBoundingBox((0, 170), (0, -180))").unwrap().unwrap()) + .filter(Filter::from_str("_geoBoundingBox([0, 170], [0, -180])").unwrap().unwrap()) .execute() .unwrap(); insta::assert_debug_snapshot!(search_result.candidates, @"RoaringBitmap<[2]>"); // wrap around the longitude let search_result = search - .filter(Filter::from_str("_geoBoundingBox((0, 170), (0, -170))").unwrap().unwrap()) + .filter(Filter::from_str("_geoBoundingBox([0, 170], [0, -170])").unwrap().unwrap()) .execute() .unwrap(); insta::assert_debug_snapshot!(search_result.candidates, @"RoaringBitmap<[1, 2]>"); // go on the edge of the latitude let search_result = search - .filter(Filter::from_str("_geoBoundingBox((90, 0), (80, 0))").unwrap().unwrap()) + .filter(Filter::from_str("_geoBoundingBox([90, 0], [80, 0])").unwrap().unwrap()) .execute() .unwrap(); insta::assert_debug_snapshot!(search_result.candidates, @"RoaringBitmap<[3]>"); // go on the edge of the latitude let search_result = search - .filter(Filter::from_str("_geoBoundingBox((-80, 0), (-90, 0))").unwrap().unwrap()) + .filter(Filter::from_str("_geoBoundingBox([-80, 0], [-90, 0])").unwrap().unwrap()) .execute() .unwrap(); insta::assert_debug_snapshot!(search_result.candidates, @"RoaringBitmap<[4]>"); // try to wrap around the latitude let search_result = search - .filter(Filter::from_str("_geoBoundingBox((-80, 0), (80, 0))").unwrap().unwrap()) + .filter(Filter::from_str("_geoBoundingBox([-80, 0], [80, 0])").unwrap().unwrap()) .execute() .unwrap(); insta::assert_debug_snapshot!(search_result.candidates, @"RoaringBitmap<[]>"); @@ -1593,7 +1593,7 @@ pub(crate) mod tests { // the request that doesn't make sense // send a top latitude lower than the bottow latitude let search_result = search - .filter(Filter::from_str("_geoBoundingBox((-10, 0), (10, 0))").unwrap().unwrap()) + .filter(Filter::from_str("_geoBoundingBox([-10, 0], [10, 0])").unwrap().unwrap()) .execute() .unwrap(); insta::assert_debug_snapshot!(search_result.candidates, @"RoaringBitmap<[]>"); diff --git a/milli/src/search/facet/filter.rs b/milli/src/search/facet/filter.rs index d148d707a..82073c66b 100644 --- a/milli/src/search/facet/filter.rs +++ b/milli/src/search/facet/filter.rs @@ -619,7 +619,7 @@ mod tests { "Attribute `_geo` is not filterable. This index does not have configured filterable attributes." )); - let filter = Filter::from_str("_geoBoundingBox((42, 150), (30, 10))").unwrap().unwrap(); + let filter = Filter::from_str("_geoBoundingBox([42, 150], [30, 10])").unwrap().unwrap(); let error = filter.evaluate(&rtxn, &index).unwrap_err(); assert!(error.to_string().starts_with( "Attribute `_geo` is not filterable. This index does not have configured filterable attributes." @@ -647,7 +647,7 @@ mod tests { "Attribute `_geo` is not filterable. Available filterable attributes are: `title`." )); - let filter = Filter::from_str("_geoBoundingBox((42, 150), (30, 10))").unwrap().unwrap(); + let filter = Filter::from_str("_geoBoundingBox([42, 150], [30, 10])").unwrap().unwrap(); let error = filter.evaluate(&rtxn, &index).unwrap_err(); assert!(error.to_string().starts_with( "Attribute `_geo` is not filterable. Available filterable attributes are: `title`." @@ -819,7 +819,7 @@ mod tests { // geoboundingbox top left coord have a bad latitude let filter = - Filter::from_str("_geoBoundingBox((-90.0000001, 150), (30, 10))").unwrap().unwrap(); + Filter::from_str("_geoBoundingBox([-90.0000001, 150], [30, 10])").unwrap().unwrap(); let error = filter.evaluate(&rtxn, &index).unwrap_err(); assert!( error.to_string().starts_with( @@ -831,7 +831,7 @@ mod tests { // geoboundingbox top left coord have a bad latitude let filter = - Filter::from_str("_geoBoundingBox((90.0000001, 150), (30, 10))").unwrap().unwrap(); + Filter::from_str("_geoBoundingBox([90.0000001, 150], [30, 10])").unwrap().unwrap(); let error = filter.evaluate(&rtxn, &index).unwrap_err(); assert!( error.to_string().starts_with( @@ -843,7 +843,7 @@ mod tests { // geoboundingbox bottom right coord have a bad latitude let filter = - Filter::from_str("_geoBoundingBox((30, 10), (-90.0000001, 150))").unwrap().unwrap(); + Filter::from_str("_geoBoundingBox([30, 10], [-90.0000001, 150])").unwrap().unwrap(); let error = filter.evaluate(&rtxn, &index).unwrap_err(); assert!(error.to_string().contains( "Bad latitude `-90.0000001`. Latitude must be contained between -90 and 90 degrees." @@ -851,7 +851,7 @@ mod tests { // geoboundingbox bottom right coord have a bad latitude let filter = - Filter::from_str("_geoBoundingBox((30, 10), (90.0000001, 150))").unwrap().unwrap(); + Filter::from_str("_geoBoundingBox([30, 10], [90.0000001, 150])").unwrap().unwrap(); let error = filter.evaluate(&rtxn, &index).unwrap_err(); assert!(error.to_string().contains( "Bad latitude `90.0000001`. Latitude must be contained between -90 and 90 degrees." @@ -859,7 +859,7 @@ mod tests { // geoboundingbox top left coord have a bad longitude let filter = - Filter::from_str("_geoBoundingBox((-10, 180.000001), (30, 10))").unwrap().unwrap(); + Filter::from_str("_geoBoundingBox([-10, 180.000001], [30, 10])").unwrap().unwrap(); let error = filter.evaluate(&rtxn, &index).unwrap_err(); assert!(error.to_string().contains( "Bad longitude `180.000001`. Longitude must be contained between -180 and 180 degrees." @@ -867,7 +867,7 @@ mod tests { // geoboundingbox top left coord have a bad longitude let filter = - Filter::from_str("_geoBoundingBox((-10, -180.000001), (30, 10))").unwrap().unwrap(); + Filter::from_str("_geoBoundingBox([-10, -180.000001], [30, 10])").unwrap().unwrap(); let error = filter.evaluate(&rtxn, &index).unwrap_err(); assert!(error.to_string().contains( "Bad longitude `-180.000001`. Longitude must be contained between -180 and 180 degrees." @@ -875,7 +875,7 @@ mod tests { // geoboundingbox bottom right coord have a bad longitude let filter = - Filter::from_str("_geoBoundingBox((30, 10), (-10, -180.000001))").unwrap().unwrap(); + Filter::from_str("_geoBoundingBox([30, 10], [-10, -180.000001])").unwrap().unwrap(); let error = filter.evaluate(&rtxn, &index).unwrap_err(); assert!(error.to_string().contains( "Bad longitude `-180.000001`. Longitude must be contained between -180 and 180 degrees." @@ -883,7 +883,7 @@ mod tests { // geoboundingbox bottom right coord have a bad longitude let filter = - Filter::from_str("_geoBoundingBox((30, 10), (-10, 180.000001))").unwrap().unwrap(); + Filter::from_str("_geoBoundingBox([30, 10], [-10, 180.000001])").unwrap().unwrap(); let error = filter.evaluate(&rtxn, &index).unwrap_err(); assert!(error.to_string().contains( "Bad longitude `180.000001`. Longitude must be contained between -180 and 180 degrees."