diff --git a/sqlx-core/src/postgres/protocol/type_id.rs b/sqlx-core/src/postgres/protocol/type_id.rs index 83be3a2d..be3655a9 100644 --- a/sqlx-core/src/postgres/protocol/type_id.rs +++ b/sqlx-core/src/postgres/protocol/type_id.rs @@ -15,10 +15,14 @@ impl TypeId { pub(crate) const BOOL: TypeId = TypeId(16); + pub(crate) const CHAR: TypeId = TypeId(18); + pub(crate) const INT2: TypeId = TypeId(21); pub(crate) const INT4: TypeId = TypeId(23); pub(crate) const INT8: TypeId = TypeId(20); + pub(crate) const OID: TypeId = TypeId(26); + pub(crate) const FLOAT4: TypeId = TypeId(700); pub(crate) const FLOAT8: TypeId = TypeId(701); @@ -46,10 +50,14 @@ impl TypeId { pub(crate) const ARRAY_BOOL: TypeId = TypeId(1000); + pub(crate) const ARRAY_CHAR: TypeId = TypeId(1002); + pub(crate) const ARRAY_INT2: TypeId = TypeId(1005); pub(crate) const ARRAY_INT4: TypeId = TypeId(1007); pub(crate) const ARRAY_INT8: TypeId = TypeId(1016); + pub(crate) const ARRAY_OID: TypeId = TypeId(1028); + pub(crate) const ARRAY_FLOAT4: TypeId = TypeId(1021); pub(crate) const ARRAY_FLOAT8: TypeId = TypeId(1022); @@ -83,10 +91,14 @@ impl Display for TypeId { match *self { TypeId::BOOL => f.write_str("BOOL"), + TypeId::CHAR => f.write_str("\"CHAR\""), + TypeId::INT2 => f.write_str("INT2"), TypeId::INT4 => f.write_str("INT4"), TypeId::INT8 => f.write_str("INT8"), + TypeId::OID => f.write_str("OID"), + TypeId::FLOAT4 => f.write_str("FLOAT4"), TypeId::FLOAT8 => f.write_str("FLOAT8"), @@ -112,10 +124,14 @@ impl Display for TypeId { TypeId::ARRAY_BOOL => f.write_str("BOOL[]"), + TypeId::ARRAY_CHAR => f.write_str("\"CHAR\"[]"), + TypeId::ARRAY_INT2 => f.write_str("INT2[]"), TypeId::ARRAY_INT4 => f.write_str("INT4[]"), TypeId::ARRAY_INT8 => f.write_str("INT8[]"), + TypeId::ARRAY_OID => f.write_str("OID[]"), + TypeId::ARRAY_FLOAT4 => f.write_str("FLOAT4[]"), TypeId::ARRAY_FLOAT8 => f.write_str("FLOAT8[]"), diff --git a/sqlx-core/src/postgres/types/int.rs b/sqlx-core/src/postgres/types/int.rs index 1e57ee7a..a8321bac 100644 --- a/sqlx-core/src/postgres/types/int.rs +++ b/sqlx-core/src/postgres/types/int.rs @@ -10,6 +10,39 @@ use crate::postgres::{PgData, PgValue, Postgres}; use crate::types::Type; use crate::Error; +impl Type for i8 { + fn type_info() -> PgTypeInfo { + PgTypeInfo::new(TypeId::CHAR, "CHAR") + } +} + +impl Type for [i8] { + fn type_info() -> PgTypeInfo { + PgTypeInfo::new(TypeId::ARRAY_CHAR, "CHAR[]") + } +} + +impl Type for Vec { + fn type_info() -> PgTypeInfo { + <[i8] as Type>::type_info() + } +} + +impl Encode for i8 { + fn encode(&self, buf: &mut Vec) { + buf.extend_from_slice(&self.to_be_bytes()); + } +} + +impl<'de> Decode<'de, Postgres> for i8 { + fn decode(value: PgValue<'de>) -> crate::Result { + match value.try_get()? { + PgData::Binary(mut buf) => buf.read_i8().map_err(Error::decode), + PgData::Text(s) => Ok(s.as_bytes()[0] as i8), + } + } +} + impl Type for i16 { fn type_info() -> PgTypeInfo { PgTypeInfo::new(TypeId::INT2, "INT2") @@ -21,6 +54,7 @@ impl Type for [i16] { PgTypeInfo::new(TypeId::ARRAY_INT2, "INT2[]") } } + impl Type for Vec { fn type_info() -> PgTypeInfo { <[i16] as Type>::type_info() @@ -53,6 +87,7 @@ impl Type for [i32] { PgTypeInfo::new(TypeId::ARRAY_INT4, "INT4[]") } } + impl Type for Vec { fn type_info() -> PgTypeInfo { <[i32] as Type>::type_info() @@ -74,6 +109,39 @@ impl<'de> Decode<'de, Postgres> for i32 { } } +impl Type for u32 { + fn type_info() -> PgTypeInfo { + PgTypeInfo::new(TypeId::OID, "OID") + } +} + +impl Type for [u32] { + fn type_info() -> PgTypeInfo { + PgTypeInfo::new(TypeId::ARRAY_OID, "OID[]") + } +} + +impl Type for Vec { + fn type_info() -> PgTypeInfo { + <[u32] as Type>::type_info() + } +} + +impl Encode for u32 { + fn encode(&self, buf: &mut Vec) { + buf.extend_from_slice(&self.to_be_bytes()); + } +} + +impl<'de> Decode<'de, Postgres> for u32 { + fn decode(value: PgValue<'de>) -> crate::Result { + match value.try_get()? { + PgData::Binary(mut buf) => buf.read_u32::().map_err(Error::decode), + PgData::Text(s) => u32::from_str(s).map_err(Error::decode), + } + } +} + impl Type for i64 { fn type_info() -> PgTypeInfo { PgTypeInfo::new(TypeId::INT8, "INT8") diff --git a/sqlx-macros/src/database/postgres.rs b/sqlx-macros/src/database/postgres.rs index d213753b..656190a4 100644 --- a/sqlx-macros/src/database/postgres.rs +++ b/sqlx-macros/src/database/postgres.rs @@ -2,8 +2,10 @@ impl_database_ext! { sqlx::postgres::Postgres { bool, String | &str, + i8, i16, i32, + u32, i64, f32, f64, @@ -46,8 +48,10 @@ impl_database_ext! { // Arrays Vec | &[bool], Vec | &[String], + Vec | &[i8], Vec | &[i16], Vec | &[i32], + Vec | &[u32], Vec | &[i64], Vec | &[f32], Vec | &[f64], diff --git a/tests/postgres-types.rs b/tests/postgres-types.rs index e9c2052d..b0a4b340 100644 --- a/tests/postgres-types.rs +++ b/tests/postgres-types.rs @@ -22,8 +22,17 @@ test_type!(bool( "true::boolean" == true )); +test_type!(i8(Postgres, i8, "120::\"char\"" == 120_i8)); test_type!(i16(Postgres, i16, "821::smallint" == 821_i16)); -test_type!(i32(Postgres, i32, "94101::int" == 94101_i32)); + +test_type!(i32( + Postgres, + i32, + "94101::int" == 94101_i32, + "-5101::int" == -5101_i32 +)); + +test_type!(u32(Postgres, u32, "94101::oid" == 94101_u32)); test_type!(i64(Postgres, i64, "9358295312::bigint" == 9358295312_i64)); test_type!(f32(Postgres, f32, "9419.122::real" == 9419.122_f32));