From 04928d9f77e54f13fe2420161a0f6c960070c32a Mon Sep 17 00:00:00 2001 From: Huliiiii <134658521+Huliiiiii@users.noreply.github.com> Date: Thu, 21 Aug 2025 11:07:56 +0800 Subject: [PATCH 1/2] Add `as_types` to PostgresValues --- sea-query-postgres/src/lib.rs | 116 +++++++++++++++++++++++++++++++++- 1 file changed, 115 insertions(+), 1 deletion(-) diff --git a/sea-query-postgres/src/lib.rs b/sea-query-postgres/src/lib.rs index a98660c6a..f9807bb61 100644 --- a/sea-query-postgres/src/lib.rs +++ b/sea-query-postgres/src/lib.rs @@ -5,7 +5,7 @@ use std::error::Error; use bytes::BytesMut; use postgres_types::{IsNull, ToSql, Type, to_sql_checked}; -use sea_query::{QueryBuilder, Value, query::*}; +use sea_query::{ArrayType, QueryBuilder, Value, query::*}; #[derive(Clone, Debug, PartialEq)] pub struct PostgresValue(pub Value); @@ -22,6 +22,14 @@ impl PostgresValues { }) .collect() } + + pub fn as_types(&self) -> Vec { + self.0 + .iter() + .map(|x| &x.0) + .map(value_to_postgres_type) + .collect() + } } pub trait PostgresBinder { @@ -145,3 +153,109 @@ impl ToSql for PostgresValue { to_sql_checked!(); } + +fn value_to_postgres_type(value: &Value) -> Type { + match value { + Value::Bool(_) => Type::BOOL, + Value::TinyInt(_) => Type::INT2, + Value::TinyUnsigned(_) => Type::INT2, + Value::SmallInt(_) => Type::INT2, + Value::SmallUnsigned(_) => Type::INT4, + Value::Int(_) => Type::INT4, + Value::BigInt(_) => Type::INT8, + Value::Unsigned(_) => Type::INT8, + Value::BigUnsigned(_) => Type::INT8, + Value::Float(_) => Type::FLOAT4, + Value::Double(_) => Type::FLOAT8, + Value::String(_) => Type::TEXT, + Value::Char(_) => Type::CHAR, + Value::Bytes(_) => Type::BYTEA, + #[cfg(feature = "with-json")] + Value::Json(_) => Type::JSON, + #[cfg(feature = "with-chrono")] + Value::ChronoDate(_) => Type::DATE, + #[cfg(feature = "with-chrono")] + Value::ChronoTime(_) => Type::TIME, + #[cfg(feature = "with-chrono")] + Value::ChronoDateTime(_) => Type::TIMESTAMP, + #[cfg(feature = "with-chrono")] + Value::ChronoDateTimeUtc(_) => Type::TIMESTAMP, + #[cfg(feature = "with-chrono")] + Value::ChronoDateTimeLocal(_) => Type::TIMESTAMP, + #[cfg(feature = "with-chrono")] + Value::ChronoDateTimeWithTimeZone(_) => Type::TIMESTAMPTZ, + #[cfg(feature = "with-time")] + Value::TimeDate(_) => Type::DATE, + #[cfg(feature = "with-time")] + Value::TimeTime(_) => Type::TIME, + #[cfg(feature = "with-time")] + Value::TimeDateTime(_) => Type::TIMESTAMP, + #[cfg(feature = "with-time")] + Value::TimeDateTimeWithTimeZone(_) => Type::TIMESTAMPTZ, + #[cfg(feature = "with-uuid")] + Value::Uuid(_) => Type::UUID, + #[cfg(feature = "with-rust_decimal")] + Value::Decimal(_) => Type::NUMERIC, + #[cfg(feature = "with-bigdecimal")] + Value::BigDecimal(_) => Type::NUMERIC, + #[cfg(feature = "postgres-array")] + Value::Array(ty, _) => array_type_to_pg_type(ty), + #[cfg(feature = "postgres-vector")] + Value::Vector(_) => todo!(), + #[cfg(feature = "with-ipnetwork")] + Value::IpNetwork(_) => Type::INET, + #[cfg(feature = "with-mac_address")] + Value::MacAddress(_) => Type::MACADDR, + } +} + +fn array_type_to_pg_type(ty: &ArrayType) -> Type { + match ty { + ArrayType::Bool => Type::BOOL_ARRAY, + ArrayType::TinyInt => Type::INT2_ARRAY, + ArrayType::TinyUnsigned => Type::INT2_ARRAY, + ArrayType::SmallInt => Type::INT2_ARRAY, + ArrayType::SmallUnsigned => Type::INT4_ARRAY, + ArrayType::Int => Type::INT4_ARRAY, + ArrayType::Unsigned => Type::INT8_ARRAY, + ArrayType::BigInt => Type::INT8_ARRAY, + ArrayType::BigUnsigned => Type::INT8_ARRAY, + ArrayType::Float => Type::FLOAT4_ARRAY, + ArrayType::Double => Type::FLOAT8_ARRAY, + ArrayType::String => Type::TEXT_ARRAY, + ArrayType::Char => Type::CHAR_ARRAY, + ArrayType::Bytes => Type::BYTEA_ARRAY, + #[cfg(feature = "with-json")] + ArrayType::Json => Type::JSON_ARRAY, + #[cfg(feature = "with-chrono")] + ArrayType::ChronoDate => Type::DATE_ARRAY, + #[cfg(feature = "with-chrono")] + ArrayType::ChronoTime => Type::TIME_ARRAY, + #[cfg(feature = "with-chrono")] + ArrayType::ChronoDateTime => Type::TIMESTAMP_ARRAY, + #[cfg(feature = "with-chrono")] + ArrayType::ChronoDateTimeUtc => Type::TIMESTAMP_ARRAY, + #[cfg(feature = "with-chrono")] + ArrayType::ChronoDateTimeLocal => Type::TIMESTAMP_ARRAY, + #[cfg(feature = "with-chrono")] + ArrayType::ChronoDateTimeWithTimeZone => Type::TIMESTAMPTZ_ARRAY, + #[cfg(feature = "with-time")] + ArrayType::TimeDate => Type::DATE_ARRAY, + #[cfg(feature = "with-time")] + ArrayType::TimeTime => Type::TIME_ARRAY, + #[cfg(feature = "with-time")] + ArrayType::TimeDateTime => Type::TIMESTAMP_ARRAY, + #[cfg(feature = "with-time")] + ArrayType::TimeDateTimeWithTimeZone => Type::TIMESTAMPTZ_ARRAY, + #[cfg(feature = "with-uuid")] + ArrayType::Uuid => Type::UUID_ARRAY, + #[cfg(feature = "with-rust_decimal")] + ArrayType::Decimal => Type::NUMERIC_ARRAY, + #[cfg(feature = "with-bigdecimal")] + ArrayType::BigDecimal => Type::NUMERIC_ARRAY, + #[cfg(feature = "with-ipnetwork")] + ArrayType::IpNetwork => Type::INET_ARRAY, + #[cfg(feature = "with-mac_address")] + ArrayType::MacAddress => Type::MACADDR_ARRAY, + } +} From 6a55e5e2411e363cde5af2076e1b898badc92d99 Mon Sep 17 00:00:00 2001 From: Huliiiii <134658521+Huliiiiii@users.noreply.github.com> Date: Thu, 21 Aug 2025 11:12:56 +0800 Subject: [PATCH 2/2] Fix --- sea-query-postgres/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sea-query-postgres/src/lib.rs b/sea-query-postgres/src/lib.rs index f9807bb61..284936811 100644 --- a/sea-query-postgres/src/lib.rs +++ b/sea-query-postgres/src/lib.rs @@ -164,7 +164,7 @@ fn value_to_postgres_type(value: &Value) -> Type { Value::Int(_) => Type::INT4, Value::BigInt(_) => Type::INT8, Value::Unsigned(_) => Type::INT8, - Value::BigUnsigned(_) => Type::INT8, + Value::BigUnsigned(_) => Type::NUMERIC, Value::Float(_) => Type::FLOAT4, Value::Double(_) => Type::FLOAT8, Value::String(_) => Type::TEXT, @@ -219,7 +219,7 @@ fn array_type_to_pg_type(ty: &ArrayType) -> Type { ArrayType::Int => Type::INT4_ARRAY, ArrayType::Unsigned => Type::INT8_ARRAY, ArrayType::BigInt => Type::INT8_ARRAY, - ArrayType::BigUnsigned => Type::INT8_ARRAY, + ArrayType::BigUnsigned => Type::NUMERIC_ARRAY, ArrayType::Float => Type::FLOAT4_ARRAY, ArrayType::Double => Type::FLOAT8_ARRAY, ArrayType::String => Type::TEXT_ARRAY,