Skip to content

Commit

Permalink
refactor(expr): preserve column ordering in aggregations/mutations
Browse files Browse the repository at this point in the history
BREAKING CHANGE: Columns that were added or used in an aggregation or
mutation would be alphabetically sorted in compiled SQL outputs.  This
was a vestige from when Python dicts didn't preserve insertion order.
Now columns will appear in the order in which they were passed to
`aggregate` or `mutate`
  • Loading branch information
gforsyth authored and cpcloud committed Mar 28, 2022
1 parent f7e6f65 commit 668be0f
Show file tree
Hide file tree
Showing 4 changed files with 5 additions and 30 deletions.
7 changes: 3 additions & 4 deletions ibis/expr/types/groupby.py
Original file line number Diff line number Diff line change
Expand Up @@ -222,11 +222,10 @@ def mutate(
else:
exprs = util.promote_list(exprs)

kwd_names = list(kwds.keys())
kwd_values = list(kwds.values())
kwd_values = self.table._resolve(kwd_values)
kwd_keys = list(kwds.keys())
kwd_values = self.table._resolve(list(kwds.values()))

for k, v in sorted(zip(kwd_names, kwd_values)):
for k, v in zip(kwd_keys, kwd_values):
exprs.append(v.name(k))

return self.projection([self.table] + exprs)
Expand Down
5 changes: 1 addition & 4 deletions ibis/expr/types/relations.py
Original file line number Diff line number Diff line change
Expand Up @@ -356,10 +356,7 @@ def aggregate(
"""
metrics = [] if metrics is None else util.promote_list(metrics)
metrics.extend(
self._ensure_expr(expr).name(name)
for name, expr in sorted(
kwargs.items(), key=operator.itemgetter(0)
)
self._ensure_expr(expr).name(name) for name, expr in kwargs.items()
)

op = self.op().aggregate(
Expand Down
2 changes: 1 addition & 1 deletion ibis/tests/expr/test_table.py
Original file line number Diff line number Diff line change
Expand Up @@ -499,7 +499,7 @@ def test_aggregate_keywords(table):
expr = t.aggregate(foo=t.f.sum(), bar=lambda x: x.f.mean(), by='g')
expr2 = t.group_by('g').aggregate(foo=t.f.sum(), bar=lambda x: x.f.mean())
expected = t.aggregate(
[t.f.mean().name('bar'), t.f.sum().name('foo')], by='g'
[t.f.sum().name('foo'), t.f.mean().name('bar')], by='g'
)

assert_equal(expr, expected)
Expand Down
21 changes: 0 additions & 21 deletions ibis/tests/expr/test_window_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,27 +187,6 @@ def metric(x):
assert_equal(enriched, expected)


def test_mutate_sorts_keys(con):
t = con.table('airlines')
m = t.arrdelay.mean()
g = t.group_by('dest')

result = g.mutate(zzz=m, yyy=m, ddd=m, ccc=m, bbb=m, aaa=m)

expected = g.mutate(
[
m.name('aaa'),
m.name('bbb'),
m.name('ccc'),
m.name('ddd'),
m.name('yyy'),
m.name('zzz'),
]
)

assert_equal(result, expected)


def test_window_bind_to_table(alltypes):
t = alltypes
w = ibis.window(group_by='g', order_by=ibis.desc('f'))
Expand Down

0 comments on commit 668be0f

Please sign in to comment.