diff --git a/.hgtags b/.hgtags index 14b976e1bb135969d5caccb3d7e1bdf2f115090f_LmhndGFncw==..73216278aa9e33a881ae30473a7e7852e2233670_LmhndGFncw== 100644 --- a/.hgtags +++ b/.hgtags @@ -50,3 +50,5 @@ 677736b455f5fb7a31882e37165dbd4879c4bf11 rql-debian-version-0.26.0-1 42ae413193a8403a749fb1a206a86cec09f5efdb rql-version-0.26.1 3142115086127f3e9995081fff3fef3d420838cf rql-debian-version-0.26.1-1 +7d5bef1742bc302309668982af10409bcc96eadf rql-version-0.26.2 +cb66c5a9918dd8958dd3cdf48f8bdd0c2786b76a rql-debian-version-0.26.2-1 diff --git a/ChangeLog b/ChangeLog index 14b976e1bb135969d5caccb3d7e1bdf2f115090f_Q2hhbmdlTG9n..73216278aa9e33a881ae30473a7e7852e2233670_Q2hhbmdlTG9n 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,12 @@ ChangeLog for RQL ================= - -- +2010-06-11 -- 0.26.2 + * totally remove 'IS' operator + + * replace get_variable_variables by get_variable_indicies + + * fix rule order so 'HAVING (X op Y)' is now parseable while 'HAVING (1+2) op Y' isn't anymore parseable + * fix simplification bug with ored uid relations @@ -5,5 +11,7 @@ * fix simplification bug with ored uid relations + + 2010-06-04 -- 0.26.1 * normalize NOT() to NOT EXISTS() when it makes sense diff --git a/__pkginfo__.py b/__pkginfo__.py index 14b976e1bb135969d5caccb3d7e1bdf2f115090f_X19wa2dpbmZvX18ucHk=..73216278aa9e33a881ae30473a7e7852e2233670_X19wa2dpbmZvX18ucHk= 100644 --- a/__pkginfo__.py +++ b/__pkginfo__.py @@ -20,7 +20,7 @@ __docformat__ = "restructuredtext en" modname = "rql" -numversion = (0, 26, 1) +numversion = (0, 26, 2) version = '.'.join(str(num) for num in numversion) license = 'LGPL' diff --git a/debian/changelog b/debian/changelog index 14b976e1bb135969d5caccb3d7e1bdf2f115090f_ZGViaWFuL2NoYW5nZWxvZw==..73216278aa9e33a881ae30473a7e7852e2233670_ZGViaWFuL2NoYW5nZWxvZw== 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +rql (0.26.2-1) unstable; urgency=low + + * new upstream release + + -- Sylvain Thénault <sylvain.thenault@logilab.fr> Fri, 11 Jun 2010 10:04:46 +0200 + rql (0.26.1-1) unstable; urgency=low * new upstream release diff --git a/parser.g b/parser.g index 14b976e1bb135969d5caccb3d7e1bdf2f115090f_cGFyc2VyLmc=..73216278aa9e33a881ae30473a7e7852e2233670_cGFyc2VyLmc= 100644 --- a/parser.g +++ b/parser.g @@ -268,8 +268,16 @@ rule exprs_not<<S>>: NOT balanced_expr<<S>> {{ return Not(balanced_expr) }} | balanced_expr<<S>> {{ return balanced_expr }} -rule balanced_expr<<S>>: expr_add<<S>> expr_op<<S>> {{ expr_op.insert(0, expr_add); return expr_op }} - | r"\(" logical_expr<<S>> r"\)" {{ return logical_expr }} +#// XXX ambiguity, expr_add may also have '(' as first token. Hence +#// put "(" logical_expr<<S>> ")" rule first. We can then parse: +#// +#// Any T2 WHERE T1 relation T2 HAVING (1 < COUNT(T1)); +#// +#// but not +#// +#// Any T2 WHERE T1 relation T2 HAVING (1+2) < COUNT(T1); +rule balanced_expr<<S>>: r"\(" logical_expr<<S>> r"\)" {{ return logical_expr }} + | expr_add<<S>> expr_op<<S>> {{ expr_op.insert(0, expr_add); return expr_op }} # // cant use expr<<S>> without introducing some ambiguities rule expr_op<<S>>: CMP_OP expr_add<<S>> {{ return Comparison(CMP_OP.upper(), expr_add) }} diff --git a/parser.py b/parser.py index 14b976e1bb135969d5caccb3d7e1bdf2f115090f_cGFyc2VyLnB5..73216278aa9e33a881ae30473a7e7852e2233670_cGFyc2VyLnB5 100644 --- a/parser.py +++ b/parser.py @@ -519,9 +519,17 @@ def balanced_expr(self, S, _parent=None): _context = self.Context(_parent, self._scanner, 'balanced_expr', [S]) _token = self._peek('r"\\("', 'NULL', 'DATE', 'DATETIME', 'TRUE', 'FALSE', 'FLOAT', 'INT', 'STRING', 'SUBSTITUTE', 'VARIABLE', 'E_TYPE', 'FUNCTION', context=_context) - expr_add = self.expr_add(S, _context) - expr_op = self.expr_op(S, _context) - expr_op.insert(0, expr_add); return expr_op + if _token == 'r"\\("': + self._scan('r"\\("', context=_context) + logical_expr = self.logical_expr(S, _context) + self._scan('r"\\)"', context=_context) + return logical_expr + elif 1: + expr_add = self.expr_add(S, _context) + expr_op = self.expr_op(S, _context) + expr_op.insert(0, expr_add); return expr_op + else: + raise runtime.SyntaxError(_token[0], 'Could not match balanced_expr') def expr_op(self, S, _parent=None): _context = self.Context(_parent, self._scanner, 'expr_op', [S]) diff --git a/test/unittest_parser.py b/test/unittest_parser.py index 14b976e1bb135969d5caccb3d7e1bdf2f115090f_dGVzdC91bml0dGVzdF9wYXJzZXIucHk=..73216278aa9e33a881ae30473a7e7852e2233670_dGVzdC91bml0dGVzdF9wYXJzZXIucHk= 100644 --- a/test/unittest_parser.py +++ b/test/unittest_parser.py @@ -133,6 +133,21 @@ ' GROUPBY T2' ' WHERE T1 relation T2' ' HAVING 1 < COUNT(T1) OR COUNT(T1) IN (3,4);', + + 'Any T2' + ' GROUPBY T2' + ' WHERE T1 relation T2' + ' HAVING (COUNT(T1) IN (1,2)) OR (COUNT(T1) IN (3,4));', + + 'Any T2' + ' GROUPBY T2' + ' WHERE T1 relation T2' + ' HAVING (1 < COUNT(T1) OR COUNT(T1) IN (3,4));', + + 'Any T2' + ' GROUPBY T2' + ' WHERE T1 relation T2' + ' HAVING 1+2 < COUNT(T1);', ) class ParserHercule(TestCase):