
Security News
arXiv Is Rate Limiting Authors Following a Flood of AI Slop Submissions
arXiv now limits authors to two submissions a month as AI slop overwhelms moderators, delays good papers, and sparks debate over applying the limit to everyone.
@pgsql/traverse
Advanced tools
PostgreSQL AST traversal utilities for pgsql-parser. This package provides a visitor pattern for traversing PostgreSQL Abstract Syntax Tree (AST) nodes, similar to Babel's traverse functionality but specifically designed for PostgreSQL AST structures.
npm install @pgsql/traverse
The walk function provides improved traversal with NodePath context and early return support:
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);
The NodePath class provides rich context information:
class NodePath<TTag extends NodeTag = NodeTag> {
tag: TTag; // Node type (e.g., 'SelectStmt', 'RangeVar')
node: Node[TTag]; // The actual node data
parent: NodePath | null; // Parent NodePath (null for root)
keyPath: readonly (string | number)[]; // Full path array
get path(): (string | number)[]; // Copy of keyPath
get key(): string | number; // Last element of path
}
The new implementation uses PostgreSQL's runtime schema to precisely determine which fields contain Node types that need traversal, eliminating guesswork and improving accuracy.
The original visit function is still available for backward compatibility:
import { visit } from '@pgsql/traverse';
const visitor = {
SelectStmt: (node, ctx) => {
console.log('Found SELECT statement:', node);
console.log('Path:', ctx.path);
},
RangeVar: (node, ctx) => {
console.log('Found table reference:', node.relname);
}
};
// Parse some SQL and traverse the AST
const ast = /* your parsed AST */;
visit(ast, visitor);
import { walk } from '@pgsql/traverse';
const visitor = {
ParseResult: (path) => {
console.log('Parse result version:', path.node.version);
console.log('Number of statements:', path.node.stmts.length);
},
SelectStmt: (path) => {
console.log('SELECT statement found');
}
};
walk(parseResult, visitor);
The visitor context provides information about the current traversal state:
const visitor = {
RangeVar: (path) => {
console.log('Table name:', path.node.relname);
console.log('Path to this node:', path.path);
console.log('Parent node:', path.parent?.tag);
console.log('Key in parent:', path.key);
}
};
import { visit } from '@pgsql/traverse';
import type { Visitor } from '@pgsql/traverse';
const tableNames: string[] = [];
const columnRefs: string[] = [];
const visitor: Visitor = {
RangeVar: (node) => {
if (node.relname) {
tableNames.push(node.relname);
}
},
ColumnRef: (node) => {
if (node.fields) {
node.fields.forEach(field => {
if (field.String?.sval) {
columnRefs.push(field.String.sval);
}
});
}
}
};
visit(ast, visitor);
console.log('Tables referenced:', tableNames);
console.log('Columns referenced:', columnRefs);
walk(root, callback, parent?, keyPath?)Walks the tree of PostgreSQL AST nodes using runtime schema for precise traversal.
Parameters:
root: The AST node to traversecallback: A walker function or visitor objectparent?: Optional parent NodePath (for internal use)keyPath?: Optional key path array (for internal use)Example:
walk(ast, {
SelectStmt: (path) => {
// Handle SELECT statements
// Return false to skip children
},
RangeVar: (path) => {
// Handle table references
}
});
visit(node, visitor, ctx?) (Legacy)Recursively visits a PostgreSQL AST node, calling any matching visitor functions. Maintained for backward compatibility.
Parameters:
node: The AST node to traversevisitor: An object with visitor functions for different node typesctx?: Optional initial visitor contextVisitorAn object type where keys are node type names and values are walker functions:
type Visitor = {
[TTag in NodeTag]?: Walker<NodePath<TTag>>;
};
WalkerA function that receives a NodePath and can return false to skip children:
type Walker<TNodePath extends NodePath = NodePath> = (
path: TNodePath,
) => boolean | void;
NodePathA class that encapsulates node traversal context:
class NodePath<TTag extends NodeTag = NodeTag> {
tag: TTag; // Node type
node: Node[TTag]; // Node data
parent: NodePath | null; // Parent path
keyPath: readonly (string | number)[]; // Full path
get path(): (string | number)[]; // Path copy
get key(): string | number; // Current key
}
VisitorContext (Legacy)Context information provided to legacy visitor functions:
type VisitorContext = {
path: (string | number)[]; // Path to current node
parent: any; // Parent node
key: string | number; // Key in parent node
};
NodeTagUnion type of all PostgreSQL AST node type names:
type NodeTag = keyof Node;
This package works with all PostgreSQL AST node types defined in @pgsql/types, including:
ParseResult - Root parse result from libpg-querySelectStmt - SELECT statementsInsertStmt - INSERT statementsUpdateStmt - UPDATE statementsDeleteStmt - DELETE statementsRangeVar - Table referencesColumnRef - Column referencesA_Expr - ExpressionsA_Const - ConstantsThis package is designed to work seamlessly with the pgsql-parser ecosystem:
import { parse } from 'pgsql-parser';
import { visit } from '@pgsql/traverse';
const sql = 'SELECT name, email FROM users WHERE age > 18';
const ast = await parse(sql);
const visitor = {
RangeVar: (node) => {
console.log('Table:', node.relname);
},
ColumnRef: (node) => {
console.log('Column:', node.fields?.[0]?.String?.sval);
}
};
visit(ast, visitor);
🛠 Built by the Constructive team — creators of modular Postgres tooling for secure, composable backends. If you like our work, contribute on GitHub.
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.
FAQs
PostgreSQL AST traversal utilities for pgsql-parser
The npm package @pgsql/traverse receives a total of 246,078 weekly downloads. As such, @pgsql/traverse popularity was classified as popular.
We found that @pgsql/traverse demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Security News
arXiv now limits authors to two submissions a month as AI slop overwhelms moderators, delays good papers, and sparks debate over applying the limit to everyone.

Research
/Security News
A new GhostAction wave hits hundreds of GitHub repos, expanding CI/CD secret theft to cloud and AI credentials in source code and git history.

Research
/Security News
Tensorlake npm SDK version 0.5.144 was compromised in a ChainDrop / Shai-Hulud attack, delivering credential-stealing malware.