Skip to content

Commit c13ad11

Browse files
authored
Merge pull request #246 from xnuinside/v1.1.0_release
V1.1.0 release
2 parents bf95ea9 + c0d07a0 commit c13ad11

File tree

13 files changed

+53136
-658
lines changed

13 files changed

+53136
-658
lines changed

CHANGELOG.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
**v1.1.0**
2+
### Improvements
3+
MySQL:
4+
1. Added support for INDEX statement inside table definition
5+
2. Added support for MySQL INVISIBLE/VISIBLE statement - https://github.com/xnuinside/simple-ddl-parser/issues/243
6+
7+
Snowflake:
8+
1. Added support for cluster by statement before columns definition - https://github.com/xnuinside/simple-ddl-parser/issues/234
9+
10+
111
**v1.0.4**
212
### Improvements
313
1. Support functions with schema prefix in `DEFAULT` and `CHECK` statements. https://github.com/xnuinside/simple-ddl-parser/issues/240

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,16 @@ for help with debugging & testing support for BigQuery dialect DDLs:
486486

487487

488488
## Changelog
489+
**v1.1.0**
490+
### Improvements
491+
MySQL:
492+
1. Added support for INDEX statement inside table definition
493+
2. Added support for MySQL INVISIBLE/VISIBLE statement - https://github.com/xnuinside/simple-ddl-parser/issues/243
494+
495+
Snowflake:
496+
1. Added support for cluster by statement before columns definition - https://github.com/xnuinside/simple-ddl-parser/issues/234
497+
498+
489499
**v1.0.4**
490500
### Improvements
491501
1. Support functions with schema prefix in `DEFAULT` and `CHECK` statements. https://github.com/xnuinside/simple-ddl-parser/issues/240

docs/README.rst

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -537,7 +537,7 @@ Big thanks for the involving & contribution with test cases with DDL samples & o
537537

538538

539539
* https://github.com/kukigai ,
540-
* https://github.com/Awalkman90 ,
540+
* https://github.com/kliushnichenko ,
541541
* https://github.com/geob3d
542542

543543
for help with debugging & testing support for BigQuery dialect DDLs:
@@ -549,6 +549,22 @@ for help with debugging & testing support for BigQuery dialect DDLs:
549549
Changelog
550550
---------
551551

552+
**v1.1.0**
553+
554+
Improvements
555+
^^^^^^^^^^^^
556+
557+
MySQL:
558+
559+
560+
#. Added support for INDEX statement inside table definition
561+
#. Added support for MySQL INVISIBLE/VISIBLE statement - https://github.com/xnuinside/simple-ddl-parser/issues/243
562+
563+
Snowflake:
564+
565+
566+
#. Added support for cluster by statement before columns definition - https://github.com/xnuinside/simple-ddl-parser/issues/234
567+
552568
**v1.0.4**
553569

554570
Improvements

pyproject.toml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "simple-ddl-parser"
3-
version = "1.0.4"
3+
version = "1.1.0"
44
description = "Simple DDL Parser to parse SQL & dialects like HQL, TSQL (MSSQL), Oracle, AWS Redshift, Snowflake, MySQL, PostgreSQL, etc ddl files to json/python dict with full information about columns: types, defaults, primary keys, etc.; sequences, alters, custom types & other entities from ddl."
55
authors = ["Iuliia Volkova <[email protected]>"]
66
license = "MIT"
@@ -22,6 +22,10 @@ classifiers = [
2222
"Topic :: Software Development :: Libraries :: Python Modules"
2323
]
2424

25+
[[tool.poetry.source]]
26+
name = "pypi-public"
27+
url = "https://pypi.org/simple/"
28+
2529
[tool.poetry.dependencies]
2630
python = "^3.6"
2731
dataclasses = { version = "0.8", python = ">=3.6,<3.7" }

simple_ddl_parser/ddl_parser.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,9 @@ def after_columns_tokens(self, t: LexToken) -> LexToken:
6262
return t
6363

