|
1 | | -# sqlint |
2 | | -This is a SQL parser and linter for Standard SQL(BigQuery). |
3 | | - |
4 | | -## Install |
5 | | - |
6 | | -pip, |
7 | | - |
8 | | -```bash |
9 | | -$ pip install sqlint |
10 | | -``` |
11 | | - |
12 | | -repository, |
13 | | - |
14 | | -```bash |
15 | | -$ git clone [email protected]:shigeru0215/sqlint.git |
16 | | -$ cd sqlint |
17 | | -$ python setup.py install |
18 | | -``` |
19 | | - |
20 | | - - if you use pyenv, |
21 | | - |
22 | | -```bash |
23 | | -$ pyenv rehash |
24 | | -``` |
25 | | - |
26 | | -## Usage |
27 | | - |
28 | | -Command line |
29 | | - |
30 | | -``` |
31 | | -$ sqlint query/*sql |
32 | | -``` |
33 | | - |
34 | | -Python module |
35 | | - |
36 | | -``` |
37 | | -$ python |
38 | | ->>> from sqlint import parse, check |
39 | | ->>> stmt = 'SELECT id From user_table where user_table.age >10' |
40 | | ->>> |
41 | | ->>> parse(stmt) |
42 | | -[[<Keyword: 'SELECT'>, <Whitespace: ' '>, <Identifier: 'id'>, <Whitespace: ' '>, <Keyword: 'From'>, <Whitespace: ' '>, <Identifier: 'user_table'>, <Whitespace: ' '>, <Keyword: 'where'>, <Whitespace: ' '>, <Identifier: 'user_table.age'>, <Whitespace: ' '>, <Operator: '>'>, <Identifier: '10'>]] |
43 | | ->>> |
44 | | ->>> check(stmt) |
45 | | -['(L1, 1): reserved keywords must be lower case: SELECT -> select', '(L1, 11): reserved keywords must be lower case: From -> from', '(L1, 26): too many spaces', '(L1, 49): whitespace must be after binary operator: >10'] |
46 | | -``` |
47 | | - |
48 | | -## Checking variations |
49 | | - |
50 | | -check all following variations in default |
51 | | - |
52 | | -- indent steps are N multiples.(default: N = 4) |
53 | | - |
54 | | -- duplicated spaces. |
55 | | - |
56 | | -- duplicated blank lines. |
57 | | - |
58 | | -- reserved keywords is capital or not (default: not capital). |
59 | | - |
60 | | -- comma is head(end) of the line which connect some columns or conditions. (default: head) |
61 | | - |
62 | | - |
63 | | -- white-spaces are not before ) or after ( |
64 | | - |
65 | | -- a whitespace is before and after binary operators |
66 | | - - (e.g.) =, <, >, <=. >=. <>, !=, +, -, *, /, % |
67 | | - |
68 | | -- the table name is at the same line as join context |
69 | | - |
70 | | -- join context is [left outer join], [inner join] or [cross join] |
71 | | - |
72 | | -- indent before 'on', 'or', 'and' (except between a and b) |
73 | | - |
74 | | -## Futures |
75 | | -- table_name alias doesn't equal reserved functions |
76 | | -- indent appropriately in reserved keywords. |
77 | | -- the order of conditions(x, y) at 'join on x = y' |
78 | | -- Optional: do not use sub-query |
79 | | -- Optional: do use hard-coding constant |
80 | | - |
81 | | -## Sample |
82 | | - |
83 | | -``` |
84 | | -$ sqlint sqlint/tests/data/* |
85 | | -sqlint/tests/data/query001.sql:(L2, 6): comma must be head of line |
86 | | -sqlint/tests/data/query001.sql:(L7, 6): comma must be head of line |
87 | | -sqlint/tests/data/query002.sql:(L1, 1): reserved keywords must be lower case: SELECT -> select |
88 | | -sqlint/tests/data/query002.sql:(L3, 7): reserved keywords must be lower case: COUNT -> count |
89 | | -sqlint/tests/data/query003.sql:(L2, 1): indent steps must be 4 multiples (5) |
90 | | -sqlint/tests/data/query004.sql:(L5, 18): too many spaces |
91 | | -sqlint/tests/data/query005.sql:(L2, 7): whitespace must not be after bracket: ( |
92 | | -sqlint/tests/data/query005.sql:(L2, 22): whitespace must not be before bracket: ) |
93 | | -sqlint/tests/data/query006.sql:(L3, 8): whitespace must be after binary operator: +c |
94 | | -sqlint/tests/data/query006.sql:(L3, 8): whitespace must be after binary operator: b+ |
95 | | -sqlint/tests/data/query007.sql:(L8, 16): table_name must be at the same line as join context |
96 | | -sqlint/tests/data/query008.sql:(L6, 5): join context must be [left outer join], [inner join] or [cross join]: join |
97 | | -sqlint/tests/data/query008.sql:(L10, 10): join context must be [left outer join], [inner join] or [cross join]: left join |
98 | | -sqlint/tests/data/query008.sql:(L14, 11): join context must be [left outer join], [inner join] or [cross join]: right join |
99 | | -sqlint/tests/data/query008.sql:(L16, 17): join context must be [left outer join], [inner join] or [cross join]: right outer join |
100 | | -sqlint/tests/data/query009.sql:(L6, 0): too many blank lines (2) |
101 | | -sqlint/tests/data/query009.sql:(L10, 0): too many blank lines (2) |
102 | | -sqlint/tests/data/query010.sql:(L6, 35): break line at 'and', 'or', 'on': on |
103 | | -sqlint/tests/data/query010.sql:(L11, 29): break line at 'and', 'or', 'on': and |
104 | | -sqlint/tests/data/query010.sql:(L12, 14): break line at 'and', 'or', 'on': or |
105 | | -``` |
| 1 | +[](https://circleci.com/gh/shigeru0215/sqlint/tree/develop) |
| 2 | + |
| 3 | +# sqlint |
| 4 | +This is a SQL parser and linter for Standard SQL(BigQuery). |
| 5 | + |
| 6 | +## Install |
| 7 | + |
| 8 | +pip, |
| 9 | + |
| 10 | +```bash |
| 11 | +$ pip install sqlint |
| 12 | +``` |
| 13 | + |
| 14 | +repository, |
| 15 | + |
| 16 | +```bash |
| 17 | +$ git clone [email protected]:shigeru0215/sqlint.git |
| 18 | +$ cd sqlint |
| 19 | +$ python setup.py install |
| 20 | +``` |
| 21 | + |
| 22 | + - if you use pyenv, |
| 23 | + |
| 24 | +```bash |
| 25 | +$ pyenv rehash |
| 26 | +``` |
| 27 | + |
| 28 | +## Usage |
| 29 | + |
| 30 | +Command line |
| 31 | + |
| 32 | +```bash |
| 33 | +$ sqlint query/*sql |
| 34 | +``` |
| 35 | + |
| 36 | +REPL |
| 37 | + |
| 38 | +```bash |
| 39 | +$ python |
| 40 | +>>> from sqlint import parse, check |
| 41 | +>>> sql = 'SELECT id From user_table where user_table.age >10' |
| 42 | +>>> |
| 43 | +>>> parse(sql) |
| 44 | +[[<Keyword: 'SELECT'>, <Whitespace: ' '>, <Identifier: 'id'>, <Whitespace: ' '>, <Keyword: 'From'>, <Whitespace: ' '>, <Identifier: 'user_table'>, <Whitespace: ' '>, <Keyword: 'where'>, <Whitespace: ' '>, <Identifier: 'user_table.age'>, <Whitespace: ' '>, <Operator: '>'>, <Identifier: '10'>]] |
| 45 | +>>> |
| 46 | +>>> check(sql) |
| 47 | +['(L1, 1): reserved keywords must be lower case: SELECT -> select', '(L1, 11): reserved keywords must be lower case: From -> from', '(L1, 26): too many spaces', '(L1, 49): whitespace must be after binary operator: >10'] |
| 48 | +``` |
| 49 | + |
| 50 | +Dockerfile |
| 51 | + |
| 52 | +```bash |
| 53 | +$ docker build -t sqlint:latest . |
| 54 | + ... |
| 55 | +$ docker run -it sqlint:latset /bin/bash |
| 56 | +xxxxx:/work # python3 -m sqlint sqlint/tests/data/query005.sql |
| 57 | +sqlint/tests/data/query005.sql:(L2, 6): comma must be head of line |
| 58 | +sqlint/tests/data/query005.sql:(L7, 6): comma must be head of line |
| 59 | +``` |
| 60 | + |
| 61 | +## Checking variations |
| 62 | + |
| 63 | +Check if sql statement violates following rules. |
| 64 | + |
| 65 | +- indent steps are N multiples (default: N = 4). |
| 66 | + |
| 67 | +- duplicated whitespaces except indent. |
| 68 | + |
| 69 | +- duplicated blank lines. |
| 70 | + |
| 71 | +- reserved keywords is capital case or not (default: not capital). |
| 72 | + |
| 73 | +- comma is head(or end) of the line which connects some columns or conditions (default: head). |
| 74 | + |
| 75 | +- a whitespace are not before `)` or after `(`. |
| 76 | + |
| 77 | +- a whitespace is before and after binary operators. |
| 78 | + - (e.g.) `=`, `<`, `>`, `<=`. `>=`. `<>`, `!=`, `+`, `-`, `*`, `/`, `%` |
| 79 | + |
| 80 | +- the table name is at the same line as join context. |
| 81 | + |
| 82 | +- join contexts are written fully, for example `left outer join, `inner join or `cross join`. |
| 83 | + |
| 84 | +- whether new line starts at 'on', 'or', 'and' context (except `between`). |
| 85 | + |
| 86 | +## Futures |
| 87 | +- table_name alias doesn't equal reserved functions |
| 88 | +- indent appropriately in reserved keywords. |
| 89 | +- the order of conditions(x, y) at 'join on x = y' |
| 90 | +- Optional: do not use sub-query |
| 91 | +- Optional: do use hard-coding constant |
| 92 | + |
| 93 | +## Sample |
| 94 | + |
| 95 | +``` |
| 96 | +$ sqlint sqlint/tests/samples/* |
| 97 | +tests/samples/query001.sql (L2, 1): indent steps must be 4 multiples, but 5 spaces |
| 98 | +tests/samples/query002.sql (L6, 16): there are multiple whitespaces |
| 99 | +tests/samples/query003.sql (L2, 7): whitespace must not be after bracket: ( |
| 100 | +tests/samples/query003.sql (L2, 22): whitespace must not be before bracket: ) |
| 101 | +tests/samples/query004.sql (L3, 8): whitespace must be before binary operator: b+ |
| 102 | +tests/samples/query004.sql (L3, 8): whitespace must be after binary operator: +c |
| 103 | +tests/samples/query005.sql (L2, 6): comma must be head of line |
| 104 | +tests/samples/query005.sql (L7, 6): comma must be head of line |
| 105 | +tests/samples/query006.sql (L1, 1): reserved keywords must be lower case: SELECT -> select |
| 106 | +tests/samples/query006.sql (L3, 7): reserved keywords must be lower case: Count -> count |
| 107 | +tests/samples/query007.sql (L8, 16): table_name must be at the same line as join context |
| 108 | +tests/samples/query008.sql (L6, 5): join context must be fully: join -> inner join |
| 109 | +tests/samples/query008.sql (L10, 10): join context must be fully: left join -> left outer join |
| 110 | +tests/samples/query008.sql (L14, 11): join context must be fully: right join -> right outer join |
| 111 | +tests/samples/query009.sql (L6, 1): there are multiple blank lines |
| 112 | +tests/samples/query009.sql (L9, 1): there are multiple blank lines |
| 113 | +tests/samples/query013.sql (L3, 5): whitespace must be after comma: ,b |
| 114 | +tests/samples/query013.sql (L7, 13): whitespace must not be before comma: , |
| 115 | +tests/samples/query013.sql (L7, 13): whitespace must be after comma: ,2 |
| 116 | +``` |
0 commit comments