Skip to content

Commit 55704ed

Browse files
committed
docs and tests
1 parent 0aef8e2 commit 55704ed

File tree

5 files changed

+148
-93
lines changed

5 files changed

+148
-93
lines changed

README.md

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -47,25 +47,41 @@ console.log(deparse(stmts));
4747

4848
## Deparser Example
4949

50-
The deparser functionality is provided as a standalone module, enabling you to serialize AST (Abstract Syntax Tree) objects back to SQL statements without the need for the full parsing engine. This separation is particularly beneficial for environments where the native dependencies of the full parser are problematic or unnecessary. For instance, if you already have an AST representation of your SQL query and merely need to convert it back to a SQL string, you can use the pgsql-deparser module directly. This module is implemented in pure TypeScript, avoiding the need for native bindings and thereby simplifying deployment and compatibility across different environments.
50+
The `pgsql-deparser` module serializes ASTs to SQL in pure TypeScript, avoiding the full parser's native dependencies. It's useful when only SQL string conversion from ASTs is needed, and is written in pure TypeScript for easy cross-environment deployment.
5151

52-
Here's how you can use the deparser in your TypeScript code:
52+
Here's how you can use the deparser in your TypeScript code, using [`@pgsql/utils`](https://github.com/launchql/pgsql-parser/tree/main/packages/utils) to create an AST for `deparse`:
5353

5454
```ts
55+
import ast, { SelectStmt } from '@pgsql/utils';
5556
import { deparse } from 'pgsql-deparser';
5657

57-
// Assuming `stmts` is an AST object for the query 'SELECT * FROM test_table'
58-
// This could have been obtained from any source, not necessarily the pgsql-parser
59-
const stmts = getAstFromSomewhere();
60-
61-
// Modify the AST as needed
62-
stmts[0].RawStmt.stmt.SelectStmt.fromClause[0].RangeVar.relname = 'another_table';
58+
// This could have been obtained from any JSON or AST, not necessarily @pgsql/utils
59+
const stmt: SelectStmt = ast.selectStmt({
60+
targetList: [
61+
ast.resTarget({
62+
val: ast.columnRef({
63+
fields: [ast.aStar()]
64+
})
65+
})
66+
],
67+
fromClause: [
68+
ast.rangeVar({
69+
relname: 'some_table',
70+
inh: true,
71+
relpersistence: 'p'
72+
})
73+
],
74+
limitOption: 'LIMIT_OPTION_DEFAULT',
75+
op: 'SETOP_NONE'
76+
});
77+
78+
// Modify the AST if needed
79+
stmt.SelectStmt.fromClause[0].RangeVar.relname = 'another_table';
6380

6481
// Deparse the modified AST back to a SQL string
6582
console.log(deparse(stmts));
6683

67-
// Output: SELECT * FROM "another_table"
68-
84+
// Output: SELECT * FROM another_table
6985
```
7086

7187
## CLI

packages/deparser/README.md

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,25 +30,41 @@ npm install pgsql-deparser
3030

3131
## Deparser Example
3232

33-
The deparser functionality is provided as a standalone module, enabling you to serialize AST (Abstract Syntax Tree) objects back to SQL statements without the need for the full parsing engine. This separation is particularly beneficial for environments where the native dependencies of the full parser are problematic or unnecessary. For instance, if you already have an AST representation of your SQL query and merely need to convert it back to a SQL string, you can use the pgsql-deparser module directly. This module is implemented in pure TypeScript, avoiding the need for native bindings and thereby simplifying deployment and compatibility across different environments.
33+
The `pgsql-deparser` module serializes ASTs to SQL in pure TypeScript, avoiding the full parser's native dependencies. It's useful when only SQL string conversion from ASTs is needed, and is written in pure TypeScript for easy cross-environment deployment.
3434

35-
Here's how you can use the deparser in your TypeScript code:
35+
Here's how you can use the deparser in your TypeScript code, using [`@pgsql/utils`](https://github.com/launchql/pgsql-parser/tree/main/packages/utils) to create an AST for `deparse`:
3636

