import { SemanticQuery, QueryResult, SecurityContext, DatabaseExecutor, CubeMetadata, Cube, QueryAnalysis, CacheConfig, ExplainOptions, ExplainResult, ExecutionOptions, RLSSetupFn } from './types/index.js'; import { PlanOptimiser } from './logical-plan/index.js'; export { validateQueryAgainstCubes } from './query-validator.js'; export declare class SemanticLayerCompiler { private cubes; private metadataCache?; private cacheConfig?; private rlsSetup?; private planOptimiser?; private db?; private schema?; private engineType?; constructor(options?: { drizzle?: DatabaseExecutor['db']; schema?: any; databaseExecutor?: DatabaseExecutor; engineType?: 'postgres' | 'mysql' | 'sqlite' | 'singlestore' | 'duckdb' | 'databend' | 'snowflake'; /** Cache configuration for query result caching */ cache?: CacheConfig; /** * Row-Level Security setup function. * When provided, every query execution opens a transaction, calls this function * to configure RLS (e.g., set JWT claims and switch roles), then runs the query. * Dry-run/SQL generation is NOT wrapped in a transaction. */ rlsSetup?: RLSSetupFn; /** * Optional logical-plan optimiser injected into every QueryExecutor. * Defaults to a no-op IdentityOptimiser when omitted. */ planOptimiser?: PlanOptimiser; }); /** * Set or update the database connection */ setDatabaseExecutor(executor: DatabaseExecutor): void; /** * Get the database engine type for SQL formatting */ getEngineType(): 'postgres' | 'mysql' | 'sqlite' | 'singlestore' | 'duckdb' | 'databend' | 'snowflake' | undefined; /** * Set Drizzle instance and schema directly */ setDrizzle(db: DatabaseExecutor['db'], schema?: any, engineType?: 'postgres' | 'mysql' | 'sqlite' | 'singlestore' | 'duckdb' | 'databend' | 'snowflake'): void; /** * Check if database executor is configured */ hasExecutor(): boolean; /** * Create a fresh DatabaseExecutor from stored ingredients, or throw. */ private createDbExecutor; /** * Create a query executor with optional cache integration. * Each call creates a fresh DatabaseExecutor so concurrent requests * never share mutable state. */ private createQueryExecutor; /** * Format SQL result using current engine dialect. */ private formatSqlResult; /** * Register a simplified cube with dynamic query building * Validates calculated measures during registration */ registerCube(cube: Cube): void; /** * Validate that all string-based cube references in joins resolve to registered cubes. * Call after all cubes are registered for strict startup validation. * Throws an error listing all unresolved references. */ validateCubeReferences(): void; /** * Validate calculated measures in a cube * Checks template syntax, dependency existence, and circular dependencies */ private validateCalculatedMeasures; /** * Get a cube by name */ getCube(name: string): Cube | undefined; /** * Get all registered cubes */ getAllCubes(): Cube[]; /** * Get all cubes as a Map for multi-cube queries */ getAllCubesMap(): Map; /** * Unified query execution method that handles both single and multi-cube queries * @param options.skipCache - Skip cache lookup (but still cache the fresh result) */ execute(query: SemanticQuery, securityContext: SecurityContext, options?: ExecutionOptions): Promise; /** * Execute a multi-cube query * @param options.skipCache - Skip cache lookup (but still cache the fresh result) */ executeMultiCubeQuery(query: SemanticQuery, securityContext: SecurityContext, options?: ExecutionOptions): Promise; /** * Execute a single cube query */ executeQuery(cubeName: string, query: SemanticQuery, securityContext: SecurityContext): Promise; /** * Get metadata for all cubes (for API responses) * Uses caching to improve performance for repeated requests * Cache is invalidated when cubes are modified (registerCube, removeCube, clearCubes) */ getMetadata(): CubeMetadata[]; /** * Extract column name from Drizzle column reference * Handles different column types and extracts the actual column name */ private getColumnName; /** * Generate cube metadata for API responses from cubes * Includes drill-down support: drillMembers on measures, granularities on time dimensions, hierarchies */ private generateCubeMetadata; /** * Get SQL for a query without executing it (debugging) */ generateSQL(cubeName: string, query: SemanticQuery, securityContext: SecurityContext): Promise<{ sql: string; params?: any[]; }>; /** * Get SQL for a multi-cube query without executing it (debugging) */ generateMultiCubeSQL(query: SemanticQuery, securityContext: SecurityContext): Promise<{ sql: string; params?: any[]; }>; /** * Canonical dry-run SQL generation entrypoint for all query modes. */ dryRun(query: SemanticQuery, securityContext: SecurityContext): Promise<{ sql: string; params?: any[]; }>; /** * Get SQL for a funnel query without executing it (debugging) * Returns the actual CTE-based SQL that would be executed for funnel queries */ dryRunFunnel(query: SemanticQuery, securityContext: SecurityContext): Promise<{ sql: string; params?: any[]; }>; /** * Get SQL for a flow query without executing it (debugging) * Returns the actual CTE-based SQL that would be executed for flow queries */ dryRunFlow(query: SemanticQuery, securityContext: SecurityContext): Promise<{ sql: string; params?: any[]; }>; /** * Generate SQL for a retention query without execution (dry-run) * Returns the CTE-based SQL that would be executed for retention analysis */ dryRunRetention(query: SemanticQuery, securityContext: SecurityContext): Promise<{ sql: string; params?: any[]; }>; /** * Execute EXPLAIN on a query to get the execution plan * Uses the same secure path as execute/dryRun to generate SQL, * then runs database EXPLAIN on it. */ explainQuery(query: SemanticQuery, securityContext: SecurityContext, options?: ExplainOptions): Promise; /** * Check if a cube exists */ hasCube(name: string): boolean; /** * Unregister a cube by name. * Returns true if the cube existed and was removed, false if not found. */ unregisterCube(name: string): boolean; /** * Remove a cube */ removeCube(name: string): boolean; /** * Clear all cubes */ clearCubes(): void; /** * Invalidate the metadata cache * Called whenever cubes are modified */ private invalidateMetadataCache; /** * Get cube names */ getCubeNames(): string[]; /** * Validate a query against registered cubes * Ensures all referenced cubes and fields exist */ validateQuery(query: SemanticQuery): { isValid: boolean; errors: string[]; }; /** * Analyze query planning decisions for debugging and transparency * Returns detailed metadata about how the query would be planned * Used by the playground UI to help users understand query structure */ analyzeQuery(query: SemanticQuery, securityContext: SecurityContext): QueryAnalysis; }