diff options
author | Ilja Everilä <saarni@gmail.com> | 2014-09-11 15:39:56 +0300 |
---|---|---|
committer | Ilja Everilä <saarni@gmail.com> | 2014-09-11 15:39:56 +0300 |
commit | 52a095ba6675f5f5807a1dc655b4ae32b9999f27 (patch) | |
tree | 88a3592ea51dbca2e438b720ca303050d9c14d54 | |
parent | ab1c25266dd49f087b5fff316b6ba6fb610b1d35 (diff) | |
download | sqlalchemy-52a095ba6675f5f5807a1dc655b4ae32b9999f27.tar.gz |
allow windowing filtered functions
-rw-r--r-- | lib/sqlalchemy/sql/elements.py | 20 | ||||
-rw-r--r-- | test/sql/test_compiler.py | 27 |
2 files changed, 47 insertions, 0 deletions
diff --git a/lib/sqlalchemy/sql/elements.py b/lib/sqlalchemy/sql/elements.py index 5ac16ab7a..62fe6553a 100644 --- a/lib/sqlalchemy/sql/elements.py +++ b/lib/sqlalchemy/sql/elements.py @@ -2931,6 +2931,26 @@ class FunctionFilter(ColumnElement): return self + def over(self, partition_by=None, order_by=None): + """Produce an OVER clause against this filtered function. + + Used against aggregate or so-called "window" functions, + for database backends that support window functions. + + The expression:: + + func.rank().filter(MyClass.y > 5).over(order_by='x') + + is shorthand for:: + + from sqlalchemy import over, funcfilter + over(funcfilter(func.rank(), MyClass.y > 5), order_by='x') + + See :func:`~.expression.over` for a full description. + + """ + return Over(self, partition_by=partition_by, order_by=order_by) + @util.memoized_property def type(self): return self.func.type diff --git a/test/sql/test_compiler.py b/test/sql/test_compiler.py index 7bba29563..fc33db184 100644 --- a/test/sql/test_compiler.py +++ b/test/sql/test_compiler.py @@ -2254,6 +2254,33 @@ class SelectTest(fixtures.TestBase, AssertsCompiledSQL): "AS anon_1 FROM mytable" ) + # test filtered windowing: + self.assert_compile( + select([ + func.rank().filter( + table1.c.name > 'foo' + ).over( + order_by=table1.c.name + ) + ]), + "SELECT rank() FILTER (WHERE mytable.name > :name_1) " + "OVER (ORDER BY mytable.name) AS anon_1 FROM mytable" + ) + + self.assert_compile( + select([ + func.rank().filter( + table1.c.name > 'foo' + ).over( + order_by=table1.c.name, + partition_by=['description'] + ) + ]), + "SELECT rank() FILTER (WHERE mytable.name > :name_1) " + "OVER (PARTITION BY mytable.description ORDER BY mytable.name) " + "AS anon_1 FROM mytable" + ) + def test_date_between(self): import datetime table = Table('dt', metadata, |