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
(cherry picked from commit
fe2ced9e79b9640f3ca135f8d3782dd41ca16782)
--- /dev/null
+.. 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.
)
-class FunctionFilter(ColumnElement[_T]):
+class FunctionFilter(Generative, ColumnElement[_T]):
"""Represent a function FILTER clause.
This is a special operator against aggregate and window functions,
*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.
"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,