Skip to content

fix(indexes): ensure CCI created on final relation, not __dbt_tmp (#578)#751

Open
mopthe wants to merge 4 commits into
dbt-msft:masterfrom
mopthe:feat/index-refactor
Open

fix(indexes): ensure CCI created on final relation, not __dbt_tmp (#578)#751
mopthe wants to merge 4 commits into
dbt-msft:masterfrom
mopthe:feat/index-refactor

Conversation

@mopthe

@mopthe mopthe commented Jul 20, 2026

Copy link
Copy Markdown

Fixes #578 - Creating nonclustered indexes in a SQL Server materialized table was resulting in an orphaned clustered columnstore index.

The key fix: index names are now derived from the final relation name (with __dbt_tmp / __dbt_backup suffixes stripped). This ensures:

  • A second run produces an identical index name (idempotent)
  • CCIs are not orphaned after intermediate relations are renamed
  • No conflicts when drop_all_indexes_on_table runs

Add comprehensive integration and unit tests covering incremental runs, INCLUDE columns, quoted identifiers, and idempotence.

…t-msft#578)

Add helper macros for index creation: mssql__quote_ident, mssql__qualified_relation, mssql__strip_dbt_suffix, mssql__index_name, and sqlserver__index_exists.

The key fix: index names are now derived from the *final* relation name (with __dbt_tmp / __dbt_backup suffixes stripped). This ensures:
  * A second run produces an identical index name (idempotent)
  * CCIs are not orphaned after intermediate relations are renamed
  * No conflicts when `drop_all_indexes_on_table` runs

Update create_clustered_index and create_nonclustered_index to accept a `relation` parameter and use bracket-quoted, ]]-escaped column names.

Add comprehensive integration and unit tests covering incremental runs,INCLUDE columns, quoted identifiers, and idempotence.
Copilot AI review requested due to automatic review settings July 20, 2026 10: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.

Pull request overview

This PR fixes SQL Server index-macro behavior to prevent “orphaned” clustered columnstore index (CCI) naming during materializations that involve intermediate __dbt_tmp / __dbt_backup relations, by deriving index names from the final relation name and improving identifier quoting. It also adds unit + integration coverage around determinism/idempotence, INCLUDE columns, and quoted identifiers.

Changes:

  • Refactors index macros to use deterministic index naming derived from the final relation identifier (suffix-stripped) and improved quoting.
  • Updates the CCI creation macro to avoid __dbt_tmp / __dbt_backup leaking into the index name.
  • Adds comprehensive unit tests for macro rendering plus live SQL Server integration tests validating idempotence, INCLUDE semantics, quoted identifiers, and the orphaned-CCI regression.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
dbt/include/sqlserver/macros/adapters/indexes.sql Adds quoting/qualification helpers and refactors index/CCI macros to produce deterministic names and safer SQL.
dbt/include/sqlserver/macros/relations/table/create.sql Updates the inline comment to document the new “final relation name” index naming behavior.
tests/unit/adapters/mssql/test_indexes.py Adds Jinja-rendered unit tests for quoting, suffix-stripping, deterministic names, and emitted SQL shapes.
tests/functional/adapter/mssql/test_index_macros.py Adds integration tests against live SQL Server for incremental stability, INCLUDE columns, quoted identifiers, and orphaned-CCI regression.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread tests/unit/adapters/mssql/test_indexes.py Outdated
Comment thread tests/functional/adapter/mssql/test_index_macros.py
Comment thread dbt/include/sqlserver/macros/adapters/indexes.sql
- Escape and quote CCI index name to prevent SQL injection
- Use get_use_database_sql() helper for consistency
- Limit Jinja2 macro patch fixture to module scope
- Remove misleading multi-threaded bullet from comment
@mopthe

mopthe commented Jul 20, 2026

Copy link
Copy Markdown
Author

Migration Note: Orphaned Indexes

This release prevents orphaned CCI indexes from being created on intermediate __dbt_tmp tables across all materializations.

  • table materialization: No action required. The table is fully recreated on each run, so any pre-existing orphaned indexes are dropped automatically.
  • incremental materialization: Orphaned indexes created by prior versions persist and must be cleaned up manually (see below).

Cleaning up orphaned indexes

-- Identify orphaned CCI indexes
SELECT
    name AS index_name,
    OBJECT_SCHEMA_NAME(object_id) AS schema_name,
    OBJECT_NAME(object_id) AS table_name
FROM sys.indexes
WHERE name LIKE '%__dbt_tmp%cci';

-- Drop each one
DROP INDEX [index_name] ON [schema_name].[table_name];

@Benjamin-Knight

Copy link
Copy Markdown
Collaborator

I think you have converted the file endings because the file is showing a huge number of changes and I don't think there are any there, it makes the pull request difficult to parse.

@mopthe
mopthe force-pushed the feat/index-refactor branch 2 times, most recently from 6497d0e to 8a2916f Compare July 20, 2026 12:52
@mopthe

mopthe commented Jul 20, 2026

Copy link
Copy Markdown
Author

@Benjamin-Knight Thanks! Should be readable now.

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.

[Bug] Creating nonclustered indexes in a SQL Server materialized table is resulting in an orphaned clustered columnstore index

3 participants