Skip to content

Commit

Permalink
Merge pull request #4 from ota-meshi/master
Browse files Browse the repository at this point in the history
[fix] bugfix
  • Loading branch information
ota-meshi authored Mar 6, 2017
2 parents 8d62e5b + b150d65 commit 5e3fa0a
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 20 deletions.
49 changes: 49 additions & 0 deletions python/test/test_issues.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# coding:utf-8
'''
Created on 2016/07/05
@author: ota
'''
import unittest
import uroborosqlfmt


class Test(unittest.TestCase):

def test1(self):
self.assertEqual(format_sql("""
SELECT
/* _SQL_ID_ */
EMP.EMP_NO AS EMP_NO
, EMP.FIRST_NAME AS FIRST_NAME
, EMP.LAST_NAME AS LAST_NAME
, EMP.BIRTH_DATE AS BIRTH_DATE
, EMP.GENDER AS GENDER
FROM
EMPLOYEE EMP /*BEGIN*/
WHERE
/*IF SF.isNotEmpty(emp_no)*/
AND EMP.EMP_NO = /*emp_no*/1
/*END*/
/*IF female != null and female*/
AND EMP.GENDER = /*#CLS_GENDER_FEMALE*/'M'
/*END*/
/*END*/
"""), "SELECT /* _SQL_ID_ */\n\tEMP.EMP_NO\t\tAS\tEMP_NO\n,\tEMP.FIRST_NAME\tAS\tFIRST_NAME\n,\tEMP.LAST_NAME\tAS\tLAST_NAME\n,\tEMP.BIRTH_DATE\tAS\tBIRTH_DATE\n,\tEMP.GENDER\t\tAS\tGENDER\nFROM\n\tEMPLOYEE\tEMP\n/*BEGIN*/\nWHERE\n/*IF SF.isNotEmpty(emp_no)*/\nAND\tEMP.EMP_NO\t=\t/*emp_no*/1\n/*END*/\n/*IF female != null and female*/\nAND\tEMP.GENDER\t=\t/*#CLS_GENDER_FEMALE*/'M'\n/*END*/\n/*END*/\n")

def test2(self):
self.assertEqual(format_sql("""
select * from tbl where 1 = 1 and(2 = 2)
"""),'SELECT\n\t*\nFROM\n\tTBL\nWHERE\n\t1\t=\t1\nAND\t(\n\t\t2\t=\t2\n\t)')

def format_sql(text):
formated = uroborosqlfmt.format_sql(text)
# print(formated)
# print(repr(formated))

return formated


if __name__ == "__main__":
#import sys;sys.argv = ['', 'Test.testName']
unittest.main()
4 changes: 2 additions & 2 deletions python/uroborosqlfmt/commentsyntax.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ def get_block_comment_type(self, token):
tokens = token.tokens
if len(tokens) >= 3 :
comment = tokens[1].value
if comment.strip() == "_SQL_IDENTIFIER_":
if comment.strip() == "_SQL_ID_" or comment.strip() == "_SQL_IDENTIFIER_":
return EngineComment.sql_identifier # _SQL_IDENTIFIER_
if tu.startswith_ignore_case(comment, ("IF", "ELIF", "ELSE", "END")):
if tu.startswith_ignore_case(comment, ("IF", "ELIF", "ELSE", "END", "BEGIN")):
return EngineComment.syntax
if comment.strip() == comment and (not comment.startswith("*")) and (not comment.startswith("+")):
return EngineComment.param # param
Expand Down
33 changes: 33 additions & 0 deletions python/uroborosqlfmt/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -969,6 +969,25 @@ def is_include_join(tlist):

return False

def is_with_query_cols(tlist):
"""
WITHのqueryカラム名括弧判定
"""
parent = tlist.parent
if parent and tu.is_identifier(parent):
nametoken = tu.token_prev_enable(parent, tlist)
if not nametoken:
return False
if not tu.is_identifier(nametoken) and not nametoken.ttype in T.Name:
return False

parent = parent.parent
if parent and tu.is_identifier_list(parent):
parent = parent.parent
if parent and tu.is_with(parent):
return True
return False

