Skip to content

Commit f5c4a26

Browse files
authored
Fix cql2-text between operator (#521)
**Related Issue(s):** - #513 **Description:** - Fix cql2-text between operator **PR Checklist:** - [x] Code is formatted and linted (run `pre-commit run --all-files`) - [x] Tests pass (run `make test`) - [x] Documentation has been updated to reflect changes, if applicable - [x] Changes are added to the changelog
1 parent 983fedd commit f5c4a26

File tree

4 files changed

+35
-3
lines changed

4 files changed

+35
-3
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
1313

1414
### Fixed
1515

16+
- Fixed "list index out of range" error when using BETWEEN operator in CQL2-text filters. [#521](https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch/pull/521)
17+
1618
### Removed
1719

1820
### Updated

stac_fastapi/core/stac_fastapi/core/core.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -830,7 +830,7 @@ async def post_search(
830830
search = await self.database.apply_cql2_filter(search, cql2_filter)
831831
except Exception as e:
832832
raise HTTPException(
833-
status_code=400, detail=f"Error with cql2_json filter: {e}"
833+
status_code=400, detail=f"Error with cql2 filter: {e}"
834834
)
835835

836836
if hasattr(search_request, "q"):

stac_fastapi/sfeos_helpers/stac_fastapi/sfeos_helpers/filter/transform.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,19 @@ def to_es(queryables_mapping: Dict[str, Any], query: Dict[str, Any]) -> Dict[str
9292

9393
elif query["op"] == AdvancedComparisonOp.BETWEEN:
9494
field = to_es_field(queryables_mapping, query["args"][0]["property"])
95-
gte, lte = query["args"][1], query["args"][2]
95+
96+
# Handle both formats: [property, [lower, upper]] or [property, lower, upper]
97+
if len(query["args"]) == 2 and isinstance(query["args"][1], list):
98+
# Format: [{'property': '...'}, [lower, upper]]
99+
gte, lte = query["args"][1][0], query["args"][1][1]
100+
elif len(query["args"]) == 3:
101+
# Format: [{'property': '...'}, lower, upper]
102+
gte, lte = query["args"][1], query["args"][2]
103+
else:
104+
raise ValueError(
105+
f"BETWEEN operator expects 2 or 3 args, got {len(query['args'])}"
106+
)
107+
96108
if isinstance(gte, dict) and "timestamp" in gte:
97109
gte = gte["timestamp"]
98110
if isinstance(lte, dict) and "timestamp" in lte:

stac_fastapi/tests/extensions/test_filter.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,7 @@ async def test_search_filter_extension_in_no_list(app_client, ctx):
410410

411411
assert resp.status_code == 400
412412
assert resp.json() == {
413-
"detail": f"Error with cql2_json filter: Arg {product_id} is not a list"
413+
"detail": f"Error with cql2 filter: Arg {product_id} is not a list"
414414
}
415415

416416

@@ -440,6 +440,24 @@ async def test_search_filter_extension_between(app_client, ctx):
440440
assert len(resp.json()["features"]) == 1
441441

442442

443+
@pytest.mark.asyncio
444+
async def test_search_filter_extension_between_get(app_client, ctx):
445+
"""Test BETWEEN operator with GET request using CQL2-text format."""
446+
sun_elevation = ctx.item["properties"]["view:sun_elevation"]
447+
lower_bound = sun_elevation - 0.01
448+
upper_bound = sun_elevation + 0.01
449+
450+
# Use CQL2-text format for GET request
451+
filter_expr = f"properties.view:sun_elevation BETWEEN {lower_bound} AND {upper_bound} AND id = '{ctx.item['id']}'"
452+
453+
resp = await app_client.get(
454+
"/search", params={"filter": filter_expr, "filter_lang": "cql2-text"}
455+
)
456+
457+
assert resp.status_code == 200
458+
assert len(resp.json()["features"]) == 1
459+
460+
443461
@pytest.mark.asyncio
444462
async def test_search_filter_extension_isnull_post(app_client, ctx):
445463
# Test for a property that is not null

0 commit comments

Comments
 (0)