Skip to content

Commit 06a6273

Browse files
committed
Support conversion of the UNKNOWN type to String
Closes #256
1 parent f892c4b commit 06a6273

File tree

2 files changed

+149
-138
lines changed

2 files changed

+149
-138
lines changed

postgres-shared/src/types/mod.rs

+46-86
Original file line numberDiff line numberDiff line change
@@ -156,11 +156,11 @@ impl Other {
156156
#[doc(hidden)]
157157
pub fn new(name: String, oid: Oid, kind: Kind, schema: String) -> Other {
158158
Other(Arc::new(OtherInner {
159-
name: name,
160-
oid: oid,
161-
kind: kind,
162-
schema: schema,
163-
}))
159+
name: name,
160+
oid: oid,
161+
kind: kind,
162+
schema: schema,
163+
}))
164164
}
165165
}
166166

@@ -236,19 +236,19 @@ impl WrongType {
236236
/// The following implementations are provided by this crate, along with the
237237
/// corresponding Postgres types:
238238
///
239-
/// | Rust type | Postgres type(s) |
240-
/// |-----------------------------------|--------------------------------------|
241-
/// | `bool` | BOOL |
242-
/// | `i8` | "char" |
243-
/// | `i16` | SMALLINT, SMALLSERIAL |
244-
/// | `i32` | INT, SERIAL |
245-
/// | `u32` | OID |
246-
/// | `i64` | BIGINT, BIGSERIAL |
247-
/// | `f32` | REAL |
248-
/// | `f64` | DOUBLE PRECISION |
249-
/// | `String` | VARCHAR, CHAR(n), TEXT, CITEXT, NAME |
250-
/// | `Vec<u8>` | BYTEA |
251-
/// | `HashMap<String, Option<String>>` | HSTORE |
239+
/// | Rust type | Postgres type(s) |
240+
/// |-----------------------------------|-----------------------------------------------|
241+
/// | `bool` | BOOL |
242+
/// | `i8` | "char" |
243+
/// | `i16` | SMALLINT, SMALLSERIAL |
244+
/// | `i32` | INT, SERIAL |
245+
/// | `u32` | OID |
246+
/// | `i64` | BIGINT, BIGSERIAL |
247+
/// | `f32` | REAL |
248+
/// | `f64` | DOUBLE PRECISION |
249+
/// | `String` | VARCHAR, CHAR(n), TEXT, CITEXT, NAME, UNKNOWN |
250+
/// | `Vec<u8>` | BYTEA |
251+
/// | `HashMap<String, Option<String>>` | HSTORE |
252252
///
253253
/// In addition, some implementations are provided for types in third party
254254
/// crates. These are disabled by default; to opt into one of these
@@ -288,9 +288,7 @@ pub trait FromSql: Sized {
288288
///
289289
/// The caller of this method is responsible for ensuring that this type
290290
/// is compatible with the Postgres `Type`.
291-
fn from_sql(ty: &Type,
292-
raw: &[u8])
293-
-> Result<Self, Box<Error + Sync + Send>>;
291+
fn from_sql(ty: &Type, raw: &[u8]) -> Result<Self, Box<Error + Sync + Send>>;
294292

295293
/// Creates a new value of this type from a `NULL` SQL value.
296294
///
@@ -306,9 +304,7 @@ pub trait FromSql: Sized {
306304

307305
/// A convenience function that delegates to `from_sql` and `from_sql_null` depending on the
308306
/// value of `raw`.
309-
fn from_sql_nullable(ty: &Type,
310-
raw: Option<&[u8]>)
311-
-> Result<Self, Box<Error + Sync + Send>> {
307+
fn from_sql_nullable(ty: &Type, raw: Option<&[u8]>) -> Result<Self, Box<Error + Sync + Send>> {
312308
match raw {
313309
Some(raw) => Self::from_sql(ty, raw),
314310
None => Self::from_sql_null(ty),
@@ -321,9 +317,7 @@ pub trait FromSql: Sized {
321317
}
322318

323319
impl<T: FromSql> FromSql for Option<T> {
324-
fn from_sql(ty: &Type,
325-
raw: &[u8])
326-
-> Result<Option<T>, Box<Error + Sync + Send>> {
320+
fn from_sql(ty: &Type, raw: &[u8]) -> Result<Option<T>, Box<Error + Sync + Send>> {
327321
<T as FromSql>::from_sql(ty, raw).map(Some)
328322
}
329323

@@ -337,9 +331,7 @@ impl<T: FromSql> FromSql for Option<T> {
337331
}
338332

339333
impl<T: FromSql> FromSql for Vec<T> {
340-
fn from_sql(ty: &Type,
341-
raw: &[u8])
342-
-> Result<Vec<T>, Box<Error + Sync + Send>> {
334+
fn from_sql(ty: &Type, raw: &[u8]) -> Result<Vec<T>, Box<Error + Sync + Send>> {
343335
let member_type = match *ty.kind() {
344336
Kind::Array(ref member) => member,
345337
_ => panic!("expected array type"),
@@ -350,7 +342,8 @@ impl<T: FromSql> FromSql for Vec<T> {
350342
return Err("array contains too many dimensions".into());
351343
}
352344

353-
array.values()
345+
array
346+
.values()
354347
.and_then(|v| T::from_sql_nullable(member_type, v))
355348
.collect()
356349
}
@@ -364,9 +357,7 @@ impl<T: FromSql> FromSql for Vec<T> {
364357
}
365358

366359
impl FromSql for Vec<u8> {
367-
fn from_sql(_: &Type,
368-
raw: &[u8])
369-
-> Result<Vec<u8>, Box<Error + Sync + Send>> {
360+
fn from_sql(_: &Type, raw: &[u8]) -> Result<Vec<u8>, Box<Error + Sync + Send>> {
370361
Ok(types::bytea_from_sql(raw).to_owned())
371362
}
372363

@@ -380,7 +371,7 @@ impl FromSql for String {
380371

381372
fn accepts(ty: &Type) -> bool {
382373
match *ty {
383-
Type::Varchar | Type::Text | Type::Bpchar | Type::Name => true,
374+
Type::Varchar | Type::Text | Type::Bpchar | Type::Name | Type::Unknown => true,
384375
Type::Other(ref u) if u.name() == "citext" => true,
385376
_ => false,
386377
}
@@ -500,10 +491,7 @@ pub trait ToSql: fmt::Debug {
500491
/// The return value indicates if this value should be represented as
501492
/// `NULL`. If this is the case, implementations **must not** write
502493
/// anything to `out`.
503-
fn to_sql(&self,
504-
ty: &Type,
505-
out: &mut Vec<u8>)
506-
-> Result<IsNull, Box<Error + Sync + Send>>
494+
fn to_sql(&self, ty: &Type, out: &mut Vec<u8>) -> Result<IsNull, Box<Error + Sync + Send>>
507495
where Self: Sized;
508496

509497
/// Determines if a value of this type can be converted to the specified
@@ -523,10 +511,7 @@ pub trait ToSql: fmt::Debug {
523511
impl<'a, T> ToSql for &'a T
524512
where T: ToSql
525513
{
526-
fn to_sql(&self,
527-
ty: &Type,
528-
out: &mut Vec<u8>)
529-
-> Result<IsNull, Box<Error + Sync + Send>> {
514+
fn to_sql(&self, ty: &Type, out: &mut Vec<u8>) -> Result<IsNull, Box<Error + Sync + Send>> {
530515
(*self).to_sql(ty, out)
531516
}
532517

@@ -538,10 +523,7 @@ impl<'a, T> ToSql for &'a T
538523
}
539524

540525
impl<T: ToSql> ToSql for Option<T> {
541-
fn to_sql(&self,
542-
ty: &Type,
543-
out: &mut Vec<u8>)
544-
-> Result<IsNull, Box<Error + Sync + Send>> {
526+
fn to_sql(&self, ty: &Type, out: &mut Vec<u8>) -> Result<IsNull, Box<Error + Sync + Send>> {
545527
match *self {
546528
Some(ref val) => val.to_sql(ty, out),
547529
None => Ok(IsNull::Yes),
@@ -556,10 +538,7 @@ impl<T: ToSql> ToSql for Option<T> {
556538
}
557539

558540
impl<'a, T: ToSql> ToSql for &'a [T] {
559-
fn to_sql(&self,
560-
ty: &Type,
561-
w: &mut Vec<u8>)
562-
-> Result<IsNull, Box<Error + Sync + Send>> {
541+
fn to_sql(&self, ty: &Type, w: &mut Vec<u8>) -> Result<IsNull, Box<Error + Sync + Send>> {
563542
let member_type = match *ty.kind() {
564543
Kind::Array(ref member) => member,
565544
_ => panic!("expected array type"),
@@ -571,16 +550,14 @@ impl<'a, T: ToSql> ToSql for &'a [T] {
571550
};
572551

573552
types::array_to_sql(Some(dimension),
574-
true,
575-
member_type.oid(),
576-
self.iter(),
577-
|e, w| {
578-
match e.to_sql(member_type, w)? {
579-
IsNull::No => Ok(postgres_protocol::IsNull::No),
580-
IsNull::Yes => Ok(postgres_protocol::IsNull::Yes),
581-
}
582-
},
583-
w)?;
553+
true,
554+
member_type.oid(),
555+
self.iter(),
556+
|e, w| match e.to_sql(member_type, w)? {
557+
IsNull::No => Ok(postgres_protocol::IsNull::No),
558+
IsNull::Yes => Ok(postgres_protocol::IsNull::Yes),
559+
},
560+
w)?;
584561
Ok(IsNull::No)
585562
}
586563

@@ -595,10 +572,7 @@ impl<'a, T: ToSql> ToSql for &'a [T] {
595572
}
596573

597574
impl<'a> ToSql for &'a [u8] {
598-
fn to_sql(&self,
599-
_: &Type,
600-
w: &mut Vec<u8>)
601-
-> Result<IsNull, Box<Error + Sync + Send>> {
575+
fn to_sql(&self, _: &Type, w: &mut Vec<u8>) -> Result<IsNull, Box<Error + Sync + Send>> {
602576
types::bytea_to_sql(*self, w);
603577
Ok(IsNull::No)
604578
}
@@ -609,10 +583,7 @@ impl<'a> ToSql for &'a [u8] {
609583
}
610584

611585
impl<T: ToSql> ToSql for Vec<T> {
612-
fn to_sql(&self,
613-
ty: &Type,
614-
w: &mut Vec<u8>)
615-
-> Result<IsNull, Box<Error + Sync + Send>> {
586+
fn to_sql(&self, ty: &Type, w: &mut Vec<u8>) -> Result<IsNull, Box<Error + Sync + Send>> {
616587
<&[T] as ToSql>::to_sql(&&**self, ty, w)
617588
}
618589

@@ -624,10 +595,7 @@ impl<T: ToSql> ToSql for Vec<T> {
624595
}
625596

626597
impl ToSql for Vec<u8> {
627-
fn to_sql(&self,
628-
ty: &Type,
629-
w: &mut Vec<u8>)
630-
-> Result<IsNull, Box<Error + Sync + Send>> {
598+
fn to_sql(&self, ty: &Type, w: &mut Vec<u8>) -> Result<IsNull, Box<Error + Sync + Send>> {
631599
<&[u8] as ToSql>::to_sql(&&**self, ty, w)
632600
}
633601

@@ -639,10 +607,7 @@ impl ToSql for Vec<u8> {
639607
}
640608

641609
impl<'a> ToSql for &'a str {
642-
fn to_sql(&self,
643-
_: &Type,
644-
w: &mut Vec<u8>)
645-
-> Result<IsNull, Box<Error + Sync + Send>> {
610+
fn to_sql(&self, _: &Type, w: &mut Vec<u8>) -> Result<IsNull, Box<Error + Sync + Send>> {
646611
types::text_to_sql(*self, w);
647612
Ok(IsNull::No)
648613
}
@@ -659,10 +624,7 @@ impl<'a> ToSql for &'a str {
659624
}
660625

661626
impl ToSql for String {
662-
fn to_sql(&self,
663-
ty: &Type,
664-
w: &mut Vec<u8>)
665-
-> Result<IsNull, Box<Error + Sync + Send>> {
627+
fn to_sql(&self, ty: &Type, w: &mut Vec<u8>) -> Result<IsNull, Box<Error + Sync + Send>> {
666628
<&str as ToSql>::to_sql(&&**self, ty, w)
667629
}
668630

@@ -701,11 +663,9 @@ simple_to!(f32, float4_to_sql, Type::Float4);
701663
simple_to!(f64, float8_to_sql, Type::Float8);
702664

703665
impl ToSql for HashMap<String, Option<String>> {
704-
fn to_sql(&self,
705-
_: &Type,
706-
w: &mut Vec<u8>)
707-
-> Result<IsNull, Box<Error + Sync + Send>> {
708-
types::hstore_to_sql(self.iter().map(|(k, v)| (&**k, v.as_ref().map(|v| &**v))), w)?;
666+
fn to_sql(&self, _: &Type, w: &mut Vec<u8>) -> Result<IsNull, Box<Error + Sync + Send>> {
667+
types::hstore_to_sql(self.iter().map(|(k, v)| (&**k, v.as_ref().map(|v| &**v))),
668+
w)?;
709669
Ok(IsNull::No)
710670
}
711671

0 commit comments

Comments
 (0)