def is_need_shift(tlist):
"""
閉じ括弧「)」の前が改行されている場合shiftさせる
Expand Down Expand Up @@ -1013,6 +1032,8 @@ def is_need_shift(tlist):
self.__process_parenthesis_for_insert(tlist)
elif is_include_join(tlist): # JOIN句の括弧
self.__process_parenthesis_for_jointables(tlist)
elif is_with_query_cols(tlist): # WITH句の括弧
self.__process_parenthesis_for_with_query_cols(tlist)
elif tu.is_enum_parenthesis(tlist):
if self._is_include_format_target_identifire_list_parenthesis(tlist):
self.__process_parenthesis_for_identifier_list(tlist) # identifierlistのフォーマットを期待した処理
Expand Down Expand Up @@ -1072,6 +1093,18 @@ def __process_parenthesis_for_jointables(self, tlist):

self.indent -= 1

def __process_parenthesis_for_with_query_cols(self, tlist):
"""
WITHのqueryカラム名
"""
open_punc = tlist.token_next_match(0, T.Punctuation, '(')
self.indent += 1
tlist.insert_after(open_punc, self.nl())
self._process_default(tlist)

close_punc = tlist.token_next_match(open_punc, T.Punctuation, ')')
tlist.insert_before(close_punc, self.nl())
self.indent -= 1

def __process_parenthesis_for_insert(self, tlist):
open_punc = tlist.token_next_match(0, T.Punctuation, '(')
Expand Down
47 changes: 29 additions & 18 deletions python/uroborosqlfmt/grouping.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,9 @@ def re_group_function(stmt):
SET(A,B,・・・)
と記述するとSET句がFunction扱いになるのを修正する(バグ)
AND(A = B)
と記述するとAND句がFunction扱いになるのを修正する(バグ)
INSERT INTO TABLE1(COL1,COL2,COL3)
及び
INSERT INTO SC.TABLE1(COL1,COL2,COL3)
Expand Down Expand Up @@ -282,11 +285,27 @@ def _split_function(tlist, parent):
"""
functionを分解
"""
_remove_split_token(tlist, parent)
return _remove_split_token(tlist, parent)

def _split_function_for_keyword(tlist, parent):
"""
functionを分解 (KEY WORD用)
"""
keyword_token = next(tlist.flatten())
keyword_token.ttype = T.Keyword # なぜかKeywordにならないときがある
target = _split_function(tlist, parent)
# identifier扱いされていることがある
while keyword_token.parent \
and len(keyword_token.parent.tokens) == 1 \
and tu.is_identifier(keyword_token.parent):
target = _remove_split_token(keyword_token.parent, keyword_token.parent.parent)
return target

def proc(tlist, parent):
[proc(sgroup, tlist) for sgroup in tlist.get_sublists()]



if tu.is_function(tlist):
if tu.equals_ignore_case(tu.token_next_enable(tlist).value, "FROM"): # FROM句がfunction扱いされている
_adjust_from_function(tlist, parent)
Expand All @@ -307,25 +326,17 @@ def proc(tlist, parent):
elif tu.equals_ignore_case(tu.token_next_enable(tlist).value, "UNION"): # UNIONがfunction扱いされている
_split_function(tlist, parent)
elif tu.equals_ignore_case(tu.token_next_enable(tlist).value, "ON"): # ONがfunction扱いされている
keyword_token = next(tlist.flatten())
keyword_token.ttype = T.Keyword # なぜかKeywordにならないときがある
_split_function(tlist, parent)
# identifier扱いされていることがある
while keyword_token.parent \
and len(keyword_token.parent.tokens) == 1 \
and tu.is_identifier(keyword_token.parent):
_remove_split_token(keyword_token.parent, keyword_token.parent.parent)
_split_function_for_keyword(tlist, parent)
elif tu.equals_ignore_case(tu.token_next_enable(tlist).value, "USING"): # USINGがfunction扱いされている
_split_function(tlist, parent)
elif tu.equals_ignore_case(tu.token_next_enable(tlist).value, "SET"): # SETがfunction扱いされている
keyword_token = next(tlist.flatten())
keyword_token.ttype = T.Keyword # なぜかKeywordにならないときがある
_split_function(tlist, parent)
# identifier扱いされていることがある
while keyword_token.parent and \
len(keyword_token.parent.tokens) == 1 and \
tu.is_identifier(keyword_token.parent):
_remove_split_token(keyword_token.parent, keyword_token.parent.parent)
elif tu.equals_ignore_case(tu.token_next_enable(tlist).value, "SET"): # SETがfunction扱いされている \
_split_function_for_keyword(tlist, parent)
elif tu.equals_ignore_case(tu.token_next_enable(tlist).value, "AND") \
or tu.equals_ignore_case(tu.token_next_enable(tlist).value, "OR"): # AND/ORがfunction扱いされている
target = _split_function_for_keyword(tlist, parent)[0]
# スペース挿入
target.parent.insert_after(target, sql.Token(T.Whitespace, "\t"))


proc = SqlFormatterException.to_wrap_try_except(proc, 0)
proc(stmt, None)
Expand Down

0 comments on commit 5e3fa0a

Please sign in to comment.