This is an automated email from the ASF dual-hosted git repository.
potiuk pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git
The following commit(s) were added to refs/heads/main by this push:
new 4dd620f48d8 Fix XCom slice endpoint for crossed bounds (#72584)
4dd620f48d8 is described below
commit 4dd620f48d80806b7ae12a3c04f11bc678e54721
Author: Vincent Hsiao <[email protected]>
AuthorDate: Wed Sep 9 09:59:07 2026 +0800
Fix XCom slice endpoint for crossed bounds (#72584)
---
.../src/airflow/api_fastapi/execution_api/routes/xcoms.py | 14 ++++++++++----
.../api_fastapi/execution_api/versions/head/test_xcoms.py | 4 ++++
2 files changed, 14 insertions(+), 4 deletions(-)
diff --git a/airflow-core/src/airflow/api_fastapi/execution_api/routes/xcoms.py
b/airflow-core/src/airflow/api_fastapi/execution_api/routes/xcoms.py
index 2e1736a5290..4dd7f6818fc 100644
--- a/airflow-core/src/airflow/api_fastapi/execution_api/routes/xcoms.py
+++ b/airflow-core/src/airflow/api_fastapi/execution_api/routes/xcoms.py
@@ -178,6 +178,12 @@ class GetXComSliceFilterParams(BaseModel):
include_prior_dates: bool = False
+def _get_sliced_query_or_empty(query: Select, low: int, high: int) -> Select:
+ if high <= low:
+ return query.limit(0)
+ return query.slice(low, high)
+
+
@router.get(
"/{dag_id}/{run_id}/{task_id}/{key:path}/slice",
description="Get XCom values from a mapped task by sequence slice",
@@ -235,9 +241,9 @@ def get_mapped_xcom_by_slice(
if stop < 0:
stop += get_query_count(query, session=session)
if step >= 0:
- query = query.slice(start, stop)
+ query = _get_sliced_query_or_empty(query, start, stop)
else:
- query = query.slice(stop + 1, start + 1)
+ query = _get_sliced_query_or_empty(query, stop + 1, start + 1)
else:
query = query.order_by(XComModel.map_index.desc())
step = -step
@@ -250,9 +256,9 @@ def get_mapped_xcom_by_slice(
if stop >= 0:
stop -= get_query_count(query, session=session)
if step > 0:
- query = query.slice(-1 - start, -1 - stop)
+ query = _get_sliced_query_or_empty(query, -1 - start, -1 -
stop)
else:
- query = query.slice(-stop, -start)
+ query = _get_sliced_query_or_empty(query, -stop, -start)
values = [row.value for row in
session.execute(query.with_only_columns(XComModel.value)).all()]
if step != 1:
diff --git
a/airflow-core/tests/unit/api_fastapi/execution_api/versions/head/test_xcoms.py
b/airflow-core/tests/unit/api_fastapi/execution_api/versions/head/test_xcoms.py
index 0b424dedc5d..64ddba31fc0 100644
---
a/airflow-core/tests/unit/api_fastapi/execution_api/versions/head/test_xcoms.py
+++
b/airflow-core/tests/unit/api_fastapi/execution_api/versions/head/test_xcoms.py
@@ -232,6 +232,10 @@ class TestXComsGetEndpoint:
pytest.param(slice(1, None, None), id="1:"),
pytest.param(slice(2, None, -1), id="2::-1"),
pytest.param(slice(1, 2, None), id="1:2"),
+ pytest.param(slice(2, 1, None), id="2:1"),
+ pytest.param(slice(1, -1, -1), id="1:-1:-1"),
+ pytest.param(slice(-1, -2, None), id="-1:-2"),
+ pytest.param(slice(-3, -1, -1), id="-3:-1:-1"),
pytest.param(slice(2, 1, -1), id="2:1:-1"),
pytest.param(slice(1, -1, None), id="1:-1"),
pytest.param(slice(2, -2, -1), id="2:-2:-1"),