Skip to content

Commit 2a40481

Browse files
committed
docs(pgsql-types): add README with experimental warning and DefElem example
1 parent d6d6ac3 commit 2a40481

File tree

1 file changed

+126
-0
lines changed

1 file changed

+126
-0
lines changed

packages/pgsql-types/README.md

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
# pgsql-types
2+
3+
<p align="center" width="100%">
4+
<img height="250" src="https://raw.githubusercontent.com/constructive-io/constructive/refs/heads/main/assets/outline-logo.svg" />
5+
</p>
6+
7+
<p align="center" width="100%">
8+
<a href="https://github.com/constructive-io/pgsql-parser/actions/workflows/run-tests.yaml">
9+
<img height="20" src="https://github.com/constructive-io/pgsql-parser/actions/workflows/run-tests.yaml/badge.svg" />
10+
</a>
11+
<a href="https://github.com/constructive-io/pgsql-parser/blob/main/LICENSE-MIT"><img height="20" src="https://img.shields.io/badge/license-MIT-blue.svg"/></a>
12+
<a href="https://www.npmjs.com/package/pgsql-types"><img height="20" src="https://img.shields.io/github/package-json/v/constructive-io/pgsql-parser?filename=packages%2Fpgsql-types%2Fpackage.json"/></a>
13+
</p>
14+
15+
Narrowed TypeScript type definitions for PostgreSQL AST nodes.
16+
17+
> **Experimental:** This package provides narrowed types inferred from real SQL usage patterns. For production use, see [`@pgsql/types`](https://www.npmjs.com/package/@pgsql/types). However, please kick the tires and let us know what you think!
18+
19+
## Overview
20+
21+
This package provides TypeScript type definitions for PostgreSQL AST nodes with **narrowed `Node` unions**. Instead of generic `Node` types that could be any of ~250 node types, fields are narrowed to only the specific types that actually appear in practice.
22+
23+
The narrowed types are inferred by parsing thousands of SQL statements from PostgreSQL's test suite and tracking which node types appear in each field.
24+
25+
## Installation
26+
27+
```bash
28+
npm install pgsql-types
29+
```
30+
31+
## The Problem
32+
33+
With `@pgsql/types`, the `arg` field in `DefElem` is typed as `Node` - a union of all possible AST node types:
34+
35+
```typescript
36+
// @pgsql/types
37+
export interface DefElem {
38+
defnamespace?: string;
39+
defname?: string;
40+
arg?: Node; // Could be any of ~250 types!
41+
defaction?: DefElemAction;
42+
location?: number;
43+
}
44+
```
45+
46+
When processing the AST, you have no guidance on what types to actually handle.
47+
48+
## The Solution
49+
50+
With `pgsql-types`, the same field is narrowed to only the types that actually appear:
51+
52+
```typescript
53+
// pgsql-types
54+
export interface DefElem {
55+
defnamespace?: string;
56+
defname?: string;
57+
arg?: { A_Const: A_Const }
58+
| { A_Star: A_Star }
59+
| { Boolean: Boolean }
60+
| { Float: Float }
61+
| { Integer: Integer }
62+
| { List: List }
63+
| { String: String }
64+
| { TypeName: TypeName }
65+
| { VariableSetStmt: VariableSetStmt };
66+
defaction?: DefElemAction;
67+
location?: number;
68+
}
69+
```
70+
71+
Now you know exactly which cases to handle when processing `DefElem.arg`.
72+
73+
## Usage
74+
75+
```typescript
76+
import { DefElem, SelectStmt, CreateStmt } from 'pgsql-types';
77+
78+
function processDefElem(elem: DefElem) {
79+
if (elem.arg) {
80+
// TypeScript knows arg can only be one of 9 specific types
81+
if ('String' in elem.arg) {
82+
console.log('String value:', elem.arg.String.sval);
83+
} else if ('Integer' in elem.arg) {
84+
console.log('Integer value:', elem.arg.Integer.ival);
85+
} else if ('List' in elem.arg) {
86+
console.log('List with', elem.arg.List.items?.length, 'items');
87+
}
88+
// ... handle other cases
89+
}
90+
}
91+
```
92+
93+
## How It Works
94+
95+
The narrowed types are generated by:
96+
97+
1. Parsing all SQL fixtures from PostgreSQL's regression test suite (~70,000 statements)
98+
2. Walking each AST and tracking which node types appear in each `Node`-typed field
99+
3. Generating TypeScript interfaces with narrowed unions based on the observed types
100+
101+
This approach ensures the narrowed types reflect real-world usage patterns from PostgreSQL's own test suite.
102+
103+
## Exports
104+
105+
This package exports:
106+
107+
- All narrowed interfaces (e.g., `SelectStmt`, `CreateStmt`, `DefElem`, etc.)
108+
- The `Node` type from `@pgsql/types`
109+
- All enums from `@pgsql/enums`
110+
111+
## Limitations
112+
113+
- The narrowed types are based on SQL fixtures and may not cover every possible valid AST structure
114+
- Some rarely-used node combinations may not be included in the narrowed unions
115+
- For maximum type safety in production, consider using `@pgsql/types` with runtime validation
116+
117+
## Related Packages
118+
119+
- [`@pgsql/types`](https://www.npmjs.com/package/@pgsql/types) - Production TypeScript types for PostgreSQL AST
120+
- [`@pgsql/enums`](https://www.npmjs.com/package/@pgsql/enums) - PostgreSQL enum definitions
121+
- [`pgsql-parser`](https://www.npmjs.com/package/pgsql-parser) - Parse SQL to AST
122+
- [`pgsql-deparser`](https://www.npmjs.com/package/pgsql-deparser) - Convert AST back to SQL
123+
124+
## License
125+
126+
MIT

0 commit comments

Comments
 (0)