@pgsql/transform 18.1.1 → 18.3.1

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.
Files changed (107) hide show
  1. package/README.md +24 -76
  2. package/esm/facts.js +289 -0
  3. package/esm/index.js +5 -22
  4. package/esm/qualify.js +297 -0
  5. package/esm/round-trip-core.js +126 -0
  6. package/esm/round-trip.js +116 -0
  7. package/esm/transform.js +1169 -0
  8. package/facts.d.ts +69 -0
  9. package/facts.js +292 -0
  10. package/index.d.ts +10 -28
  11. package/index.js +37 -76
  12. package/package.json +22 -14
  13. package/qualify.d.ts +125 -0
  14. package/qualify.js +303 -0
  15. package/round-trip-core.d.ts +60 -0
  16. package/round-trip-core.js +133 -0
  17. package/round-trip.d.ts +47 -0
  18. package/round-trip.js +123 -0
  19. package/transform.d.ts +259 -0
  20. package/transform.js +1190 -0
  21. package/13/enums.d.ts +0 -62
  22. package/13/enums.js +0 -2
  23. package/13/types.d.ts +0 -2103
  24. package/13/types.js +0 -2
  25. package/14/enums.d.ts +0 -62
  26. package/14/enums.js +0 -2
  27. package/14/types.d.ts +0 -2164
  28. package/14/types.js +0 -2
  29. package/15/enums.d.ts +0 -64
  30. package/15/enums.js +0 -2
  31. package/15/types.d.ts +0 -2222
  32. package/15/types.js +0 -2
  33. package/16/enums.d.ts +0 -69
  34. package/16/enums.js +0 -2
  35. package/16/types.d.ts +0 -2328
  36. package/16/types.js +0 -2
  37. package/17/enums.d.ts +0 -76
  38. package/17/enums.js +0 -2
  39. package/17/types.d.ts +0 -2488
  40. package/17/types.js +0 -2
  41. package/18/enums.d.ts +0 -78
  42. package/18/enums.js +0 -2
  43. package/18/types.d.ts +0 -2538
  44. package/18/types.js +0 -2
  45. package/esm/13/enums.js +0 -1
  46. package/esm/13/types.js +0 -1
  47. package/esm/14/enums.js +0 -1
  48. package/esm/14/types.js +0 -1
  49. package/esm/15/enums.js +0 -1
  50. package/esm/15/types.js +0 -1
  51. package/esm/16/enums.js +0 -1
  52. package/esm/16/types.js +0 -1
  53. package/esm/17/enums.js +0 -1
  54. package/esm/17/types.js +0 -1
  55. package/esm/18/enums.js +0 -1
  56. package/esm/18/types.js +0 -1
  57. package/esm/multi-version-transformer.js +0 -80
  58. package/esm/transformers/context.js +0 -1
  59. package/esm/transformers/v13-to-v14.js +0 -2767
  60. package/esm/transformers/v14-to-v15.js +0 -1218
  61. package/esm/transformers/v15-to-v16.js +0 -2935
  62. package/esm/transformers/v16-to-v17.js +0 -1526
  63. package/esm/transformers/v17-to-v18.js +0 -204
  64. package/esm/transformers-direct/index.js +0 -13
  65. package/esm/transformers-direct/v13-to-v17/index.js +0 -74
  66. package/esm/transformers-direct/v13-to-v18/index.js +0 -84
  67. package/esm/transformers-direct/v14-to-v17/index.js +0 -63
  68. package/esm/transformers-direct/v14-to-v18/index.js +0 -73
  69. package/esm/transformers-direct/v15-to-v17/index.js +0 -53
  70. package/esm/transformers-direct/v15-to-v18/index.js +0 -62
  71. package/esm/transformers-direct/v16-to-v17/index.js +0 -40
  72. package/esm/transformers-direct/v16-to-v18/index.js +0 -51
  73. package/esm/transformers-direct/v17-to-v18/index.js +0 -39
  74. package/multi-version-transformer.d.ts +0 -14
  75. package/multi-version-transformer.js +0 -84
  76. package/transformers/context.d.ts +0 -4
  77. package/transformers/context.js +0 -2
  78. package/transformers/v13-to-v14.d.ts +0 -255
  79. package/transformers/v13-to-v14.js +0 -2771
  80. package/transformers/v14-to-v15.d.ts +0 -615
  81. package/transformers/v14-to-v15.js +0 -1222
  82. package/transformers/v15-to-v16.d.ts +0 -632
  83. package/transformers/v15-to-v16.js +0 -2939
  84. package/transformers/v16-to-v17.d.ts +0 -640
  85. package/transformers/v16-to-v17.js +0 -1530
  86. package/transformers/v17-to-v18.d.ts +0 -54
  87. package/transformers/v17-to-v18.js +0 -208
  88. package/transformers-direct/index.d.ts +0 -13
  89. package/transformers-direct/index.js +0 -25
  90. package/transformers-direct/v13-to-v17/index.d.ts +0 -27
  91. package/transformers-direct/v13-to-v17/index.js +0 -78
  92. package/transformers-direct/v13-to-v18/index.d.ts +0 -28
  93. package/transformers-direct/v13-to-v18/index.js +0 -88
  94. package/transformers-direct/v14-to-v17/index.d.ts +0 -26
  95. package/transformers-direct/v14-to-v17/index.js +0 -67
  96. package/transformers-direct/v14-to-v18/index.d.ts +0 -27
  97. package/transformers-direct/v14-to-v18/index.js +0 -77
  98. package/transformers-direct/v15-to-v17/index.d.ts +0 -25
  99. package/transformers-direct/v15-to-v17/index.js +0 -57
  100. package/transformers-direct/v15-to-v18/index.d.ts +0 -26
  101. package/transformers-direct/v15-to-v18/index.js +0 -66
  102. package/transformers-direct/v16-to-v17/index.d.ts +0 -24
  103. package/transformers-direct/v16-to-v17/index.js +0 -44
  104. package/transformers-direct/v16-to-v18/index.d.ts +0 -25
  105. package/transformers-direct/v16-to-v18/index.js +0 -55
  106. package/transformers-direct/v17-to-v18/index.d.ts +0 -24
  107. package/transformers-direct/v17-to-v18/index.js +0 -43
