All versions since 5.0.1
5.0.1
Fixed
- Policy enforcement ignored on apply/destroy. Running a plan or apply will now correctly respect policy enforcement adjustments, so destructive actions can be made allowed.
5.1.0
Changed
Schema.IsImplicitis now part of the provider contract. Each introspector should set it to report the schemas its engine provides. It’s also now recorded in the state payload.
5.2.0
Added
- Type references resolve against the database. A plan now verifies that every type the project references will exist once it applies.
- The type vocabulary is part of the provider contract. An introspector can capture the types the engine and its extensions provide (
NativeType) and record which extension provides an object (ProvidedBy). - Extensions now include their types. A plan that drops an extension now blocks when data still depends on its types.
- Types are a category.
TypeObjectis the common base of everything a type reference can resolve to:EnumType,DomainType,CompositeType, and nowNativeType.
Changed
IsImplicitandProvidedBylive on every database element. An implicit object, like a container-only schema, or a native type, is never created, dropped, managed, or imported, whatever its kind.
Fixed
- Schema-qualified engine types no longer block planning. A reference like
pg_catalog.tsvectoron an imported column previously demanded a declaration nobody could write.
5.3.0
Changed
- A create is a create; a replacement says so. A definition-only change to a routine or view now emits the new
ReplaceRoutine/ReplaceViewactions instead of reusingCreateRoutine/CreateView. - Routines are created after the tables they may reference. Routine actions now order after table creation and before constraints, triggers, and views.
5.4.0
Added
- Aggregates.
CREATE AGGREGATE name(args) (…)is now supported as a kind of routine. - Routine actions include signatures. Routine-based actions now include the routine signature in their arguments for engines that require a signature to drop a routine.
Changed
- Routines are created in dependency order. A routine’s definition is scanned at projection for the objects it references — the tables and views its queries read, and the routines it calls — and creates are ordered so a callee precedes its caller, across schemas. The scan is deliberately shallow and errs wide: a reference only matters when it names an object in the same plan.
Fixed
- Teardown mirrors creation. Routines now drop before the tables they may reference, an aggregate drops before the functions it is assembled from, and a dropped table sheds its triggers explicitly first.
5.5.0
While this is technically a bug fix, it does also make additive changes to the state file in the form of capturing every opaque SQL body twice, one as-written in the project, and again as the database stores it.
Fixed
- Hand-authored definitions now don’t cause drift. For objects that store a provider-specific body (triggers, routines, views, etc.), the state now records both the project-side and database-side definitions for comparisons. Planning does its best to compare the different versions symmetrically, so the two being written differently doesn’t show as drift.
5.6.0
Added
- Models answer their own dependencies.
View.Reads(schema),Routine.References(schema),Column.References(schema),CheckConstraint.References(schema), andTrigger.References(schema)(its function reference plus its scanned body andWHENpredicate). SqlLexer: one lexical layer for engine SQL. A public, tolerant scanner over the amorphous “SQL grammar” — nestable block comments,'…'strings,"…"and[…]identifiers with doubling escapes, etc.
Changed
- The whole migration is linearized from the dependency graph. Action ordering is a priority-respecting topological sort: every create runs after what it requires and every drop before what requires it.
Fixed
- Multi-statement bodies round-trip. A routine definition or view body may now be written as a single dollar-quoted block (
$$ … $$), the same quoting triggers and scripts already use, andimportwrites that form whenever the bare text would not re-parse. A T-SQL body’s top-level;previously ended the statement early, so an imported SQL Server routine could not be read back. - Trailing line comments no longer swallow what follows.
importguards a routine definition or argument list that ends in a--comment, which previously commented out the closing)or;the writer printed on the same line.
5.6.1
Added
- Lockfiles can be updated additively.
LockFile.With(pins)applies a resolution over the existing file, replacing the entry for each source it names and appending the rest, so partial resolutions don’t clobber other pinned versions.
Fixed
- Multi-line doc comments indent correctly. Every line of a
---doc comment on a column or setting now takes the member indent, rather than only the first. - A state payload with no captured schema is rejected. Reading one now fails as an unreadable payload, instead of throwing an NRE.
5.7.0
Added
- Clustered indexes.
TableIndex.Clustered,PrimaryKey.ClusteredandUniqueConstraint.Clusteredrecord whether a relation’s rows are physically ordered by that index, written as T-SQL writes it. - A relation may declare only one clustered index.
multiple-clustered-indexesis an error: a clustered index is the relation’s row order, so a second one has nothing left to order. - Clustering an engine cannot honor is reported rather than dropped.
SqlDialect.SupportsClusteringsays whether the engine has clustered indexes at all. - XML schema collections.
Schema.XmlSchemaCollectionsholds the named XSD bundles a typedxmlcolumn is validated against, written asCREATE XML SCHEMA COLLECTION s.name AS '…'and bound from a column asxml(DOCUMENT s.name). - XML indexes.
TableIndex.Xmlcarries anXmlIndexDefinition— the kind (primary, path, value, property) and, for a secondary, the primary XML index whose node table it reads. Written as SQL Server writes it. - Views declare their schema binding.
View.IsSchemaBoundrecords whether a view is bound to the schema of what it reads, written in NSQL asCREATE VIEW name WITH SCHEMABINDING AS …, the spelling SQL Server uses.
Changed
- An unscoped run stays unscoped. It no longer derives a schema list from the project and the recorded state. What a run may touch is the managed set’s job.
- A view may carry indexes whether or not it is materialized.
CREATE INDEX … ON schema.viewno longer requires the view to be materialized. CreateIndexsays whether its owner is a view. The newOnViewflag rides the action, asIsMaterializeddoes on the view actions.
Fixed
- Objects managed inside an unmanaged schema are no longer stranded. An object can be managed in a schema that is not.
- A comment opening an opaque body survives the round trip. A view body or routine definition whose first line is a comment lost it on re-parse. This is now fixed.
- A view carrying indexes is recreated, not replaced. Indexes hang off a view’s stored form, and SQL Server’s
CREATE OR ALTER VIEWdrops an indexed view’s indexes outright, so redeclaring one in place destroyed them silently. A body or binding change on a view carrying indexes now drops and recreates it, rebuilding the indexes with the definition.
5.8.0
Added
- A plugin may be declared by path.
PLUGIN db ( path = './artifacts/NSchema.Postgres.dll' )names a built assembly instead of a package to resolve, so a provider can be exercised straight fromdotnet buildoutput with no packing, feed or restore.
Changed
LockFile.Resolvetakes aPackageReferencerather than aPluginDeclaration. A plugin declared by path has no version to resolve and no lockfile entry, so it is now unable to reach this rather than guarded inside it.- A
PLUGINstatement with no attributes reports one finding, not two. It used to reportsourceandversionas separately missing; withpathas an alternative neither is required on its own, so it reportsmissing-plugin-origininstead.
5.9.0
Added
RESTRICTis a referential action in its own right.ReferentialAction.Restrictis parsed, written and rendered.SqlDialect.SupportsRestrictsays whether the engine hasRESTRICTas distinct fromNO ACTION. Providers have to opt in.- A generated column records whether it is stored.
Column.IsStoredand the NSQLSTORED/VIRTUALkeywords. SqlDialect.SupportsVirtualGeneratedColumnssays whether the engine can leave one unstored. Off by default, matching Postgres, which stores every generated column.virtual-generated-column-not-supportedis a warning: a virtual generated column declared against an engine that always stores.- A column records whether it is the table’s row identifier for merge replication.
Column.IsRowGuidand the NSQLROWGUIDCOLkeyword. - A column default can carry its constraint’s name.
Column.DefaultConstraintNameand the NSQLCONSTRAINT <name> DEFAULT <expr>form, for engines that make a default a named constraint. - An identity and a trigger can stand aside for a replication agent.
IdentityOptions.NotForReplication,Trigger.IsNotForReplication, and the NSQLNOT FOR REPLICATIONform on both. DiagnosticSourcesdeclares every source the engine reports under, andDiagnosticSources.Alloffers them to a caller checking a configured name against the sources that exist.
Changed
- Diagnostic sources and codes are a configuration contract, so this release settles their naming before the next CLI makes them addressable from
.editorconfig.
Fixed
Trigger.Clone(),EqualsandGetHashCodecover every field, asColumn’s now do. Both enumerate fields by hand, and import clones every object on its way to a file.
5.9.1
Added
- Statements contain their originating action type.
SqlStatement.Actionnames theMigrationActiona statement came from, and is included in the plan file.
Fixed
- Invalid plan files now throw immediately. The JSON held in a plan file is now more strictly deserialized so as to catch an invalid payload earlier.
5.9.2
Fixed
SqlStatementkeeps the constructor providers were built against. 5.9.1 added the action as a positional parameter, which deletes the arity every already-compiled provider calls.
5.9.3
Fixed
- Authored check constraints settle. Check expressions are opaque SQL, rewritten by the engine, so a handwritten constraint would never match. Both definitions are now kept and declared like-for-like as they are for triggers, and routines.
5.10.0
Added
SqlDialect.SupportsCommentssays whether the engine records a comment at all. True unless a dialect says otherwise, which is the opposite of the other capabilities: they describe something extra an engine might do, while this describes something nearly every engine does, so a provider built before the flag has to keep meaning yes.comments-not-supportedis a warning: documentation declared against an engine that records none, naming every object it covers in one finding rather than one per action skipped while rendering.
5.10.1
Fixed
- Every remaining authored expression settles. Column defaults and generated expressions, index and exclusion predicates, and a domain’s checks and default are opaque SQL, rewritten by the engine, so a handwritten one would never match. All are now kept and declared like-for-like as they are for triggers, routines etc. An expression the database no longer reports is still drift, not a spelling to restore.
- Renaming a type no longer retypes the columns declared against it. The rename moved the type but left every reference naming the old one, so each column read as a retype.
- Recreate is now correctly blocked by dependents. Recreating a type that’s in use now causes an error.
5.10.2
Fixed
- An identity that explicitly declares no options no longer differs from one that does so implicitly. No options at all and a set of unstated ones now compare equal.
- A sequence altered for one reason no longer restates the others. The change carries the folded options, so a plan that changes the cache does not also restate a start it never asked to change.
- Identity and sequence restarts now warn correctly. Restarts are data hazards: restarting the counter, means duplicate values are issued, meaning inserts collide with what is already stored.
5.11.0 Latest
Added
- .nsql extension. NSchema files can now be authored from a
.nsqlextension as well as a.sqlextension. - TextMate Grammar. There is a TextMate grammar project in the
grammardirectory in this project that will enable syntax highlighting for.nsqlfiles.
Changed
- Default file extension. The default file extension is now
.nsql.