fix(sql): add SQL support for Postgres NUMERIC and custom data types (fix: #3158) (#3275)

This commit is contained in:
Mike
2026-03-05 21:31:20 +09:00
committed by GitHub
parent f5f68063e4
commit 1dc3612862
4 changed files with 34 additions and 2 deletions
@@ -0,0 +1,6 @@
---
"sql": minor
"sql-js": minor
---
Add support for Postgres `NUMERIC` and custom data types.
Generated
+4
View File
@@ -6018,6 +6018,7 @@ dependencies = [
"memchr",
"once_cell",
"percent-encoding",
"rust_decimal",
"rustls",
"serde",
"serde_json",
@@ -6103,6 +6104,7 @@ dependencies = [
"percent-encoding",
"rand 0.8.5",
"rsa",
"rust_decimal",
"serde",
"sha1",
"sha2",
@@ -6142,6 +6144,7 @@ dependencies = [
"memchr",
"once_cell",
"rand 0.8.5",
"rust_decimal",
"serde",
"serde_json",
"sha2",
@@ -6970,6 +6973,7 @@ dependencies = [
"futures-core",
"indexmap 2.9.0",
"log",
"rust_decimal",
"serde",
"serde_json",
"sqlx",
+2 -1
View File
@@ -29,7 +29,8 @@ tauri = { workspace = true }
log = { workspace = true }
thiserror = { workspace = true }
futures-core = "0.3"
sqlx = { version = "0.8", features = ["json", "time", "uuid"] }
sqlx = { version = "0.8", features = ["json", "time", "uuid", "rust_decimal"] }
rust_decimal = "1"
time = "0.3"
tokio = { version = "1", features = ["sync"] }
indexmap = { version = "2", features = ["serde"] }
+22 -1
View File
@@ -2,6 +2,7 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
use rust_decimal::prelude::ToPrimitive;
use serde_json::Value as JsonValue;
use sqlx::{postgres::PgValueRef, TypeInfo, Value, ValueRef};
use time::{Date, OffsetDateTime, PrimitiveDateTime, Time};
@@ -107,8 +108,28 @@ pub(crate) fn to_json(v: PgValueRef) -> Result<JsonValue, Error> {
JsonValue::Null
}
}
"NUMERIC" => {
if let Ok(v) = ValueRef::to_owned(&v).try_decode::<rust_decimal::Decimal>() {
if let Some(n) = v.to_f64().and_then(serde_json::Number::from_f64) {
JsonValue::Number(n)
} else {
JsonValue::String(v.to_string())
}
} else {
JsonValue::Null
}
}
"VOID" => JsonValue::Null,
_ => return Err(Error::UnsupportedDatatype(v.type_info().name().to_string())),
// Handle custom types (enums, domains, etc.) by trying to decode as string
_ => {
let type_name = v.type_info().name().to_string();
if let Ok(v) = ValueRef::to_owned(&v).try_decode_unchecked::<String>() {
log::warn!("unsupported type {type_name} decoded as string");
JsonValue::String(v)
} else {
return Err(Error::UnsupportedDatatype(v.type_info().name().to_string()));
}
}
};
Ok(res)