diff --git a/packages/database/src/analyze-performance.ts b/packages/database/src/analyze-performance.ts index b0079628b..c456eeffa 100644 --- a/packages/database/src/analyze-performance.ts +++ b/packages/database/src/analyze-performance.ts @@ -79,7 +79,13 @@ function analyzeQueryPerformance(db: Database) { ) SELECT response_time_ms as p95_response_time FROM ordered_times - WHERE row_num = CAST(CEIL(total_count * 0.95) AS INTEGER) + -- CEIL()/FLOOR() are not builtin SQLite functions in bun:sqlite; portable + -- ceil(x) for non-negative x = trunc(x) + (x > trunc(x)) (see analytics.repository.ts + -- for the same fix applied to the production query). + WHERE row_num = ( + CAST(total_count * 0.95 AS INTEGER) + + (total_count * 0.95 > CAST(total_count * 0.95 AS INTEGER)) + ) LIMIT 1 `, params: ["claude-3-5-sonnet-20241022"], diff --git a/packages/database/src/repositories/analytics.repository.ts b/packages/database/src/repositories/analytics.repository.ts index f445da278..d148e3d5f 100644 --- a/packages/database/src/repositories/analytics.repository.ts +++ b/packages/database/src/repositories/analytics.repository.ts @@ -208,7 +208,16 @@ export class AnalyticsRepository extends BaseRepository { FROM model_stats ms LEFT JOIN ranked_times rt ON rt.model = ms.model - AND rt.row_num = CAST(CEIL(rt.total_count * 0.95) AS INTEGER) + -- p95 rank = ceil(total_count * 0.95). CEIL()/FLOOR() are not builtin SQLite + -- functions unless compiled with SQLITE_ENABLE_MATH_FUNCTIONS (not available in + -- bun:sqlite), so ceil(x) for non-negative x is computed portably as + -- trunc(x) + (x > trunc(x)) — CAST(x AS INTEGER) truncates toward zero, which + -- equals floor(x) for any x >= 0 (total_count is always a positive COUNT(*), so + -- this is always non-negative). + AND rt.row_num = ( + CAST(rt.total_count * 0.95 AS INTEGER) + + (rt.total_count * 0.95 > CAST(rt.total_count * 0.95 AS INTEGER)) + ) ORDER BY ms.total_requests DESC `, [...queryParams, ...queryParams],