Skip to content

Commit

Permalink
track the kind of null arguments in order to provide the appropriate …
Browse files Browse the repository at this point in the history
…type when converting them
  • Loading branch information
etorreborre committed Jun 21, 2024
1 parent 402022d commit f919e0b
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 14 deletions.
21 changes: 18 additions & 3 deletions sqlx-core/src/any/arguments.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::any::value::AnyValueKind;
use crate::any::Any;
use crate::any::{Any, AnyTypeInfoKind};
use crate::arguments::Arguments;
use crate::encode::{Encode, IsNull};
use crate::error::BoxDynError;
Expand Down Expand Up @@ -46,6 +46,14 @@ impl<'q> AnyArguments<'q> {
where
'q: 'a,
Option<i32>: Type<A::Database> + Encode<'a, A::Database>,
Option<bool>: Type<A::Database> + Encode<'a, A::Database>,
Option<i16>: Type<A::Database> + Encode<'a, A::Database>,
Option<i32>: Type<A::Database> + Encode<'a, A::Database>,
Option<i64>: Type<A::Database> + Encode<'a, A::Database>,
Option<f32>: Type<A::Database> + Encode<'a, A::Database>,
Option<f64>: Type<A::Database> + Encode<'a, A::Database>,
Option<String>: Type<A::Database> + Encode<'a, A::Database>,
Option<Vec<u8>>: Type<A::Database> + Encode<'a, A::Database>,
bool: Type<A::Database> + Encode<'a, A::Database>,
i16: Type<A::Database> + Encode<'a, A::Database>,
i32: Type<A::Database> + Encode<'a, A::Database>,
Expand All @@ -59,7 +67,15 @@ impl<'q> AnyArguments<'q> {

for arg in &self.values.0 {
match arg {
AnyValueKind::Null => out.add(Option::<i32>::None),
AnyValueKind::Null(AnyTypeInfoKind::Null) => out.add(Option::<i32>::None),
AnyValueKind::Null(AnyTypeInfoKind::Bool) => out.add(Option::<bool>::None),
AnyValueKind::Null(AnyTypeInfoKind::SmallInt) => out.add(Option::<i16>::None),
AnyValueKind::Null(AnyTypeInfoKind::Integer) => out.add(Option::<i32>::None),
AnyValueKind::Null(AnyTypeInfoKind::BigInt) => out.add(Option::<i64>::None),
AnyValueKind::Null(AnyTypeInfoKind::Real) => out.add(Option::<f64>::None),
AnyValueKind::Null(AnyTypeInfoKind::Double) => out.add(Option::<f32>::None),
AnyValueKind::Null(AnyTypeInfoKind::Text) => out.add(Option::<String>::None),
AnyValueKind::Null(AnyTypeInfoKind::Blob) => out.add(Option::<Vec<u8>>::None),
AnyValueKind::Bool(b) => out.add(b),
AnyValueKind::SmallInt(i) => out.add(i),
AnyValueKind::Integer(i) => out.add(i),
Expand All @@ -70,7 +86,6 @@ impl<'q> AnyArguments<'q> {
AnyValueKind::Blob(b) => out.add(&**b),
}?
}

Ok(out)
}
}
5 changes: 3 additions & 2 deletions sqlx-core/src/any/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ pub use transaction::AnyTransactionManager;
pub use type_info::{AnyTypeInfo, AnyTypeInfoKind};
pub use value::{AnyValue, AnyValueRef};

use crate::types::Type;
#[doc(hidden)]
pub use value::AnyValueKind;

Expand All @@ -65,7 +66,7 @@ impl_column_index_for_statement!(AnyStatement);
// required because some databases have a different handling of NULL
impl<'q, T> Encode<'q, Any> for Option<T>
where
T: Encode<'q, Any> + 'q,
T: Encode<'q, Any> + 'q + Type<Any>,
{
fn encode_by_ref(
&self,
Expand All @@ -74,7 +75,7 @@ where
if let Some(value) = self {
value.encode_by_ref(buf)
} else {
buf.0.push(AnyValueKind::Null);
buf.0.push(AnyValueKind::Null(T::type_info().kind));
Ok(crate::encode::IsNull::Yes)
}
}
Expand Down
4 changes: 2 additions & 2 deletions sqlx-core/src/any/row.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,8 @@ impl AnyRow {
})?;

let value_kind = match type_info.kind {
_ if value.is_null() => AnyValueKind::Null,
AnyTypeInfoKind::Null => AnyValueKind::Null,
k if value.is_null() => AnyValueKind::Null(k),
AnyTypeInfoKind::Null => AnyValueKind::Null(AnyTypeInfoKind::Null),
AnyTypeInfoKind::Bool => AnyValueKind::Bool(decode(value)?),
AnyTypeInfoKind::SmallInt => AnyValueKind::SmallInt(decode(value)?),
AnyTypeInfoKind::Integer => AnyValueKind::Integer(decode(value)?),
Expand Down
12 changes: 6 additions & 6 deletions sqlx-core/src/any/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::value::{Value, ValueRef};
#[derive(Clone, Debug)]
#[non_exhaustive]
pub enum AnyValueKind<'a> {
Null,
Null(AnyTypeInfoKind),
Bool(bool),
SmallInt(i16),
Integer(i32),
Expand All @@ -24,7 +24,7 @@ impl AnyValueKind<'_> {
fn type_info(&self) -> AnyTypeInfo {
AnyTypeInfo {
kind: match self {
AnyValueKind::Null => AnyTypeInfoKind::Null,
AnyValueKind::Null(_) => AnyTypeInfoKind::Null,
AnyValueKind::Bool(_) => AnyTypeInfoKind::Bool,
AnyValueKind::SmallInt(_) => AnyTypeInfoKind::SmallInt,
AnyValueKind::Integer(_) => AnyTypeInfoKind::Integer,
Expand Down Expand Up @@ -74,7 +74,7 @@ impl Value for AnyValue {
fn as_ref(&self) -> <Self::Database as Database>::ValueRef<'_> {
AnyValueRef {
kind: match &self.kind {
AnyValueKind::Null => AnyValueKind::Null,
AnyValueKind::Null(k) => AnyValueKind::Null(*k),
AnyValueKind::Bool(b) => AnyValueKind::Bool(*b),
AnyValueKind::SmallInt(i) => AnyValueKind::SmallInt(*i),
AnyValueKind::Integer(i) => AnyValueKind::Integer(*i),
Expand All @@ -92,7 +92,7 @@ impl Value for AnyValue {
}

fn is_null(&self) -> bool {
matches!(self.kind, AnyValueKind::Null)
matches!(self.kind, AnyValueKind::Null(_))
}
}

Expand All @@ -102,7 +102,7 @@ impl<'a> ValueRef<'a> for AnyValueRef<'a> {
fn to_owned(&self) -> <Self::Database as Database>::Value {
AnyValue {
kind: match &self.kind {
AnyValueKind::Null => AnyValueKind::Null,
AnyValueKind::Null(k) => AnyValueKind::Null(*k),
AnyValueKind::Bool(b) => AnyValueKind::Bool(*b),
AnyValueKind::SmallInt(i) => AnyValueKind::SmallInt(*i),
AnyValueKind::Integer(i) => AnyValueKind::Integer(*i),
Expand All @@ -120,6 +120,6 @@ impl<'a> ValueRef<'a> for AnyValueRef<'a> {
}

fn is_null(&self) -> bool {
matches!(self.kind, AnyValueKind::Null)
matches!(self.kind, AnyValueKind::Null(_))
}
}
2 changes: 1 addition & 1 deletion sqlx-sqlite/src/any.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ fn map_arguments(args: AnyArguments<'_>) -> SqliteArguments<'_> {
.0
.into_iter()
.map(|val| match val {
AnyValueKind::Null => SqliteArgumentValue::Null,
AnyValueKind::Null(_) => SqliteArgumentValue::Null,
AnyValueKind::Bool(b) => SqliteArgumentValue::Int(b as i32),
AnyValueKind::SmallInt(i) => SqliteArgumentValue::Int(i as i32),
AnyValueKind::Integer(i) => SqliteArgumentValue::Int(i),
Expand Down

0 comments on commit f919e0b

Please sign in to comment.