Skip to content

Fix/ma sat v0 inserting non deltas on incremental runs#486

Open
pkumar-data wants to merge 12 commits into
mainfrom
fix/ma_sat_v0_inserting_non_deltas_on_incremental_runs
Open

Fix/ma sat v0 inserting non deltas on incremental runs#486
pkumar-data wants to merge 12 commits into
mainfrom
fix/ma_sat_v0_inserting_non_deltas_on_incremental_runs

Conversation

@pkumar-data

Copy link
Copy Markdown
Contributor

Description

Title: fix: ma_sat_v0 incremental delta logic - all adapters including SQL Server & Trino

Body:

Summary

Fixes the ma_sat_v0 incremental delta failure affecting all database adapters:

  • Re-insertion of non-deltas (loading same data multiple times)
  • Skipping valid deltas (missing changes when values revert within batch)

Root Cause & Solution

Problem: PARTITION BY with |lower caused casing issues; batch reverts weren't detected

Solution:

  1. Removed identifier casing manipulation (|lower)
  2. Added ROW_NUMBER() as rn to track changes within batches
  3. Only compare rn=1 rows against satellite history; keep rn>1 automatically

Adapters Covered

✅ BigQuery, Databricks, Exasol, Fabric, Oracle, Postgres, Redshift, Snowflake, Synapse
✅ SQL Server (newly included)
✅ Trino (newly included)

Status

Branch has been rebased/merged with main to include SQL Server and Trino implementations.
Ready for merge to main.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 updates the ma_sat_v0 incremental delta logic across multiple adapter-specific implementations to prevent re-inserting non-deltas and to correctly retain intra-batch changes (including “revert within batch” scenarios). It does so by removing identifier casing manipulation in window partitions and introducing an rn (row number) to distinguish the first change in a batch from subsequent changes.

Changes:

  • Removed |lower casing manipulation from PARTITION BY in “latest in sat” lookups.
  • Added ROW_NUMBER() (rn) into the source dedupe/change-tracking pipeline.
  • Updated incremental records_to_insert filtering to always keep rn > 1 rows while only comparing the first row per key to existing satellite history.

Reviewed changes

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

