This is an automated email from the ASF dual-hosted git repository.
amoghdesai 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 abb42c21ef2 Bump sqlglot range to 30+ in common ai (#63784)
abb42c21ef2 is described below
commit abb42c21ef2b0e5ef2fc2858c70f13a1058d403c
Author: Amogh Desai <[email protected]>
AuthorDate: Tue Mar 17 15:23:14 2026 +0530
Bump sqlglot range to 30+ in common ai (#63784)
---
docs/spelling_wordlist.txt | 1 +
providers/common/ai/pyproject.toml | 4 ++--
.../providers/common/ai/operators/llm_sql.py | 2 +-
.../providers/common/ai/utils/sql_validation.py | 10 ++++-----
uv.lock | 26 +++++++++++-----------
5 files changed, 22 insertions(+), 21 deletions(-)
diff --git a/docs/spelling_wordlist.txt b/docs/spelling_wordlist.txt
index bf61681f903..0f0ee26d8bd 100644
--- a/docs/spelling_wordlist.txt
+++ b/docs/spelling_wordlist.txt
@@ -583,6 +583,7 @@ exitcode
expanduser
explicit
exportingmultiple
+Expr
ext
extensibility
externalbrowser
diff --git a/providers/common/ai/pyproject.toml
b/providers/common/ai/pyproject.toml
index 502e65b975f..6e1cbe50f56 100644
--- a/providers/common/ai/pyproject.toml
+++ b/providers/common/ai/pyproject.toml
@@ -81,7 +81,7 @@ dependencies = [
"mcp" = ["pydantic-ai-slim[mcp]"]
"sql" = [
"apache-airflow-providers-common-sql",
- "sqlglot>=26.0.0",
+ "sqlglot>=30.0.0",
]
"common.sql" = [
"apache-airflow-providers-common-sql"
@@ -96,7 +96,7 @@ dev = [
"apache-airflow-providers-common-sql",
"apache-airflow-providers-standard",
# Additional devel dependencies (do not remove this line and add extra
development dependencies)
- "sqlglot>=26.0.0",
+ "sqlglot>=30.0.0",
"pydantic-ai-slim[mcp]",
"apache-airflow-providers-common-sql[datafusion]"
]
diff --git
a/providers/common/ai/src/airflow/providers/common/ai/operators/llm_sql.py
b/providers/common/ai/src/airflow/providers/common/ai/operators/llm_sql.py
index 05ffc1cdf5f..53c1424fb0f 100644
--- a/providers/common/ai/src/airflow/providers/common/ai/operators/llm_sql.py
+++ b/providers/common/ai/src/airflow/providers/common/ai/operators/llm_sql.py
@@ -109,7 +109,7 @@ class LLMSQLQueryOperator(LLMOperator):
table_names: list[str] | None = None,
schema_context: str | None = None,
validate_sql: bool = True,
- allowed_sql_types: tuple[type[exp.Expression], ...] =
DEFAULT_ALLOWED_TYPES,
+ allowed_sql_types: tuple[type[exp.Expr], ...] = DEFAULT_ALLOWED_TYPES,
dialect: str | None = None,
datasource_config: DataSourceConfig | None = None,
**kwargs: Any,
diff --git
a/providers/common/ai/src/airflow/providers/common/ai/utils/sql_validation.py
b/providers/common/ai/src/airflow/providers/common/ai/utils/sql_validation.py
index e20b8804f80..42d41dcfc7d 100644
---
a/providers/common/ai/src/airflow/providers/common/ai/utils/sql_validation.py
+++
b/providers/common/ai/src/airflow/providers/common/ai/utils/sql_validation.py
@@ -32,7 +32,7 @@ from sqlglot.errors import ErrorLevel
# - Select: plain queries and CTE-wrapped queries (WITH ... AS ... SELECT is
parsed
# as Select with a `with` clause property — still a Select node at the top
level)
# - Union/Intersect/Except: set operations on SELECT results
-DEFAULT_ALLOWED_TYPES: tuple[type[exp.Expression], ...] = (
+DEFAULT_ALLOWED_TYPES: tuple[type[exp.Expr], ...] = (
exp.Select,
exp.Union,
exp.Intersect,
@@ -47,10 +47,10 @@ class SQLSafetyError(Exception):
def validate_sql(
sql: str,
*,
- allowed_types: tuple[type[exp.Expression], ...] | None = None,
+ allowed_types: tuple[type[exp.Expr], ...] | None = None,
dialect: str | None = None,
allow_multiple_statements: bool = False,
-) -> list[exp.Expression]:
+) -> list[exp.Expr]:
"""
Parse SQL and verify all statements are in the allowed types list.
@@ -66,7 +66,7 @@ def validate_sql(
:param dialect: SQL dialect for parsing (``postgres``, ``mysql``, etc.).
:param allow_multiple_statements: Whether to allow multiple
semicolon-separated
statements. Default ``False``.
- :return: List of parsed sqlglot Expression objects.
+ :return: List of parsed sqlglot Expr objects.
:raises SQLSafetyError: If the SQL is empty, contains disallowed statement
types,
or has multiple statements when not permitted.
"""
@@ -81,7 +81,7 @@ def validate_sql(
raise SQLSafetyError(f"SQL parse error: {e}") from e
# sqlglot.parse can return [None] for empty input
- parsed: list[exp.Expression] = [s for s in statements if s is not None] #
type: ignore[misc]
+ parsed: list[exp.Expr] = [s for s in statements if s is not None]
if not parsed:
raise SQLSafetyError("Empty SQL input.")
diff --git a/uv.lock b/uv.lock
index 3a33b968f69..254e349f702 100644
--- a/uv.lock
+++ b/uv.lock
@@ -3828,7 +3828,7 @@ requires-dist = [
{ name = "pydantic-ai-slim", extras = ["google"], marker = "extra ==
'google'" },
{ name = "pydantic-ai-slim", extras = ["mcp"], marker = "extra == 'mcp'" },
{ name = "pydantic-ai-slim", extras = ["openai"], marker = "extra ==
'openai'" },
- { name = "sqlglot", marker = "extra == 'sql'", specifier = ">=26.0.0" },
+ { name = "sqlglot", marker = "extra == 'sql'", specifier = ">=30.0.0" },
]
provides-extras = ["anthropic", "bedrock", "google", "openai", "mcp", "sql",
"common-sql"]
@@ -3842,7 +3842,7 @@ dev = [
{ name = "apache-airflow-providers-standard", editable =
"providers/standard" },
{ name = "apache-airflow-task-sdk", editable = "task-sdk" },
{ name = "pydantic-ai-slim", extras = ["mcp"] },
- { name = "sqlglot", specifier = ">=26.0.0" },
+ { name = "sqlglot", specifier = ">=30.0.0" },
]
docs = [{ name = "apache-airflow-devel-common", extras = ["docs"], editable =
"devel-common" }]
@@ -19644,8 +19644,8 @@ name = "secretstorage"
version = "3.5.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
- { name = "cryptography" },
- { name = "jeepney" },
+ { name = "cryptography", marker = "(python_full_version < '3.14' and
sys_platform == 'emscripten') or (python_full_version < '3.14' and sys_platform
== 'win32') or (sys_platform != 'emscripten' and sys_platform != 'win32')" },
+ { name = "jeepney", marker = "(python_full_version < '3.14' and
sys_platform == 'emscripten') or (python_full_version < '3.14' and sys_platform
== 'win32') or (sys_platform != 'emscripten' and sys_platform != 'win32')" },
]
sdist = { url =
"https://files.pythonhosted.org/packages/1c/03/e834bcd866f2f8a49a85eaff47340affa3bfa391ee9912a952a1faa68c7b/secretstorage-3.5.0.tar.gz",
hash =
"sha256:f04b8e4689cbce351744d5537bf6b1329c6fc68f91fa666f60a380edddcd11be", size
= 19884, upload-time = "2025-11-23T19:02:53.191Z" }
wheels = [
@@ -19968,15 +19968,15 @@ name = "snowflake-snowpark-python"
version = "1.47.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
- { name = "cloudpickle" },
- { name = "protobuf" },
- { name = "python-dateutil" },
- { name = "pyyaml" },
- { name = "setuptools" },
- { name = "snowflake-connector-python" },
- { name = "typing-extensions" },
- { name = "tzlocal" },
- { name = "wheel" },
+ { name = "cloudpickle", marker = "python_full_version < '3.14'" },
+ { name = "protobuf", marker = "python_full_version < '3.14'" },
+ { name = "python-dateutil", marker = "python_full_version < '3.14'" },
+ { name = "pyyaml", marker = "python_full_version < '3.14'" },
+ { name = "setuptools", marker = "python_full_version < '3.14'" },
+ { name = "snowflake-connector-python", marker = "python_full_version <
'3.14'" },
+ { name = "typing-extensions", marker = "python_full_version < '3.14'" },
+ { name = "tzlocal", marker = "python_full_version < '3.14'" },
+ { name = "wheel", marker = "python_full_version < '3.14'" },
]
sdist = { url =
"https://files.pythonhosted.org/packages/91/9a/0377127c344f2ccdf0877f96bf7a0215ea686d2656987698f972e6aab717/snowflake_snowpark_python-1.47.0.tar.gz",
hash =
"sha256:e4b4bfb24a52b50fe32746935fb6d0337183d57d3967ecd001c5cebe4a695a54", size
= 1735283, upload-time = "2026-03-05T18:18:19.121Z" }
wheels = [