rawsql-ts
Version:
[beta]High-performance SQL parser and AST analyzer written in TypeScript. Provides fast parsing and advanced transformation capabilities.
215 lines (214 loc) • 8.31 kB
TypeScript
/**
* Enum for duplicate detection modes in SelectableColumnCollector.
* Determines how duplicates are identified during column collection.
*/
export declare enum DuplicateDetectionMode {
/**
* Detect duplicates based only on column names.
* This mode ignores the table name, so columns with the same name
* from different tables are considered duplicates.
*/
ColumnNameOnly = "columnNameOnly",
/**
* Detect duplicates based on both table and column names.
* This mode ensures that columns with the same name from different
* tables are treated as distinct.
*/
FullName = "fullName"
}
import { SqlComponent, SqlComponentVisitor } from "../models/SqlComponent";
import { ValueComponent } from "../models/ValueComponent";
import { TableColumnResolver } from "./TableColumnResolver";
/**
* A visitor that collects all ColumnReference instances from SQL query structures.
* This visitor scans through all clauses and collects all unique ColumnReference objects.
* It supports both regular column collection and upstream column collection for maximum
* search conditions in DynamicQuery scenarios.
*
* Supported query types:
* - SimpleSelectQuery: Basic SELECT queries with all standard clauses
* - BinarySelectQuery: UNION, INTERSECT, EXCEPT queries (collects from both sides)
* - Common Table Expressions (CTEs) within queries
* - Subqueries and nested queries
*
* Behavioral notes:
* - Collects column references to tables defined in the root FROM/JOIN clauses
* - For aliased columns (e.g., 'title as name'), collects both the original column
* reference ('title') AND the alias ('name') to enable complete dependency tracking
* - When upstream option is enabled, collects all available columns from upstream sources
* (CTEs, subqueries, and tables) for maximum search conditions in DynamicQuery
* - Automatically removes duplicates based on the specified duplicate detection mode
*
* Use cases:
* - Dependency analysis and schema migration tools
* - Column usage tracking across complex queries including unions and CTEs
* - Security analysis for column-level access control
* - DynamicQuery maximum search condition column discovery
*
* @example
* ```typescript
* // Basic usage - collect only referenced columns
* const collector = new SelectableColumnCollector();
* const columns = collector.collect(query);
*
* // With upstream collection for DynamicQuery
* const upstreamCollector = new SelectableColumnCollector(
* null, false, DuplicateDetectionMode.ColumnNameOnly,
* { upstream: true }
* );
* const allColumns = upstreamCollector.collect(query);
*
* // Works with union queries and CTEs
* const unionQuery = SelectQueryParser.parse(`
* SELECT name, email FROM users
* UNION
* SELECT name, email FROM customers
* `);
* const unionColumns = collector.collect(unionQuery);
* ```
*/
export declare class SelectableColumnCollector implements SqlComponentVisitor<void> {
private handlers;
private selectValues;
private visitedNodes;
private uniqueKeys;
private isRootVisit;
private tableColumnResolver;
private commonTableCollector;
private commonTables;
private includeWildCard;
private duplicateDetection;
private options;
/**
* Creates a new instance of SelectableColumnCollector.
*
* @param {TableColumnResolver | null} [tableColumnResolver=null] - The resolver used to resolve column references to their respective tables.
* @param {boolean} [includeWildCard=false] - If true, wildcard columns (e.g., `*`) are included in the collection.
* @param {DuplicateDetectionMode} [duplicateDetection=DuplicateDetectionMode.ColumnNameOnly] - Specifies the duplicate detection mode: 'columnNameOnly' (default, only column name is used), or 'fullName' (table name + column name).
* @param {Object} [options={}] - Additional options for the collector.
* @param {boolean} [options.ignoreCaseAndUnderscore=false] - If true, column names are compared without considering case and underscores.
* @param {boolean} [options.upstream=false] - If true, collect all columns available from upstream sources for maximum search conditions in DynamicQuery.
*/
constructor(tableColumnResolver?: TableColumnResolver | null, includeWildCard?: boolean, duplicateDetection?: DuplicateDetectionMode, options?: {
ignoreCaseAndUnderscore?: boolean;
upstream?: boolean;
});
/**
* Initialize instance properties.
*/
private initializeProperties;
/**
* Initialize the handler map for different SQL component types.
*/
private initializeHandlers;
/**
* Initialize handlers for SQL clause types.
*/
private initializeClauseHandlers;
/**
* Initialize handlers for value component types.
*/
private initializeValueComponentHandlers;
getValues(): {
name: string;
value: ValueComponent;
}[];
collect(arg: SqlComponent): {
name: string;
value: ValueComponent;
}[];
/**
* Reset the collection of ColumnReferences
*/
private reset;
/**
* Add a select value as unique, according to the duplicate detection option.
* Uses efficient Set-based duplicate detection for better performance.
*/
private addSelectValueAsUnique;
/**
* Generate a unique key based on the duplicate detection mode.
*/
private generateUniqueKey;
/**
* Normalize column name based on options.
* Ensures safe string handling to prevent injection attacks.
*/
private normalizeColumnName;
/**
* Main entry point for the visitor pattern.
* Implements the shallow visit pattern to distinguish between root and recursive visits.
*/
visit(arg: SqlComponent): void;
/**
* Internal visit method used for all nodes.
* This separates the visit flag management from the actual node visitation logic.
*/
private visitNode;
/**
* Process a SimpleSelectQuery to collect ColumnReferences from all its clauses
*/
private visitSimpleSelectQuery;
/**
* Process a BinarySelectQuery (UNION, INTERSECT, EXCEPT) to collect ColumnReferences from both sides
*/
private visitBinarySelectQuery;
private visitSelectClause;
private visitFromClause;
private visitWhereClause;
private visitGroupByClause;
private visitHavingClause;
private visitOrderByClause;
private visitWindowFrameClause;
private visitWindowFrameExpression;
private visitLimitClause;
private offsetClause;
private visitFetchClause;
private visitJoinOnClause;
private visitJoinUsingClause;
private visitColumnReference;
private visitBinaryExpression;
private visitUnaryExpression;
private visitFunctionCall;
private visitInlineQuery;
private visitParenExpression;
private visitCaseExpression;
private visitCastExpression;
private visitBetweenExpression;
private visitArrayExpression;
private visitArrayQueryExpression;
private visitArraySliceExpression;
private visitArrayIndexExpression;
private visitValueList;
private visitPartitionByClause;
/**
* Collect all upstream columns available for DynamicQuery maximum search conditions.
* This includes columns from CTEs, subqueries, and tables that can be used for filtering.
*/
private collectUpstreamColumns;
/**
* Collect upstream columns from a specific source (table, subquery, or CTE).
*/
private collectUpstreamColumnsFromSource;
/**
* Collect upstream columns from a table source using table column resolver.
*/
private collectUpstreamColumnsFromTable;
/**
* Collect upstream columns from a subquery source.
*/
private collectUpstreamColumnsFromSubquery;
/**
* Collect upstream columns from a CTE.
*/
private collectUpstreamColumnsFromCTE;
/**
* Collect columns from ALL available CTEs for upstream functionality.
* This ensures that complex multi-CTE queries have all available columns for filtering.
*/
private collectAllAvailableCTEColumns;
/**
* Find a CTE by name in the common tables.
*/
private findCTEByName;
}