Skip to content

Commit 3e2b5d1

Browse files
committed
transformers πŸš€
1 parent b10f619 commit 3e2b5d1

File tree

19 files changed

+630
-466
lines changed

19 files changed

+630
-466
lines changed
Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
import { Parser } from '@pgsql/parser';
2+
import {
3+
PG13ToPG17Transformer,
4+
PG14ToPG17Transformer,
5+
PG15ToPG17Transformer,
6+
PG16ToPG17Transformer
7+
} from '../src/transformers-direct';
8+
9+
describe('Direct Transformers', () => {
10+
const testSQL = 'SELECT id, name FROM users WHERE active = true';
11+
12+
describe('PG16ToPG17Transformer', () => {
13+
it('should transform PG16 ParseResult to PG17', async () => {
14+
const pg16Parser = new Parser({ version: 16 });
15+
16+
const pg16Ast = await pg16Parser.parse(testSQL);
17+
const transformer = new PG16ToPG17Transformer();
18+
const transformedAst = transformer.transform(pg16Ast);
19+
20+
expect(transformedAst.version).toBe(170004);
21+
expect(transformedAst.stmts).toBeDefined();
22+
expect(transformedAst.stmts.length).toBe(1);
23+
24+
// Verify the structure is preserved
25+
expect(transformedAst.stmts[0].stmt).toBeDefined();
26+
const stmt = transformedAst.stmts[0].stmt as any;
27+
expect(stmt.SelectStmt).toBeDefined();
28+
});
29+
30+
it('should transform PG16 Node to PG17', async () => {
31+
const pg16Parser = new Parser({ version: 16 });
32+
33+
const pg16Ast = await pg16Parser.parse(testSQL);
34+
const transformer = new PG16ToPG17Transformer();
35+
36+
// Transform just the statement node
37+
const stmtNode = pg16Ast.stmts[0].stmt;
38+
const transformedNode = transformer.transform(stmtNode);
39+
40+
// Verify the node was transformed
41+
expect(transformedNode).toBeDefined();
42+
expect((transformedNode as any).SelectStmt).toBeDefined();
43+
});
44+
});
45+
46+
describe('PG15ToPG17Transformer', () => {
47+
it('should transform PG15 ParseResult to PG17', async () => {
48+
const pg15Parser = new Parser({ version: 15 });
49+
50+
const pg15Ast = await pg15Parser.parse(testSQL);
51+
const transformer = new PG15ToPG17Transformer();
52+
const transformedAst = transformer.transform(pg15Ast);
53+
54+
expect(transformedAst.version).toBe(170004);
55+
expect(transformedAst.stmts).toBeDefined();
56+
expect(transformedAst.stmts.length).toBe(1);
57+
58+
// Verify the structure is preserved
59+
expect(transformedAst.stmts[0].stmt).toBeDefined();
60+
const stmt = transformedAst.stmts[0].stmt as any;
61+
expect(stmt.SelectStmt).toBeDefined();
62+
});
63+
64+
it('should transform PG15 Node to PG17', async () => {
65+
const pg15Parser = new Parser({ version: 15 });
66+
67+
const pg15Ast = await pg15Parser.parse(testSQL);
68+
const transformer = new PG15ToPG17Transformer();
69+
70+
// Transform just the statement node
71+
const stmtNode = pg15Ast.stmts[0].stmt;
72+
const transformedNode = transformer.transform(stmtNode);
73+
74+
// Verify the node was transformed
75+
expect(transformedNode).toBeDefined();
76+
expect((transformedNode as any).SelectStmt).toBeDefined();
77+
});
78+
});
79+
80+
describe('PG14ToPG17Transformer', () => {
81+
it('should transform PG14 ParseResult to PG17', async () => {
82+
const pg14Parser = new Parser({ version: 14 });
83+
84+
const pg14Ast = await pg14Parser.parse(testSQL);
85+
const transformer = new PG14ToPG17Transformer();
86+
const transformedAst = transformer.transform(pg14Ast);
87+
88+
expect(transformedAst.version).toBe(170004);
89+
expect(transformedAst.stmts).toBeDefined();
90+
expect(transformedAst.stmts.length).toBe(1);
91+
92+
// Verify the structure is preserved
93+
expect(transformedAst.stmts[0].stmt).toBeDefined();
94+
const stmt = transformedAst.stmts[0].stmt as any;
95+
expect(stmt.SelectStmt).toBeDefined();
96+
});
97+
98+
it('should transform PG14 Node to PG17', async () => {
99+
const pg14Parser = new Parser({ version: 14 });
100+
101+
const pg14Ast = await pg14Parser.parse(testSQL);
102+
const transformer = new PG14ToPG17Transformer();
103+
104+
// Transform just the statement node
105+
const stmtNode = pg14Ast.stmts[0].stmt;
106+
const transformedNode = transformer.transform(stmtNode);
107+
108+
// Verify the node was transformed
109+
expect(transformedNode).toBeDefined();
110+
expect((transformedNode as any).SelectStmt).toBeDefined();
111+
});
112+
});
113+
114+
describe('PG13ToPG17Transformer', () => {
115+
it('should transform PG13 ParseResult to PG17', async () => {
116+
const pg13Parser = new Parser({ version: 13 });
117+
118+
const pg13Ast = await pg13Parser.parse(testSQL);
119+
const transformer = new PG13ToPG17Transformer();
120+
const transformedAst = transformer.transform(pg13Ast);
121+
122+
expect(transformedAst.version).toBe(170004);
123+
expect(transformedAst.stmts).toBeDefined();
124+
expect(transformedAst.stmts.length).toBe(1);
125+
126+
// Verify the structure is preserved
127+
expect(transformedAst.stmts[0].stmt).toBeDefined();
128+
const stmt = transformedAst.stmts[0].stmt as any;
129+
expect(stmt.SelectStmt).toBeDefined();
130+
});
131+
132+
it('should transform PG13 Node to PG17', async () => {
133+
const pg13Parser = new Parser({ version: 13 });
134+
135+
const pg13Ast = await pg13Parser.parse(testSQL);
136+
const transformer = new PG13ToPG17Transformer();
137+
138+
// Transform just the statement node
139+
const stmtNode = pg13Ast.stmts[0].stmt;
140+
const transformedNode = transformer.transform(stmtNode);
141+
142+
// Verify the node was transformed
143+
expect(transformedNode).toBeDefined();
144+
expect((transformedNode as any).SelectStmt).toBeDefined();
145+
});
146+
});
147+
148+
describe('Complex node transformations', () => {
149+
it('should transform nested nodes', async () => {
150+
const complexSQL = `
151+
WITH active_users AS (
152+
SELECT * FROM users WHERE active = true
153+
)
154+
SELECT id, name FROM active_users
155+
ORDER BY name
156+
LIMIT 10
157+
`;
158+
159+
const pg15Parser = new Parser({ version: 15 });
160+
const pg15Ast = await pg15Parser.parse(complexSQL);
161+
const transformer = new PG15ToPG17Transformer();
162+
163+
// Transform the entire AST
164+
const transformedAst = transformer.transform(pg15Ast);
165+
expect(transformedAst.version).toBe(170004);
166+
167+
// Transform just a nested node (the WITH clause)
168+
const selectStmt = pg15Ast.stmts[0].stmt as any;
169+
const withClause = selectStmt.SelectStmt.withClause;
170+
if (withClause) {
171+
const transformedWith = transformer.transform(withClause);
172+
expect(transformedWith).toBeDefined();
173+
}
174+
});
175+
});
176+
177+
describe('Error handling', () => {
178+
it('should handle null/undefined gracefully', () => {
179+
const transformer = new PG16ToPG17Transformer();
180+
181+
expect(() => transformer.transform(null as any)).not.toThrow();
182+
expect(() => transformer.transform(undefined as any)).not.toThrow();
183+
});
184+
185+
it('should handle invalid nodes', () => {
186+
const transformer = new PG16ToPG17Transformer();
187+
const invalidNode = { someRandomProp: 'value' };
188+
189+
// Should not throw, but return transformed node
190+
const result = transformer.transform(invalidNode as any);
191+
expect(result).toBeDefined();
192+
});
193+
});
194+
});

