Skip to content

Commit

Permalink
Merge "Accept multiple expressions for aggregate_order_by order_by"
Browse files Browse the repository at this point in the history
  • Loading branch information
zzzeek authored and Gerrit Code Review committed Sep 26, 2018
2 parents 5476881 + b7ba3f0 commit f109e62
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 2 deletions.
7 changes: 7 additions & 0 deletions doc/build/changelog/unreleased_12/4337.rst
Original file line number Diff line number Diff line change
@@ -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.

15 changes: 13 additions & 2 deletions lib/sqlalchemy/dialects/postgresql/ext.py
Original file line number Diff line number Diff line change
Expand Up @@ -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`
Expand All @@ -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
Expand Down
25 changes: 25 additions & 0 deletions test/dialect/postgresql/test_compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -1100,6 +1100,31 @@ def test_aggregate_order_by_two(self):
"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))
Expand Down

0 comments on commit f109e62

Please sign in to comment.