diff --git a/Language/SQL/SimpleSQL/Parser.lhs b/Language/SQL/SimpleSQL/Parser.lhs index 46d2234..b321856 100644 --- a/Language/SQL/SimpleSQL/Parser.lhs +++ b/Language/SQL/SimpleSQL/Parser.lhs @@ -1461,7 +1461,7 @@ TODO: change style > CreateTable > <$> names > -- todo: is this order mandatory or is it a perm? -> <*> parens (commaSep1 (tableConstraintDef +> <*> parens (commaSep1 (uncurry TableConstraintDef <$> tableConstraintDef > <|> TableColumnDef <$> columnDef)) > columnDef :: Parser ColumnDef @@ -1477,8 +1477,7 @@ TODO: change style > GenerationClause <$> parens valueExpr) > ,keyword_ "generated" >> > IdentityColumnSpec -> <$> option GeneratedDefault -> (GeneratedAlways <$ keyword_ "always" +> <$> (GeneratedAlways <$ keyword_ "always" > <|> GeneratedByDefault <$ keywords_ ["by", "default"]) > <*> (keywords_ ["as", "identity"] *> > option [] (parens sequenceGeneratorOptions)) @@ -1509,9 +1508,9 @@ TODO: change style > scycle = SGOCycle <$ keyword_ "cycle" > noCycle = SGONoCycle <$ try (keywords_ ["no","cycle"]) -> tableConstraintDef :: Parser TableElement +> tableConstraintDef :: Parser (Maybe [Name], TableConstraint) > tableConstraintDef = -> TableConstraintDef +> (,) > <$> (optionMaybe (keyword_ "constraint" *> names)) > <*> (unique <|> primaryKey <|> check <|> references) > where @@ -1575,11 +1574,40 @@ slightly hacky parser for signed integers > alterTable :: Parser Statement > alterTable = keyword_ "table" >> -> AlterTable <$> names <*> choice [addColumnDef] +> -- the choices have been ordered so that it works +> AlterTable <$> names <*> choice [addConstraint +> ,dropConstraint +> ,addColumnDef +> ,alterColumn +> ,dropColumn +> ] > where > addColumnDef = try (keyword_ "add" > *> optional (keyword_ "column")) >> > AddColumnDef <$> columnDef +> alterColumn = keyword_ "alter" >> optional (keyword_ "column") >> +> name <**> choice [setDefault +> ,dropDefault +> ,setNotNull +> ,dropNotNull +> ,setDataType] +> setDefault :: Parser (Name -> AlterTableAction) +> -- todo: left factor +> setDefault = try (keywords_ ["set","default"]) >> +> valueExpr <$$> AlterColumnSetDefault +> dropDefault = AlterColumnDropDefault <$ try (keywords_ ["drop","default"]) +> setNotNull = AlterColumnSetNotNull <$ try (keywords_ ["set","not","null"]) +> dropNotNull = AlterColumnDropNotNull <$ try (keywords_ ["drop","not","null"]) +> setDataType = try (keywords_ ["set","data","type"]) >> +> typeName <$$> AlterColumnSetDataType +> dropColumn = try (keyword_ "drop" *> optional (keyword_ "column")) >> +> DropColumn <$> name <*> dropBehaviour +> -- todo: left factor, this try is especially bad +> addConstraint = try (keyword_ "add" >> +> uncurry AddTableConstraintDef <$> tableConstraintDef) +> dropConstraint = try (keywords_ ["drop","constraint"]) >> +> DropTableConstraintDef <$> names <*> dropBehaviour + > dropSchema :: Parser Statement > dropSchema = keyword_ "schema" >> diff --git a/Language/SQL/SimpleSQL/Pretty.lhs b/Language/SQL/SimpleSQL/Pretty.lhs index 76e4a06..918b3f8 100644 --- a/Language/SQL/SimpleSQL/Pretty.lhs +++ b/Language/SQL/SimpleSQL/Pretty.lhs @@ -459,22 +459,8 @@ which have been changed to try to improve the layout of the output. > where > cd (TableConstraintDef n con) = > maybe empty (\s -> text "constraint" <+> names s) n -> <+> ptcon con +> <+> tableConstraint d con > cd (TableColumnDef cd') = columnDef d cd' -> ptcon (TableUniqueConstraint ns) = -> text "unique" <+> parens (commaSep $ map name ns) -> ptcon (TablePrimaryKeyConstraint ns) = -> texts ["primary","key"] <+> parens (commaSep $ map name ns) -> ptcon (TableReferencesConstraint cs t tcs m u del) = -> texts ["foreign", "key"] -> <+> parens (commaSep $ map name cs) -> <+> text "references" -> <+> names t -> <+> maybe empty (\c' -> parens (commaSep $ map name c')) tcs -> <+> refMatch m -> <+> refAct "update" u -> <+> refAct "delete" del -> ptcon (TableCheckConstraint v) = text "check" <+> parens (valueExpr d v) > statement d (AlterTable t act) = > texts ["alter","table"] <+> names t @@ -543,7 +529,6 @@ which have been changed to try to improve the layout of the output. > Just (IdentityColumnSpec w o) -> > text "generated" > <+> (case w of -> GeneratedDefault -> empty > GeneratedAlways -> text "always" > GeneratedByDefault -> text "by" <+> text "default") > <+> text "as" <+> text "identity" @@ -595,6 +580,65 @@ which have been changed to try to improve the layout of the output. > alterTableAction d (AddColumnDef cd) = > texts ["add", "column"] <+> columnDef d cd +> alterTableAction d (AlterColumnSetDefault n v) = +> texts ["alter", "column"] +> <+> name n +> <+> texts ["set","default"] <+> valueExpr d v +> alterTableAction _ (AlterColumnDropDefault n) = +> texts ["alter", "column"] +> <+> name n +> <+> texts ["drop","default"] + +> alterTableAction _ (AlterColumnSetNotNull n) = +> texts ["alter", "column"] +> <+> name n +> <+> texts ["set","not","null"] + +> alterTableAction _ (AlterColumnDropNotNull n) = +> texts ["alter", "column"] +> <+> name n +> <+> texts ["drop","not","null"] + +> alterTableAction _ (AlterColumnSetDataType n t) = +> texts ["alter", "column"] +> <+> name n +> <+> texts ["set","data","Type"] +> <+> typeName t + +> alterTableAction _ (DropColumn n b) = +> texts ["drop", "column"] +> <+> name n +> <+> dropBehav b + +> alterTableAction d (AddTableConstraintDef n con) = +> text "add" +> <+> maybe empty (\s -> text "constraint" <+> names s) n +> <+> tableConstraint d con + +> alterTableAction _ (DropTableConstraintDef n b) = +> texts ["drop", "constraint"] +> <+> names n +> <+> dropBehav b + + +> tableConstraint :: Dialect -> TableConstraint -> Doc +> tableConstraint _ (TableUniqueConstraint ns) = +> text "unique" <+> parens (commaSep $ map name ns) +> tableConstraint _ (TablePrimaryKeyConstraint ns) = +> texts ["primary","key"] <+> parens (commaSep $ map name ns) +> tableConstraint _ (TableReferencesConstraint cs t tcs m u del) = +> texts ["foreign", "key"] +> <+> parens (commaSep $ map name cs) +> <+> text "references" +> <+> names t +> <+> maybe empty (\c' -> parens (commaSep $ map name c')) tcs +> <+> refMatch m +> <+> refAct "update" u +> <+> refAct "delete" del +> tableConstraint d (TableCheckConstraint v) = text "check" <+> parens (valueExpr d v) + + + = utils > commaSep :: [Doc] -> Doc diff --git a/Language/SQL/SimpleSQL/Syntax.lhs b/Language/SQL/SimpleSQL/Syntax.lhs index 576d553..662336f 100644 --- a/Language/SQL/SimpleSQL/Syntax.lhs +++ b/Language/SQL/SimpleSQL/Syntax.lhs @@ -553,13 +553,18 @@ I'm not sure if this is valid syntax or not. > data AlterTableAction = > AddColumnDef ColumnDef -> {- -> | AlterColumnDef -> | DropColumnDef -> | AddTableConstraintDef -> | AlterTableConstraintDef -> | DropTableConstraintDef -> -} +> | AlterColumnSetDefault Name ValueExpr +> | AlterColumnDropDefault Name +> | AlterColumnSetNotNull Name +> | AlterColumnDropNotNull Name +> | AlterColumnSetDataType Name TypeName +> {- | AlterColumnAlterIdentity +> | AlterColumnDropIdentity +> | AlterColumnDropColumnGeneration-} +> | DropColumn Name DropBehaviour +> | AddTableConstraintDef (Maybe [Name]) TableConstraint +> -- | AlterTableConstraintDef +> | DropTableConstraintDef [Name] DropBehaviour > deriving (Eq,Show,Read,Data,Typeable) > {-data ConstraintCharacteristics = @@ -597,8 +602,7 @@ I'm not sure if this is valid syntax or not. > deriving (Eq,Show,Read,Data,Typeable) > data IdentityWhen = -> GeneratedDefault -> | GeneratedAlways +> GeneratedAlways > | GeneratedByDefault > deriving (Eq,Show,Read,Data,Typeable) diff --git a/tools/Language/SQL/SimpleSQL/SQL2011Schema.lhs b/tools/Language/SQL/SimpleSQL/SQL2011Schema.lhs index 9378406..5614704 100644 --- a/tools/Language/SQL/SimpleSQL/SQL2011Schema.lhs +++ b/tools/Language/SQL/SimpleSQL/SQL2011Schema.lhs @@ -455,11 +455,6 @@ options GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ] -> ,(TestStatement SQL2011 "create table t (a int generated as identity);" -> $ CreateTable [Name "t"] -> [TableColumnDef $ ColumnDef (Name "a") (TypeName [Name "int"]) -> (Just $ IdentityColumnSpec GeneratedDefault []) []]) - > ,(TestStatement SQL2011 "create table t (a int generated always as identity);" > $ CreateTable [Name "t"] > [TableColumnDef $ ColumnDef (Name "a") (TypeName [Name "int"]) @@ -472,11 +467,11 @@ options > ,(TestStatement SQL2011 -> "create table t (a int generated as identity\n\ +> "create table t (a int generated always as identity\n\ > \ ( start with 5 increment by 5 maxvalue 500 minvalue 5 cycle ));" > $ CreateTable [Name "t"] > [TableColumnDef $ ColumnDef (Name "a") (TypeName [Name "int"]) -> (Just $ IdentityColumnSpec GeneratedDefault +> (Just $ IdentityColumnSpec GeneratedAlways > [SGOStartWith 5 > ,SGOIncrementBy 5 > ,SGOMaxValue 500 @@ -484,11 +479,11 @@ options > ,SGOCycle]) []]) > ,(TestStatement SQL2011 -> "create table t (a int generated as identity\n\ +> "create table t (a int generated always as identity\n\ > \ ( start with -4 no maxvalue no minvalue no cycle ));" > $ CreateTable [Name "t"] > [TableColumnDef $ ColumnDef (Name "a") (TypeName [Name "int"]) -> (Just $ IdentityColumnSpec GeneratedDefault +> (Just $ IdentityColumnSpec GeneratedAlways > [SGOStartWith (-4) > ,SGONoMaxValue > ,SGONoMinValue @@ -764,6 +759,7 @@ alter table t add a int unique not null check (a>0) > $ ColumnDef (Name "a") (TypeName [Name "int"]) Nothing [] > ) +todo: more add column 11.12 @@ -788,29 +784,39 @@ alter table t add a int unique not null check (a>0) ::= SET -alter table t alter column c set default ... -alter table t alter c set default ... + +> ,(TestStatement SQL2011 +> "alter table t alter column c set default 0" +> $ AlterTable [Name "t"] $ AlterColumnSetDefault (Name "c") +> $ NumLit "0") 11.14 ::= DROP DEFAULT -alter table t alter column c drop default +> ,(TestStatement SQL2011 +> "alter table t alter column c drop default" +> $ AlterTable [Name "t"] $ AlterColumnDropDefault (Name "c")) + 11.15 ::= SET NOT NULL -alter table t alter column c set not null +> ,(TestStatement SQL2011 +> "alter table t alter column c set not null" +> $ AlterTable [Name "t"] $ AlterColumnSetNotNull (Name "c")) 11.16 ::= DROP NOT NULL -alter table t alter column c drop not null +> ,(TestStatement SQL2011 +> "alter table t alter column c drop not null" +> $ AlterTable [Name "t"] $ AlterColumnDropNotNull (Name "c")) 11.17 @@ -827,7 +833,12 @@ alter table t alter column c drop not null ::= SET DATA TYPE -alter table t alter column c set data type int; +> ,(TestStatement SQL2011 +> "alter table t alter column c set data type int;" +> $ AlterTable [Name "t"] $ +> AlterColumnSetDataType (Name "c") (TypeName [Name "int"])) + + 11.20 @@ -838,6 +849,18 @@ alter table t alter column c set data type int; ::= SET GENERATED { ALWAYS | BY DEFAULT } +so you have to write set generated for alter identity? +and you have to use always or by default + +makes no sense: if you just want to restart you have to explicitly set +the always or by default? you can't just leave it unchanged? + +you don't write as identity like with create table, this is wrong: + +alter table t alter column c set generated always as identity + +but these are ok? + alter table t alter column c set generated always alter table t alter column c set generated by default @@ -846,10 +869,39 @@ 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 generated always restart +alter table t alter column c set generated always restart with 4 -alter table t alter column c set increment by minvalue maxvalue cycle +you can just write restart + +but to write others you have to repeat set? each time? + +alter table t alter column c set generated always set increment by 5 set minvalue 0 set maxvalue 5 set cycle restart with 5 +(no set before the restart + +in create table, it looks like this: + +c int generated generated always as identity (increment by 5 minvalue 0 maxvalue 5 cycle restart with 5) + +why gratuituous differences??? + +is there no way to do this: + +alter table t alter column c set generated as (a * 3) +?? + +PLAN: TODO + +don't implement alter table alter column generated now + +review the syntax for generated in db2, oracle, sql server, postgres, others? + +observe which features are supported, and the consistency between +create table and alter table + +try to find some people to ask if the standard really is this much of +a mess or I have misunderstood the grammer, or maybe there is a good +reason for the inconsistencies? 11.21 @@ -859,6 +911,8 @@ alter table t alter column c set increment by minvalue maxvalue cycle alter table t alter column c drop identity +included in the generated plan above + 11.22 ::= @@ -866,22 +920,48 @@ alter table t alter column c drop identity alter table t alter column c drop expression +included in the generated plan above + + 11.23 ::= DROP [ COLUMN ] -alter table t alter drop column c +> ,(TestStatement SQL2011 +> "alter table t drop column c" +> $ AlterTable [Name "t"] $ +> DropColumn (Name "c") DefaultDropBehaviour) + +> ,(TestStatement SQL2011 +> "alter table t drop c cascade" +> $ AlterTable [Name "t"] $ +> DropColumn (Name "c") Cascade) + +> ,(TestStatement SQL2011 +> "alter table t drop c restrict" +> $ AlterTable [Name "t"] $ +> DropColumn (Name "c") Restrict) + -alter table t alter drop c restrict -alter table t alter drop c cascade 11.24 ::= ADD -todo +> ,(TestStatement SQL2011 +> "alter table t add constraint c unique (a,b)" +> $ AlterTable [Name "t"] $ +> AddTableConstraintDef (Just [Name "c"]) +> $ TableUniqueConstraint [Name "a", Name "b"]) + +> ,(TestStatement SQL2011 +> "alter table t add unique (a,b)" +> $ AlterTable [Name "t"] $ +> AddTableConstraintDef Nothing +> $ TableUniqueConstraint [Name "a", Name "b"]) + 11.25 ::= @@ -894,7 +974,15 @@ todo ::= DROP CONSTRAINT -todo +> ,(TestStatement SQL2011 +> "alter table t drop constraint c" +> $ AlterTable [Name "t"] $ +> DropTableConstraintDef [Name "c"] DefaultDropBehaviour) + +> ,(TestStatement SQL2011 +> "alter table t drop constraint c restrict" +> $ AlterTable [Name "t"] $ +> DropTableConstraintDef [Name "c"] Restrict) 11.27