β€Žpackages/transform/__tests__/full-transformers.test.tsβ€Ž

Lines changed: 0 additions & 112 deletions
This file was deleted.

β€Žpackages/transform/src/index.tsβ€Ž

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,16 @@ import * as PG15Types from './15/types';
1010
import * as PG16Types from './16/types';
1111
import * as PG17Types from './17/types';
1212

13-
export { ASTTransformer, PG13ToPG17Transformer } from './transformer';
13+
export { ASTTransformer } from './multi-version-transformer';
14+
1415
export { V13ToV14Transformer } from './transformers/v13-to-v14';
1516
export { V14ToV15Transformer } from './transformers/v14-to-v15';
1617
export { V15ToV16Transformer } from './transformers/v15-to-v16';
1718
export { V16ToV17Transformer } from './transformers/v16-to-v17';
1819

19-
export { PG13ToPG17Transformer as DirectPG13ToPG17Transformer } from './transformers-full/v13-to-v17';
20-
export { PG14ToPG17Transformer as DirectPG14ToPG17Transformer } from './transformers-full/v14-to-v17';
21-
export { PG15ToPG17Transformer as DirectPG15ToPG17Transformer } from './transformers-full/v15-to-v17';
22-
export { PG16ToPG17Transformer as DirectPG16ToPG17Transformer } from './transformers-full/v16-to-v17';
20+
export { PG13ToPG17Transformer } from './transformers-direct/v13-to-v17';
21+
export { PG14ToPG17Transformer } from './transformers-direct/v14-to-v17';
22+
export { PG15ToPG17Transformer } from './transformers-direct/v15-to-v17';
23+
export { PG16ToPG17Transformer } from './transformers-direct/v16-to-v17';
2324

