summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndi Albrecht <albrecht.andi@gmail.com>2016-09-14 18:42:22 +0200
committerAndi Albrecht <albrecht.andi@gmail.com>2016-09-14 18:42:22 +0200
commit4d05b441fcb801d320ac52ce90465b74d419ceac (patch)
tree0f18b1f401d1fce76be0d8403153e5616dbe573e
parent4430c5c163d8b6ffc89d83b506c8a478037d26ea (diff)
downloadsqlparse-4d05b441fcb801d320ac52ce90465b74d419ceac.tar.gz
Add formatter option for comma first notation (fixes #141).
-rw-r--r--CHANGELOG5
-rwxr-xr-xsqlparse/cli.py7
-rw-r--r--sqlparse/filters/reindent.py17
-rw-r--r--sqlparse/formatter.py8
-rw-r--r--tests/test_format.py15
5 files changed, 50 insertions, 2 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 33479cf..6cad45f 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,11 @@
Development Version
-------------------
+Enhancements
+
+* Add comma_first option: When splitting list "comma first" notation
+ is used (issue141).
+
Bug Fixes
* Fix parsing of incomplete AS (issue284, by vmuriart).
diff --git a/sqlparse/cli.py b/sqlparse/cli.py
index 9479dd1..bd2e1b8 100755
--- a/sqlparse/cli.py
+++ b/sqlparse/cli.py
@@ -118,6 +118,13 @@ def create_parser():
type=int,
help='Column after which lists should be wrapped')
+ group.add_argument(
+ '--comma_first',
+ dest='comma_first',
+ default=False,
+ type=bool,
+ help='Insert linebreak before comma (default False)')
+
return parser
diff --git a/sqlparse/filters/reindent.py b/sqlparse/filters/reindent.py
index dab4d03..7421f6d 100644
--- a/sqlparse/filters/reindent.py
+++ b/sqlparse/filters/reindent.py
@@ -11,13 +11,15 @@ from sqlparse.utils import offset, indent
class ReindentFilter(object):
- def __init__(self, width=2, char=' ', wrap_after=0, n='\n'):
+ def __init__(self, width=2, char=' ', wrap_after=0, n='\n',
+ comma_first=False):
self.n = n
self.width = width
self.char = char
self.indent = 0
self.offset = 0
self.wrap_after = wrap_after
+ self.comma_first = comma_first
self._curr_stmt = None
self._last_stmt = None
@@ -123,7 +125,20 @@ class ReindentFilter(object):
# Add 1 for the "," separator
position += len(token.value) + 1
if position > (self.wrap_after - self.offset):
+ if self.comma_first:
+ _, comma = tlist.token_prev(
+ tlist.token_index(token))
+ if comma is None:
+ continue
+ token = comma
tlist.insert_before(token, self.nl())
+ if self.comma_first:
+ _, ws = tlist.token_next(
+ tlist.token_index(token), skip_ws=False)
+ if (ws is not None
+ and not ws.ttype is T.Text.Whitespace):
+ tlist.insert_after(
+ token, sql.Token(T.Whitespace, ' '))
position = 0
self._process_default(tlist)
diff --git a/sqlparse/formatter.py b/sqlparse/formatter.py
index 72b50eb..a58d5af 100644
--- a/sqlparse/formatter.py
+++ b/sqlparse/formatter.py
@@ -97,6 +97,11 @@ def validate_options(options):
raise SQLParseError('wrap_after requires a positive integer')
options['wrap_after'] = wrap_after
+ comma_first = options.get('comma_first', False)
+ if comma_first not in [True, False]:
+ raise SQLParseError('comma_first requires a boolean value')
+ options['comma_first'] = comma_first
+
right_margin = options.get('right_margin')
if right_margin is not None:
try:
@@ -148,7 +153,8 @@ def build_filter_stack(stack, options):
stack.stmtprocess.append(
filters.ReindentFilter(char=options['indent_char'],
width=options['indent_width'],
- wrap_after=options['wrap_after']))
+ wrap_after=options['wrap_after'],
+ comma_first=options['comma_first']))
if options.get('reindent_aligned', False):
stack.enable_grouping()
diff --git a/tests/test_format.py b/tests/test_format.py
index 023f26d..67377ab 100644
--- a/tests/test_format.py
+++ b/tests/test_format.py
@@ -322,6 +322,8 @@ class TestFormatReindent(object):
sqlparse.format('foo', reindent=True, wrap_after='foo')
with pytest.raises(SQLParseError):
sqlparse.format('foo', reindent=True, wrap_after=-12)
+ with pytest.raises(SQLParseError):
+ sqlparse.format('foo', reindent=True, comma_first='foo')
def test_stmts(self):
f = lambda sql: sqlparse.format(sql, reindent=True)
@@ -428,6 +430,19 @@ class TestFormatReindent(object):
'from table1, table2',
'where 1 = 2'])
+ def test_identifier_list_comment_first(self):
+ f = lambda sql: sqlparse.format(sql, reindent=True, comma_first=True)
+ # not the 3: It cleans up whitespace too!
+ s = 'select foo, bar, baz from table where foo in (1, 2,3)'
+ assert f(s) == '\n'.join([
+ 'select foo',
+ ' , bar',
+ ' , baz',
+ 'from table',
+ 'where foo in (1',
+ ' , 2',
+ ' , 3)'])
+
def test_identifier_list_with_functions(self):
f = lambda sql: sqlparse.format(sql, reindent=True)
s = ("select 'abc' as foo, coalesce(col1, col2)||col3 as bar,"