fix(indexes): ensure CCI created on final relation, not __dbt_tmp (#578)#751
fix(indexes): ensure CCI created on final relation, not __dbt_tmp (#578)#751mopthe wants to merge 5 commits into
Conversation
There was a problem hiding this comment.
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_backupleaking 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.
Migration Note: Orphaned IndexesThis release prevents orphaned CCI indexes from being created on intermediate
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]; |
|
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. |
6497d0e to
8a2916f
Compare
|
@Benjamin-Knight Thanks! Should be readable now. |
c845896 to
f6f601b
Compare
|
After a careful analysis, this is a bug with how Commvault works, we deliberatelly chose to make a swap and avoid building this heavy index while the table is being read, this approach doesnt fix the issue because commvault just uses names to check object ownership, can you warrant it indeed fixes it @mopthe ? |
…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.
for more information, see https://pre-commit.ci
- 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
Head branch was pushed to by a user without write access
f6f601b to
ac9c3e7
Compare
|
The index work I did also means that a certain prefix is required for DBT to consider indexes part of its managed set for that code, and that it could drop codes if you enable the flag that DBT does not think its managing. I believe CCIs are exempt from this but best to check how your changes interact with that code. |
|
@Benjamin-Knight You are right that CCI is exempt by type, not name. Reconciliation checks |
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:
drop_all_indexes_on_tablerunsAdd comprehensive integration and unit tests covering incremental runs, INCLUDE columns, quoted identifiers, and idempotence.