Skip to content

Commit 6ede0eb

Browse files
docs: add RULES.md with correct @pgsql/parser usage patterns
- Document multi-version parser interface (@pgsql/parser) vs wrong single-version parser - Include parse(), PgParser class, and version-specific import examples - Explain sval vs str field naming discrepancy caused by using wrong parser - Prevent future ACU waste by documenting correct parsing approach Co-Authored-By: Dan Lynch <[email protected]>
1 parent b94e607 commit 6ede0eb

File tree

1 file changed

+152
-0
lines changed

1 file changed

+152
-0
lines changed

packages/transform/RULES.md

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
# Transform Package Rules
2+
3+
## Critical Parser Usage
4+
5+
**⚠️ MUST ONLY USE @pgsql/parser for AST parsing in the transform project**
6+
7+
The `@pgsql/parser` is the ONLY multi-version parser that can handle different PostgreSQL versions correctly. Using any other parser (like `/packages/parser/dist/index.js`) will result in incorrect version handling and field naming issues.
8+
9+
## Correct Parser Usage
10+
11+
### Basic Import and Usage
12+
```javascript
13+
import { parse, PgParser } from '@pgsql/parser';
14+
15+
// Parse with specific version
16+
const result15 = await parse('SELECT 1+1 as sum', 15);
17+
console.log(result15);
18+
// { version: 15, result: { version: 150007, stmts: [...] } }
19+
20+
// Using PgParser class
21+
const parser = new PgParser(16);
22+
const result16 = await parser.parse('SELECT * FROM users');
23+
```
24+
25+
### Version-Specific Imports
26+
```javascript
27+
// Import specific version
28+
import * as pg17 from '@pgsql/parser/v17';
29+
30+
await pg17.loadModule();
31+
const result = await pg17.parse('SELECT 1');
32+
console.log(result);
33+
// { version: 170004, stmts: [...] }
34+
```
35+
36+
### Error Handling
37+
```javascript
38+
const result = await parse('INVALID SQL');
39+
if (result.error) {
40+
console.error(result.error);
41+
// { type: 'syntax', message: 'syntax error at or near "INVALID"', position: 0 }
42+
}
43+
```
44+
45+
## What NOT to Use
46+
47+
**NEVER use these incorrect parser imports:**
48+
```javascript
49+
// WRONG - This is NOT multi-version
50+
const parser = require('/home/ubuntu/pgsql-parser/packages/parser/dist/index.js');
51+
const pg13Result = await parser.parse(sql, { version: 130000 });
52+
const pg14Result = await parser.parse(sql, { version: 140000 });
53+
```
54+
55+
## Field Naming Issues
56+
57+
When using the wrong parser:
58+
- All versions return the same result version (170004)
59+
- String nodes use "sval" fields instead of version-appropriate field names
60+
- Version parameters are ignored
61+
- Transformations fail because they're not testing actual version differences
62+
63+
When using the correct @pgsql/parser:
64+
- Each version returns its proper version number
65+
- Field names match the actual PostgreSQL version specifications
66+
- String nodes use correct field names per version
67+
- Transformations work because they test real version differences
68+
69+
## Debug Script Template
70+
71+
```javascript
72+
import { parse, PgParser } from '@pgsql/parser';
73+
74+
async function debugTransformation() {
75+
const testSql = `SELECT 'test'`;
76+
77+
// Parse with different versions
78+
const pg13Result = await parse(testSql, 13);
79+
const pg14Result = await parse(testSql, 14);
80+
81+
console.log(`PG13 version: ${pg13Result.version}`);
82+
console.log(`PG14 version: ${pg14Result.version}`);
83+
84+
// Now you'll see actual version differences
85+
const pg13Str = JSON.stringify(pg13Result, null, 2);
86+
const pg14Str = JSON.stringify(pg14Result, null, 2);
87+
88+
// Check for field differences
89+
const pg13StrCount = (pg13Str.match(/"str":/g) || []).length;
90+
const pg13SvalCount = (pg13Str.match(/"sval":/g) || []).length;
91+
const pg14StrCount = (pg14Str.match(/"str":/g) || []).length;
92+
const pg14SvalCount = (pg14Str.match(/"sval":/g) || []).length;
93+
94+
console.log(`PG13: "str" fields: ${pg13StrCount}, "sval" fields: ${pg13SvalCount}`);
95+
console.log(`PG14: "str" fields: ${pg14StrCount}, "sval" fields: ${pg14SvalCount}`);
96+
}
97+
```
98+
99+
## Transformer Testing
100+
101+
When testing transformers, always use the correct parser:
102+
103+
```javascript
104+
import { parse } from '@pgsql/parser';
105+
import { ASTTransformer } from '../dist/index.js';
106+
107+
async function testTransformer() {
108+
const transformer = new ASTTransformer();
109+
const sql = `ALTER TABLE test ADD CONSTRAINT name CHECK (col = 'value')`;
110+
111+
// Parse with correct versions
112+
const pg13Result = await parse(sql, 13);
113+
const pg14Result = await parse(sql, 14);
114+
115+
// Transform PG13 to PG14
116+
const astToTransform = JSON.parse(JSON.stringify(pg13Result.result));
117+
118+
if (astToTransform.stmts && Array.isArray(astToTransform.stmts)) {
119+
astToTransform.stmts = astToTransform.stmts.map((stmtWrapper) => {
120+
if (stmtWrapper.stmt) {
121+
const transformedStmt = transformer.transform(stmtWrapper.stmt, 13, 14);
122+
return { ...stmtWrapper, stmt: transformedStmt };
123+
}
124+
return stmtWrapper;
125+
});
126+
}
127+
128+
astToTransform.version = pg14Result.result.version;
129+
130+
// Compare transformed result with actual PG14 result
131+
const expectedStr = JSON.stringify(pg14Result.result, null, 2);
132+
const transformedStr = JSON.stringify(astToTransform, null, 2);
133+
134+
if (expectedStr === transformedStr) {
135+
console.log('✅ Transformation successful');
136+
} else {
137+
console.log('❌ Transformation failed');
138+
}
139+
}
140+
```
141+
142+
## Key Lessons Learned
143+
144+
1. **Parser Selection is Critical**: Using the wrong parser wastes significant compute resources and produces incorrect results
145+
2. **Version Parameters Must Work**: If all versions return the same result, you're using the wrong parser
146+
3. **Field Names Matter**: Different PostgreSQL versions use different field names, and transformers must handle these correctly
147+
4. **Test Framework Alignment**: Debug scripts must use the same parser as the actual test framework
148+
5. **ACU Conservation**: Using the correct tools from the start prevents wasted debugging cycles
149+
150+
## Summary
151+
152+
Always use `@pgsql/parser` for multi-version PostgreSQL AST parsing in the transform package. This is the only way to get accurate version-specific results and build working transformers.

0 commit comments

Comments
 (0)