rawsql-ts
Version:
[beta]High-performance SQL parser and AST analyzer written in TypeScript. Provides fast parsing and advanced transformation capabilities.
137 lines (136 loc) • 4.97 kB
TypeScript
import { SqlFormatterOptions } from "./SqlFormatter";
/**
* Interface representing an edited CTE with simplified structure
* @public
*/
export interface EditedCTE {
/** Name of the CTE */
name: string;
/** SQL query for this CTE, may contain WITH clause from editing */
query: string;
}
/**
* Options for CTEComposer extending SqlFormatterOptions
* @public
*/
export interface CTEComposerOptions extends SqlFormatterOptions {
/** Whether to validate the composed query against a schema */
validateSchema?: boolean;
/** Table to columns mapping for schema validation (required if validateSchema is true) */
schema?: Record<string, string[]>;
}
/**
* Composes edited CTEs back into a unified SQL query
*
* Takes CTEs that were individually edited after decomposition and reconstructs them
* into a proper WITH clause structure. This completes the CTE debugging workflow:
* 1. Use CTEQueryDecomposer to break down complex CTEs
* 2. Edit individual CTEs to fix issues
* 3. Use CTEComposer to reconstruct the unified query
*
* @example
* ```typescript
* // After decomposing and editing CTEs
* const composer = new CTEComposer({
* preset: 'postgres',
* validateSchema: true,
* schema: { users: ['id', 'name', 'active'] }
* });
*
* const editedCTEs = [
* { name: 'base_data', query: 'select * from users where active = true' },
* { name: 'filtered_data', query: 'select * from base_data where region = "US"' }
* ];
*
* const composedSQL = composer.compose(editedCTEs, 'select * from filtered_data');
* // Dependencies are automatically analyzed and sorted
* // Result: "with base_data as (...), filtered_data as (...) select * from filtered_data"
* ```
*
* @public
*/
export declare class CTEComposer {
private readonly formatter;
private readonly options;
private readonly dependencyAnalyzer;
private knownCTENames;
/**
* Creates a new CTEComposer instance
* @param options - Configuration options extending SqlFormatterOptions
*/
constructor(options?: CTEComposerOptions);
/**
* Compose edited CTEs and root query into a unified SQL query
*
* This method:
* 1. Extracts pure SELECT queries from edited CTEs (removes any WITH clauses)
* 2. Builds a temporary query to analyze dependencies automatically
* 3. Sorts CTEs by dependency order using topological sort
* 4. Validates schema if options.validateSchema is enabled
* 5. Applies formatter options for consistent output
* 6. Constructs the final WITH clause with proper recursive handling
*
* @param editedCTEs - Array of edited CTEs with name and query only
* @param rootQuery - The main query that uses the CTEs (without WITH clause)
* @returns Composed SQL query with properly structured WITH clause
* @throws Error if schema validation fails or circular dependencies are detected
*
* @example
* ```typescript
* const editedCTEs = [
* { name: 'base_data', query: 'select * from users where active = true' },
* { name: 'filtered_data', query: 'select * from base_data where region = "US"' }
* ];
*
* const result = composer.compose(editedCTEs, 'select count(*) from filtered_data');
* // Dependencies automatically analyzed and sorted
* // Result: "with base_data as (...), filtered_data as (...) select count(*) from filtered_data"
* ```
*/
compose(editedCTEs: EditedCTE[], rootQuery: string): string;
/**
* Extract pure SELECT query from a query that may contain WITH clause
* If query contains WITH with known CTEs, extract main SELECT and ignore old definitions
* If query contains WITH with unknown CTEs, preserve entire query
* @param query The query that may contain WITH clause
* @param cteName The name of the CTE to extract (if query contains WITH)
* @returns Pure SELECT query without WITH clause, or entire query if it contains new sub-CTEs
*/
private extractPureQuery;
/**
* Get list of known CTE names from current composition context
*/
private getKnownCTENames;
/**
* Extract CTE name from CommonTable
*/
private getCTEName;
/**
* Extract CTE definition using regex as fallback
*/
private extractCTEWithRegex;
/**
* Build a temporary query for dependency analysis
*/
private buildTempQueryForAnalysis;
/**
* Sort CTEs by dependencies using dependency graph
*/
private sortCTEsByDependencies;
/**
* Detect if any CTEs are recursive by analyzing original queries
*/
private detectRecursiveFromOriginalQueries;
/**
* Detect if any CTEs are recursive
*/
private detectRecursiveCTEs;
/**
* Validate the composed query against schema
*/
private validateComposedQuery;
/**
* Apply formatting to the final query
*/
private formatFinalQuery;
}