Skip to main content

bind

Function bind 

Source
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 from Table requires the Table query 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 let variables 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);