diff options
| author | Victor Uriarte <victor.m.uriarte@intel.com> | 2016-05-10 20:03:20 -0700 |
|---|---|---|
| committer | Victor Uriarte <victor.m.uriarte@intel.com> | 2016-05-10 20:20:03 -0700 |
| commit | 4364b250c6b0632e7a39f8153e864a7f3d63833e (patch) | |
| tree | dcc5426a4ac1c05cf772d3a26815582fa62771ce /sqlparse/engine | |
| parent | f26719dc8d2c9cf4bf85501bb68cc4ed3f4da86d (diff) | |
| download | sqlparse-4364b250c6b0632e7a39f8153e864a7f3d63833e.tar.gz | |
Add group matching M_tokens and refactor group matching
remove slots in subclasses
Diffstat (limited to 'sqlparse/engine')
| -rw-r--r-- | sqlparse/engine/grouping.py | 112 |
1 files changed, 22 insertions, 90 deletions
diff --git a/sqlparse/engine/grouping.py b/sqlparse/engine/grouping.py index df967c3..a34706f 100644 --- a/sqlparse/engine/grouping.py +++ b/sqlparse/engine/grouping.py @@ -4,7 +4,7 @@ import itertools from sqlparse import sql from sqlparse import tokens as T -from sqlparse.utils import recurse +from sqlparse.utils import recurse, imt, find_matching def _group_left_right(tlist, ttype, value, cls, @@ -47,68 +47,36 @@ def _group_left_right(tlist, ttype, value, cls, ttype, value) -def _find_matching(idx, tlist, start_ttype, start_value, end_ttype, end_value): - depth = 1 - for tok in tlist.tokens[idx:]: - if tok.match(start_ttype, start_value): - depth += 1 - elif tok.match(end_ttype, end_value): - depth -= 1 - if depth == 1: - return tok - return None - - -def _group_matching(tlist, start_ttype, start_value, end_ttype, end_value, - cls, include_semicolon=False, recurse=False): - - [_group_matching(sgroup, start_ttype, start_value, end_ttype, end_value, - cls, include_semicolon) for sgroup in tlist.get_sublists() - if recurse] - if isinstance(tlist, cls): - idx = 1 - else: - idx = 0 - token = tlist.token_next_match(idx, start_ttype, start_value) +def _group_matching(tlist, cls): + """Groups Tokens that have beginning and end. ie. parenthesis, brackets..""" + idx = 1 if imt(tlist, i=cls) else 0 + + token = tlist.token_next_by(m=cls.M_OPEN, idx=idx) while token: - tidx = tlist.token_index(token) - end = _find_matching(tidx, tlist, start_ttype, start_value, - end_ttype, end_value) - if end is None: - idx = tidx + 1 - else: - if include_semicolon: - next_ = tlist.token_next(tlist.token_index(end)) - if next_ and next_.match(T.Punctuation, ';'): - end = next_ - group = tlist.group_tokens(cls, tlist.tokens_between(token, end)) - _group_matching(group, start_ttype, start_value, - end_ttype, end_value, cls, include_semicolon) - idx = tlist.token_index(group) + 1 - token = tlist.token_next_match(idx, start_ttype, start_value) + end = find_matching(tlist, token, cls.M_OPEN, cls.M_CLOSE) + if end is not None: + token = tlist.group_tokens(cls, tlist.tokens_between(token, end)) + _group_matching(token, cls) + token = tlist.token_next_by(m=cls.M_OPEN, idx=token) def group_if(tlist): - _group_matching(tlist, T.Keyword, 'IF', T.Keyword, 'END IF', sql.If, True) + _group_matching(tlist, sql.If) def group_for(tlist): - _group_matching(tlist, T.Keyword, 'FOR', T.Keyword, 'END LOOP', - sql.For, True) + _group_matching(tlist, sql.For) def group_foreach(tlist): - _group_matching(tlist, T.Keyword, 'FOREACH', T.Keyword, 'END LOOP', - sql.For, True) + _group_matching(tlist, sql.For) def group_begin(tlist): - _group_matching(tlist, T.Keyword, 'BEGIN', T.Keyword, 'END', - sql.Begin, True) + _group_matching(tlist, sql.Begin) def group_as(tlist): - def _right_valid(token): # Currently limited to DML/DDL. Maybe additional more non SQL reserved # keywords should appear here (see issue8). @@ -130,7 +98,6 @@ def group_assignment(tlist): def group_comparison(tlist): - def _parts_valid(token): return (token.ttype in (T.String.Symbol, T.String.Single, T.Name, T.Number, T.Number.Float, @@ -140,13 +107,13 @@ def group_comparison(tlist): sql.Function)) or (token.ttype is T.Keyword and token.value.upper() in ['NULL', ])) + _group_left_right(tlist, T.Operator.Comparison, None, sql.Comparison, check_left=_parts_valid, check_right=_parts_valid) def group_case(tlist): - _group_matching(tlist, T.Keyword, 'CASE', T.Keyword, 'END', sql.Case, - include_semicolon=True, recurse=True) + _group_matching(tlist, sql.Case) def group_identifier(tlist): @@ -222,7 +189,7 @@ def group_identifier(tlist): and (isinstance(identifier_tokens[0], (sql.Function, sql.Parenthesis)) or identifier_tokens[0].ttype in ( - T.Literal.Number.Integer, T.Literal.Number.Float))): + T.Literal.Number.Integer, T.Literal.Number.Float))): group = tlist.group_tokens(sql.Identifier, identifier_tokens) idx = tlist.token_index(group, start=idx) + 1 else: @@ -284,47 +251,11 @@ def group_identifier_list(tlist): def group_brackets(tlist): - """Group parentheses () or square brackets [] - - This is just like _group_matching, but complicated by the fact that - round brackets can contain square bracket groups and vice versa - """ - - if isinstance(tlist, (sql.Parenthesis, sql.SquareBrackets)): - idx = 1 - else: - idx = 0 - - # Find the first opening bracket - token = tlist.token_next_match(idx, T.Punctuation, ['(', '[']) - - while token: - start_val = token.value # either '(' or '[' - if start_val == '(': - end_val = ')' - group_class = sql.Parenthesis - else: - end_val = ']' - group_class = sql.SquareBrackets - - tidx = tlist.token_index(token) - - # Find the corresponding closing bracket - end = _find_matching(tidx, tlist, T.Punctuation, start_val, - T.Punctuation, end_val) - - if end is None: - idx = tidx + 1 - else: - group = tlist.group_tokens(group_class, - tlist.tokens_between(token, end)) + _group_matching(tlist, sql.SquareBrackets) - # Check for nested bracket groups within this group - group_brackets(group) - idx = tlist.token_index(group) + 1 - # Find the next opening bracket - token = tlist.token_next_match(idx, T.Punctuation, ['(', '[']) +def group_parenthesis(tlist): + _group_matching(tlist, sql.Parenthesis) @recurse(sql.Comment) @@ -431,6 +362,7 @@ def group(tlist): for func in [ group_comments, group_brackets, + group_parenthesis, group_functions, group_where, group_case, |
