diff --git a/ChangeLog b/ChangeLog index 21e23dabd0bda15649e10bc3977b823c95166e76_Q2hhbmdlTG9n..a574133725258188c211fcc4a31b0ead93b20561_Q2hhbmdlTG9n 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5,6 +5,7 @@ * support != operator for non equality * support for CAST function * support for regexp-based pattern matching using a REGEXP operator +* may now GROUPBY functions / column number 2011-01-12 -- 0.28.0 * enhance rewrite_shared_optional so one can specify where the new identity diff --git a/parser.g b/parser.g index 21e23dabd0bda15649e10bc3977b823c95166e76_cGFyc2VyLmc=..a574133725258188c211fcc4a31b0ead93b20561_cGFyc2VyLmc= 100644 --- a/parser.g +++ b/parser.g @@ -173,7 +173,10 @@ rule dgroupby<<S>>: groupby<<S>> {{ if groupby: warn('GROUPBY is now before WHERE clause') }} rule dlimit_offset<<S>>: limit_offset<<S>> {{ if limit_offset: warn('LIMIT/OFFSET are now before WHERE clause') }} -rule groupby<<S>>: GROUPBY variables<<S>> {{ S.set_groupby(variables); return True }} +rule groupby<<S>>: GROUPBY {{ nodes = [] }} + expr_add<<S>> {{ nodes.append(expr_add) }} + ( ',' expr_add<<S>> {{ nodes.append(expr_add) }} + )* {{ S.set_groupby(nodes); return True }} | rule having<<S>>: HAVING logical_expr<<S>> {{ S.set_having([logical_expr]) }} diff --git a/parser.py b/parser.py index 21e23dabd0bda15649e10bc3977b823c95166e76_cGFyc2VyLnB5..a574133725258188c211fcc4a31b0ead93b20561_cGFyc2VyLnB5 100644 --- a/parser.py +++ b/parser.py @@ -246,8 +246,14 @@ _token = self._peek('GROUPBY', 'ORDERBY', 'WHERE', 'LIMIT', 'OFFSET', 'HAVING', 'WITH', "';'", 'r"\\)"', context=_context) if _token == 'GROUPBY': GROUPBY = self._scan('GROUPBY', context=_context) - variables = self.variables(S, _context) - S.set_groupby(variables); return True + nodes = [] + expr_add = self.expr_add(S, _context) + nodes.append(expr_add) + while self._peek("','", 'ORDERBY', 'WHERE', 'LIMIT', 'OFFSET', 'HAVING', 'WITH', "';'", 'GROUPBY', 'r"\\)"', context=_context) == "','": + self._scan("','", context=_context) + expr_add = self.expr_add(S, _context) + nodes.append(expr_add) + S.set_groupby(nodes); return True elif 1: pass else: @@ -533,7 +539,7 @@ vars = [] var = self.var(S, _context) vars.append(var) - while self._peek("','", 'BEING', 'ORDERBY', 'WHERE', 'LIMIT', 'OFFSET', 'HAVING', 'WITH', "';'", 'GROUPBY', 'r"\\)"', context=_context) == "','": + while self._peek("','", 'BEING', context=_context) == "','": self._scan("','", context=_context) var = self.var(S, _context) vars.append(var) @@ -704,4 +710,3 @@ f = stdin print parse(argv[1], f.read()) else: print >>sys.stderr, 'Args: <rule> [<filename>]' -# End -- grammar generated by Yapps diff --git a/test/unittest_parser.py b/test/unittest_parser.py index 21e23dabd0bda15649e10bc3977b823c95166e76_dGVzdC91bml0dGVzdF9wYXJzZXIucHk=..a574133725258188c211fcc4a31b0ead93b20561_dGVzdC91bml0dGVzdF9wYXJzZXIucHk= 100644 --- a/test/unittest_parser.py +++ b/test/unittest_parser.py @@ -153,6 +153,10 @@ 'Any X,Y,A ORDERBY Y ' 'WHERE A done_for Y, X split_into Y, A diem D ' 'HAVING MIN(D) < "2010-07-01", MAX(D) >= "2010-07-01";', + + 'Any YEAR(XD),COUNT(X) GROUPBY YEAR(XD) ORDERBY YEAR(XD) WHERE X date XD;', + 'Any YEAR(XD),COUNT(X) GROUPBY 1 ORDERBY 1 WHERE X date XD;', + ) class ParserHercule(TestCase):