import type { ColumnRef, Projection } from "../ir/ir.js"; import type { SchemaProvider } from "../qualify/schema-provider.js"; import { type ColumnResolution, type ResolvedSource, type Scope } from "../scope/scope.js"; export interface ResolvedColumn { source: ResolvedSource; column: string; /** Struct/map field navigation after the column (`a.b.c` bound to column `a` → ["b","c"]). */ fields: string[]; } /** * Bind a (possibly qualified) column reference to its source, schema-OPTIONAL. * - Qualified (`t.c`, `t.c.field`): the source whose key matches the qualifier, at the nearest * enclosing scope defining it; the part after it is the column, any further parts field navigation. * - Unqualified (`c`, `c.field`): the visible source whose columns include the column, walking * enclosing scopes local-first (correlation). >1 source exposing it → `ambiguous`. * With `schema`, a source's columns come from the catalog (`columnNamesOf` — so a bare column binds * through a schema-fed `SELECT *`), and a lone source whose columns are still unknown owns it; * without `schema`, columns come from the schema-free `sourceOutputs` and an unknown source yields * `needs-schema`. GROUP BY / HAVING / ORDER BY / QUALIFY may fall back to a SELECT-list alias * (source columns win over an alias). Never fabricates a binding. */ export declare function resolveColumnRef(scope: Scope, ref: ColumnRef, schema?: SchemaProvider): ColumnResolution; /** Bind a (possibly qualified) column reference to its source — the `bound` case of the unified binder, * normalized to the (source, column, fields) shape. Schema-aware. Ambiguous / alias / unresolved / * needs-schema all yield `undefined` (never a fabricated binding — ambiguous no longer first-matches). * Thin adapter over `resolveColumnRef`; kept for infer / lineage / nullability / references / qualify's * `bindingOf`, which take `parts` and only ever want the concrete binding. */ export declare function resolveColumnSource(scope: Scope, parts: string[], schema: SchemaProvider): ResolvedColumn | undefined; /** * The projection producing `column` in a derived relation's projection list — the ONE shared * "which projection is this column?" step used by BOTH lineage walks (the flat `derivedOrigins` * origin walk and the per-hop `hops.ts` spine), so they can never drift on producer selection. * With declared column aliases (`WITH c (x, y) AS …`), the alias position picks the projection * (even a `*`, matching the origin walk's `projs[i]` read); otherwise a non-star projection whose * name folds equal. Returns undefined when no projection produces the column (a bare `*`/source). */ export declare function findProducerProjection(projections: Projection[], column: string, aliases: string[] | undefined, dialect: string): Projection | undefined; /** The output column names a source exposes — schema for a table, the (schema-expanded) output * names for a derived relation (column aliases rename them), the AS columns for a lateral view. * `dialect` folds a table's name parts for the catalog lookup (quoted names reach the schema in * raw form); when absent, the default fold (backtick-strip + lower) reproduces legacy behavior. */ export declare function columnNamesOf(src: ResolvedSource, schema: SchemaProvider, visited?: Set, dialect?: string): string[] | undefined; /** A scope's output column names, expanding `*`/`t.*` against the schema (so a `SELECT *` CTE * reports the underlying columns). Returns undefined when a star can't be enumerated or a * projection is anonymous. Cycle-guarded for recursive CTEs. * * `visited` tracks the scopes on the CURRENT resolution PATH (a stack), NOT every scope ever * seen: a scope is added on entry and REMOVED on exit. This still guards a genuine cycle (a * recursive CTE whose scope is on the active path returns undefined), but it must NOT reject a * legitimate re-visit off the path — the same CTE reached by two sibling sources in one `SELECT *` * (a staging CTE reused across a join). Marking `visited` permanently (never deleting) turned that * into a false cycle: the second sibling saw the scope "visited" and returned undefined, poisoning * the whole star expansion to undefined and unbinding bare columns downstream. */ export declare function outputNames(scope: Scope, schema: SchemaProvider, visited?: Set): string[] | undefined;