]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Add missing range_ / rows parameters to additional over() methods
authorMike Bayer <mike_mp@zzzcomputing.com>
Mon, 20 Aug 2018 02:19:59 +0000 (22:19 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Mon, 20 Aug 2018 02:22:24 +0000 (22:22 -0400)
Added missing window function parameters
:paramref:`.WithinGroup.over.range_` and :paramref:`.WithinGroup.over.rows`
parameters to the :meth:`.WithinGroup.over` and
:meth:`.FunctionFilter.over` methods, to correspond to the range/rows
feature added to the "over" method of SQL functions as part of
:ticket:`3049` in version 1.1.

Fixes: #4322
Change-Id: I77dcdac65c699a4b52a3fc3ee09a100ffb4fc20e

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

diff --git a/doc/build/changelog/unreleased_12/4322.rst b/doc/build/changelog/unreleased_12/4322.rst
new file mode 100644 (file)
index 0000000..f1b1634
--- /dev/null
@@ -0,0 +1,10 @@
+.. change::
+    :tags: bug, sql
+    :tickets: 4322
+
+    Added missing window function parameters
+    :paramref:`.WithinGroup.over.range_` and :paramref:`.WithinGroup.over.rows`
+    parameters to the :meth:`.WithinGroup.over` and
+    :meth:`.FunctionFilter.over` methods, to correspond to the range/rows
+    feature added to the "over" method of SQL functions as part of
+    :ticket:`3049` in version 1.1.
index 2a6fa323cf754d93c2256d29f5dcecbc4a2b47e2..5f9fd2ebf568a3d619b34992fbabcca63a0f0ed6 100644 (file)
@@ -3368,7 +3368,7 @@ class WithinGroup(ColumnElement):
                 *util.to_list(order_by),
                 _literal_as_text=_literal_as_label_reference)
 
-    def over(self, partition_by=None, order_by=None):
+    def over(self, partition_by=None, order_by=None, range_=None, rows=None):
         """Produce an OVER clause against this :class:`.WithinGroup`
         construct.
 
@@ -3376,7 +3376,9 @@ class WithinGroup(ColumnElement):
         :meth:`.FunctionElement.over`.
 
         """
-        return Over(self, partition_by=partition_by, order_by=order_by)
+        return Over(
+            self, partition_by=partition_by, order_by=order_by,
+            range_=range_, rows=rows)
 
     @util.memoized_property
     def type(self):
@@ -3477,7 +3479,7 @@ class FunctionFilter(ColumnElement):
 
         return self
 
-    def over(self, partition_by=None, order_by=None):
+    def over(self, partition_by=None, order_by=None, range_=None, rows=None):
         """Produce an OVER clause against this filtered function.
 
         Used against aggregate or so-called "window" functions,
@@ -3495,7 +3497,9 @@ class FunctionFilter(ColumnElement):
         See :func:`~.expression.over` for a full description.
 
         """
-        return Over(self, partition_by=partition_by, order_by=order_by)
+        return Over(
+            self, partition_by=partition_by, order_by=order_by,
+            range_=range_, rows=rows)
 
     @util.memoized_property
     def type(self):
index 0ef19e0cb597c7d405b66b724cf0227df250102e..7f2c44bf119b5f4561e04dee8000581e8f5b97b3 100644 (file)
@@ -2485,6 +2485,50 @@ class SelectTest(fixtures.TestBase, AssertsCompiledSQL):
             func.row_number().over, range_=(-5, 8), rows=(-2, 5)
         )
 
+    def test_over_within_group(self):
+        from sqlalchemy import within_group
+        stmt = select([
+            table1.c.myid,
+            within_group(
+                func.percentile_cont(0.5),
+                table1.c.name.desc()
+            ).over(
+                range_=(1, 2),
+                partition_by=table1.c.name,
+                order_by=table1.c.myid
+            )
+        ])
+        eq_ignore_whitespace(
+            str(stmt),
+            "SELECT mytable.myid, percentile_cont(:percentile_cont_1) "
+            "WITHIN GROUP (ORDER BY mytable.name DESC) "
+            "OVER (PARTITION BY mytable.name ORDER BY mytable.myid "
+            "RANGE BETWEEN :param_1 FOLLOWING AND :param_2 FOLLOWING) "
+            "AS anon_1 FROM mytable"
+        )
+
+        stmt = select([
+            table1.c.myid,
+            within_group(
+                func.percentile_cont(0.5),
+                table1.c.name.desc()
+            ).over(
+                rows=(1, 2),
+                partition_by=table1.c.name,
+                order_by=table1.c.myid
+            )
+        ])
+        eq_ignore_whitespace(
+            str(stmt),
+            "SELECT mytable.myid, percentile_cont(:percentile_cont_1) "
+            "WITHIN GROUP (ORDER BY mytable.name DESC) "
+            "OVER (PARTITION BY mytable.name ORDER BY mytable.myid "
+            "ROWS BETWEEN :param_1 FOLLOWING AND :param_2 FOLLOWING) "
+            "AS anon_1 FROM mytable"
+        )
+
+
+
     def test_date_between(self):
         import datetime
         table = Table('dt', metadata,
index 3032c3ce3afd92f19315bb44bedda5b306545d7a..48d5fc37f861b87135d416f2769b2f83bf61f220 100644 (file)
@@ -513,6 +513,38 @@ class CompileTest(fixtures.TestBase, AssertsCompiledSQL):
             "AS anon_1 FROM mytable"
         )
 
+    def test_funcfilter_windowing_range(self):
+        self.assert_compile(
+            select([
+                func.rank().filter(
+                    table1.c.name > 'foo'
+                ).over(
+                    range_=(1, 5),
+                    partition_by=['description']
+                )
+            ]),
+            "SELECT rank() FILTER (WHERE mytable.name > :name_1) "
+            "OVER (PARTITION BY mytable.description RANGE BETWEEN :param_1 "
+            "FOLLOWING AND :param_2 FOLLOWING) "
+            "AS anon_1 FROM mytable"
+        )
+
+    def test_funcfilter_windowing_rows(self):
+        self.assert_compile(
+            select([
+                func.rank().filter(
+                    table1.c.name > 'foo'
+                ).over(
+                    rows=(1, 5),
+                    partition_by=['description']
+                )
+            ]),
+            "SELECT rank() FILTER (WHERE mytable.name > :name_1) "
+            "OVER (PARTITION BY mytable.description ROWS BETWEEN :param_1 "
+            "FOLLOWING AND :param_2 FOLLOWING) "
+            "AS anon_1 FROM mytable"
+        )
+
     def test_funcfilter_within_group(self):
         stmt = select([
             table1.c.myid,