dbt-labs/dbt-core · error

should treat qualified vs unqualified __dbt_tmp in MERGE…

Error message

should treat qualified vs unqualified __dbt_tmp in MERGE USING as equivalent

What it means

Test panic from .expect at crates/dbt-adapter/src/sql/diff.rs:4512: compare_sql(merge_actual, merge_expected, AdapterType::Databricks) returned Err because the USING clause referenced the __dbt_tmp temp table with a three-part qualified name in one SQL and a bare identifier in the other. The differ should canonicalize relation qualification so these compare as equal for Databricks MERGE statements.

Solutions

  1. Inspect the Err to confirm the only divergence is relation qualification depth in USING
  2. Normalize relation names in the canonicalizer: qualify/strip to a common form (e.g. compare by trailing identifier when one side is a temp __dbt_tmp relation)
  3. Ensure this normalization is enabled for AdapterType::Databricks and shared with the view-DDL path (diff.rs:4464)
  4. If qualification differences are semantically meaningful (different relations), fix the SQL generator instead

Example fix

// before
compare_sql(merge_actual, merge_expected, AdapterType::Databricks)
    .expect("should treat qualified vs unqualified __dbt_tmp in MERGE USING as equivalent");
// after (library-side: unify relation qualification before compare)
let norm = |s: &str| unify_relation_qualification(canonicalize(s, AdapterType::Databricks));
assert_eq!(norm(merge_actual), norm(merge_expected));
Defensive patterns

Strategy: validation

Validate before calling

// check qualification depth of the USING relation before diff
let depth_actual = relation_parts(merge_actual).len();
let depth_expected = relation_parts(merge_expected).len();
if depth_actual != depth_expected && relation_name(merge_actual) == relation_name(merge_expected) {
    // pure qualification drift — normalize before comparing
}

Try / catch

compare_sql(merge_actual, merge_expected, AdapterType::Databricks)
    .unwrap_or_else(|e| eprintln!("MERGE USING relation drift: {e}"));

Prevention

When it happens

Trigger: cargo test -p dbt-adapter with the MERGE half of the test at diff.rs:4512: merge_actual uses `catalog.schema.__dbt_tmp` (three-part) in the MERGE USING clause while merge_expected uses just `__dbt_tmp`, and compare_sql under AdapterType::Databricks reports a mismatch, panicking the expect.

Common situations: Fusion qualifies temp relations fully while Mantle emits bare identifiers (or vice versa) in MERGE USING; adapter relation-rendering changes alter qualification depth; MERGE-style incremental models replayed against recorded SQL fail only on the USING relation name.

Related errors


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

Appendix: source

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


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

        compare_sql(merge_actual, merge_expected, AdapterType::Databricks)
            .expect("should treat qualified vs unqualified __dbt_tmp in MERGE USING as equivalent");
    }

    #[test]
    fn test_compare_sql_query_tag_payload_ignored() {
        let actual = r#"    alter session set query_tag = '{""model_name"":""stg_base_orders"",""env"":""PRD"",""job"":{""run_id"":"""",""execution_date"":"""",""start_date"":""""}}'"#;
        let expected = r#"    alter session set query_tag = '{""env"": ""PRD"", ""job"": {""execution_date"": """", ""run_id"": """", ""start_date"": """"}, ""model_name"": ""stg_base_orders""}'"#;
        let result = compare_sql(actual, expected, AdapterType::Snowflake);
        assert!(
            result.is_ok(),
            "Query tag payload differences should be ignored"
        );
    }

    #[test]
    fn test_compare_sql_uuid_literals_ignored() {
        let actual = r#"
INSERT INTO
    PROD_SSAP_AUDIT.ABAC.ABAC_JOB_RUN

View on GitHub (pinned to 0267ce9170)