Unified SCRIPT statement.SCRIPT '<name>' RUN [ALWAYS | ONCE] ON <event> AS $$…$$; is the new canonical form of deployment scripts and data migrations.
The event is a deployment bookend (PRE DEPLOYMENT / POST DEPLOYMENT) or a structural change (ADD COLUMN / ALTER COLUMN TYPE / ADD CONSTRAINT with a target path);
RunCondition on scripts and data migrations, carrying the parsed RUN clause.
The backend state store now carries the recorded script executions.
A RUN ONCE script is recorded on a successful apply and skipped by later plans. A recorded script whose body has since changed stays skipped and warns.
Migrations in schema templates. A MIGRATION block can now be declared inside a TEMPLATE … BEGIN … END; body with an unqualified table.member path; applying the template instantiates the block once per target schema. The {schema} token in the block’s SQL is replaced with each target schema’s name.
Changed
Script names must now be unique across the project (they identify scripts in diagnostics and run-once tracking). A named block declared in a template applied to multiple schemas can include the {schema} token in its name to keep instances distinct.
DdlWriter renders deployment scripts and named data migrations in the SCRIPT form; anonymous migrations keep the legacy spelling.
Deprecated
The PRE|POST DEPLOYMENT '<name>' AS $$…$$; and MIGRATION ['name'] FOR <trigger> <path> AS $$…$$; forms. Both still parse into the same model, and plan/apply/validate now surface a deprecations warning naming the SCRIPT replacement. They will be removed in NSchema 5.0.
Fixed
The formatter no longer re-indents the interior of a dollar-quoted body inside a TEMPLATE block, which grew the indentation on every pass and changed the SQL a routine or migration body carries.