Skip to content

Commit 50ea0c7

Browse files
committed
transformer
1 parent ab92f8e commit 50ea0c7

File tree

4 files changed

+171
-1
lines changed

4 files changed

+171
-1
lines changed
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
// this the deparser for PG17
2+
import { deparse } from '../../deparser/src';
3+
4+
// this is the type of the AST for PG13
5+
import { SelectStmt } from 'libpg-query';
6+
7+
// import the transformer
8+
import { transformPG13ToPG17 } from '../src/index';
9+
10+
xdescribe('PG13 to PG17 transformer', () => {
11+
12+
it('should deparse a select statement', async () => {
13+
const stmt: { SelectStmt: SelectStmt } = {
14+
SelectStmt: {
15+
targetList: [{ ResTarget: { val: { ColumnRef: { fields: [{ A_Star: {} }] } } } }],
16+
fromClause: [{ RangeVar: { relname: 'users' } }],
17+
limitOption: 'LIMIT_OPTION_DEFAULT',
18+
op: 'SETOP_NONE'
19+
}
20+
}
21+
// transform the PG13 AST to a PG17 AST
22+
const pg17Stmt = transformPG13ToPG17(stmt as any);
23+
const deparsed = await deparse(pg17Stmt);
24+
expect(deparsed).toBe('SELECT * FROM ONLY users');
25+
});
26+
27+
it('should deparse a select statement with WHERE clause', async () => {
28+
const stmt: { SelectStmt: SelectStmt } = {
29+
SelectStmt: {
30+
targetList: [
31+
{
32+
ResTarget: {
33+
val: {
34+
ColumnRef: {
35+
fields: [
36+
{ String: { str: 'name' } }
37+
]
38+
}
39+
}
40+
}
41+
}
42+
],
43+
fromClause: [{ RangeVar: { relname: 'users' } }],
44+
whereClause: {
45+
A_Expr: {
46+
kind: 'AEXPR_OP',
47+
name: [{ String: { str: '=' } }],
48+
lexpr: {
49+
ColumnRef: {
50+
fields: [{ String: { str: 'id' } }]
51+
}
52+
},
53+
rexpr: {
54+
A_Const: {
55+
val: { Integer: { ival: 1 } }
56+
}
57+
}
58+
}
59+
},
60+
limitOption: 'LIMIT_OPTION_DEFAULT',
61+
op: 'SETOP_NONE'
62+
}
63+
};
64+
65+
const pg17Stmt = transformPG13ToPG17(stmt as any);
66+
const deparsed = await deparse(pg17Stmt);
67+
expect(deparsed).toBe('SELECT name FROM ONLY users WHERE id = 1');
68+
});
69+
70+
it('should deparse a select statement with JOIN', async () => {
71+
const stmt: { SelectStmt: SelectStmt } = {
72+
SelectStmt: {
73+
targetList: [{ ResTarget: { val: { ColumnRef: { fields: [{ A_Star: {} }] } } } }],
74+
fromClause: [
75+
{
76+
JoinExpr: {
77+
jointype: 'JOIN_INNER',
78+
larg: { RangeVar: { relname: 'users' } },
79+
rarg: { RangeVar: { relname: 'posts' } },
80+
quals: {
81+
A_Expr: {
82+
kind: 'AEXPR_OP',
83+
name: [{ String: { str: '=' } }],
84+
lexpr: {
85+
ColumnRef: {
86+
fields: [
87+
{ String: { str: 'users' } },
88+
{ String: { str: 'id' } }
89+
]
90+
}
91+
},
92+
rexpr: {
93+
ColumnRef: {
94+
fields: [
95+
{ String: { str: 'posts' } },
96+
{ String: { str: 'user_id' } }
97+
]
98+
}
99+
}
100+
}
101+
}
102+
}
103+
}
104+
],
105+
limitOption: 'LIMIT_OPTION_DEFAULT',
106+
op: 'SETOP_NONE'
107+
}
108+
};
109+
110+
const pg17Stmt = transformPG13ToPG17(stmt as any);
111+
const deparsed = await deparse(pg17Stmt);
112+
expect(deparsed).toBe('SELECT * FROM ONLY users JOIN ONLY posts ON users.id = posts.user_id');
113+
});
114+
});

packages/transform/package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,10 @@
3131
"test:watch": "jest --watch"
3232
},
3333
"devDependencies": {
34-
"pg-proto-parser": "^1.28.2"
34+
"pg-proto-parser": "^1.28.2",
35+
"pgsql-deparser": "^17.6.2",
36+
"@pgsql/parser": "^1.0.0",
37+
"libpg-query": "^13.5.2"
3538
},
3639
"keywords": []
3740
}

packages/transform/src/index.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,9 @@ export function transformPG13ToPG17(node: PG13Node): PG17Node {
329329
if ('MergeAction' in node) {
330330
return { MergeAction: transformMergeAction(node.MergeAction) };
331331
}
332+
if ('SelectStmt' in node) {
333+
return { SelectStmt: transformSelectStmt(node.SelectStmt) };
334+
}
332335

333336
throw new Error(`Unknown node type: ${JSON.stringify(node)}`);
334337
}
@@ -1411,10 +1414,43 @@ function transformMergeAction(mergeAction: PG13Types.MergeAction): PG17Types.Mer
14111414
};
14121415
}
14131416

