rawsql-ts
Version:
High-performance SQL parser and AST analyzer written in TypeScript. Provides fast parsing and advanced transformation capabilities.
321 lines (320 loc) • 12.9 kB
TypeScript
import { FromClause, JoinClause, JoinOnClause, JoinUsingClause, FunctionSource, SourceAliasExpression, WhereClause, GroupByClause, HavingClause, SubQuerySource, WindowFrameClause, LimitClause, ForClause, OffsetClause, WindowsClause as WindowClause, CommonTable, WithClause, FetchClause, FetchExpression, UpdateClause, DeleteClause, UsingClause, SetClause, ReturningClause, SetClauseItem } from "../models/Clause";
import { SimpleSelectQuery, ValuesQuery } from "../models/SelectQuery";
import { SqlComponent, SqlComponentVisitor } from "../models/SqlComponent";
import { SqlPrintToken } from "../models/SqlPrintToken";
import { InlineQuery } from "../models/ValueComponent";
import { IdentifierDecorator } from "./IdentifierDecorator";
import { ParameterDecorator } from "./ParameterDecorator";
import { CreateTableQuery } from "../models/CreateTableQuery";
export declare enum ParameterStyle {
Anonymous = "anonymous",
Indexed = "indexed",
Named = "named"
}
export type CastStyle = 'postgres' | 'standard';
export type ConstraintStyle = 'postgres' | 'mysql';
export interface FormatterConfig {
identifierEscape?: {
start: string;
end: string;
};
parameterSymbol?: string | {
start: string;
end: string;
};
/**
* Parameter style: anonymous (?), indexed ($1), or named (:name)
*/
parameterStyle?: ParameterStyle;
/** Controls how CAST expressions are rendered */
castStyle?: CastStyle;
/** Controls how table/column constraints are rendered */
constraintStyle?: ConstraintStyle;
}
export declare const PRESETS: Record<string, FormatterConfig>;
export declare class SqlPrintTokenParser implements SqlComponentVisitor<SqlPrintToken> {
private static readonly SPACE_TOKEN;
private static readonly COMMA_TOKEN;
private static readonly ARGUMENT_SPLIT_COMMA_TOKEN;
private static readonly PAREN_OPEN_TOKEN;
private static readonly PAREN_CLOSE_TOKEN;
private static readonly DOT_TOKEN;
private static _selfHandlingComponentTypes;
private static getSelfHandlingComponentTypes;
private handlers;
parameterDecorator: ParameterDecorator;
identifierDecorator: IdentifierDecorator;
index: number;
private castStyle;
private constraintStyle;
private readonly normalizeJoinConditionOrder;
private joinConditionContexts;
constructor(options?: {
preset?: FormatterConfig;
identifierEscape?: {
start: string;
end: string;
};
parameterSymbol?: string | {
start: string;
end: string;
};
parameterStyle?: 'anonymous' | 'indexed' | 'named';
castStyle?: CastStyle;
constraintStyle?: ConstraintStyle;
joinConditionOrderByDeclaration?: boolean;
});
/**
* Pretty-prints a BinarySelectQuery (e.g., UNION, INTERSECT, EXCEPT).
* This will recursively print left and right queries, separated by the operator.
* @param arg BinarySelectQuery
*/
private visitBinarySelectQuery;
/**
* Returns an array of tokens representing a comma followed by a space.
* This is a common pattern in SQL pretty-printing.
*/
private static commaSpaceTokens;
private static argumentCommaSpaceTokens;
private visitQualifiedName;
private visitPartitionByClause;
private visitOrderByClause;
/**
* Print an OrderByItem (expression [asc|desc] [nulls first|last])
*/
private visitOrderByItem;
parse(arg: SqlComponent): {
token: SqlPrintToken;
params: any[] | Record<string, any>[] | Record<string, any>;
};
/**
* Check if a component handles its own comments
*/
private componentHandlesOwnComments;
visit(arg: SqlComponent): SqlPrintToken;
/**
* Check if a component has positioned comments
*/
private hasPositionedComments;
/**
* Check if a component has legacy comments
*/
private hasLegacyComments;
/**
* Centralized comment handling - checks positioned comments first, falls back to legacy
*/
private addComponentComments;
/**
* Adds positioned comment tokens to a SqlPrintToken for inline formatting
*/
private addPositionedCommentsToToken;
/**
* Adds comment tokens to a SqlPrintToken based on the comments array
*/
private addCommentsToToken;
/**
* Creates inline comment sequence for multiple comments without newlines
*/
private createInlineCommentSequence;
/**
* Creates CommentBlock containers for the given comments.
* Each CommentBlock contains: Comment -> CommentNewline -> Space.
* @param comments Raw comment strings to convert into CommentBlock tokens.
* @param isHeaderComment Marks the generated blocks as originating from header comments when true.
*/
private createCommentBlocks;
/**
* Determines if a comment should be merged with consecutive comments
*/
private shouldMergeComment;
/**
* Creates a multi-line block comment structure from consecutive comments
* Returns a CommentBlock containing multiple comment lines for proper LinePrinter integration
*/
/**
* Creates a single CommentBlock with the standard structure:
* Comment -> CommentNewline -> Space
*
* This structure supports both formatting modes:
* - Multiline mode: Comment + newline (space is filtered as leading space)
* - Oneliner mode: Comment + space (commentNewline is skipped)
*/
private createSingleCommentBlock;
/**
* Formats a comment, preserving line comment format for -- comments
* and converting others to block format for safety
*/
private formatComment;
/**
* Inserts comment blocks into a token and handles spacing logic.
* Adds separator spaces for clause-level containers and manages duplicate space removal.
*/
private insertCommentBlocksWithSpacing;
/**
* Handles positioned comments for ParenExpression with special spacing rules.
* ParenExpression comments should be adjacent to parentheses without separator spaces.
*/
private addPositionedCommentsToParenExpression;
/**
* Determines whether a separator space should be added after comments for the given container type.
*
* Clause-level containers (SELECT, FROM, WHERE, etc.) need separator spaces because:
* - Comments appear before the main clause content
* - A space is needed to separate comment block from SQL tokens
*
* Item-level containers (SelectItem, etc.) don't need separator spaces because:
* - Comments are inline with the item content
* - Spacing is handled by existing token structure
*/
private shouldAddSeparatorSpace;
/**
* Checks if the container type represents a SQL clause (as opposed to an item within a clause).
*/
private isClauseLevelContainer;
/**
* Formats a comment string as a block comment with security sanitization.
* Prevents SQL injection by removing dangerous comment sequences.
*/
private formatBlockComment;
private shouldMergeHeaderComments;
private createHeaderMultiLineCommentBlock;
/**
* Formats text as a single-line comment while sanitizing unsafe sequences.
*/
private formatLineComment;
/**
* Sanitizes content intended for a single-line comment.
*/
private sanitizeLineCommentContent;
private escapeCommentDelimiters;
private visitValueList;
private visitColumnReference;
private visitFunctionCall;
private relocateGroupingSetComments;
private isGroupingSetsFunction;
private extractPositionedComments;
private visitUnaryExpression;
private visitBinaryExpression;
private visitLiteralValue;
private visitParameterExpression;
private visitSwitchCaseArgument;
private createElseToken;
private visitCaseKeyValuePair;
private visitRawString;
private visitIdentifierString;
private visitParenExpression;
private visitCastExpression;
private visitCaseExpression;
private extractSwitchAfterComments;
private collectCaseLeadingCommentsFromSwitch;
private findCaseKeyToken;
private collectCaseLeadingCommentBlocks;
private collectCaseLeadingCommentBlocksRecursive;
private isTransparentCaseWrapper;
private commentBlockSignature;
private visitArrayExpression;
private visitArrayQueryExpression;
private visitArraySliceExpression;
private visitArrayIndexExpression;
private visitBetweenExpression;
private visitStringSpecifierExpression;
private visitTypeValue;
private visitTupleExpression;
private tupleRequiresMultiline;
private hasInlineComments;
private hasLeadingComments;
private visitWindowFrameExpression;
private visitWindowFrameSpec;
/**
* Prints a window frame boundary value, such as "5 preceding" or "3 following".
* @param arg WindowFrameBoundaryValue
*/
private visitWindowFrameBoundaryValue;
/**
* Prints a static window frame bound, such as "unbounded preceding", "current row", or "unbounded following".
* @param arg WindowFrameBoundStatic
*/
private visitWindowFrameBoundStatic;
private visitSelectItem;
private visitSelectClause;
private flattenTokenText;
private visitHintClause;
private visitDistinct;
private visitDistinctOn;
private visitTableSource;
private visitSourceExpression;
visitFromClause(arg: FromClause): SqlPrintToken;
visitJoinClause(arg: JoinClause): SqlPrintToken;
visitJoinOnClause(arg: JoinOnClause): SqlPrintToken;
private getCurrentJoinAliasOrder;
private buildJoinAliasOrder;
private collectSourceIdentifiers;
private normalizeJoinConditionValue;
private normalizeBinaryEquality;
private resolveColumnOwner;
visitJoinUsingClause(arg: JoinUsingClause): SqlPrintToken;
visitFunctionSource(arg: FunctionSource): SqlPrintToken;
visitSourceAliasExpression(arg: SourceAliasExpression): SqlPrintToken;
visitWhereClause(arg: WhereClause): SqlPrintToken;
visitGroupByClause(arg: GroupByClause): SqlPrintToken;
visitHavingClause(arg: HavingClause): SqlPrintToken;
visitWindowClause(arg: WindowClause): SqlPrintToken;
visitWindowFrameClause(arg: WindowFrameClause): SqlPrintToken;
visitLimitClause(arg: LimitClause): SqlPrintToken;
visitOffsetClause(arg: OffsetClause): SqlPrintToken;
visitFetchClause(arg: FetchClause): SqlPrintToken;
visitFetchExpression(arg: FetchExpression): SqlPrintToken;
visitForClause(arg: ForClause): SqlPrintToken;
visitWithClause(arg: WithClause): SqlPrintToken;
visitCommonTable(arg: CommonTable): SqlPrintToken;
visitSimpleQuery(arg: SimpleSelectQuery): SqlPrintToken;
visitSubQuerySource(arg: SubQuerySource): SqlPrintToken;
visitValuesQuery(arg: ValuesQuery): SqlPrintToken;
visitInlineQuery(arg: InlineQuery): SqlPrintToken;
private visitInsertQuery;
private visitInsertClause;
private visitDeleteQuery;
visitDeleteClause(arg: DeleteClause): SqlPrintToken;
visitUsingClause(arg: UsingClause): SqlPrintToken;
private visitMergeQuery;
private visitMergeWhenClause;
private visitMergeUpdateAction;
private visitMergeDeleteAction;
private visitMergeInsertAction;
private visitMergeDoNothingAction;
private mergeMatchTypeToKeyword;
private visitUpdateQuery;
visitUpdateClause(arg: UpdateClause): SqlPrintToken;
visitSetClause(arg: SetClause): SqlPrintToken;
visitSetClauseItem(arg: SetClauseItem): SqlPrintToken;
visitReturningClause(arg: ReturningClause): SqlPrintToken;
visitCreateTableQuery(arg: CreateTableQuery): SqlPrintToken;
private visitTableColumnDefinition;
private visitColumnConstraintDefinition;
private visitTableConstraintDefinition;
private wrapWithParenExpression;
private visitReferenceDefinition;
private visitCreateIndexStatement;
private visitCreateSequenceStatement;
private visitAlterSequenceStatement;
private visitSequenceClauses;
private visitSequenceClause;
private visitIndexColumnDefinition;
private visitDropTableStatement;
private visitDropIndexStatement;
private visitAlterTableStatement;
private visitAlterTableAddConstraint;
private visitAlterTableDropConstraint;
private visitAlterTableAddColumn;
private visitAlterTableDropColumn;
private visitAlterTableAlterColumnDefault;
private visitDropConstraintStatement;
private visitExplainStatement;
private visitAnalyzeStatement;
private renderExplainOption;
private isExplainLegacyFlag;
private isExplainBooleanTrue;
private renderQualifiedNameInline;
private renderIdentifierInline;
private renderIdentifierText;
}