我正在查询PostgreSQL的实例并选择一个十进制值的总和:
db=# SELECT SUM(distance) AS total_distance FROM table_name WHERE deleted_at IS NULL;
total_distance
-----------------------
3808.0666666666666578
(1 row)
当我尝试在Rust中执行此查询时:
extern crate postgres;
use postgres::{Connection, TlsMode};
fn main() {
let conn = Connection::connect("postgresql://u:p@localhost:5432/db", TlsMode::None).unwrap();
let query = "SELECT SUM(distance) AS total_distance FROM table_name WHERE deleted_at IS NULL;";
for row in &conn.query(query, &[]).unwrap() {
let total_distance: f64 = row.get("total_distance");
println!("{}", total_distance);
}
}
结果:
thread 'main' panicked at 'error retrieving column "total_distance": Error(Conversion(WrongType(Type(Numeric))))'
我在各种线程中看到Postgres板条箱不支持Numeric
类型,因此我尝试创建自己的数字类型:
#[derive(Debug)]
struct Float64(f64);
impl FromSql for Float64 {
fn from_sql(ty: &Type, raw: &[u8]) -> Result<Float64, Box<Error + Sync + Send>> {
let bytes = raw.try_into().expect("failed!");
Ok(Float64(f64::from_be_bytes(bytes)))
}
fn from_sql_null(ty: &Type) -> Result<Float64, Box<Error + Sync + Send>> {
Ok(Float64(0.0))
}
fn from_sql_nullable(
ty: &Type,
raw: Option<&[u8]>,
) -> Result<Float64, Box<Error + Sync + Send>> {
match raw {
None => Ok(Float64(0.0)),
Some(value) => Float64::from_sql(ty, value),
}
}
fn accepts(ty: &Type) -> bool {
NUMERIC.eq(ty)
}
}
impl Display for Float64 {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.to_string())
}
}
但是由于原始字节无法解包,这仍然不起作用:
thread 'main' panicked at 'failed!: TryFromSliceError(())', src/libcore/result.rs:1165:5
raw: &[u8]
的长度为18,这就是为什么它不能解包的原因。将18字节切片转换为f64
的最佳方法是什么?