Skip to content

fix(database): portable p95 ceil() for bun:sqlite (analytics 500s) - #62

Open
doanhv wants to merge 1 commit into
snipeship:mainfrom
doanhv:fix/analytics-p95-ceil-sqlite-portability
Open

fix(database): portable p95 ceil() for bun:sqlite (analytics 500s)#62
doanhv wants to merge 1 commit into
snipeship:mainfrom
doanhv:fix/analytics-p95-ceil-sqlite-portability

Conversation

@doanhv

@doanhv doanhv commented Jul 23, 2026

Copy link
Copy Markdown

CEIL() is not a builtin SQLite function unless compiled with SQLITE_ENABLE_MATH_FUNCTIONS, which bun:sqlite does not enable -- so the p95 response-time query in getAnalytics() throws SQLiteError: no such function: CEIL on every call, breaking /api/analytics entirely (500 for any request/range once there is data). Same bug duplicated in analyze-performance.ts. Fixed by replacing CEIL(x) with a portable non-negative-ceil idiom: CAST(x AS INTEGER) + (x > CAST(x AS INTEGER)) -- CAST(...AS INTEGER) truncates toward zero in SQLite, which equals floor(x) for any x >= 0; total_count here is always a non-negative COUNT(*) OVER (...) result. Verified by hand and by an exhaustive n=1..10000 check against an exact BigInt rational ceiling (0 mismatches). Test plan: bun test packages/api/src and packages/database/src -- was 1 fail / 2 fail (SQLiteError), now all green; bun x tsc --noEmit clean; independently re-verified by a fresh reviewer pass.

getAnalytics()'s model-performance query computed the p95-response-time
rank as CAST(CEIL(total_count * 0.95) AS INTEGER), but CEIL is not a
builtin SQLite function unless compiled with SQLITE_ENABLE_MATH_FUNCTIONS,
which bun:sqlite does not enable. Every analytics query threw
"SQLiteError: no such function: CEIL", breaking GET /api/analytics
entirely (500 for every request/range).

Replaced with a portable non-negative-ceil idiom:
  CAST(x AS INTEGER) + (x > CAST(x AS INTEGER))
CAST(x AS INTEGER) truncates toward zero, which equals floor(x) for any
x >= 0; total_count is always a positive COUNT(*) window result, so this
holds. Verified by hand for n=1,10,20,3 and exhaustively re-checked
(independent review) for n=1..25 against Math.ceil and n=1..10000 against
an exact BigInt rational ceiling -- 0 mismatches, no float-boundary risk.

Applied the same fix to analyze-performance.ts's identical CEIL usage
(a diagnostic script, same root cause, kept consistent).

Fixes: analytics.repository.test.ts, database-operations.test.ts,
router.test.ts (all previously failing on this exact SQLiteError).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant