@pgsql/transform 18.8.0 → 18.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm/graph.js +184 -0
- package/esm/index.js +3 -0
- package/esm/naming.js +65 -0
- package/esm/restructure.js +327 -0
- package/graph.d.ts +83 -0
- package/graph.js +187 -0
- package/index.d.ts +6 -0
- package/index.js +8 -1
- package/naming.d.ts +43 -0
- package/naming.js +68 -0
- package/package.json +2 -2
- package/restructure.d.ts +29 -0
- package/restructure.js +331 -0
package/graph.js
ADDED
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildStatementGraph = buildStatementGraph;
|
|
4
|
+
const keyOf = (q) => `${q.schema ?? ''}.${q.name}`;
|
|
5
|
+
/**
|
|
6
|
+
* Build the typed statement dependency graph for a classified script.
|
|
7
|
+
*
|
|
8
|
+
* Edges only exist between statements of the same script: a reference with
|
|
9
|
+
* no in-script producer is an external dependency and induces no edge (the
|
|
10
|
+
* caller decides what to do with those — pgpm expresses them as
|
|
11
|
+
* cross-package requires).
|
|
12
|
+
*/
|
|
13
|
+
function buildStatementGraph(facts) {
|
|
14
|
+
const nodes = facts.map((f, index) => ({
|
|
15
|
+
index,
|
|
16
|
+
facts: f,
|
|
17
|
+
out: [],
|
|
18
|
+
in: []
|
|
19
|
+
}));
|
|
20
|
+
const producers = new Map();
|
|
21
|
+
facts.forEach((f, i) => {
|
|
22
|
+
for (const created of f.creates) {
|
|
23
|
+
const key = keyOf(created);
|
|
24
|
+
const list = producers.get(key) ?? [];
|
|
25
|
+
list.push(i);
|
|
26
|
+
producers.set(key, list);
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
// The producer a reference binds to is the closest preceding statement
|
|
30
|
+
// that creates the object (redefinitions shadow earlier ones); when the
|
|
31
|
+
// reference precedes every producer, it binds to the first one — that is
|
|
32
|
+
// exactly the forward edge a reordering pass must satisfy.
|
|
33
|
+
const bind = (ref, from) => {
|
|
34
|
+
const list = producers.get(keyOf(ref));
|
|
35
|
+
if (!list || list.length === 0)
|
|
36
|
+
return undefined;
|
|
37
|
+
let found;
|
|
38
|
+
for (const i of list) {
|
|
39
|
+
if (i === from)
|
|
40
|
+
return undefined; // self-dependency: never an edge
|
|
41
|
+
if (i < from)
|
|
42
|
+
found = i;
|
|
43
|
+
}
|
|
44
|
+
return found ?? list[0];
|
|
45
|
+
};
|
|
46
|
+
const edges = [];
|
|
47
|
+
const addEdge = (from, to, kind, via) => {
|
|
48
|
+
if (edges.some(e => e.from === from && e.to === to && e.kind === kind))
|
|
49
|
+
return;
|
|
50
|
+
const edge = { from, to, kind, via };
|
|
51
|
+
edges.push(edge);
|
|
52
|
+
nodes[from].out.push(edge);
|
|
53
|
+
nodes[to].in.push(edge);
|
|
54
|
+
};
|
|
55
|
+
facts.forEach((f, i) => {
|
|
56
|
+
const bodyOnly = new Set(f.bodyReferences.map(keyOf));
|
|
57
|
+
const fkKeys = new Set(f.fkTargets.map(keyOf));
|
|
58
|
+
for (const ref of f.references) {
|
|
59
|
+
const to = bind(ref, i);
|
|
60
|
+
if (to === undefined)
|
|
61
|
+
continue;
|
|
62
|
+
const key = keyOf(ref);
|
|
63
|
+
const kind = fkKeys.has(key) ? 'fk' : bodyOnly.has(key) ? 'late' : 'hard';
|
|
64
|
+
addEdge(i, to, kind, ref);
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
const components = condense(nodes);
|
|
68
|
+
const order = stableTopoOrder(nodes, components);
|
|
69
|
+
return { nodes, edges, producers, components, order };
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Tarjan SCC over `hard` + `fk` edges (`late` edges are ignored — they are
|
|
73
|
+
* call-time bindings and legitimately cyclic). Components are returned in
|
|
74
|
+
* reverse-topological completion order and then re-sorted topologically with
|
|
75
|
+
* source-order tie-breaking by {@link stableTopoOrder}; here we only sort
|
|
76
|
+
* each component's members and order components by their smallest member so
|
|
77
|
+
* output is deterministic.
|
|
78
|
+
*/
|
|
79
|
+
function condense(nodes) {
|
|
80
|
+
const n = nodes.length;
|
|
81
|
+
const indexOf = new Array(n).fill(-1);
|
|
82
|
+
const low = new Array(n).fill(0);
|
|
83
|
+
const onStack = new Array(n).fill(false);
|
|
84
|
+
const stack = [];
|
|
85
|
+
const components = [];
|
|
86
|
+
let counter = 0;
|
|
87
|
+
const orderingEdges = (v) => nodes[v].out.filter(e => e.kind !== 'late').map(e => e.to);
|
|
88
|
+
// Iterative Tarjan (DDL scripts can be tens of thousands of statements).
|
|
89
|
+
const visit = (root) => {
|
|
90
|
+
const frames = [{ v: root, edges: orderingEdges(root), i: 0 }];
|
|
91
|
+
indexOf[root] = low[root] = counter++;
|
|
92
|
+
stack.push(root);
|
|
93
|
+
onStack[root] = true;
|
|
94
|
+
while (frames.length > 0) {
|
|
95
|
+
const frame = frames[frames.length - 1];
|
|
96
|
+
if (frame.i < frame.edges.length) {
|
|
97
|
+
const w = frame.edges[frame.i++];
|
|
98
|
+
if (indexOf[w] === -1) {
|
|
99
|
+
indexOf[w] = low[w] = counter++;
|
|
100
|
+
stack.push(w);
|
|
101
|
+
onStack[w] = true;
|
|
102
|
+
frames.push({ v: w, edges: orderingEdges(w), i: 0 });
|
|
103
|
+
}
|
|
104
|
+
else if (onStack[w]) {
|
|
105
|
+
low[frame.v] = Math.min(low[frame.v], indexOf[w]);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
frames.pop();
|
|
110
|
+
if (frames.length > 0) {
|
|
111
|
+
const parent = frames[frames.length - 1];
|
|
112
|
+
low[parent.v] = Math.min(low[parent.v], low[frame.v]);
|
|
113
|
+
}
|
|
114
|
+
if (low[frame.v] === indexOf[frame.v]) {
|
|
115
|
+
const component = [];
|
|
116
|
+
for (;;) {
|
|
117
|
+
const w = stack.pop();
|
|
118
|
+
onStack[w] = false;
|
|
119
|
+
component.push(w);
|
|
120
|
+
if (w === frame.v)
|
|
121
|
+
break;
|
|
122
|
+
}
|
|
123
|
+
component.sort((a, b) => a - b);
|
|
124
|
+
components.push(component);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
for (let v = 0; v < n; v++) {
|
|
130
|
+
if (indexOf[v] === -1)
|
|
131
|
+
visit(v);
|
|
132
|
+
}
|
|
133
|
+
components.sort((a, b) => a[0] - b[0]);
|
|
134
|
+
return components;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Topologically order the condensation with source order breaking ties
|
|
138
|
+
* (Kahn's algorithm over components, min-heap on smallest member index),
|
|
139
|
+
* then flatten: members of each component stay in source order.
|
|
140
|
+
*/
|
|
141
|
+
function stableTopoOrder(nodes, components) {
|
|
142
|
+
const componentOf = new Array(nodes.length).fill(0);
|
|
143
|
+
components.forEach((members, c) => {
|
|
144
|
+
for (const m of members)
|
|
145
|
+
componentOf[m] = c;
|
|
146
|
+
});
|
|
147
|
+
const succ = components.map(() => new Set());
|
|
148
|
+
const indegree = new Array(components.length).fill(0);
|
|
149
|
+
for (const node of nodes) {
|
|
150
|
+
for (const e of node.out) {
|
|
151
|
+
if (e.kind === 'late')
|
|
152
|
+
continue;
|
|
153
|
+
const from = componentOf[e.from];
|
|
154
|
+
const to = componentOf[e.to];
|
|
155
|
+
if (from === to)
|
|
156
|
+
continue;
|
|
157
|
+
// Dependency edge from → to means `to` must come first.
|
|
158
|
+
if (!succ[to].has(from)) {
|
|
159
|
+
succ[to].add(from);
|
|
160
|
+
indegree[from]++;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
const ready = [];
|
|
165
|
+
for (let c = 0; c < components.length; c++) {
|
|
166
|
+
if (indegree[c] === 0)
|
|
167
|
+
ready.push(c);
|
|
168
|
+
}
|
|
169
|
+
const takeMin = () => {
|
|
170
|
+
let best = 0;
|
|
171
|
+
for (let i = 1; i < ready.length; i++) {
|
|
172
|
+
if (components[ready[i]][0] < components[ready[best]][0])
|
|
173
|
+
best = i;
|
|
174
|
+
}
|
|
175
|
+
return ready.splice(best, 1)[0];
|
|
176
|
+
};
|
|
177
|
+
const order = [];
|
|
178
|
+
while (ready.length > 0) {
|
|
179
|
+
const c = takeMin();
|
|
180
|
+
order.push(...components[c]);
|
|
181
|
+
for (const next of succ[c]) {
|
|
182
|
+
if (--indegree[next] === 0)
|
|
183
|
+
ready.push(next);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
return order;
|
|
187
|
+
}
|
package/index.d.ts
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
export type { ExtensionAction, ExtensionFact, QualifiedName, StatementFacts, StatementKind, } from './facts';
|
|
2
2
|
export { classifyStatements } from './facts';
|
|
3
|
+
export type { EdgeKind, StatementEdge, StatementGraph, StatementNode, } from './graph';
|
|
4
|
+
export { buildStatementGraph } from './graph';
|
|
5
|
+
export type { ObjectIdentity, ObjectIdentityKind, } from './naming';
|
|
6
|
+
export { identityOf } from './naming';
|
|
7
|
+
export type { Granularity, RestructureOptions, RestructureResult, } from './restructure';
|
|
8
|
+
export { orderStatements, restructureSql } from './restructure';
|
|
3
9
|
export type { ExtensionDefinition, ExtensionRoute, ExtensionRouteSpec, ExtensionRouterOptions, ExtensionSymbol, ExtensionSymbolNamespace, SymbolRewrite, } from './extension-router';
|
|
4
10
|
export { COMMON_EXTENSIONS, ExtensionRouter } from './extension-router';
|
|
5
11
|
export type { ExtensionTransformResult } from './extension-transform';
|
package/index.js
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.walkPlpgsqlForSchemas = exports.validateNoUntransformedSchemas = exports.transformVerifyCalls = exports.transformSqlStatement = exports.transformSql = exports.transformSchemaName = exports.transformRelation = exports.transformPlpgsqlTypeString = exports.transformPlpgsqlTypeAst = exports.transformNameList = exports.transformJsonStringValues = exports.transformComments = exports.shouldTransformSchema = exports.extractPgpmHeader = exports.escapeRegexp = exports.createSqlVisitor = exports.createPlpgsqlVisitor = exports.trimDefElemBody = exports.normalizeTree = exports.cleanTree = exports.CLEAN_TREE_VOLATILE_KEYS = exports.validateRoundTrip = exports.normalizeParseTree = exports.firstDifference = exports.captureTransformAsts = exports.captureAstsFromSql = exports.SchemaRouter = exports.qualifyUnqualified = exports.mergeInventories = exports.createQualifyVisitor = exports.collectCreatedObjects = exports.transformRoles = exports.createRoleVisitor = exports.createRoleResult = exports.RoleRouter = exports.transformExtensions = exports.createExtensionVisitor = exports.createExtensionResult = exports.ExtensionRouter = exports.COMMON_EXTENSIONS = exports.classifyStatements = void 0;
|
|
3
|
+
exports.walkPlpgsqlForSchemas = exports.validateNoUntransformedSchemas = exports.transformVerifyCalls = exports.transformSqlStatement = exports.transformSql = exports.transformSchemaName = exports.transformRelation = exports.transformPlpgsqlTypeString = exports.transformPlpgsqlTypeAst = exports.transformNameList = exports.transformJsonStringValues = exports.transformComments = exports.shouldTransformSchema = exports.extractPgpmHeader = exports.escapeRegexp = exports.createSqlVisitor = exports.createPlpgsqlVisitor = exports.trimDefElemBody = exports.normalizeTree = exports.cleanTree = exports.CLEAN_TREE_VOLATILE_KEYS = exports.validateRoundTrip = exports.normalizeParseTree = exports.firstDifference = exports.captureTransformAsts = exports.captureAstsFromSql = exports.SchemaRouter = exports.qualifyUnqualified = exports.mergeInventories = exports.createQualifyVisitor = exports.collectCreatedObjects = exports.transformRoles = exports.createRoleVisitor = exports.createRoleResult = exports.RoleRouter = exports.transformExtensions = exports.createExtensionVisitor = exports.createExtensionResult = exports.ExtensionRouter = exports.COMMON_EXTENSIONS = exports.restructureSql = exports.orderStatements = exports.identityOf = exports.buildStatementGraph = exports.classifyStatements = void 0;
|
|
4
4
|
var facts_1 = require("./facts");
|
|
5
5
|
Object.defineProperty(exports, "classifyStatements", { enumerable: true, get: function () { return facts_1.classifyStatements; } });
|
|
6
|
+
var graph_1 = require("./graph");
|
|
7
|
+
Object.defineProperty(exports, "buildStatementGraph", { enumerable: true, get: function () { return graph_1.buildStatementGraph; } });
|
|
8
|
+
var naming_1 = require("./naming");
|
|
9
|
+
Object.defineProperty(exports, "identityOf", { enumerable: true, get: function () { return naming_1.identityOf; } });
|
|
10
|
+
var restructure_1 = require("./restructure");
|
|
11
|
+
Object.defineProperty(exports, "orderStatements", { enumerable: true, get: function () { return restructure_1.orderStatements; } });
|
|
12
|
+
Object.defineProperty(exports, "restructureSql", { enumerable: true, get: function () { return restructure_1.restructureSql; } });
|
|
6
13
|
var extension_router_1 = require("./extension-router");
|
|
7
14
|
Object.defineProperty(exports, "COMMON_EXTENSIONS", { enumerable: true, get: function () { return extension_router_1.COMMON_EXTENSIONS; } });
|
|
8
15
|
Object.defineProperty(exports, "ExtensionRouter", { enumerable: true, get: function () { return extension_router_1.ExtensionRouter; } });
|
package/naming.d.ts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Object identity — the canonical, Postgres-native answer to "what object is
|
|
3
|
+
* this statement about?".
|
|
4
|
+
*
|
|
5
|
+
* Identity is the key used by dependency graphs, semantic diffing, and any
|
|
6
|
+
* downstream naming scheme. It is a pure function of classifier facts —
|
|
7
|
+
* grounded in the parser's node taxonomy (`CreateStmt`, `CreateTrigStmt`,
|
|
8
|
+
* `IndexStmt`, ...), never in surface syntax like RangeVars. Rendering an
|
|
9
|
+
* identity to a change path (e.g. a pgpm module layout) is deliberately NOT
|
|
10
|
+
* defined here: paths are derived projections that belong to whichever
|
|
11
|
+
* packaging layer consumes the identity, so nothing is ever attached to them.
|
|
12
|
+
*
|
|
13
|
+
* Identity tuple: `(kind, schema, name, table?)` — `table` scopes objects
|
|
14
|
+
* that are only unique per table (triggers, policies, indexes, constraints,
|
|
15
|
+
* seed data). Function overloads share an identity for now (signature
|
|
16
|
+
* disambiguation is a planned refinement).
|
|
17
|
+
*/
|
|
18
|
+
import { StatementFacts } from './facts';
|
|
19
|
+
/** The kinds of objects an identity can describe. */
|
|
20
|
+
export type ObjectIdentityKind = 'schema' | 'extension' | 'role' | 'table' | 'view' | 'sequence' | 'type' | 'function' | 'index' | 'trigger' | 'policy' | 'constraint' | 'seed_dml' | 'other';
|
|
21
|
+
/**
|
|
22
|
+
* The identity of a database object. Identity is the diff/dependency key;
|
|
23
|
+
* any path or name is only a downstream rendering of it.
|
|
24
|
+
*/
|
|
25
|
+
export interface ObjectIdentity {
|
|
26
|
+
kind: ObjectIdentityKind;
|
|
27
|
+
/** Owning schema (`null` for non-schema objects: roles, extensions). */
|
|
28
|
+
schema: string | null;
|
|
29
|
+
/** Object name, unqualified (for table-scoped kinds: without the table). */
|
|
30
|
+
name: string;
|
|
31
|
+
/** Owning table, for objects only unique per table (trigger/policy/index/constraint/seed). */
|
|
32
|
+
table?: string;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Derive the identity of the object a statement primarily creates or
|
|
36
|
+
* targets, or `null` when the statement creates nothing (grants, comments —
|
|
37
|
+
* such statements ride with the change of the object they attach to).
|
|
38
|
+
*
|
|
39
|
+
* Table-scoped kinds are recovered from the classifier's table-qualified
|
|
40
|
+
* names (`table.trigger`) and, for indexes and constraints, from the
|
|
41
|
+
* targeted relation.
|
|
42
|
+
*/
|
|
43
|
+
export declare function identityOf(facts: StatementFacts): ObjectIdentity | null;
|
package/naming.js
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.identityOf = identityOf;
|
|
4
|
+
/**
|
|
5
|
+
* Derive the identity of the object a statement primarily creates or
|
|
6
|
+
* targets, or `null` when the statement creates nothing (grants, comments —
|
|
7
|
+
* such statements ride with the change of the object they attach to).
|
|
8
|
+
*
|
|
9
|
+
* Table-scoped kinds are recovered from the classifier's table-qualified
|
|
10
|
+
* names (`table.trigger`) and, for indexes and constraints, from the
|
|
11
|
+
* targeted relation.
|
|
12
|
+
*/
|
|
13
|
+
function identityOf(facts) {
|
|
14
|
+
if (facts.kind === 'extension' && facts.extension) {
|
|
15
|
+
return { kind: 'extension', schema: null, name: facts.extension.name };
|
|
16
|
+
}
|
|
17
|
+
const created = facts.creates[0];
|
|
18
|
+
if (!created)
|
|
19
|
+
return null;
|
|
20
|
+
switch (facts.kind) {
|
|
21
|
+
case 'schema':
|
|
22
|
+
return { kind: 'schema', schema: null, name: created.name };
|
|
23
|
+
case 'trigger':
|
|
24
|
+
case 'policy': {
|
|
25
|
+
const dot = created.name.indexOf('.');
|
|
26
|
+
if (dot > 0) {
|
|
27
|
+
return {
|
|
28
|
+
kind: facts.kind,
|
|
29
|
+
schema: created.schema,
|
|
30
|
+
name: created.name.slice(dot + 1),
|
|
31
|
+
table: created.name.slice(0, dot)
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
return { kind: facts.kind, schema: created.schema, name: created.name };
|
|
35
|
+
}
|
|
36
|
+
case 'index': {
|
|
37
|
+
// IndexStmt records the index name in creates and the indexed relation
|
|
38
|
+
// in references (same-schema RangeVar).
|
|
39
|
+
const rel = facts.references.find(r => r.schema === created.schema) ?? facts.references[0];
|
|
40
|
+
return {
|
|
41
|
+
kind: 'index',
|
|
42
|
+
schema: created.schema,
|
|
43
|
+
name: created.name,
|
|
44
|
+
table: rel?.name
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
case 'fk_constraint':
|
|
48
|
+
case 'constraint':
|
|
49
|
+
case 'rls_enable':
|
|
50
|
+
// ALTER TABLE statements target their table.
|
|
51
|
+
return { kind: 'constraint', schema: created.schema, name: created.name, table: created.name };
|
|
52
|
+
case 'seed_dml':
|
|
53
|
+
return { kind: 'seed_dml', schema: created.schema, name: created.name, table: created.name };
|
|
54
|
+
case 'table':
|
|
55
|
+
// AlterTableStmt facts also classify as `table`-targeting; the created
|
|
56
|
+
// name is the table either way.
|
|
57
|
+
return { kind: 'table', schema: created.schema, name: created.name };
|
|
58
|
+
case 'view':
|
|
59
|
+
case 'function':
|
|
60
|
+
case 'type':
|
|
61
|
+
return { kind: facts.kind, schema: created.schema, name: created.name };
|
|
62
|
+
default:
|
|
63
|
+
if (facts.nodeTag === 'CreateSeqStmt') {
|
|
64
|
+
return { kind: 'sequence', schema: created.schema, name: created.name };
|
|
65
|
+
}
|
|
66
|
+
return { kind: 'other', schema: created.schema, name: created.name };
|
|
67
|
+
}
|
|
68
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pgsql/transform",
|
|
3
|
-
"version": "18.
|
|
3
|
+
"version": "18.10.0",
|
|
4
4
|
"author": "Constructive <developers@constructive.io>",
|
|
5
5
|
"description": "AST-based SQL transformation, qualification, classification and closure analysis for PostgreSQL",
|
|
6
6
|
"main": "index.js",
|
|
@@ -49,5 +49,5 @@
|
|
|
49
49
|
"classify",
|
|
50
50
|
"plpgsql"
|
|
51
51
|
],
|
|
52
|
-
"gitHead": "
|
|
52
|
+
"gitHead": "ce8ea3fadd2549dfbe699c05c38c8a85090efc8c"
|
|
53
53
|
}
|
package/restructure.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/** The target shape of a restructured script. */
|
|
2
|
+
export type Granularity = 'atomic' | 'object' | 'consolidated';
|
|
3
|
+
export interface RestructureOptions {
|
|
4
|
+
granularity: Granularity;
|
|
5
|
+
}
|
|
6
|
+
export interface RestructureResult {
|
|
7
|
+
/** The restructured script, statements in stable topological order. */
|
|
8
|
+
sql: string;
|
|
9
|
+
/** Number of statements folded into a `CREATE TABLE` (fold direction). */
|
|
10
|
+
folded: number;
|
|
11
|
+
/** Number of statements produced by explosion (atomize direction). */
|
|
12
|
+
exploded: number;
|
|
13
|
+
/** Folds that were rejected (with the reason) and other non-fatal notes. */
|
|
14
|
+
warnings: string[];
|
|
15
|
+
}
|
|
16
|
+
type AnyNode = Record<string, any>;
|
|
17
|
+
/**
|
|
18
|
+
* Restructure a DDL script to the requested granularity. The input and
|
|
19
|
+
* output scripts deploy to identical schemas; only statement shape and
|
|
20
|
+
* order change.
|
|
21
|
+
*/
|
|
22
|
+
export declare function restructureSql(sql: string, options: RestructureOptions): RestructureResult;
|
|
23
|
+
/**
|
|
24
|
+
* Re-emit statements in the stable topological order of their dependency
|
|
25
|
+
* graph. Statements are deparsed and re-classified so the ordering reflects
|
|
26
|
+
* exactly what will be emitted.
|
|
27
|
+
*/
|
|
28
|
+
export declare function orderStatements(stmts: AnyNode[]): AnyNode[];
|
|
29
|
+
export {};
|