Skip to content

Do not carry a named default constraint onto the temporal history table - #38875

Open
HuzaifaChaudary wants to merge 1 commit into
dotnet:mainfrom
HuzaifaChaudary:fix/temporal-history-named-default-constraint
Open

Do not carry a named default constraint onto the temporal history table#38875
HuzaifaChaudary wants to merge 1 commit into
dotnet:mainfrom
HuzaifaChaudary:fix/temporal-history-named-default-constraint

Conversation

@HuzaifaChaudary

Copy link
Copy Markdown

Fixes #38836

problem

removing a named default constraint from a property on a temporal table generates a drop against the history table as well, and applying the migration fails:

'DF_MyEntity_Seq' is not a constraint.
Could not drop constraint. See previous errors.

the constraint only ever existed on the current table.

cause

when an AlterColumnOperation runs against a temporal table the generator makes a copy of it for the history table. CopyColumnOperation copies every annotation from the source, so the copy carries Relational:DefaultConstraintName with the current table's constraint name on it.

DropDefaultConstraint then has a name to work with and emits the direct form:

ALTER TABLE [MY_ENTITYHistory] DROP CONSTRAINT [DF_MyEntity_Seq];

which fails, because that constraint is not there.

fix

drop the annotation from the history copy, the same way the identity annotations directly above it are already dropped and for the same reason: it describes something that belongs to the current table only.

with no name to use, DropDefaultConstraint falls through to its other branch, which looks the default up in sys.columns first and does nothing when the column has none. so the history column still gets altered, it just no longer tries to drop a constraint that was never created.

tests

AlterColumnOperation_default_constraint_name_not_propagated_to_history_table in SqlServerMigrationsSqlGeneratorTest, sitting next to the existing AddColumnOperation_identity_not_propagated_to_history_table since it is the same shape of problem.

it is a generator test, so it needs no sql server. on main it fails with

Assert.DoesNotContain() Failure: Sub-string found
Found: "[CustomersHistory] DROP CONSTRAINT [DF_Customers_N"

and passes with the change.

whole SqlServerMigrationsSqlGeneratorTest class: 132 passed, 0 failed.

built with the repo's own sdk via restore.sh, net11.0 on macos arm64.


disclaimer: this contribution was prepared with the assistance of an ai agent. i reproduced the generated sql against main first, reviewed the change, and ran the generator test class locally before opening it.

the history column operation is a copy of the current one and the copy brings
every annotation with it, including the default constraint name. so migrating
away from a named default emitted a drop against the history table for a
constraint that only ever existed on the current one and sql server failed
with error 3728

dropping the name lets the existing lookup path run instead, which checks
sys.columns first and does nothing when there is no default there

the identity annotations right above are removed for the same reason
Copilot AI lite review requested due to automatic review settings August 28, 2026 00:30
@HuzaifaChaudary
HuzaifaChaudary requested a review from a team as a code owner August 28, 2026 00:30

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Named default constraint removal incorrectly targets temporal history table

2 participants