From 1dc36128624f6954e09ea1574f68615e34e83f63 Mon Sep 17 00:00:00 2001 From: Mike <788827+mikenikles@users.noreply.github.com> Date: Thu, 5 Mar 2026 21:31:20 +0900 Subject: [PATCH] fix(sql): add SQL support for Postgres `NUMERIC` and custom data types (fix: #3158) (#3275) --- .../change-plugin-sql-numeric-custom-types.md | 6 +++++ Cargo.lock | 4 ++++ plugins/sql/Cargo.toml | 3 ++- plugins/sql/src/decode/postgres.rs | 23 ++++++++++++++++++- 4 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 .changes/change-plugin-sql-numeric-custom-types.md diff --git a/.changes/change-plugin-sql-numeric-custom-types.md b/.changes/change-plugin-sql-numeric-custom-types.md new file mode 100644 index 000000000..7fb49bdbb --- /dev/null +++ b/.changes/change-plugin-sql-numeric-custom-types.md @@ -0,0 +1,6 @@ +--- +"sql": minor +"sql-js": minor +--- + +Add support for Postgres `NUMERIC` and custom data types. diff --git a/Cargo.lock b/Cargo.lock index cbce1f54c..32431a2d2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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", diff --git a/plugins/sql/Cargo.toml b/plugins/sql/Cargo.toml index e1a5feefc..350c9d883 100644 --- a/plugins/sql/Cargo.toml +++ b/plugins/sql/Cargo.toml @@ -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"] } diff --git a/plugins/sql/src/decode/postgres.rs b/plugins/sql/src/decode/postgres.rs index 88082fb70..4af9b713d 100644 --- a/plugins/sql/src/decode/postgres.rs +++ b/plugins/sql/src/decode/postgres.rs @@ -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::Null } } + "NUMERIC" => { + if let Ok(v) = ValueRef::to_owned(&v).try_decode::() { + 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::() { + 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)