SQL Server
5.8.1 Latest
Fixed
- A sequence start declared alongside its minimum now settles.
- An identity column reports no seed or increment where neither was declared.
textno longer drifts.
5.8.0
Added
is_persistedis introspected, andSupportsVirtualGeneratedColumnsis declared.
Changed
- The build now writes the full dependency closure beside the assembly (
CopyLocalLockFileAssemblies), so adotnet buildof this project can be loaded directly byPLUGIN ( path = '...' )without being packed first. Package contents are unchanged.
Fixed
- Computed columns are no longer all
PERSISTED. The keyword was emitted unconditionally, so a column computed on read came back written to storage. ROWGUIDCOLis no longer dropped. It was neither introspected nor rendered, so a column marked as the table’s row identifier came back as an ordinary one.- Default constraint names are preserved. A default was emitted unnamed, so SQL Server generated one.
NOT FOR REPLICATIONis no longer dropped from identity columns or triggers.
5.7.0
Added
- Clustered indexes round-trip.
SupportsClusteringis on, soCLUSTEREDandNONCLUSTEREDare rendered on indexes, primary keys and unique constraints. - XML schema collections round-trip.
XML_SCHEMA_NAMESPACEreassembles a collection fromsys.xml_schema_*into the single document it was declared as, and a typedxmlcolumn carries the collection it is bound to along with whether it isDOCUMENTorCONTENT. - Constraints SQL Server named for itself are reported.
is_system_namedis read for key, foreign-key and check constraints, and asystem-named-constraintwarning names them as one grouped finding. - XML indexes round-trip.
sys.xml_indexessupplies the kind and, for a secondary, the primary whose node table it reads (i.typeidentifies an XML index, sincesecondary_type_descis null for a primary as well as for a non-XML index). - Indexed views round-trip. Indexes are read from
sys.objectsrather thansys.tables, so a view’s indexes are introspected ontoView.Indexesalongside a table’s. - Schema binding round-trips.
WITH SCHEMABINDINGis read fromsys.sql_modules.is_schema_boundontoView.IsSchemaBoundand written back from it.
5.6.0
Fixed
- Options clauses on procedures split correctly. An options clause (
WITH EXECUTE AS …,WITH RECOMPILE) ends the header too and stays with the definition. - Comments before a module’s
CREATEno longer derail the split.sys.sql_modulesstores the batch as written, comments included; the leading trivia is now stepped over before the header is matched, for routines, views, and triggers. - A parameter list ending in a line comment renders intact. The closing parenthesis is printed on a new line rather than being swallowed by the comment.
- A parameter-less procedure renders without parentheses. T-SQL rejects
CREATE PROCEDURE name(); the empty list is omitted (functions keep theirs).
5.5.0
Added
- Alias types are domains. A user-defined alias type (
CREATE TYPE … FROM base) now introspects as a domain — base type, nullability, andMS_Descriptioncomment — and the dialect renders domain actions: create, drop, rename (sp_rename … 'USERDATATYPE'), recreate, and comment. A domain declaring a default or check constraints remains a clear diagnostic — alias types cannot carry them.
Changed
- Alias types left the vocabulary. They were previously reported as
NativeTypes; a declaration the plan can create and drop is not vocabulary. CLR types remain vocabulary, and table types remain excluded.
Fixed
- A view’s introspected body is the bare query. The trailing statement terminator
sys.sql_modulespreserves from the originalCREATE VIEWis now stripped, so the introspected body matches what an author writes. - Introspected comments are trimmed. An
MS_Descriptionvalue with surrounding whitespace cannot be expressed by an NSQL doc comment, so it could never round-trip; values are trimmed on the way in and whitespace-only values are treated as no comment. - Unparenthesized procedure headers split correctly. A procedure declared without parentheses had its parameter list found by searching for a space-padded
AS, which missed a newline-delimited headerASand could match one inside the body (a CTE’s, an alias’s). The headerASis now located by a scan that honours strings, bracketed identifiers, comments, parenthesis depth, and a parameter’s own@name AS type.
5.4.0
Added
- Aggregates are a declared limitation. A project declaring
CREATE AGGREGATEgets a clear diagnostic — SQL Server aggregates are CLR assemblies the model cannot express — instead of a wrongCREATE FUNCTION.
Changed
datetimeanddatetime2are two types, and both are preserved. A user who writesdatetimegetsdatetime;datetime2round-trips verbatim. The model’s canonicaldatetimeno longer silently upgrades todatetime2.- System types are captured bare. A built-in outside the model’s vocabulary (
money,xml, bothdatetimes) introspects under its own bare name — the engine’s vocabulary is addressed bare — while user-defined types keep their owning schema.
5.3.0
Changed
- A create is a create.
CREATE FUNCTION,CREATE PROCEDURE,CREATE VIEW, andCREATE TRIGGERrender withoutOR ALTERwhen the plan is creating;CREATE OR ALTERrenders only for the replace and recreate actions, where the plan knows the object exists. (A changed trigger plans as a replacement, renderedCREATE OR ALTER.) A create colliding with an object the plan didn’t know about now fails loudly instead of silently overwriting it.
5.2.0
Added
- The engine’s type vocabulary is captured. Introspection now records the types SQL Server provides (
sys.types, table types excluded) asNativeTypes in the snapshot, spelled in the model’s canonical names, alongside user-defined alias and CLR types. With a captured vocabulary, a plan can verify every type the project references and report an unresolvable reference at plan time. - SQL Server equivalence rules.
UseSqlServernow registersSqlServerSqlEquivalence: a type qualifier namingdboorsysfolds away when comparing, sosys.moneyand a declaredmoneyread as one type. sysis reported as a schema SQL Server provides, alongsidedbo.
Fixed
- User-defined types no longer lose their schema. A column typed by a UDT outside
dbopreviously introspected as a bare name; it now captures fully qualified, so type references resolve to the right object.
5.1.0
Fixed
dbois reported as a schema SQL Server provides. It is a container rather than something a migration creates, and declaring it is a warning.
5.0.0
Tracks the NSchema.Core 5.0 rearchitecture (requires NSchema.Core 5.0.0-alpha.1).
Changed
SqlServerSqlDialectreplaces the SQL generator. The provider now plugs into Core’sSqlDialectseam, rendering one migration action at a time. Features SQL Server cannot express (schema renames, materialized views, exclusion constraints, in-place identity/computed-column changes,BEFORE/row-level/WHEN/function-style triggers, enums, domains, composite types, extensions) now surface as error diagnostics on the plan instead of throwingNotSupportedException.SqlServerDatabaseIntrospectorreplaces the schema provider. It implements Core’sIDatabaseIntrospector, reading the live database into the newNSchema.Modelschema model scoped by aPlanningScope.UseSqlServer(...)replacesUseSqlServerSchema(...), andUseSqlServerDialect()replacesUseSqlServerGenerator(). Same overloads and registrations under the new Core seams.- The plugin is configured by a
DATABASEstatement.SqlServerPluginimplementsINSchemaDatabasePlugin:Configuretakes the core’s typedPluginSettingsand returns aResultwhose diagnostics carry any configuration errors. Environment overrides are the engine’sNSCHEMA_DATABASE_<SETTING>now; the provider reads no environment variables of its own.
Added
newasks for the connection details. The plugin declares server, database, authentication and username as scaffolding questions and composes the answers into theconnection_stringit writes. The password is deliberately not asked for — it belongs inNSCHEMA_DATABASE_PASSWORD.- Supports change-event scripts (
SCRIPT '<name>' RUN ON <event> <path>): the script’s SQL is executed verbatim at its planned position in the migration.