Skip to content

Commit 1278b39

Browse files
committed
feat(plpgsql-deparser): add DehydrationOptions to thread SQL deparse options
- Add DehydrationOptions interface with sqlDeparseOptions field - Thread options through dehydratePlpgsqlAst -> dehydrateNode -> dehydrateQuery - Pass sqlDeparseOptions to Deparser.deparse() for sql-stmt kinds - Export DehydrationOptions from package index This allows callers to control formatting (pretty printing, etc.) of embedded SQL statements inside PL/pgSQL function bodies.
1 parent 070f9a0 commit 1278b39

File tree

2 files changed

+23
-10
lines changed

2 files changed

+23
-10
lines changed

packages/plpgsql-deparser/src/hydrate.ts

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { parseSync, scanSync } from '@libpg-query/parser';
22
import { ParseResult, Node } from '@pgsql/types';
3-
import { Deparser } from 'pgsql-deparser';
3+
import { Deparser, DeparserOptions } from 'pgsql-deparser';
44
import {
55
HydratedExprQuery,
66
HydratedExprRaw,
@@ -15,6 +15,18 @@ import {
1515
} from './hydrate-types';
1616
import { PLpgSQLParseResult } from './types';
1717

18+
/**
19+
* Options for dehydrating (converting back to strings) a hydrated PL/pgSQL AST
20+
*/
21+
export interface DehydrationOptions {
22+
/**
23+
* Options to pass to the SQL deparser when deparsing sql-stmt expressions.
24+
* This allows callers to control formatting (pretty printing, etc.) of
25+
* embedded SQL statements inside PL/pgSQL function bodies.
26+
*/
27+
sqlDeparseOptions?: DeparserOptions;
28+
}
29+
1830
function extractExprFromSelectWrapper(result: ParseResult): Node | undefined {
1931
const stmt = result.stmts?.[0]?.stmt as any;
2032
if (stmt?.SelectStmt?.targetList?.[0]?.ResTarget?.val) {
@@ -352,17 +364,17 @@ export function getOriginalQuery(query: string | HydratedExprQuery): string {
352364
return query.original;
353365
}
354366

355-
export function dehydratePlpgsqlAst<T>(ast: T): T {
356-
return dehydrateNode(ast) as T;
367+
export function dehydratePlpgsqlAst<T>(ast: T, options?: DehydrationOptions): T {
368+
return dehydrateNode(ast, options) as T;
357369
}
358370

359-
function dehydrateNode(node: any): any {
371+
function dehydrateNode(node: any, options?: DehydrationOptions): any {
360372
if (node === null || node === undefined) {
361373
return node;
362374
}
363375

364376
if (Array.isArray(node)) {
365-
return node.map(item => dehydrateNode(item));
377+
return node.map(item => dehydrateNode(item, options));
366378
}
367379

368380
if (typeof node !== 'object') {
@@ -377,7 +389,7 @@ function dehydrateNode(node: any): any {
377389
if (typeof query === 'string') {
378390
dehydratedQuery = query;
379391
} else if (isHydratedExpr(query)) {
380-
dehydratedQuery = dehydrateQuery(query);
392+
dehydratedQuery = dehydrateQuery(query, options?.sqlDeparseOptions);
381393
} else {
382394
dehydratedQuery = String(query);
383395
}
@@ -392,12 +404,12 @@ function dehydrateNode(node: any): any {
392404

393405
const result: any = {};
394406
for (const [key, value] of Object.entries(node)) {
395-
result[key] = dehydrateNode(value);
407+
result[key] = dehydrateNode(value, options);
396408
}
397409
return result;
398410
}
399411

400-
function dehydrateQuery(query: HydratedExprQuery): string {
412+
function dehydrateQuery(query: HydratedExprQuery, sqlDeparseOptions?: DeparserOptions): string {
401413
switch (query.kind) {
402414
case 'assign': {
403415
// For assignments, use the target and value strings directly
@@ -408,10 +420,11 @@ function dehydrateQuery(query: HydratedExprQuery): string {
408420
case 'sql-stmt': {
409421
// Deparse the modified parseResult back to SQL
410422
// This enables AST-based transformations (e.g., schema renaming)
423+
// Pass through sqlDeparseOptions to control formatting (pretty printing, etc.)
411424
const stmtQuery = query as HydratedExprSqlStmt;
412425
if (stmtQuery.parseResult?.stmts?.[0]?.stmt) {
413426
try {
414-
return Deparser.deparse(stmtQuery.parseResult.stmts[0].stmt);
427+
return Deparser.deparse(stmtQuery.parseResult.stmts[0].stmt, sqlDeparseOptions);
415428
} catch {
416429
// Fall back to original if deparse fails
417430
return query.original;

packages/plpgsql-deparser/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,4 @@ export const deparseFunction = async (
2121
export { PLpgSQLDeparser, PLpgSQLDeparserOptions };
2222
export * from './types';
2323
export * from './hydrate-types';
24-
export { hydratePlpgsqlAst, dehydratePlpgsqlAst, isHydratedExpr, getOriginalQuery } from './hydrate';
24+
export { hydratePlpgsqlAst, dehydratePlpgsqlAst, isHydratedExpr, getOriginalQuery, DehydrationOptions } from './hydrate';

0 commit comments

Comments
 (0)