From a9427d9aff77fd6fcd8ab8d13fc2a87eb16cc2b9 Mon Sep 17 00:00:00 2001 From: Adam Greenhall Date: Fri, 11 Sep 2015 16:51:06 -0700 Subject: Start work on Aligned-reindent --- sqlparse/filters.py | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++ sqlparse/formatter.py | 12 +++++++ 2 files changed, 104 insertions(+) (limited to 'sqlparse') diff --git a/sqlparse/filters.py b/sqlparse/filters.py index 95ac74c..78c8d34 100644 --- a/sqlparse/filters.py +++ b/sqlparse/filters.py @@ -335,6 +335,98 @@ class ReindentFilter(object): self._last_stmt = stmt +class AlignedIndentFilter: + split_words = ( + 'FROM', + 'JOIN', 'ON', + 'WHERE', 'AND', 'OR', + 'GROUP', 'HAVING', + 'ORDER', 'UNION', 'VALUES', + 'SET', 'BETWEEN', 'EXCEPT', + ) + + def __init__(self, char=' ', line_width=None): + self.char = char + self._max_kwd_len = len('select') + + def newline(self): + return sql.Token(T.Newline, '\n') + + def whitespace(self, chars=0, newline_before=False, newline_after=False): + return sql.Token( + T.Whitespace, + (str(self.newline()) if newline_before else '') + self.char * chars + (str(self.newline()) if newline_after else '')) + + def _process_statement(self, tlist, base_indent=0): + if tlist.tokens[0].is_whitespace() and base_indent == 0: + tlist.tokens.pop(0) + + # process the main query body + return self._process(sql.TokenList(tlist.tokens), base_indent=base_indent) + + def _process_parenthesis(self, tlist, base_indent=0): + sub_indent = base_indent + self._max_kwd_len + 2 # add two for the space and parens + tlist.insert_after(tlist.tokens[0], self.whitespace(sub_indent, newline_before=True)) + # de-indent the last parenthesis + tlist.insert_before(tlist.tokens[-1], self.whitespace(sub_indent - 1, newline_before=True)) + + # process the inside of the parantheses + tlist.tokens = ( + [tlist.tokens[0]] + + self._process(sql.TokenList(tlist._groupable_tokens), base_indent=sub_indent).tokens + + [tlist.tokens[-1]] + ) + return tlist + + def _process_identifierlist(self, tlist, base_indent=0): + # columns being selected + new_tokens = [] + identifiers = filter(lambda t: isinstance(t, sql.Identifier), tlist.tokens) + for i, token in enumerate(identifiers): + if i > 0: + new_tokens.append(self.newline()) + new_tokens.append(self.whitespace(self._max_kwd_len + base_indent + 1)) + new_tokens.append(token) + if i < len(identifiers) - 1: + # if not last column in select, add a comma seperator + new_tokens.append(sql.Token(T.Punctuation, ',')) + tlist.tokens = new_tokens + return tlist + + def _process_substatement(self, tlist, base_indent=0): + def _next_token(i): + t = tlist.token_next_match(i, T.Keyword, self.split_words, regex=True) + # treat "BETWEEN x and y" as a single statement + if t and t.value.upper() == 'BETWEEN': + t = _next_token(tlist.token_index(t) + 1) + if t and t.value.upper() == 'AND': + t = _next_token(tlist.token_index(t) + 1) + return t + + idx = 0 + token = _next_token(idx) + while token: + tlist.insert_before(token, self.whitespace(self._max_kwd_len - len(str(token)) + base_indent, newline_before=True)) + next_idx = tlist.token_index(token) + 1 + token = _next_token(next_idx) + + # process any sub-sub statements + for sgroup in tlist.get_sublists(): + self._process(sgroup, base_indent=base_indent) + return tlist + + def _process(self, tlist, base_indent=0, verbose=False): + token_name = tlist.__class__.__name__.lower() + func_name = '_process_%s' % token_name + func = getattr(self, func_name, self._process_substatement) + if verbose: + print func.__name__, token_name, str(tlist) + return func(tlist, base_indent=base_indent) + + def process(self, stack, stmt): + self._process(stmt) + + # FIXME: Doesn't work class RightMarginFilter(object): keep_together = ( diff --git a/sqlparse/formatter.py b/sqlparse/formatter.py index 7441313..5af8743 100644 --- a/sqlparse/formatter.py +++ b/sqlparse/formatter.py @@ -55,6 +55,13 @@ def validate_options(options): elif reindent: options['strip_whitespace'] = True + reindent_aligned = options.get('reindent_aligned', False) + if reindent_aligned not in [True, False]: + raise SQLParseError('Invalid value for reindent_aligned: %r' + % reindent) + elif reindent_aligned: + options['strip_whitespace'] = True + indent_tabs = options.get('indent_tabs', False) if indent_tabs not in [True, False]: raise SQLParseError('Invalid value for indent_tabs: %r' % indent_tabs) @@ -130,6 +137,11 @@ def build_filter_stack(stack, options): width=options['indent_width'], wrap_after=options['wrap_after'])) + if options.get('reindent_aligned', False): + stack.enable_grouping() + stack.stmtprocess.append( + filters.AlignedIndentFilter(char=options['indent_char'])) + if options.get('right_margin'): stack.enable_grouping() stack.stmtprocess.append( -- cgit v1.2.1 From 9ad0acafabd8c8216fdacb71310f6ec56ef59ae9 Mon Sep 17 00:00:00 2001 From: Adam Greenhall Date: Fri, 11 Sep 2015 21:58:17 -0700 Subject: Fix Case statements --- sqlparse/filters.py | 29 +++++++++++++++++++++++++++++ sqlparse/sql.py | 5 ++++- 2 files changed, 33 insertions(+), 1 deletion(-) (limited to 'sqlparse') diff --git a/sqlparse/filters.py b/sqlparse/filters.py index 78c8d34..dad754e 100644 --- a/sqlparse/filters.py +++ b/sqlparse/filters.py @@ -391,8 +391,37 @@ class AlignedIndentFilter: # if not last column in select, add a comma seperator new_tokens.append(sql.Token(T.Punctuation, ',')) tlist.tokens = new_tokens + + # process any sub-sub statements (like case statements) + for sgroup in tlist.get_sublists(): + self._process(sgroup, base_indent=base_indent) return tlist + def _process_case(self, tlist, base_indent=0): + base_offset = base_indent + self._max_kwd_len + len('case ') + case_offset = len('when ') + cases = tlist.get_cases(skip_ws=True) + # align the end as well + end_token = tlist.token_next_match(0, T.Keyword, 'END') + cases.append((None, [end_token])) + + condition_width = max(len(str(cond)) for cond, value in cases) + for i, (cond, value) in enumerate(cases): + if cond is None: # else or end + stmt = value[0] + line = value + else: + stmt = cond[0] + line = cond + value + if i > 0: + tlist.insert_before(stmt, self.whitespace(base_offset + case_offset - len(str(stmt)))) + if cond: + tlist.insert_after(cond[-1], self.whitespace(condition_width - len(str(cond)))) + + if i < len(cases) - 1: + # if not the END add a newline + tlist.insert_after(line[-1], self.newline()) + def _process_substatement(self, tlist, base_indent=0): def _next_token(i): t = tlist.token_next_match(i, T.Keyword, self.split_words, regex=True) diff --git a/sqlparse/sql.py b/sqlparse/sql.py index 57bf1e7..daa5cf5 100644 --- a/sqlparse/sql.py +++ b/sqlparse/sql.py @@ -538,7 +538,7 @@ class Case(TokenList): M_OPEN = T.Keyword, 'CASE' M_CLOSE = T.Keyword, 'END' - def get_cases(self): + def get_cases(self, skip_ws=False): """Returns a list of 2-tuples (condition, value). If an ELSE exists condition is None. @@ -554,6 +554,9 @@ class Case(TokenList): if token.match(T.Keyword, 'CASE'): continue + elif skip_ws and token.ttype in T.Whitespace: + continue + elif token.match(T.Keyword, 'WHEN'): ret.append(([], [])) mode = CONDITION -- cgit v1.2.1 From 0e5a25f39fcff8cac8c54f0209be39dc86914570 Mon Sep 17 00:00:00 2001 From: Adam Greenhall Date: Fri, 11 Sep 2015 22:38:38 -0700 Subject: Fix/Test `Group-By` --- sqlparse/filters.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'sqlparse') diff --git a/sqlparse/filters.py b/sqlparse/filters.py index dad754e..0d0be5c 100644 --- a/sqlparse/filters.py +++ b/sqlparse/filters.py @@ -365,6 +365,10 @@ class AlignedIndentFilter: return self._process(sql.TokenList(tlist.tokens), base_indent=base_indent) def _process_parenthesis(self, tlist, base_indent=0): + if not tlist.token_next_match(0, T.DML, 'SELECT'): + # if this isn't a subquery, don't re-indent + return tlist + sub_indent = base_indent + self._max_kwd_len + 2 # add two for the space and parens tlist.insert_after(tlist.tokens[0], self.whitespace(sub_indent, newline_before=True)) # de-indent the last parenthesis @@ -381,7 +385,7 @@ class AlignedIndentFilter: def _process_identifierlist(self, tlist, base_indent=0): # columns being selected new_tokens = [] - identifiers = filter(lambda t: isinstance(t, sql.Identifier), tlist.tokens) + identifiers = filter(lambda t: t.ttype not in (T.Punctuation, T.Whitespace, T.Newline), tlist.tokens) for i, token in enumerate(identifiers): if i > 0: new_tokens.append(self.newline()) @@ -441,7 +445,13 @@ class AlignedIndentFilter: # process any sub-sub statements for sgroup in tlist.get_sublists(): - self._process(sgroup, base_indent=base_indent) + prev_token = tlist.token_prev(tlist.token_index(sgroup)) + indent_offset = 0 + if prev_token and prev_token.match(T.Keyword, 'BY'): + # HACK: make "group by" and "order by" indents work. these are longer than _max_kwd_len. + # TODO: generalize this + indent_offset = 3 + self._process(sgroup, base_indent=base_indent + indent_offset) return tlist def _process(self, tlist, base_indent=0, verbose=False): -- cgit v1.2.1 From 09de892c3b4e14d9b1a765d44e4824ec88e7e0eb Mon Sep 17 00:00:00 2001 From: Adam Greenhall Date: Sat, 12 Sep 2015 01:14:44 -0700 Subject: Fix/Test Limit statements --- sqlparse/filters.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sqlparse') diff --git a/sqlparse/filters.py b/sqlparse/filters.py index 0d0be5c..2f0e3b9 100644 --- a/sqlparse/filters.py +++ b/sqlparse/filters.py @@ -340,7 +340,7 @@ class AlignedIndentFilter: 'FROM', 'JOIN', 'ON', 'WHERE', 'AND', 'OR', - 'GROUP', 'HAVING', + 'GROUP', 'HAVING', 'LIMIT', 'ORDER', 'UNION', 'VALUES', 'SET', 'BETWEEN', 'EXCEPT', ) -- cgit v1.2.1 From b15c9c60e2479f6397b7bbcb0787ee66c499e7f8 Mon Sep 17 00:00:00 2001 From: Adam Greenhall Date: Sat, 12 Sep 2015 01:30:37 -0700 Subject: Fix/Test Joins --- sqlparse/filters.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'sqlparse') diff --git a/sqlparse/filters.py b/sqlparse/filters.py index 2f0e3b9..2ce17e9 100644 --- a/sqlparse/filters.py +++ b/sqlparse/filters.py @@ -336,9 +336,10 @@ class ReindentFilter(object): class AlignedIndentFilter: + join_words = r'((LEFT\s+|RIGHT\s+|FULL\s+)?(INNER\s+|OUTER\s+|STRAIGHT\s+)?|(CROSS\s+|NATURAL\s+)?)?JOIN\b' split_words = ( 'FROM', - 'JOIN', 'ON', + join_words, 'ON', 'WHERE', 'AND', 'OR', 'GROUP', 'HAVING', 'LIMIT', 'ORDER', 'UNION', 'VALUES', @@ -439,7 +440,12 @@ class AlignedIndentFilter: idx = 0 token = _next_token(idx) while token: - tlist.insert_before(token, self.whitespace(self._max_kwd_len - len(str(token)) + base_indent, newline_before=True)) + if token.match(T.Keyword, self.join_words, regex=True): + # joins are a special case. we only consider the first word of the join as the aligner + token_indent = len(token.value.split()[0]) + else: + token_indent = len(str(token)) + tlist.insert_before(token, self.whitespace(self._max_kwd_len - token_indent + base_indent, newline_before=True)) next_idx = tlist.token_index(token) + 1 token = _next_token(next_idx) -- cgit v1.2.1 From 74faef72d8e136a37bec93cc688817c97d162482 Mon Sep 17 00:00:00 2001 From: Adam Greenhall Date: Sat, 12 Sep 2015 01:52:01 -0700 Subject: Fix Case statements Alignment --- sqlparse/filters.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sqlparse') diff --git a/sqlparse/filters.py b/sqlparse/filters.py index 2ce17e9..193029f 100644 --- a/sqlparse/filters.py +++ b/sqlparse/filters.py @@ -410,7 +410,7 @@ class AlignedIndentFilter: end_token = tlist.token_next_match(0, T.Keyword, 'END') cases.append((None, [end_token])) - condition_width = max(len(str(cond)) for cond, value in cases) + condition_width = max(len(' '.join(map(str, cond))) for cond, value in cases if cond) for i, (cond, value) in enumerate(cases): if cond is None: # else or end stmt = value[0] @@ -421,7 +421,7 @@ class AlignedIndentFilter: if i > 0: tlist.insert_before(stmt, self.whitespace(base_offset + case_offset - len(str(stmt)))) if cond: - tlist.insert_after(cond[-1], self.whitespace(condition_width - len(str(cond)))) + tlist.insert_after(cond[-1], self.whitespace(condition_width - len(' '.join(map(str, cond))))) if i < len(cases) - 1: # if not the END add a newline -- cgit v1.2.1 From 2928a7c8f1192b8376795368825c2cf2dae243c3 Mon Sep 17 00:00:00 2001 From: Adam Greenhall Date: Sat, 12 Sep 2015 14:49:47 -0700 Subject: Add filter `Spaces around Operators` --- sqlparse/filters.py | 30 ++++++++++++++++++++++++++++++ sqlparse/formatter.py | 9 +++++++++ 2 files changed, 39 insertions(+) (limited to 'sqlparse') diff --git a/sqlparse/filters.py b/sqlparse/filters.py index 193029f..464a570 100644 --- a/sqlparse/filters.py +++ b/sqlparse/filters.py @@ -139,6 +139,36 @@ class StripWhitespaceFilter(object): stmt.tokens.pop(-1) +class SpacesAroundOperatorsFilter: + whitelist = (sql.Identifier, sql.Comparison, sql.Where) + + def _process(self, tlist): + def next_token(idx): + # HACK: distinguish between real wildcard from multiplication operator + return tlist.token_next_by_type(idx, (T.Operator, T.Comparison, T.Wildcard)) + idx = 0 + token = next_token(idx) + while token: + idx = tlist.token_index(token) + if idx > 0 and tlist.tokens[idx - 1].ttype != T.Whitespace: + tlist.tokens.insert(idx, sql.Token(T.Whitespace, ' ')) # insert before + idx += 1 + if idx < len(tlist.tokens) - 1: + if token.ttype == T.Wildcard and tlist.tokens[idx + 1].match(T.Punctuation, ','): + pass # this must have been a real wildcard, not multiplication + elif tlist.tokens[idx + 1].ttype != T.Whitespace: + tlist.tokens.insert(idx + 1, sql.Token(T.Whitespace, ' ')) + + idx += 1 + token = next_token(idx) + + for sgroup in tlist.get_sublists(): + self._process(sgroup) + + def process(self, stack, stmt): + self._process(stmt) + + class ReindentFilter(object): def __init__(self, width=2, char=' ', line_width=None, wrap_after=0): self.width = width diff --git a/sqlparse/formatter.py b/sqlparse/formatter.py index 5af8743..0fa563c 100644 --- a/sqlparse/formatter.py +++ b/sqlparse/formatter.py @@ -30,6 +30,11 @@ def validate_options(options): raise SQLParseError('Invalid value for strip_comments: %r' % strip_comments) + use_space_around_operators = options.get('use_space_around_operators', False) + if use_space_around_operators not in [True, False]: + raise SQLParseError('Invalid value for use_space_around_operators: %r' + % use_space_around_operators) + strip_ws = options.get('strip_whitespace', False) if strip_ws not in [True, False]: raise SQLParseError('Invalid value for strip_whitespace: %r' @@ -121,6 +126,10 @@ def build_filter_stack(stack, options): stack.preprocess.append(filters.TruncateStringFilter( width=options['truncate_strings'], char=options['truncate_char'])) + if options.get('use_space_around_operators', False): + stack.enable_grouping() + stack.stmtprocess.append(filters.SpacesAroundOperatorsFilter()) + # After grouping if options.get('strip_comments'): stack.enable_grouping() -- cgit v1.2.1 From a7c7d9586208516de372cb01203b48a53f7095fb Mon Sep 17 00:00:00 2001 From: Victor Uriarte Date: Sat, 4 Jun 2016 21:57:43 -0700 Subject: Format `pr` to pass flake8 and update functions used --- sqlparse/filters.py | 95 ++++++++++++++++++++++++++++----------------------- sqlparse/formatter.py | 6 ++-- 2 files changed, 56 insertions(+), 45 deletions(-) (limited to 'sqlparse') diff --git a/sqlparse/filters.py b/sqlparse/filters.py index 464a570..20f61a0 100644 --- a/sqlparse/filters.py +++ b/sqlparse/filters.py @@ -139,24 +139,23 @@ class StripWhitespaceFilter(object): stmt.tokens.pop(-1) -class SpacesAroundOperatorsFilter: +class SpacesAroundOperatorsFilter(object): whitelist = (sql.Identifier, sql.Comparison, sql.Where) def _process(self, tlist): def next_token(idx): - # HACK: distinguish between real wildcard from multiplication operator - return tlist.token_next_by_type(idx, (T.Operator, T.Comparison, T.Wildcard)) + return tlist.token_next_by(t=(T.Operator, T.Comparison), idx=idx) + idx = 0 token = next_token(idx) while token: idx = tlist.token_index(token) if idx > 0 and tlist.tokens[idx - 1].ttype != T.Whitespace: - tlist.tokens.insert(idx, sql.Token(T.Whitespace, ' ')) # insert before + # insert before + tlist.tokens.insert(idx, sql.Token(T.Whitespace, ' ')) idx += 1 if idx < len(tlist.tokens) - 1: - if token.ttype == T.Wildcard and tlist.tokens[idx + 1].match(T.Punctuation, ','): - pass # this must have been a real wildcard, not multiplication - elif tlist.tokens[idx + 1].ttype != T.Whitespace: + if tlist.tokens[idx + 1].ttype != T.Whitespace: tlist.tokens.insert(idx + 1, sql.Token(T.Whitespace, ' ')) idx += 1 @@ -165,7 +164,7 @@ class SpacesAroundOperatorsFilter: for sgroup in tlist.get_sublists(): self._process(sgroup) - def process(self, stack, stmt): + def process(self, stmt): self._process(stmt) @@ -365,16 +364,16 @@ class ReindentFilter(object): self._last_stmt = stmt -class AlignedIndentFilter: - join_words = r'((LEFT\s+|RIGHT\s+|FULL\s+)?(INNER\s+|OUTER\s+|STRAIGHT\s+)?|(CROSS\s+|NATURAL\s+)?)?JOIN\b' - split_words = ( - 'FROM', - join_words, 'ON', - 'WHERE', 'AND', 'OR', - 'GROUP', 'HAVING', 'LIMIT', - 'ORDER', 'UNION', 'VALUES', - 'SET', 'BETWEEN', 'EXCEPT', - ) +class AlignedIndentFilter(object): + join_words = (r'((LEFT\s+|RIGHT\s+|FULL\s+)?' + r'(INNER\s+|OUTER\s+|STRAIGHT\s+)?|' + r'(CROSS\s+|NATURAL\s+)?)?JOIN\b') + split_words = ('FROM', + join_words, 'ON', + 'WHERE', 'AND', 'OR', + 'GROUP', 'HAVING', 'LIMIT', + 'ORDER', 'UNION', 'VALUES', + 'SET', 'BETWEEN', 'EXCEPT') def __init__(self, char=' ', line_width=None): self.char = char @@ -384,43 +383,51 @@ class AlignedIndentFilter: return sql.Token(T.Newline, '\n') def whitespace(self, chars=0, newline_before=False, newline_after=False): - return sql.Token( - T.Whitespace, - (str(self.newline()) if newline_before else '') + self.char * chars + (str(self.newline()) if newline_after else '')) + return sql.Token(T.Whitespace, ('\n' if newline_before else '') + + self.char * chars + ('\n' if newline_after else '')) def _process_statement(self, tlist, base_indent=0): if tlist.tokens[0].is_whitespace() and base_indent == 0: tlist.tokens.pop(0) # process the main query body - return self._process(sql.TokenList(tlist.tokens), base_indent=base_indent) + return self._process(sql.TokenList(tlist.tokens), + base_indent=base_indent) def _process_parenthesis(self, tlist, base_indent=0): - if not tlist.token_next_match(0, T.DML, 'SELECT'): + if not tlist.token_next_by(m=(T.DML, 'SELECT')): # if this isn't a subquery, don't re-indent return tlist - sub_indent = base_indent + self._max_kwd_len + 2 # add two for the space and parens - tlist.insert_after(tlist.tokens[0], self.whitespace(sub_indent, newline_before=True)) + # add two for the space and parens + sub_indent = base_indent + self._max_kwd_len + 2 + tlist.insert_after(tlist.tokens[0], + self.whitespace(sub_indent, newline_before=True)) # de-indent the last parenthesis - tlist.insert_before(tlist.tokens[-1], self.whitespace(sub_indent - 1, newline_before=True)) + tlist.insert_before(tlist.tokens[-1], + self.whitespace(sub_indent - 1, + newline_before=True)) # process the inside of the parantheses tlist.tokens = ( [tlist.tokens[0]] + - self._process(sql.TokenList(tlist._groupable_tokens), base_indent=sub_indent).tokens + + self._process(sql.TokenList(tlist._groupable_tokens), + base_indent=sub_indent).tokens + [tlist.tokens[-1]] - ) + ) return tlist def _process_identifierlist(self, tlist, base_indent=0): # columns being selected new_tokens = [] - identifiers = filter(lambda t: t.ttype not in (T.Punctuation, T.Whitespace, T.Newline), tlist.tokens) + identifiers = list(filter( + lambda t: t.ttype not in (T.Punctuation, T.Whitespace, T.Newline), + tlist.tokens)) for i, token in enumerate(identifiers): if i > 0: new_tokens.append(self.newline()) - new_tokens.append(self.whitespace(self._max_kwd_len + base_indent + 1)) + new_tokens.append( + self.whitespace(self._max_kwd_len + base_indent + 1)) new_tokens.append(token) if i < len(identifiers) - 1: # if not last column in select, add a comma seperator @@ -437,10 +444,11 @@ class AlignedIndentFilter: case_offset = len('when ') cases = tlist.get_cases(skip_ws=True) # align the end as well - end_token = tlist.token_next_match(0, T.Keyword, 'END') + end_token = tlist.token_next_by(m=(T.Keyword, 'END')) cases.append((None, [end_token])) - condition_width = max(len(' '.join(map(str, cond))) for cond, value in cases if cond) + condition_width = max( + len(' '.join(map(str, cond))) for cond, value in cases if cond) for i, (cond, value) in enumerate(cases): if cond is None: # else or end stmt = value[0] @@ -449,9 +457,11 @@ class AlignedIndentFilter: stmt = cond[0] line = cond + value if i > 0: - tlist.insert_before(stmt, self.whitespace(base_offset + case_offset - len(str(stmt)))) + tlist.insert_before(stmt, self.whitespace( + base_offset + case_offset - len(str(stmt)))) if cond: - tlist.insert_after(cond[-1], self.whitespace(condition_width - len(' '.join(map(str, cond))))) + tlist.insert_after(cond[-1], self.whitespace( + condition_width - len(' '.join(map(str, cond))))) if i < len(cases) - 1: # if not the END add a newline @@ -459,7 +469,8 @@ class AlignedIndentFilter: def _process_substatement(self, tlist, base_indent=0): def _next_token(i): - t = tlist.token_next_match(i, T.Keyword, self.split_words, regex=True) + t = tlist.token_next_by(m=(T.Keyword, self.split_words, True), + idx=i) # treat "BETWEEN x and y" as a single statement if t and t.value.upper() == 'BETWEEN': t = _next_token(tlist.token_index(t) + 1) @@ -470,12 +481,14 @@ class AlignedIndentFilter: idx = 0 token = _next_token(idx) while token: + # joins are special case. only consider the first word as aligner if token.match(T.Keyword, self.join_words, regex=True): - # joins are a special case. we only consider the first word of the join as the aligner token_indent = len(token.value.split()[0]) else: token_indent = len(str(token)) - tlist.insert_before(token, self.whitespace(self._max_kwd_len - token_indent + base_indent, newline_before=True)) + tlist.insert_before(token, self.whitespace( + self._max_kwd_len - token_indent + base_indent, + newline_before=True)) next_idx = tlist.token_index(token) + 1 token = _next_token(next_idx) @@ -483,22 +496,20 @@ class AlignedIndentFilter: for sgroup in tlist.get_sublists(): prev_token = tlist.token_prev(tlist.token_index(sgroup)) indent_offset = 0 + # HACK: make "group/order by" work. Longer than _max_kwd_len. if prev_token and prev_token.match(T.Keyword, 'BY'): - # HACK: make "group by" and "order by" indents work. these are longer than _max_kwd_len. # TODO: generalize this indent_offset = 3 self._process(sgroup, base_indent=base_indent + indent_offset) return tlist - def _process(self, tlist, base_indent=0, verbose=False): + def _process(self, tlist, base_indent=0): token_name = tlist.__class__.__name__.lower() func_name = '_process_%s' % token_name func = getattr(self, func_name, self._process_substatement) - if verbose: - print func.__name__, token_name, str(tlist) return func(tlist, base_indent=base_indent) - def process(self, stack, stmt): + def process(self, stmt): self._process(stmt) diff --git a/sqlparse/formatter.py b/sqlparse/formatter.py index 0fa563c..069109b 100644 --- a/sqlparse/formatter.py +++ b/sqlparse/formatter.py @@ -30,10 +30,10 @@ def validate_options(options): raise SQLParseError('Invalid value for strip_comments: %r' % strip_comments) - use_space_around_operators = options.get('use_space_around_operators', False) - if use_space_around_operators not in [True, False]: + space_around_operators = options.get('use_space_around_operators', False) + if space_around_operators not in [True, False]: raise SQLParseError('Invalid value for use_space_around_operators: %r' - % use_space_around_operators) + % space_around_operators) strip_ws = options.get('strip_whitespace', False) if strip_ws not in [True, False]: -- cgit v1.2.1