2425
export { PG13Node, PG14Node, PG15Node, PG16Node, PG17Node, PG13Types, PG14Types, PG15Types, PG16Types, PG17Types };

β€Žpackages/transform/src/transformer.tsβ€Ž renamed to β€Žpackages/transform/src/multi-version-transformer.tsβ€Ž

Lines changed: 1 addition & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
import { ParseResult } from './17/types';
2-
import * as V17Types from './17/types';
3-
import * as V13Types from './13/types';
41
import { V13ToV14Transformer } from './transformers/v13-to-v14';
52
import { V14ToV15Transformer } from './transformers/v14-to-v15';
63
import { V15ToV16Transformer } from './transformers/v15-to-v16';
@@ -73,32 +70,4 @@ export class ASTTransformer {
7370
transform16To17(ast: any): any {
7471
return this.transform(ast, 16, 17);
7572
}
76-
}
77-
78-
/**
79-
* Composite transformer that handles the complete PG13 β†’ PG17 transformation
80-
* including proper handling of parse result structure with stmts array
81-
*/
82-
export class PG13ToPG17Transformer {
83-
private astTransformer = new ASTTransformer();
84-
85-
transform(parseResult: V13Types.ParseResult): V17Types.ParseResult {
86-
if (!parseResult || !parseResult.stmts) {
87-
throw new Error('Invalid parse result');
88-
}
89-
90-
const transformedStmts = parseResult.stmts.map((stmtWrapper: any) => {
91-
if (stmtWrapper.stmt) {
92-
const transformedStmt = this.astTransformer.transform13To17(stmtWrapper.stmt);
93-
return { ...stmtWrapper, stmt: transformedStmt };
94-
}
95-
return stmtWrapper;
96-
});
97-
98-
return {
99-
...parseResult,
100-
version: 170004,
101-
stmts: transformedStmts
102-
};
103-
}
104-
}
73+
}

0 commit comments

Comments
Β (0)