]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Make `FunctionFilter.filter` generative
authorFederico Caselli <cfederico87@gmail.com>
Wed, 29 May 2024 19:39:08 +0000 (21:39 +0200)
committerFederico Caselli <cfederico87@gmail.com>
Thu, 30 May 2024 20:25:33 +0000 (22:25 +0200)
Fixed bug in :meth:`_sql.FunctionFilter.filter` that would mutate
the existing function in-place. It now behaves like the rest of the
SQLAlchemy API, returning a new instance instead of mutating the
original one.

Fixes: #11426
Change-Id: I46ffebaed82426cfb1623db066686cfb911055a1

doc/build/changelog/unreleased_20/11426.rst [new file with mode: 0644]
lib/sqlalchemy/sql/elements.py
test/sql/test_functions.py

diff --git a/doc/build/changelog/unreleased_20/11426.rst b/doc/build/changelog/unreleased_20/11426.rst
new file mode 100644 (file)
index 0000000..c9018b0
--- /dev/null
@@ -0,0 +1,8 @@
+.. change::
+    :tags: bug, sql
+    :tickets: 11426
+
+    Fixed bug in :meth:`_sql.FunctionFilter.filter` that would mutate
+    the existing function in-place. It now behaves like the rest of the
+    SQLAlchemy API, returning a new instance instead of mutating the
+    original one.
index 080011eb7d0b8ca1e16f20ba23cc6449e0e896e8..c82c2751d116e5744fb16b7db9e23196ee403700 100644 (file)
@@ -4366,7 +4366,7 @@ class WithinGroup(ColumnElement[_T]):
         )
 
 
-class FunctionFilter(ColumnElement[_T]):
+class FunctionFilter(Generative, ColumnElement[_T]):
     """Represent a function FILTER clause.
 
     This is a special operator against aggregate and window functions,
@@ -4399,8 +4399,9 @@ class FunctionFilter(ColumnElement[_T]):
         *criterion: _ColumnExpressionArgument[bool],
     ):
         self.func = func
-        self.filter(*criterion)
+        self.filter.non_generative(self, *criterion)  # type: ignore
 
+    @_generative
     def filter(self, *criterion: _ColumnExpressionArgument[bool]) -> Self:
         """Produce an additional FILTER against the function.
 
index c47601b7616622c9c66a78eed982fe93063ef7eb..c324c8f33abebe7d7791e0ea91aca773e1226994 100644 (file)
@@ -844,6 +844,17 @@ class CompileTest(fixtures.TestBase, AssertsCompiledSQL):
             "AS anon_1 FROM mytable",
         )
 
+    def test_funcfilter_more_criteria(self):
+        ff = func.rank().filter(table1.c.name > "foo")
+        ff2 = ff.filter(table1.c.myid == 1)
+        self.assert_compile(
+            select(ff, ff2),
+            "SELECT rank() FILTER (WHERE mytable.name > :name_1) AS anon_1, "
+            "rank() FILTER (WHERE mytable.name > :name_1 AND "
+            "mytable.myid = :myid_1) AS anon_2 FROM mytable",
+            {"name_1": "foo", "myid_1": 1},
+        )
+
     def test_funcfilter_within_group(self):
         stmt = select(
             table1.c.myid,