Skip to content

Commit 2deaa22

Browse files
haasonsaasclaude
andcommitted
fix: cast PG aggregate results to correct types for sqlx decoding
AVG() returns NUMERIC in PostgreSQL which is incompatible with f64 in sqlx. Cast AVG results to FLOAT8 and fix PERCENTILE_CONT parentheses. Also fix WHERE clause for by_repo query when no time filters are set. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 037562e commit 2deaa22

1 file changed

Lines changed: 14 additions & 9 deletions

File tree

src/server/storage_pg.rs

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -403,8 +403,8 @@ impl StorageBackend for PgStorageBackend {
403403
COUNT(*) FILTER (WHERE event_type = 'review.completed'), \
404404
COUNT(*) FILTER (WHERE event_type != 'review.completed'), \
405405
COALESCE(SUM(COALESCE(tokens_total, 0)), 0), \
406-
COALESCE(AVG(duration_ms), 0), \
407-
AVG(overall_score) FILTER (WHERE overall_score IS NOT NULL) \
406+
COALESCE(AVG(duration_ms)::FLOAT8, 0), \
407+
(AVG(overall_score) FILTER (WHERE overall_score IS NOT NULL))::FLOAT8 \
408408
FROM review_events {where_clause}"
409409
))
410410
.fetch_one(&self.pool)
@@ -422,9 +422,9 @@ impl StorageBackend for PgStorageBackend {
422422
// Latency percentiles
423423
let latency = sqlx::query_as::<_, (i64, i64, i64)>(&format!(
424424
"SELECT \
425-
COALESCE(PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY duration_ms)::BIGINT, 0), \
426-
COALESCE(PERCENTILE_CONT(0.95) WITHIN GROUP (ORDER BY duration_ms)::BIGINT, 0), \
427-
COALESCE(PERCENTILE_CONT(0.99) WITHIN GROUP (ORDER BY duration_ms)::BIGINT, 0) \
425+
COALESCE((PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY duration_ms))::BIGINT, 0), \
426+
COALESCE((PERCENTILE_CONT(0.95) WITHIN GROUP (ORDER BY duration_ms))::BIGINT, 0), \
427+
COALESCE((PERCENTILE_CONT(0.99) WITHIN GROUP (ORDER BY duration_ms))::BIGINT, 0) \
428428
FROM review_events {where_clause}"
429429
))
430430
.fetch_one(&self.pool)
@@ -434,8 +434,8 @@ impl StorageBackend for PgStorageBackend {
434434
// By model
435435
let by_model = sqlx::query_as::<_, (String, i64, f64, i64, Option<f64>)>(
436436
&format!(
437-
"SELECT model, COUNT(*), AVG(duration_ms), COALESCE(SUM(COALESCE(tokens_total, 0)), 0), \
438-
AVG(overall_score) FILTER (WHERE overall_score IS NOT NULL) \
437+
"SELECT model, COUNT(*), AVG(duration_ms)::FLOAT8, COALESCE(SUM(COALESCE(tokens_total, 0)), 0), \
438+
(AVG(overall_score) FILTER (WHERE overall_score IS NOT NULL))::FLOAT8 \
439439
FROM review_events {where_clause} GROUP BY model ORDER BY COUNT(*) DESC"
440440
)
441441
)
@@ -458,10 +458,15 @@ impl StorageBackend for PgStorageBackend {
458458
.collect();
459459

460460
// By repo
461+
let repo_where = if where_clause.is_empty() {
462+
"WHERE github_repo IS NOT NULL".to_string()
463+
} else {
464+
format!("{where_clause} AND github_repo IS NOT NULL")
465+
};
461466
let by_repo = sqlx::query_as::<_, (String, i64, Option<f64>)>(
462467
&format!(
463-
"SELECT github_repo, COUNT(*), AVG(overall_score) FILTER (WHERE overall_score IS NOT NULL) \
464-
FROM review_events {where_clause} AND github_repo IS NOT NULL GROUP BY github_repo ORDER BY COUNT(*) DESC"
468+
"SELECT github_repo, COUNT(*), (AVG(overall_score) FILTER (WHERE overall_score IS NOT NULL))::FLOAT8 \
469+
FROM review_events {repo_where} GROUP BY github_repo ORDER BY COUNT(*) DESC"
465470
)
466471
)
467472
.fetch_all(&self.pool)

0 commit comments

Comments
 (0)