1417+
function transformSelectStmt(selectStmt: PG13Types.SelectStmt): PG17Types.SelectStmt {
1418+
return {
1419+
distinctClause: transformNodeArray(selectStmt.distinctClause),
1420+
intoClause: selectStmt.intoClause ? transformIntoClause(selectStmt.intoClause) : undefined,
1421+
targetList: transformNodeArray(selectStmt.targetList),
1422+
fromClause: transformNodeArray(selectStmt.fromClause),
1423+
whereClause: transformOptionalNode(selectStmt.whereClause),
1424+
groupClause: transformNodeArray(selectStmt.groupClause),
1425+
groupDistinct: selectStmt.groupDistinct,
1426+
havingClause: transformOptionalNode(selectStmt.havingClause),
1427+
windowClause: transformNodeArray(selectStmt.windowClause),
1428+
valuesLists: transformNodeArray(selectStmt.valuesLists),
1429+
sortClause: transformNodeArray(selectStmt.sortClause),
1430+
limitOffset: transformOptionalNode(selectStmt.limitOffset),
1431+
limitCount: transformOptionalNode(selectStmt.limitCount),
1432+
limitOption: selectStmt.limitOption,
1433+
lockingClause: transformNodeArray(selectStmt.lockingClause),
1434+
withClause: selectStmt.withClause ? transformWithClause(selectStmt.withClause) : undefined,
1435+
op: selectStmt.op,
1436+
all: selectStmt.all,
1437+
larg: selectStmt.larg ? transformSelectStmt(selectStmt.larg) : undefined,
1438+
rarg: selectStmt.rarg ? transformSelectStmt(selectStmt.rarg) : undefined
1439+
};
1440+
}
1441+
14141442
function transformTableSampleClause(tableSampleClause: PG13Types.TableSampleClause): PG17Types.TableSampleClause {
14151443
return tableSampleClause as PG17Types.TableSampleClause;
14161444
}
14171445

1446+
function transformWithClause(withClause: PG13Types.WithClause): PG17Types.WithClause {
1447+
return {
1448+
ctes: transformNodeArray(withClause.ctes),
1449+
recursive: withClause.recursive,
1450+
location: withClause.location
1451+
};
1452+
}
1453+
14181454
export { Node as PG13Node } from './13/types';
14191455
export { Node as PG17Node } from './17/types';
14201456
export * as PG13Types from './13/types';

yarn.lock

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1227,6 +1227,16 @@
12271227
node-addon-api "^3.2.1"
12281228
node-gyp-build "^4.3.0"
12291229

1230+
"@pgsql/parser@^1.0.0":
1231+
version "1.0.0"
1232+
resolved "https://registry.yarnpkg.com/@pgsql/parser/-/parser-1.0.0.tgz#5873444ad033b079c7bfe45e6c4d4c0adf020f7e"
1233+
integrity sha512-clOjRiq/s4kbt7LmqGJzqMuiq8RVox5bLkfFRKAZUtg9gYTl7Y9tUNaom6n5fiy12PcI1eOpc0wVzNZ5xOa1FA==
1234+
1235+
"@pgsql/types@^13.11.1":
1236+
version "13.11.1"
1237+
resolved "https://registry.yarnpkg.com/@pgsql/types/-/types-13.11.1.tgz#f822e09bbb553d9a444ced7ad67f4526c8ba389f"
1238+
integrity sha512-5JeN7DZYCVbxPPFI47Z370Jzr3eHZpqgwCdutYWV8e8XtuhxF7UuvWvOsx2oPJe9KnQen0vzJWnVq/61bRvxmw==
1239+
12301240
"@pgsql/types@^17.6.1":
12311241
version "17.6.1"
12321242
resolved "https://registry.yarnpkg.com/@pgsql/types/-/types-17.6.1.tgz#fcbe4910321bd0dfa38aa0c26d87eff7b098d0e9"
@@ -4568,6 +4578,13 @@ [email protected]:
45684578
dependencies:
45694579
"@pgsql/types" "^17.6.1"
45704580

4581+
libpg-query@^13.5.2:
4582+
version "13.5.2"
4583+
resolved "https://registry.yarnpkg.com/libpg-query/-/libpg-query-13.5.2.tgz#138ec937891722097bae7785f5696d0f12781711"
4584+
integrity sha512-fy5fB2+zt4ITNf1NhujlUZ/MuV12R5KvVKZDcCdCY1dtSdb3Im4ePPVqR3p4+MS9dG96Dzg2cUSkmvrePKjqPQ==
4585+
dependencies:
4586+
"@pgsql/types" "^13.11.1"
4587+
45714588
lines-and-columns@^1.1.6:
45724589
version "1.2.4"
45734590
resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632"

0 commit comments

Comments
 (0)