]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
allow windowing filtered functions
authorIlja Everilä <saarni@gmail.com>
Thu, 11 Sep 2014 12:39:56 +0000 (15:39 +0300)
committerIlja Everilä <saarni@gmail.com>
Thu, 11 Sep 2014 12:39:56 +0000 (15:39 +0300)
lib/sqlalchemy/sql/elements.py
test/sql/test_compiler.py

index 5ac16ab7ad645166c960b41acf64b504d34bbab0..62fe6553a37052cbb3b7ea9e64adc88f536849cb 100644 (file)
@@ -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
index 7bba2956342e70875a5d05ae74fa447162f63dab..fc33db184ce7f39ed4016e66f6099e103a4cece5 100644 (file)
@@ -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,