/** * Column-level lineage extractor. * * Parses a DQL block's SQL with `node-sql-parser` to produce a list of * output columns each tagged with the source `table.column` (or columns) * they derive from. Used by the manifest builder to populate the * `outputs[*].lineage` field documented in * manifest-spec/schemas/v1/dql-manifest.schema.json. * * Scope of v1: * - Single-SELECT statements (no UNION / no top-level CTE chains yet). * - Common shapes: `SELECT col`, `SELECT t.col`, `SELECT col AS alias`, * `SELECT SUM(col) AS metric`, `SELECT a + b AS c`. * - Star expansion is reported as a single `*` entry with `unresolved`. * - Anything else (subqueries in select list, complex CASE, * window functions, UNION) parses cleanly but the column entry is * marked `unresolved: true`. The caller falls back to table-level * lineage in that case. * * Phase 2.4 follow-up will expand to CTEs and joins with alias chains. */ export interface ColumnSource { table: string; column: string; } export interface ColumnLineageEntry { /** Output column name; alias when present, else the bare source column. */ name: string; /** True if the column is an aggregate (SUM, COUNT, AVG, MIN, MAX, COUNT(DISTINCT), …). */ isAggregate?: boolean; /** The aggregate function name when isAggregate is true. */ aggregateFn?: string; /** * Source bindings (one per source column the output references). May be * empty when the column is a literal or fully-computed expression. */ sources: ColumnSource[]; /** * True when the entry could not be fully resolved (e.g. star expansion, * subquery, deeply nested CASE). The caller should fall back to * table-level lineage for unresolved entries. */ unresolved?: boolean; } export interface ColumnLineageResult { /** True if SQL parsed AND we extracted at least one column entry. */ parsed: boolean; /** Output columns in the order they appear in the SELECT list. */ columns: ColumnLineageEntry[]; /** Tables resolved from the FROM/JOIN clauses (best-effort, alias-aware). */ tables: string[]; /** Parse-error message when `parsed === false`. */ error?: string; } export declare function extractColumnLineage(sql: string, dialect?: string): ColumnLineageResult; /** * Per-child-block column usage discovered in a parent block's SQL. `block` is * the child block name (the `ref()` argument); `columns` are the child columns * the parent references — qualified (`alias.col`) or, when the parent's only * source is a single `ref()`, unqualified columns too. */ export interface RefColumnUsage { block: string; columns: string[]; } /** * Extract, per `ref()`'d child block, the columns a parent block's SQL * references. Powers output-contract drift detection: each returned column is * checked against the child block's current output schema. * * In DQL, `ref("child")` appears in a FROM/JOIN clause and parses (via * node-sql-parser) as a *function* call — not a `table` node — so the standard * column-lineage table resolver does not see it. This walker special-cases * that shape: it maps each `ref(...)` source to its alias, then attributes * column references back to the child block by alias. Unqualified columns are * attributed only when there is exactly one `ref()` source and no other table * in the FROM clause (so we never guess wrong on joins). * * Conservative by design: anything ambiguous yields no usage rather than a * false-positive drift warning. Returns one entry per distinct child block. */ export declare function extractRefColumnUsage(sql: string, dialect?: string): RefColumnUsage[]; //# sourceMappingURL=column-lineage.d.ts.map