dbt-labs/dbt-core · error

should treat persisted view vs temp view as equivalent

Error message

should treat persisted view vs temp view as equivalent

What it means

Test panic from .expect at crates/dbt-adapter/src/sql/diff.rs:4464: compare_sql(actual, expected, AdapterType::Databricks) returned Err because a persisted view reference and its __dbt_tmp temp-view equivalent were not canonicalized to the same shape. The differ must treat dbt's temp-relation naming/qualification variants (__dbt_tmp) as equivalent so Mantle-generated and recorded Fusion SQL match for Databricks DDL and MERGE statements.

Solutions

  1. Read the Err detail to see the exact relation names that failed to unify
  2. Extend the Databricks canonicalizer to strip/normalize __dbt_tmp suffixes and unify two-part vs three-part relation names
  3. Check whether relation-name normalization is adapter-gated and missing for AdapterType::Databricks
  4. Also cover the MERGE USING variant (diff.rs:4512) since it shares the same normalization path

Example fix

// before
compare_sql(actual, expected, AdapterType::Databricks)
    .expect("should treat persisted view vs temp view as equivalent");
// after (library-side: normalize temp relation names before compare)
let norm = |s: &str| unify_temp_relations(canonicalize(s, AdapterType::Databricks));
assert_eq!(norm(actual), norm(expected));
Defensive patterns

Strategy: validation

Validate before calling

// normalize temp relation names before diffing Databricks SQL
fn normalize_temp_rels(sql: &str) -> String {
    Regex::new(r"([\w`]+\.)+[\w`]*__dbt_tmp\b").unwrap()
        .replace_all(sql, "__dbt_tmp").to_string()
}
assert_eq!(normalize_temp_rels(actual), normalize_temp_rels(expected));

Try / catch

compare_sql(&normalize_temp_rels(actual), &normalize_temp_rels(expected), AdapterType::Databricks)
    .unwrap_or_else(|e| eprintln!("temp-view drift: {e}"));

Prevention

When it happens

Trigger: cargo test -p dbt-adapter with test at diff.rs:4464: a Databricks query selecting from dummy_cte with a persisted-view vs temp-view (__dbt_tmp) qualified-name difference, and compare_sql(actual, expected, AdapterType::Databricks) yields Err, panicking "should treat persisted view vs temp view as equivalent".

Common situations: dbt creates a __dbt_tmp view before swapping in the persisted relation; replayed recorded SQL references the final name while newly generated SQL references __dbt_tmp (or vice versa); adapter changes to relation-name rendering for Databricks (catalog/schema qualification) break the equivalence normalization.

Related errors


AI-assisted analysis of dbt-labs/dbt-core@0267ce9170 (2026-09-07). Data as JSON: /api/errors/ae4cdf83145291b2. Report an issue: GitHub.

Appendix: source

Thrown at crates/dbt-adapter/src/sql/diff.rs:4464

with dummy_cte as (select 1 as foo)
select
    cast(null as string) as command_invocation_id
from dummy_cte
where 1 = 0
"#;

        let expected = r#"
create or replace temporary view `sources__dbt_tmp` as
/* Bigquery won't let us `where` without `from` so we use this workaround */
with dummy_cte as (select 1 as foo)
select
    cast(null as string) as command_invocation_id
from dummy_cte
where 1 = 0
"#;

        compare_sql(actual, expected, AdapterType::Databricks)
            .expect("should treat persisted view vs temp view as equivalent");

        // Same pattern but in a MERGE statement: Fusion uses a three-part qualified name for the
        // __dbt_tmp temp table in the USING clause, while Mantle uses just the identifier.
        let merge_actual = r#"
-- back compat for old kwarg name



    merge
    into
        `dbt`.`dbt_dbt_audit`.`seed_executions` as DBT_INTERNAL_DEST
    using
        `dbt`.`dbt_dbt_audit`.`seed_executions__dbt_tmp` as DBT_INTERNAL_SOURCE
    on
        FALSE
    when matched
        then update set
            *

View on GitHub (pinned to 0267ce9170)