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):