Show a summary per file
File Description
macros/tables/bigquery/ma_sat_v0.sql Removes `
macros/tables/databricks/ma_sat_v0.sql Removes `
macros/tables/exasol/ma_sat_v0.sql Removes `
macros/tables/fabric/ma_sat_v0.sql Adds rn and changes incremental insertion predicate logic (Fabric already escapes identifiers).
macros/tables/oracle/ma_sat_v0.sql Removes `
macros/tables/postgres/ma_sat_v0.sql Removes `
macros/tables/redshift/ma_sat_v0.sql Adds rn and changes incremental insertion predicate logic.
macros/tables/snowflake/ma_sat_v0.sql Removes `
macros/tables/synapse/ma_sat_v0.sql Removes `

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

Comment thread macros/tables/bigquery/ma_sat_v0.sql Outdated
Comment thread macros/tables/snowflake/ma_sat_v0.sql Outdated
Comment thread macros/tables/synapse/ma_sat_v0.sql Outdated
Comment thread macros/tables/postgres/ma_sat_v0.sql Outdated
Comment thread macros/tables/redshift/ma_sat_v0.sql Outdated
Comment thread macros/tables/oracle/ma_sat_v0.sql Outdated
Comment thread macros/tables/fabric/ma_sat_v0.sql Outdated
Comment thread macros/tables/exasol/ma_sat_v0.sql Outdated
Comment thread macros/tables/databricks/ma_sat_v0.sql Outdated

@tkiehn tkiehn left a comment

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.

Additionally to the Review from Copilot:

✅ SQL Server (newly included)
✅ Trino (newly included)

Are these adapter already following the new logic? I don't seem them included in this PR.

@tkiehn

tkiehn commented Jul 6, 2026

Copy link
Copy Markdown
Collaborator

Companion regression test: ScalefreeCOM/datavault4dbt-automatic-tests#240

It adds a dedicated multi-batch fixture (ma_sat_v0_05) reproducing the exact scenario this PR fixes — within one incremental load a multi-active group changes and then reverts to the sat's current latest hashdiff (A → B → A across three ascending ldts). Assertions: rsrc='revert' → 2 rows after init, 6 after the delta run (the pre-fix macro drops the reverting group and yields 4); plus a non-delta rsrc='nochange' over-insertion guard (1/1).

Note it exercises the default multi-batch path (source_is_single_batch/disable_hwm left at defaults), which is where the rn logic lives. Two points from reviewing this PR that the test surfaces:

  1. Single-batch + incremental compiles to an invalid reference. records_to_insert hardcodes WHERE deduped_rows.rn > 1 OR ..., but deduped_rows only exists under {% if not source_is_single_batch %}. With source_is_single_batch=true the CTE is absent and source_cte stays source_data, so the incremental run fails (deduped_rows not found). Suggest guarding it, e.g. WHERE {% if not source_is_single_batch %}{{ source_cte }}.rn > 1 OR {% endif %}NOT EXISTS (...). This is already exercised by ma_sat_v0_03 / ma_sat_v0_04 (both source_is_single_batch: true + incremental).
  2. SQL Server and Trino are not actually changed by this PR despite the description marking them ✅ — macros/tables/sqlserver/ma_sat_v0.sql and macros/tables/trino/ma_sat_v0.sql still carry the old WHERE NOT EXISTS (...) with no rn. Either apply the same fix there or adjust the description.

…r/Trino adapters

- Wrap deduped_rows.rn > 1 in if not source_is_single_batch across
  all 9 adapters (bigquery, snowflake, postgres, databricks, exasol, fabric,
  oracle, redshift, synapse) to prevent invalid CTE reference when
  source_is_single_batch=true
- Add ROW_NUMBER() rn column to SQL Server and Trino lag_source_data,
  deduped_row_hashdiff, and deduped_rows CTEs to bring them in line with
  the other adapters
- Apply the same guarded WHERE clause to SQL Server and Trino records_to_insert

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 11 out of 11 changed files in this pull request and generated no new comments.

@tkiehn tkiehn added the waiting-on-maintainers Waiting for a response from the maintainers. label Jul 13, 2026
@tkiehn

tkiehn commented Jul 13, 2026

Copy link
Copy Markdown
Collaborator

…apters

Window functions in latest_entries_in_sat and deduped_row_hashdiff were
partitioned by parent_hashkey only, causing all MA key rows in the same
hashkey group to share a single rn sequence. Rows with rn>1 were always
inserted, bypassing the NOT EXISTS delta check. Fixed by adding
src_ma_key_list to every PARTITION BY so each MA key gets its own
independent row sequence.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 11 out of 11 changed files in this pull request and generated 17 comments.

Comment thread macros/tables/bigquery/ma_sat_v0.sql Outdated
Comment thread macros/tables/snowflake/ma_sat_v0.sql Outdated
Comment thread macros/tables/redshift/ma_sat_v0.sql Outdated
Comment thread macros/tables/exasol/ma_sat_v0.sql
Comment thread macros/tables/databricks/ma_sat_v0.sql Outdated
Comment thread macros/tables/postgres/ma_sat_v0.sql Outdated
Comment thread macros/tables/oracle/ma_sat_v0.sql
Comment thread macros/tables/oracle/ma_sat_v0.sql Outdated
Comment thread macros/tables/fabric/ma_sat_v0.sql
Comment thread macros/tables/fabric/ma_sat_v0.sql Outdated
…in condition

deduped_row_hashdiff (and lag_source_data for subquery adapters) were
partitioned by MA key but did not project those columns into the CTE
output. The join back to source_data on (hashkey, ldts, hashdiff) alone
could multiply rows or assign the wrong rn when multiple MA key rows
share the same ldts and hashdiff. MA key columns are now selected in
deduped_row_hashdiff and included in the join condition across all 11
adapters.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 11 out of 11 changed files in this pull request and generated 10 comments.

Comments suppressed due to low confidence (1)

macros/tables/synapse/ma_sat_v0.sql:140

  • The incremental NOT EXISTS check only compares parent_hashkey + hashdiff, but latest_entries_in_sat is now deduped per (parent_hashkey, src_ma_key). If two different multi-active keys share the same hashdiff, this can incorrectly suppress inserts for one key. Include the MA key column(s) in latest_entries_in_sat and add a multikey(src_ma_key, ...) predicate to this NOT EXISTS filter (and ensure the MA key columns are selected in the latest_entries CTE).
            AND {{ datavault4dbt.multikey(ns.hdiff_alias, prefix=['latest_entries_in_sat', source_cte], condition='=') }}
            )
    {%- endif %}

    )

Comment thread macros/tables/trino/ma_sat_v0.sql
Comment thread macros/tables/sqlserver/ma_sat_v0.sql
Comment thread macros/tables/snowflake/ma_sat_v0.sql
Comment thread macros/tables/redshift/ma_sat_v0.sql
Comment thread macros/tables/postgres/ma_sat_v0.sql
Comment thread macros/tables/oracle/ma_sat_v0.sql
Comment thread macros/tables/exasol/ma_sat_v0.sql
Comment thread macros/tables/databricks/ma_sat_v0.sql
Comment thread macros/tables/fabric/ma_sat_v0.sql
Comment thread macros/tables/bigquery/ma_sat_v0.sql
…S check

Add MA key column(s) to latest_entries_in_sat SELECT (and latest_entries_in_sat_prep
for subquery-based adapters) so the NOT EXISTS deduplication is scoped per
(hashkey, MA key) rather than just per hashkey. Add multikey(src_ma_key, ...)
predicate to the NOT EXISTS WHERE clause across all 11 adapters, preventing
false suppression when two distinct MA keys share the same hashdiff.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 11 out of 11 changed files in this pull request and generated no new comments.

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

Labels

waiting-on-maintainers Waiting for a response from the maintainers.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants