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.

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)

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.