]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
override get_select_precolumns() in StrSQLCompiler
authorMike Bayer <mike_mp@zzzcomputing.com>
Wed, 24 Jun 2026 12:49:30 +0000 (08:49 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Wed, 24 Jun 2026 20:04:25 +0000 (16:04 -0400)
Fixed issue where :meth:`_sql.Select.get_final_froms` would emit a
deprecation warning when the statement made use of the PostgreSQL-specific
expression argument to :meth:`_sql.Select.distinct`; the same spurious
warning would be emitted when stringifying such a statement without
explicitly using a PostgreSQL dialect.  The fix ensures that this 1.4-era
warning is suppressed under both 2.0 and 2.1.

Note that under SQLAlchemy 2.1, passing an expression to
:meth:`_sql.Select.distinct` is deprecated overall, and is replaced by a
new PostgreSQL-specific construct (see :ticket:`12342`).

Fixes: #13396
Change-Id: I587e24aa7016c56b1d5bfe1048c4b6eb809dfb30

doc/build/changelog/unreleased_20/13396.rst [new file with mode: 0644]
lib/sqlalchemy/sql/compiler.py
test/sql/test_compiler.py

diff --git a/doc/build/changelog/unreleased_20/13396.rst b/doc/build/changelog/unreleased_20/13396.rst
new file mode 100644 (file)
index 0000000..e25fd6d
--- /dev/null
@@ -0,0 +1,14 @@
+.. change::
+    :tags: bug, sql
+    :tickets: 13396
+
+    Fixed issue where :meth:`_sql.Select.get_final_froms` would emit a
+    deprecation warning when the statement made use of the PostgreSQL-specific
+    expression argument to :meth:`_sql.Select.distinct`; the same spurious
+    warning would be emitted when stringifying such a statement without
+    explicitly using a PostgreSQL dialect.  The fix ensures that this 1.4-era
+    warning is suppressed under both 2.0 and 2.1.
+
+    Note that under SQLAlchemy 2.1, passing an expression to
+    :meth:`_sql.Select.distinct` is deprecated overall, and is replaced by a
+    new PostgreSQL-specific construct (see :ticket:`12342`).
index 890a92f634cfce541ac3c88aa5bd103ce24d57d9..42b64ec726391b238bddfac8e4c804897197d06d 100644 (file)
@@ -6898,6 +6898,9 @@ class StrSQLCompiler(SQLCompiler):
 
     """
 
+    def get_select_precolumns(self, select: Select[Any], **kw: Any) -> str:
+        return "DISTINCT " if select._distinct else ""
+
     def _fallback_column_name(self, column):
         return "<name unknown>"
 
index 50eb4cf75c76f5b12c80f0b103f24dd1d6d078d7..3a88da9e121395d9d8e40936b59284638afb2f92 100644 (file)
@@ -106,6 +106,7 @@ from sqlalchemy.testing import assert_raises_message
 from sqlalchemy.testing import AssertsCompiledSQL
 from sqlalchemy.testing import eq_
 from sqlalchemy.testing import eq_ignore_whitespace
+from sqlalchemy.testing import expect_deprecated
 from sqlalchemy.testing import expect_raises
 from sqlalchemy.testing import expect_raises_message
 from sqlalchemy.testing import fixtures
@@ -1952,6 +1953,24 @@ class SelectTest(fixtures.TestBase, AssertsCompiledSQL):
             "SELECT DISTINCT mytable.myid AS mytable_myid FROM mytable",
         )
 
+    @testing.variation("case", ["stringify", "final_froms"])
+    def test_distinct_expr_no_dep_warning_str_compiler(self, case):
+        """test for #13396"""
+
+        t = Table("foo", MetaData(), Column("bar"))
+
+        with expect_deprecated(
+            "Passing expression to ``distinct`` to generate a DISTINCT ON"
+        ):
+            stmt = select(t).distinct(t.c.bar)
+
+        if case.stringify:
+            eq_(str(stmt), "SELECT DISTINCT foo.bar \nFROM foo")
+        elif case.final_froms:
+            eq_(stmt.get_final_froms(), [t])
+        else:
+            case.fail()
+
     @testing.emits_warning("Column-expression-level unary distinct")
     def test_distinct_function_6008(self):
         # the bug fixed here as part of #6008 is the same bug that's
@@ -2009,7 +2028,9 @@ class SelectTest(fixtures.TestBase, AssertsCompiledSQL):
             "DISTINCT ON is currently supported only by the PostgreSQL "
             "dialect",
         ):
-            select("*").distinct(table1.c.myid).compile()
+            self.assert_compile(
+                select("*").distinct(table1.c.myid), "SELECT DISTINCT *"
+            )
 
     def test_where_empty(self):
         self.assert_compile(