import type { ColumnRef, Projection } from "../ir/ir.js"; import { type ResolvedSource, type Scope, type ScopeTree } from "../scope/scope.js"; import type { Column } from "./schema.js"; import { type SchemaProvider } from "./schema-provider.js"; import { type ResolvedColumn } from "../sema/resolve.js"; export interface Diagnostic { kind: "unknown-table" | "ambiguous-table" | "unknown-column" | "ambiguous-column" | "unknown-field" | "wrong-arity" | "wrong-argument-type"; message: string; /** Start of the offending node: 1-based line, 0-based column. */ line: number; column: number; /** End of the offending node (one past the last char): 1-based line, 0-based column. * Same convention as `Span` in src/symbols/symbols.ts, so rangeFromSpan works on it. */ endLine: number; endColumn: number; } export interface Qualification { diagnostics: Diagnostic[]; /** Resolved output columns of a scope (stars expanded), or "unknown". */ columnsOf(scope: Scope): string[] | "unknown"; /** The column→source binding for a reference AS IT APPEARS in `scope` — the read-only equivalent of * a mutating qualifier rewrite (bare `city` → its `ResolvedSource`, not a rewritten `addr.city`). * Schema-aware: a bare column binds to whichever visible source exposes it, including columns learned * by expanding a source's `SELECT *` against the schema. `undefined` when the reference doesn't bind * to a source (unresolved / bare projection-alias / unknown) — never a fabricated binding. `source` * carries the source kind + base table (the `resolvedTableRef` a consumer needs); `column` is the * resolved name; `fields` is struct navigation after it. Wraps the shared binder `resolveColumnSource` * (src/sema/resolve.ts), so infer / lineage / references and this all agree. */ bindingOf(scope: Scope, ref: ColumnRef): ColumnBinding | undefined; /** The ordered {name, sourceKey} pairs a star projection expands to (star modifiers — EXCLUDE/ * ILIKE/RENAME — already applied), or `undefined` when `projection` isn't a star, or when any * matched source's columns are unknown (never-wrong: no fabricated partial list). `sourceKey` * is the same fold-normalized key `scope.sources` is keyed by (matches `bindingOf`'s `source`). */ expandStarOf(scope: Scope, projection: Projection): { name: string; sourceKey: string; }[] | undefined; /** The columns a single visible source contributes, schema-resolved — or "unknown". * Read-only and idempotent: never emits diagnostics (the expandStarOf double-diagnosis * lesson applies — this rides the same internal `resolved` cache qualify already built). * It never changes any answer either; a lazy CallbackSchema may record misses for a * later prime(), same as every read path. */ columnsOfSource(scope: Scope, src: ResolvedSource): Column[] | "unknown"; } /** The result of `Qualification.bindingOf` — a column reference's resolved source binding. Structurally * the shared `ResolvedColumn` (src/sema/resolve.ts); re-exported under this public name. */ export type ColumnBinding = ResolvedColumn; export declare function qualify(tree: ScopeTree, schema: SchemaProvider): Qualification;