package/README.md CHANGED
@@ -12,25 +12,9 @@
12
12
  <a href="https://www.npmjs.com/package/@pgsql/transform"><img height="20" src="https://img.shields.io/github/package-json/v/constructive-io/pgsql-parser?filename=packages%2Ftransform%2Fpackage.json"/></a>
13
13
  </p>
14
14
 
15
- `@pgsql/transform` is a TypeScript library for transforming PostgreSQL ASTs between different PostgreSQL versions. It serves as a crucial component for building a single source of truth deparser that can handle SQL from multiple PostgreSQL versions while maintaining backward compatibility.
15
+ AST-based SQL transformation, qualification, classification, and dependency-closure analysis for PostgreSQL. Works on plain SQL **and inside PL/pgSQL function bodies** (via `plpgsql-parser` hydration) — no regexes.
16
16
 
17
- ## Transforming ASTs Between PG Versions
18
-
19
- The transform package enables you to:
20
-
21
- - **Transform legacy ASTs**: Convert ASTs from PostgreSQL versions 13-16 to version 17
22
- - **Build unified deparsers**: Create a single deparser pipeline that works with multiple PostgreSQL versions
23
- - **Maintain backward compatibility**: Support legacy codebases while leveraging the latest PostgreSQL features
24
-
25
- ## Key Limitation
26
-
27
- This package only supports ASTs derived from SQL that is parseable by PostgreSQL 17. This means:
28
-
29
- - ✅ **Supported**: SQL from PG13-16 that remains valid in PG17
30
- - ❌ **Not supported**: Deprecated syntax from older versions that was removed
31
- - ❌ **Not supported**: SQL that cannot be parsed by the PG17 parser
32
-
33
- This design ensures all transformed ASTs can be reliably deparsed using the latest PostgreSQL grammar.
17
+ > Looking for the PG13→17/18 version-upgrade AST transformer previously published under this name? It now lives at [`@pgsql/transform-ast`](../transform-ast).
34
18
 
35
19
  ## Installation
36
20
 
