Skip to content

Commit 6489f44

Browse files
committed
Gracefully ignore parition
1 parent e4a1569 commit 6489f44

File tree

8 files changed

+84
-38
lines changed

8 files changed

+84
-38
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,8 @@ stack run -- test.sql -o erd.svg
7878
- [ ] Adding support for interval data type
7979
- [x] GENERATED constraint
8080
- [ ] Parse 2D array
81-
- [ ] Gracefully ignore partition.
81+
- [x] Gracefully ignore partition.
82+
- [ ] bigserial
8283

8384
See the [open issues](https://github.com/tusharad/sql2er/issues) for a full list of proposed features (and known issues).
8485

example/erd.svg

Lines changed: 1 addition & 1 deletion
Loading

example/test.sql

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,10 @@
11
BEGIN;
22

3-
CREATE TABLE orders (
4-
order_id bigint not null,
5-
cust_id bigint not null,
6-
status text
7-
);
8-
93
CREATE TABLE cities (
10-
city_id bigserial not null,
4+
city_id int not null,
115
name text not null,
126
population bigint
13-
) PARTITION BY LIST (left(lower(name), 1));
7+
) partition by (logdate);
148

159
CREATE TABLE emails (
1610
email_record_id SERIAL PRIMARY KEY,

src/Sql2er/Common/Types.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ data SqlType
4040
| PGint
4141
| PGtimestamp
4242
| PGtimestamptz
43+
| PGBigSerial
4344
| SomeType
4445
deriving (Show, Eq)
4546

src/Sql2er/Parser/Common.hs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,5 +195,7 @@ parseSqlType =
195195
*> lexeme (string "time")
196196
*> lexeme (string "zone")
197197
)
198+
, PGbigInt <$ string "bigint"
199+
, PGBigSerial <$ string "bigserial"
198200
, SomeType <$ lexeme (takeWhile1P Nothing (/= ' '))
199201
]

src/Sql2er/Parser/CreateTable.hs

