A comprehensive monorepo for PostgreSQL Abstract Syntax Tree (AST) parsing, manipulation, and code generation. This collection of packages provides everything you need to work with PostgreSQL at the AST level, from parsing SQL queries to generating type-safe TypeScript definitions.
Choose the packages you need:
# For parsing SQL to AST and back (includes deparser) npm install pgsql-parser # For only converting AST to SQL (lighter weight) npm install pgsql-deparser # For the unified CLI tool npm install -g @pgsql/cli # For programmatic AST construction npm install @pgsql/utils # For programmatic AST visiting/traversal npm install @pgsql/traverse # For protobuf parsing and code generation npm install pg-proto-parser
import { parse } from 'pgsql-parser'; const ast = await parse('SELECT * FROM users WHERE id = 1'); console.log(JSON.stringify(ast, null, 2)); // {"version":170004,"stmts":[{"stmt":{"SelectStmt":{"targetList":[{"ResTarget": ... ,"op":"SETOP_NONE"}}}]}
import { deparse } from 'pgsql-deparser'; const sql = await deparse(ast); console.log(sql); // SELECT * FROM users WHERE id = 1
import { deparse } from 'pgsql-deparser'; import { SelectStmt } from '@pgsql/types'; const stmt: { SelectStmt: SelectStmt } = { SelectStmt: { targetList: [ { ResTarget: { val: { ColumnRef: { fields: [{ A_Star: {} }] } } } } ], fromClause: [ { RangeVar: { relname: 'some_table', inh: true, relpersistence: 'p' } } ], limitOption: 'LIMIT_OPTION_DEFAULT', op: 'SETOP_NONE' } }; await deparse(stmt);Build AST Programmatically
import * as t from '@pgsql/utils'; import { deparse } from 'pgsql-deparser'; import { SelectStmt } from '@pgsql/types'; const stmt: { SelectStmt: SelectStmt } = t.nodes.selectStmt({ targetList: [ t.nodes.resTarget({ val: t.nodes.columnRef({ fields: [t.nodes.aStar()] }) }) ], fromClause: [ t.nodes.rangeVar({ relname: 'some_table', inh: true, relpersistence: 'p' }) ], limitOption: 'LIMIT_OPTION_DEFAULT', op: 'SETOP_NONE' }); await deparse(stmt);
import { walk, NodePath } from '@pgsql/traverse'; import type { Walker, Visitor } from '@pgsql/traverse'; // Using a simple walker function const walker: Walker = (path: NodePath) => { console.log(`Visiting ${path.tag} at path:`, path.path); // Return false to skip traversing children if (path.tag === 'SelectStmt') { return false; // Skip SELECT statement children } }; walk(ast, walker); // Using a visitor object (recommended for multiple node types) const visitor: Visitor = { SelectStmt: (path) => { console.log('SELECT statement:', path.node); }, RangeVar: (path) => { console.log('Table:', path.node.relname); console.log('Path to table:', path.path); console.log('Parent node:', path.parent?.tag); } }; walk(ast, visitor);Package Description Key Features pgsql-parser The real PostgreSQL parser for Node.js • Uses actual PostgreSQL C parser via WebAssembly
This project uses Yarn workspaces and Lerna for monorepo management. See DEVELOPMENT.md for more info.
# Install dependencies yarn install # Build all packages yarn buildBuilding Individual Packages
cd packages/parser npm run build
import { parse } from 'pgsql-parser'; import { deparse } from 'pgsql-deparser'; // Parse the original query const ast = await parse('SELECT * FROM users WHERE active = true'); // Modify the table name ast[0].RawStmt.stmt.SelectStmt.fromClause[0].RangeVar.relname = 'customers'; // Generate the modified SQL const newSql = await deparse(ast); console.log(newSql); // SELECT * FROM customers WHERE active = TRUEBuild a Query Programmatically
import ast from '@pgsql/utils'; import { deparse } from 'pgsql-deparser'; const query: { SelectStmt: SelectStmt } = t.nodes.selectStmt({ targetList: [ t.nodes.resTarget({ val: t.nodes.columnRef({ fields: [t.nodes.string({ sval: 'name' })] }) }), t.nodes.resTarget({ val: t.nodes.columnRef({ fields: [t.nodes.string({ sval: 'email' })] }) }) ], fromClause: [ t.nodes.rangeVar({ relname: 'users', inh: true, relpersistence: 'p' }) ], whereClause: t.nodes.aExpr({ kind: 'AEXPR_OP', name: [t.nodes.string({ sval: '>' })], lexpr: t.nodes.columnRef({ fields: [t.nodes.string({ sval: 'age' })] }), rexpr: t.nodes.aConst({ ival: t.ast.integer({ ival: 18 }) }) }), limitOption: 'LIMIT_OPTION_DEFAULT', op: 'SETOP_NONE' }); console.log(await deparse(query)); // SELECT name, email FROM users WHERE age > 18
pgsql-parser
.pgsql-parser
for parsing and deparsing SQL queries.AS DESCRIBED IN THE LICENSES, THE SOFTWARE IS PROVIDED "AS IS", AT YOUR OWN RISK, AND WITHOUT WARRANTIES OF ANY KIND.
No developer or entity involved in creating Software will be liable for any claims or damages whatsoever associated with your use, inability to use, or your interaction with other users of the Software code or Software CLI, including any direct, indirect, incidental, special, exemplary, punitive or consequential damages, or loss of profits, cryptocurrencies, tokens, or anything else of value.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4