From: Mike Bayer Date: Wed, 24 Jun 2026 12:49:30 +0000 (-0400) Subject: override get_select_precolumns() in StrSQLCompiler X-Git-Tag: rel_2_1_0b3~6 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=101fd7f9b31db22f6ca2efdd3384a1e2751890bd;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git override get_select_precolumns() in StrSQLCompiler 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 --- diff --git a/doc/build/changelog/unreleased_20/13396.rst b/doc/build/changelog/unreleased_20/13396.rst new file mode 100644 index 0000000000..e25fd6d629 --- /dev/null +++ b/doc/build/changelog/unreleased_20/13396.rst @@ -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`). diff --git a/lib/sqlalchemy/sql/compiler.py b/lib/sqlalchemy/sql/compiler.py index 890a92f634..42b64ec726 100644 --- a/lib/sqlalchemy/sql/compiler.py +++ b/lib/sqlalchemy/sql/compiler.py @@ -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 "" diff --git a/test/sql/test_compiler.py b/test/sql/test_compiler.py index 50eb4cf75c..3a88da9e12 100644 --- a/test/sql/test_compiler.py +++ b/test/sql/test_compiler.py @@ -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(