summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndi Albrecht <albrecht.andi@gmail.com>2009-09-12 08:05:34 +0200
committerAndi Albrecht <albrecht.andi@gmail.com>2009-09-12 08:05:34 +0200
commit3d13c5d4bb14f76d407285f2a91e7061585fd6da (patch)
tree8816cdae40c231eb4da4c4ae8d49befb1f05e854
parent29590e09223ca9eb44e15429488664cff9db5f9e (diff)
downloadsqlparse-3d13c5d4bb14f76d407285f2a91e7061585fd6da.tar.gz
Prevent WHERE grouper from consuming closing parenthesis (fixes issue9, reported by estama).
-rw-r--r--CHANGES1
-rw-r--r--sqlparse/engine/grouping.py2
-rw-r--r--sqlparse/sql.py8
-rw-r--r--tests/test_grouping.py2
-rw-r--r--tests/test_regressions.py20
5 files changed, 31 insertions, 2 deletions
diff --git a/CHANGES b/CHANGES
index af7b917..0521b8c 100644
--- a/CHANGES
+++ b/CHANGES
@@ -5,6 +5,7 @@ Bug Fixes
* Fixed incorrect detection of keyword fragments embed in names (issue7,
reported and initial patch by andyboyko).
* Stricter detection of identfier aliases (issue8, reported by estama).
+ * WHERE grouping consumed closing parenthesis (issue9, reported by estama).
Release 0.1.1 (May 6, 2009)
diff --git a/sqlparse/engine/grouping.py b/sqlparse/engine/grouping.py
index d30031f..a03c0b4 100644
--- a/sqlparse/engine/grouping.py
+++ b/sqlparse/engine/grouping.py
@@ -231,7 +231,7 @@ def group_where(tlist):
tidx = tlist.token_index(token)
end = tlist.token_next_match(tidx+1, T.Keyword, stopwords)
if end is None:
- end = tlist.tokens[-1]
+ end = tlist._groupable_tokens[-1]
else:
end = tlist.tokens[tlist.token_index(end)-1]
group = tlist.group_tokens(Where, tlist.tokens_between(token, end))
diff --git a/sqlparse/sql.py b/sqlparse/sql.py
index 5969841..195696e 100644
--- a/sqlparse/sql.py
+++ b/sqlparse/sql.py
@@ -176,6 +176,10 @@ class TokenList(Token):
def get_sublists(self):
return [x for x in self.tokens if isinstance(x, TokenList)]
+ @property
+ def _groupable_tokens(self):
+ return self.tokens
+
def token_first(self, ignore_whitespace=True):
"""Returns the first child token.
@@ -426,6 +430,10 @@ class Parenthesis(TokenList):
"""Tokens between parenthesis."""
__slots__ = ('value', 'ttype', 'tokens')
+ @property
+ def _groupable_tokens(self):
+ return self.tokens[1:-1]
+
class Assignment(TokenList):
"""An assignment like 'var := val;'"""
diff --git a/tests/test_grouping.py b/tests/test_grouping.py
index c3039b8..119f574 100644
--- a/tests/test_grouping.py
+++ b/tests/test_grouping.py
@@ -114,7 +114,7 @@ class TestGrouping(TestCaseBase):
s = 'select x from (select y from foo where bar = 1) z'
p = sqlparse.parse(s)[0]
self.ndiffAssertEqual(s, p.to_unicode())
- self.assertTrue(isinstance(p.tokens[-3].tokens[-1], Where))
+ self.assertTrue(isinstance(p.tokens[-3].tokens[-2], Where))
def test_typecast(self):
s = 'select foo::integer from bar'
diff --git a/tests/test_regressions.py b/tests/test_regressions.py
new file mode 100644
index 0000000..41ca531
--- /dev/null
+++ b/tests/test_regressions.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+
+import sqlparse
+from sqlparse import tokens as T
+from sqlparse.engine.grouping import *
+
+from tests.utils import TestCaseBase
+
+
+class TestRegression(TestCaseBase):
+
+ def test_where_doesnt_consume_parenthesis(self): # issue9
+ p = sqlparse.parse('(where 1)')[0]
+ self.assert_(isinstance(p, Statement))
+ self.assertEqual(len(p.tokens), 1)
+ self.assert_(isinstance(p.tokens[0], Parenthesis))
+ prt = p.tokens[0]
+ self.assertEqual(len(prt.tokens), 3)
+ self.assertEqual(prt.tokens[0].ttype, T.Punctuation)
+ self.assertEqual(prt.tokens[-1].ttype, T.Punctuation)