6464
def process_body_tokens(self, t: LexToken) -> LexToken:
65-
if (
66-
self.lexer.last_par == "RP" and not self.lexer.lp_open
67-
) or self.lexer.after_columns:
65+
if (self.lexer.last_par == "RP" and not self.lexer.lp_open) or (
66+
self.lexer.after_columns and not self.lexer.columns_def
67+
):
6868
t = self.after_columns_tokens(t)
6969
elif self.lexer.columns_def:
7070
t.type = tok.columns_definition.get(t.value.upper(), t.type)
@@ -83,7 +83,6 @@ def tokens_not_columns_names(self, t: LexToken) -> LexToken:
8383
t_tag = self.parse_tags_symbols(t)
8484
if t_tag:
8585
return t_tag
86-
8786
if "ARRAY" in t.value:
8887
t.type = "ARRAY"
8988
return t
@@ -98,7 +97,8 @@ def tokens_not_columns_names(self, t: LexToken) -> LexToken:
9897
elif self.lexer.last_token != "COMMA":
9998
t.type = tok.common_statements.get(t.value.upper(), t.type)
10099
else:
101-
t.type = tok.first_liners.get(t.value.upper(), t.type)
100+
if not (self.lexer.columns_def and self.lexer.after_columns):
101+
t.type = tok.first_liners.get(t.value.upper(), t.type)
102102

103103
# get tokens from other token dicts
104104
t = self.process_body_tokens(t)
@@ -198,7 +198,6 @@ def t_ID(self, t: LexToken):
198198
self.commat_type(t)
199199

200200
self.set_lexx_tags(t)
201-
202201
return self.set_last_token(t)
203202

204203
def commat_type(self, t: LexToken):
@@ -209,14 +208,16 @@ def capitalize_tokens(self, t: LexToken):
209208
if t.type != "ID" and t.type not in ["LT", "RT"]:
210209
t.value = t.value.upper()
211210

212-
def set_parathesis_tokens(self, t: LexToken):
211+
def set_parenthesis_tokens(self, t: LexToken):
213212
if t.type in ["RP", "LP"]:
214213
if t.type == "RP" and self.lexer.lp_open:
215214
self.lexer.lp_open -= 1
215+
if not self.lexer.lp_open:
216+
self.lexer.after_columns = True
216217
self.lexer.last_par = t.type
217218

218219
def set_lexx_tags(self, t: LexToken):
219-
self.set_parathesis_tokens(t)
220+
self.set_parenthesis_tokens(t)
220221

221222
if t.type == "ALTER":
222223
self.lexer.is_alter = True

simple_ddl_parser/dialects/snowflake.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1+
import re
12
from typing import List
23

34
from simple_ddl_parser.utils import remove_par
4-
import re
55

66

77
class Snowflake:
@@ -11,12 +11,17 @@ def p_clone(self, p: List) -> None:
1111
p[0] = {"clone": {"from": p_list[-1]}}
1212

1313
def p_expression_cluster_by(self, p: List) -> None:
14-
"""expr : expr CLUSTER BY LP pid RP
15-
| expr CLUSTER BY pid
16-
"""
14+
"""expr : expr cluster_by"""
15+
p_list = list(p)
1716
p[0] = p[1]
17+
p[0].update(p_list[-1])
18+
19+
def p_cluster_by(self, p: List) -> None:
20+
"""cluster_by : CLUSTER BY LP pid RP
21+
| CLUSTER BY pid
22+
"""
1823
p_list = remove_par(list(p))
19-
p[0]["cluster_by"] = p_list[-1]
24+
p[0] = {"cluster_by": p_list[-1]}
2025

