This commit is contained in:
Steven Fackler 2018-11-28 19:32:29 -08:00
parent a0ba0ce214
commit 52dd0b6780
22 changed files with 306 additions and 273 deletions

View File

@ -9,7 +9,7 @@
//! //!
//! This library assumes that the `client_encoding` backend parameter has been //! This library assumes that the `client_encoding` backend parameter has been
//! set to `UTF8`. It will most likely not behave properly if that is not the case. //! set to `UTF8`. It will most likely not behave properly if that is not the case.
#![doc(html_root_url="https://docs.rs/postgres-protocol/0.3")] #![doc(html_root_url = "https://docs.rs/postgres-protocol/0.3")]
#![warn(missing_docs)] #![warn(missing_docs)]
extern crate base64; extern crate base64;
extern crate byteorder; extern crate byteorder;
@ -68,13 +68,16 @@ macro_rules! from_usize {
#[inline] #[inline]
fn from_usize(x: usize) -> io::Result<$t> { fn from_usize(x: usize) -> io::Result<$t> {
if x > <$t>::max_value() as usize { if x > <$t>::max_value() as usize {
Err(io::Error::new(io::ErrorKind::InvalidInput, "value too large to transmit")) Err(io::Error::new(
io::ErrorKind::InvalidInput,
"value too large to transmit",
))
} else { } else {
Ok(x as $t) Ok(x as $t)
} }
} }
} }
} };
} }
from_usize!(i16); from_usize!(i16);

View File

