diff --git a/sqlparse/filters/reindent.py b/sqlparse/filters/reindent.py index ea41ac6b..8a818caa 100644 --- a/sqlparse/filters/reindent.py +++ b/sqlparse/filters/reindent.py @@ -139,26 +139,30 @@ def _process_identifierlist(self, tlist): if not tlist.within(sql.Function) and not tlist.within(sql.Values): with offset(self, num_offset): position = 0 + # Walk the identifiers in order and keep a cursor into the + # token list so token_index() doesn't rescan from the start on + # every insertion (that made wide lists O(n^2)). + last_idx = 0 for token in identifiers: # Add 1 for the "," separator position += len(token.value) + 1 if position > (self.wrap_after - self.offset): adjust = 0 + tidx = tlist.token_index(token, last_idx) if self.comma_first: adjust = -2 - _, comma = tlist.token_prev( - tlist.token_index(token)) + tidx, comma = tlist.token_prev(tidx) if comma is None: continue - token = comma - tlist.insert_before(token, self.nl(offset=adjust)) + tlist.insert_before(tidx, self.nl(offset=adjust)) + last_idx = tidx if self.comma_first: _, ws = tlist.token_next( - tlist.token_index(token), skip_ws=False) + tidx + 1, skip_ws=False) if (ws is not None and ws.ttype is not T.Text.Whitespace): tlist.insert_after( - token, sql.Token(T.Whitespace, ' ')) + tidx + 1, sql.Token(T.Whitespace, ' ')) position = 0 else: # ensure whitespace diff --git a/sqlparse/sql.py b/sqlparse/sql.py index 5489f055..64c133c2 100644 --- a/sqlparse/sql.py +++ b/sqlparse/sql.py @@ -307,7 +307,7 @@ def matcher(tk): def token_index(self, token, start=0): """Return list index of token.""" start = start if isinstance(start, int) else self.token_index(start) - return start + self.tokens[start:].index(token) + return self.tokens.index(token, start) def group_tokens(self, grp_cls, start, end, include_end=True, extend=False):