2126
def p_multi_id_or_string(self, p: List) -> None:
2227
"""multi_id_or_string : id_or_string

simple_ddl_parser/dialects/sql.py

Lines changed: 40 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -981,6 +981,26 @@ def p_index_table_name(self, p: List) -> None:
981981
table_name = p_list[-1]
982982
p[0].update({"schema": schema, "table_name": table_name})
983983

984+
def p_c_index(self, p: List) -> None:
985+
"""c_index : INDEX LP index_pid RP
986+
| INDEX id LP index_pid RP
987+
| c_index INVISIBLE
988+
| c_index VISIBLE"""
989+
p_list = remove_par(p_list=list(p))
990+
if isinstance(p_list[1], dict):
991+
p[0] = p_list[1]
992+
p[0]["details"] = {p_list[-1].lower(): True}
993+
else:
994+
if len(p_list) == 3:
995+
name = None
996+
else:
997+
name = p_list[2]
998+
p[0] = {
999+
"index_stmt": True,
1000+
"name": name,
1001+
"columns": p_list[-1]["detailed_columns"],
1002+
}
1003+
9841004
def p_create_index(self, p: List) -> None:
9851005
"""create_index : CREATE INDEX id
9861006
| CREATE UNIQUE INDEX id
@@ -1020,7 +1040,9 @@ def p_expression_table(self, p: List) -> None: # noqa R701
10201040
| table_name LP defcolumn
10211041
| table_name
10221042
| table_name LP RP
1043+
| table_name cluster_by LP defcolumn
10231044
| expr COMMA defcolumn
1045+
| expr COMMA c_index
10241046
| expr COMMA
10251047
| expr COMMA constraint
10261048
| expr COMMA check_ex
@@ -1041,30 +1063,33 @@ def p_expression_table(self, p: List) -> None: # noqa R701
10411063
"""
10421064
p[0] = p[1] or defaultdict(list)
10431065
p_list = remove_par(list(p))
1066+
if len(p_list) > 2 and "cluster_by" in p_list[2]:
1067+
p[0].update(p_list[2])
10441068
if p_list[-1] != "," and p_list[-1] is not None:
10451069
if "type" in p_list[-1] and "name" in p_list[-1]:
10461070
if not p[0].get("columns"):
10471071
p[0]["columns"] = []
10481072
p[0]["columns"].append(p_list[-1])
10491073
elif "index_stmt" in p_list[-1]:
1074+
del p_list[-1]["index_stmt"]
10501075
if not p[0].get("index"):
10511076
p[0]["index"] = []
10521077
index_data = p_list[-1]
1053-
p[0]["index"].append(
1054-
{
1055-
"clustered": False,
1056-
"columns": [index_data["columns"]],
1057-
"detailed_columns": [
1058-
{
1059-
"name": index_data["columns"],
1060-
"nulls": "LAST",
1061-
"order": "ASC",
1062-
}
1063-
],
1064-
"index_name": index_data["name"],
1065-
"unique": False,
1066-
}
1067-
)
1078+
_index = {
1079+
"clustered": False,
1080+
"columns": [index_data["columns"]],
1081+
"detailed_columns": [
1082+
{
1083+
"name": index_data["columns"],
1084+
"nulls": "LAST",
1085+
"order": "ASC",
1086+
}
1087+
],
1088+
"index_name": index_data["name"],
1089+
"unique": False,
1090+
}
1091+
_index.update(index_data.get("details", {}))
1092+
p[0]["index"].append(_index)
10681093
elif "check" in p_list[-1]:
10691094
p[0] = self.extract_check_data(p, p_list)
10701095
elif "enforced" in p_list[-1]:

simple_ddl_parser/parsetab.py

Lines changed: 52588 additions & 468 deletions
Large diffs are not rendered by default.

simple_ddl_parser/tokens.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@
6060
"WITH",
6161
"ORDER",
6262
"NOORDER",
63+
"VISIBLE",
64+
"INVISIBLE",
6365
}
6466
columns_definition = {value: value for value in columns_definition}
6567
columns_definition[","] = "COMMA"
@@ -70,9 +72,12 @@
7072
"CONSTRAINT",
7173
"FOREIGN",
7274
"PRIMARY",
75+
"INDEX",
7376
"UNIQUE",
7477
"CHECK",
7578
"WITH",
79+
"CLUSTER",
80+
"BY",
7681
}
7782
first_liners = {value: value for value in first_liners}
7883

tests/dialects/test_mssql_specific.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1876,7 +1876,7 @@ def test_constraint_primary_key():
18761876

18771877
ddl = """CREATE TABLE [dbo].[users_WorkSchedule](
18781878
[id] [int] IDENTITY(1,1) NOT NULL,
1879-
[user_id] [int] NULL),
1879+
[user_id] [int] NULL,
18801880
CONSTRAINT [PK_users_WorkSchedule_id] PRIMARY KEY CLUSTERED
18811881
(
18821882
[id] ASC
@@ -1885,7 +1885,7 @@ def test_constraint_primary_key():
18851885
CONSTRAINT [PK_users_WorkSchedule_id] PRIMARY KEY
18861886
(
18871887
[id] ASC
1888-
)
1888+
))
18891889
"""
18901890
result = DDLParser(ddl).run(group_by_type=True, output_mode="mssql")
18911891
assert result == expected

0 commit comments

Comments
 (0)