From f37645ffa7e8859fcc98a6c049d23c42e0f6261b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Srokosz?= Date: Tue, 9 Jul 2024 11:31:24 +0200 Subject: [PATCH] Fix: ISE 500 when non-numerical value appears in range search in JSON column (#953) --- mwdb/core/search/parse_helpers.py | 20 ++++++++++++++------ tests/backend/test_attributes.py | 9 +++++++++ 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/mwdb/core/search/parse_helpers.py b/mwdb/core/search/parse_helpers.py index b84876071..e8c560b24 100644 --- a/mwdb/core/search/parse_helpers.py +++ b/mwdb/core/search/parse_helpers.py @@ -122,7 +122,7 @@ def unescape_string(value: str) -> str: return re.sub(r"\\(.)", r"\1", value) -def transform_for_eq_statement(escaped_value: str) -> str: +def transform_for_regular_statement(escaped_value: str) -> str: return unescape_string(escaped_value) @@ -180,7 +180,7 @@ def transform_token(token: StringToken) -> StringToken: return join_tokenized_string(transformed_string) -def transform_for_config_eq_statement(escaped_value: str) -> str: +def transform_for_config_regular_statement(escaped_value: str) -> str: """ Transforms Lucene value to value for == condition against "unicode-escape"-escaped JSON value @@ -352,7 +352,7 @@ def string_equals(column: ColumnElement, escaped_value: str): pattern = transform_for_like_statement(escaped_value) return column.like(pattern) else: - value = transform_for_eq_statement(escaped_value) + value = transform_for_regular_statement(escaped_value) return column == value @@ -361,7 +361,7 @@ def config_string_equals(column: ColumnElement, escaped_value: str): pattern = transform_for_config_like_statement(escaped_value) return column.like(pattern) else: - value = transform_for_config_eq_statement(escaped_value) + value = transform_for_config_regular_statement(escaped_value) return column == value @@ -377,7 +377,7 @@ def _jsonpath_string_equals(path_selector: PathSelector, value: str) -> str: def jsonpath_string_equals(path_selector: PathSelector, escaped_value: str) -> str: # Wildcards are not supported - value = transform_for_eq_statement(escaped_value) + value = transform_for_regular_statement(escaped_value) return _jsonpath_string_equals(path_selector, value) @@ -385,7 +385,7 @@ def jsonpath_config_string_equals( path_selector: PathSelector, escaped_value: str ) -> str: # Wildcards are not supported - value = transform_for_config_eq_statement(escaped_value) + value = transform_for_config_regular_statement(escaped_value) return _jsonpath_string_equals(path_selector, value) @@ -429,6 +429,14 @@ def jsonpath_range_equals( low, high = high, low include_low, include_high = include_high, include_low + if low is not None and not is_nonstring_object(low): + low = transform_for_regular_statement(low) + low = jsonpath_quote(low) + + if high is not None and not is_nonstring_object(high): + high = transform_for_regular_statement(high) + high = jsonpath_quote(high) + low_condition = f"@ >= {low}" if include_low else f"@ > {low}" high_condition = f"@ <= {high}" if include_high else f"@ < {high}" diff --git a/tests/backend/test_attributes.py b/tests/backend/test_attributes.py index 63cd24815..552a51d40 100644 --- a/tests/backend/test_attributes.py +++ b/tests/backend/test_attributes.py @@ -217,3 +217,12 @@ def test_attribute_falsy_values(admin_session, random_attribute): admin_session.add_attribute(sample_id, attr_name, "") admin_session.add_attribute(sample_id, attr_name, ["nonempty"]) admin_session.add_attribute(sample_id, attr_name, {"nonempty": None}) + + +def test_attribute_json_string_range(admin_session, random_attribute): + sample_id, attr_name = random_attribute + admin_session.add_attribute(sample_id, attr_name, {"creation-time": "2024-06-01 12:00:00"}) + assert len(admin_session.search(f'attribute.{attr_name}.creation-time:>="2024-05"')) == 1 + assert len(admin_session.search(f'attribute.{attr_name}.creation-time:>="2024-07"')) == 0 + assert len(admin_session.search(f'attribute.{attr_name}.creation-time:["2024-07" TO "2024-08"]')) == 0 + assert len(admin_session.search(f'attribute.{attr_name}.creation-time:["2024-06" TO "2024-07"]')) == 1