Schema Compare: Fabric Warehouse platform detection + constraint script preservation#2722
Schema Compare: Fabric Warehouse platform detection + constraint script preservation#2722roramsay wants to merge 4 commits into
Conversation
For Feature 1847587 (Schema Compare for Fabric Warehouse). The vscode-mssql client needs to know which DacFx platform a comparison ran under so it can display the dialect badge in the diff view header (e.g. `SqlDwUnified` for Fabric Warehouse vs. `Sql160` for Azure SQL Database). Today the result has no way to convey this without the client re-walking the DacFx model. Adds `SourcePlatform` and `TargetPlatform` (nullable `string`) to both `SchemaCompareResult` types (`Microsoft.SqlTools.SqlCore` for SSMS direct-call consumers; `Microsoft.SqlTools.ServiceLayer` for the JSON-RPC `schemaCompare/compare` response). Populated from `ComparisonResult.SourceModel.Version.ToString()` and the target equivalent after the comparison runs -- pass-through reads, no new I/O. Null-safe when the comparison didn't produce a model. Wired through `SchemaCompareOperation`: - New `SourcePlatform` / `TargetPlatform` properties on the operation set by `Execute()` from the DacFx `ComparisonResult` models. - `SchemaCompareService` reads these into the JSON-RPC `SchemaCompareResult` it returns to clients. Tests: two new unit tests in `SchemaCompareTests.cs` covering the contract shape (both `SchemaCompareResult` and the operation expose the properties, default to `null`, and accept writes). End-to-end behaviour against live comparisons is covered by integration tests for Feature 1847587. No DacFx API change. No version bump required for this commit. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The public TSqlModel.Version surface maps SqlPlatforms.SqlDwUnified to
SqlServerVersion.Sql150 inside DacFx (InternalModelUtils.CalculateVersionsForPlatform),
so reading .Version.ToString() always returned 'Sql150' for Fabric Warehouse
models and mislabelled the platform pill in Schema Compare.
Read the comparison's normalized DSP from
SchemaComparisonResult.DataModel.DatabaseSchemaProvider.Platform via reflection.
DatabaseSchemaProvider is internal-abstract in DacFx but its .Platform property
returns the public SqlPlatforms enum, whose values map directly to the DSP-name
strings clients expect ('Sql160', 'SqlAzure', 'SqlDwUnified', etc.). Lookups
are cached statically; any reflection failure is logged and falls back to a
null platform string (the pill silently hides).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…diffs CreateDiffEntry stripped any child script that started with `alter` to avoid duplicating constraint DDL that the parent's CREATE TABLE already inlined for legacy SQL Server. SqlDwUnified (Fabric Warehouse) never inlines PK/FK/UNIQUE/ CHECK/DEFAULT constraints into CREATE TABLE; they are always emitted as standalone `ALTER TABLE ... ADD CONSTRAINT ...` statements. The filter therefore discarded the only script that defined the constraint, so the diff editor showed CREATE TABLE without the PK and the generated script was missing the PK definition entirely. Detect constraint children (PK/FK/UNIQUE/CHECK/DEFAULT) under a SqlDwUnified comparison and preserve their scripts in that case. Behavior is unchanged for all other platforms. Move the cached reflection-based platform detector from SchemaCompareOperation into SchemaCompareUtils so CreateDiffEntry can use it; add a ConditionalWeakTable cache keyed by SchemaComparisonResult so the recursive walk pays the reflection cost once per comparison, not once per diff entry. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
@microsoft-github-policy-service agree company="Microsoft" |
…e 1847587) Implements the test design from the Schema Compare for Fabric Warehouse spec (Feature 1847587). Unit tests (SchemaCompareTests.cs): Extracts SchemaCompareUtils.ShouldPreserveAlterScriptForConstraint(typeName, platform) as a pure helper so the SqlDwUnified strip-on-alter carve-out is testable without manufacturing a sealed DacFx SchemaComparisonResult graph. Existing IsConstraintChildOnSqlDwUnified is now a thin wrapper. Adds 18 TestCase rows covering every constraint suffix under SqlDwUnified, non-constraint types under SqlDwUnified, every non-Fabric platform string a comparison can emit (Sql160/Sql150/SqlAzure/SqlAzureV12/SqlDw), null/empty type and platform inputs, substring-vs-suffix guard, and GetComparisonPlatform null-result short-circuit. Integration tests (SchemaCompareFabricTests.cs): Full 4-endpoint-pair x 7-scenario matrix (28 cells) via [TestCaseSource]. Scenarios: AllSupportedTypes, CompatibleAlterColumn, IncompatibleAlterColumn, PrimaryKey, Unique, ForeignKey, SelectionScope. Endpoint pairs: DacpacToDacpac, DacpacToProject, ProjectToDacpac, ProjectToProject. Fabric dacpacs are built offline at fixture setup via new TSqlModel(SqlServerVersion.SqlDwUnified, ...) + DacPackageExtensions.BuildPackage so the suite requires no live Fabric Warehouse. Per-cell assertions (per spec lines 309-316): comparison validity + IsEqual=false + Differences.Any(); SourcePlatform == TargetPlatform == SqlDwUnified; constraints folded under parent SqlTable diff (not surfaced as top-level entries); constraint child carries ADD CONSTRAINT NONCLUSTERED NOT ENFORCED script; selection-scope IncludeOnly(OrdersScope) yields a Generate Script output that references zero unrelated tables or constraints (locks in the Prototype 3 empirical regression that motivated DacFx PR 2143938); project-target round-trip converges to IsEqual after publish. Live Fabric publish (per-cell assertion 7) is intentionally manual-only per the spec; it is exercised by the WSR matrix, not automated here. Fixtures (test/.../SchemaCompare/Fabric/*.sql): 14 minimal T-SQL scripts confined to the Fabric-supported data type list, with all constraints scripted as NONCLUSTERED NOT ENFORCED. Plus emptyFabricTemplate.sqlproj with DSP=SqlDwUnifiedDatabaseSchemaProvider for the Project endpoint cases. Requires DacFx >= 170.5.20 (the published build that ships PR 2143938's cascade fix). The sts-version-bump that flips Packages.props onto that DacFx is a separate change and is not included here. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Added the test scenarios from the spec (Feature 1847587 §Test design) in commit 40f96df: Unit tests ( Integration tests ( Fabric dacpacs are built offline at fixture setup via Per-cell assertions implemented per spec lines 309-316:
Local run: 28/28 Fabric integration tests pass (~17 s) against a locally-built DacFx
|
Three commits on this branch ship the sqltoolsservice changes for Schema Compare
on Microsoft Fabric Warehouse (Feature 1847587):
30d90abe— surfaceSourcePlatform/TargetPlatformon the result contract.23a8ef56— read platform from the comparison''s DSP via cached reflection(TSqlModel.Version returns
Sql150for SqlDwUnified due to an internalDacFx mapping bug — see InternalModelUtils.CalculateVersionsForPlatform).
aa9a0761— keep Fabric Warehouse constraint scripts under table diffs(SqlDwUnified-scoped carve-out in CreateDiffEntry''s
starts-with-alterfilter; behaviour unchanged for every other platform).
Companion PRs:
constraints under SqlDwUnified.
affected-constraints banner.
Spec: https://dev.azure.com/powerbi/Trident/_git/specs-dw/pullrequest/989687
Verified end-to-end against a live Fabric Warehouse + a Fabric .sqlproj:
SqlDwUnifiedon both endpoints.for an Add table with a PK constraint.
CREATE TABLEfollowed bythe standalone
ALTER TABLE ... ADD CONSTRAINT [PK_...] PRIMARY KEY NONCLUSTERED ([col]) NOT ENFORCED;statement.Test gap: a new unit test for
CreateDiffEntry_PreservesConstraintAlterScriptUnderSqlDwUnifiedis in the spec''s test design but not added in this PR — the SchemaCompare
unit-test project (
Microsoft.SqlTools.ServiceLayer.UnitTests) currentlyfails to compile against the DacFx 170.5 overlay (
TSqlModelBuilderremoved inIntelliSense/SqlProjectIntelliSenseTests.cs). The test will be added once
the DacFx package version is officially bumped (gated on PR 2143938).