may now GROUPBY function call or column number. Closes #66602

authorSylvain Thénault <sylvain.thenault@logilab.fr>
changeseta57413372525
branchdefault
phasepublic
hiddenno
parent revision#21e23dabd0bd drop oldstable tag which drives me crazy
child revision#56dbd4ec5137 fix parsing of negative float (closes #63421)
files modified by this revision
ChangeLog
parser.g
parser.py
test/unittest_parser.py
# HG changeset patch
# User Sylvain Thénault <sylvain.thenault@logilab.fr>
# Date 1305724848 -7200
# Wed May 18 15:20:48 2011 +0200
# Node ID a574133725258188c211fcc4a31b0ead93b20561
# Parent 21e23dabd0bda15649e10bc3977b823c95166e76
may now GROUPBY function call or column number. Closes #66602

diff --git a/ChangeLog b/ChangeLog
@@ -3,10 +3,11 @@
1 
2  --
3  * support != operator for non equality
4  * support for CAST function
5  * support for regexp-based pattern matching using a REGEXP operator
6 +* may now GROUPBY functions / column number
7 
8  2011-01-12  --  0.28.0
9      * enhance rewrite_shared_optional so one can specify where the new identity
10        relation should be added (used by cw multi-sources planner)
11 
diff --git a/parser.g b/parser.g
@@ -171,11 +171,14 @@
12  #// to remove in rql 1.0
13  rule dorderby<<S>>: orderby<<S>> {{ if orderby: warn('ORDERBY is now before WHERE clause') }}
14  rule dgroupby<<S>>: groupby<<S>> {{ if groupby: warn('GROUPBY is now before WHERE clause') }}
15  rule dlimit_offset<<S>>: limit_offset<<S>> {{ if limit_offset: warn('LIMIT/OFFSET are now before WHERE clause') }}
16 
17 -rule groupby<<S>>: GROUPBY variables<<S>> {{ S.set_groupby(variables); return True }}
18 +rule groupby<<S>>: GROUPBY              {{ nodes = [] }}
19 +                   expr_add<<S>>        {{ nodes.append(expr_add) }}
20 +                   ( ',' expr_add<<S>>  {{ nodes.append(expr_add) }}
21 +                   )*                   {{ S.set_groupby(nodes); return True }}
22                   |
23 
24  rule having<<S>>: HAVING logical_expr<<S>> {{ S.set_having([logical_expr]) }}
25                  |
26 
diff --git a/parser.py b/parser.py
@@ -244,12 +244,18 @@
27      def groupby(self, S, _parent=None):
28          _context = self.Context(_parent, self._scanner, 'groupby', [S])
29          _token = self._peek('GROUPBY', 'ORDERBY', 'WHERE', 'LIMIT', 'OFFSET', 'HAVING', 'WITH', "';'", 'r"\\)"', context=_context)
30          if _token == 'GROUPBY':
31              GROUPBY = self._scan('GROUPBY', context=_context)
32 -            variables = self.variables(S, _context)
33 -            S.set_groupby(variables); return True
34 +            nodes = []
35 +            expr_add = self.expr_add(S, _context)
36 +            nodes.append(expr_add)
37 +            while self._peek("','", 'ORDERBY', 'WHERE', 'LIMIT', 'OFFSET', 'HAVING', 'WITH', "';'", 'GROUPBY', 'r"\\)"', context=_context) == "','":
38 +                self._scan("','", context=_context)
39 +                expr_add = self.expr_add(S, _context)
40 +                nodes.append(expr_add)
41 +            S.set_groupby(nodes); return True
42          elif 1:
43              pass
44          else:
45              raise runtime.SyntaxError(_token[0], 'Could not match groupby')
46 
@@ -531,11 +537,11 @@
47      def variables(self, S, _parent=None):
48          _context = self.Context(_parent, self._scanner, 'variables', [S])
49          vars = []
50          var = self.var(S, _context)
51          vars.append(var)
52 -        while self._peek("','", 'BEING', 'ORDERBY', 'WHERE', 'LIMIT', 'OFFSET', 'HAVING', 'WITH', "';'", 'GROUPBY', 'r"\\)"', context=_context) == "','":
53 +        while self._peek("','", 'BEING', context=_context) == "','":
54              self._scan("','", context=_context)
55              var = self.var(S, _context)
56              vars.append(var)
57          return vars
58 
@@ -702,6 +708,5 @@
59              f = open(argv[2],'r')
60          else:
61              f = stdin
62          print parse(argv[1], f.read())
63      else: print >>sys.stderr, 'Args:  <rule> [<filename>]'
64 -# End -- grammar generated by Yapps
diff --git a/test/unittest_parser.py b/test/unittest_parser.py
@@ -151,10 +151,14 @@
65      ' HAVING 1+2 < COUNT(T1);',
66 
67      'Any X,Y,A ORDERBY Y '
68      'WHERE A done_for Y, X split_into Y, A diem D '
69      'HAVING MIN(D) < "2010-07-01", MAX(D) >= "2010-07-01";',
70 +
71 +    'Any YEAR(XD),COUNT(X) GROUPBY YEAR(XD) ORDERBY YEAR(XD) WHERE X date XD;',
72 +    'Any YEAR(XD),COUNT(X) GROUPBY 1 ORDERBY 1 WHERE X date XD;',
73 +
74      )
75 
76  class ParserHercule(TestCase):
77      _syntaxerr = SyntaxError
78