Skip to content

feat: apply data masks on the full_refresh_build=prebuilt path - #804

Open
Benjamin-Knight wants to merge 1 commit into
dbt-msft:masterfrom
Benjamin-Knight:feat/prebuilt-apply-masks
Open

feat: apply data masks on the full_refresh_build=prebuilt path#804
Benjamin-Knight wants to merge 1 commit into
dbt-msft:masterfrom
Benjamin-Knight:feat/prebuilt-apply-masks

Conversation

@Benjamin-Knight

@Benjamin-Knight Benjamin-Knight commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator

Resolve #805

The prebuilt rebuild path drops and recreates the table but never called apply_masks, so a model configured with both full_refresh_build=prebuilt and masks / masked_with silently lost its masks on every --full-refresh. (Independent feature branches: masking predated prebuilt and never wired that path.)

Apply masks after the load but before create_indexes in the use_prebuilt branch, mirroring the standard build path. Ordering matters on prebuilt: the clustered design (CCI or clustered rowstore index) is built inside create_table_as_prebuilt before masks can be applied, while nonclustered indexes are built afterward by create_indexes. Applying masks before create_indexes lets a mask on a nonclustered key column land before that index exists (mask-then-index). A CCI exposes no key columns so masks apply freely; a mask on a clustered rowstore key column can't be honoured on this path and apply_masks raises its descriptive index-key error.

Add a functional test covering all three cases (CCI maskable, nonclustered key masked before its index, clustered rowstore key errors).

The prebuilt rebuild path drops and recreates the table but never called
apply_masks, so a model configured with both full_refresh_build=prebuilt
and masks / masked_with silently lost its masks on every --full-refresh.
(Independent feature branches: masking predated prebuilt and never wired
that path.)

Apply masks after the load but before create_indexes in the use_prebuilt
branch, mirroring the standard build path. Ordering matters on prebuilt:
the clustered design (CCI or clustered rowstore index) is built inside
create_table_as_prebuilt before masks can be applied, while nonclustered
indexes are built afterward by create_indexes. Applying masks before
create_indexes lets a mask on a nonclustered key column land before that
index exists (mask-then-index). A CCI exposes no key columns so masks
apply freely; a mask on a clustered rowstore key column can't be honoured
on this path and apply_masks raises its descriptive index-key error.

Add a functional test covering all three cases (CCI maskable, nonclustered
key masked before its index, clustered rowstore key errors).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.

full_refresh_build=prebuilt silently drops Dynamic Data Masking on every --full-refresh

1 participant