]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Accept multiple expressions for aggregate_order_by order_by
authorMike Bayer <mike_mp@zzzcomputing.com>
Tue, 25 Sep 2018 15:11:41 +0000 (11:11 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Tue, 25 Sep 2018 15:14:32 +0000 (11:14 -0400)
Added support for the :class:`.aggregate_order_by` function to receive
multiple ORDER BY elements, previously only a single element was accepted.

Fixes: #4337
Change-Id: I411ac31697a0d65b568ad65ce5b5181717afbd65

doc/build/changelog/unreleased_12/4337.rst [new file with mode: 0644]
lib/sqlalchemy/dialects/postgresql/ext.py
test/dialect/postgresql/test_compiler.py

diff --git a/doc/build/changelog/unreleased_12/4337.rst b/doc/build/changelog/unreleased_12/4337.rst
new file mode 100644 (file)
index 0000000..e056f3e
--- /dev/null
@@ -0,0 +1,7 @@
+.. change::
+   :tags: bug, postgresql
+   :tickets: 4337
+
+   Added support for the :class:`.aggregate_order_by` function to receive
+   multiple ORDER BY elements, previously only a single element was accepted.
+
index 71fb3cc5bc5724f5d0f51d4edb1c440839409584..a588eafddd4341152883941389f113bbdbf50521 100644 (file)
@@ -39,6 +39,8 @@ class aggregate_order_by(expression.ColumnElement):
 
     .. versionadded:: 1.1
 
+    .. versionchanged:: 1.2.13 - the ORDER BY argument may be multiple terms
+
     .. seealso::
 
         :class:`.array_agg`
@@ -47,9 +49,18 @@ class aggregate_order_by(expression.ColumnElement):
 
     __visit_name__ = 'aggregate_order_by'
 
-    def __init__(self, target, order_by):
+    def __init__(self, target, *order_by):
         self.target = elements._literal_as_binds(target)
-        self.order_by = elements._literal_as_binds(order_by)
+
+        _lob = len(order_by)
+        if _lob == 0:
+            raise TypeError("at least one ORDER BY element is required")
+        elif _lob == 1:
+            self.order_by = elements._literal_as_binds(order_by[0])
+        else:
+            self.order_by = elements.ClauseList(
+                *order_by,
+                _literal_as_text=elements._literal_as_binds)
 
     def self_group(self, against=None):
         return self
index 6133ab4821680eead771adae2f8350ff1cd14d22..3ebc4a1ab2b5c74a88e915885dda764666ea07b5 100644 (file)
@@ -1100,6 +1100,31 @@ class CompileTest(fixtures.TestBase, AssertsCompiledSQL):
             "AS string_agg_1 FROM table1"
         )
 
+    def test_aggregate_order_by_multi_col(self):
+        m = MetaData()
+        table = Table('table1', m, Column('a', Integer), Column('b', Integer))
+        expr = func.string_agg(
+            table.c.a,
+            aggregate_order_by(
+                literal_column("','"),
+                table.c.a, table.c.b.desc())
+        )
+        stmt = select([expr])
+
+        self.assert_compile(
+            stmt,
+            "SELECT string_agg(table1.a, "
+            "',' ORDER BY table1.a, table1.b DESC) "
+            "AS string_agg_1 FROM table1"
+        )
+
+    def test_aggregate_orcer_by_no_arg(self):
+        assert_raises_message(
+            TypeError,
+            "at least one ORDER BY element is required",
+            aggregate_order_by, literal_column("','")
+        )
+
     def test_pg_array_agg_implicit_pg_array(self):
 
         expr = pg_array_agg(column('data', Integer))