fix(fabric): support elementary schema in a different DB than target#1009
fix(fabric): support elementary schema in a different DB than target#1009tderk wants to merge 1 commit into
Conversation
📝 WalkthroughWalkthroughThe ChangesTest Result Sampling View Database Context
🎯 2 (Simple) | ⏱️ ~10 minutes
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
👋 @tderk |
When the elementary schema lives in a different database than
target.database on dbt-fabric / Fabric DW, the CREATE VIEW issued by
fabric__query_test_result_rows uses a 2-part name (schema.view) and
lands in the connection's current DB (= target.database). If the
elementary schema does not exist there, the statement fails with:
('42000', '[42000] [Microsoft][ODBC Driver 18 for SQL Server][SQL Server]
The specified schema name "<elementary_schema>" either does not exist
or you do not have permission to use it. (2760)')
Fabric/T-SQL constraints prevent both a 3-part qualified CREATE VIEW
(error 166) and `USE [db]; CREATE VIEW ...` in a single batch (error
111). Dispatching the DDL via `EXEC [db]..sp_executesql N'...'` executes
it in the target database's context with a 2-part name and no
session-DB leak across run_query calls.
The SELECT against the helper view stays 3-part qualified, which Fabric
already accepts.
03ee80a to
997c89e
Compare
There was a problem hiding this comment.
🧹 Nitpick comments (1)
macros/edr/materializations/test/test.sql (1)
276-290: ⚡ Quick winPersist the sampling view for deferred cleanup.
If Line 285 fails after the
CREATE VIEWon Line 278 succeeds, theDROP VIEWon Line 290 is never reached, soedr_test_sample_*can be left behind in the elementary schema. Please register this helper view in the same Fabric cleanup path used for other temp relations before issuing the sampling query.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@macros/edr/materializations/test/test.sql` around lines 276 - 290, The CREATE VIEW performed via create_stmt (which builds create_inner) can succeed while the later sampling query fails, leaving edr_test_sample_* behind; after running run_query(create_stmt) register the created short_view_name with the same Fabric/elementary cleanup mechanism used elsewhere (e.g., add the view name to the temp-relations cleanup list or call the project's register_temp_relation helper) before executing the sampling query that uses qualified_view_name and elementary.run_query/elementary.agate_to_dicts; then keep the existing drop_inner/drop_stmt as a best-effort immediate cleanup so the view is both registered for deferred cleanup and also dropped if possible.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@macros/edr/materializations/test/test.sql`:
- Around line 276-290: The CREATE VIEW performed via create_stmt (which builds
create_inner) can succeed while the later sampling query fails, leaving
edr_test_sample_* behind; after running run_query(create_stmt) register the
created short_view_name with the same Fabric/elementary cleanup mechanism used
elsewhere (e.g., add the view name to the temp-relations cleanup list or call
the project's register_temp_relation helper) before executing the sampling query
that uses qualified_view_name and
elementary.run_query/elementary.agate_to_dicts; then keep the existing
drop_inner/drop_stmt as a best-effort immediate cleanup so the view is both
registered for deferred cleanup and also dropped if possible.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 077a21d3-3694-40c8-802f-b0663fd73e9d
📒 Files selected for processing (1)
macros/edr/materializations/test/test.sql
Summary
When the elementary schema lives in a different database than
target.databaseon dbt-fabric / Fabric DW, theCREATE VIEWissued byfabric__query_test_result_rowsuses a 2-part name (schema.view) and lands in the connection's current DB (=target.database). If the elementary schema does not exist there, the statement fails with:Root cause
The compiled test SQL passed into
CREATE VIEW … AS …references the source table via dbt's Relation API, which produces a 3-part qualified name. The target view, however, is only 2-part qualified, so the target side assumes the connection's current DB matches the elementary database. That assumption breaks when the two DBs differ.Why the obvious fixes don't work on Fabric
CREATE VIEWis rejected (error 166: 'CREATE/ALTER VIEW' does not allow specifying the database name as a prefix to the object name).USE [db]; CREATE VIEW …in a single batch is rejected (error 111: 'CREATE VIEW' must be the first statement in a query batch).Fix
Dispatch the
CREATE VIEW/DROP VIEW IF EXISTSviaEXEC [db]..sp_executesql N'...'.sp_executesqlinvoked with a database prefix executes in that database's context, so the view is created with a 2-part name inside the elementary database. TheSELECTagainst the helper view stays 3-part qualified (Fabric already accepts that).No session DB state is mutated, so this is safe under dbt-fabric's threadsafe connection model.
Test plan
dbt teston Fabric DW with elementary schema in a separate DB fromtarget.database— passes (was failing with 2760)dbt teston Fabric DW with elementary schema in the same DB astarget.database— no regressiondbt teston dbt-sqlserver (inheritsfabric__via dispatch) — not verified locally, behaviour identical at SQL levelSummary by CodeRabbit
Bug Fixes