Skip to content

Fix duplicate clustered index issue when both CreateWithPrimaryKey and UniqueIndexName are set#2160

Merged
jzabroski merged 4 commits into
mainfrom
copilot/fix-2051
Nov 11, 2025
Merged

Fix duplicate clustered index issue when both CreateWithPrimaryKey and UniqueIndexName are set#2160
jzabroski merged 4 commits into
mainfrom
copilot/fix-2051

Conversation

Copilot AI commented Sep 6, 2025

Copy link
Copy Markdown
Contributor

When using a custom IVersionTableMetaData implementation with both CreateWithPrimaryKey = true and UniqueIndexName specified, FluentMigrator would attempt to create two clustered indexes on the same table, causing SQL Server to fail with:

Cannot create more than one clustered index on table 'dbo.IdentityVersionInfo'. 
Drop the existing clustered index 'PK_IdentityVersionInfo' before creating another.

This occurred because:

  1. VersionMigration.Up() creates a clustered primary key when CreateWithPrimaryKey = true
  2. VersionUniqueMigration.Up() unconditionally creates a unique clustered index using UniqueIndexName

The fix modifies VersionUniqueMigration.Up() to create different index types based on the CreateWithPrimaryKey setting:

  • When CreateWithPrimaryKey = false: Creates a clustered unique index
  • When CreateWithPrimaryKey = true: Creates a non-clustered unique index

This approach avoids the clustered index conflict while still maintaining the UniqueIndexName functionality in both scenarios.

Example scenario that now works:

[VersionTableMetaData]
public class IdentityVersionTableMetaData : IVersionTableMetaData
{
    public string TableName => "IdentityVersionInfo";
    public string ColumnName => "Version";
    public string UniqueIndexName => "UC_Version";
    public bool CreateWithPrimaryKey => true; // Creates non-clustered unique index
    // ... other properties
}

The change maintains backward compatibility:

  • When CreateWithPrimaryKey = false and UniqueIndexName is set → creates unique clustered index (existing behavior)
  • When CreateWithPrimaryKey = true and UniqueIndexName is set → creates non-clustered unique index (new behavior)
  • When only one option is used → works as before

Fixes #2051.


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI changed the title [WIP] Issue: Duplicate Clustered Index on Version Table Causes Migration Failure Fix duplicate clustered index issue when both CreateWithPrimaryKey and UniqueIndexName are set Sep 6, 2025
Copilot AI requested a review from jzabroski September 6, 2025 21:45
Comment on lines +144 to +152
if (!_versionTableMeta.CreateWithPrimaryKey)
{
Create.Index(_versionTableMeta.UniqueIndexName)
.OnTable(_versionTableMeta.TableName)
.InSchema(_versionTableMeta.SchemaName)
.WithOptions().Unique()
.WithOptions().Clustered()
.OnColumn(_versionTableMeta.ColumnName);
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

try this idea:

var createIndexBuilder = Create.Index(_versionTableMeta.UniqueIndexName)
  .OnTable(_versionTableMeta.TableName)
  .InSchema(_versionTableMeta.SchemaName);

if (!_versionTableMeta.CreateWithPrimaryKey)
{
  createIndexBuilder
    .WithOptions()
    .Clustered();
}
else
{
  createIndexBuilder
    .WithOptions()
    .NonClustered();
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Implemented your suggestion in commit a9c5b3e. The code now creates a non-clustered unique index when CreateWithPrimaryKey=true instead of skipping the index creation entirely.

@jzabroski

Copy link
Copy Markdown
Collaborator

@copilot Update this PR to help trigger a new GitHub Action workflow for this PR so that we can validate all the tests pass.

Instead of skipping the unique index creation entirely when CreateWithPrimaryKey=true,
now creates a non-clustered unique index. This maintains the UniqueIndexName functionality
while avoiding SQL Server's "Cannot create more than one clustered index" error.

When CreateWithPrimaryKey=false: Creates clustered unique index (existing behavior)
When CreateWithPrimaryKey=true: Creates non-clustered unique index (new behavior)

Co-authored-by: jzabroski <[email protected]>

Copilot AI commented Nov 11, 2025

Copy link
Copy Markdown
Contributor Author

@copilot Update this PR to help trigger a new GitHub Action workflow for this PR so that we can validate all the tests pass.

Updated the PR with new changes in commit a9c5b3e. This should trigger the GitHub Action workflows.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Issue: Duplicate Clustered Index on Version Table Causes Migration Failure

2 participants