This is an automated email from the ASF dual-hosted git repository.

ephraimanierobi pushed a commit to branch v3-1-test
in repository https://gitbox.apache.org/repos/asf/airflow.git

commit e73a90866d7ad746c9a9761d248be8936590779b
Author: Amogh Desai <[email protected]>
AuthorDate: Fri Oct 31 23:23:26 2025 +0530

    Fix upgrade failure when xcom contains NaN in string values (#57614)
    
    (cherry picked from commit 376ab5d877b74a676132c5c69e5cd535037632ec)
---
 airflow-core/docs/img/airflow_erd.sha256                          | 2 +-
 .../versions/0049_3_0_0_remove_pickled_data_from_xcom_table.py    | 8 ++++++--
 2 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/airflow-core/docs/img/airflow_erd.sha256 
b/airflow-core/docs/img/airflow_erd.sha256
index 6162bcff312..bbe090dba2f 100644
--- a/airflow-core/docs/img/airflow_erd.sha256
+++ b/airflow-core/docs/img/airflow_erd.sha256
@@ -1 +1 @@
-db7901e22801d299714b84b9a676081b12bc6247de807cb2469f3c59bdabcfad
\ No newline at end of file
+977556bd7302c9f753e206b6fa0bfb3a2b123d2cb1b3ef177460b02dd10e10b4
\ No newline at end of file
diff --git 
a/airflow-core/src/airflow/migrations/versions/0049_3_0_0_remove_pickled_data_from_xcom_table.py
 
b/airflow-core/src/airflow/migrations/versions/0049_3_0_0_remove_pickled_data_from_xcom_table.py
index f7d7093649e..549ab600948 100644
--- 
a/airflow-core/src/airflow/migrations/versions/0049_3_0_0_remove_pickled_data_from_xcom_table.py
+++ 
b/airflow-core/src/airflow/migrations/versions/0049_3_0_0_remove_pickled_data_from_xcom_table.py
@@ -114,10 +114,12 @@ def upgrade():
 
     # Update the values from nan to nan string
     if dialect == "postgresql":
+        # Replace standalone NaN tokens only (not NaN inside string values)
+        # Use regex with word boundaries to match only standalone NaN tokens
         conn.execute(
             text("""
                 UPDATE xcom
-                SET value = convert_to(replace(convert_from(value, 'UTF8'), 
'NaN', '"nan"'), 'UTF8')
+                SET value = convert_to(regexp_replace(convert_from(value, 
'UTF8'), '\\bNaN\\b', '"nan"'), 'UTF8')
                 WHERE value IS NOT NULL AND get_byte(value, 0) != 128
             """)
         )
@@ -133,10 +135,12 @@ def upgrade():
             """
         )
     elif dialect == "mysql":
+        # Replace standalone NaN tokens only (not NaN inside string values)
+        # MySQL 8.0 supports REGEXP_REPLACE with word boundaries, use that here
         conn.execute(
             text("""
                 UPDATE xcom
-                SET value = CONVERT(REPLACE(CONVERT(value USING utf8mb4), 
'NaN', '"nan"') USING BINARY)
+                SET value = CONVERT(REGEXP_REPLACE(CONVERT(value USING 
utf8mb4), '[[:<:]]NaN[[:>:]]', '"nan"') USING BINARY)
                 WHERE value IS NOT NULL AND HEX(SUBSTRING(value, 1, 1)) != '80'
             """)
         )

Reply via email to