@@ -38,82 +22,46 @@ This design ensures all transformed ASTs can be reliably deparsed using the late
38
22
  npm install @pgsql/transform
39
23
  ```
40
24
 
41
- ## 🚀 Quick Start
42
-
43
- ### Multi-Version Transformer
44
-
45
- ```typescript
46
- import { ASTTransformer } from '@pgsql/transform';
47
-
48
- const transformer = new ASTTransformer();
49
-
50
- // Transform any version to PG17
51
- const pg17Ast = transformer.transformToLatest(pg13Ast, 13);
25
+ The parser runs on a WASM build of the real PostgreSQL parser; call `loadModule()` from `plpgsql-parser` once before using any synchronous API.
52
26
 
53
- // Transform between specific versions
54
- const pg15Ast = transformer.transform(pg13Ast, 13, 15);
27
+ ## Features
55
28
 
56
- // Convenience methods
57
- const result = transformer.transform13To17(pg13Ast);
58
- ```
29
+ ### `transformSql` — schema-name rewriting
59
30
 
60
- ### Direct Transformers
61
-
62
- For better performance when you know source and target versions:
31
+ Rewrite schema names everywhere they can appear (DDL, DML, function bodies, trigger definitions, grants, policies, comments, type casts, string-embedded types inside PL/pgSQL, ...):
63
32
 
64
33
  ```typescript
65
- import { PG13ToPG17Transformer } from '@pgsql/transform';
34
+ import { loadModule } from 'plpgsql-parser';
35
+ import { transformSql } from '@pgsql/transform';
66
36
 
67
- const transformer = new PG13ToPG17Transformer();
68
- const pg17Ast = transformer.transform(pg13Ast);
37
+ await loadModule();
38
+ const mapping = new Map([['my-schema', 'my_schema']]);
39
+ const { sql } = transformSql(inputSql, mapping);
69
40
  ```
70
41
 
71
- ### Integration Example
42
+ ### `classifyStatements` — per-statement AST facts
72
43
 
73
44
  ```typescript
74
- import { parse } from '@pgsql/parser';
75
- import { deparse } from 'pgsql-deparser';
76
- import { PG13ToPG17Transformer } from '@pgsql/transform';
77
-
78
- // Parse with older version
79
- const pg13Ast = await parse('SELECT * FROM users', { version: 13 });
45
+ import { classifyStatements } from '@pgsql/transform';
80
46
 
