From 8ed1a52c250bedd870b9f97b5c897f7b7690e285 Mon Sep 17 00:00:00 2001 From: Sam Cooke Date: Tue, 13 Feb 2018 11:39:06 +0000 Subject: [PATCH] Adding support for LAST --- tinyquery/evaluator_test.py | 16 ++++++++++++++++ tinyquery/runtime.py | 21 ++++++++++++++++++++- 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/tinyquery/evaluator_test.py b/tinyquery/evaluator_test.py index 61d2c2c..d49fe7b 100644 --- a/tinyquery/evaluator_test.py +++ b/tinyquery/evaluator_test.py @@ -1270,6 +1270,22 @@ def test_first(self): ]) ) + def test_last(self): + # Test over the equivalent of a GROUP BY + self.assert_query_result( + 'SELECT LAST(val1) FROM test_table', + self.make_context([ + ('f0_', tq_types.INT, [2]) + ]) + ) + # Test over something repeated + self.assert_query_result( + 'SELECT LAST(QUANTILES(val1, 3)) FROM test_table', + self.make_context([ + ('f0_', tq_types.INT, [8]) + ]) + ) + # TODO(colin): test behavior on empty list in both cases def test_left(self): diff --git a/tinyquery/runtime.py b/tinyquery/runtime.py index 12d0eab..2c33266 100644 --- a/tinyquery/runtime.py +++ b/tinyquery/runtime.py @@ -558,6 +558,24 @@ def _evaluate(self, num_rows, column): values=values) +class LastFunction(AggregateFunction): + def check_types(self, rep_list_type): + return rep_list_type + + def _evaluate(self, num_rows, column): + values = [] + if len(column.values) == 0: + values = [None] + + if column.mode == tq_modes.REPEATED: + values = [repeated_row[-1] if len(repeated_row) > 0 else None + for repeated_row in column.values] + else: + values = [column.values[-1]] + return context.Column(type=column.type, mode=tq_modes.NULLABLE, + values=values) + + class NoArgFunction(ScalarFunction): def __init__(self, func, return_type=tq_types.INT): self.func = func @@ -1304,7 +1322,8 @@ def _evaluate(self, num_rows, json_expressions, json_paths): 'count_distinct': CountDistinctFunction(), 'stddev_samp': StddevSampFunction(), 'quantiles': QuantilesFunction(), - 'first': FirstFunction() + 'first': FirstFunction(), + 'last': LastFunction(), }