fix(database): cast extract(epoch)::double precision in active-connections query

extract(epoch FROM now() - query_start) returns numeric (decimal) in
PostgreSQL, but the result was read as f64 via r.get(4). tokio-postgres
has no FromSql<f64> impl for the numeric type, so get_db_status panicked
at runtime with 'error deserializing column 4' (HTTP 500).

Cast to ::double precision (float8) to match query_duration_secs: Option<f64>.

Audited the remaining column mappings in status.rs to rule out further
type mismatches — all sound: reltuples::bigint->i64, native bigint size
columns->i64, last_vacuum/last_analyze timestamptz->DateTime<Utc>
(chrono feature enabled), schema_migrations.version TEXT->String,
count(*)::int->i32 (fixed previously).
This commit is contained in:
xfy 2026-06-30 13:51:48 +08:00
parent 116286f80f
commit 36168f26d7

View File

@ -173,11 +173,13 @@ pub async fn get_db_status() -> Result<DbStatus, ServerFnError> {
})
.collect();
// 活跃连接(过滤自身 pid避免循环显示
// 活跃连接(过滤自身 pid避免循环显示
// extract(epoch FROM ...) 原生返回 numeric(decimal)tokio-postgres 无 FromSql<f64>
// 实现该类型;显式 ::double precision 转 float8 以匹配 query_duration_secs 的 f64。
let conn_rows = client
.query(
"SELECT pid, usename, state, query, \
extract(epoch FROM now() - query_start) \
extract(epoch FROM now() - query_start)::double precision \
FROM pg_stat_activity \
WHERE datname = current_database() AND pid <> pg_backend_pid() \
ORDER BY query_start DESC NULLS LAST LIMIT 50",