Skip to content

Commit

Permalink
track null arguments in order to provide the appropriate type when co…
Browse files Browse the repository at this point in the history
…nverting them
  • Loading branch information
etorreborre committed Jun 20, 2024
1 parent 402022d commit 9a8a9e1
Showing 1 changed file with 41 additions and 13 deletions.
54 changes: 41 additions & 13 deletions sqlx-core/src/any/arguments.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
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;
use crate::types::Type;
use std::collections::HashMap;

pub struct AnyArguments<'q> {
#[doc(hidden)]
pub values: AnyArgumentBuffer<'q>,
#[doc(hidden)]
pub null_values: HashMap<usize, AnyTypeInfoKind>,
}

impl<'q> Arguments<'q> for AnyArguments<'q> {
Expand All @@ -21,7 +24,12 @@ impl<'q> Arguments<'q> for AnyArguments<'q> {
where
T: 'q + Encode<'q, Self::Database> + Type<Self::Database>,
{
let _: IsNull = value.encode(&mut self.values)?;
let kind = T::type_info().kind;
let index = self.values.0.len();
match value.encode(&mut self.values)? {
IsNull::Yes => self.null_values.insert(index, kind),
IsNull::No => None,
};
Ok(())
}

Expand All @@ -36,6 +44,7 @@ impl<'q> Default for AnyArguments<'q> {
fn default() -> Self {
AnyArguments {
values: AnyArgumentBuffer(vec![]),
null_values: HashMap::new(),
}
}
}
Expand All @@ -46,6 +55,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 @@ -57,17 +74,28 @@ impl<'q> AnyArguments<'q> {
{
let mut out = A::default();

for arg in &self.values.0 {
match arg {
AnyValueKind::Null => out.add(Option::<i32>::None),
AnyValueKind::Bool(b) => out.add(b),
AnyValueKind::SmallInt(i) => out.add(i),
AnyValueKind::Integer(i) => out.add(i),
AnyValueKind::BigInt(i) => out.add(i),
AnyValueKind::Real(r) => out.add(r),
AnyValueKind::Double(d) => out.add(d),
AnyValueKind::Text(t) => out.add(&**t),
AnyValueKind::Blob(b) => out.add(&**b),
for (index, arg) in self.values.0.iter().enumerate() {
match self.null_values.get(&index) {
Some(AnyTypeInfoKind::Null) => out.add(Option::<i32>::None),
Some(AnyTypeInfoKind::Bool) => out.add(Option::<bool>::None),
Some(AnyTypeInfoKind::SmallInt) => out.add(Option::<i16>::None),
Some(AnyTypeInfoKind::Integer) => out.add(Option::<i32>::None),
Some(AnyTypeInfoKind::BigInt) => out.add(Option::<i64>::None),
Some(AnyTypeInfoKind::Real) => out.add(Option::<f64>::None),
Some(AnyTypeInfoKind::Double) => out.add(Option::<f32>::None),
Some(AnyTypeInfoKind::Text) => out.add(Option::<String>::None),
Some(AnyTypeInfoKind::Blob) => out.add(Option::<Vec<u8>>::None),
None => match arg {
AnyValueKind::Null => out.add(Option::<i32>::None),
AnyValueKind::Bool(b) => out.add(b),
AnyValueKind::SmallInt(i) => out.add(i),
AnyValueKind::Integer(i) => out.add(i),
AnyValueKind::BigInt(i) => out.add(i),
AnyValueKind::Real(r) => out.add(r),
AnyValueKind::Double(d) => out.add(d),
AnyValueKind::Text(t) => out.add(&**t),
AnyValueKind::Blob(b) => out.add(&**b),
},
}?
}

Expand Down

0 comments on commit 9a8a9e1

Please sign in to comment.