Skip to content

Commit

Permalink
fix parse 'FOREIGN KEY', block comments
Browse files Browse the repository at this point in the history
  • Loading branch information
Shinichi Takii committed Feb 17, 2019
1 parent 349788c commit 998e327
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 33 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
@@ -1,5 +1,9 @@
# Changelog

## 1.2.3
- Fix parse error for MySQL DDL with 'FOREIGN KEY'.
- Fix not completely parsed with block comments.

## 1.2.2
- Fix FutureWarning of Python 3.7.
- Add supports PostgreSQL data type.
Expand Down
20 changes: 10 additions & 10 deletions README.md
@@ -1,7 +1,7 @@
# DDL Parse

[![PyPI version](https://img.shields.io/pypi/v/ddlparse.svg)](https://pypi.python.org/pypi/ddlparse)
[![Python version](https://img.shields.io/pypi/pyversions/ddlparse.svg)](https://pypi.python.org/pypi/ddlparse)
[![PyPI version](https://img.shields.io/pypi/v/ddlparse.svg)](https://pypi.org/project/ddlparse/)
[![Python version](https://img.shields.io/pypi/pyversions/ddlparse.svg)](https://pypi.org/project/ddlparse/)
[![Travis CI Build Status](https://travis-ci.org/shinichi-takii/ddlparse.svg?branch=master)](https://travis-ci.org/shinichi-takii/ddlparse)
[![Coveralls Coverage Status](https://coveralls.io/repos/github/shinichi-takii/ddlparse/badge.svg?branch=master)](https://coveralls.io/github/shinichi-takii/ddlparse?branch=master)
[![codecov Coverage Status](https://codecov.io/gh/shinichi-takii/ddlparse/branch/master/graph/badge.svg)](https://codecov.io/gh/shinichi-takii/ddlparse)
Expand All @@ -22,7 +22,7 @@
## Requirement

1. Python >= 3.4
1. [pyparsing](http://pyparsing.wikispaces.com/)
1. [pyparsing](https://github.com/pyparsing/pyparsing)

## Installation

Expand Down Expand Up @@ -118,11 +118,11 @@ for col in table.columns.values():
col_info.append("precision(=length) = {}".format(col.precision))
col_info.append("scale = {}".format(col.scale))
col_info.append("constraint = {}".format(col.constraint))
col_info.append("not_null = {}".format(col.not_null))
col_info.append("PK = {}".format(col.primary_key))
col_info.append("unique = {}".format(col.unique))
col_info.append("bq_legacy_data_type = {}".format(col.bigquery_legacy_data_type))
col_info.append("bq_standard_data_type = {}".format(col.bigquery_standard_data_type))
col_info.append("not_null = {}".format(col.not_null))
col_info.append("PK = {}".format(col.primary_key))
col_info.append("unique = {}".format(col.unique))
col_info.append("bq_legacy_data_type = {}".format(col.bigquery_legacy_data_type))
col_info.append("bq_standard_data_type = {}".format(col.bigquery_standard_data_type))
col_info.append("BQ {}".format(col.to_bigquery_field()))
print(" : ".join(col_info))

Expand All @@ -148,8 +148,8 @@ Shinichi Takii <shinichi.takii@gmail.com>
## Links

- Repository : https://github.com/shinichi-takii/ddlparse
- PyPI Package : https://pypi.python.org/pypi/ddlparse
- PyPI Package : https://pypi.org/project/ddlparse/

## Special Thanks

- pyparsing : http://pyparsing.wikispaces.com/
- pyparsing : https://github.com/pyparsing/pyparsing
20 changes: 10 additions & 10 deletions README.rst
Expand Up @@ -2,11 +2,11 @@ DDL Parse
=========

.. image:: https://img.shields.io/pypi/v/ddlparse.svg
:target: https://pypi.python.org/pypi/ddlparse
:target: https://pypi.org/project/ddlparse/
:alt: PyPI version

.. image:: https://img.shields.io/pypi/pyversions/ddlparse.svg
:target: https://pypi.python.org/pypi/ddlparse
:target: https://pypi.org/project/ddlparse/
:alt: Python version

.. image:: https://travis-ci.org/shinichi-takii/ddlparse.svg?branch=master
Expand Down Expand Up @@ -49,7 +49,7 @@ Requirement
-----------

1. Python >= 3.4
2. `pyparsing <http://pyparsing.wikispaces.com/>`__
2. `pyparsing <https://github.com/pyparsing/pyparsing>`__

Installation
------------
Expand Down Expand Up @@ -154,11 +154,11 @@ Example
col_info.append("precision(=length) = {}".format(col.precision))
col_info.append("scale = {}".format(col.scale))
col_info.append("constraint = {}".format(col.constraint))
col_info.append("not_null = {}".format(col.not_null))
col_info.append("PK = {}".format(col.primary_key))
col_info.append("unique = {}".format(col.unique))
col_info.append("bq_legacy_data_type = {}".format(col.bigquery_legacy_data_type))
col_info.append("bq_standard_data_type = {}".format(col.bigquery_standard_data_type))
col_info.append("not_null = {}".format(col.not_null))
col_info.append("PK = {}".format(col.primary_key))
col_info.append("unique = {}".format(col.unique))
col_info.append("bq_legacy_data_type = {}".format(col.bigquery_legacy_data_type))
col_info.append("bq_standard_data_type = {}".format(col.bigquery_standard_data_type))
col_info.append("BQ {}".format(col.to_bigquery_field()))
print(" : ".join(col_info))
Expand Down Expand Up @@ -187,9 +187,9 @@ Links
-----

- Repository : https://github.com/shinichi-takii/ddlparse
- PyPI Package : https://pypi.python.org/pypi/ddlparse
- PyPI Package : https://pypi.org/project/ddlparse/

Special Thanks
--------------

- pyparsing : http://pyparsing.wikispaces.com/
- pyparsing : https://github.com/pyparsing/pyparsing
30 changes: 23 additions & 7 deletions ddlparse/ddlparse.py
Expand Up @@ -454,8 +454,8 @@ class DdlParse(DdlParseBase):
"""DDL parser"""

_LPAR, _RPAR, _COMMA, _SEMICOLON, _DOT, _DOUBLEQUOTE, _BACKQUOTE, _SPACE = map(Suppress, "(),;.\"` ")
_CREATE, _TABLE, _TEMP, _CONSTRAINT, _NOT_NULL, _PRIMARY_KEY, _UNIQUE, _UNIQUE_KEY, _KEY, _CHAR_SEMANTICS, _BYTE_SEMANTICS = \
map(CaselessKeyword, "CREATE, TABLE, TEMP, CONSTRAINT, NOT NULL, PRIMARY KEY, UNIQUE, UNIQUE KEY, KEY, CHAR, BYTE".replace(", ", ",").split(","))
_CREATE, _TABLE, _TEMP, _CONSTRAINT, _NOT_NULL, _PRIMARY_KEY, _UNIQUE, _UNIQUE_KEY, _FOREIGN_KEY, _REFERENCES, _KEY, _CHAR_SEMANTICS, _BYTE_SEMANTICS = \
map(CaselessKeyword, "CREATE, TABLE, TEMP, CONSTRAINT, NOT NULL, PRIMARY KEY, UNIQUE, UNIQUE KEY, FOREIGN KEY, REFERENCES, KEY, CHAR, BYTE".replace(", ", ",").split(","))
_SUPPRESS_QUOTE = _BACKQUOTE | _DOUBLEQUOTE

_COMMENT = Suppress("--" + Regex(r".+"))
Expand All @@ -465,19 +465,33 @@ class DdlParse(DdlParseBase):
+ _LPAR \
+ delimitedList(
OneOrMore(
_COMMENT
|
# Ignore Index
Suppress(_KEY + Word(alphanums+"_'`() "))
|
Group(
Optional(Suppress(_CONSTRAINT) + Optional(_SUPPRESS_QUOTE) + Word(alphanums+"_")("name") + Optional(_SUPPRESS_QUOTE))
+ (_PRIMARY_KEY ^ _UNIQUE ^ _UNIQUE_KEY ^ _NOT_NULL)("type")
+ Optional(_SUPPRESS_QUOTE) + Optional(Word(alphanums+"_"))("name") + Optional(_SUPPRESS_QUOTE)
+ _LPAR + Group(delimitedList(Optional(_SUPPRESS_QUOTE) + Word(alphanums+"_") + Optional(_SUPPRESS_QUOTE)))("constraint_columns") + _RPAR
+ (
(
(_PRIMARY_KEY ^ _UNIQUE ^ _UNIQUE_KEY ^ _NOT_NULL)("type")
+ Optional(_SUPPRESS_QUOTE) + Optional(Word(alphanums+"_"))("name") + Optional(_SUPPRESS_QUOTE)
+ _LPAR + Group(delimitedList(Optional(_SUPPRESS_QUOTE) + Word(alphanums+"_") + Optional(_SUPPRESS_QUOTE)))("constraint_columns") + _RPAR
)
|
(
(_FOREIGN_KEY)("type")
+ _LPAR + Group(delimitedList(Optional(_SUPPRESS_QUOTE) + Word(alphanums+"_") + Optional(_SUPPRESS_QUOTE)))("constraint_columns") + _RPAR
+ Optional(Suppress(_REFERENCES)
+ Optional(_SUPPRESS_QUOTE) + Word(alphanums+"_")("references_table") + Optional(_SUPPRESS_QUOTE)
+ _LPAR + Group(delimitedList(Optional(_SUPPRESS_QUOTE) + Word(alphanums+"_") + Optional(_SUPPRESS_QUOTE)))("references_columns") + _RPAR
)
)
)
)("constraint")
|
Group(
Optional(_COMMENT)
+ Optional(_SUPPRESS_QUOTE) + Word(alphanums+"_")("name") + Optional(_SUPPRESS_QUOTE)
Optional(_SUPPRESS_QUOTE) + Word(alphanums+"_")("name") + Optional(_SUPPRESS_QUOTE)
+ Group(
Word(alphanums+"_")
+ Optional(CaselessKeyword("WITHOUT TIME ZONE") ^ CaselessKeyword("WITH TIME ZONE") ^ CaselessKeyword("PRECISION") ^ CaselessKeyword("VARYING"))
Expand All @@ -486,6 +500,8 @@ class DdlParse(DdlParseBase):
+ Optional(Word(r"\[\]"))("array_brackets")
+ Optional(Regex(r"DEFAULT\s+[^,]+", re.IGNORECASE) | Word(alphanums+"_': -"))("constraint")
)("column")
|
_COMMENT
)
)("columns")

Expand Down
10 changes: 5 additions & 5 deletions example/example.py
Expand Up @@ -73,11 +73,11 @@
col_info.append("precision(=length) = {}".format(col.precision))
col_info.append("scale = {}".format(col.scale))
col_info.append("constraint = {}".format(col.constraint))
col_info.append("not_null = {}".format(col.not_null))
col_info.append("PK = {}".format(col.primary_key))
col_info.append("unique = {}".format(col.unique))
col_info.append("bq_legacy_data_type = {}".format(col.bigquery_legacy_data_type))
col_info.append("bq_standard_data_type = {}".format(col.bigquery_standard_data_type))
col_info.append("not_null = {}".format(col.not_null))
col_info.append("PK = {}".format(col.primary_key))
col_info.append("unique = {}".format(col.unique))
col_info.append("bq_legacy_data_type = {}".format(col.bigquery_legacy_data_type))
col_info.append("bq_standard_data_type = {}".format(col.bigquery_standard_data_type))
col_info.append("BQ {}".format(col.to_bigquery_field()))
print(" : ".join(col_info))

Expand Down
6 changes: 5 additions & 1 deletion test/test_ddlparse.py
Expand Up @@ -13,6 +13,8 @@
"""
CREATE TABLE Sample_Table (
Col_01 varchar(100) PRIMARY KEY,
-- comment
-- comment
Col_02 char(200) NOT NULL UNIQUE,
Col_03 text UNIQUE,
Col_04 integer,
Expand Down Expand Up @@ -151,7 +153,8 @@
Col_04 double,
Col_05 datetime,
CONSTRAINT const_01 PRIMARY KEY (Col_01, Col_02),
CONSTRAINT \"const_02\" UNIQUE (Col_03, Col_04)
CONSTRAINT \"const_02\" UNIQUE (Col_03, Col_04),
CONSTRAINT \"const_03\" FOREIGN KEY (Col_04, \"Col_05\") REFERENCES ref_table_01 (\"Col_04\", Col_05)
);
""",
"database" : DdlParse.DATABASE.mysql,
Expand Down Expand Up @@ -193,6 +196,7 @@
PRIMARY KEY (Col_01, Col_02),
UNIQUE (Col_03, Col_04),
NOT NULL (Col_04, Col_05)
FOREIGN KEY (Col_04, Col_05) REFERENCES ref_table_01 (Col_04, Col_05)
);
""",
"database" : None,
Expand Down

0 comments on commit 998e327

Please sign in to comment.