Skip to content
Snippets Groups Projects
Commit c225f5dc1a7e authored by Sylvain Thénault's avatar Sylvain Thénault
Browse files

fix rule order so 'HAVING (X op Y)' is now parseable while 'HAVING (1+2) op Y'...

fix rule order so 'HAVING (X op Y)' is now parseable while 'HAVING (1+2) op Y' isn't anymore parseable... At some point we should consider more advanced parsing system than yapps.
parent 0314d8a14d0d
No related branches found
No related tags found
No related merge requests found
...@@ -268,8 +268,16 @@ ...@@ -268,8 +268,16 @@
rule exprs_not<<S>>: NOT balanced_expr<<S>> {{ return Not(balanced_expr) }} rule exprs_not<<S>>: NOT balanced_expr<<S>> {{ return Not(balanced_expr) }}
| balanced_expr<<S>> {{ return 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 }} #// XXX ambiguity, expr_add may also have '(' as first token. Hence
| r"\(" logical_expr<<S>> r"\)" {{ return logical_expr }} #// 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 # // cant use expr<<S>> without introducing some ambiguities
rule expr_op<<S>>: CMP_OP expr_add<<S>> {{ return Comparison(CMP_OP.upper(), expr_add) }} rule expr_op<<S>>: CMP_OP expr_add<<S>> {{ return Comparison(CMP_OP.upper(), expr_add) }}
......
...@@ -519,9 +519,17 @@ ...@@ -519,9 +519,17 @@
def balanced_expr(self, S, _parent=None): def balanced_expr(self, S, _parent=None):
_context = self.Context(_parent, self._scanner, 'balanced_expr', [S]) _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) _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) if _token == 'r"\\("':
expr_op = self.expr_op(S, _context) self._scan('r"\\("', context=_context)
expr_op.insert(0, expr_add); return expr_op 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): def expr_op(self, S, _parent=None):
_context = self.Context(_parent, self._scanner, 'expr_op', [S]) _context = self.Context(_parent, self._scanner, 'expr_op', [S])
......
...@@ -133,6 +133,21 @@ ...@@ -133,6 +133,21 @@
' GROUPBY T2' ' GROUPBY T2'
' WHERE T1 relation T2' ' WHERE T1 relation T2'
' HAVING 1 < COUNT(T1) OR COUNT(T1) IN (3,4);', ' 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): class ParserHercule(TestCase):
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment