From e495e240c041d30d279ec9fe780d98f3713fa76b Mon Sep 17 00:00:00 2001 From: Jake Wheat Date: Sun, 2 Aug 2015 18:04:40 +0300 Subject: [PATCH] add default and identity to create table --- Language/SQL/SimpleSQL/Parser.lhs | 45 +++++ Language/SQL/SimpleSQL/Pretty.lhs | 31 +++- Language/SQL/SimpleSQL/Syntax.lhs | 31 +++- .../Language/SQL/SimpleSQL/SQL2011Schema.lhs | 169 +++++++++++++++++- 4 files changed, 260 insertions(+), 16 deletions(-) diff --git a/Language/SQL/SimpleSQL/Parser.lhs b/Language/SQL/SimpleSQL/Parser.lhs index bd84430..4eddec6 100644 --- a/Language/SQL/SimpleSQL/Parser.lhs +++ b/Language/SQL/SimpleSQL/Parser.lhs @@ -1468,6 +1468,51 @@ TODO: change style > <*> parens (commaSep1 columnDef) > where > columnDef = ColumnDef <$> name <*> typeName +> <*> optionMaybe defaultClause +> defaultClause = choice [ +> keyword_ "default" >> +> DefaultClause <$> valueExpr +> ,keyword_ "generated" >> +> IdentityColumnSpec +> <$> option GeneratedDefault +> (GeneratedAlways <$ keyword_ "always" +> <|> GeneratedByDefault <$ keywords_ ["by", "default"]) +> <*> (keywords_ ["as", "identity"] *> +> option [] (parens sequenceGeneratorOptions)) +> ] +> sequenceGeneratorOptions = +> -- todo: could try to combine exclusive options +> -- such as cycle and nocycle +> permute ((\a b c d e f g h -> catMaybes [a,b,c,d,e,f,g,h]) +> <$?> (Nothing, Just <$> startWith) +> <|?> (Nothing, Just <$> incrementBy) +> <|?> (Nothing, Just <$> maxValue) +> <|?> (Nothing, Just <$> noMaxValue) +> <|?> (Nothing, Just <$> minValue) +> <|?> (Nothing, Just <$> noMinValue) +> <|?> (Nothing, Just <$> scycle) +> <|?> (Nothing, Just <$> noCycle) +> ) +> startWith = keywords_ ["start", "with"] >> +> SGOStartWith <$> signedInteger +> incrementBy = keywords_ ["increment", "by"] >> +> SGOIncrementBy <$> signedInteger +> maxValue = keyword_ "maxvalue" >> +> SGOMaxValue <$> signedInteger +> noMaxValue = SGONoMaxValue <$ try (keywords_ ["no","maxvalue"]) +> minValue = keyword_ "minvalue" >> +> SGOMinValue <$> signedInteger +> noMinValue = SGONoMinValue <$ try (keywords_ ["no","minvalue"]) +> scycle = SGOCycle <$ keyword_ "cycle" +> noCycle = SGONoCycle <$ try (keywords_ ["no","cycle"]) + +slightly hacky parser for signed integers + +> signedInteger :: Parser Integer +> signedInteger = do +> s <- option 1 (1 <$ symbol "+" <|> (-1) <$ symbol "-") +> d <- unsignedInteger +> return $ s * d > dropSchema :: Parser Statement > dropSchema = keyword_ "schema" >> diff --git a/Language/SQL/SimpleSQL/Pretty.lhs b/Language/SQL/SimpleSQL/Pretty.lhs index 689a27d..6fdb1fd 100644 --- a/Language/SQL/SimpleSQL/Pretty.lhs +++ b/Language/SQL/SimpleSQL/Pretty.lhs @@ -453,12 +453,34 @@ which have been changed to try to improve the layout of the output. > statement _ (CreateSchema nm) = > text "create" <+> text "schema" <+> names nm -> statement _ (CreateTable nm cds) = +> statement d (CreateTable nm cds) = > text "create" <+> text "table" <+> names nm > <+> parens (commaSep $ map cd cds) > where -> cd (ColumnDef n t) = name n <+> typeName t - +> cd (ColumnDef n t mdef) = +> name n <+> typeName t +> <+> case mdef of +> Nothing -> empty +> Just (DefaultClause def) -> +> text "default" <+> valueExpr d def +> Just (IdentityColumnSpec w o) -> +> text "generated" +> <+> (case w of +> GeneratedDefault -> empty +> GeneratedAlways -> text "always" +> GeneratedByDefault -> text "by" <+> text "default") +> <+> text "as" <+> text "identity" +> <+> (case o of +> [] -> empty +> os -> parens (sep $ map sgo os)) +> sgo (SGOStartWith i) = texts ["start", "with", show i] +> sgo (SGOIncrementBy i) = texts ["increment", "by", show i] +> sgo (SGOMaxValue i) = texts ["maxvalue", show i] +> sgo SGONoMaxValue = texts ["no", "maxvalue"] +> sgo (SGOMinValue i) = texts ["minvalue", show i] +> sgo SGONoMinValue = texts ["no", "minvalue"] +> sgo SGOCycle = text "cycle" +> sgo SGONoCycle = text "no cycle" > statement _ (DropSchema nm db) = > text "drop" <+> text "schema" <+> names nm <+> dropBehav db @@ -521,3 +543,6 @@ which have been changed to try to improve the layout of the output. > comment :: Comment -> Doc > comment (BlockComment str) = text "/*" <+> text str <+> text "*/" + +> texts :: [String] -> Doc +> texts ts = sep $ map text ts diff --git a/Language/SQL/SimpleSQL/Syntax.lhs b/Language/SQL/SimpleSQL/Syntax.lhs index 1b1df45..73b518c 100644 --- a/Language/SQL/SimpleSQL/Syntax.lhs +++ b/Language/SQL/SimpleSQL/Syntax.lhs @@ -36,7 +36,10 @@ > ,IdentityRestart(..) > ,InsertSource(..) > ,SetClause(..) -> ,TableElement(..) +> ,TableElement(..) +> ,DefaultClause(..) +> ,IdentityWhen(..) +> ,SequenceGeneratorOption(..) > -- * Dialect > ,Dialect(..) > -- * Comment @@ -489,7 +492,7 @@ I'm not sure if this is valid syntax or not. > data TableElement = > ColumnDef Name TypeName -> -- (Maybe DefaultClause) +> (Maybe DefaultClause) > -- (Maybe ColumnConstraintDef) > -- (Maybe CollateClause) > -- | TableConstraintDef @@ -498,10 +501,28 @@ I'm not sure if this is valid syntax or not. > {-data TableConstraintDef > deriving (Eq,Show,Read,Data,Typeable) -} -> {-data DefaultClause = +> data DefaultClause = > DefaultClause ValueExpr -> | IdentityColumnSpec -> | GenerationClause-} +> | IdentityColumnSpec IdentityWhen [SequenceGeneratorOption] +> -- | GenerationClause +> deriving (Eq,Show,Read,Data,Typeable) + +> data IdentityWhen = +> GeneratedDefault +> | GeneratedAlways +> | GeneratedByDefault +> deriving (Eq,Show,Read,Data,Typeable) + +> data SequenceGeneratorOption = +> SGOStartWith Integer +> | SGOIncrementBy Integer +> | SGOMaxValue Integer +> | SGONoMaxValue +> | SGOMinValue Integer +> | SGONoMinValue +> | SGOCycle +> | SGONoCycle +> deriving (Eq,Show,Read,Data,Typeable) > {-data ColumnConstraintDef = > | NotNullConstraint diff --git a/tools/Language/SQL/SimpleSQL/SQL2011Schema.lhs b/tools/Language/SQL/SimpleSQL/SQL2011Schema.lhs index aba17dd..eddd330 100644 --- a/tools/Language/SQL/SimpleSQL/SQL2011Schema.lhs +++ b/tools/Language/SQL/SimpleSQL/SQL2011Schema.lhs @@ -92,8 +92,8 @@ schema name can be quoted iden or unicode quoted iden > ,(TestStatement SQL2011 "create table t (a int, b int);" > $ CreateTable [Name "t"] -> [ColumnDef (Name "a") (TypeName [Name "int"]) -> ,ColumnDef (Name "b") (TypeName [Name "int"])]) +> [ColumnDef (Name "a") (TypeName [Name "int"]) Nothing +> ,ColumnDef (Name "b") (TypeName [Name "int"]) Nothing]) ::= @@ -111,10 +111,14 @@ schema name can be quoted iden or unicode quoted iden ::= SYSTEM VERSIONING +defintely skip +
::= PRESERVE | DELETE +defintely skip +
::=
[ {
}... ] @@ -128,41 +132,63 @@ schema name can be quoted iden or unicode quoted iden OF [ ] [ ] +defintely skip + ::= [ { }... ] +defintely skip + ::= |
| +defintely skip + ::= REF IS [ ] +defintely skip + ::= SYSTEM GENERATED | USER GENERATED | DERIVED +defintely skip + ::= +defintely skip + ::= WITH OPTIONS +defintely skip + ::= [ ] [ ] [ ... ] +defintely skip + ::= UNDER +defintely skip + ::= +defintely skip + ::=
+defintely skip + ::= LIKE
[ ] @@ -198,25 +224,39 @@ schema name can be quoted iden or unicode quoted iden +defintely skip + ::= | +defintely skip + ::= PERIOD FOR SYSTEM_TIME +defintely skip + ::= PERIOD FOR +defintely skip + ::= +defintely skip + ::= +defintely skip + ::= +defintely skip + 11.4 @@ -235,12 +275,18 @@ schema name can be quoted iden or unicode quoted iden ::= AS ROW START +defintely skip + ::= AS ROW END +defintely skip + ::= GENERATED ALWAYS +defintely skip + ::= [ ] [ ] @@ -254,13 +300,50 @@ schema name can be quoted iden or unicode quoted iden GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ] -generated always as identity -generated by default as identity +> ,(TestStatement SQL2011 "create table t (a int generated as identity);" +> $ CreateTable [Name "t"] +> [ColumnDef (Name "a") (TypeName [Name "int"]) +> (Just $ IdentityColumnSpec GeneratedDefault [])]) -generated always as identity (start with signed_numeric - increment by n - maxvalue n | no maxvalue - minvalue n | no minvalue) +> ,(TestStatement SQL2011 "create table t (a int generated always as identity);" +> $ CreateTable [Name "t"] +> [ColumnDef (Name "a") (TypeName [Name "int"]) +> (Just $ IdentityColumnSpec GeneratedAlways [])]) + +> ,(TestStatement SQL2011 "create table t (a int generated by default as identity);" +> $ CreateTable [Name "t"] +> [ColumnDef (Name "a") (TypeName [Name "int"]) +> (Just $ IdentityColumnSpec GeneratedByDefault [])]) + + +> ,(TestStatement SQL2011 +> "create table t (a int generated as identity\ +> \ ( start with 5 increment by 5 maxvalue 500 minvalue 5 cycle ));" +> $ CreateTable [Name "t"] +> [ColumnDef (Name "a") (TypeName [Name "int"]) +> (Just $ IdentityColumnSpec GeneratedDefault +> [SGOStartWith 5 +> ,SGOIncrementBy 5 +> ,SGOMaxValue 500 +> ,SGOMinValue 5 +> ,SGOCycle])]) + +> ,(TestStatement SQL2011 +> "create table t (a int generated as identity\ +> \ ( start with -4 no maxvalue no minvalue no cycle ));" +> $ CreateTable [Name "t"] +> [ColumnDef (Name "a") (TypeName [Name "int"]) +> (Just $ IdentityColumnSpec GeneratedDefault +> [SGOStartWith (-4) +> ,SGONoMaxValue +> ,SGONoMinValue +> ,SGONoCycle])]) + +I think is supposed to just +whitespace separated. In db2 it seems to be csv, but the grammar here +just seems to be whitespace separated, and it is just whitespace +separated in oracle... Not completely sure though. Usually db2 is +closer than oracle? generated always (valueexpr) @@ -293,6 +376,12 @@ generated always (valueexpr) | +> ,(TestStatement SQL2011 "create table t (a int default 0);" +> $ CreateTable [Name "t"] +> [ColumnDef (Name "a") (TypeName [Name "int"]) +> (Just $ DefaultClause $ NumLit "0")]) + + 11.6
@@ -322,6 +411,9 @@ generated always (valueexpr) ::= WITHOUT OVERLAPS +defintely skip + + 11.8 ::= @@ -344,6 +436,8 @@ generated always (valueexpr) ::= PERIOD +defintely skip + ::=
[ [ ] ] @@ -354,6 +448,8 @@ generated always (valueexpr) ::= PERIOD +defintely skip + ::= [ ] | [ ] @@ -397,6 +493,10 @@ generated always (valueexpr) ::= ADD [ COLUMN ] +alter table t add column a int +alter table t add a int +alter table t add a int unique not null check (a>0) + 11.12 ::= @@ -420,22 +520,30 @@ generated always (valueexpr) ::= SET +alter table t alter column c set default ... +alter table t alter c set default ... + 11.14 ::= DROP DEFAULT +alter table t alter column c drop default 11.15 ::= SET NOT NULL +alter table t alter column c set not null + 11.16 ::= DROP NOT NULL +alter table t alter column c drop not null + 11.17 ::= @@ -451,6 +559,8 @@ generated always (valueexpr) ::= SET DATA TYPE +alter table t alter column c set data type int; + 11.20 ::= @@ -460,73 +570,116 @@ generated always (valueexpr) ::= SET GENERATED { ALWAYS | BY DEFAULT } +alter table t alter column c set generated always + +alter table t alter column c set generated by default + ::= | SET +alter table t alter column c restart +alter table t alter column c restart with 4 (snl) + +alter table t alter column c set increment by minvalue maxvalue cycle + + 11.21 ::= DROP IDENTITY +alter table t alter column c drop identity + 11.22 ::= DROP EXPRESSION +alter table t alter column c drop expression + 11.23 ::= DROP [ COLUMN ] +alter table t alter drop column c + +alter table t alter drop c restrict +alter table t alter drop c cascade + 11.24 ::= ADD
+todo + 11.25 ::= ALTER CONSTRAINT +todo + 11.26 ::= DROP CONSTRAINT +todo + 11.27 ::= ADD
[ ] +defintely skip + ::= ADD [ COLUMN ] ADD [ COLUMN ] +defintely skip + ::= +defintely skip + ::= +defintely skip + 11.28 ::= DROP +defintely skip + 11.29 ::= ADD +defintely skip + 11.30 ::= DROP SYSTEM VERSIONING +defintely skip + 11.31 ::= DROP TABLE
+drop table t +drop table t cascade +drop table t restrict + 11.32 ::=