Skip to content

Commit 617b8f6

Browse files
r33s3n6andialbrecht
authored andcommitted
Add OVER clause, and group it into Function (fixes #701)
1 parent d8f8147 commit 617b8f6

File tree

3 files changed

+36
-1
lines changed

3 files changed

+36
-1
lines changed

sqlparse/engine/grouping.py

+17-1
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,16 @@ def group_identifier(tlist):
235235
tidx, token = tlist.token_next_by(t=ttypes, idx=tidx)
236236

237237

238+
@recurse(sql.Over)
239+
def group_over(tlist):
240+
tidx, token = tlist.token_next_by(m=sql.Over.M_OPEN)
241+
while token:
242+
nidx, next_ = tlist.token_next(tidx)
243+
if imt(next_, i=sql.Parenthesis, t=T.Name):
244+
tlist.group_tokens(sql.Over, tidx, nidx)
245+
tidx, token = tlist.token_next_by(m=sql.Over.M_OPEN, idx=tidx)
246+
247+
238248
def group_arrays(tlist):
239249
sqlcls = sql.SquareBrackets, sql.Identifier, sql.Function
240250
ttypes = T.Name, T.String.Symbol
@@ -361,7 +371,12 @@ def group_functions(tlist):
361371
while token:
362372
nidx, next_ = tlist.token_next(tidx)
363373
if isinstance(next_, sql.Parenthesis):
364-
tlist.group_tokens(sql.Function, tidx, nidx)
374+
over_idx, over = tlist.token_next(nidx)
375+
if over and isinstance(over, sql.Over):
376+
eidx = over_idx
377+
else:
378+
eidx = nidx
379+
tlist.group_tokens(sql.Function, tidx, eidx)
365380
tidx, token = tlist.token_next_by(t=T.Name, idx=tidx)
366381

367382

@@ -412,6 +427,7 @@ def group(stmt):
412427
group_for,
413428
group_begin,
414429

430+
group_over,
415431
group_functions,
416432
group_where,
417433
group_period,

sqlparse/sql.py

+5
Original file line numberDiff line numberDiff line change
@@ -554,6 +554,11 @@ class Where(TokenList):
554554
'HAVING', 'RETURNING', 'INTO')
555555

556556

557+
class Over(TokenList):
558+
"""An OVER clause."""
559+
M_OPEN = T.Keyword, 'OVER'
560+
561+
557562
class Having(TokenList):
558563
"""A HAVING clause."""
559564
M_OPEN = T.Keyword, 'HAVING'

tests/test_grouping.py

+14
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,20 @@ def test_grouping_identifier_function():
185185
assert isinstance(p.tokens[0], sql.Identifier)
186186
assert isinstance(p.tokens[0].tokens[0], sql.Operation)
187187
assert isinstance(p.tokens[0].tokens[0].tokens[0], sql.Function)
188+
p = sqlparse.parse('foo(c1) over win1 as bar')[0]
189+
assert isinstance(p.tokens[0], sql.Identifier)
190+
assert isinstance(p.tokens[0].tokens[0], sql.Function)
191+
assert len(p.tokens[0].tokens[0].tokens) == 4
192+
assert isinstance(p.tokens[0].tokens[0].tokens[3], sql.Over)
193+
assert isinstance(p.tokens[0].tokens[0].tokens[3].tokens[2],
194+
sql.Identifier)
195+
p = sqlparse.parse('foo(c1) over (partition by c2 order by c3) as bar')[0]
196+
assert isinstance(p.tokens[0], sql.Identifier)
197+
assert isinstance(p.tokens[0].tokens[0], sql.Function)
198+
assert len(p.tokens[0].tokens[0].tokens) == 4
199+
assert isinstance(p.tokens[0].tokens[0].tokens[3], sql.Over)
200+
assert isinstance(p.tokens[0].tokens[0].tokens[3].tokens[2],
201+
sql.Parenthesis)
188202

189203

190204
@pytest.mark.parametrize('s', ['foo+100', 'foo + 100', 'foo*100'])

0 commit comments

Comments
 (0)