diff --git a/sqlx-core/src/mysql/protocol/row.rs b/sqlx-core/src/mysql/protocol/row.rs index 92f517d6..384db51c 100644 --- a/sqlx-core/src/mysql/protocol/row.rs +++ b/sqlx-core/src/mysql/protocol/row.rs @@ -110,16 +110,16 @@ impl<'c> Row<'c> { if is_null { values.push(None); } else { - let size = match columns[column_idx] { - TypeId::TINY_INT => 1, - TypeId::SMALL_INT => 2, - TypeId::INT | TypeId::FLOAT => 4, - TypeId::BIG_INT | TypeId::DOUBLE => 8, + let (offset, size) = match columns[column_idx] { + TypeId::TINY_INT => (0, 1), + TypeId::SMALL_INT => (0, 2), + TypeId::INT | TypeId::FLOAT => (0, 4), + TypeId::BIG_INT | TypeId::DOUBLE => (0, 8), - TypeId::DATE => 5, - TypeId::TIME => 1 + buffer[index] as usize, + TypeId::DATE => (0, 5), + TypeId::TIME => (0, 1 + buffer[index] as usize), - TypeId::TIMESTAMP | TypeId::DATETIME => 1 + buffer[index] as usize, + TypeId::TIMESTAMP | TypeId::DATETIME => (0, 1 + buffer[index] as usize), TypeId::TINY_BLOB | TypeId::MEDIUM_BLOB @@ -129,7 +129,7 @@ impl<'c> Row<'c> { | TypeId::VAR_CHAR => { let (len_size, len) = get_lenenc(&buffer[index..]); - len_size + len.unwrap_or_default() + (len_size, len.unwrap_or_default()) } id => { @@ -137,8 +137,8 @@ impl<'c> Row<'c> { } }; - values.push(Some(index..(index + size))); - index += size; + values.push(Some((index + offset)..(index + offset + size))); + index += size + offset; } } diff --git a/sqlx-core/src/mysql/types/bytes.rs b/sqlx-core/src/mysql/types/bytes.rs index 685dd0aa..ec1725cb 100644 --- a/sqlx-core/src/mysql/types/bytes.rs +++ b/sqlx-core/src/mysql/types/bytes.rs @@ -2,7 +2,7 @@ use byteorder::LittleEndian; use crate::decode::Decode; use crate::encode::Encode; -use crate::mysql::io::{BufExt, BufMutExt}; +use crate::mysql::io::{BufMutExt}; use crate::mysql::protocol::TypeId; use crate::mysql::types::MySqlTypeInfo; use crate::mysql::{MySql, MySqlValue}; @@ -41,16 +41,7 @@ impl Encode for Vec { impl<'de> Decode<'de, MySql> for Vec { fn decode(value: Option>) -> crate::Result { match value.try_into()? { - MySqlValue::Binary(mut buf) => { - let len = buf - .get_uint_lenenc::() - .map_err(crate::Error::decode)? - .unwrap_or_default(); - - Ok((&buf[..(len as usize)]).to_vec()) - } - - MySqlValue::Text(s) => Ok(s.to_vec()), + MySqlValue::Binary(buf) | MySqlValue::Text(buf) => Ok(buf.to_vec()), } } } @@ -58,16 +49,7 @@ impl<'de> Decode<'de, MySql> for Vec { impl<'de> Decode<'de, MySql> for &'de [u8] { fn decode(value: Option>) -> crate::Result { match value.try_into()? { - MySqlValue::Binary(mut buf) => { - let len = buf - .get_uint_lenenc::() - .map_err(crate::Error::decode)? - .unwrap_or_default(); - - Ok(&buf[..(len as usize)]) - } - - MySqlValue::Text(s) => Ok(s), + MySqlValue::Binary(buf) | MySqlValue::Text(buf) => Ok(buf), } } } diff --git a/sqlx-core/src/mysql/types/str.rs b/sqlx-core/src/mysql/types/str.rs index e644b671..043352d2 100644 --- a/sqlx-core/src/mysql/types/str.rs +++ b/sqlx-core/src/mysql/types/str.rs @@ -4,7 +4,7 @@ use byteorder::LittleEndian; use crate::decode::Decode; use crate::encode::Encode; -use crate::mysql::io::{BufExt, BufMutExt}; +use crate::mysql::io::{BufMutExt}; use crate::mysql::protocol::TypeId; use crate::mysql::types::MySqlTypeInfo; use crate::mysql::{MySql, MySqlValue}; @@ -44,16 +44,9 @@ impl Encode for String { impl<'de> Decode<'de, MySql> for &'de str { fn decode(value: Option>) -> crate::Result { match value.try_into()? { - MySqlValue::Binary(mut buf) => { - let len = buf - .get_uint_lenenc::() - .map_err(crate::Error::decode)? - .unwrap_or_default(); - - from_utf8(&buf[..(len as usize)]).map_err(crate::Error::decode) + MySqlValue::Binary(buf) | MySqlValue::Text(buf) => { + from_utf8(buf).map_err(crate::Error::decode) } - - MySqlValue::Text(s) => from_utf8(s).map_err(crate::Error::decode), } } } diff --git a/sqlx-macros/src/derives.rs b/sqlx-macros/src/derives.rs index 1d4a7172..b4e73a07 100644 --- a/sqlx-macros/src/derives.rs +++ b/sqlx-macros/src/derives.rs @@ -25,10 +25,10 @@ pub(crate) fn expand_derive_encode(input: DeriveInput) -> syn::Result for #ident #ty_generics #where_clause { - fn encode(&self, buf: &mut std::vec::Vec) { + fn encode(&self, buf: &mut ::RawBuffer) { sqlx::encode::Encode::encode(&self.0, buf) } - fn encode_nullable(&self, buf: &mut std::vec::Vec) -> sqlx::encode::IsNull { + fn encode_nullable(&self, buf: &mut ::RawBuffer) -> sqlx::encode::IsNull { sqlx::encode::Encode::encode_nullable(&self.0, buf) } fn size_hint(&self) -> usize { diff --git a/tests/derives.rs b/tests/derives.rs index facdbea9..f6feac71 100644 --- a/tests/derives.rs +++ b/tests/derives.rs @@ -4,31 +4,36 @@ use sqlx::encode::Encode; #[derive(PartialEq, Debug, Encode, Decode)] struct Foo(i32); -#[test] -#[cfg(feature = "mysql")] -fn encode_mysql() { - encode_with_db::(); -} - #[test] #[cfg(feature = "postgres")] -fn encode_postgres() { - encode_with_db::(); -} - -#[allow(dead_code)] -fn encode_with_db() -where - Foo: Encode, - i32: Encode, +fn encode_with_postgres() { + use sqlx_core::postgres::Postgres; + let example = Foo(0x1122_3344); let mut encoded = Vec::new(); let mut encoded_orig = Vec::new(); - Encode::::encode(&example, &mut encoded); - Encode::::encode(&example.0, &mut encoded_orig); + Encode::::encode(&example, &mut encoded); + Encode::::encode(&example.0, &mut encoded_orig); + + assert_eq!(encoded, encoded_orig); +} + +#[test] +#[cfg(feature = "mysql")] +fn encode_with_mysql() +{ + use sqlx_core::mysql::MySql; + + let example = Foo(0x1122_3344); + + let mut encoded = Vec::new(); + let mut encoded_orig = Vec::new(); + + Encode::::encode(&example, &mut encoded); + Encode::::encode(&example.0, &mut encoded_orig); assert_eq!(encoded, encoded_orig); }