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

   <!-- SPDX-License-Identifier: Apache-2.0
         https://www.apache.org/licenses/LICENSE-2.0 -->
   
   closes: #73248
   
   On PostgreSQL, migration 0049 converts `xcom.value` from `bytea` to `jsonb`. 
A single `jsonb` document holds at most 268435455 bytes of array elements or 
object pairs, while `bytea` allowed up to 1 GB, so a value written by Airflow 2 
can be impossible to convert. The conversion is a single atomic `ALTER TABLE 
xcom ALTER COLUMN value TYPE JSONB USING CAST(...)`, so one such row aborts the 
entire migration with `ProgramLimitExceeded`, leaves alembic at `9fc3fc5de720`, 
and
   every retry fails at the same step. The only way forward today is to find 
and delete the rows by hand.
   
   This moves those values into the `_xcom_archive` table the migration already 
creates for the pickled values it also cannot convert, so no new table is 
introduced and the upgrade completes. The `dag_id`/`task_id`/`run_id`/`key` of 
everything archived is printed, so the affected XComs can still be retrieved 
afterwards. The two kinds of archived row are distinguishable by their
   first byte (`0x80` for pickled).
   
   ### Why the rows are chosen by attempting the conversion, not by size
   
   Size is unreliable in both directions, so the migration defines a `pg_temp` 
function that tries the exact cast the `ALTER` will perform and archives only 
the rows that genuinely fail:
   
   - The limit applies to a document's **elements**, not to the value as a 
whole, so a long top-level string can be far larger than 268435455 bytes and 
still convert. Filtering on size would archive data unnecessarily.
   - The parse expands the value enormously, so a value far **under** the limit 
can still fail. Measured on PostgreSQL 16, the densest possible input 
(`[1,1,1,...]`, two bytes per element) converts fine at 30.5 MB of text and 
fails from roughly 34.3 MB with `invalid memory alloc request size 1073741824` 
— it exhausts the 1 GB allocation limit long before the element cap is reached. 
Filtering at 268435455 would miss these entirely and the migration would still 
abort.
   
   An `octet_length` screen in front of the probe keeps it off rows that cannot 
be affected. It is set at 8 MB, about 4x below the smallest measured failure, 
and is deliberately not derived from the element cap, which is not what a value 
of this shape hits first.
   
   Scoped to PostgreSQL — MySQL and SQLite use generic `JSON` and have no 
equivalent per-value cap.
   
   ### Testing
   
   Verified against PostgreSQL 16:
   
   - Reproduced the reported failure: a 283 MB value fails the unpatched cast 
with
     `ProgramLimitExceeded: total size of jsonb array elements exceeds the 
maximum of 268435455 bytes`,
     and with this change it is archived and the cast completes.
   - The added test asserts that an unconvertible row is archived, that a 
**valid** row above the
     screen is kept (so the probe decides, not the size), and that the cast 
then succeeds.
   - The existing sanitization regression suite still passes — no change to 
NaN/Infinity or NUL
     handling.
   
   ### Note on the issue's suggested detection query
   
   The issue proposes `octet_length(value) > 268435455` as a pre-upgrade check. 
That is a useful
   guide but, per the above, is neither necessary nor sufficient. The upgrade 
docs updated here say
   so and point at the list the migration itself prints.
   
   
   * 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