/** * Statement-level dependency graph over classified SQL. * * {@link classifyStatements} reduces each top-level statement to * {@link StatementFacts} — what it creates, what it references, which of * those references live only inside PL/pgSQL bodies. This module turns a * sequence of facts into a typed dependency graph and computes the orderings * the granularity passes (consolidate / atomize) need: * * - **typed edges**: `hard` edges (the referenced object must exist at * CREATE time), `fk` edges (foreign-key targets — hard, but singled out * because they are the edges FK inlining must respect), and `late` edges * (PL/pgSQL body references, resolved at call time — they never constrain * deploy order and may legitimately form cycles). * - **SCC condensation**: strongly connected components over hard+fk edges. * A well-formed DDL script condenses to singleton components; any larger * component is a genuine ordering cycle (e.g. mutually referencing FKs) * that granularity passes must leave in atomic form. * - **topological order** of the condensation, stable with respect to the * original statement order (ties keep source order), so re-emission is * deterministic and minimally surprising. */ import { QualifiedName, StatementFacts } from './facts'; /** * How a dependency edge constrains ordering. * * - `hard` — name must resolve when the dependent statement executes. * - `fk` — a hard edge arising from a foreign-key target; distinguished so * folding passes can decide whether an FK may be inlined into its table. * - `late` — reached only inside a PL/pgSQL body; resolved at call time, * so it does not constrain deploy order. */ export type EdgeKind = 'hard' | 'fk' | 'late'; /** A directed dependency: statement `from` depends on statement `to`. */ export interface StatementEdge { from: number; to: number; kind: EdgeKind; /** The referenced object that induced this edge. */ via: QualifiedName; } /** A node in the statement graph: one top-level statement. */ export interface StatementNode { /** Index of the statement in the classified script. */ index: number; facts: StatementFacts; /** Outgoing edges (this statement's dependencies). */ out: StatementEdge[]; /** Incoming edges (statements that depend on this one). */ in: StatementEdge[]; } /** The statement-level dependency graph for one SQL script. */ export interface StatementGraph { nodes: StatementNode[]; edges: StatementEdge[]; /** * `schema.name` → indices of the statements that create that object. * Trigger and policy names are table-qualified (`table.trigger`), matching * {@link StatementFacts.creates}. */ producers: Map; /** * Strongly connected components over `hard` + `fk` edges, in topological * order of the condensation. Singleton components are the common case; * larger ones are genuine DDL ordering cycles. */ components: number[][]; /** * A stable topological order of all statements: components in condensation * order, members of a component in source order. Ties between independent * components keep source order. */ order: number[]; } /** * Build the typed statement dependency graph for a classified script. * * Edges only exist between statements of the same script: a reference with * no in-script producer is an external dependency and induces no edge (the * caller decides what to do with those — pgpm expresses them as * cross-package requires). */ export declare function buildStatementGraph(facts: StatementFacts[]): StatementGraph;