pub fn bind<'a>(
db: &TabularDatabase,
index: &ModelIndex,
raw: RawRef<'a>,
) -> Binding<'a>Expand description
Resolves one extracted reference against the model.
Resolution rules — deliberately narrower than the DAX side where M’s semantics differ:
- qualified
#"Table"[Name]→ that table and its column — reading a field fromTablerequires theTablequery to exist at refresh — but never a measure fallback: an M expression cannot reference a measure; - unqualified
[Name]and a harvested column string → every column of that name in the model: M string arguments carry no row context, so the conservative direction is to name all candidates; - a bare or quoted name → the table and/or shared expression of that name
(most bare words are
letvariables and resolve to nothing — data).
use ripbi_core::{Column, Measure, ModelIndex, Table, TabularDatabase, m};
let db = TabularDatabase {
tables: vec![
Table {
name: "Sales".to_string(),
columns: vec![Column { name: "Antal".to_string(), ..Default::default() }],
measures: vec![Measure { name: "Antal".to_string(), expression: "0".to_string(), ..Default::default() }],
..Default::default()
},
Table {
name: "Dato".to_string(),
columns: vec![Column { name: "Antal".to_string(), ..Default::default() }],
..Default::default()
},
],
..Default::default()
};
let index = ModelIndex::build(&db);
// A qualified name names the table and its column — no measure fallback.
let raw = m::references(r#"#"Sales"[Antal]"#).remove(0);
assert_eq!(m::bind(&db, &index, raw).targets().len(), 2);
// An unqualified name keeps every candidate alive, on every table.
let raw = m::references("[Antal]").remove(0);
assert_eq!(m::bind(&db, &index, raw).targets().len(), 2);