fix: do not enforce type equality if matching against the NULL type

This commit is contained in:
Ryan Leckey 2020-07-15 02:04:32 -07:00
parent 1247daec83
commit dc5fc1b6c1
9 changed files with 41 additions and 4 deletions

View File

@ -33,6 +33,22 @@ pub(crate) enum AnyTypeInfoKind {
}
impl TypeInfo for AnyTypeInfo {
fn is_null(&self) -> bool {
match &self.0 {
#[cfg(feature = "postgres")]
AnyTypeInfoKind::Postgres(ty) => ty.is_null(),
#[cfg(feature = "mysql")]
AnyTypeInfoKind::MySql(ty) => ty.is_null(),
#[cfg(feature = "sqlite")]
AnyTypeInfoKind::Sqlite(ty) => ty.is_null(),
#[cfg(feature = "mssql")]
AnyTypeInfoKind::Mssql(ty) => ty.is_null(),
}
}
fn name(&self) -> &str {
match &self.0 {
#[cfg(feature = "postgres")]

View File

@ -1,6 +1,6 @@
use std::fmt::{self, Display, Formatter};
use crate::mssql::protocol::type_info::TypeInfo as ProtocolTypeInfo;
use crate::mssql::protocol::type_info::{TypeInfo as ProtocolTypeInfo, DataType};
use crate::type_info::TypeInfo;
#[derive(Debug, Clone, PartialEq, Eq)]
@ -8,6 +8,10 @@ use crate::type_info::TypeInfo;
pub struct MssqlTypeInfo(pub(crate) ProtocolTypeInfo);
impl TypeInfo for MssqlTypeInfo {
fn is_null(&self) -> bool {
matches!(self.0.ty, DataType::Null)
}
fn name(&self) -> &str {
self.0.name()
}

View File

@ -60,6 +60,10 @@ impl Display for MySqlTypeInfo {
}
impl TypeInfo for MySqlTypeInfo {
fn is_null(&self) -> bool {
matches!(self.r#type, ColumnType::Null)
}
fn name(&self) -> &str {
self.r#type.name(self.char_set, self.flags)
}

View File

@ -741,6 +741,10 @@ impl TypeInfo for PgTypeInfo {
fn name(&self) -> &str {
self.0.display_name()
}
fn is_null(&self) -> bool {
false
}
}
impl PartialEq<PgCustomType> for PgCustomType {

View File

@ -6,6 +6,7 @@ use crate::error::{mismatched_types, BoxDynError};
use crate::postgres::type_info::{PgType, PgTypeKind};
use crate::postgres::{PgArgumentBuffer, PgTypeInfo, PgValueFormat, PgValueRef, Postgres};
use crate::types::Type;
use crate::type_info::TypeInfo;
#[doc(hidden)]
pub struct PgRecordEncoder<'a> {
@ -126,7 +127,7 @@ impl<'r> PgRecordDecoder<'r> {
self.ind += 1;
if let Some(ty) = &element_type_opt {
if !T::compatible(ty) {
if !ty.is_null() && !T::compatible(ty) {
return Err(mismatched_types::<Postgres, T>(ty));
}
}

View File

@ -4,6 +4,7 @@ use crate::database::{Database, HasValueRef};
use crate::decode::Decode;
use crate::error::{mismatched_types, Error};
use crate::types::Type;
use crate::type_info::TypeInfo;
use crate::value::ValueRef;
/// A type that can be used to index into a [`Row`].
@ -171,7 +172,7 @@ pub trait Row: private_row::Sealed + Unpin + Send + Sync + 'static {
if !value.is_null() {
let ty = value.type_info();
if !T::compatible(&ty) {
if !ty.is_null() && !T::compatible(&ty) {
return Err(Error::ColumnDecode {
index: format!("{:?}", index),
source: mismatched_types::<Self::Database, T>(&ty),

View File

@ -40,6 +40,10 @@ impl Display for SqliteTypeInfo {
}
impl TypeInfo for SqliteTypeInfo {
fn is_null(&self) -> bool {
matches!(self.0, DataType::Null)
}
fn name(&self) -> &str {
match self.0 {
DataType::Null => "NULL",

View File

@ -2,6 +2,8 @@ use std::fmt::{Debug, Display};
/// Provides information about a SQL type for the database driver.
pub trait TypeInfo: Debug + Display + Clone + PartialEq<Self> {
fn is_null(&self) -> bool;
/// Returns the database system name of the type. Length specifiers should not be included.
/// Common type names are `VARCHAR`, `TEXT`, or `INT`. Type names should be uppercase. They
/// should be a rough approximation of how they are written in SQL in the given database.

View File

@ -2,6 +2,7 @@ use crate::database::{Database, HasValueRef};
use crate::decode::Decode;
use crate::error::{mismatched_types, Error};
use crate::types::Type;
use crate::type_info::TypeInfo;
/// An owned value from the database.
pub trait Value {
@ -65,7 +66,7 @@ pub trait Value {
if !self.is_null() {
let ty = self.type_info();
if !T::compatible(&ty) {
if !ty.is_null() && !T::compatible(&ty) {
return Err(Error::Decode(mismatched_types::<Self::Database, T>(&ty)));
}
}