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)