@simonecoelhosfo/optimizely-mcp-server
Version:
Optimizely MCP Server for AI assistants with integrated CLI tools
135 lines • 3.87 kB
TypeScript
/**
* JOIN Cardinality Guard - Prevent Query Explosion
*
* CRITICAL COMPONENT: Prevents Cartesian product explosions by:
* 1. Estimating JOIN multiplication factors
* 2. Enforcing cardinality limits based on query type
* 3. Automatically injecting DISTINCT when necessary
* 4. Providing fallback strategies for dangerous JOINs
*
* Created: July 5, 2025
* Purpose: Second line of defense against 700-1400x count inflation
*/
export interface CardinalityEstimate {
fromTable: string;
toTable: string;
estimatedFromRows: number;
estimatedToRows: number;
relationshipType: 'one-to-one' | 'one-to-many' | 'many-to-many';
expectedMultiplier: number;
confidence: number;
}
export interface CardinalityLimits {
simpleCount: number;
groupByCount: number;
crossEntity: number;
detail: number;
maxExecutionTime: number;
}
export interface CardinalityGuardConfig {
enabled: boolean;
limits: CardinalityLimits;
autoDistinct: boolean;
fallbackEnabled: boolean;
debugMode: boolean;
}
export declare class CardinalityGuard {
private config;
private tableStats;
private joinHistograms;
constructor(config?: Partial<CardinalityGuardConfig>);
/**
* Validate if a set of JOINs is safe based on cardinality estimation
*/
validateJoinCardinality(joins: Array<{
fromTable: string;
toTable: string;
joinType: string;
}>, queryType: 'count' | 'groupBy' | 'crossEntity' | 'detail', queryContext?: {
whereConditions?: Array<{
field: string;
operator: string;
value: any;
}>;
groupByFields?: string[];
}): {
isValid: boolean;
totalMultiplier: number;
estimates: CardinalityEstimate[];
recommendations: string[];
fallbackSQL?: string;
};
/**
* Estimate cardinality for a single JOIN
*/
private estimateJoinCardinality;
/**
* Calculate total multiplication factor for all JOINs
*/
private calculateTotalMultiplier;
/**
* Get cardinality limit for query type
*/
private getLimitForQueryType;
/**
* Determine relationship type between two tables
*/
private determineRelationshipType;
/**
* Check if this is a known dangerous JOIN pattern
*/
private isDangerousJoinPattern;
/**
* Check if table is a lookup table (typically large and causes explosions)
*/
private isLookupTable;
/**
* Get or estimate table statistics
*/
private getTableStats;
/**
* Estimate table size based on table type
*/
private estimateTableSize;
/**
* Estimate JOIN selectivity (how much JOINs typically filter)
*/
private estimateJoinSelectivity;
/**
* Extract project_id from query context
*/
private extractProjectId;
/**
* Generate fallback SQL when JOINs are too dangerous
*/
private generateFallbackSQL;
/**
* Inject DISTINCT into COUNT queries when multiplication detected
*/
injectDistinctIfNeeded(sql: string, multiplier: number, primaryTable?: string): string;
/**
* Get primary key field for a table
*/
private getPrimaryKeyForTable;
/**
* Initialize default table statistics
*/
private initializeTableStats;
/**
* Update table statistics with real data
*/
updateTableStats(tableName: string, actualRows: number, joinSelectivity?: number): void;
/**
* Get statistics for monitoring and debugging
*/
getStatistics(): {
totalValidations: number;
rejectedJoins: number;
averageMultiplier: number;
topDangerousPatterns: Array<{
pattern: string;
count: number;
}>;
};
}
//# sourceMappingURL=CardinalityGuard.d.ts.map