@ -1,12 +1,12 @@
//! Frontend message serialization. //! Frontend message serialization.
#![allow(missing_docs)] #![allow(missing_docs)]
use byteorder::{WriteBytesExt, BigEndian, ByteOrder}; use byteorder::{BigEndian, ByteOrder, WriteBytesExt};
use std::error::Error; use std::error::Error;
use std::io; use std::io;
use std::marker; use std::marker;
use {Oid, FromUsize, IsNull, write_nullable}; use {write_nullable, FromUsize, IsNull, Oid};
pub enum Message<'a> { pub enum Message<'a> {
Bind { Bind {
@ -16,24 +16,51 @@ pub enum Message<'a> {
values: &'a [Option<Vec<u8>>], values: &'a [Option<Vec<u8>>],
result_formats: &'a [i16], result_formats: &'a [i16],
}, },
CancelRequest { process_id: i32, secret_key: i32 }, CancelRequest {
Close { variant: u8, name: &'a str }, process_id: i32,
CopyData { data: &'a [u8] }, secret_key: i32,
},
Close {
variant: u8,
name: &'a str,
},
CopyData {
data: &'a [u8],
},
CopyDone, CopyDone,
CopyFail { message: &'a str }, CopyFail {
Describe { variant: u8, name: &'a str }, message: &'a str,
Execute { portal: &'a str, max_rows: i32 }, },
Describe {
variant: u8,
name: &'a str,
},
Execute {
portal: &'a str,
max_rows: i32,
},
Parse { Parse {
name: &'a str, name: &'a str,
query: &'a str, query: &'a str,
param_types: &'a [Oid], param_types: &'a [Oid],
}, },
PasswordMessage { password: &'a str }, PasswordMessage {
Query { query: &'a str }, password: &'a str,
SaslInitialResponse { mechanism: &'a str, data: &'a [u8] }, },
SaslResponse { data: &'a [u8] }, Query {
query: &'a str,
},
SaslInitialResponse {
mechanism: &'a str,
data: &'a [u8],
},
SaslResponse {
data: &'a [u8],
},
SslRequest, SslRequest,
StartupMessage { parameters: &'a [(String, String)] }, StartupMessage {
parameters: &'a [(String, String)],
},
Sync, Sync,
Terminate, Terminate,
#[doc(hidden)] #[doc(hidden)]

View File

@ -33,7 +33,8 @@ impl SqlState {
pub const WARNING_IMPLICIT_ZERO_BIT_PADDING: SqlState = SqlState(Cow::Borrowed("01008")); pub const WARNING_IMPLICIT_ZERO_BIT_PADDING: SqlState = SqlState(Cow::Borrowed("01008"));
/// 01003 /// 01003
pub const WARNING_NULL_VALUE_ELIMINATED_IN_SET_FUNCTION: SqlState = SqlState(Cow::Borrowed("01003")); pub const WARNING_NULL_VALUE_ELIMINATED_IN_SET_FUNCTION: SqlState =
SqlState(Cow::Borrowed("01003"));
/// 01007 /// 01007
pub const WARNING_PRIVILEGE_NOT_GRANTED: SqlState = SqlState(Cow::Borrowed("01007")); pub const WARNING_PRIVILEGE_NOT_GRANTED: SqlState = SqlState(Cow::Borrowed("01007"));
@ -51,7 +52,8 @@ impl SqlState {
pub const NO_DATA: SqlState = SqlState(Cow::Borrowed("02000")); pub const NO_DATA: SqlState = SqlState(Cow::Borrowed("02000"));
/// 02001 /// 02001
pub const NO_ADDITIONAL_DYNAMIC_RESULT_SETS_RETURNED: SqlState = SqlState(Cow::Borrowed("02001")); pub const NO_ADDITIONAL_DYNAMIC_RESULT_SETS_RETURNED: SqlState =
SqlState(Cow::Borrowed("02001"));
/// 03000 /// 03000
pub const SQL_STATEMENT_NOT_YET_COMPLETE: SqlState = SqlState(Cow::Borrowed("03000")); pub const SQL_STATEMENT_NOT_YET_COMPLETE: SqlState = SqlState(Cow::Borrowed("03000"));
@ -66,10 +68,12 @@ impl SqlState {
pub const CONNECTION_FAILURE: SqlState = SqlState(Cow::Borrowed("08006")); pub const CONNECTION_FAILURE: SqlState = SqlState(Cow::Borrowed("08006"));
/// 08001 /// 08001
pub const SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION: SqlState = SqlState(Cow::Borrowed("08001")); pub const SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION: SqlState =
SqlState(Cow::Borrowed("08001"));
/// 08004 /// 08004
pub const SQLSERVER_REJECTED_ESTABLISHMENT_OF_SQLCONNECTION: SqlState = SqlState(Cow::Borrowed("08004")); pub const SQLSERVER_REJECTED_ESTABLISHMENT_OF_SQLCONNECTION: SqlState =
SqlState(Cow::Borrowed("08004"));
/// 08007 /// 08007
pub const TRANSACTION_RESOLUTION_UNKNOWN: SqlState = SqlState(Cow::Borrowed("08007")); pub const TRANSACTION_RESOLUTION_UNKNOWN: SqlState = SqlState(Cow::Borrowed("08007"));
@ -105,7 +109,8 @@ impl SqlState {
pub const DIAGNOSTICS_EXCEPTION: SqlState = SqlState(Cow::Borrowed("0Z000")); pub const DIAGNOSTICS_EXCEPTION: SqlState = SqlState(Cow::Borrowed("0Z000"));
/// 0Z002 /// 0Z002
pub const STACKED_DIAGNOSTICS_ACCESSED_WITHOUT_ACTIVE_HANDLER: SqlState = SqlState(Cow::Borrowed("0Z002")); pub const STACKED_DIAGNOSTICS_ACCESSED_WITHOUT_ACTIVE_HANDLER: SqlState =
SqlState(Cow::Borrowed("0Z002"));
/// 20000 /// 20000
pub const CASE_NOT_FOUND: SqlState = SqlState(Cow::Borrowed("20000")); pub const CASE_NOT_FOUND: SqlState = SqlState(Cow::Borrowed("20000"));
@ -159,7 +164,8 @@ impl SqlState {
pub const INVALID_ARGUMENT_FOR_POWER_FUNCTION: SqlState = SqlState(Cow::Borrowed("2201F")); pub const INVALID_ARGUMENT_FOR_POWER_FUNCTION: SqlState = SqlState(Cow::Borrowed("2201F"));
/// 2201G /// 2201G
pub const INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION: SqlState = SqlState(Cow::Borrowed("2201G")); pub const INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION: SqlState =
SqlState(Cow::Borrowed("2201G"));
/// 22018 /// 22018
pub const INVALID_CHARACTER_VALUE_FOR_CAST: SqlState = SqlState(Cow::Borrowed("22018")); pub const INVALID_CHARACTER_VALUE_FOR_CAST: SqlState = SqlState(Cow::Borrowed("22018"));
@ -192,7 +198,8 @@ impl SqlState {
pub const INVALID_ROW_COUNT_IN_LIMIT_CLAUSE: SqlState = SqlState(Cow::Borrowed("2201W")); pub const INVALID_ROW_COUNT_IN_LIMIT_CLAUSE: SqlState = SqlState(Cow::Borrowed("2201W"));
/// 2201X /// 2201X
pub const INVALID_ROW_COUNT_IN_RESULT_OFFSET_CLAUSE: SqlState = SqlState(Cow::Borrowed("2201X")); pub const INVALID_ROW_COUNT_IN_RESULT_OFFSET_CLAUSE: SqlState =
SqlState(Cow::Borrowed("2201X"));
/// 2202H /// 2202H
pub const INVALID_TABLESAMPLE_ARGUMENT: SqlState = SqlState(Cow::Borrowed("2202H")); pub const INVALID_TABLESAMPLE_ARGUMENT: SqlState = SqlState(Cow::Borrowed("2202H"));
@ -303,22 +310,27 @@ impl SqlState {
pub const BRANCH_TRANSACTION_ALREADY_ACTIVE: SqlState = SqlState(Cow::Borrowed("25002")); pub const BRANCH_TRANSACTION_ALREADY_ACTIVE: SqlState = SqlState(Cow::Borrowed("25002"));
/// 25008 /// 25008
pub const HELD_CURSOR_REQUIRES_SAME_ISOLATION_LEVEL: SqlState = SqlState(Cow::Borrowed("25008")); pub const HELD_CURSOR_REQUIRES_SAME_ISOLATION_LEVEL: SqlState =
SqlState(Cow::Borrowed("25008"));
/// 25003 /// 25003
pub const INAPPROPRIATE_ACCESS_MODE_FOR_BRANCH_TRANSACTION: SqlState = SqlState(Cow::Borrowed("25003")); pub const INAPPROPRIATE_ACCESS_MODE_FOR_BRANCH_TRANSACTION: SqlState =
SqlState(Cow::Borrowed("25003"));
/// 25004 /// 25004
pub const INAPPROPRIATE_ISOLATION_LEVEL_FOR_BRANCH_TRANSACTION: SqlState = SqlState(Cow::Borrowed("25004")); pub const INAPPROPRIATE_ISOLATION_LEVEL_FOR_BRANCH_TRANSACTION: SqlState =
SqlState(Cow::Borrowed("25004"));
/// 25005 /// 25005
pub const NO_ACTIVE_SQL_TRANSACTION_FOR_BRANCH_TRANSACTION: SqlState = SqlState(Cow::Borrowed("25005")); pub const NO_ACTIVE_SQL_TRANSACTION_FOR_BRANCH_TRANSACTION: SqlState =
SqlState(Cow::Borrowed("25005"));
/// 25006 /// 25006
pub const READ_ONLY_SQL_TRANSACTION: SqlState = SqlState(Cow::Borrowed("25006")); pub const READ_ONLY_SQL_TRANSACTION: SqlState = SqlState(Cow::Borrowed("25006"));
/// 25007 /// 25007
pub const SCHEMA_AND_DATA_STATEMENT_MIXING_NOT_SUPPORTED: SqlState = SqlState(Cow::Borrowed("25007")); pub const SCHEMA_AND_DATA_STATEMENT_MIXING_NOT_SUPPORTED: SqlState =
SqlState(Cow::Borrowed("25007"));
/// 25P01 /// 25P01
pub const NO_ACTIVE_SQL_TRANSACTION: SqlState = SqlState(Cow::Borrowed("25P01")); pub const NO_ACTIVE_SQL_TRANSACTION: SqlState = SqlState(Cow::Borrowed("25P01"));
@ -345,7 +357,8 @@ impl SqlState {
pub const INVALID_PASSWORD: SqlState = SqlState(Cow::Borrowed("28P01")); pub const INVALID_PASSWORD: SqlState = SqlState(Cow::Borrowed("28P01"));
/// 2B000 /// 2B000
pub const DEPENDENT_PRIVILEGE_DESCRIPTORS_STILL_EXIST: SqlState = SqlState(Cow::Borrowed("2B000")); pub const DEPENDENT_PRIVILEGE_DESCRIPTORS_STILL_EXIST: SqlState =
SqlState(Cow::Borrowed("2B000"));
/// 2BP01 /// 2BP01
pub const DEPENDENT_OBJECTS_STILL_EXIST: SqlState = SqlState(Cow::Borrowed("2BP01")); pub const DEPENDENT_OBJECTS_STILL_EXIST: SqlState = SqlState(Cow::Borrowed("2BP01"));
@ -357,7 +370,8 @@ impl SqlState {
pub const SQL_ROUTINE_EXCEPTION: SqlState = SqlState(Cow::Borrowed("2F000")); pub const SQL_ROUTINE_EXCEPTION: SqlState = SqlState(Cow::Borrowed("2F000"));
/// 2F005 /// 2F005
pub const S_R_E_FUNCTION_EXECUTED_NO_RETURN_STATEMENT: SqlState = SqlState(Cow::Borrowed("2F005")); pub const S_R_E_FUNCTION_EXECUTED_NO_RETURN_STATEMENT: SqlState =
SqlState(Cow::Borrowed("2F005"));
/// 2F002 /// 2F002
pub const S_R_E_MODIFYING_SQL_DATA_NOT_PERMITTED: SqlState = SqlState(Cow::Borrowed("2F002")); pub const S_R_E_MODIFYING_SQL_DATA_NOT_PERMITTED: SqlState = SqlState(Cow::Borrowed("2F002"));
@ -699,7 +713,8 @@ impl SqlState {
pub const FDW_INVALID_OPTION_NAME: SqlState = SqlState(Cow::Borrowed("HV00D")); pub const FDW_INVALID_OPTION_NAME: SqlState = SqlState(Cow::Borrowed("HV00D"));
/// HV090 /// HV090
pub const FDW_INVALID_STRING_LENGTH_OR_BUFFER_LENGTH: SqlState = SqlState(Cow::Borrowed("HV090")); pub const FDW_INVALID_STRING_LENGTH_OR_BUFFER_LENGTH: SqlState =
SqlState(Cow::Borrowed("HV090"));
/// HV00A /// HV00A
pub const FDW_INVALID_STRING_FORMAT: SqlState = SqlState(Cow::Borrowed("HV00A")); pub const FDW_INVALID_STRING_FORMAT: SqlState = SqlState(Cow::Borrowed("HV00A"));

View File

@ -1,15 +1,15 @@
#![allow(unknown_lints)] // for clippy #![allow(unknown_lints)] // for clippy
extern crate hex;
extern crate fallible_iterator; extern crate fallible_iterator;
extern crate hex;
extern crate phf; extern crate phf;
extern crate postgres_protocol; extern crate postgres_protocol;
pub mod error; pub mod error;
pub mod params; pub mod params;
pub mod types;
pub mod rows; pub mod rows;
pub mod stmt; pub mod stmt;
pub mod types;
/// Contains information necessary to cancel queries for a session. /// Contains information necessary to cancel queries for a session.
#[derive(Copy, Clone, Debug)] #[derive(Copy, Clone, Debug)]

View File

@ -7,8 +7,8 @@
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use std::str::FromStr;
use hex::FromHex; use hex::FromHex;
use std::str::FromStr;
pub struct Url { pub struct Url {
pub scheme: String, pub scheme: String,
@ -128,31 +128,29 @@ fn decode_inner(c: &str, full_url: bool) -> DecodeResult<String> {
let bytes = match (iter.next(), iter.next()) { let bytes = match (iter.next(), iter.next()) {
(Some(one), Some(two)) => [one, two], (Some(one), Some(two)) => [one, two],
_ => { _ => {
return Err( return Err("Malformed input: found '%' without two \
"Malformed input: found '%' without two \ trailing bytes"
trailing bytes" .to_owned())
.to_owned(),
)
} }
}; };
let bytes_from_hex = match Vec::<u8>::from_hex(&bytes) { let bytes_from_hex = match Vec::<u8>::from_hex(&bytes) {
Ok(b) => b, Ok(b) => b,
_ => { _ => {
return Err( return Err("Malformed input: found '%' followed by \
"Malformed input: found '%' followed by \
invalid hex values. Character '%' must \ invalid hex values. Character '%' must \
escaped." escaped."
.to_owned(), .to_owned())
)
} }
}; };
// Only decode some characters if full_url: // Only decode some characters if full_url:
match bytes_from_hex[0] as char { match bytes_from_hex[0] as char {
// gen-delims: // gen-delims:
':' | '/' | '?' | '#' | '[' | ']' | '@' | '!' | '$' | '&' | '"' | ':' | '/' | '?' | '#' | '[' | ']' | '@' | '!' | '$' | '&' | '"'
'(' | ')' | '*' | '+' | ',' | ';' | '=' if full_url => { | '(' | ')' | '*' | '+' | ',' | ';' | '='
if full_url =>
{
out.push('%'); out.push('%');
out.push(bytes[0] as char); out.push(bytes[0] as char);
out.push(bytes[1] as char); out.push(bytes[1] as char);
@ -221,18 +219,18 @@ pub fn get_scheme(rawurl: &str) -> DecodeResult<(&str, &str)> {
// returns userinfo, host, port, and unparsed part, or an error // returns userinfo, host, port, and unparsed part, or an error
fn get_authority(rawurl: &str) -> DecodeResult<(Option<UserInfo>, &str, Option<u16>, &str)> { fn get_authority(rawurl: &str) -> DecodeResult<(Option<UserInfo>, &str, Option<u16>, &str)> {
enum State { enum State {
Start, // starting state Start, // starting state
PassHostPort, // could be in user or port PassHostPort, // could be in user or port
Ip6Port, // either in ipv6 host or port Ip6Port, // either in ipv6 host or port
Ip6Host, // are in an ipv6 host Ip6Host, // are in an ipv6 host
InHost, // are in a host - may be ipv6, but don't know yet InHost, // are in a host - may be ipv6, but don't know yet
InPort, // are in port InPort, // are in port
} }
#[derive(Clone, PartialEq)] #[derive(Clone, PartialEq)]
enum Input { enum Input {
Digit, // all digits Digit, // all digits
Hex, // digits and letters a-f Hex, // digits and letters a-f
Unreserved, // all other legal characters Unreserved, // all other legal characters
} }
@ -263,8 +261,23 @@ fn get_authority(rawurl: &str) -> DecodeResult<(Option<UserInfo>, &str, Option<u
input = Input::Hex; input = Input::Hex;
} }
} }
'G'...'Z' | 'g'...'z' | '-' | '.' | '_' | '~' | '%' | '&' | '\'' | '(' | ')' | 'G'...'Z'
'+' | '!' | '*' | ',' | ';' | '=' => input = Input::Unreserved, | 'g'...'z'
| '-'
| '.'
| '_'
| '~'
| '%'
| '&'
| '\''
| '('
| ')'
| '+'
| '!'
| '*'
| ','
| ';'
| '=' => input = Input::Unreserved,
':' | '@' | '?' | '#' | '/' => { ':' | '@' | '?' | '#' | '/' => {
// separators, don't change anything // separators, don't change anything
} }
@ -366,26 +379,42 @@ fn get_authority(rawurl: &str) -> DecodeResult<(Option<UserInfo>, &str, Option<u
// If we have a port string, ensure it parses to u16. // If we have a port string, ensure it parses to u16.
let port = match port { let port = match port {
None => None, None => None,
opt => { opt => match opt.and_then(|p| FromStr::from_str(p).ok()) {
match opt.and_then(|p| FromStr::from_str(p).ok()) { None => return Err(format!("Failed to parse port: {:?}", port)),
None => return Err(format!("Failed to parse port: {:?}", port)), opt => opt,
opt => opt, },
}
}
}; };
Ok((userinfo, host, port, rest)) Ok((userinfo, host, port, rest))
} }
// returns the path and unparsed part of url, or an error // returns the path and unparsed part of url, or an error
fn get_path(rawurl: &str, is_authority: bool) -> DecodeResult<(String, &str)> { fn get_path(rawurl: &str, is_authority: bool) -> DecodeResult<(String, &str)> {
let len = rawurl.len(); let len = rawurl.len();
let mut end = len; let mut end = len;
for (i, c) in rawurl.chars().enumerate() { for (i, c) in rawurl.chars().enumerate() {
match c { match c {
'A'...'Z' | 'a'...'z' | '0'...'9' | '&' | '\'' | '(' | ')' | '.' | '@' | ':' | 'A'...'Z'
'%' | '/' | '+' | '!' | '*' | ',' | ';' | '=' | '_' | '-' | '~' => continue, | 'a'...'z'
| '0'...'9'
| '&'
| '\''
| '('
| ')'
| '.'
| '@'
| ':'
| '%'
| '/'
| '+'
| '!'
| '*'
| ','
| ';'
| '='
| '_'
| '-'
| '~' => continue,
'?' | '#' => { '?' | '#' => {
end = i; end = i;
break; break;
@ -395,9 +424,7 @@ fn get_path(rawurl: &str, is_authority: bool) -> DecodeResult<(String, &str)> {
} }
if is_authority && end != 0 && !rawurl.starts_with('/') { if is_authority && end != 0 && !rawurl.starts_with('/') {
Err( Err("Non-empty path must begin with '/' in presence of authority.".to_owned())
"Non-empty path must begin with '/' in presence of authority.".to_owned(),
)
} else { } else {
Ok((decode_component(&rawurl[0..end])?, &rawurl[end..len])) Ok((decode_component(&rawurl[0..end])?, &rawurl[end..len]))
} }

View File

@ -59,11 +59,7 @@ where
} }
} }
impl<'a, T> RowIndex for &'a T impl<'a, T> RowIndex for &'a T where T: ?Sized + Sealed {}
where
T: ?Sized + Sealed,
{
}
#[doc(hidden)] #[doc(hidden)]
pub struct RowData { pub struct RowData {

View File

@ -1,7 +1,8 @@
extern crate chrono; extern crate chrono;
use self::chrono::{DateTime, Duration, FixedOffset, Local, NaiveDate, NaiveDateTime, NaiveTime, use self::chrono::{
Utc}; DateTime, Duration, FixedOffset, Local, NaiveDate, NaiveDateTime, NaiveTime, Utc,
};
use postgres_protocol::types; use postgres_protocol::types;
use std::error::Error; use std::error::Error;

View File

@ -30,8 +30,14 @@ impl<'a> FromSql<'a> for Rect<f64> {
fn from_sql(_: &Type, raw: &[u8]) -> Result<Self, Box<Error + Sync + Send>> { fn from_sql(_: &Type, raw: &[u8]) -> Result<Self, Box<Error + Sync + Send>> {
let rect = types::box_from_sql(raw)?; let rect = types::box_from_sql(raw)?;
Ok(Rect { Ok(Rect {
min: Coordinate { x: rect.lower_left().x(), y: rect.lower_left().y(), }, min: Coordinate {
max: Coordinate { x: rect.upper_right().x(), y: rect.upper_right().y(), }, x: rect.lower_left().x(),
y: rect.lower_left().y(),
},
max: Coordinate {
x: rect.upper_right().x(),
y: rect.upper_right().y(),
},
}) })
} }
@ -51,7 +57,10 @@ impl ToSql for Rect<f64> {
impl<'a> FromSql<'a> for LineString<f64> { impl<'a> FromSql<'a> for LineString<f64> {
fn from_sql(_: &Type, raw: &[u8]) -> Result<Self, Box<Error + Sync + Send>> { fn from_sql(_: &Type, raw: &[u8]) -> Result<Self, Box<Error + Sync + Send>> {
let path = types::path_from_sql(raw)?; let path = types::path_from_sql(raw)?;
let points = path.points().map(|p| Coordinate { x: p.x(), y: p.y() }).collect()?; let points = path
.points()
.map(|p| Coordinate { x: p.x(), y: p.y() })
.collect()?;
Ok(LineString(points)) Ok(LineString(points))
} }

View File

@ -337,11 +337,7 @@ pub trait FromSql<'a>: Sized {
/// This is primarily useful for trait bounds on functions. /// This is primarily useful for trait bounds on functions.
pub trait FromSqlOwned: for<'a> FromSql<'a> {} pub trait FromSqlOwned: for<'a> FromSql<'a> {}
impl<T> FromSqlOwned for T impl<T> FromSqlOwned for T where T: for<'a> FromSql<'a> {}
where
T: for<'a> FromSql<'a>,
{
}
impl<'a, T: FromSql<'a>> FromSql<'a> for Option<T> { impl<'a, T: FromSql<'a>> FromSql<'a> for Option<T> {
fn from_sql(ty: &Type, raw: &'a [u8]) -> Result<Option<T>, Box<Error + Sync + Send>> { fn from_sql(ty: &Type, raw: &'a [u8]) -> Result<Option<T>, Box<Error + Sync + Send>> {

View File

@ -1,7 +1,7 @@
// Autogenerated file - DO NOT EDIT // Autogenerated file - DO NOT EDIT
use std::sync::Arc; use std::sync::Arc;
use types::{Type, Oid, Kind}; use types::{Kind, Oid, Type};
#[derive(PartialEq, Eq, Debug)] #[derive(PartialEq, Eq, Debug)]
pub struct Other { pub struct Other {

View File

@ -19,21 +19,21 @@ macro_rules! check_desync {
} }
macro_rules! bad_response { macro_rules! bad_response {
($s:expr) => ({ ($s:expr) => {{
debug!("Bad response at {}:{}", file!(), line!()); debug!("Bad response at {}:{}", file!(), line!());
$s.desynchronized = true; $s.desynchronized = true;
return Err(::bad_response().into()); return Err(::bad_response().into());
}) }};
} }
#[cfg(feature = "no-logging")] #[cfg(feature = "no-logging")]
macro_rules! debug { macro_rules! debug {
($($t:tt)*) => {} ($($t:tt)*) => {};
} }
#[cfg(feature = "no-logging")] #[cfg(feature = "no-logging")]
macro_rules! info { macro_rules! info {
($($t:tt)*) => {} ($($t:tt)*) => {};
} }
/// Generates a simple implementation of `ToSql::accepts` which accepts the /// Generates a simple implementation of `ToSql::accepts` which accepts the

View File

@ -1,17 +1,17 @@
//! Asynchronous notifications. //! Asynchronous notifications.
use error::DbError;
use fallible_iterator::{FallibleIterator, IntoFallibleIterator}; use fallible_iterator::{FallibleIterator, IntoFallibleIterator};
use postgres_protocol::message::backend::{self, ErrorFields};
use std::fmt; use std::fmt;
use std::time::Duration; use std::time::Duration;
use postgres_protocol::message::backend::{self, ErrorFields};
use error::DbError;
#[doc(inline)] #[doc(inline)]
use postgres_shared; use postgres_shared;
pub use postgres_shared::Notification; pub use postgres_shared::Notification;
use {desynchronized, Result, Connection};
use error::Error; use error::Error;
use {desynchronized, Connection, Result};
/// Notifications from the Postgres backend. /// Notifications from the Postgres backend.
pub struct Notifications<'conn> { pub struct Notifications<'conn> {
@ -105,13 +105,11 @@ impl<'a> FallibleIterator for Iter<'a> {
} }
match conn.read_message_with_notification_nonblocking() { match conn.read_message_with_notification_nonblocking() {
Ok(Some(backend::Message::NotificationResponse(body))) => { Ok(Some(backend::Message::NotificationResponse(body))) => Ok(Some(Notification {
Ok(Some(Notification { process_id: body.process_id(),
process_id: body.process_id(), channel: body.channel()?.to_owned(),
channel: body.channel()?.to_owned(), payload: body.message()?.to_owned(),
payload: body.message()?.to_owned(), })),
}))
}
Ok(Some(backend::Message::ErrorResponse(body))) => Err(err(&mut body.fields())), Ok(Some(backend::Message::ErrorResponse(body))) => Err(err(&mut body.fields())),
Ok(None) => Ok(None), Ok(None) => Ok(None),
Err(err) => Err(err.into()), Err(err) => Err(err.into()),
@ -145,13 +143,11 @@ impl<'a> FallibleIterator for BlockingIter<'a> {
} }
match conn.read_message_with_notification() { match conn.read_message_with_notification() {
Ok(backend::Message::NotificationResponse(body)) => { Ok(backend::Message::NotificationResponse(body)) => Ok(Some(Notification {
Ok(Some(Notification { process_id: body.process_id(),
process_id: body.process_id(), channel: body.channel()?.to_owned(),
channel: body.channel()?.to_owned(), payload: body.message()?.to_owned(),
payload: body.message()?.to_owned(), })),
}))
}
Ok(backend::Message::ErrorResponse(body)) => Err(err(&mut body.fields())), Ok(backend::Message::ErrorResponse(body)) => Err(err(&mut body.fields())),
Err(err) => Err(err.into()), Err(err) => Err(err.into()),
_ => unreachable!(), _ => unreachable!(),
@ -182,13 +178,11 @@ impl<'a> FallibleIterator for TimeoutIter<'a> {
} }
match conn.read_message_with_notification_timeout(self.timeout) { match conn.read_message_with_notification_timeout(self.timeout) {
Ok(Some(backend::Message::NotificationResponse(body))) => { Ok(Some(backend::Message::NotificationResponse(body))) => Ok(Some(Notification {
Ok(Some(Notification { process_id: body.process_id(),
process_id: body.process_id(), channel: body.channel()?.to_owned(),
channel: body.channel()?.to_owned(), payload: body.message()?.to_owned(),
payload: body.message()?.to_owned(), })),
}))
}
Ok(Some(backend::Message::ErrorResponse(body))) => Err(err(&mut body.fields())), Ok(Some(backend::Message::ErrorResponse(body))) => Err(err(&mut body.fields())),
Ok(None) => Ok(None), Ok(None) => Ok(None),
Err(err) => Err(err.into()), Err(err) => Err(err.into()),

View File

@ -1,3 +1,3 @@
//! Connection parameters //! Connection parameters
pub use postgres_shared::params::{Builder, ConnectParams, User, Host, IntoConnectParams}; pub use postgres_shared::params::{Builder, ConnectParams, Host, IntoConnectParams, User};

View File

@ -59,7 +59,8 @@ impl MessageStream {
fn read_in(&mut self) -> io::Result<()> { fn read_in(&mut self) -> io::Result<()> {
self.in_buf.reserve(1); self.in_buf.reserve(1);
match self.stream match self
.stream
.get_mut() .get_mut()
.read(unsafe { self.in_buf.bytes_mut() }) .read(unsafe { self.in_buf.bytes_mut() })
{ {
@ -206,8 +207,7 @@ fn open_socket(params: &ConnectParams) -> Result<Socket> {
io::ErrorKind::InvalidInput, io::ErrorKind::InvalidInput,
"could not resolve any addresses", "could not resolve any addresses",
) )
}) }).into())
.into())
} }
#[cfg(unix)] #[cfg(unix)]
Host::Unix(ref path) => { Host::Unix(ref path) => {

View File

@ -1,20 +1,20 @@
//! Prepared statements //! Prepared statements
use fallible_iterator::FallibleIterator; use fallible_iterator::FallibleIterator;
use postgres_protocol::message::{backend, frontend};
use postgres_shared::rows::RowData;
use std::cell::Cell; use std::cell::Cell;
use std::collections::VecDeque; use std::collections::VecDeque;
use std::fmt; use std::fmt;
use std::io::{self, Read, Write}; use std::io::{self, Read, Write};
use std::sync::Arc; use std::sync::Arc;
use postgres_protocol::message::{backend, frontend};
use postgres_shared::rows::RowData;
#[doc(inline)] #[doc(inline)]
pub use postgres_shared::stmt::Column; pub use postgres_shared::stmt::Column;
use types::{Type, ToSql}; use rows::{LazyRows, Rows};
use rows::{Rows, LazyRows};
use transaction::Transaction; use transaction::Transaction;
use types::{ToSql, Type};
use {bad_response, err, Connection, Result, StatementInfo}; use {bad_response, err, Connection, Result, StatementInfo};
/// A prepared statement. /// A prepared statement.
@ -135,13 +135,7 @@ impl<'conn> Statement<'conn> {
pub fn execute(&self, params: &[&ToSql]) -> Result<u64> { pub fn execute(&self, params: &[&ToSql]) -> Result<u64> {
let mut conn = self.conn.0.borrow_mut(); let mut conn = self.conn.0.borrow_mut();
check_desync!(conn); check_desync!(conn);
conn.raw_execute( conn.raw_execute(&self.info.name, "", 0, self.param_types(), params)?;
&self.info.name,
"",
0,
self.param_types(),
params,
)?;
let num; let num;
loop { loop {
@ -163,9 +157,8 @@ impl<'conn> Statement<'conn> {
conn.stream.write_message(|buf| { conn.stream.write_message(|buf| {
frontend::copy_fail("COPY queries cannot be directly executed", buf) frontend::copy_fail("COPY queries cannot be directly executed", buf)
})?; })?;
conn.stream.write_message( conn.stream
|buf| Ok::<(), io::Error>(frontend::sync(buf)), .write_message(|buf| Ok::<(), io::Error>(frontend::sync(buf)))?;
)?;
conn.stream.flush()?; conn.stream.flush()?;
} }
backend::Message::CopyOutResponse(_) => { backend::Message::CopyOutResponse(_) => {
@ -269,7 +262,7 @@ impl<'conn> Statement<'conn> {
assert!( assert!(
self.conn as *const _ == trans.conn() as *const _, self.conn as *const _ == trans.conn() as *const _,
"the `Transaction` passed to `lazy_query` must be associated with the same \ "the `Transaction` passed to `lazy_query` must be associated with the same \
`Connection` as the `Statement`" `Connection` as the `Statement`"
); );
let conn = self.conn.0.borrow(); let conn = self.conn.0.borrow();
check_desync!(conn); check_desync!(conn);
@ -284,12 +277,8 @@ impl<'conn> Statement<'conn> {
let portal_name = format!("{}p{}", self.info.name, id); let portal_name = format!("{}p{}", self.info.name, id);
let mut rows = VecDeque::new(); let mut rows = VecDeque::new();
let more_rows = self.inner_query( let more_rows =
&portal_name, self.inner_query(&portal_name, row_limit, params, |row| rows.push_back(row))?;
row_limit,
params,
|row| rows.push_back(row),
)?;
Ok(LazyRows::new( Ok(LazyRows::new(
self, self,
rows, rows,
@ -324,36 +313,29 @@ impl<'conn> Statement<'conn> {
/// ``` /// ```
pub fn copy_in<R: ReadWithInfo>(&self, params: &[&ToSql], r: &mut R) -> Result<u64> { pub fn copy_in<R: ReadWithInfo>(&self, params: &[&ToSql], r: &mut R) -> Result<u64> {
let mut conn = self.conn.0.borrow_mut(); let mut conn = self.conn.0.borrow_mut();
conn.raw_execute( conn.raw_execute(&self.info.name, "", 0, self.param_types(), params)?;
&self.info.name,
"",
0,
self.param_types(),
params,
)?;
let (format, column_formats) = match conn.read_message()? { let (format, column_formats) = match conn.read_message()? {
backend::Message::CopyInResponse(body) => { backend::Message::CopyInResponse(body) => {
let format = body.format(); let format = body.format();
let column_formats = body.column_formats().map(|f| Format::from_u16(f)).collect()?; let column_formats = body
.column_formats()
.map(|f| Format::from_u16(f))
.collect()?;
(format, column_formats) (format, column_formats)
} }
backend::Message::ErrorResponse(body) => { backend::Message::ErrorResponse(body) => {
conn.wait_for_ready()?; conn.wait_for_ready()?;
return Err(err(&mut body.fields())); return Err(err(&mut body.fields()));
} }
_ => { _ => loop {
loop { if let backend::Message::ReadyForQuery(_) = conn.read_message()? {
if let backend::Message::ReadyForQuery(_) = conn.read_message()? { return Err(io::Error::new(
return Err( io::ErrorKind::InvalidInput,
io::Error::new( "called `copy_in` on a non-`COPY FROM STDIN` statement",
io::ErrorKind::InvalidInput, ).into());
"called `copy_in` on a non-`COPY FROM STDIN` statement",
).into(),
);
}
} }
} },
}; };
let info = CopyInfo { let info = CopyInfo {
@ -366,20 +348,16 @@ impl<'conn> Statement<'conn> {
match fill_copy_buf(&mut buf, r, &info) { match fill_copy_buf(&mut buf, r, &info) {
Ok(0) => break, Ok(0) => break,
Ok(len) => { Ok(len) => {
conn.stream.write_message( conn.stream
|out| frontend::copy_data(&buf[..len], out), .write_message(|out| frontend::copy_data(&buf[..len], out))?;
)?;
} }
Err(err) => { Err(err) => {
conn.stream.write_message( conn.stream
|buf| frontend::copy_fail("", buf), .write_message(|buf| frontend::copy_fail("", buf))?;
)?; conn.stream
conn.stream.write_message(|buf| { .write_message(|buf| Ok::<(), io::Error>(frontend::copy_done(buf)))?;
Ok::<(), io::Error>(frontend::copy_done(buf)) conn.stream
})?; .write_message(|buf| Ok::<(), io::Error>(frontend::sync(buf)))?;
conn.stream.write_message(
|buf| Ok::<(), io::Error>(frontend::sync(buf)),
)?;
conn.stream.flush()?; conn.stream.flush()?;
match conn.read_message()? { match conn.read_message()? {
backend::Message::ErrorResponse(_) => { backend::Message::ErrorResponse(_) => {
@ -396,12 +374,10 @@ impl<'conn> Statement<'conn> {
} }
} }
conn.stream.write_message(|buf| { conn.stream
Ok::<(), io::Error>(frontend::copy_done(buf)) .write_message(|buf| Ok::<(), io::Error>(frontend::copy_done(buf)))?;
})?; conn.stream
conn.stream.write_message( .write_message(|buf| Ok::<(), io::Error>(frontend::sync(buf)))?;
|buf| Ok::<(), io::Error>(frontend::sync(buf)),
)?;
conn.stream.flush()?; conn.stream.flush()?;
let num = match conn.read_message()? { let num = match conn.read_message()? {
@ -444,30 +420,24 @@ impl<'conn> Statement<'conn> {
/// ``` /// ```
pub fn copy_out<'a, W: WriteWithInfo>(&'a self, params: &[&ToSql], w: &mut W) -> Result<u64> { pub fn copy_out<'a, W: WriteWithInfo>(&'a self, params: &[&ToSql], w: &mut W) -> Result<u64> {
let mut conn = self.conn.0.borrow_mut(); let mut conn = self.conn.0.borrow_mut();
conn.raw_execute( conn.raw_execute(&self.info.name, "", 0, self.param_types(), params)?;
&self.info.name,
"",
0,
self.param_types(),
params,
)?;
let (format, column_formats) = match conn.read_message()? { let (format, column_formats) = match conn.read_message()? {
backend::Message::CopyOutResponse(body) => { backend::Message::CopyOutResponse(body) => {
let format = body.format(); let format = body.format();
let column_formats = body.column_formats().map(|f| Format::from_u16(f)).collect()?; let column_formats = body
.column_formats()
.map(|f| Format::from_u16(f))
.collect()?;
(format, column_formats) (format, column_formats)
} }
backend::Message::CopyInResponse(_) => { backend::Message::CopyInResponse(_) => {
conn.stream.write_message( conn.stream
|buf| frontend::copy_fail("", buf), .write_message(|buf| frontend::copy_fail("", buf))?;
)?; conn.stream
conn.stream.write_message(|buf| { .write_message(|buf| Ok::<(), io::Error>(frontend::copy_done(buf)))?;
Ok::<(), io::Error>(frontend::copy_done(buf)) conn.stream
})?; .write_message(|buf| Ok::<(), io::Error>(frontend::sync(buf)))?;
conn.stream.write_message(
|buf| Ok::<(), io::Error>(frontend::sync(buf)),
)?;
conn.stream.flush()?; conn.stream.flush()?;
match conn.read_message()? { match conn.read_message()? {
backend::Message::ErrorResponse(_) => { backend::Message::ErrorResponse(_) => {
@ -479,29 +449,23 @@ impl<'conn> Statement<'conn> {
} }
} }
conn.wait_for_ready()?; conn.wait_for_ready()?;
return Err( return Err(io::Error::new(
io::Error::new( io::ErrorKind::InvalidInput,
io::ErrorKind::InvalidInput, "called `copy_out` on a non-`COPY TO STDOUT` statement",
"called `copy_out` on a non-`COPY TO STDOUT` statement", ).into());
).into(),
);
} }
backend::Message::ErrorResponse(body) => { backend::Message::ErrorResponse(body) => {
conn.wait_for_ready()?; conn.wait_for_ready()?;
return Err(err(&mut body.fields())); return Err(err(&mut body.fields()));
} }
_ => { _ => loop {
loop { if let backend::Message::ReadyForQuery(_) = conn.read_message()? {
if let backend::Message::ReadyForQuery(_) = conn.read_message()? { return Err(io::Error::new(
return Err( io::ErrorKind::InvalidInput,
io::Error::new( "called `copy_out` on a non-`COPY TO STDOUT` statement",
io::ErrorKind::InvalidInput, ).into());
"called `copy_out` on a non-`COPY TO STDOUT` statement",
).into(),
);
}
} }
} },
}; };
let info = CopyInfo { let info = CopyInfo {
@ -517,15 +481,11 @@ impl<'conn> Statement<'conn> {
while !data.is_empty() { while !data.is_empty() {
match w.write_with_info(data, &info) { match w.write_with_info(data, &info) {
Ok(n) => data = &data[n..], Ok(n) => data = &data[n..],
Err(e) => { Err(e) => loop {
loop { if let backend::Message::ReadyForQuery(_) = conn.read_message()? {
if let backend::Message::ReadyForQuery(_) = return Err(e.into());
conn.read_message()?
{
return Err(e.into());
}
} }
} },
} }
} }
} }
@ -534,20 +494,16 @@ impl<'conn> Statement<'conn> {
count = parse_update_count(body.tag()?); count = parse_update_count(body.tag()?);
break; break;
} }
backend::Message::ErrorResponse(body) => { backend::Message::ErrorResponse(body) => loop {
loop { if let backend::Message::ReadyForQuery(_) = conn.read_message()? {
if let backend::Message::ReadyForQuery(_) = conn.read_message()? { return Err(err(&mut body.fields()));
return Err(err(&mut body.fields()));
}
} }
} },
_ => { _ => loop {
loop { if let backend::Message::ReadyForQuery(_) = conn.read_message()? {
if let backend::Message::ReadyForQuery(_) = conn.read_message()? { return Err(bad_response().into());
return Err(bad_response().into());
}
} }
} },
} }
} }

View File

@ -8,8 +8,8 @@ use std::str;
#[doc(inline)] #[doc(inline)]
pub use postgres_shared::rows::RowIndex; pub use postgres_shared::rows::RowIndex;
use stmt::{Column}; use stmt::Column;
use {Result, error}; use {error, Result};
/// The resulting rows of a query. /// The resulting rows of a query.
pub struct TextRows { pub struct TextRows {
@ -89,11 +89,9 @@ impl<'a> Iterator for Iter<'a> {
type Item = TextRow<'a>; type Item = TextRow<'a>;
fn next(&mut self) -> Option<TextRow<'a>> { fn next(&mut self) -> Option<TextRow<'a>> {
self.iter.next().map(|row| { self.iter.next().map(|row| TextRow {
TextRow { columns: self.columns,
columns: self.columns, data: row,
data: row,
}
}) })
} }
@ -104,11 +102,9 @@ impl<'a> Iterator for Iter<'a> {
impl<'a> DoubleEndedIterator for Iter<'a> { impl<'a> DoubleEndedIterator for Iter<'a> {
fn next_back(&mut self) -> Option<TextRow<'a>> { fn next_back(&mut self) -> Option<TextRow<'a>> {
self.iter.next_back().map(|row| { self.iter.next_back().map(|row| TextRow {
TextRow { columns: self.columns,
columns: self.columns, data: row,
data: row,
}
}) })
} }
} }
@ -188,7 +184,8 @@ impl<'a> TextRow<'a> {
None => return None, None => return None,
}; };
self.data.get(idx) self.data
.get(idx)
.map(|s| str::from_utf8(s).map_err(|e| error::conversion(Box::new(e)))) .map(|s| str::from_utf8(s).map_err(|e| error::conversion(Box::new(e))))
} }
} }

View File

@ -4,8 +4,8 @@ use std::cell::Cell;
use std::fmt; use std::fmt;
use rows::Rows; use rows::Rows;
use text_rows::TextRows;
use stmt::Statement; use stmt::Statement;
use text_rows::TextRows;
use types::ToSql; use types::ToSql;
use {bad_response, Connection, Result}; use {bad_response, Connection, Result};
@ -226,10 +226,9 @@ impl<'conn> Transaction<'conn> {
} }
/// Like `Connection::batch_execute`. /// Like `Connection::batch_execute`.
#[deprecated(since="0.15.3", note="please use `simple_query` instead")] #[deprecated(since = "0.15.3", note = "please use `simple_query` instead")]
pub fn batch_execute(&self, query: &str) -> Result<()> { pub fn batch_execute(&self, query: &str) -> Result<()> {
self.simple_query(query) self.simple_query(query).map(|_| ())
.map(|_| ())
} }
/// Like `Connection::simple_query`. /// Like `Connection::simple_query`.
@ -255,7 +254,8 @@ impl<'conn> Transaction<'conn> {
/// Panics if there is an active nested transaction. /// Panics if there is an active nested transaction.
#[inline] #[inline]
pub fn savepoint<'a, I>(&'a self, name: I) -> Result<Transaction<'a>> pub fn savepoint<'a, I>(&'a self, name: I) -> Result<Transaction<'a>>
where I: Into<String> where
I: Into<String>,
{ {
self._savepoint(name.into()) self._savepoint(name.into())
} }
@ -292,8 +292,7 @@ impl<'conn> Transaction<'conn> {
pub fn set_config(&self, config: &Config) -> Result<()> { pub fn set_config(&self, config: &Config) -> Result<()> {
let mut command = "SET TRANSACTION".to_owned(); let mut command = "SET TRANSACTION".to_owned();
config.build_command(&mut command); config.build_command(&mut command);
self.simple_query(&command) self.simple_query(&command).map(|_| ())
.map(|_| ())
} }
/// Determines if the transaction is currently set to commit or roll back. /// Determines if the transaction is currently set to commit or roll back.

View File

@ -1365,8 +1365,8 @@ fn test_rows_index() {
#[test] #[test]
fn test_type_names() { fn test_type_names() {
let conn = Connection::connect("postgres://postgres@localhost:5433", TlsMode::None).unwrap(); let conn = Connection::connect("postgres://postgres@localhost:5433", TlsMode::None).unwrap();
let stmt = let stmt = conn
conn.prepare( .prepare(
"SELECT t.oid, t.typname "SELECT t.oid, t.typname
FROM pg_catalog.pg_type t, pg_namespace n FROM pg_catalog.pg_type t, pg_namespace n
WHERE n.oid = t.typnamespace WHERE n.oid = t.typnamespace

View File

@ -1,6 +1,6 @@
extern crate chrono; extern crate chrono;
use self::chrono::{TimeZone, NaiveDate, NaiveTime, NaiveDateTime, DateTime, Utc}; use self::chrono::{DateTime, NaiveDate, NaiveDateTime, NaiveTime, TimeZone, Utc};
use types::test_type; use types::test_type;
use postgres::types::{Date, Timestamp}; use postgres::types::{Date, Timestamp};
@ -9,9 +9,7 @@ use postgres::types::{Date, Timestamp};
fn test_naive_date_time_params() { fn test_naive_date_time_params() {
fn make_check<'a>(time: &'a str) -> (Option<NaiveDateTime>, &'a str) { fn make_check<'a>(time: &'a str) -> (Option<NaiveDateTime>, &'a str) {
( (
Some( Some(NaiveDateTime::parse_from_str(time, "'%Y-%m-%d %H:%M:%S.%f'").unwrap()),
NaiveDateTime::parse_from_str(time, "'%Y-%m-%d %H:%M:%S.%f'").unwrap(),
),
time, time,
) )
} }

View File

@ -364,7 +364,8 @@ fn test_slice() {
INSERT INTO foo (f) VALUES ('a'), ('b'), ('c'), ('d');", INSERT INTO foo (f) VALUES ('a'), ('b'), ('c'), ('d');",
).unwrap(); ).unwrap();
let stmt = conn.prepare("SELECT f FROM foo WHERE id = ANY($1)") let stmt = conn
.prepare("SELECT f FROM foo WHERE id = ANY($1)")
.unwrap(); .unwrap();
let result = stmt.query(&[&&[1i32, 3, 4][..]]).unwrap(); let result = stmt.query(&[&&[1i32, 3, 4][..]]).unwrap();
assert_eq!( assert_eq!(
@ -382,7 +383,8 @@ fn test_slice_wrong_type() {
conn.simple_query("CREATE TEMPORARY TABLE foo (id SERIAL PRIMARY KEY)") conn.simple_query("CREATE TEMPORARY TABLE foo (id SERIAL PRIMARY KEY)")
.unwrap(); .unwrap();
let stmt = conn.prepare("SELECT * FROM foo WHERE id = ANY($1)") let stmt = conn
.prepare("SELECT * FROM foo WHERE id = ANY($1)")
.unwrap(); .unwrap();
let err = stmt.query(&[&&["hi"][..]]).unwrap_err(); let err = stmt.query(&[&&["hi"][..]]).unwrap_err();
match err.as_conversion() { match err.as_conversion() {

View File

@ -8,9 +8,7 @@ fn test_uuid_params() {
"UUID", "UUID",
&[ &[
( (
Some( Some(uuid::Uuid::parse_str("a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11").unwrap()),
uuid::Uuid::parse_str("a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11").unwrap(),
),
"'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'", "'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'",
), ),
(None, "NULL"), (None, "NULL"),

View File

@ -33,7 +33,8 @@ impl SqlState {
pub const WARNING_IMPLICIT_ZERO_BIT_PADDING: SqlState = SqlState(Cow::Borrowed("01008")); pub const WARNING_IMPLICIT_ZERO_BIT_PADDING: SqlState = SqlState(Cow::Borrowed("01008"));
/// 01003 /// 01003
pub const WARNING_NULL_VALUE_ELIMINATED_IN_SET_FUNCTION: SqlState = SqlState(Cow::Borrowed("01003")); pub const WARNING_NULL_VALUE_ELIMINATED_IN_SET_FUNCTION: SqlState =
SqlState(Cow::Borrowed("01003"));
/// 01007 /// 01007
pub const WARNING_PRIVILEGE_NOT_GRANTED: SqlState = SqlState(Cow::Borrowed("01007")); pub const WARNING_PRIVILEGE_NOT_GRANTED: SqlState = SqlState(Cow::Borrowed("01007"));
@ -51,7 +52,8 @@ impl SqlState {
pub const NO_DATA: SqlState = SqlState(Cow::Borrowed("02000")); pub const NO_DATA: SqlState = SqlState(Cow::Borrowed("02000"));
/// 02001 /// 02001
pub const NO_ADDITIONAL_DYNAMIC_RESULT_SETS_RETURNED: SqlState = SqlState(Cow::Borrowed("02001")); pub const NO_ADDITIONAL_DYNAMIC_RESULT_SETS_RETURNED: SqlState =
SqlState(Cow::Borrowed("02001"));
/// 03000 /// 03000
pub const SQL_STATEMENT_NOT_YET_COMPLETE: SqlState = SqlState(Cow::Borrowed("03000")); pub const SQL_STATEMENT_NOT_YET_COMPLETE: SqlState = SqlState(Cow::Borrowed("03000"));
@ -66,10 +68,12 @@ impl SqlState {
pub const CONNECTION_FAILURE: SqlState = SqlState(Cow::Borrowed("08006")); pub const CONNECTION_FAILURE: SqlState = SqlState(Cow::Borrowed("08006"));
/// 08001 /// 08001
pub const SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION: SqlState = SqlState(Cow::Borrowed("08001")); pub const SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION: SqlState =
SqlState(Cow::Borrowed("08001"));
/// 08004 /// 08004
pub const SQLSERVER_REJECTED_ESTABLISHMENT_OF_SQLCONNECTION: SqlState = SqlState(Cow::Borrowed("08004")); pub const SQLSERVER_REJECTED_ESTABLISHMENT_OF_SQLCONNECTION: SqlState =
SqlState(Cow::Borrowed("08004"));
/// 08007 /// 08007
pub const TRANSACTION_RESOLUTION_UNKNOWN: SqlState = SqlState(Cow::Borrowed("08007")); pub const TRANSACTION_RESOLUTION_UNKNOWN: SqlState = SqlState(Cow::Borrowed("08007"));
@ -105,7 +109,8 @@ impl SqlState {
pub const DIAGNOSTICS_EXCEPTION: SqlState = SqlState(Cow::Borrowed("0Z000")); pub const DIAGNOSTICS_EXCEPTION: SqlState = SqlState(Cow::Borrowed("0Z000"));
/// 0Z002 /// 0Z002
pub const STACKED_DIAGNOSTICS_ACCESSED_WITHOUT_ACTIVE_HANDLER: SqlState = SqlState(Cow::Borrowed("0Z002")); pub const STACKED_DIAGNOSTICS_ACCESSED_WITHOUT_ACTIVE_HANDLER: SqlState =
SqlState(Cow::Borrowed("0Z002"));
/// 20000 /// 20000
pub const CASE_NOT_FOUND: SqlState = SqlState(Cow::Borrowed("20000")); pub const CASE_NOT_FOUND: SqlState = SqlState(Cow::Borrowed("20000"));
@ -159,7 +164,8 @@ impl SqlState {
pub const INVALID_ARGUMENT_FOR_POWER_FUNCTION: SqlState = SqlState(Cow::Borrowed("2201F")); pub const INVALID_ARGUMENT_FOR_POWER_FUNCTION: SqlState = SqlState(Cow::Borrowed("2201F"));
/// 2201G /// 2201G
pub const INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION: SqlState = SqlState(Cow::Borrowed("2201G")); pub const INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION: SqlState =
SqlState(Cow::Borrowed("2201G"));
/// 22018 /// 22018
pub const INVALID_CHARACTER_VALUE_FOR_CAST: SqlState = SqlState(Cow::Borrowed("22018")); pub const INVALID_CHARACTER_VALUE_FOR_CAST: SqlState = SqlState(Cow::Borrowed("22018"));
@ -192,7 +198,8 @@ impl SqlState {
pub const INVALID_ROW_COUNT_IN_LIMIT_CLAUSE: SqlState = SqlState(Cow::Borrowed("2201W")); pub const INVALID_ROW_COUNT_IN_LIMIT_CLAUSE: SqlState = SqlState(Cow::Borrowed("2201W"));
/// 2201X /// 2201X
pub const INVALID_ROW_COUNT_IN_RESULT_OFFSET_CLAUSE: SqlState = SqlState(Cow::Borrowed("2201X")); pub const INVALID_ROW_COUNT_IN_RESULT_OFFSET_CLAUSE: SqlState =
SqlState(Cow::Borrowed("2201X"));
/// 2202H /// 2202H
pub const INVALID_TABLESAMPLE_ARGUMENT: SqlState = SqlState(Cow::Borrowed("2202H")); pub const INVALID_TABLESAMPLE_ARGUMENT: SqlState = SqlState(Cow::Borrowed("2202H"));
@ -303,22 +310,27 @@ impl SqlState {
pub const BRANCH_TRANSACTION_ALREADY_ACTIVE: SqlState = SqlState(Cow::Borrowed("25002")); pub const BRANCH_TRANSACTION_ALREADY_ACTIVE: SqlState = SqlState(Cow::Borrowed("25002"));
/// 25008 /// 25008
pub const HELD_CURSOR_REQUIRES_SAME_ISOLATION_LEVEL: SqlState = SqlState(Cow::Borrowed("25008")); pub const HELD_CURSOR_REQUIRES_SAME_ISOLATION_LEVEL: SqlState =
SqlState(Cow::Borrowed("25008"));
/// 25003 /// 25003
pub const INAPPROPRIATE_ACCESS_MODE_FOR_BRANCH_TRANSACTION: SqlState = SqlState(Cow::Borrowed("25003")); pub const INAPPROPRIATE_ACCESS_MODE_FOR_BRANCH_TRANSACTION: SqlState =
SqlState(Cow::Borrowed("25003"));
/// 25004 /// 25004
pub const INAPPROPRIATE_ISOLATION_LEVEL_FOR_BRANCH_TRANSACTION: SqlState = SqlState(Cow::Borrowed("25004")); pub const INAPPROPRIATE_ISOLATION_LEVEL_FOR_BRANCH_TRANSACTION: SqlState =
SqlState(Cow::Borrowed("25004"));
/// 25005 /// 25005
pub const NO_ACTIVE_SQL_TRANSACTION_FOR_BRANCH_TRANSACTION: SqlState = SqlState(Cow::Borrowed("25005")); pub const NO_ACTIVE_SQL_TRANSACTION_FOR_BRANCH_TRANSACTION: SqlState =
SqlState(Cow::Borrowed("25005"));
/// 25006 /// 25006
pub const READ_ONLY_SQL_TRANSACTION: SqlState = SqlState(Cow::Borrowed("25006")); pub const READ_ONLY_SQL_TRANSACTION: SqlState = SqlState(Cow::Borrowed("25006"));
/// 25007 /// 25007
pub const SCHEMA_AND_DATA_STATEMENT_MIXING_NOT_SUPPORTED: SqlState = SqlState(Cow::Borrowed("25007")); pub const SCHEMA_AND_DATA_STATEMENT_MIXING_NOT_SUPPORTED: SqlState =
SqlState(Cow::Borrowed("25007"));
/// 25P01 /// 25P01
pub const NO_ACTIVE_SQL_TRANSACTION: SqlState = SqlState(Cow::Borrowed("25P01")); pub const NO_ACTIVE_SQL_TRANSACTION: SqlState = SqlState(Cow::Borrowed("25P01"));
@ -345,7 +357,8 @@ impl SqlState {
pub const INVALID_PASSWORD: SqlState = SqlState(Cow::Borrowed("28P01")); pub const INVALID_PASSWORD: SqlState = SqlState(Cow::Borrowed("28P01"));
/// 2B000 /// 2B000
pub const DEPENDENT_PRIVILEGE_DESCRIPTORS_STILL_EXIST: SqlState = SqlState(Cow::Borrowed("2B000")); pub const DEPENDENT_PRIVILEGE_DESCRIPTORS_STILL_EXIST: SqlState =
SqlState(Cow::Borrowed("2B000"));
/// 2BP01 /// 2BP01
pub const DEPENDENT_OBJECTS_STILL_EXIST: SqlState = SqlState(Cow::Borrowed("2BP01")); pub const DEPENDENT_OBJECTS_STILL_EXIST: SqlState = SqlState(Cow::Borrowed("2BP01"));
@ -357,7 +370,8 @@ impl SqlState {
pub const SQL_ROUTINE_EXCEPTION: SqlState = SqlState(Cow::Borrowed("2F000")); pub const SQL_ROUTINE_EXCEPTION: SqlState = SqlState(Cow::Borrowed("2F000"));
/// 2F005 /// 2F005
pub const S_R_E_FUNCTION_EXECUTED_NO_RETURN_STATEMENT: SqlState = SqlState(Cow::Borrowed("2F005")); pub const S_R_E_FUNCTION_EXECUTED_NO_RETURN_STATEMENT: SqlState =
SqlState(Cow::Borrowed("2F005"));
/// 2F002 /// 2F002
pub const S_R_E_MODIFYING_SQL_DATA_NOT_PERMITTED: SqlState = SqlState(Cow::Borrowed("2F002")); pub const S_R_E_MODIFYING_SQL_DATA_NOT_PERMITTED: SqlState = SqlState(Cow::Borrowed("2F002"));
@ -699,7 +713,8 @@ impl SqlState {
pub const FDW_INVALID_OPTION_NAME: SqlState = SqlState(Cow::Borrowed("HV00D")); pub const FDW_INVALID_OPTION_NAME: SqlState = SqlState(Cow::Borrowed("HV00D"));
/// HV090 /// HV090
pub const FDW_INVALID_STRING_LENGTH_OR_BUFFER_LENGTH: SqlState = SqlState(Cow::Borrowed("HV090")); pub const FDW_INVALID_STRING_LENGTH_OR_BUFFER_LENGTH: SqlState =
SqlState(Cow::Borrowed("HV090"));
/// HV00A /// HV00A
pub const FDW_INVALID_STRING_FORMAT: SqlState = SqlState(Cow::Borrowed("HV00A")); pub const FDW_INVALID_STRING_FORMAT: SqlState = SqlState(Cow::Borrowed("HV00A"));