diff --git a/src/Rezoom.SQL.Compiler/AST.fs b/src/Rezoom.SQL.Compiler/AST.fs index 3bab0b4..a2eb4e4 100644 --- a/src/Rezoom.SQL.Compiler/AST.fs +++ b/src/Rezoom.SQL.Compiler/AST.fs @@ -582,13 +582,17 @@ type [] CreateTableDefinition<'t, 'e> = type [] CreateTableAs<'t, 'e> = | CreateAsDefinition of CreateTableDefinition<'t, 'e> | CreateAsSelect of SelectStmt<'t, 'e> - + type [] CreateTableStmt<'t, 'e> = { Temporary : bool Name : ObjectName<'t> As : CreateTableAs<'t, 'e> } +type [] CreateSchemaStmt<'t,'e> = + { SchemaName : Name + } + type [] CreateIndexStmt<'t, 'e> = { Unique : bool IndexName : ObjectName<'t> @@ -682,6 +686,7 @@ type [] CreateViewStmt<'t, 'e> = type DropObjectType = | DropIndex + | DropSchema | DropTable | DropView @@ -703,6 +708,7 @@ type [] VendorStmt<'t, 'e> = and [] Stmt<'t, 'e> = | AlterTableStmt of AlterTableStmt<'t, 'e> | CreateIndexStmt of CreateIndexStmt<'t, 'e> + | CreateSchemaStmt of CreateSchemaStmt<'t,'e> | CreateTableStmt of CreateTableStmt<'t, 'e> | CreateViewStmt of CreateViewStmt<'t, 'e> | DeleteStmt of DeleteStmt<'t, 'e> @@ -746,6 +752,7 @@ type CompoundExpr = CompoundExpr type CompoundTermCore = CompoundTermCore type CompoundTerm = CompoundTerm type CreateTableDefinition = CreateTableDefinition +type CreateSchemaStmt = CreateSchemaStmt type CreateTableStmt = CreateTableStmt type SelectCore = SelectCore type Join = Join diff --git a/src/Rezoom.SQL.Compiler/ASTMapping.fs b/src/Rezoom.SQL.Compiler/ASTMapping.fs index f4d61f6..9c29f3d 100644 --- a/src/Rezoom.SQL.Compiler/ASTMapping.fs +++ b/src/Rezoom.SQL.Compiler/ASTMapping.fs @@ -12,6 +12,7 @@ type ASTMapping<'t1, 'e1, 't2, 'e2>(mapT : 't1 -> 't2, mapE : 'e1 -> 'e2) = { Operator = unary.Operator Operand = this.Expr(unary.Operand) } + member this.Name = Name member this.ObjectName(objectName : ObjectName<'t1>) = { SchemaName = objectName.SchemaName ObjectName = objectName.ObjectName @@ -277,6 +278,10 @@ type ASTMapping<'t1, 'e1, 't2, 'e2>(mapT : 't1 -> 't2, mapE : 'e1 -> 'e2) = { Columns = createTable.Columns |> rmap this.ColumnDef Constraints = createTable.Constraints |> rmap this.TableConstraint } + + member this.CreateSchema(createSchemaStmt: CreateSchemaStmt<'t1,'e1>) = + { SchemaName = createSchemaStmt.SchemaName + } member this.CreateTable(createTable : CreateTableStmt<'t1, 'e1>) = { Temporary = createTable.Temporary Name = this.ObjectName(createTable.Name) @@ -327,6 +332,7 @@ type ASTMapping<'t1, 'e1, 't2, 'e2>(mapT : 't1 -> 't2, mapE : 'e1 -> 'e2) = Alteration = this.Alteration(alter.Alteration) } | CreateIndexStmt index -> CreateIndexStmt <| this.CreateIndex(index) + | CreateSchemaStmt createSchema -> CreateSchemaStmt <| this.CreateSchema(createSchema) | CreateTableStmt createTable -> CreateTableStmt <| this.CreateTable(createTable) | CreateViewStmt createView -> CreateViewStmt <| this.CreateView(createView) | DeleteStmt delete -> DeleteStmt <| this.Delete(delete) diff --git a/src/Rezoom.SQL.Compiler/CommandEffect.fs b/src/Rezoom.SQL.Compiler/CommandEffect.fs index f5eee9e..92a97f4 100644 --- a/src/Rezoom.SQL.Compiler/CommandEffect.fs +++ b/src/Rezoom.SQL.Compiler/CommandEffect.fs @@ -71,6 +71,7 @@ and private CommandEffectBuilder(model : Model) = match stmt with | AlterTableStmt { Alteration = AddColumn _ | AddConstraint _ | AddDefault _ } | CreateIndexStmt _ + | CreateSchemaStmt _ | CreateTableStmt _ | SelectStmt _ | CreateViewStmt _ -> false diff --git a/src/Rezoom.SQL.Compiler/ComplexModelOps.fs b/src/Rezoom.SQL.Compiler/ComplexModelOps.fs index 7ae5aaf..9c127a3 100644 --- a/src/Rezoom.SQL.Compiler/ComplexModelOps.fs +++ b/src/Rezoom.SQL.Compiler/ComplexModelOps.fs @@ -85,6 +85,11 @@ let addColumnDef tableName (column : ColumnDef<'t, 'e> WithSource) = do! ModelOps.addConstraint tableName constraintName constraintType cols } +let createSchema schemaName (_def: CreateSchemaStmt<'t, 'e>) = + stateful { + do! ModelOps.putSchema schemaName + } + let createTableByDefinition tableName (def : CreateTableDefinition<'t, 'e>) = stateful { do! ModelOps.createEmptyTable tableName diff --git a/src/Rezoom.SQL.Compiler/CoreParser.fs b/src/Rezoom.SQL.Compiler/CoreParser.fs index 3bbd13a..bebaefc 100644 --- a/src/Rezoom.SQL.Compiler/CoreParser.fs +++ b/src/Rezoom.SQL.Compiler/CoreParser.fs @@ -1006,13 +1006,21 @@ let private createTableDefinition = |> Seq.toArray } +let private createSchemaStmt = + %% kw "CREATE" + -? kw "SCHEMA" + -- +.name + -|> fun name -> + { SchemaName = name + } + let private createTableAs = %[ %% kw "AS" -- +.selectStmt -|> fun select _ -> CreateAsSelect select %% +.createTableDefinition -|> fun def tblName -> CreateAsDefinition (def tblName) ] let private temporary = %(zeroOrOne * [kw "TEMPORARY"; kw "TEMP"]) - + let private createTableStmt = %% kw "CREATE" -- +.temporary @@ -1164,6 +1172,7 @@ let private dropObjectType = %[ %% kw "INDEX" -|> DropIndex %% kw "TABLE" -|> DropTable %% kw "VIEW" -|> DropView + %% kw "SCHEMA" -|> DropSchema ] let private dropObjectStmt = @@ -1186,6 +1195,7 @@ let private cteStmt = let coreStmt = %[ %% +.alterTableStmt -|> AlterTableStmt + %% +.createSchemaStmt -|> CreateSchemaStmt %% +.createIndexStmt -|> CreateIndexStmt %% +.createTableStmt -|> CreateTableStmt %% +.createViewStmt -|> CreateViewStmt diff --git a/src/Rezoom.SQL.Compiler/DefaultStatementTranslator.fs b/src/Rezoom.SQL.Compiler/DefaultStatementTranslator.fs index d15e932..279c8cf 100644 --- a/src/Rezoom.SQL.Compiler/DefaultStatementTranslator.fs +++ b/src/Rezoom.SQL.Compiler/DefaultStatementTranslator.fs @@ -352,6 +352,14 @@ type DefaultStatementTranslator(expectedVendorName : Name, indexer : IParameterI let constraints = create.Constraints |> Seq.map (fun c -> this.TableConstraint(table, c.Value)) yield! Seq.append columns constraints |> parencols } + override this.CreateSchema(create:TCreateSchemaStmt) = + seq { + yield text "CREATE" + yield ws + yield text "SCHEMA" + yield ws + yield this.Expr.Name(create.SchemaName) + } override this.CreateTable(create) = seq { yield text "CREATE" @@ -485,6 +493,7 @@ type DefaultStatementTranslator(expectedVendorName : Name, indexer : IParameterI | DropIndex -> text "INDEX" | DropTable -> text "TABLE" | DropView -> text "VIEW" + | DropSchema -> text "SCHEMA" yield ws yield! this.Expr.ObjectName(drop.ObjectName) } @@ -609,6 +618,7 @@ type DefaultStatementTranslator(expectedVendorName : Name, indexer : IParameterI override this.Statement(stmt) = match stmt with | AlterTableStmt alter -> this.AlterTable(alter) + | CreateSchemaStmt create -> this.CreateSchema(create) | CreateTableStmt create -> this.CreateTable(create) | CreateViewStmt create -> this.CreateView(create) | CreateIndexStmt create -> this.CreateIndex(create) diff --git a/src/Rezoom.SQL.Compiler/Error.fs b/src/Rezoom.SQL.Compiler/Error.fs index f1a33cb..b12759b 100644 --- a/src/Rezoom.SQL.Compiler/Error.fs +++ b/src/Rezoom.SQL.Compiler/Error.fs @@ -158,4 +158,7 @@ let updateDuplicateColumn columnName = sprintf "SQ066: The column ``%O`` is specified multiple times in the update statement" columnName let tableNameNotSuitableForPG = - "SQ069: Table name is not suitable for PG (maybe you thought you were writing R?)" \ No newline at end of file + "SQ069: Table name is not suitable for PG (maybe you thought you were writing R?)" + +let cannotDropSchemaWithObjects schemaName objectNames = + sprintf "SQ070: Cannot drop the schema ``%O`` while it still contains object(s) (%O)" schemaName objectNames \ No newline at end of file diff --git a/src/Rezoom.SQL.Compiler/ExprInfo.fs b/src/Rezoom.SQL.Compiler/ExprInfo.fs index 02df39b..0be6327 100644 --- a/src/Rezoom.SQL.Compiler/ExprInfo.fs +++ b/src/Rezoom.SQL.Compiler/ExprInfo.fs @@ -134,12 +134,14 @@ and [] and [] [] ObjectInfo<'t> = + | Schema of Schema | TableLike of 't TableLikeExprInfo | Index of SchemaIndex | Missing member this.Idempotent = match this with | TableLike t -> t.Query.Idempotent + | Schema _ | Index _ | Missing -> true member this.Table = @@ -153,7 +155,7 @@ and [] | TableLike t -> TableLike (t.Map(f)) | Index i -> Index i | Missing -> Missing - + | Schema s -> Schema s and TSelectStmt = SelectStmt and TCreateViewStmt = CreateViewStmt @@ -182,6 +184,7 @@ type TCompoundTerm = CompoundTerm type TForeignKeyClause = ForeignKeyClause type TCreateTableDefinition = CreateTableDefinition type TCreateTableStmt = CreateTableStmt +type TCreateSchemaStmt = CreateSchemaStmt type TSelectCore = SelectCore type TJoinConstraint = JoinConstraint type TJoin = Join diff --git a/src/Rezoom.SQL.Compiler/InferredTypes.fs b/src/Rezoom.SQL.Compiler/InferredTypes.fs index 6acf3f8..2e76792 100644 --- a/src/Rezoom.SQL.Compiler/InferredTypes.fs +++ b/src/Rezoom.SQL.Compiler/InferredTypes.fs @@ -114,6 +114,7 @@ type InfCompoundExpr = CompoundExpr type InfCompoundTerm = CompoundTerm type InfCreateTableDefinition = CreateTableDefinition +type InfCreateSchemaStmt = CreateSchemaStmt type InfCreateTableStmt = CreateTableStmt type InfSelectCore = SelectCore type InfJoinConstraint = JoinConstraint @@ -264,6 +265,9 @@ and [] ParentScope = Some this } + member private this.ResolveSchema + (schema : Schema) = + Found (ObjectInfo.Schema schema) member private this.ResolveObjectReferenceBySchema (schema : Schema, name : Name, inferView : CreateViewStmt -> TCreateViewStmt) = match schema.Objects |> Map.tryFind name with @@ -280,6 +284,10 @@ and [] /// Resolve a reference to a table which may occur as part of a TableExpr. /// This will resolve against the database model and CTEs, but not table aliases defined in the FROM clause. member this.ResolveObjectReference(name : ObjectName, inferView) = + match this.Model.Schema (Some name.ObjectName) with + | Some schema -> + this.ResolveSchema(schema) + | None -> match name.SchemaName with | None -> match this.CTEVariables.TryFind(name.ObjectName) with diff --git a/src/Rezoom.SQL.Compiler/ModelChange.fs b/src/Rezoom.SQL.Compiler/ModelChange.fs index 4d0e206..87406c7 100644 --- a/src/Rezoom.SQL.Compiler/ModelChange.fs +++ b/src/Rezoom.SQL.Compiler/ModelChange.fs @@ -4,6 +4,11 @@ open System.Collections.Generic open Rezoom.SQL.Compiler.InferredTypes type private ModelChange(model : Model, inference : ITypeInferenceContext) = + member private this.CreateSchema(create: InfCreateSchemaStmt) = + stateful { + let schema = { SchemaName = create.SchemaName; Objects = Map.empty } + return! ComplexModelOps.createSchema schema create + } |> State.runForOutputState model |> Some member private this.CreateTable(create : InfCreateTableStmt) = stateful { let! tableName = ComplexModelOps.qualifyTemp create.Temporary create.Name @@ -64,6 +69,8 @@ type private ModelChange(model : Model, inference : ITypeInferenceContext) = return! ModelOps.dropView objName | DropTable -> return! ModelOps.dropTable objName + | DropSchema -> + return! ModelOps.dropSchema { Value = Some drop.ObjectName.ObjectName; Source = objName.Source } } |> State.runForOutputState model |> Some member this.CreateIndex(create : InfCreateIndexStmt) = stateful { @@ -75,6 +82,7 @@ type private ModelChange(model : Model, inference : ITypeInferenceContext) = member this.Stmt(stmt : InfStmt) = match stmt with | AlterTableStmt alter -> this.AlterTable(alter) + | CreateSchemaStmt create -> this.CreateSchema(create) | CreateTableStmt create -> this.CreateTable(create) | CreateViewStmt create -> this.CreateView(create) | CreateIndexStmt create -> this.CreateIndex(create) diff --git a/src/Rezoom.SQL.Compiler/ModelOps.fs b/src/Rezoom.SQL.Compiler/ModelOps.fs index 04f04d6..c98a6e1 100644 --- a/src/Rezoom.SQL.Compiler/ModelOps.fs +++ b/src/Rezoom.SQL.Compiler/ModelOps.fs @@ -47,7 +47,6 @@ let getRequiredSchema (schemaName: Name option WithSource) = let getRequiredObject objectTypeName (name : QualifiedObjectName WithSource) = stateful { - let! model = State.get let! schema = name.Map(fun n -> Some n.SchemaName) |> getRequiredSchema return match schema.Objects |> Map.tryFind name.Value.ObjectName with @@ -88,10 +87,20 @@ let putSchema (schema : Schema) = return! State.put newModel } +/// Remove an existing schema from the model. +let removeSchema (schemaName : Name option WithSource) = + stateful { + let! model = State.get + let! schema = schemaName |> getRequiredSchema + if schema.Objects.Count > 0 then + failAt schemaName.Source <| Error.cannotDropSchemaWithObjects schema.SchemaName (schema.Objects |> Map.toArray |> Array.map (fun (k,_) -> k.Value) |> String.concat ", ") + let newModel = { model with Schemas = model.Schemas |> Map.remove schema.SchemaName } + return! State.put newModel + } + /// Create or update an object within an existing schema in the model. let putObject (name : QualifiedObjectName WithSource) (obj : SchemaObject) = stateful { - let! model = State.get let! schema = name.Map(fun n -> Some n.SchemaName) |> getRequiredSchema let newSchema = { schema with Objects = schema.Objects |> Map.add name.Value.ObjectName obj } return! putSchema newSchema @@ -100,7 +109,6 @@ let putObject (name : QualifiedObjectName WithSource) (obj : SchemaObject) = /// Remove an existing object from the model. let removeObject (name : QualifiedObjectName WithSource) = stateful { - let! model = State.get let! schema = name.Map(fun n -> Some n.SchemaName) |> getRequiredSchema let newSchema = { schema with Objects = schema.Objects |> Map.remove name.Value.ObjectName } return! putSchema newSchema @@ -356,6 +364,13 @@ let dropView (viewName : QualifiedObjectName WithSource) = return! removeObject viewName } +/// Remove an existing schema from the model. +let dropSchema (schemaName : Name option WithSource) = + stateful { + let! _ = getRequiredSchema schemaName // ensure it exists + return! removeSchema schemaName + } + /// Remove an existing index from the model. let dropIndex (indexName : QualifiedObjectName WithSource) = stateful { @@ -367,7 +382,7 @@ let dropIndex (indexName : QualifiedObjectName WithSource) = return! removeObject indexName } -/// Remove an existing table constraint from the mode. +/// Remove an existing table constraint from the model. let dropConstraint (tableName : QualifiedObjectName WithSource) (constraintName : Name WithSource) = stateful { let! table = getRequiredTable tableName diff --git a/src/Rezoom.SQL.Compiler/ReadWriteReferences.fs b/src/Rezoom.SQL.Compiler/ReadWriteReferences.fs index d448b52..c962a62 100644 --- a/src/Rezoom.SQL.Compiler/ReadWriteReferences.fs +++ b/src/Rezoom.SQL.Compiler/ReadWriteReferences.fs @@ -195,6 +195,7 @@ type private ReferenceFinder(model : Model) = | UpdateStmt update -> this.Update(update) | AlterTableStmt _ | CreateIndexStmt _ + | CreateSchemaStmt _ | CreateTableStmt _ | CreateViewStmt _ | DropObjectStmt _ -> () diff --git a/src/Rezoom.SQL.Compiler/TSQL.Statement.fs b/src/Rezoom.SQL.Compiler/TSQL.Statement.fs index 906d2c6..f38a515 100644 --- a/src/Rezoom.SQL.Compiler/TSQL.Statement.fs +++ b/src/Rezoom.SQL.Compiler/TSQL.Statement.fs @@ -28,6 +28,7 @@ type private TSQLStatement(indexer : IParameterIndexer) as this = | DropIndex -> text "INDEX" | DropTable -> text "TABLE" | DropView -> text "VIEW" + | DropSchema -> text "SCHEMA" yield ws yield! this.Expr.ObjectName(drop.ObjectName) match drop.Drop with diff --git a/src/Rezoom.SQL.Compiler/Translators.fs b/src/Rezoom.SQL.Compiler/Translators.fs index 445b025..701c169 100644 --- a/src/Rezoom.SQL.Compiler/Translators.fs +++ b/src/Rezoom.SQL.Compiler/Translators.fs @@ -55,6 +55,7 @@ type StatementTranslator() = abstract member ColumnConstraint : table : TObjectName * constr : TColumnConstraint -> Fragments abstract member ColumnDefinition : table : TObjectName * col : TColumnDef -> Fragments abstract member CreateTableDefinition : table : TObjectName * create : TCreateTableDefinition -> Fragments + abstract member CreateSchema : create : TCreateSchemaStmt -> Fragments abstract member CreateTable : create : TCreateTableStmt -> Fragments abstract member AlterTable : alter : TAlterTableStmt -> Fragments abstract member CreateView : create : TCreateViewStmt -> Fragments diff --git a/src/Rezoom.SQL.Compiler/TypeChecker.fs b/src/Rezoom.SQL.Compiler/TypeChecker.fs index 053a874..a6da756 100644 --- a/src/Rezoom.SQL.Compiler/TypeChecker.fs +++ b/src/Rezoom.SQL.Compiler/TypeChecker.fs @@ -634,6 +634,9 @@ type private TypeChecker(cxt : ITypeInferenceContext, scope : InferredSelectScop Constraints = createTable.Constraints |> rmap (fun con -> this.TableConstraint(con, creating)) } + member this.CreateSchema(createSchema: CreateSchemaStmt) = + { SchemaName = createSchema.SchemaName } + member this.CreateTable(createTable : CreateTableStmt) = let name = this.ObjectName(createTable.Name, true) let name = @@ -775,7 +778,9 @@ type private TypeChecker(cxt : ITypeInferenceContext, scope : InferredSelectScop { Table = tbl Alteration = this.Alteration(tbl, alter.Alteration) } + | CreateIndexStmt index -> CreateIndexStmt <| this.CreateIndex(index) + | CreateSchemaStmt createSchema -> CreateSchemaStmt <| this.CreateSchema(createSchema) | CreateTableStmt createTable -> CreateTableStmt <| this.CreateTable(createTable) | CreateViewStmt createView -> CreateViewStmt <| this.CreateView(createView) | DeleteStmt delete -> DeleteStmt <| this.Delete(delete) diff --git a/src/Rezoom.SQL.Provider/DocStrings.fs b/src/Rezoom.SQL.Provider/DocStrings.fs index ae0478a..77b016c 100644 --- a/src/Rezoom.SQL.Provider/DocStrings.fs +++ b/src/Rezoom.SQL.Provider/DocStrings.fs @@ -5,12 +5,14 @@ let private shortDescriptionCore (statement : Stmt<_, _>) = match statement with | AlterTableStmt _ -> "ALTER TABLE" | CreateIndexStmt _ -> "CREATE INDEX" + | CreateSchemaStmt _ -> "CREATE SCHEMA" | CreateTableStmt _ -> "CREATE TABLE" | CreateViewStmt _ -> "CREATE VIEW" | DeleteStmt _ -> "DELETE" | DropObjectStmt { Drop = DropIndex } -> "DROP INDEX" | DropObjectStmt { Drop = DropTable } -> "DROP TABLE" | DropObjectStmt { Drop = DropView } -> "DROP VIEW" + | DropObjectStmt { Drop = DropSchema } -> "DROP SCHEMA" | InsertStmt _ -> "INSERT" | SelectStmt _ -> "SELECT" | UpdateStmt _ -> "UPDATE" diff --git a/src/Rezoom.SQL.Test/Rezoom.SQL.Test.fsproj b/src/Rezoom.SQL.Test/Rezoom.SQL.Test.fsproj index 3b72ee2..9761985 100644 --- a/src/Rezoom.SQL.Test/Rezoom.SQL.Test.fsproj +++ b/src/Rezoom.SQL.Test/Rezoom.SQL.Test.fsproj @@ -28,6 +28,7 @@ + diff --git a/src/Rezoom.SQL.Test/TestCreateSchema.fs b/src/Rezoom.SQL.Test/TestCreateSchema.fs new file mode 100644 index 0000000..4938258 --- /dev/null +++ b/src/Rezoom.SQL.Test/TestCreateSchema.fs @@ -0,0 +1,15 @@ +module Rezoom.SQL.Test.CreateSchema +open Rezoom.SQL.Compiler +open NUnit.Framework + +[] +let ``schema can contain table`` () = + { defaultTest with + Migration = """ + create schema fancy_schema; + create table fancy_schema.fancy_table (fancy_column int); + """ + Command = "insert into fancy_schema.fancy_table (fancy_column) values (1)" + Expect = Good expect + } |> assertSimple + diff --git a/src/Rezoom.SQL.Test/TestTQLSmoke.fs b/src/Rezoom.SQL.Test/TestTQLSmoke.fs index 27b70e7..dd982a7 100644 --- a/src/Rezoom.SQL.Test/TestTQLSmoke.fs +++ b/src/Rezoom.SQL.Test/TestTQLSmoke.fs @@ -62,10 +62,14 @@ create table dbo.SmokeTable1 , DateTimeColumn datetime , DateTimeOffsetColumn datetimeoffset ); + +create schema foo; +create table foo.footable ( a int ); """ Command = """ with cte as (select GuidColumn, DateTimeOffsetColumn from SmokeTable1 where AutoColumn = 0) +, cte2 as (select * from foo.footable) select s.BooleanColumn from SmokeTable1 s join cte c on s.GuidColumn = c.GuidColumn @@ -77,6 +81,7 @@ union all select true except select false + """ Expect = { expect with @@ -124,6 +129,10 @@ CREATE TABLE [dbo].[SmokeTable1] ( [AutoColumn] INT NOT NULL CONSTRAINT [SmokeTa , [BooleanColumn] BIT NOT NULL , [DateTimeColumn] DATETIME2 NOT NULL , [DateTimeOffsetColumn] DATETIMEOFFSET NOT NULL ); +CREATE SCHEMA [foo]; +CREATE TABLE [foo].[footable] +( [a] INT NOT NULL +); """ |> Some OutputCommand = """ @@ -131,6 +140,11 @@ WITH [cte] AS ( SELECT [SmokeTable1].[GuidColumn] , [SmokeTable1].[DateTimeOffsetColumn] FROM [SmokeTable1] WHERE ([SmokeTable1].[AutoColumn] = 0) +),[cte2] +AS ( +SELECT +[footable].[a] +FROM [foo].[footable] ) ((SELECT [s].[BooleanColumn] FROM [SmokeTable1] AS [s] diff --git a/src/Rezoom.SQL.Test/TestTSQL.fs b/src/Rezoom.SQL.Test/TestTSQL.fs index 02a11c2..183cf4b 100644 --- a/src/Rezoom.SQL.Test/TestTSQL.fs +++ b/src/Rezoom.SQL.Test/TestTSQL.fs @@ -175,6 +175,32 @@ alter table foo drop column x; Expect = expect |> Good } |> assertSimple +[] +let ``tsql create and drop schema is ok`` () = + { tsqlTest with + Migration = + """ +create schema s; +create table s.foo(x int default 0, y int); +drop table s.foo; +drop schema s; + """ + Expect = expect |> Good + } |> assertSimple + +[] +let ``tsql create and drop schema with objects is not ok`` () = + { tsqlTest with + Migration = + """ +create schema s; +create table s.foo(x int default 0, y int); +create table s.bar(x int default 0, y int); +drop schema s; + """ + Expect = BadMigration <| Error.cannotDropSchemaWithObjects "s" "bar, foo" + } |> assertSimple + [] let ``tsql dump function signatures`` () = for KeyValue(_, func) in tsqlTest.TestBackend.InitialModel.Builtin.Functions do