-
-
Notifications
You must be signed in to change notification settings - Fork 1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Support for Unsigned Types in Mysql #1561
Conversation
Tests are failing |
diesel/src/mysql/types/mod.rs
Outdated
@@ -12,6 +12,12 @@ use mysql::Mysql; | |||
use serialize::{self, IsNull, Output, ToSql}; | |||
use sql_types; | |||
|
|||
impl sql_types::HasSqlType<sql_types::Unsigned<sql_types::Integer>> for Mysql { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs to support more than just Integer
doesn't it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, is it just SmallInt
, Integer
, and BigInt
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This impl can probably just be generic over everything.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unsigned strings let's go !
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There wouldn't be a corresponding AsExpression
impl, so... :P
There's nothing to prevent you from putting Unsigned<Text>
in your table declaration already
diesel/src/sql_types/mod.rs
Outdated
type QueryId = (); | ||
} | ||
|
||
// impl<ST: NotNull + SingleValue> QueryId for ST { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
✂️
You're missing |
@sgrif it seems as though, for the |
diesel/src/sql_types/mod.rs
Outdated
@@ -70,7 +72,7 @@ pub struct Tinyint; | |||
/// - [`i16`][i16] | |||
/// | |||
/// [i16]: https://doc.rust-lang.org/nightly/std/primitive.i16.html | |||
#[derive(Debug, Clone, Copy, Default, QueryId, SqlType)] | |||
#[derive(Debug, Clone, Copy, Default, QueryId, SqlType, FromSqlRow)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This type should not be deriving FromSqlRow
, nor should any other SQL types.
diesel/src/sql_types/mod.rs
Outdated
/// The unsigned SQL type. | ||
/// TODO: Add proper documentation. | ||
#[derive(Debug, Clone, Copy, Default, SqlType, FromSqlRow, AsExpression)] | ||
pub struct Unsigned<ST: NotNull + SingleValue + QueryId + Expression + AsExpression<ST>>(ST); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be in the mysql module, it's backend specific.
diesel/src/sql_types/mod.rs
Outdated
type SqlType = BigInt; | ||
} | ||
|
||
impl QueryId for u16 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
None of these should have QueryId
implemented.
diesel/src/sql_types/mod.rs
Outdated
const HAS_STATIC_QUERY_ID: bool = ST::HAS_STATIC_QUERY_ID; | ||
} | ||
|
||
impl Expression for SmallInt { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
None of these should have Expression
implemented.
diesel/src/sql_types/mod.rs
Outdated
@@ -467,3 +481,37 @@ impl<T: NotNull> IntoNullable for Nullable<T> { | |||
pub trait SingleValue {} | |||
|
|||
impl<T: NotNull + SingleValue> SingleValue for Nullable<T> {} | |||
|
|||
impl<ST: NotNull + SingleValue + QueryId + Expression + AsExpression<ST>> QueryId for Unsigned<ST> { | |||
type QueryId = ST::QueryId; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be Unsigned<ST::QueryId>
.
diesel/src/type_impls/integers.rs
Outdated
@@ -88,3 +88,85 @@ impl<DB: Backend> ToSql<sql_types::BigInt, DB> for i64 { | |||
.map_err(|e| Box::new(e) as Box<Error + Send + Sync>) | |||
} | |||
} | |||
|
|||
impl<DB: Backend<RawValue = [u8]>> FromSql<sql_types::SmallInt, DB> for u16 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should only be implemented for Unsigned<SmallInt>
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also all of these implementations are backend specific, they should not be generic like this.
diesel/src/type_impls/integers.rs
Outdated
} | ||
} | ||
|
||
impl<DB: Backend> ToSql<sql_types::SmallInt, DB> for u16 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should only be implemented for Unsigned<SmallInt>
.
diesel/src/type_impls/integers.rs
Outdated
} | ||
} | ||
|
||
impl<DB: Backend<RawValue = [u8]>> FromSql<sql_types::Integer, DB> for u32 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should only be implemented for Unsigned<Integer>
.
diesel/src/type_impls/integers.rs
Outdated
} | ||
} | ||
|
||
impl<DB: Backend> ToSql<sql_types::Integer, DB> for u32 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should only be implemented for Unsigned<Integer>
.
diesel/src/type_impls/integers.rs
Outdated
} | ||
} | ||
|
||
impl<DB: Backend<RawValue = [u8]>> FromSql<sql_types::BigInt, DB> for u64 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should only be implemented for Unsigned<BigInt>
.
diesel/src/type_impls/integers.rs
Outdated
} | ||
} | ||
|
||
impl<DB: Backend> ToSql<sql_types::BigInt, DB> for u64 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should only be implemented for Unsigned<BigInt>
.
diesel/src/type_impls/unsigned.rs
Outdated
use query_builder::QueryId; | ||
use sql_types::*; | ||
|
||
impl<T, DB> HasSqlType<Unsigned<T>> for DB |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be MySQL specific.
diesel/src/mysql/types/mod.rs
Outdated
pub struct Unsigned<ST: NotNull + SingleValue + QueryId>(ST); | ||
|
||
#[doc(hidden)] | ||
pub type UInt2 = Unsigned<SmallInt>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need these types?
@joshleeb Since CI is still red, and there's still a bunch of debug code in there I'm assuming this is still WIP. I'm hoping to release 1.2 this week, so let me know what I can do to help get this done. |
So far the added tests for unsigned types are passing but some documentation still needs to be added. |
Your code has changed the errors that occur. You should look at the differences, if they seem reasonable, update the tests. |
Thanks for doing this. Just started trying diesel out on our existing database today and ran into this almost immediately. Also it looks like the tests are all passing now 👍 |
diesel/src/mysql/types/mod.rs
Outdated
#[derive(Debug, Clone, Copy, Default, SqlType)] | ||
pub struct Unsigned<ST: NotNull + SingleValue + QueryId>(ST); | ||
|
||
impl ToSql<Unsigned<Integer>, Mysql> for u16 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this be impl ToSql<Unsigned<SmallInt>, Mysql> for u16
?
diesel/src/mysql/types/mod.rs
Outdated
} | ||
} | ||
|
||
impl ToSql<Unsigned<Integer>, Mysql> for u64 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be impl ToSql<Unsigned<BigInt>, Mysql> for u64
?
fn from_sql(bytes: Option<&[u8]>) -> deserialize::Result<Self> { | ||
Ok(not_none!(bytes).iter().any(|x| *x != 0)) | ||
} | ||
} | ||
|
||
impl<ST> HasSqlType<Unsigned<ST>> for Mysql |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if this is a good idea, because this will allow also things like Unsigned<Bool>
to be valid in some contexts. (Note for @diesel-rs/reviewers)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@weiznich would it be better to have a HasSqlType
for SmallInt
, Integer
, and BigInt
, instead of this more generic version?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think the HasSqlType
impl being generic is a problem. It doesn't enable anything on its own.
diesel/src/mysql/types/mod.rs
Outdated
fn build(row: Self::Row) -> Self { | ||
row | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here it seems like the impl for u32
is missing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I went to add this and doing so causes a compilation error. It looks like this implementation is already done by https://github.com/diesel-rs/diesel/blob/master/diesel/src/type_impls/primitives.rs#L38
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll add similar structs to /diesel/src/type_impls/primitives.rs
for u16
and u64
. I imagine that's better than implementing the traits manually here.
diesel/src/mysql/types/mod.rs
Outdated
fn build_from_row<T: Row<Mysql>>(row: &mut T) -> deserialize::Result<Self> { | ||
Self::from_sql(row.take()) | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also: Is the impl for u32
missing?
@@ -101,14 +103,22 @@ fn determine_type_name(sql_type_name: &str) -> Result<&str, Box<Error>> { | |||
}; | |||
|
|||
if result.to_lowercase().contains("unsigned") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this condition should be replaced with a call to determine_unsigned
The travis build appears to be breaking on compiling cargo metadata. That seems like it should be unrelated to the change here. |
Ref. Handling unsigned integer types from MySQL #1181
This functionality was originally added in #782 and then reverted in #912.