81
- // Transform to latest
82
- const transformer = new PG13ToPG17Transformer();
83
- const pg17Ast = transformer.transform(pg13Ast);
84
-
85
- // Deparse with latest grammar
86
- const sql = await deparse(pg17Ast);
47
+ const facts = classifyStatements(sql);
48
+ // per statement: kind (schema|table|view|index|type|function|trigger|policy|grant|...),
49
+ // creates, references (incl. inside PL/pgSQL bodies), referencedSchemas, roles,
50
+ // fkTargets, securityRelevant, securityDefiner, dynamicSql
87
51
  ```
88
52
 
89
- ## 🔄 Transformation Chain
90
-
91
- **Incremental**: PG13 → PG14 → PG15 → PG16 → PG17
92
- - Step-by-step version upgrades
93
- - Useful for debugging transformation issues
94
-
95
- **Direct**: PG13 → PG17, PG14 → PG17, etc.
96
- - Single-step transformations
97
- - Optimized for performance
98
-
99
- ## 📋 Supported Transformations
53
+ ### `qualifyUnqualified` — add schema qualification
100
54
 
101
- | From | To | Transformer |
102
- |------|----|-----------|
103
- | PG13 | PG14, PG15, PG16, PG17 | `V13ToV14Transformer`, `PG13ToPG17Transformer` |
104
- | PG14 | PG15, PG16, PG17 | `V14ToV15Transformer`, `PG14ToPG17Transformer` |
105
- | PG15 | PG16, PG17 | `V15ToV16Transformer`, `PG15ToPG17Transformer` |
106
- | PG16 | PG17 | `V16ToV17Transformer`, `PG16ToPG17Transformer` |
55
+ Qualify unqualified object references against an inventory of known objects, with multi-schema routing support.
107
56
 
108
- ## 🏗️ Architecture
57
+ ### Round-trip validation
109
58
 
110
- The transform package fits into the broader pgsql-parser ecosystem:
59
+ `normalizeTree` / `cleanTree` / `validateRoundTrip` — dependency-free AST normalization and mutation-aware parse→deparse→re-parse validation.
111
60
 
112
- 1. **Parse** legacy SQL with version-specific parsers
113
- 2. **Transform** ASTs to the latest version
114
- 3. **Deparse** using the unified, latest-version deparser
61
+ ## Scripts
115
62
 
116
- This enables a single source of truth for SQL generation while supporting legacy codebases.
63
+ - `npm run fixtures` — regenerate `__fixtures__/output/` golden files from `__fixtures__/input/`
64
+ - `npm run scan-corpus <dir> [dir...]` — audit node-type coverage over a SQL corpus
117
65
 
118
66
  ---
119
67
 
package/esm/facts.js ADDED
@@ -0,0 +1,289 @@
1
+ import { walk as walkSql } from '@pgsql/traverse';
2
+ import { transformSync, walk as walkPlpgsql } from 'plpgsql-parser';
3
+ const SECURITY_TAGS = new Set([
4
+ 'CreatePolicyStmt',
5
+ 'AlterPolicyStmt',
6
+ 'GrantStmt',
7
+ 'GrantRoleStmt',
8
+ 'AlterDefaultPrivilegesStmt',
9
+ 'SecLabelStmt',
10
+ 'AlterOwnerStmt',
11
+ 'CreateRoleStmt',
12
+ 'AlterRoleStmt'
13
+ ]);
14
+ const KIND_BY_TAG = {
15
+ CreateSchemaStmt: 'schema',
16
+ CreateStmt: 'table',
17
+ ViewStmt: 'view',
18
+ IndexStmt: 'index',
19
+ CompositeTypeStmt: 'type',
20
+ CreateEnumStmt: 'type',
21
+ CreateDomainStmt: 'type',
22
+ CreateRangeStmt: 'type',
23
+ DefineStmt: 'type',
24
+ CreateFunctionStmt: 'function',
25
+ CreateTrigStmt: 'trigger',
26
+ CreateEventTrigStmt: 'trigger',
27
+ CreatePolicyStmt: 'policy',
28
+ AlterPolicyStmt: 'policy',
29
+ GrantStmt: 'grant',
30
+ GrantRoleStmt: 'grant',
31
+ AlterDefaultPrivilegesStmt: 'grant',
32
+ CommentStmt: 'comment',
33
+ InsertStmt: 'seed_dml',
34
+ UpdateStmt: 'seed_dml',
35
+ DeleteStmt: 'seed_dml'
36
+ };
37
+ function qn(schema, name) {
38
+ return { schema: schema ?? null, name };
39
+ }
40
+ function nameListToQualified(names) {
41
+ if (!Array.isArray(names) || names.length === 0)
42
+ return null;
43
+ const parts = names
44
+ .map((n) => n?.String?.sval)
45
+ .filter((s) => typeof s === 'string');
46
+ if (parts.length === 0)
47
+ return null;
48
+ if (parts.length === 1)
49
+ return qn(null, parts[0]);
50
+ return qn(parts[parts.length - 2], parts[parts.length - 1]);
51
+ }
52
+ function isCatalogSchema(schema) {
53
+ return schema === 'pg_catalog' || schema === 'information_schema';
54
+ }
55
+ function pushRef(refs, ref) {
56
+ if (!ref || !ref.schema || isCatalogSchema(ref.schema))
57
+ return;
58
+ if (refs.some(r => r.schema === ref.schema && r.name === ref.name))
59
+ return;
60
+ refs.push(ref);
61
+ }
62
+ function collectRoles(node, roles) {
63
+ const push = (role) => {
64
+ if (typeof role === 'string' && role.length > 0 && !roles.includes(role)) {
65
+ roles.push(role);
66
+ }
67
+ };
68
+ if (Array.isArray(node?.grantees)) {
69
+ for (const g of node.grantees)
70
+ push(g?.RoleSpec?.rolename);
71
+ }
72
+ if (Array.isArray(node?.roles)) {
73
+ for (const r of node.roles)
74
+ push(r?.RoleSpec?.rolename);
75
+ }
76
+ push(node?.newowner?.rolename);
77
+ push(node?.role?.rolename);
78
+ }
79
+ /**
80
+ * Create a read-only visitor that accumulates references, roles and FK
81
+ * targets into the provided facts object.
82
+ */
83
+ function createFactsVisitor(facts, bodyRefs) {
84
+ const push = (ref) => {
85
+ pushRef(facts.references, ref);
86
+ if (bodyRefs)
87
+ pushRef(bodyRefs, ref);
88
+ };
89
+ return {
90
+ RangeVar: (path) => {
91
+ const node = path.node;
92
+ if (node.schemaname) {
93
+ push(qn(node.schemaname, node.relname));
94
+ }
95
+ },
96
+ FuncCall: (path) => {
97
+ push(nameListToQualified(path.node.funcname));
98
+ },
99
+ TypeName: (path) => {
100
+ push(nameListToQualified(path.node.names));
101
+ },
102
+ ColumnRef: (path) => {
103
+ // schema.table.column references carry cross-schema information
104
+ const fields = path.node.fields;
105
+ if (Array.isArray(fields) && fields.length >= 3) {
106
+ const parts = fields
107
+ .map((f) => f?.String?.sval)
108
+ .filter((s) => typeof s === 'string');
109
+ if (parts.length >= 3) {
110
+ push(qn(parts[0], parts[1]));
111
+ }
112
+ }
113
+ },
114
+ Constraint: (path) => {
115
+ const node = path.node;
116
+ if (node.contype === 'CONSTR_FOREIGN' && node.pktable) {
117
+ const target = qn(node.pktable.schemaname ?? null, node.pktable.relname);
118
+ if (!facts.fkTargets.some(t => t.schema === target.schema && t.name === target.name)) {
119
+ facts.fkTargets.push(target);
120
+ }
121
+ if (target.schema)
122
+ pushRef(facts.references, target);
123
+ }
124
+ }
125
+ };
126
+ }
127
+ function classifyOne(nodeTag, node) {
128
+ const facts = {
129
+ kind: KIND_BY_TAG[nodeTag] ?? 'other',
130
+ nodeTag,
131
+ creates: [],
132
+ references: [],
133
+ referencedSchemas: [],
134
+ roles: [],
135
+ fkTargets: [],
136
+ bodyReferences: [],
137
+ securityRelevant: SECURITY_TAGS.has(nodeTag),
138
+ securityDefiner: false,
139
+ dynamicSql: false
140
+ };
141
+ switch (nodeTag) {
142
+ case 'CreateSchemaStmt':
143
+ facts.creates.push(qn(null, node.schemaname));
144
+ break;
145
+ case 'CreateStmt':
146
+ case 'ViewStmt': {
147
+ const rel = nodeTag === 'ViewStmt' ? node.view : node.relation;
148
+ if (rel)
149
+ facts.creates.push(qn(rel.schemaname ?? null, rel.relname));
150
+ break;
151
+ }
152
+ case 'IndexStmt':
153
+ if (node.relation) {
154
+ facts.creates.push(qn(node.relation.schemaname ?? null, node.idxname ?? node.relation.relname));
155
+ }
156
+ break;
157
+ case 'CreateFunctionStmt': {
158
+ const name = nameListToQualified(node.funcname);
159
+ if (name)
160
+ facts.creates.push(name);
161
+ for (const opt of node.options ?? []) {
162
+ const def = opt?.DefElem;
163
+ if (def?.defname === 'security' && def?.arg?.Boolean?.boolval === true) {
164
+ facts.securityDefiner = true;
165
+ }
166
+ }
167
+ break;
168
+ }
169
+ case 'CreateTrigStmt':
170
+ if (node.relation) {
171
+ // Trigger names are only unique per table; qualify with the table.
172
+ facts.creates.push(qn(node.relation.schemaname ?? null, `${node.relation.relname}.${node.trigname}`));
173
+ }
174
+ pushRef(facts.references, nameListToQualified(node.funcname));
175
+ break;
176
+ case 'CreatePolicyStmt':
177
+ case 'AlterPolicyStmt':
178
+ if (node.table) {
179
+ // Policy names are only unique per table; qualify with the table.
180
+ facts.creates.push(qn(node.table.schemaname ?? null, `${node.table.relname}.${node.policy_name}`));
181
+ // The guarded table lives on `node.table`; the generic RangeVar walker
182
+ // does not descend into it, so capture the reference explicitly.
183
+ if (node.table.schemaname) {
184
+ pushRef(facts.references, qn(node.table.schemaname, node.table.relname));
185
+ }
186
+ }
187
+ break;
188
+ case 'CreateSeqStmt':
189
+ if (node.sequence) {
190
+ facts.creates.push(qn(node.sequence.schemaname ?? null, node.sequence.relname));
191
+ }
192
+ break;
193
+ case 'CompositeTypeStmt':
194
+ if (node.typevar) {
195
+ facts.creates.push(qn(node.typevar.schemaname ?? null, node.typevar.relname));
196
+ }
197
+ break;
198
+ case 'CreateEnumStmt':
199
+ case 'CreateDomainStmt':
200
+ case 'CreateRangeStmt': {
201
+ const name = nameListToQualified(node.typeName ?? node.domainname);
202
+ if (name)
203
+ facts.creates.push(name);
204
+ break;
205
+ }
206
+ case 'AlterTableStmt': {
207
+ if (node.relation) {
208
+ facts.creates.push(qn(node.relation.schemaname ?? null, node.relation.relname));
209
+ }
210
+ const cmds = node.cmds ?? [];
211
+ for (const cmd of cmds) {
212
+ const subtype = cmd?.AlterTableCmd?.subtype;
213
+ if (subtype === 'AT_EnableRowSecurity' || subtype === 'AT_ForceRowSecurity' ||
214
+ subtype === 'AT_DisableRowSecurity' || subtype === 'AT_NoForceRowSecurity') {
215
+ facts.kind = 'rls_enable';
216
+ facts.securityRelevant = true;
217
+ }
218
+ else if (subtype === 'AT_AddConstraint') {
219
+ const contype = cmd?.AlterTableCmd?.def?.Constraint?.contype;
220
+ facts.kind = contype === 'CONSTR_FOREIGN' ? 'fk_constraint' : 'constraint';
221
+ }
222
+ else if (subtype === 'AT_ChangeOwner') {
223
+ facts.securityRelevant = true;
224
+ const owner = cmd?.AlterTableCmd?.newowner?.rolename;
225
+ if (owner && !facts.roles.includes(owner))
226
+ facts.roles.push(owner);
227
+ }
228
+ }
229
+ break;
230
+ }
231
+ case 'InsertStmt':
232
+ case 'UpdateStmt':
233
+ case 'DeleteStmt':
234
+ if (node.relation) {
235
+ facts.creates.push(qn(node.relation.schemaname ?? null, node.relation.relname));
236
+ }
237
+ break;
238
+ default:
239
+ break;
240
+ }
241
+ collectRoles(node, facts.roles);
242
+ return facts;
243
+ }
244
+ /**
245
+ * Classify each top-level statement in a SQL script into {@link StatementFacts}.
246
+ *
247
+ * Uses the same parser stack as the schema transformer (pgsql AST walk plus
248
+ * hydrated PL/pgSQL body walk), so references inside function bodies are
249
+ * included. The input SQL is never modified.
250
+ */
251
+ export function classifyStatements(sql) {
252
+ const allFacts = [];
253
+ transformSync(sql, (ctx) => {
254
+ const stmts = ctx.sql?.stmts ?? [];
255
+ for (const stmt of stmts) {
256
+ const stmtNode = stmt?.stmt;
257
+ const nodeTag = stmtNode ? Object.keys(stmtNode)[0] : 'other';
258
+ const node = stmtNode?.[nodeTag] ?? {};
259
+ const facts = classifyOne(nodeTag, node);
260
+ if (stmtNode) {
261
+ walkSql(stmtNode, createFactsVisitor(facts));
262
+ }
263
+ allFacts.push(facts);
264
+ }
265
+ for (const fn of ctx.functions ?? []) {
266
+ const facts = allFacts[fn.stmtIndex];
267
+ if (!facts || !fn.plpgsql?.hydrated)
268
+ continue;
269
+ // Refs already found outside the body (signature types, defaults)
270
+ // constrain deploy order and are not body-only.
271
+ const outer = new Set(facts.references.map(r => `${r.schema ?? '?'}.${r.name}`));
272
+ walkPlpgsql(fn.plpgsql.hydrated, {
273
+ PLpgSQL_stmt_dynexecute: () => { facts.dynamicSql = true; },
274
+ PLpgSQL_stmt_dynfors: () => { facts.dynamicSql = true; }
275
+ }, {
276
+ walkSqlExpressions: true,
277
+ sqlVisitor: createFactsVisitor(facts, facts.bodyReferences)
278
+ });
279
+ facts.bodyReferences = facts.bodyReferences.filter(r => !outer.has(`${r.schema ?? '?'}.${r.name}`));
280
+ }
281
+ }, { hydrate: true });
282
+ for (const facts of allFacts) {
283
+ const selfRef = (r) => facts.creates.some(c => c.schema === r.schema && c.name === r.name);
284
+ facts.references = facts.references.filter(r => !selfRef(r));
285
+ facts.bodyReferences = facts.bodyReferences.filter(r => !selfRef(r));
286
+ facts.referencedSchemas = [...new Set(facts.references.map(r => r.schema).filter(Boolean))];
287
+ }
288
+ return allFacts;
289
+ }
package/esm/index.js CHANGED
@@ -1,22 +1,5 @@
1
- import * as PG13Types from './13/types';
2
- import * as PG14Types from './14/types';
3
- import * as PG15Types from './15/types';
4
- import * as PG16Types from './16/types';
5
- import * as PG17Types from './17/types';
6
- import * as PG18Types from './18/types';
7
- export { ASTTransformer } from './multi-version-transformer';
8
- export { V13ToV14Transformer } from './transformers/v13-to-v14';
9
- export { V14ToV15Transformer } from './transformers/v14-to-v15';
10
- export { V15ToV16Transformer } from './transformers/v15-to-v16';
11
- export { V16ToV17Transformer } from './transformers/v16-to-v17';
12
- export { V17ToV18Transformer } from './transformers/v17-to-v18';
13
- export { PG13ToPG17Transformer } from './transformers-direct/v13-to-v17';
14
- export { PG14ToPG17Transformer } from './transformers-direct/v14-to-v17';
15
- export { PG15ToPG17Transformer } from './transformers-direct/v15-to-v17';
16
- export { PG16ToPG17Transformer } from './transformers-direct/v16-to-v17';
17
- export { PG13ToPG18Transformer } from './transformers-direct/v13-to-v18';
18
- export { PG14ToPG18Transformer } from './transformers-direct/v14-to-v18';
19
- export { PG15ToPG18Transformer } from './transformers-direct/v15-to-v18';
20
- export { PG16ToPG18Transformer } from './transformers-direct/v16-to-v18';
21
- export { PG17ToPG18Transformer } from './transformers-direct/v17-to-v18';
22
- export { PG13Types, PG14Types, PG15Types, PG16Types, PG17Types, PG18Types };
1
+ export { classifyStatements } from './facts';
2
+ export { collectCreatedObjects, createQualifyVisitor, mergeInventories, qualifyUnqualified, } from './qualify';
3
+ export { captureAstsFromSql, captureTransformAsts, firstDifference, normalizeParseTree, validateRoundTrip, } from './round-trip';
4
+ export { CLEAN_TREE_VOLATILE_KEYS, cleanTree, normalizeTree, trimDefElemBody, } from './round-trip-core';
5
+ export { createPlpgsqlVisitor, createSqlVisitor, escapeRegexp, extractPgpmHeader, shouldTransformSchema, transformComments, transformJsonStringValues, transformNameList, transformPlpgsqlTypeAst, transformPlpgsqlTypeString, transformRelation, transformSchemaName, transformSql, transformSqlStatement, transformVerifyCalls, validateNoUntransformedSchemas, walkPlpgsqlForSchemas, } from './transform';