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

michaelsmolina pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/superset.git


The following commit(s) were added to refs/heads/master by this push:
     new c41942a38ad chore(deps): Upgrade sqlglot from 27.15.2 to 28.10.0 
(#37841)
c41942a38ad is described below

commit c41942a38ad1a4139526340042a31a6df8f67bef
Author: Michael S. Molina <[email protected]>
AuthorDate: Tue Feb 10 13:13:11 2026 -0300

    chore(deps): Upgrade sqlglot from 27.15.2 to 28.10.0 (#37841)
---
 pyproject.toml                      |  2 +-
 requirements/base.txt               |  2 +-
 requirements/development.txt        |  2 +-
 superset-core/pyproject.toml        |  2 +-
 superset/sql/dialects/pinot.py      |  2 ++
 superset/sql/parse.py               | 10 +++++-----
 tests/unit_tests/sql/parse_tests.py | 17 +++++++++++++++++
 7 files changed, 28 insertions(+), 9 deletions(-)

diff --git a/pyproject.toml b/pyproject.toml
index b9100a9b2c5..77abbf8b977 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -100,7 +100,7 @@ dependencies = [
     "slack_sdk>=3.19.0, <4",
     "sqlalchemy>=1.4, <2",
     "sqlalchemy-utils>=0.38.3, <0.39",
-    "sqlglot>=27.15.2, <28",
+    "sqlglot>=28.10.0, <29",
     # newer pandas needs 0.9+
     "tabulate>=0.9.0, <1.0",
     "typing-extensions>=4, <5",
diff --git a/requirements/base.txt b/requirements/base.txt
index 445c3ae8812..e96797714a0 100644
--- a/requirements/base.txt
+++ b/requirements/base.txt
@@ -404,7 +404,7 @@ sqlalchemy-utils==0.38.3
     #   apache-superset (pyproject.toml)
     #   apache-superset-core
     #   flask-appbuilder
-sqlglot==27.15.2
+sqlglot==28.10.0
     # via
     #   apache-superset (pyproject.toml)
     #   apache-superset-core
diff --git a/requirements/development.txt b/requirements/development.txt
index 82bb3e76232..7bb5c766343 100644
--- a/requirements/development.txt
+++ b/requirements/development.txt
@@ -996,7 +996,7 @@ sqlalchemy-utils==0.38.3
     #   apache-superset
     #   apache-superset-core
     #   flask-appbuilder
-sqlglot==27.15.2
+sqlglot==28.10.0
     # via
     #   -c requirements/base-constraint.txt
     #   apache-superset
diff --git a/superset-core/pyproject.toml b/superset-core/pyproject.toml
index 80b57b49b1c..ff8a1400eb7 100644
--- a/superset-core/pyproject.toml
+++ b/superset-core/pyproject.toml
@@ -46,7 +46,7 @@ dependencies = [
     "pydantic>=2.8.0",
     "sqlalchemy>=1.4.0,<2.0",
     "sqlalchemy-utils>=0.38.0",
-    "sqlglot>=27.15.2, <28",
+    "sqlglot>=28.10.0, <29",
     "typing-extensions>=4.0.0",
 ]
 
diff --git a/superset/sql/dialects/pinot.py b/superset/sql/dialects/pinot.py
index e0aca308171..6344fee4a0d 100644
--- a/superset/sql/dialects/pinot.py
+++ b/superset/sql/dialects/pinot.py
@@ -144,6 +144,8 @@ class Pinot(MySQL):
                 e.args.get("expression"),
                 e.args.get("variant"),
             ),
+            # Preserve Pinot's YEAROFWEEK (sqlglot normalizes to YEAR_OF_WEEK)
+            exp.YearOfWeek: lambda self, e: self.func("YEAROFWEEK", e.this),
         }
         # Remove DATE_TRUNC transformation - Pinot supports standard SQL 
DATE_TRUNC
         TRANSFORMS.pop(exp.DateTrunc, None)
diff --git a/superset/sql/parse.py b/superset/sql/parse.py
index 843962eb091..fdbc524b149 100644
--- a/superset/sql/parse.py
+++ b/superset/sql/parse.py
@@ -271,7 +271,7 @@ class RLSAsSubqueryTransformer(RLSTransformer):
                 this=exp.Select(
                     expressions=[exp.Star()],
                     where=exp.Where(this=predicate),
-                    **{"from": exp.From(this=node.copy())},
+                    from_=exp.From(this=node.copy()),
                 ),
                 alias=alias,
             )
@@ -816,7 +816,7 @@ class SQLStatement(BaseSQLStatement[exp.Expression]):
                 limit=exp.Limit(
                     expression=exp.Literal(this=str(limit), is_string=False)
                 ),
-                **{"from": 
exp.From(this=exp.Subquery(this=self._parsed.copy()))},
+                from_=exp.From(this=exp.Subquery(this=self._parsed.copy())),
             )
         else:  # method == LimitMethod.FETCH_MANY
             pass
@@ -827,7 +827,7 @@ class SQLStatement(BaseSQLStatement[exp.Expression]):
 
         :return: True if the statement has a CTE at the top level.
         """
-        return "with" in self._parsed.args
+        return bool(self._parsed.args.get("with_"))
 
     def as_cte(self, alias: str = "__cte") -> SQLStatement:
         """
@@ -840,8 +840,8 @@ class SQLStatement(BaseSQLStatement[exp.Expression]):
         :param alias: The alias to use for the CTE.
         :return: A new SQLStatement with the CTE.
         """
-        existing_ctes = self._parsed.args["with"].expressions if 
self.has_cte() else []
-        self._parsed.args["with"] = None
+        existing_ctes = self._parsed.args["with_"].expressions if 
self.has_cte() else []
+        self._parsed.args["with_"] = None
         new_cte = exp.CTE(
             this=self._parsed.copy(),
             alias=exp.TableAlias(this=exp.Identifier(this=alias)),
diff --git a/tests/unit_tests/sql/parse_tests.py 
b/tests/unit_tests/sql/parse_tests.py
index b50718173cb..57bab2b9589 100644
--- a/tests/unit_tests/sql/parse_tests.py
+++ b/tests/unit_tests/sql/parse_tests.py
@@ -1867,6 +1867,23 @@ def test_as_cte(sql: str, engine: str, expected: str) -> 
None:
     assert SQLStatement(sql, engine).as_cte().format() == expected
 
 
+def test_as_cte_called_twice() -> None:
+    """
+    Test that calling as_cte() multiple times on the same instance works.
+
+    Regression test for a bug where as_cte() sets self._parsed.args["with_"] = 
None
+    after extracting CTEs, but has_cte() only checked if the key existed, not 
if
+    the value was truthy. This caused an AttributeError on subsequent as_cte() 
calls.
+    """
+    sql = "WITH cte AS (SELECT 1) SELECT * FROM cte"
+    stmt = SQLStatement(sql, "postgresql")
+
+    assert stmt.has_cte() is True
+    stmt.as_cte()
+    assert stmt.has_cte() is False
+    stmt.as_cte()
+
+
 @pytest.mark.parametrize(
     "sql, rules, expected",
     [

Reply via email to