Skip to content

Commit 1dc3612

Browse files
authored
fix(sql): add SQL support for Postgres NUMERIC and custom data types (fix: #3158) (#3275)
1 parent f5f6806 commit 1dc3612

4 files changed

Lines changed: 34 additions & 2 deletions

File tree

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"sql": minor
3+
"sql-js": minor
4+
---
5+
6+
Add support for Postgres `NUMERIC` and custom data types.

Cargo.lock

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

plugins/sql/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ tauri = { workspace = true }
2929
log = { workspace = true }
3030
thiserror = { workspace = true }
3131
futures-core = "0.3"
32-
sqlx = { version = "0.8", features = ["json", "time", "uuid"] }
32+
sqlx = { version = "0.8", features = ["json", "time", "uuid", "rust_decimal"] }
33+
rust_decimal = "1"
3334
time = "0.3"
3435
tokio = { version = "1", features = ["sync"] }
3536
indexmap = { version = "2", features = ["serde"] }

plugins/sql/src/decode/postgres.rs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// SPDX-License-Identifier: Apache-2.0
33
// SPDX-License-Identifier: MIT
44

5+
use rust_decimal::prelude::ToPrimitive;
56
use serde_json::Value as JsonValue;
67
use sqlx::{postgres::PgValueRef, TypeInfo, Value, ValueRef};
78
use time::{Date, OffsetDateTime, PrimitiveDateTime, Time};
@@ -107,8 +108,28 @@ pub(crate) fn to_json(v: PgValueRef) -> Result<JsonValue, Error> {
107108
JsonValue::Null
108109
}
109110
}
111+
"NUMERIC" => {
112+
if let Ok(v) = ValueRef::to_owned(&v).try_decode::<rust_decimal::Decimal>() {
113+
if let Some(n) = v.to_f64().and_then(serde_json::Number::from_f64) {
114+
JsonValue::Number(n)
115+
} else {
116+
JsonValue::String(v.to_string())
117+
}
118+
} else {
119+
JsonValue::Null
120+
}
121+
}
110122
"VOID" => JsonValue::Null,
111-
_ => return Err(Error::UnsupportedDatatype(v.type_info().name().to_string())),
123+
// Handle custom types (enums, domains, etc.) by trying to decode as string
124+
_ => {
125+
let type_name = v.type_info().name().to_string();
126+
if let Ok(v) = ValueRef::to_owned(&v).try_decode_unchecked::<String>() {
127+
log::warn!("unsupported type {type_name} decoded as string");
128+
JsonValue::String(v)
129+
} else {
130+
return Err(Error::UnsupportedDatatype(v.type_info().name().to_string()));
131+
}
132+
}
112133
};
113134

114135
Ok(res)

0 commit comments

Comments
 (0)