Mappings and lineage

Mappings persist the declared flow from source tables or columns into local targets. They make design-time lineage, impact analysis, reviews, and reports deterministic without parsing or executing SQL expressions.

A mapping is either table-level or column-level. Its target is always local; inputs may be local, come from a declared library, or come from a sibling model in the same repository. Input order is significant.

Format reference

A declaration writes its target first, followed by source lines, then optional expression, filter, notes, and properties:

mapping customer_email {
  target target warehouse schema analytics table customer_summary column email
  source target warehouse schema raw table customer column email as source_email
  expression "lower(source_email)"
  filter "source_email is not null"
  notes "Normalize the address for matching."
}

Use library <alias> or model "<path>" before target on a source reference. Column mappings may have an opaque expression. Table mappings cannot have an expression. A filter is allowed at either level, and expression and filter strings are stored exactly as written.

Selector syntax

Local selectors are table:<target>.<schema>.<table> and column:<target>.<schema>.<table>.<column>. A dot or percent sign inside a component is percent-escaped.

Resolved external sources prepend their provenance:

  • Local: column:warehouse.raw.customer.email
  • Library: library:common:column:common.public.source_code.code
  • Sibling model: model:sources/customer:table:source.public.customer

CLI roots must be local. External selectors appear in results and are read-only.

Validation and security

Every target and input must exist and all endpoints in one mapping must have the same table or column level. At least one source is required, non-empty aliases are unique, and library aliases must be declared.

Sibling model paths are relative to the containing model. Absolute paths, parent traversal, references back to the same directory, missing directories, and symlinks that escape the Git repository are rejected. Models are parsed as data; expressions and filters are never executed.

CLI

Run:

bluep lineage <dir> <object> [--upstream|--downstream|--both]
  [--level table|column] [--max-depth <n>] [--json]

Direction defaults to both. Level defaults to the selector level. --max-depth accepts 1 through 1000. Text output is intended for people; --json emits canonical version-one JSON.

Web workflow

Open Mappings in the sidebar to create, inspect, replace, or delete a mapping. The form accepts canonical selectors for its target and sources. In team mode, viewing requires the View permission and mutation requires Edit plus the current base fingerprint.

Open Lineage, choose table or column level and a direction, then query a local selector. Selecting a local result navigates to the model object. Library and sibling-model results display their source provenance and remain read-only.

Reports

The built-in report family is lineage.html, lineage.csv, lineage.md, lineage.txt, lineage.xlsx, and lineage.pdf. Supply selector=<local-selector>; optional direction and level use the CLI spellings. Tabular formats use the columns Direction, Depth, Object, and Mapping.

RPC

Call lineage.run after opening a model. Parameters are selector, with optional direction, level, and max_depth. The result is the same canonical JSON value produced by a direct lineage query. model.list accepts mappings, and model.get accepts a mapping/<name> selector.

Git diff, merge and review

Mappings are named model objects in canonical JSON. Logical diff reports mapping additions, removals, and changes after relationships. Three-way merge treats mappings by name while preserving the ordered inputs array; conflicting edits identify the exact mapping field. Review change IDs use logical:mapping:<name>, and mapping review anchors navigate back to the declaration.

Mapping edges also join source objects to targets in downstream impact analysis with reason mapping <name>. Unchanged models with no mappings retain their previous text and JSON bytes.

Limitations

Lineage is declared design-time lineage only. It does not parse SQL, evaluate expressions, move data, inspect runtime query plans, infer mappings, access remote repositories, edit external objects, or add mapping-specific diagram layout.