sahilSENPAII opened a new pull request, #75015:
URL: https://github.com/apache/airflow/pull/75015

   related: #69204, #72584
   
   ### Problem
   
   `GET /execution/xcoms/{dag_id}/{run_id}/{task_id}/{key}/slice` returns wrong 
rows, or fails, when one slice bound lies before the first mapped XCom once it 
is resolved against the row count. With 3 mapped XComs `["f", "o", "b"]`:
   
   | Slice | Python result | Query sent | SQLite | Postgres / MySQL |
   |---|---|---|---|---|
   | `seq[-2:10]` | `["o", "b"]` | `LIMIT 9 OFFSET -7` | `["f", "o", "b"]` | 
negative offset rejected |
   | `seq[1:-10:-1]` | `["o", "f"]` | `LIMIT 8 OFFSET -6` | `["b", "o", "f"]` | 
negative offset rejected |
   | `seq[2:-10:-1]` | `["b", "o", "f"]` | `LIMIT 9 OFFSET -6` | `["b", "o", 
"f"]` (correct by chance) | negative offset rejected |
   
   ### Cause
   
   `_get_sliced_query_or_empty` passes `low` to `Select.slice()` unchanged, and 
SQLAlchemy compiles a negative `low` to a negative `OFFSET` with `LIMIT high - 
low`. SQLite treats the negative offset as 0, so the inflated limit returns 
extra rows. Postgres and MySQL reject the query. A negative `low` is possible 
in two branches of `get_mapped_xcom_by_slice`: a non-negative `start` with a 
negative `step` and a `stop` below `-len`, and a negative `start` with a 
positive `step` and a `stop` above `len`. #72584 fixed the crossed-bounds case 
(`high <= low`) in the same helper, but not this one.
   
   ### Fix
   
   Clamp `low` to 0 in `_get_sliced_query_or_empty` before the existing `high 
<= low` check. This matches how Python slicing clamps an out-of-range bound to 
the start of the sequence. The other two call sites always pass a non-negative 
`low`, so they are unchanged.
   
   ### Testing
   
   - Added `-2:10`, `2:-10:-1` and `1:-10:-1` to the parametrized 
`test_xcom_get_with_slice`, which compares the response with Python slicing.
   - Without the fix, on SQLite: `-2:10` and `1:-10:-1` fail, and `2:-10:-1` 
passes because the inflated limit happens to cover every row. Postgres and 
MySQL reject the negative offset in all three cases, so they would fail there 
too. I checked this by compiling the query for each dialect, not by running 
those backends.
   - With the fix, all three pass. The full `test_xcoms.py` module passes on a 
fresh SQLite database: 156 passed.
   - `prek run --stage pre-commit` passes on the changed files. 
`generate-openapi-spec` and `check-tests-in-the-right-folders` were skipped 
because they need Breeze images.
   
   ---
   
   ##### Was generative AI tooling used to co-author this PR?
   
   - [X] Yes (please specify the tool below)
   
   Generated-by: Claude Code following [the 
guidelines](https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#gen-ai-assisted-contributions)
   
   ---
   
   * Read the **[Pull Request 
Guidelines](https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#pull-request-guidelines)**
 for more information. Note: commit author/co-author name and email in commits 
become permanently public when merged.
   * For fundamental code changes, an Airflow Improvement Proposal 
([AIP](https://cwiki.apache.org/confluence/display/AIRFLOW/Airflow+Improvement+Proposals))
 is needed.
   * When adding dependency, check compliance with the [ASF 3rd Party License 
Policy](https://www.apache.org/legal/resolved.html#category-x).
   * For significant user-facing changes create newsfragment: 
`{pr_number}.significant.rst`, in 
[airflow-core/newsfragments](https://github.com/apache/airflow/tree/main/airflow-core/newsfragments).
 You can add this file in a follow-up commit after the PR is created so you 
know the PR number.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to