Lines changed: 39 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -13,24 +13,34 @@ parseColumn :: Parser Column
1313
parseColumn = do
1414
cName <- parseWordAndComma
1515
sqlType <- lexeme parseSqlType
16-
c <- many $ choice $ try <$> [
17-
parsePrimaryKeyForCol
16+
c <-
17+
many $
18+
choice $
19+
try
20+
<$> [ parsePrimaryKeyForCol
21+
, parseNotNullForCol
22+
, parseUniqueForCol
23+
, parseDefaultVForCol
24+
, parseReferenceForCol
25+
, parseNullForCol
26+
, parseCheckForCol
27+
]
28+
t <-
29+
many
30+
( lexeme (string "constraint")
31+
*> parseWordAndComma
32+
*> choice
33+
( try
34+
<$> [ parsePrimaryKeyForCol
1835
, parseNotNullForCol
1936
, parseUniqueForCol
2037
, parseDefaultVForCol
2138
, parseReferenceForCol
22-
, parseNullForCol
39+
, parseNullForCol
2340
, parseCheckForCol
2441
]
25-
t <- many (lexeme (string "constraint") *> parseWordAndComma *> choice (try <$> [
26-
parsePrimaryKeyForCol
27-
, parseNotNullForCol
28-
, parseUniqueForCol
29-
, parseDefaultVForCol
30-
, parseReferenceForCol
31-
, parseNullForCol
32-
, parseCheckForCol
33-
]))
42+
)
43+
)
3444
void $ optional ignoreConstraints
3545
return
3646
Column
@@ -57,27 +67,26 @@ skipOptionalParts =
5767

5868
skipLikeClause :: Parser ()
5969
skipLikeClause = do
60-
_ <- string "like"
61-
_ <- parseWord
62-
_ <- optional (between (char '(') (char ')') (skipManyTill anySingle (lookAhead (char ')'))))
70+
_ <- lexeme $ string "like"
71+
_ <- takeWhile1P Nothing (/= ';')
6372
return ()
6473

6574
skipPartitioning :: Parser ()
6675
skipPartitioning = do
6776
_ <- lexeme (string "partition") *> lexeme (string "by")
68-
_ <- takeWhileP Nothing (/= ')')
77+
_ <- takeWhile1P Nothing (/= ';')
6978
return ()
7079

7180
skipInheritsClause :: Parser ()
7281
skipInheritsClause = do
73-
_ <- string "inherits"
74-
_ <- between (char '(') (char ')') (parseWord `sepBy1` lexeme (char ','))
82+
_ <- lexeme $ string "inherits"
83+
_ <- takeWhile1P Nothing (/= ';')
7584
return ()
7685

7786
skipUsingMethod :: Parser ()
7887
skipUsingMethod = do
79-
_ <- string "using"
80-
_ <- parseWord
88+
_ <- lexeme $ string "using"
89+
_ <- takeWhile1P Nothing (/= ';')
8190
return ()
8291

8392
skipWithOrWithoutOids :: Parser ()
@@ -96,12 +105,14 @@ skipOnCommit = do
96105

97106
skipTablespace :: Parser ()
98107
skipTablespace = do
99-
_ <- string "tablespace"
100-
_ <- parseWord
108+
_ <- lexeme $ string "tablespace"
109+
_ <- takeWhile1P Nothing (/= ';')
101110
return ()
102111

103112
parseColumnOrConstraint :: Parser (Either Column TableConstraint)
104-
parseColumnOrConstraint = (Right <$> lexeme parseTableConstraint) <|> (Left <$> lexeme parseColumn)
113+
parseColumnOrConstraint =
114+
(Right <$> lexeme parseTableConstraint)
115+
<|> (Left <$> lexeme parseColumn)
105116

106117
parseCreateTable :: Parser Table
107118
parseCreateTable = do
@@ -113,8 +124,11 @@ parseCreateTable = do
113124
_ <- optional $ lexeme (string "if") *> lexeme (string "not") *> lexeme (string "exists")
114125
tName <- lexeme (takeWhile1P Nothing (`notElem` (" \t\n)(" :: String)))
115126
items <-
116-
between (lexeme (char '(')) (lexeme (char ')')) (parseColumnOrConstraint `sepBy` lexeme (char ','))
117-
_ <- optional skipOptionalParts
127+
between
128+
(lexeme (char '('))
129+
(lexeme (char ')'))
130+
(parseColumnOrConstraint `sepBy` lexeme (char ','))
131+
_ <- optional $ lexeme skipOptionalParts
118132
let cols = [c | Left c <- items]
119133
let constraints = [con | Right con <- items]
120134
return Table {tableName = tName, columns = cols, tableConstraints = constraints}

test/ExamplesForTests.hs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,22 @@ module ExamplesForTests where
55
import Data.Text (Text)
66
import Sql2er.Common.Types
77

8+
partitionConstraint :: Table
9+
partitionConstraint =
10+
Table
11+
{ tableName = "cities"
12+
, columns =
13+
[ Column
14+
{ columnName = "city_id"
15+
, columnType = PGinteger
16+
, cConstraints = [NotNull]
17+
}
18+
, Column {columnName = "name", columnType = PGtext, cConstraints = [NotNull]}
19+
, Column {columnName = "population", columnType = PGbigInt, cConstraints = []}
20+
]
21+
, tableConstraints = []
22+
}
23+
824
tableConstraint :: Table
925
tableConstraint =
1026
Table
@@ -22,7 +38,7 @@ tableConstraint =
2238
, PrimaryKeyConstraint "y"
2339
, ForeignKeyConstraint "z" "sometable" (Just "z")
2440
, CheckConstraint "z > 23"
25-
, UniqueConstraint ["y","z"]
41+
, UniqueConstraint ["y", "z"]
2642
]
2743
}
2844

test/Spec.hs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ testParse inputText parsingFunc expectedOp failureMsg = do
2121
parsingFunc
2222
""
2323
inputText
24-
print eRes
2524
case eRes of
2625
Left _ -> assertFailure failureMsg
2726
Right r -> expectedOp @=? r
@@ -120,19 +119,38 @@ testTableConstraint =
120119
"Parsing failed for table constraints"
121120
]
122121

122+
testPartitionConstraint :: TestTree
123+
testPartitionConstraint =
124+
testGroup "partition constraint" [
125+
testCase "paition with multiple parenthesis" $
126+
testParse
127+
(T.toLower
128+
"CREATE TABLE cities (\
129+
\city_id int not null,\
130+
\name text not null,\
131+
\population bigint\
132+
\) PARTITION BY LIST (left(lower(name), 1))"
133+
)
134+
parseCreateTable
135+
Ex.partitionConstraint
136+
"Parsing failed for table with partition"
137+
]
138+
123139
createStatementTests :: TestTree
124140
createStatementTests =
125141
testGroup
126142
"Create statement tests"
127143
[ testCreateOrReplaceTable
128144
, testColumnConstraint
129145
, testTableConstraint
146+
, testPartitionConstraint
130147
]
131148

132149
testSqlScripts :: Text -> TestTree
133150
testSqlScripts t = do
134151
let eRes = runParser parseSqlScript "" t
135-
testCase "parsing script" (assertBool "" (isRight eRes))
152+
testCase "parsing script" $ do
153+
assertBool "" (isRight eRes)
136154

137155
main :: IO ()
138156
main = do

0 commit comments

Comments
 (0)