3737
```ts
38+
import ast, { SelectStmt } from '@pgsql/utils';
3839
import { deparse } from 'pgsql-deparser';
3940

40-
// Assuming `stmts` is an AST object for the query 'SELECT * FROM test_table'
41-
// This could have been obtained from any source, not necessarily the pgsql-parser
42-
const stmts = getAstFromSomewhere();
43-
44-
// Modify the AST as needed
45-
stmts[0].RawStmt.stmt.SelectStmt.fromClause[0].RangeVar.relname = 'another_table';
41+
// This could have been obtained from any JSON or AST, not necessarily @pgsql/utils
42+
const stmt: SelectStmt = ast.selectStmt({
43+
targetList: [
44+
ast.resTarget({
45+
val: ast.columnRef({
46+
fields: [ast.aStar()]
47+
})
48+
})
49+
],
50+
fromClause: [
51+
ast.rangeVar({
52+
relname: 'some_table',
53+
inh: true,
54+
relpersistence: 'p'
55+
})
56+
],
57+
limitOption: 'LIMIT_OPTION_DEFAULT',
58+
op: 'SETOP_NONE'
59+
});
60+
61+
// Modify the AST if needed
62+
stmt.SelectStmt.fromClause[0].RangeVar.relname = 'another_table';
4663

4764
// Deparse the modified AST back to a SQL string
4865
console.log(deparse(stmts));
4966

50-
// Output: SELECT * FROM "another_table"
51-
67+
// Output: SELECT * FROM another_table
5268
```
5369

5470
## Why Use `pgsql-deparser`?

packages/parser/README.md

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -47,25 +47,41 @@ console.log(deparse(stmts));
4747

4848
## Deparser Example
4949

50-
The deparser functionality is provided as a standalone module, enabling you to serialize AST (Abstract Syntax Tree) objects back to SQL statements without the need for the full parsing engine. This separation is particularly beneficial for environments where the native dependencies of the full parser are problematic or unnecessary. For instance, if you already have an AST representation of your SQL query and merely need to convert it back to a SQL string, you can use the pgsql-deparser module directly. This module is implemented in pure TypeScript, avoiding the need for native bindings and thereby simplifying deployment and compatibility across different environments.
50+
The `pgsql-deparser` module serializes ASTs to SQL in pure TypeScript, avoiding the full parser's native dependencies. It's useful when only SQL string conversion from ASTs is needed, and is written in pure TypeScript for easy cross-environment deployment.
5151

52-
Here's how you can use the deparser in your TypeScript code:
52+
Here's how you can use the deparser in your TypeScript code, using [`@pgsql/utils`](https://github.com/launchql/pgsql-parser/tree/main/packages/utils) to create an AST for `deparse`:
5353

5454
```ts
55+
import ast, { SelectStmt } from '@pgsql/utils';
5556
import { deparse } from 'pgsql-deparser';
5657

57-
// Assuming `stmts` is an AST object for the query 'SELECT * FROM test_table'
58-
// This could have been obtained from any source, not necessarily the pgsql-parser
59-
const stmts = getAstFromSomewhere();
60-
61-
// Modify the AST as needed
62-
stmts[0].RawStmt.stmt.SelectStmt.fromClause[0].RangeVar.relname = 'another_table';
58+
// This could have been obtained from any JSON or AST, not necessarily @pgsql/utils
59+
const stmt: SelectStmt = ast.selectStmt({
60+
targetList: [
61+
ast.resTarget({
62+
val: ast.columnRef({
63+
fields: [ast.aStar()]
64+
})
65+
})
66+
],
67+
fromClause: [
68+
ast.rangeVar({
69+
relname: 'some_table',
70+
inh: true,
71+
relpersistence: 'p'
72+
})
73+
],
74+
limitOption: 'LIMIT_OPTION_DEFAULT',
75+
op: 'SETOP_NONE'
76+
});
77+
78+
// Modify the AST if needed
79+
stmt.SelectStmt.fromClause[0].RangeVar.relname = 'another_table';
6380

6481
// Deparse the modified AST back to a SQL string
6582
console.log(deparse(stmts));
6683

67-
// Output: SELECT * FROM "another_table"
68-
84+
// Output: SELECT * FROM another_table
6985
```
7086

7187
## CLI
Lines changed: 41 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,5 @@
11
// Jest Snapshot v1, https://goo.gl/fbAQLP
22

