What you see
The symptom looks like wrong aggregation, but the numbers are not being computed wrong: the join is simply not reaching the engine. It surfaces in one of three ways.
- The same total on every group. A matrix of a dimension attribute (for example
gender) against a fact measure (for exampleSum of total_amount_usd) shows the identical grand total on every row, often with an extra blank row. Power BI is reading the measure without the relationship filter. - Or an explicit fold error.
OLE DB or ODBC error: [Expression.Error] We couldn't fold the expression to the data source. Please try a simpler expression.Power BI gave up translating the join to SQL and, in DirectQuery, cannot fall back to in-memory evaluation. - Correct everywhere else. The identical query returns correct per-group values in the DeltaForge SQL editor and through the DeltaForge ODBC connector. Single-table measures and same-table groupings fold fine on ADBC; only the cross-table relationship join is affected.
Why it happens
Power BI builds each model table as its own query, each calling DeltaForgeAdbc.Contents. When a visual joins two of them, the fold optimizer compares the two source nodes, decides they are different data sources, and refuses to emit a single SQL join. The Mashup engine records the exact point of failure in its trace:
VisitJoinCore: The left and right queries come from different data sources.
-> FoldingFailureException
Yet by every signal the connector emits, this is one source. Both tables register with an identical resource path ({"Server":"http://localhost:3000"}), the same driver, and a single credential entry. The split is internal to the ADBC fold path.
The contrast with ODBC is the whole story. The Odbc.DataSource path unifies two tables that share one connection and folds the join. The preview Adbc.DataSource path does not yet unify two same-identity source nodes, and that is the entire difference in behaviour.
The fix: one shared source query
Make both tables flow from a single source node. Then there are not two sources to reconcile, and the relationship join folds. This works today with no driver change.
-
In the Power Query Editor, create a new blank query named
DFand set it to not load (right-click the query and clear Enable load before applying):let Source = DeltaForgeAdbc.Contents("http://localhost:3000") in Source -
Edit each table so its first step references
DFinstead of callingDeltaForgeAdbc.Contentsagain. Keep the existing navigation steps unchanged. For the fact table:let Source = DF, db = Source{[Name="test", Kind="Database"]}[Data], sch = db{[Name="retail", Kind="Schema"]}[Data], tbl = sch{[Name="fact_sales", Kind="Table"]}[Data] in tbl -
Do the same for the dimension table (first step
Source = DF, navigate todim_customer). Apply, confirm the relationship on the join key, and re-run the visual. Both tables now resolve to one source node, so the join folds and per-group values are correct.
Three things keep the pattern intact:
- Reference, do not re-import. Importing tables again through the Navigator always generates a fresh
DeltaForgeAdbc.Contentscall per table, which recreates the two-source condition. The shared-source pattern only holds when you edit the M so each table starts withSource = DF. - Keep
DFas a non-loaded helper. If Power BI prompts to set a storage mode forDF, close the prompt and clear Enable load; do not import it as a table, which would break DirectQuery composition. - Tables stay DirectQuery. The fact and dimension tables remain DirectQuery; only the shared
DFhelper is a non-loaded reference. The fold still happens at query time against the engine.
Alternatives
If restructuring the model is not convenient, two other paths fold the same workload today.
- Use the ODBC connector. The DeltaForge ODBC connector folds the identical star-schema relationship join and returns correct per-group values, because
Odbc.DataSourceunifies tables from one connection. DeltaForge ODBC → - Expose a pre-joined view. Create a view on the server that joins the fact and dimension, then point the ADBC connector at the single view so it only ever folds a single-table grouping, which works on ADBC.
- Single-table measures already fold. Measures that do not cross a relationship fold normally on ADBC, so unaffected pages of a report continue to fold and stream Arrow batches.
Status
This is a limitation of Power BI's current ADBC fold path, which is a preview surface in Power BI Desktop. The DeltaForge ADBC driver and engine are unaffected, and the ODBC connector is a complete workaround.
- Scope
- Affects DirectQuery visuals that fold a relationship join across two ADBC tables. Import mode and single-table folding are not affected.
- Not data correctness
- No wrong value is ever computed by the engine. The join either folds and is correct, or does not fold and surfaces an error or an unfiltered measure. There is no silent miscalculation.
- Forward path
- As Power BI's ADBC path matures, source unification is expected to reach parity with the ODBC path. Until then, the shared-source pattern and the ODBC connector both deliver folded joins.