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

shahar1 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 a211be1c115 Fix MySQL HITL responded-by filters (#67323)
a211be1c115 is described below

commit a211be1c115fdb8d245d6ddc640b5254b9dd3512
Author: Henry Chen <[email protected]>
AuthorDate: Thu Oct 29 14:41:42 2026 +0800

    Fix MySQL HITL responded-by filters (#67323)
---
 airflow-core/src/airflow/models/hitl.py     | 17 +++++++--
 airflow-core/tests/unit/models/test_hitl.py | 55 +++++++++++++++++++++++++++++
 2 files changed, 69 insertions(+), 3 deletions(-)

diff --git a/airflow-core/src/airflow/models/hitl.py 
b/airflow-core/src/airflow/models/hitl.py
index dda93d9c86f..ef7c1e4aa21 100644
--- a/airflow-core/src/airflow/models/hitl.py
+++ b/airflow-core/src/airflow/models/hitl.py
@@ -61,11 +61,22 @@ def compile_postgres(element: JSONExtract, compiler: 
SQLCompiler, **kwargs: dict
     return compiler.process(func.json_extract_path_text(column, key), **kwargs)
 
 
-@compiles(JSONExtract, "sqlite")
 @compiles(JSONExtract, "mysql")
-def compile_sqlite_mysql(element: JSONExtract, compiler: SQLCompiler, 
**kwargs: dict[str, Any]) -> str:
+def compile_mysql(element: JSONExtract, compiler: SQLCompiler, **kwargs: 
dict[str, Any]) -> str:
+    """
+    Compile JSONExtract for MySQL.
+
+    :meta: private
+    """
+    column, key = element.clauses
+    extracted = func.json_extract(column, f"$.{key.value}")
+    return compiler.process(func.json_unquote(extracted), **kwargs)
+
+
+@compiles(JSONExtract, "sqlite")
+def compile_sqlite(element: JSONExtract, compiler: SQLCompiler, **kwargs: 
dict[str, Any]) -> str:
     """
-    Compile JSONExtract for SQLite/MySQL.
+    Compile JSONExtract for SQLite.
 
     :meta: private
     """
diff --git a/airflow-core/tests/unit/models/test_hitl.py 
b/airflow-core/tests/unit/models/test_hitl.py
new file mode 100644
index 00000000000..c0e92d81b4a
--- /dev/null
+++ b/airflow-core/tests/unit/models/test_hitl.py
@@ -0,0 +1,55 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+from __future__ import annotations
+
+import pytest
+from sqlalchemy.dialects import mysql, postgresql, sqlite
+
+from airflow.models.hitl import HITLDetail
+
+
+class TestJSONExtract:
+    """The HITL responded-by filters compare against plain strings, so every 
dialect must yield text."""
+
+    @pytest.mark.parametrize("key", ["id", "name"])
+    @pytest.mark.parametrize(
+        ("dialect", "expected_sql"),
+        [
+            pytest.param(
+                mysql.dialect(),
+                "json_unquote(json_extract(hitl_detail.responded_by, 
'$.{key}'))",
+                id="mysql",
+            ),
+            pytest.param(
+                sqlite.dialect(),
+                "json_extract(hitl_detail.responded_by, '$.{key}')",
+                id="sqlite",
+            ),
+            pytest.param(
+                postgresql.dialect(),
+                "json_extract_path_text(hitl_detail.responded_by, '{key}')",
+                id="postgresql",
+            ),
+        ],
+    )
+    def test_compiles_to_text_returning_sql_per_dialect(self, dialect, 
expected_sql: str, key: str) -> None:
+        expression = getattr(HITLDetail, f"responded_by_user_{key}")
+
+        compiled = expression.compile(dialect=dialect, 
compile_kwargs={"literal_binds": True})
+
+        assert str(compiled) == expected_sql.format(key=key)

Reply via email to