3-
exports[`asts 1`] = `
4-
{
5-
"CreateStmt": {
6-
"relation": {
7-
"RangeVar": {
8-
"relname": "new_table",
9-
},
10-
},
11-
"tableElts": [
12-
{
13-
"ColumnDef": {
14-
"colname": "id",
15-
"typeName": {
16-
"names": [
17-
{
18-
"String": {
19-
"str": "int4",
20-
},
21-
},
22-
],
23-
},
24-
},
25-
},
26-
],
27-
},
28-
}
29-
`;
30-
31-
exports[`asts 2`] = `
32-
"CREATE TABLE (
33-
id int4
34-
)"
35-
`;
36-
373
exports[`dynamic creation of tables 1`] = `
384
"CREATE TABLE (
395
id int PRIMARY KEY ( id ),
@@ -43,14 +9,49 @@ exports[`dynamic creation of tables 1`] = `
439
)"
4410
`;
4511

46-
exports[`getEnumValue 1`] = `"AEXPR_OP"`;
12+
exports[`getEnumValue snapshots 1`] = `"AEXPR_OP"`;
4713

48-
exports[`getEnumValue 2`] = `"AEXPR_OP_ANY"`;
14+
exports[`getEnumValue snapshots 2`] = `"AEXPR_OP_ANY"`;
4915

50-
exports[`getEnumValue 3`] = `"AEXPR_OP_ALL"`;
16+
exports[`getEnumValue snapshots 3`] = `"AEXPR_OP_ALL"`;
5117

52-
exports[`getEnumValue 4`] = `"AEXPR_DISTINCT"`;
18+
exports[`getEnumValue snapshots 4`] = `"AEXPR_DISTINCT"`;
5319

54-
exports[`getEnumValue 5`] = `"AEXPR_NOT_DISTINCT"`;
20+
exports[`getEnumValue snapshots 5`] = `"AEXPR_NOT_DISTINCT"`;
21+
22+
exports[`getEnumValue snapshots 6`] = `"AEXPR_NULLIF"`;
23+
24+
exports[`simple SelectStmt 1`] = `
25+
{
26+
"SelectStmt": {
27+
"fromClause": [
28+
{
29+
"RangeVar": {
30+
"inh": true,
31+
"relname": "another_table",
32+
"relpersistence": "p",
33+
},
34+
},
35+
],
36+
"limitOption": "LIMIT_OPTION_DEFAULT",
37+
"op": "SETOP_NONE",
38+
"targetList": [
39+
{
40+
"ResTarget": {
41+
"val": {
42+
"ColumnRef": {
43+
"fields": [
44+
{
45+
"A_Star": {},
46+
},
47+
],
48+
},
49+
},
50+
},
51+
},
52+
],
53+
},
54+
}
55+
`;
5556

56-
exports[`getEnumValue 6`] = `"AEXPR_NULLIF"`;
57+
exports[`simple SelectStmt 2`] = `"SELECT * FROM another_table"`;

packages/utils/__test__/utils.test.ts

Lines changed: 29 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,41 @@
11
import * as u from '../src';
2-
import ast, { CreateStmt, ColumnDef, SelectStmt } from '../src';
2+
import ast, { SelectStmt } from '../src';
33
import { deparse } from 'pgsql-deparser';
44

5-
it('getEnumValue', () => {
6-
expect(u.getEnumValue('A_Expr_Kind', 0)).toMatchSnapshot();
7-
expect(u.getEnumValue('A_Expr_Kind', 1)).toMatchSnapshot();
8-
expect(u.getEnumValue('A_Expr_Kind', 2)).toMatchSnapshot();
9-
expect(u.getEnumValue('A_Expr_Kind', 3)).toMatchSnapshot();
10-
expect(u.getEnumValue('A_Expr_Kind', 4)).toMatchSnapshot();
11-
expect(u.getEnumValue('A_Expr_Kind', 5)).toMatchSnapshot();
5+
it('getEnumValue snapshots', () => {
6+
for (let i = 0; i <= 5; i++) {
7+
expect(u.getEnumValue('A_Expr_Kind', i)).toMatchSnapshot();
8+
}
129
});
1310

14-
it('asts', () => {
15-
const newColumn: ColumnDef = ast.columnDef({
16-
colname: 'id',
17-
typeName: ast.typeName({
18-
names: [ast.string({ str: 'int4' })]
19-
})
11+
it('simple SelectStmt', () => {
12+
const stmt: SelectStmt = ast.selectStmt({
13+
targetList: [
14+
ast.resTarget({
15+
val: ast.columnRef({
16+
fields: [ast.aStar()]
17+
})
18+
})
19+
],
20+
fromClause: [
21+
ast.rangeVar({
22+
relname: 'some_table',
23+
inh: true,
24+
relpersistence: 'p'
25+
})
26+
],
27+
limitOption: 'LIMIT_OPTION_DEFAULT',
28+
op: 'SETOP_NONE'
2029
});
30+
31+
// @ts-ignore (because of optional args)
32+
stmt.SelectStmt.fromClause[0].RangeVar.relname = 'another_table';
2133

22-
const createStmt: CreateStmt = ast.createStmt({
23-
relation: ast.rangeVar({
24-
relname: 'new_table'
25-
}),
26-
tableElts: [newColumn]
27-
})
28-
expect(createStmt).toMatchSnapshot();
29-
expect(deparse(createStmt, {})).toMatchSnapshot();
34+
expect(stmt).toMatchSnapshot();
35+
expect(deparse(stmt, {})).toMatchSnapshot();
3036
});
3137

32-
it('SelectStmt', () => {
38+
it('SelectStmt with WHERE clause', () => {
3339
const selectStmt: SelectStmt = ast.selectStmt({
3440
targetList: [
3541
ast.resTarget({

0 commit comments

Comments
 (0)