pgsql-deparser
Version:
PostgreSQL AST Deparser
301 lines (300 loc) • 19.9 kB
TypeScript
import { Node } from '@pgsql/types';
import { DeparserContext, DeparserVisitor } from './visitors/base';
import * as t from '@pgsql/types';
export interface DeparserOptions {
newline?: string;
tab?: string;
functionDelimiter?: string;
functionDelimiterFallback?: string;
pretty?: boolean;
}
/**
* Deparser - Converts PostgreSQL AST nodes back to SQL strings
*
* Entry Points:
* 1. ParseResult (from libpg-query) - The complete parse result
* Structure: { version: number, stmts: RawStmt[] }
* Note: stmts is "repeated RawStmt" in protobuf, so array contains RawStmt
* objects inline (not wrapped as { RawStmt: ... } nodes)
* Example: { version: 170004, stmts: [{ stmt: {...}, stmt_len: 32 }] }
*
* 2. Wrapped ParseResult - When explicitly wrapped as a Node
* Structure: { ParseResult: { version: number, stmts: RawStmt[] } }
*
* 3. Wrapped RawStmt - When explicitly wrapped as a Node
* Structure: { RawStmt: { stmt: Node, stmt_len?: number } }
*
* 4. Array of Nodes - Multiple statements to deparse
* Can be: Node[] (e.g., SelectStmt, InsertStmt, etc.)
*
* 5. Single Node - Individual statement node
* Example: { SelectStmt: {...} }, { InsertStmt: {...} }, etc.
*
* The deparser automatically detects bare ParseResult objects for backward
* compatibility and wraps them internally for consistent processing.
*/
export declare class Deparser implements DeparserVisitor {
private tree;
private options;
constructor(tree: Node | Node[] | t.ParseResult, opts?: DeparserOptions);
/**
* Static method to deparse PostgreSQL AST nodes to SQL
* @param query - Can be:
* - ParseResult from libpg-query (e.g., { version: 170004, stmts: [...] })
* - Wrapped ParseResult node (e.g., { ParseResult: {...} })
* - Wrapped RawStmt node (e.g., { RawStmt: {...} })
* - Array of Nodes
* - Single Node (e.g., { SelectStmt: {...} })
* @param opts - Deparser options for formatting
* @returns The deparsed SQL string
*/
static deparse(query: Node | Node[] | t.ParseResult, opts?: DeparserOptions): string;
deparseQuery(): string;
/**
* Get the appropriate function delimiter based on the body content
* @param body The function body to check
* @returns The delimiter to use
*/
private getFunctionDelimiter;
deparse(node: Node, context?: DeparserContext): string | null;
visit(node: Node, context?: DeparserContext): string;
getNodeType(node: Node): string;
getNodeData(node: Node): any;
ParseResult(node: t.ParseResult, context: DeparserContext): string;
RawStmt(node: t.RawStmt, context: DeparserContext): string;
SelectStmt(node: t.SelectStmt, context: DeparserContext): string;
A_Expr(node: t.A_Expr, context: DeparserContext): string;
deparseOperatorName(name: t.Node[], context: DeparserContext): string;
private getOperatorPrecedence;
private needsParentheses;
private isComplexExpression;
private isComplexSelectTarget;
visitBetweenRange(rexpr: any, context: DeparserContext): string;
InsertStmt(node: t.InsertStmt, context: DeparserContext): string;
UpdateStmt(node: t.UpdateStmt, context: DeparserContext): string;
DeleteStmt(node: t.DeleteStmt, context: DeparserContext): string;
WithClause(node: t.WithClause, context: DeparserContext): string;
ResTarget(node: t.ResTarget, context: DeparserContext): string;
deparseReturningList(list: t.Node[], context: DeparserContext): string;
BoolExpr(node: t.BoolExpr, context: DeparserContext): string;
FuncCall(node: t.FuncCall, context: DeparserContext): string;
FuncExpr(node: t.FuncExpr, context: DeparserContext): string;
A_Const(node: t.A_Const, context: DeparserContext): string;
ColumnRef(node: t.ColumnRef, context: DeparserContext): string;
TypeName(node: t.TypeName, context: DeparserContext): string;
Alias(node: t.Alias, context: DeparserContext): string;
RangeVar(node: t.RangeVar, context: DeparserContext): string;
formatIntervalTypeMods(typmods: t.Node[], context: DeparserContext): string | null;
formatTypeMods(typmods: t.Node[], context: DeparserContext): string | null;
formatSingleTypeMod(typemod: number, typeName: string): string | null;
getPgCatalogTypeName(typeName: string, size: string | null): string;
isPgCatalogType(typeName: string): boolean;
A_ArrayExpr(node: t.A_ArrayExpr, context: DeparserContext): string;
A_Indices(node: t.A_Indices, context: DeparserContext): string;
A_Indirection(node: t.A_Indirection, context: DeparserContext): string;
A_Star(node: t.A_Star, context: DeparserContext): string;
CaseExpr(node: t.CaseExpr, context: DeparserContext): string;
CoalesceExpr(node: t.CoalesceExpr, context: DeparserContext): string;
TypeCast(node: t.TypeCast, context: DeparserContext): string;
CollateClause(node: t.CollateClause, context: DeparserContext): string;
BooleanTest(node: t.BooleanTest, context: DeparserContext): string;
NullTest(node: t.NullTest, context: DeparserContext): string;
private static readonly RESERVED_WORDS;
private static needsQuotes;
quoteIfNeeded(value: string): string;
preserveOperatorDefElemCase(defName: string): string;
String(node: t.String, context: DeparserContext): string;
Integer(node: t.Integer, context: DeparserContext): string;
Float(node: t.Float, context: DeparserContext): string;
Boolean(node: t.Boolean, context: DeparserContext): string;
BitString(node: t.BitString, context: DeparserContext): string;
Null(node: t.Node, context: DeparserContext): string;
List(node: t.List, context: DeparserContext): string;
CreateStmt(node: t.CreateStmt, context: DeparserContext): string;
ColumnDef(node: t.ColumnDef, context: DeparserContext): string;
Constraint(node: t.Constraint, context: DeparserContext): string;
SubLink(node: t.SubLink, context: DeparserContext): string;
CaseWhen(node: t.CaseWhen, context: DeparserContext): string;
WindowDef(node: t.WindowDef, context: DeparserContext): string;
formatWindowFrame(node: any, context: DeparserContext): string | null;
SortBy(node: t.SortBy, context: DeparserContext): string;
GroupingSet(node: t.GroupingSet, context: DeparserContext): string;
CommonTableExpr(node: t.CommonTableExpr, context: DeparserContext): string;
ParamRef(node: t.ParamRef, context: DeparserContext): string;
LockingClause(node: any, context: DeparserContext): string;
MinMaxExpr(node: t.MinMaxExpr, context: DeparserContext): string;
RowExpr(node: t.RowExpr, context: DeparserContext): string;
OpExpr(node: t.OpExpr, context: DeparserContext): string;
DistinctExpr(node: t.DistinctExpr, context: DeparserContext): string;
NullIfExpr(node: t.NullIfExpr, context: DeparserContext): string;
ScalarArrayOpExpr(node: t.ScalarArrayOpExpr, context: DeparserContext): string;
Aggref(node: t.Aggref, context: DeparserContext): string;
WindowFunc(node: t.WindowFunc, context: DeparserContext): string;
FieldSelect(node: t.FieldSelect, context: DeparserContext): string;
RelabelType(node: t.RelabelType, context: DeparserContext): string;
CoerceViaIO(node: t.CoerceViaIO, context: DeparserContext): string;
ArrayCoerceExpr(node: t.ArrayCoerceExpr, context: DeparserContext): string;
ConvertRowtypeExpr(node: t.ConvertRowtypeExpr, context: DeparserContext): string;
NamedArgExpr(node: t.NamedArgExpr, context: DeparserContext): string;
ViewStmt(node: t.ViewStmt, context: DeparserContext): string;
IndexStmt(node: t.IndexStmt, context: DeparserContext): string;
IndexElem(node: t.IndexElem, context: DeparserContext): string;
PartitionElem(node: t.PartitionElem, context: DeparserContext): string;
PartitionCmd(node: t.PartitionCmd, context: DeparserContext): string;
private getAggFunctionName;
private getWindowFunctionName;
private getOperatorName;
JoinExpr(node: t.JoinExpr, context: DeparserContext): string;
FromExpr(node: t.FromExpr, context: DeparserContext): string;
TransactionStmt(node: t.TransactionStmt, context: DeparserContext): string;
VariableSetStmt(node: t.VariableSetStmt, context: DeparserContext): string;
VariableShowStmt(node: t.VariableShowStmt, context: DeparserContext): string;
CreateSchemaStmt(node: t.CreateSchemaStmt, context: DeparserContext): string;
RoleSpec(node: t.RoleSpec, context: DeparserContext): string;
roletype(node: any, context: DeparserContext): string;
DropStmt(node: t.DropStmt, context: DeparserContext): string;
TruncateStmt(node: t.TruncateStmt, context: DeparserContext): string;
ReturnStmt(node: t.ReturnStmt, context: DeparserContext): string;
PLAssignStmt(node: t.PLAssignStmt, context: DeparserContext): string;
CopyStmt(node: t.CopyStmt, context: DeparserContext): string;
AlterTableStmt(node: t.AlterTableStmt, context: DeparserContext): string;
AlterTableCmd(node: t.AlterTableCmd, context: DeparserContext): string;
CreateFunctionStmt(node: t.CreateFunctionStmt, context: DeparserContext): string;
FunctionParameter(node: t.FunctionParameter, context: DeparserContext): string;
CreateEnumStmt(node: t.CreateEnumStmt, context: DeparserContext): string;
CreateDomainStmt(node: t.CreateDomainStmt, context: DeparserContext): string;
CreateRoleStmt(node: t.CreateRoleStmt, context: DeparserContext): string;
DefElem(node: t.DefElem, context: DeparserContext): string;
CreateTableSpaceStmt(node: t.CreateTableSpaceStmt, context: DeparserContext): string;
DropTableSpaceStmt(node: t.DropTableSpaceStmt, context: DeparserContext): string;
AlterTableSpaceOptionsStmt(node: t.AlterTableSpaceOptionsStmt, context: DeparserContext): string;
CreateExtensionStmt(node: t.CreateExtensionStmt, context: DeparserContext): string;
AlterExtensionStmt(node: t.AlterExtensionStmt, context: DeparserContext): string;
CreateFdwStmt(node: t.CreateFdwStmt, context: DeparserContext): string;
SetOperationStmt(node: t.SetOperationStmt, context: DeparserContext): string;
ReplicaIdentityStmt(node: t.ReplicaIdentityStmt, context: DeparserContext): string;
AlterCollationStmt(node: t.AlterCollationStmt, context: DeparserContext): string;
AlterDomainStmt(node: t.AlterDomainStmt, context: DeparserContext): string;
PrepareStmt(node: t.PrepareStmt, context: DeparserContext): string;
ExecuteStmt(node: t.ExecuteStmt, context: DeparserContext): string;
DeallocateStmt(node: t.DeallocateStmt, context: DeparserContext): string;
NotifyStmt(node: t.NotifyStmt, context: DeparserContext): string;
ListenStmt(node: t.ListenStmt, context: DeparserContext): string;
UnlistenStmt(node: t.UnlistenStmt, context: DeparserContext): string;
CheckPointStmt(node: t.CheckPointStmt, context: DeparserContext): string;
LoadStmt(node: t.LoadStmt, context: DeparserContext): string;
DiscardStmt(node: t.DiscardStmt, context: DeparserContext): string;
CommentStmt(node: t.CommentStmt, context: DeparserContext): string;
LockStmt(node: t.LockStmt, context: DeparserContext): string;
CreatePolicyStmt(node: t.CreatePolicyStmt, context: DeparserContext): string;
AlterPolicyStmt(node: t.AlterPolicyStmt, context: DeparserContext): string;
CreateUserMappingStmt(node: t.CreateUserMappingStmt, context: DeparserContext): string;
CreateStatsStmt(node: t.CreateStatsStmt, context: DeparserContext): string;
StatsElem(node: t.StatsElem, context: DeparserContext): string;
CreatePublicationStmt(node: t.CreatePublicationStmt, context: DeparserContext): string;
CreateSubscriptionStmt(node: t.CreateSubscriptionStmt, context: DeparserContext): string;
AlterPublicationStmt(node: t.AlterPublicationStmt, context: DeparserContext): string;
AlterSubscriptionStmt(node: t.AlterSubscriptionStmt, context: DeparserContext): string;
DropSubscriptionStmt(node: t.DropSubscriptionStmt, context: DeparserContext): string;
DoStmt(node: t.DoStmt, context: DeparserContext): string;
private generateUniqueDollarTag;
InlineCodeBlock(node: t.InlineCodeBlock, context: DeparserContext): string;
CallContext(node: t.CallContext, context: DeparserContext): string;
ConstraintsSetStmt(node: t.ConstraintsSetStmt, context: DeparserContext): string;
AlterSystemStmt(node: t.AlterSystemStmt, context: DeparserContext): string;
VacuumRelation(node: t.VacuumRelation, context: DeparserContext): string;
DropOwnedStmt(node: t.DropOwnedStmt, context: DeparserContext): string;
ReassignOwnedStmt(node: t.ReassignOwnedStmt, context: DeparserContext): string;
AlterTSDictionaryStmt(node: t.AlterTSDictionaryStmt, context: DeparserContext): string;
AlterTSConfigurationStmt(node: t.AlterTSConfigurationStmt, context: DeparserContext): string;
ClosePortalStmt(node: t.ClosePortalStmt, context: DeparserContext): string;
FetchStmt(node: t.FetchStmt, context: DeparserContext): string;
AlterStatsStmt(node: t.AlterStatsStmt, context: DeparserContext): string;
ObjectWithArgs(node: t.ObjectWithArgs, context: DeparserContext): string;
AlterOperatorStmt(node: t.AlterOperatorStmt, context: DeparserContext): string;
AlterFdwStmt(node: t.AlterFdwStmt, context: DeparserContext): string;
CreateForeignServerStmt(node: t.CreateForeignServerStmt, context: DeparserContext): string;
AlterForeignServerStmt(node: t.AlterForeignServerStmt, context: DeparserContext): string;
AlterUserMappingStmt(node: t.AlterUserMappingStmt, context: DeparserContext): string;
DropUserMappingStmt(node: t.DropUserMappingStmt, context: DeparserContext): string;
ImportForeignSchemaStmt(node: t.ImportForeignSchemaStmt, context: DeparserContext): string;
ClusterStmt(node: t.ClusterStmt, context: DeparserContext): string;
VacuumStmt(node: t.VacuumStmt, context: DeparserContext): string;
ExplainStmt(node: t.ExplainStmt, context: DeparserContext): string;
ReindexStmt(node: t.ReindexStmt, context: DeparserContext): string;
CallStmt(node: t.CallStmt, context: DeparserContext): string;
CreatedbStmt(node: t.CreatedbStmt, context: DeparserContext): string;
DropdbStmt(node: t.DropdbStmt, context: DeparserContext): string;
RenameStmt(node: t.RenameStmt, context: DeparserContext): string;
AlterOwnerStmt(node: t.AlterOwnerStmt, context: DeparserContext): string;
GrantStmt(node: t.GrantStmt, context: DeparserContext): string;
GrantRoleStmt(node: t.GrantRoleStmt, context: DeparserContext): string;
SecLabelStmt(node: t.SecLabelStmt, context: DeparserContext): string;
AlterDefaultPrivilegesStmt(node: t.AlterDefaultPrivilegesStmt, context: DeparserContext): string;
CreateConversionStmt(node: t.CreateConversionStmt, context: DeparserContext): string;
CreateCastStmt(node: t.CreateCastStmt, context: DeparserContext): string;
CreatePLangStmt(node: t.CreatePLangStmt, context: DeparserContext): string;
CreateTransformStmt(node: t.CreateTransformStmt, context: DeparserContext): string;
CreateTrigStmt(node: t.CreateTrigStmt, context: DeparserContext): string;
TriggerTransition(node: t.TriggerTransition, context: DeparserContext): string;
CreateEventTrigStmt(node: t.CreateEventTrigStmt, context: DeparserContext): string;
AlterEventTrigStmt(node: t.AlterEventTrigStmt, context: DeparserContext): string;
CreateOpClassStmt(node: t.CreateOpClassStmt, context: DeparserContext): string;
CreateOpFamilyStmt(node: t.CreateOpFamilyStmt, context: DeparserContext): string;
AlterOpFamilyStmt(node: t.AlterOpFamilyStmt, context: DeparserContext): string;
MergeStmt(node: t.MergeStmt, context: DeparserContext): string;
AlterTableMoveAllStmt(node: t.AlterTableMoveAllStmt, context: DeparserContext): string;
CreateSeqStmt(node: t.CreateSeqStmt, context: DeparserContext): string;
AlterSeqStmt(node: t.AlterSeqStmt, context: DeparserContext): string;
CompositeTypeStmt(node: t.CompositeTypeStmt, context: DeparserContext): string;
CreateRangeStmt(node: t.CreateRangeStmt, context: DeparserContext): string;
AlterEnumStmt(node: t.AlterEnumStmt, context: DeparserContext): string;
AlterTypeStmt(node: t.AlterTypeStmt, context: DeparserContext): string;
AlterRoleStmt(node: t.AlterRoleStmt, context: DeparserContext): string;
DropRoleStmt(node: t.DropRoleStmt, context: DeparserContext): string;
targetList(node: any, context: DeparserContext): string;
CreateAggregateStmt(node: t.DefineStmt, context: DeparserContext): string;
CreateTableAsStmt(node: t.CreateTableAsStmt, context: DeparserContext): string;
RefreshMatViewStmt(node: t.RefreshMatViewStmt, context: DeparserContext): string;
AccessPriv(node: t.AccessPriv, context: DeparserContext): string;
aliasname(node: any, context: DeparserContext): string;
DefineStmt(node: t.DefineStmt, context: DeparserContext): string;
AlterDatabaseStmt(node: t.AlterDatabaseStmt, context: DeparserContext): string;
AlterDatabaseRefreshCollStmt(node: t.AlterDatabaseRefreshCollStmt, context: DeparserContext): string;
AlterDatabaseSetStmt(node: t.AlterDatabaseSetStmt, context: DeparserContext): string;
DeclareCursorStmt(node: t.DeclareCursorStmt, context: DeparserContext): string;
PublicationObjSpec(node: t.PublicationObjSpec, context: DeparserContext): string;
PublicationTable(node: t.PublicationTable, context: DeparserContext): string;
CreateAmStmt(node: t.CreateAmStmt, context: DeparserContext): string;
IntoClause(node: t.IntoClause, context: DeparserContext): string;
OnConflictExpr(node: t.OnConflictExpr, context: DeparserContext): string;
ScanToken(node: t.ScanToken, context: DeparserContext): string;
CreateOpClassItem(node: t.CreateOpClassItem, context: DeparserContext): string;
Var(node: t.Var, context: DeparserContext): string;
TableFunc(node: t.TableFunc, context: DeparserContext): string;
RangeTableFunc(node: t.RangeTableFunc, context: DeparserContext): string;
RangeTableFuncCol(node: t.RangeTableFuncCol, context: DeparserContext): string;
JsonArrayQueryConstructor(node: t.JsonArrayQueryConstructor, context: DeparserContext): string;
RangeFunction(node: t.RangeFunction, context: DeparserContext): string;
XmlExpr(node: t.XmlExpr, context: DeparserContext): string;
schemaname(node: any, context: DeparserContext): string;
RangeTableSample(node: t.RangeTableSample, context: DeparserContext): string;
XmlSerialize(node: t.XmlSerialize, context: DeparserContext): string;
ctes(node: any, context: DeparserContext): string;
RuleStmt(node: t.RuleStmt, context: DeparserContext): string;
RangeSubselect(node: t.RangeSubselect, context: DeparserContext): string;
relname(node: any, context: DeparserContext): string;
rel(node: any, context: DeparserContext): string;
objname(node: any, context: DeparserContext): string;
SQLValueFunction(node: t.SQLValueFunction, context: DeparserContext): string;
GroupingFunc(node: t.GroupingFunc, context: DeparserContext): string;
MultiAssignRef(node: t.MultiAssignRef, context: DeparserContext): string;
SetToDefault(node: t.SetToDefault, context: DeparserContext): string;
CurrentOfExpr(node: t.CurrentOfExpr, context: DeparserContext): string;
TableLikeClause(node: t.TableLikeClause, context: DeparserContext): string;
AlterFunctionStmt(node: t.AlterFunctionStmt, context: DeparserContext): string;
AlterObjectSchemaStmt(node: t.AlterObjectSchemaStmt, context: DeparserContext): string;
AlterRoleSetStmt(node: t.AlterRoleSetStmt, context: DeparserContext): string;
CreateForeignTableStmt(node: t.CreateForeignTableStmt, context: DeparserContext): string;
private containsMultilineStringLiteral;
}