From 05a0643cc02e95a9c10ae7936e8941cbdb62e07f Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Sat, 24 Apr 2021 10:19:23 -0400 Subject: [PATCH 01/59] Fix matching on SqlState Closes #756 --- codegen/src/sqlstate.rs | 68 +- tokio-postgres/src/error/sqlstate.rs | 1073 +++++++++++++++++++------- 2 files changed, 852 insertions(+), 289 deletions(-) diff --git a/codegen/src/sqlstate.rs b/codegen/src/sqlstate.rs index bb21be34f..ea3045654 100644 --- a/codegen/src/sqlstate.rs +++ b/codegen/src/sqlstate.rs @@ -1,5 +1,4 @@ use linked_hash_map::LinkedHashMap; -use phf_codegen; use std::fs::File; use std::io::{BufWriter, Write}; @@ -11,7 +10,9 @@ pub fn build() { let codes = parse_codes(); make_type(&mut file); + make_code(&codes, &mut file); make_consts(&codes, &mut file); + make_inner(&codes, &mut file); make_map(&codes, &mut file); } @@ -38,26 +39,51 @@ fn make_type(file: &mut BufWriter) { write!( file, "// Autogenerated file - DO NOT EDIT -use std::borrow::Cow; /// A SQLSTATE error code #[derive(PartialEq, Eq, Clone, Debug)] -pub struct SqlState(Cow<'static, str>); +pub struct SqlState(Inner); impl SqlState {{ /// Creates a `SqlState` from its error code. pub fn from_code(s: &str) -> SqlState {{ match SQLSTATE_MAP.get(s) {{ Some(state) => state.clone(), - None => SqlState(Cow::Owned(s.to_string())), + None => SqlState(Inner::Other(s.into())), }} }} +" + ) + .unwrap(); +} +fn make_code(codes: &LinkedHashMap>, file: &mut BufWriter) { + write!( + file, + r#" /// Returns the error code corresponding to the `SqlState`. pub fn code(&self) -> &str {{ - &self.0 + match &self.0 {{"#, + ) + .unwrap(); + + for code in codes.keys() { + write!( + file, + r#" + Inner::E{code} => "{code}","#, + code = code, + ) + .unwrap(); + } + + write!( + file, + r#" + Inner::Other(code) => code, + }} }} -" + "# ) .unwrap(); } @@ -69,7 +95,7 @@ fn make_consts(codes: &LinkedHashMap>, file: &mut BufWriter< file, r#" /// {code} - pub const {name}: SqlState = SqlState(Cow::Borrowed("{code}")); + pub const {name}: SqlState = SqlState(Inner::E{code}); "#, name = name, code = code, @@ -81,6 +107,34 @@ fn make_consts(codes: &LinkedHashMap>, file: &mut BufWriter< write!(file, "}}").unwrap(); } +fn make_inner(codes: &LinkedHashMap>, file: &mut BufWriter) { + write!( + file, + r#" + +#[derive(PartialEq, Eq, Clone, Debug)] +enum Inner {{"#, + ) + .unwrap(); + for code in codes.keys() { + write!( + file, + r#" + E{},"#, + code, + ) + .unwrap(); + } + write!( + file, + r#" + Other(Box), +}} + "#, + ) + .unwrap(); +} + fn make_map(codes: &LinkedHashMap>, file: &mut BufWriter) { let mut builder = phf_codegen::Map::new(); for (code, names) in codes { diff --git a/tokio-postgres/src/error/sqlstate.rs b/tokio-postgres/src/error/sqlstate.rs index 3a6ea0bdc..6505b51ce 100644 --- a/tokio-postgres/src/error/sqlstate.rs +++ b/tokio-postgres/src/error/sqlstate.rs @@ -1,832 +1,1341 @@ // Autogenerated file - DO NOT EDIT -use std::borrow::Cow; /// A SQLSTATE error code #[derive(PartialEq, Eq, Clone, Debug)] -pub struct SqlState(Cow<'static, str>); +pub struct SqlState(Inner); impl SqlState { /// Creates a `SqlState` from its error code. pub fn from_code(s: &str) -> SqlState { match SQLSTATE_MAP.get(s) { Some(state) => state.clone(), - None => SqlState(Cow::Owned(s.to_string())), + None => SqlState(Inner::Other(s.into())), } } /// Returns the error code corresponding to the `SqlState`. pub fn code(&self) -> &str { - &self.0 + match &self.0 { + Inner::E00000 => "00000", + Inner::E01000 => "01000", + Inner::E0100C => "0100C", + Inner::E01008 => "01008", + Inner::E01003 => "01003", + Inner::E01007 => "01007", + Inner::E01006 => "01006", + Inner::E01004 => "01004", + Inner::E01P01 => "01P01", + Inner::E02000 => "02000", + Inner::E02001 => "02001", + Inner::E03000 => "03000", + Inner::E08000 => "08000", + Inner::E08003 => "08003", + Inner::E08006 => "08006", + Inner::E08001 => "08001", + Inner::E08004 => "08004", + Inner::E08007 => "08007", + Inner::E08P01 => "08P01", + Inner::E09000 => "09000", + Inner::E0A000 => "0A000", + Inner::E0B000 => "0B000", + Inner::E0F000 => "0F000", + Inner::E0F001 => "0F001", + Inner::E0L000 => "0L000", + Inner::E0LP01 => "0LP01", + Inner::E0P000 => "0P000", + Inner::E0Z000 => "0Z000", + Inner::E0Z002 => "0Z002", + Inner::E20000 => "20000", + Inner::E21000 => "21000", + Inner::E22000 => "22000", + Inner::E2202E => "2202E", + Inner::E22021 => "22021", + Inner::E22008 => "22008", + Inner::E22012 => "22012", + Inner::E22005 => "22005", + Inner::E2200B => "2200B", + Inner::E22022 => "22022", + Inner::E22015 => "22015", + Inner::E2201E => "2201E", + Inner::E22014 => "22014", + Inner::E22016 => "22016", + Inner::E2201F => "2201F", + Inner::E2201G => "2201G", + Inner::E22018 => "22018", + Inner::E22007 => "22007", + Inner::E22019 => "22019", + Inner::E2200D => "2200D", + Inner::E22025 => "22025", + Inner::E22P06 => "22P06", + Inner::E22010 => "22010", + Inner::E22023 => "22023", + Inner::E22013 => "22013", + Inner::E2201B => "2201B", + Inner::E2201W => "2201W", + Inner::E2201X => "2201X", + Inner::E2202H => "2202H", + Inner::E2202G => "2202G", + Inner::E22009 => "22009", + Inner::E2200C => "2200C", + Inner::E2200G => "2200G", + Inner::E22004 => "22004", + Inner::E22002 => "22002", + Inner::E22003 => "22003", + Inner::E2200H => "2200H", + Inner::E22026 => "22026", + Inner::E22001 => "22001", + Inner::E22011 => "22011", + Inner::E22027 => "22027", + Inner::E22024 => "22024", + Inner::E2200F => "2200F", + Inner::E22P01 => "22P01", + Inner::E22P02 => "22P02", + Inner::E22P03 => "22P03", + Inner::E22P04 => "22P04", + Inner::E22P05 => "22P05", + Inner::E2200L => "2200L", + Inner::E2200M => "2200M", + Inner::E2200N => "2200N", + Inner::E2200S => "2200S", + Inner::E2200T => "2200T", + Inner::E22030 => "22030", + Inner::E22031 => "22031", + Inner::E22032 => "22032", + Inner::E22033 => "22033", + Inner::E22034 => "22034", + Inner::E22035 => "22035", + Inner::E22036 => "22036", + Inner::E22037 => "22037", + Inner::E22038 => "22038", + Inner::E22039 => "22039", + Inner::E2203A => "2203A", + Inner::E2203B => "2203B", + Inner::E2203C => "2203C", + Inner::E2203D => "2203D", + Inner::E2203E => "2203E", + Inner::E2203F => "2203F", + Inner::E23000 => "23000", + Inner::E23001 => "23001", + Inner::E23502 => "23502", + Inner::E23503 => "23503", + Inner::E23505 => "23505", + Inner::E23514 => "23514", + Inner::E23P01 => "23P01", + Inner::E24000 => "24000", + Inner::E25000 => "25000", + Inner::E25001 => "25001", + Inner::E25002 => "25002", + Inner::E25008 => "25008", + Inner::E25003 => "25003", + Inner::E25004 => "25004", + Inner::E25005 => "25005", + Inner::E25006 => "25006", + Inner::E25007 => "25007", + Inner::E25P01 => "25P01", + Inner::E25P02 => "25P02", + Inner::E25P03 => "25P03", + Inner::E26000 => "26000", + Inner::E27000 => "27000", + Inner::E28000 => "28000", + Inner::E28P01 => "28P01", + Inner::E2B000 => "2B000", + Inner::E2BP01 => "2BP01", + Inner::E2D000 => "2D000", + Inner::E2F000 => "2F000", + Inner::E2F005 => "2F005", + Inner::E2F002 => "2F002", + Inner::E2F003 => "2F003", + Inner::E2F004 => "2F004", + Inner::E34000 => "34000", + Inner::E38000 => "38000", + Inner::E38001 => "38001", + Inner::E38002 => "38002", + Inner::E38003 => "38003", + Inner::E38004 => "38004", + Inner::E39000 => "39000", + Inner::E39001 => "39001", + Inner::E39004 => "39004", + Inner::E39P01 => "39P01", + Inner::E39P02 => "39P02", + Inner::E39P03 => "39P03", + Inner::E3B000 => "3B000", + Inner::E3B001 => "3B001", + Inner::E3D000 => "3D000", + Inner::E3F000 => "3F000", + Inner::E40000 => "40000", + Inner::E40002 => "40002", + Inner::E40001 => "40001", + Inner::E40003 => "40003", + Inner::E40P01 => "40P01", + Inner::E42000 => "42000", + Inner::E42601 => "42601", + Inner::E42501 => "42501", + Inner::E42846 => "42846", + Inner::E42803 => "42803", + Inner::E42P20 => "42P20", + Inner::E42P19 => "42P19", + Inner::E42830 => "42830", + Inner::E42602 => "42602", + Inner::E42622 => "42622", + Inner::E42939 => "42939", + Inner::E42804 => "42804", + Inner::E42P18 => "42P18", + Inner::E42P21 => "42P21", + Inner::E42P22 => "42P22", + Inner::E42809 => "42809", + Inner::E428C9 => "428C9", + Inner::E42703 => "42703", + Inner::E42883 => "42883", + Inner::E42P01 => "42P01", + Inner::E42P02 => "42P02", + Inner::E42704 => "42704", + Inner::E42701 => "42701", + Inner::E42P03 => "42P03", + Inner::E42P04 => "42P04", + Inner::E42723 => "42723", + Inner::E42P05 => "42P05", + Inner::E42P06 => "42P06", + Inner::E42P07 => "42P07", + Inner::E42712 => "42712", + Inner::E42710 => "42710", + Inner::E42702 => "42702", + Inner::E42725 => "42725", + Inner::E42P08 => "42P08", + Inner::E42P09 => "42P09", + Inner::E42P10 => "42P10", + Inner::E42611 => "42611", + Inner::E42P11 => "42P11", + Inner::E42P12 => "42P12", + Inner::E42P13 => "42P13", + Inner::E42P14 => "42P14", + Inner::E42P15 => "42P15", + Inner::E42P16 => "42P16", + Inner::E42P17 => "42P17", + Inner::E44000 => "44000", + Inner::E53000 => "53000", + Inner::E53100 => "53100", + Inner::E53200 => "53200", + Inner::E53300 => "53300", + Inner::E53400 => "53400", + Inner::E54000 => "54000", + Inner::E54001 => "54001", + Inner::E54011 => "54011", + Inner::E54023 => "54023", + Inner::E55000 => "55000", + Inner::E55006 => "55006", + Inner::E55P02 => "55P02", + Inner::E55P03 => "55P03", + Inner::E55P04 => "55P04", + Inner::E57000 => "57000", + Inner::E57014 => "57014", + Inner::E57P01 => "57P01", + Inner::E57P02 => "57P02", + Inner::E57P03 => "57P03", + Inner::E57P04 => "57P04", + Inner::E58000 => "58000", + Inner::E58030 => "58030", + Inner::E58P01 => "58P01", + Inner::E58P02 => "58P02", + Inner::E72000 => "72000", + Inner::EF0000 => "F0000", + Inner::EF0001 => "F0001", + Inner::EHV000 => "HV000", + Inner::EHV005 => "HV005", + Inner::EHV002 => "HV002", + Inner::EHV010 => "HV010", + Inner::EHV021 => "HV021", + Inner::EHV024 => "HV024", + Inner::EHV007 => "HV007", + Inner::EHV008 => "HV008", + Inner::EHV004 => "HV004", + Inner::EHV006 => "HV006", + Inner::EHV091 => "HV091", + Inner::EHV00B => "HV00B", + Inner::EHV00C => "HV00C", + Inner::EHV00D => "HV00D", + Inner::EHV090 => "HV090", + Inner::EHV00A => "HV00A", + Inner::EHV009 => "HV009", + Inner::EHV014 => "HV014", + Inner::EHV001 => "HV001", + Inner::EHV00P => "HV00P", + Inner::EHV00J => "HV00J", + Inner::EHV00K => "HV00K", + Inner::EHV00Q => "HV00Q", + Inner::EHV00R => "HV00R", + Inner::EHV00L => "HV00L", + Inner::EHV00M => "HV00M", + Inner::EHV00N => "HV00N", + Inner::EP0000 => "P0000", + Inner::EP0001 => "P0001", + Inner::EP0002 => "P0002", + Inner::EP0003 => "P0003", + Inner::EP0004 => "P0004", + Inner::EXX000 => "XX000", + Inner::EXX001 => "XX001", + Inner::EXX002 => "XX002", + Inner::Other(code) => code, + } } /// 00000 - pub const SUCCESSFUL_COMPLETION: SqlState = SqlState(Cow::Borrowed("00000")); + pub const SUCCESSFUL_COMPLETION: SqlState = SqlState(Inner::E00000); /// 01000 - pub const WARNING: SqlState = SqlState(Cow::Borrowed("01000")); + pub const WARNING: SqlState = SqlState(Inner::E01000); /// 0100C - pub const WARNING_DYNAMIC_RESULT_SETS_RETURNED: SqlState = SqlState(Cow::Borrowed("0100C")); + pub const WARNING_DYNAMIC_RESULT_SETS_RETURNED: SqlState = SqlState(Inner::E0100C); /// 01008 - pub const WARNING_IMPLICIT_ZERO_BIT_PADDING: SqlState = SqlState(Cow::Borrowed("01008")); + pub const WARNING_IMPLICIT_ZERO_BIT_PADDING: SqlState = SqlState(Inner::E01008); /// 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(Inner::E01003); /// 01007 - pub const WARNING_PRIVILEGE_NOT_GRANTED: SqlState = SqlState(Cow::Borrowed("01007")); + pub const WARNING_PRIVILEGE_NOT_GRANTED: SqlState = SqlState(Inner::E01007); /// 01006 - pub const WARNING_PRIVILEGE_NOT_REVOKED: SqlState = SqlState(Cow::Borrowed("01006")); + pub const WARNING_PRIVILEGE_NOT_REVOKED: SqlState = SqlState(Inner::E01006); /// 01004 - pub const WARNING_STRING_DATA_RIGHT_TRUNCATION: SqlState = SqlState(Cow::Borrowed("01004")); + pub const WARNING_STRING_DATA_RIGHT_TRUNCATION: SqlState = SqlState(Inner::E01004); /// 01P01 - pub const WARNING_DEPRECATED_FEATURE: SqlState = SqlState(Cow::Borrowed("01P01")); + pub const WARNING_DEPRECATED_FEATURE: SqlState = SqlState(Inner::E01P01); /// 02000 - pub const NO_DATA: SqlState = SqlState(Cow::Borrowed("02000")); + pub const NO_DATA: SqlState = SqlState(Inner::E02000); /// 02001 - pub const NO_ADDITIONAL_DYNAMIC_RESULT_SETS_RETURNED: SqlState = - SqlState(Cow::Borrowed("02001")); + pub const NO_ADDITIONAL_DYNAMIC_RESULT_SETS_RETURNED: SqlState = SqlState(Inner::E02001); /// 03000 - pub const SQL_STATEMENT_NOT_YET_COMPLETE: SqlState = SqlState(Cow::Borrowed("03000")); + pub const SQL_STATEMENT_NOT_YET_COMPLETE: SqlState = SqlState(Inner::E03000); /// 08000 - pub const CONNECTION_EXCEPTION: SqlState = SqlState(Cow::Borrowed("08000")); + pub const CONNECTION_EXCEPTION: SqlState = SqlState(Inner::E08000); /// 08003 - pub const CONNECTION_DOES_NOT_EXIST: SqlState = SqlState(Cow::Borrowed("08003")); + pub const CONNECTION_DOES_NOT_EXIST: SqlState = SqlState(Inner::E08003); /// 08006 - pub const CONNECTION_FAILURE: SqlState = SqlState(Cow::Borrowed("08006")); + pub const CONNECTION_FAILURE: SqlState = SqlState(Inner::E08006); /// 08001 - pub const SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION: SqlState = - SqlState(Cow::Borrowed("08001")); + pub const SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION: SqlState = SqlState(Inner::E08001); /// 08004 - pub const SQLSERVER_REJECTED_ESTABLISHMENT_OF_SQLCONNECTION: SqlState = - SqlState(Cow::Borrowed("08004")); + pub const SQLSERVER_REJECTED_ESTABLISHMENT_OF_SQLCONNECTION: SqlState = SqlState(Inner::E08004); /// 08007 - pub const TRANSACTION_RESOLUTION_UNKNOWN: SqlState = SqlState(Cow::Borrowed("08007")); + pub const TRANSACTION_RESOLUTION_UNKNOWN: SqlState = SqlState(Inner::E08007); /// 08P01 - pub const PROTOCOL_VIOLATION: SqlState = SqlState(Cow::Borrowed("08P01")); + pub const PROTOCOL_VIOLATION: SqlState = SqlState(Inner::E08P01); /// 09000 - pub const TRIGGERED_ACTION_EXCEPTION: SqlState = SqlState(Cow::Borrowed("09000")); + pub const TRIGGERED_ACTION_EXCEPTION: SqlState = SqlState(Inner::E09000); /// 0A000 - pub const FEATURE_NOT_SUPPORTED: SqlState = SqlState(Cow::Borrowed("0A000")); + pub const FEATURE_NOT_SUPPORTED: SqlState = SqlState(Inner::E0A000); /// 0B000 - pub const INVALID_TRANSACTION_INITIATION: SqlState = SqlState(Cow::Borrowed("0B000")); + pub const INVALID_TRANSACTION_INITIATION: SqlState = SqlState(Inner::E0B000); /// 0F000 - pub const LOCATOR_EXCEPTION: SqlState = SqlState(Cow::Borrowed("0F000")); + pub const LOCATOR_EXCEPTION: SqlState = SqlState(Inner::E0F000); /// 0F001 - pub const L_E_INVALID_SPECIFICATION: SqlState = SqlState(Cow::Borrowed("0F001")); + pub const L_E_INVALID_SPECIFICATION: SqlState = SqlState(Inner::E0F001); /// 0L000 - pub const INVALID_GRANTOR: SqlState = SqlState(Cow::Borrowed("0L000")); + pub const INVALID_GRANTOR: SqlState = SqlState(Inner::E0L000); /// 0LP01 - pub const INVALID_GRANT_OPERATION: SqlState = SqlState(Cow::Borrowed("0LP01")); + pub const INVALID_GRANT_OPERATION: SqlState = SqlState(Inner::E0LP01); /// 0P000 - pub const INVALID_ROLE_SPECIFICATION: SqlState = SqlState(Cow::Borrowed("0P000")); + pub const INVALID_ROLE_SPECIFICATION: SqlState = SqlState(Inner::E0P000); /// 0Z000 - pub const DIAGNOSTICS_EXCEPTION: SqlState = SqlState(Cow::Borrowed("0Z000")); + pub const DIAGNOSTICS_EXCEPTION: SqlState = SqlState(Inner::E0Z000); /// 0Z002 pub const STACKED_DIAGNOSTICS_ACCESSED_WITHOUT_ACTIVE_HANDLER: SqlState = - SqlState(Cow::Borrowed("0Z002")); + SqlState(Inner::E0Z002); /// 20000 - pub const CASE_NOT_FOUND: SqlState = SqlState(Cow::Borrowed("20000")); + pub const CASE_NOT_FOUND: SqlState = SqlState(Inner::E20000); /// 21000 - pub const CARDINALITY_VIOLATION: SqlState = SqlState(Cow::Borrowed("21000")); + pub const CARDINALITY_VIOLATION: SqlState = SqlState(Inner::E21000); /// 22000 - pub const DATA_EXCEPTION: SqlState = SqlState(Cow::Borrowed("22000")); + pub const DATA_EXCEPTION: SqlState = SqlState(Inner::E22000); /// 2202E - pub const ARRAY_ELEMENT_ERROR: SqlState = SqlState(Cow::Borrowed("2202E")); + pub const ARRAY_ELEMENT_ERROR: SqlState = SqlState(Inner::E2202E); /// 2202E - pub const ARRAY_SUBSCRIPT_ERROR: SqlState = SqlState(Cow::Borrowed("2202E")); + pub const ARRAY_SUBSCRIPT_ERROR: SqlState = SqlState(Inner::E2202E); /// 22021 - pub const CHARACTER_NOT_IN_REPERTOIRE: SqlState = SqlState(Cow::Borrowed("22021")); + pub const CHARACTER_NOT_IN_REPERTOIRE: SqlState = SqlState(Inner::E22021); /// 22008 - pub const DATETIME_FIELD_OVERFLOW: SqlState = SqlState(Cow::Borrowed("22008")); + pub const DATETIME_FIELD_OVERFLOW: SqlState = SqlState(Inner::E22008); /// 22008 - pub const DATETIME_VALUE_OUT_OF_RANGE: SqlState = SqlState(Cow::Borrowed("22008")); + pub const DATETIME_VALUE_OUT_OF_RANGE: SqlState = SqlState(Inner::E22008); /// 22012 - pub const DIVISION_BY_ZERO: SqlState = SqlState(Cow::Borrowed("22012")); + pub const DIVISION_BY_ZERO: SqlState = SqlState(Inner::E22012); /// 22005 - pub const ERROR_IN_ASSIGNMENT: SqlState = SqlState(Cow::Borrowed("22005")); + pub const ERROR_IN_ASSIGNMENT: SqlState = SqlState(Inner::E22005); /// 2200B - pub const ESCAPE_CHARACTER_CONFLICT: SqlState = SqlState(Cow::Borrowed("2200B")); + pub const ESCAPE_CHARACTER_CONFLICT: SqlState = SqlState(Inner::E2200B); /// 22022 - pub const INDICATOR_OVERFLOW: SqlState = SqlState(Cow::Borrowed("22022")); + pub const INDICATOR_OVERFLOW: SqlState = SqlState(Inner::E22022); /// 22015 - pub const INTERVAL_FIELD_OVERFLOW: SqlState = SqlState(Cow::Borrowed("22015")); + pub const INTERVAL_FIELD_OVERFLOW: SqlState = SqlState(Inner::E22015); /// 2201E - pub const INVALID_ARGUMENT_FOR_LOG: SqlState = SqlState(Cow::Borrowed("2201E")); + pub const INVALID_ARGUMENT_FOR_LOG: SqlState = SqlState(Inner::E2201E); /// 22014 - pub const INVALID_ARGUMENT_FOR_NTILE: SqlState = SqlState(Cow::Borrowed("22014")); + pub const INVALID_ARGUMENT_FOR_NTILE: SqlState = SqlState(Inner::E22014); /// 22016 - pub const INVALID_ARGUMENT_FOR_NTH_VALUE: SqlState = SqlState(Cow::Borrowed("22016")); + pub const INVALID_ARGUMENT_FOR_NTH_VALUE: SqlState = SqlState(Inner::E22016); /// 2201F - pub const INVALID_ARGUMENT_FOR_POWER_FUNCTION: SqlState = SqlState(Cow::Borrowed("2201F")); + pub const INVALID_ARGUMENT_FOR_POWER_FUNCTION: SqlState = SqlState(Inner::E2201F); /// 2201G - pub const INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION: SqlState = - SqlState(Cow::Borrowed("2201G")); + pub const INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION: SqlState = SqlState(Inner::E2201G); /// 22018 - pub const INVALID_CHARACTER_VALUE_FOR_CAST: SqlState = SqlState(Cow::Borrowed("22018")); + pub const INVALID_CHARACTER_VALUE_FOR_CAST: SqlState = SqlState(Inner::E22018); /// 22007 - pub const INVALID_DATETIME_FORMAT: SqlState = SqlState(Cow::Borrowed("22007")); + pub const INVALID_DATETIME_FORMAT: SqlState = SqlState(Inner::E22007); /// 22019 - pub const INVALID_ESCAPE_CHARACTER: SqlState = SqlState(Cow::Borrowed("22019")); + pub const INVALID_ESCAPE_CHARACTER: SqlState = SqlState(Inner::E22019); /// 2200D - pub const INVALID_ESCAPE_OCTET: SqlState = SqlState(Cow::Borrowed("2200D")); + pub const INVALID_ESCAPE_OCTET: SqlState = SqlState(Inner::E2200D); /// 22025 - pub const INVALID_ESCAPE_SEQUENCE: SqlState = SqlState(Cow::Borrowed("22025")); + pub const INVALID_ESCAPE_SEQUENCE: SqlState = SqlState(Inner::E22025); /// 22P06 - pub const NONSTANDARD_USE_OF_ESCAPE_CHARACTER: SqlState = SqlState(Cow::Borrowed("22P06")); + pub const NONSTANDARD_USE_OF_ESCAPE_CHARACTER: SqlState = SqlState(Inner::E22P06); /// 22010 - pub const INVALID_INDICATOR_PARAMETER_VALUE: SqlState = SqlState(Cow::Borrowed("22010")); + pub const INVALID_INDICATOR_PARAMETER_VALUE: SqlState = SqlState(Inner::E22010); /// 22023 - pub const INVALID_PARAMETER_VALUE: SqlState = SqlState(Cow::Borrowed("22023")); + pub const INVALID_PARAMETER_VALUE: SqlState = SqlState(Inner::E22023); /// 22013 - pub const INVALID_PRECEDING_OR_FOLLOWING_SIZE: SqlState = SqlState(Cow::Borrowed("22013")); + pub const INVALID_PRECEDING_OR_FOLLOWING_SIZE: SqlState = SqlState(Inner::E22013); /// 2201B - pub const INVALID_REGULAR_EXPRESSION: SqlState = SqlState(Cow::Borrowed("2201B")); + pub const INVALID_REGULAR_EXPRESSION: SqlState = SqlState(Inner::E2201B); /// 2201W - pub const INVALID_ROW_COUNT_IN_LIMIT_CLAUSE: SqlState = SqlState(Cow::Borrowed("2201W")); + pub const INVALID_ROW_COUNT_IN_LIMIT_CLAUSE: SqlState = SqlState(Inner::E2201W); /// 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(Inner::E2201X); /// 2202H - pub const INVALID_TABLESAMPLE_ARGUMENT: SqlState = SqlState(Cow::Borrowed("2202H")); + pub const INVALID_TABLESAMPLE_ARGUMENT: SqlState = SqlState(Inner::E2202H); /// 2202G - pub const INVALID_TABLESAMPLE_REPEAT: SqlState = SqlState(Cow::Borrowed("2202G")); + pub const INVALID_TABLESAMPLE_REPEAT: SqlState = SqlState(Inner::E2202G); /// 22009 - pub const INVALID_TIME_ZONE_DISPLACEMENT_VALUE: SqlState = SqlState(Cow::Borrowed("22009")); + pub const INVALID_TIME_ZONE_DISPLACEMENT_VALUE: SqlState = SqlState(Inner::E22009); /// 2200C - pub const INVALID_USE_OF_ESCAPE_CHARACTER: SqlState = SqlState(Cow::Borrowed("2200C")); + pub const INVALID_USE_OF_ESCAPE_CHARACTER: SqlState = SqlState(Inner::E2200C); /// 2200G - pub const MOST_SPECIFIC_TYPE_MISMATCH: SqlState = SqlState(Cow::Borrowed("2200G")); + pub const MOST_SPECIFIC_TYPE_MISMATCH: SqlState = SqlState(Inner::E2200G); /// 22004 - pub const NULL_VALUE_NOT_ALLOWED: SqlState = SqlState(Cow::Borrowed("22004")); + pub const NULL_VALUE_NOT_ALLOWED: SqlState = SqlState(Inner::E22004); /// 22002 - pub const NULL_VALUE_NO_INDICATOR_PARAMETER: SqlState = SqlState(Cow::Borrowed("22002")); + pub const NULL_VALUE_NO_INDICATOR_PARAMETER: SqlState = SqlState(Inner::E22002); /// 22003 - pub const NUMERIC_VALUE_OUT_OF_RANGE: SqlState = SqlState(Cow::Borrowed("22003")); + pub const NUMERIC_VALUE_OUT_OF_RANGE: SqlState = SqlState(Inner::E22003); /// 2200H - pub const SEQUENCE_GENERATOR_LIMIT_EXCEEDED: SqlState = SqlState(Cow::Borrowed("2200H")); + pub const SEQUENCE_GENERATOR_LIMIT_EXCEEDED: SqlState = SqlState(Inner::E2200H); /// 22026 - pub const STRING_DATA_LENGTH_MISMATCH: SqlState = SqlState(Cow::Borrowed("22026")); + pub const STRING_DATA_LENGTH_MISMATCH: SqlState = SqlState(Inner::E22026); /// 22001 - pub const STRING_DATA_RIGHT_TRUNCATION: SqlState = SqlState(Cow::Borrowed("22001")); + pub const STRING_DATA_RIGHT_TRUNCATION: SqlState = SqlState(Inner::E22001); /// 22011 - pub const SUBSTRING_ERROR: SqlState = SqlState(Cow::Borrowed("22011")); + pub const SUBSTRING_ERROR: SqlState = SqlState(Inner::E22011); /// 22027 - pub const TRIM_ERROR: SqlState = SqlState(Cow::Borrowed("22027")); + pub const TRIM_ERROR: SqlState = SqlState(Inner::E22027); /// 22024 - pub const UNTERMINATED_C_STRING: SqlState = SqlState(Cow::Borrowed("22024")); + pub const UNTERMINATED_C_STRING: SqlState = SqlState(Inner::E22024); /// 2200F - pub const ZERO_LENGTH_CHARACTER_STRING: SqlState = SqlState(Cow::Borrowed("2200F")); + pub const ZERO_LENGTH_CHARACTER_STRING: SqlState = SqlState(Inner::E2200F); /// 22P01 - pub const FLOATING_POINT_EXCEPTION: SqlState = SqlState(Cow::Borrowed("22P01")); + pub const FLOATING_POINT_EXCEPTION: SqlState = SqlState(Inner::E22P01); /// 22P02 - pub const INVALID_TEXT_REPRESENTATION: SqlState = SqlState(Cow::Borrowed("22P02")); + pub const INVALID_TEXT_REPRESENTATION: SqlState = SqlState(Inner::E22P02); /// 22P03 - pub const INVALID_BINARY_REPRESENTATION: SqlState = SqlState(Cow::Borrowed("22P03")); + pub const INVALID_BINARY_REPRESENTATION: SqlState = SqlState(Inner::E22P03); /// 22P04 - pub const BAD_COPY_FILE_FORMAT: SqlState = SqlState(Cow::Borrowed("22P04")); + pub const BAD_COPY_FILE_FORMAT: SqlState = SqlState(Inner::E22P04); /// 22P05 - pub const UNTRANSLATABLE_CHARACTER: SqlState = SqlState(Cow::Borrowed("22P05")); + pub const UNTRANSLATABLE_CHARACTER: SqlState = SqlState(Inner::E22P05); /// 2200L - pub const NOT_AN_XML_DOCUMENT: SqlState = SqlState(Cow::Borrowed("2200L")); + pub const NOT_AN_XML_DOCUMENT: SqlState = SqlState(Inner::E2200L); /// 2200M - pub const INVALID_XML_DOCUMENT: SqlState = SqlState(Cow::Borrowed("2200M")); + pub const INVALID_XML_DOCUMENT: SqlState = SqlState(Inner::E2200M); /// 2200N - pub const INVALID_XML_CONTENT: SqlState = SqlState(Cow::Borrowed("2200N")); + pub const INVALID_XML_CONTENT: SqlState = SqlState(Inner::E2200N); /// 2200S - pub const INVALID_XML_COMMENT: SqlState = SqlState(Cow::Borrowed("2200S")); + pub const INVALID_XML_COMMENT: SqlState = SqlState(Inner::E2200S); /// 2200T - pub const INVALID_XML_PROCESSING_INSTRUCTION: SqlState = SqlState(Cow::Borrowed("2200T")); + pub const INVALID_XML_PROCESSING_INSTRUCTION: SqlState = SqlState(Inner::E2200T); /// 22030 - pub const DUPLICATE_JSON_OBJECT_KEY_VALUE: SqlState = SqlState(Cow::Borrowed("22030")); + pub const DUPLICATE_JSON_OBJECT_KEY_VALUE: SqlState = SqlState(Inner::E22030); /// 22031 - pub const INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION: SqlState = - SqlState(Cow::Borrowed("22031")); + pub const INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION: SqlState = SqlState(Inner::E22031); /// 22032 - pub const INVALID_JSON_TEXT: SqlState = SqlState(Cow::Borrowed("22032")); + pub const INVALID_JSON_TEXT: SqlState = SqlState(Inner::E22032); /// 22033 - pub const INVALID_SQL_JSON_SUBSCRIPT: SqlState = SqlState(Cow::Borrowed("22033")); + pub const INVALID_SQL_JSON_SUBSCRIPT: SqlState = SqlState(Inner::E22033); /// 22034 - pub const MORE_THAN_ONE_SQL_JSON_ITEM: SqlState = SqlState(Cow::Borrowed("22034")); + pub const MORE_THAN_ONE_SQL_JSON_ITEM: SqlState = SqlState(Inner::E22034); /// 22035 - pub const NO_SQL_JSON_ITEM: SqlState = SqlState(Cow::Borrowed("22035")); + pub const NO_SQL_JSON_ITEM: SqlState = SqlState(Inner::E22035); /// 22036 - pub const NON_NUMERIC_SQL_JSON_ITEM: SqlState = SqlState(Cow::Borrowed("22036")); + pub const NON_NUMERIC_SQL_JSON_ITEM: SqlState = SqlState(Inner::E22036); /// 22037 - pub const NON_UNIQUE_KEYS_IN_A_JSON_OBJECT: SqlState = SqlState(Cow::Borrowed("22037")); + pub const NON_UNIQUE_KEYS_IN_A_JSON_OBJECT: SqlState = SqlState(Inner::E22037); /// 22038 - pub const SINGLETON_SQL_JSON_ITEM_REQUIRED: SqlState = SqlState(Cow::Borrowed("22038")); + pub const SINGLETON_SQL_JSON_ITEM_REQUIRED: SqlState = SqlState(Inner::E22038); /// 22039 - pub const SQL_JSON_ARRAY_NOT_FOUND: SqlState = SqlState(Cow::Borrowed("22039")); + pub const SQL_JSON_ARRAY_NOT_FOUND: SqlState = SqlState(Inner::E22039); /// 2203A - pub const SQL_JSON_MEMBER_NOT_FOUND: SqlState = SqlState(Cow::Borrowed("2203A")); + pub const SQL_JSON_MEMBER_NOT_FOUND: SqlState = SqlState(Inner::E2203A); /// 2203B - pub const SQL_JSON_NUMBER_NOT_FOUND: SqlState = SqlState(Cow::Borrowed("2203B")); + pub const SQL_JSON_NUMBER_NOT_FOUND: SqlState = SqlState(Inner::E2203B); /// 2203C - pub const SQL_JSON_OBJECT_NOT_FOUND: SqlState = SqlState(Cow::Borrowed("2203C")); + pub const SQL_JSON_OBJECT_NOT_FOUND: SqlState = SqlState(Inner::E2203C); /// 2203D - pub const TOO_MANY_JSON_ARRAY_ELEMENTS: SqlState = SqlState(Cow::Borrowed("2203D")); + pub const TOO_MANY_JSON_ARRAY_ELEMENTS: SqlState = SqlState(Inner::E2203D); /// 2203E - pub const TOO_MANY_JSON_OBJECT_MEMBERS: SqlState = SqlState(Cow::Borrowed("2203E")); + pub const TOO_MANY_JSON_OBJECT_MEMBERS: SqlState = SqlState(Inner::E2203E); /// 2203F - pub const SQL_JSON_SCALAR_REQUIRED: SqlState = SqlState(Cow::Borrowed("2203F")); + pub const SQL_JSON_SCALAR_REQUIRED: SqlState = SqlState(Inner::E2203F); /// 23000 - pub const INTEGRITY_CONSTRAINT_VIOLATION: SqlState = SqlState(Cow::Borrowed("23000")); + pub const INTEGRITY_CONSTRAINT_VIOLATION: SqlState = SqlState(Inner::E23000); /// 23001 - pub const RESTRICT_VIOLATION: SqlState = SqlState(Cow::Borrowed("23001")); + pub const RESTRICT_VIOLATION: SqlState = SqlState(Inner::E23001); /// 23502 - pub const NOT_NULL_VIOLATION: SqlState = SqlState(Cow::Borrowed("23502")); + pub const NOT_NULL_VIOLATION: SqlState = SqlState(Inner::E23502); /// 23503 - pub const FOREIGN_KEY_VIOLATION: SqlState = SqlState(Cow::Borrowed("23503")); + pub const FOREIGN_KEY_VIOLATION: SqlState = SqlState(Inner::E23503); /// 23505 - pub const UNIQUE_VIOLATION: SqlState = SqlState(Cow::Borrowed("23505")); + pub const UNIQUE_VIOLATION: SqlState = SqlState(Inner::E23505); /// 23514 - pub const CHECK_VIOLATION: SqlState = SqlState(Cow::Borrowed("23514")); + pub const CHECK_VIOLATION: SqlState = SqlState(Inner::E23514); /// 23P01 - pub const EXCLUSION_VIOLATION: SqlState = SqlState(Cow::Borrowed("23P01")); + pub const EXCLUSION_VIOLATION: SqlState = SqlState(Inner::E23P01); /// 24000 - pub const INVALID_CURSOR_STATE: SqlState = SqlState(Cow::Borrowed("24000")); + pub const INVALID_CURSOR_STATE: SqlState = SqlState(Inner::E24000); /// 25000 - pub const INVALID_TRANSACTION_STATE: SqlState = SqlState(Cow::Borrowed("25000")); + pub const INVALID_TRANSACTION_STATE: SqlState = SqlState(Inner::E25000); /// 25001 - pub const ACTIVE_SQL_TRANSACTION: SqlState = SqlState(Cow::Borrowed("25001")); + pub const ACTIVE_SQL_TRANSACTION: SqlState = SqlState(Inner::E25001); /// 25002 - pub const BRANCH_TRANSACTION_ALREADY_ACTIVE: SqlState = SqlState(Cow::Borrowed("25002")); + pub const BRANCH_TRANSACTION_ALREADY_ACTIVE: SqlState = SqlState(Inner::E25002); /// 25008 - pub const HELD_CURSOR_REQUIRES_SAME_ISOLATION_LEVEL: SqlState = - SqlState(Cow::Borrowed("25008")); + pub const HELD_CURSOR_REQUIRES_SAME_ISOLATION_LEVEL: SqlState = SqlState(Inner::E25008); /// 25003 - pub const INAPPROPRIATE_ACCESS_MODE_FOR_BRANCH_TRANSACTION: SqlState = - SqlState(Cow::Borrowed("25003")); + pub const INAPPROPRIATE_ACCESS_MODE_FOR_BRANCH_TRANSACTION: SqlState = SqlState(Inner::E25003); /// 25004 pub const INAPPROPRIATE_ISOLATION_LEVEL_FOR_BRANCH_TRANSACTION: SqlState = - SqlState(Cow::Borrowed("25004")); + SqlState(Inner::E25004); /// 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(Inner::E25005); /// 25006 - pub const READ_ONLY_SQL_TRANSACTION: SqlState = SqlState(Cow::Borrowed("25006")); + pub const READ_ONLY_SQL_TRANSACTION: SqlState = SqlState(Inner::E25006); /// 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(Inner::E25007); /// 25P01 - pub const NO_ACTIVE_SQL_TRANSACTION: SqlState = SqlState(Cow::Borrowed("25P01")); + pub const NO_ACTIVE_SQL_TRANSACTION: SqlState = SqlState(Inner::E25P01); /// 25P02 - pub const IN_FAILED_SQL_TRANSACTION: SqlState = SqlState(Cow::Borrowed("25P02")); + pub const IN_FAILED_SQL_TRANSACTION: SqlState = SqlState(Inner::E25P02); /// 25P03 - pub const IDLE_IN_TRANSACTION_SESSION_TIMEOUT: SqlState = SqlState(Cow::Borrowed("25P03")); + pub const IDLE_IN_TRANSACTION_SESSION_TIMEOUT: SqlState = SqlState(Inner::E25P03); /// 26000 - pub const INVALID_SQL_STATEMENT_NAME: SqlState = SqlState(Cow::Borrowed("26000")); + pub const INVALID_SQL_STATEMENT_NAME: SqlState = SqlState(Inner::E26000); /// 26000 - pub const UNDEFINED_PSTATEMENT: SqlState = SqlState(Cow::Borrowed("26000")); + pub const UNDEFINED_PSTATEMENT: SqlState = SqlState(Inner::E26000); /// 27000 - pub const TRIGGERED_DATA_CHANGE_VIOLATION: SqlState = SqlState(Cow::Borrowed("27000")); + pub const TRIGGERED_DATA_CHANGE_VIOLATION: SqlState = SqlState(Inner::E27000); /// 28000 - pub const INVALID_AUTHORIZATION_SPECIFICATION: SqlState = SqlState(Cow::Borrowed("28000")); + pub const INVALID_AUTHORIZATION_SPECIFICATION: SqlState = SqlState(Inner::E28000); /// 28P01 - pub const INVALID_PASSWORD: SqlState = SqlState(Cow::Borrowed("28P01")); + pub const INVALID_PASSWORD: SqlState = SqlState(Inner::E28P01); /// 2B000 - pub const DEPENDENT_PRIVILEGE_DESCRIPTORS_STILL_EXIST: SqlState = - SqlState(Cow::Borrowed("2B000")); + pub const DEPENDENT_PRIVILEGE_DESCRIPTORS_STILL_EXIST: SqlState = SqlState(Inner::E2B000); /// 2BP01 - pub const DEPENDENT_OBJECTS_STILL_EXIST: SqlState = SqlState(Cow::Borrowed("2BP01")); + pub const DEPENDENT_OBJECTS_STILL_EXIST: SqlState = SqlState(Inner::E2BP01); /// 2D000 - pub const INVALID_TRANSACTION_TERMINATION: SqlState = SqlState(Cow::Borrowed("2D000")); + pub const INVALID_TRANSACTION_TERMINATION: SqlState = SqlState(Inner::E2D000); /// 2F000 - pub const SQL_ROUTINE_EXCEPTION: SqlState = SqlState(Cow::Borrowed("2F000")); + pub const SQL_ROUTINE_EXCEPTION: SqlState = SqlState(Inner::E2F000); /// 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(Inner::E2F005); /// 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(Inner::E2F002); /// 2F003 - pub const S_R_E_PROHIBITED_SQL_STATEMENT_ATTEMPTED: SqlState = SqlState(Cow::Borrowed("2F003")); + pub const S_R_E_PROHIBITED_SQL_STATEMENT_ATTEMPTED: SqlState = SqlState(Inner::E2F003); /// 2F004 - pub const S_R_E_READING_SQL_DATA_NOT_PERMITTED: SqlState = SqlState(Cow::Borrowed("2F004")); + pub const S_R_E_READING_SQL_DATA_NOT_PERMITTED: SqlState = SqlState(Inner::E2F004); /// 34000 - pub const INVALID_CURSOR_NAME: SqlState = SqlState(Cow::Borrowed("34000")); + pub const INVALID_CURSOR_NAME: SqlState = SqlState(Inner::E34000); /// 34000 - pub const UNDEFINED_CURSOR: SqlState = SqlState(Cow::Borrowed("34000")); + pub const UNDEFINED_CURSOR: SqlState = SqlState(Inner::E34000); /// 38000 - pub const EXTERNAL_ROUTINE_EXCEPTION: SqlState = SqlState(Cow::Borrowed("38000")); + pub const EXTERNAL_ROUTINE_EXCEPTION: SqlState = SqlState(Inner::E38000); /// 38001 - pub const E_R_E_CONTAINING_SQL_NOT_PERMITTED: SqlState = SqlState(Cow::Borrowed("38001")); + pub const E_R_E_CONTAINING_SQL_NOT_PERMITTED: SqlState = SqlState(Inner::E38001); /// 38002 - pub const E_R_E_MODIFYING_SQL_DATA_NOT_PERMITTED: SqlState = SqlState(Cow::Borrowed("38002")); + pub const E_R_E_MODIFYING_SQL_DATA_NOT_PERMITTED: SqlState = SqlState(Inner::E38002); /// 38003 - pub const E_R_E_PROHIBITED_SQL_STATEMENT_ATTEMPTED: SqlState = SqlState(Cow::Borrowed("38003")); + pub const E_R_E_PROHIBITED_SQL_STATEMENT_ATTEMPTED: SqlState = SqlState(Inner::E38003); /// 38004 - pub const E_R_E_READING_SQL_DATA_NOT_PERMITTED: SqlState = SqlState(Cow::Borrowed("38004")); + pub const E_R_E_READING_SQL_DATA_NOT_PERMITTED: SqlState = SqlState(Inner::E38004); /// 39000 - pub const EXTERNAL_ROUTINE_INVOCATION_EXCEPTION: SqlState = SqlState(Cow::Borrowed("39000")); + pub const EXTERNAL_ROUTINE_INVOCATION_EXCEPTION: SqlState = SqlState(Inner::E39000); /// 39001 - pub const E_R_I_E_INVALID_SQLSTATE_RETURNED: SqlState = SqlState(Cow::Borrowed("39001")); + pub const E_R_I_E_INVALID_SQLSTATE_RETURNED: SqlState = SqlState(Inner::E39001); /// 39004 - pub const E_R_I_E_NULL_VALUE_NOT_ALLOWED: SqlState = SqlState(Cow::Borrowed("39004")); + pub const E_R_I_E_NULL_VALUE_NOT_ALLOWED: SqlState = SqlState(Inner::E39004); /// 39P01 - pub const E_R_I_E_TRIGGER_PROTOCOL_VIOLATED: SqlState = SqlState(Cow::Borrowed("39P01")); + pub const E_R_I_E_TRIGGER_PROTOCOL_VIOLATED: SqlState = SqlState(Inner::E39P01); /// 39P02 - pub const E_R_I_E_SRF_PROTOCOL_VIOLATED: SqlState = SqlState(Cow::Borrowed("39P02")); + pub const E_R_I_E_SRF_PROTOCOL_VIOLATED: SqlState = SqlState(Inner::E39P02); /// 39P03 - pub const E_R_I_E_EVENT_TRIGGER_PROTOCOL_VIOLATED: SqlState = SqlState(Cow::Borrowed("39P03")); + pub const E_R_I_E_EVENT_TRIGGER_PROTOCOL_VIOLATED: SqlState = SqlState(Inner::E39P03); /// 3B000 - pub const SAVEPOINT_EXCEPTION: SqlState = SqlState(Cow::Borrowed("3B000")); + pub const SAVEPOINT_EXCEPTION: SqlState = SqlState(Inner::E3B000); /// 3B001 - pub const S_E_INVALID_SPECIFICATION: SqlState = SqlState(Cow::Borrowed("3B001")); + pub const S_E_INVALID_SPECIFICATION: SqlState = SqlState(Inner::E3B001); /// 3D000 - pub const INVALID_CATALOG_NAME: SqlState = SqlState(Cow::Borrowed("3D000")); + pub const INVALID_CATALOG_NAME: SqlState = SqlState(Inner::E3D000); /// 3D000 - pub const UNDEFINED_DATABASE: SqlState = SqlState(Cow::Borrowed("3D000")); + pub const UNDEFINED_DATABASE: SqlState = SqlState(Inner::E3D000); /// 3F000 - pub const INVALID_SCHEMA_NAME: SqlState = SqlState(Cow::Borrowed("3F000")); + pub const INVALID_SCHEMA_NAME: SqlState = SqlState(Inner::E3F000); /// 3F000 - pub const UNDEFINED_SCHEMA: SqlState = SqlState(Cow::Borrowed("3F000")); + pub const UNDEFINED_SCHEMA: SqlState = SqlState(Inner::E3F000); /// 40000 - pub const TRANSACTION_ROLLBACK: SqlState = SqlState(Cow::Borrowed("40000")); + pub const TRANSACTION_ROLLBACK: SqlState = SqlState(Inner::E40000); /// 40002 - pub const T_R_INTEGRITY_CONSTRAINT_VIOLATION: SqlState = SqlState(Cow::Borrowed("40002")); + pub const T_R_INTEGRITY_CONSTRAINT_VIOLATION: SqlState = SqlState(Inner::E40002); /// 40001 - pub const T_R_SERIALIZATION_FAILURE: SqlState = SqlState(Cow::Borrowed("40001")); + pub const T_R_SERIALIZATION_FAILURE: SqlState = SqlState(Inner::E40001); /// 40003 - pub const T_R_STATEMENT_COMPLETION_UNKNOWN: SqlState = SqlState(Cow::Borrowed("40003")); + pub const T_R_STATEMENT_COMPLETION_UNKNOWN: SqlState = SqlState(Inner::E40003); /// 40P01 - pub const T_R_DEADLOCK_DETECTED: SqlState = SqlState(Cow::Borrowed("40P01")); + pub const T_R_DEADLOCK_DETECTED: SqlState = SqlState(Inner::E40P01); /// 42000 - pub const SYNTAX_ERROR_OR_ACCESS_RULE_VIOLATION: SqlState = SqlState(Cow::Borrowed("42000")); + pub const SYNTAX_ERROR_OR_ACCESS_RULE_VIOLATION: SqlState = SqlState(Inner::E42000); /// 42601 - pub const SYNTAX_ERROR: SqlState = SqlState(Cow::Borrowed("42601")); + pub const SYNTAX_ERROR: SqlState = SqlState(Inner::E42601); /// 42501 - pub const INSUFFICIENT_PRIVILEGE: SqlState = SqlState(Cow::Borrowed("42501")); + pub const INSUFFICIENT_PRIVILEGE: SqlState = SqlState(Inner::E42501); /// 42846 - pub const CANNOT_COERCE: SqlState = SqlState(Cow::Borrowed("42846")); + pub const CANNOT_COERCE: SqlState = SqlState(Inner::E42846); /// 42803 - pub const GROUPING_ERROR: SqlState = SqlState(Cow::Borrowed("42803")); + pub const GROUPING_ERROR: SqlState = SqlState(Inner::E42803); /// 42P20 - pub const WINDOWING_ERROR: SqlState = SqlState(Cow::Borrowed("42P20")); + pub const WINDOWING_ERROR: SqlState = SqlState(Inner::E42P20); /// 42P19 - pub const INVALID_RECURSION: SqlState = SqlState(Cow::Borrowed("42P19")); + pub const INVALID_RECURSION: SqlState = SqlState(Inner::E42P19); /// 42830 - pub const INVALID_FOREIGN_KEY: SqlState = SqlState(Cow::Borrowed("42830")); + pub const INVALID_FOREIGN_KEY: SqlState = SqlState(Inner::E42830); /// 42602 - pub const INVALID_NAME: SqlState = SqlState(Cow::Borrowed("42602")); + pub const INVALID_NAME: SqlState = SqlState(Inner::E42602); /// 42622 - pub const NAME_TOO_LONG: SqlState = SqlState(Cow::Borrowed("42622")); + pub const NAME_TOO_LONG: SqlState = SqlState(Inner::E42622); /// 42939 - pub const RESERVED_NAME: SqlState = SqlState(Cow::Borrowed("42939")); + pub const RESERVED_NAME: SqlState = SqlState(Inner::E42939); /// 42804 - pub const DATATYPE_MISMATCH: SqlState = SqlState(Cow::Borrowed("42804")); + pub const DATATYPE_MISMATCH: SqlState = SqlState(Inner::E42804); /// 42P18 - pub const INDETERMINATE_DATATYPE: SqlState = SqlState(Cow::Borrowed("42P18")); + pub const INDETERMINATE_DATATYPE: SqlState = SqlState(Inner::E42P18); /// 42P21 - pub const COLLATION_MISMATCH: SqlState = SqlState(Cow::Borrowed("42P21")); + pub const COLLATION_MISMATCH: SqlState = SqlState(Inner::E42P21); /// 42P22 - pub const INDETERMINATE_COLLATION: SqlState = SqlState(Cow::Borrowed("42P22")); + pub const INDETERMINATE_COLLATION: SqlState = SqlState(Inner::E42P22); /// 42809 - pub const WRONG_OBJECT_TYPE: SqlState = SqlState(Cow::Borrowed("42809")); + pub const WRONG_OBJECT_TYPE: SqlState = SqlState(Inner::E42809); /// 428C9 - pub const GENERATED_ALWAYS: SqlState = SqlState(Cow::Borrowed("428C9")); + pub const GENERATED_ALWAYS: SqlState = SqlState(Inner::E428C9); /// 42703 - pub const UNDEFINED_COLUMN: SqlState = SqlState(Cow::Borrowed("42703")); + pub const UNDEFINED_COLUMN: SqlState = SqlState(Inner::E42703); /// 42883 - pub const UNDEFINED_FUNCTION: SqlState = SqlState(Cow::Borrowed("42883")); + pub const UNDEFINED_FUNCTION: SqlState = SqlState(Inner::E42883); /// 42P01 - pub const UNDEFINED_TABLE: SqlState = SqlState(Cow::Borrowed("42P01")); + pub const UNDEFINED_TABLE: SqlState = SqlState(Inner::E42P01); /// 42P02 - pub const UNDEFINED_PARAMETER: SqlState = SqlState(Cow::Borrowed("42P02")); + pub const UNDEFINED_PARAMETER: SqlState = SqlState(Inner::E42P02); /// 42704 - pub const UNDEFINED_OBJECT: SqlState = SqlState(Cow::Borrowed("42704")); + pub const UNDEFINED_OBJECT: SqlState = SqlState(Inner::E42704); /// 42701 - pub const DUPLICATE_COLUMN: SqlState = SqlState(Cow::Borrowed("42701")); + pub const DUPLICATE_COLUMN: SqlState = SqlState(Inner::E42701); /// 42P03 - pub const DUPLICATE_CURSOR: SqlState = SqlState(Cow::Borrowed("42P03")); + pub const DUPLICATE_CURSOR: SqlState = SqlState(Inner::E42P03); /// 42P04 - pub const DUPLICATE_DATABASE: SqlState = SqlState(Cow::Borrowed("42P04")); + pub const DUPLICATE_DATABASE: SqlState = SqlState(Inner::E42P04); /// 42723 - pub const DUPLICATE_FUNCTION: SqlState = SqlState(Cow::Borrowed("42723")); + pub const DUPLICATE_FUNCTION: SqlState = SqlState(Inner::E42723); /// 42P05 - pub const DUPLICATE_PSTATEMENT: SqlState = SqlState(Cow::Borrowed("42P05")); + pub const DUPLICATE_PSTATEMENT: SqlState = SqlState(Inner::E42P05); /// 42P06 - pub const DUPLICATE_SCHEMA: SqlState = SqlState(Cow::Borrowed("42P06")); + pub const DUPLICATE_SCHEMA: SqlState = SqlState(Inner::E42P06); /// 42P07 - pub const DUPLICATE_TABLE: SqlState = SqlState(Cow::Borrowed("42P07")); + pub const DUPLICATE_TABLE: SqlState = SqlState(Inner::E42P07); /// 42712 - pub const DUPLICATE_ALIAS: SqlState = SqlState(Cow::Borrowed("42712")); + pub const DUPLICATE_ALIAS: SqlState = SqlState(Inner::E42712); /// 42710 - pub const DUPLICATE_OBJECT: SqlState = SqlState(Cow::Borrowed("42710")); + pub const DUPLICATE_OBJECT: SqlState = SqlState(Inner::E42710); /// 42702 - pub const AMBIGUOUS_COLUMN: SqlState = SqlState(Cow::Borrowed("42702")); + pub const AMBIGUOUS_COLUMN: SqlState = SqlState(Inner::E42702); /// 42725 - pub const AMBIGUOUS_FUNCTION: SqlState = SqlState(Cow::Borrowed("42725")); + pub const AMBIGUOUS_FUNCTION: SqlState = SqlState(Inner::E42725); /// 42P08 - pub const AMBIGUOUS_PARAMETER: SqlState = SqlState(Cow::Borrowed("42P08")); + pub const AMBIGUOUS_PARAMETER: SqlState = SqlState(Inner::E42P08); /// 42P09 - pub const AMBIGUOUS_ALIAS: SqlState = SqlState(Cow::Borrowed("42P09")); + pub const AMBIGUOUS_ALIAS: SqlState = SqlState(Inner::E42P09); /// 42P10 - pub const INVALID_COLUMN_REFERENCE: SqlState = SqlState(Cow::Borrowed("42P10")); + pub const INVALID_COLUMN_REFERENCE: SqlState = SqlState(Inner::E42P10); /// 42611 - pub const INVALID_COLUMN_DEFINITION: SqlState = SqlState(Cow::Borrowed("42611")); + pub const INVALID_COLUMN_DEFINITION: SqlState = SqlState(Inner::E42611); /// 42P11 - pub const INVALID_CURSOR_DEFINITION: SqlState = SqlState(Cow::Borrowed("42P11")); + pub const INVALID_CURSOR_DEFINITION: SqlState = SqlState(Inner::E42P11); /// 42P12 - pub const INVALID_DATABASE_DEFINITION: SqlState = SqlState(Cow::Borrowed("42P12")); + pub const INVALID_DATABASE_DEFINITION: SqlState = SqlState(Inner::E42P12); /// 42P13 - pub const INVALID_FUNCTION_DEFINITION: SqlState = SqlState(Cow::Borrowed("42P13")); + pub const INVALID_FUNCTION_DEFINITION: SqlState = SqlState(Inner::E42P13); /// 42P14 - pub const INVALID_PSTATEMENT_DEFINITION: SqlState = SqlState(Cow::Borrowed("42P14")); + pub const INVALID_PSTATEMENT_DEFINITION: SqlState = SqlState(Inner::E42P14); /// 42P15 - pub const INVALID_SCHEMA_DEFINITION: SqlState = SqlState(Cow::Borrowed("42P15")); + pub const INVALID_SCHEMA_DEFINITION: SqlState = SqlState(Inner::E42P15); /// 42P16 - pub const INVALID_TABLE_DEFINITION: SqlState = SqlState(Cow::Borrowed("42P16")); + pub const INVALID_TABLE_DEFINITION: SqlState = SqlState(Inner::E42P16); /// 42P17 - pub const INVALID_OBJECT_DEFINITION: SqlState = SqlState(Cow::Borrowed("42P17")); + pub const INVALID_OBJECT_DEFINITION: SqlState = SqlState(Inner::E42P17); /// 44000 - pub const WITH_CHECK_OPTION_VIOLATION: SqlState = SqlState(Cow::Borrowed("44000")); + pub const WITH_CHECK_OPTION_VIOLATION: SqlState = SqlState(Inner::E44000); /// 53000 - pub const INSUFFICIENT_RESOURCES: SqlState = SqlState(Cow::Borrowed("53000")); + pub const INSUFFICIENT_RESOURCES: SqlState = SqlState(Inner::E53000); /// 53100 - pub const DISK_FULL: SqlState = SqlState(Cow::Borrowed("53100")); + pub const DISK_FULL: SqlState = SqlState(Inner::E53100); /// 53200 - pub const OUT_OF_MEMORY: SqlState = SqlState(Cow::Borrowed("53200")); + pub const OUT_OF_MEMORY: SqlState = SqlState(Inner::E53200); /// 53300 - pub const TOO_MANY_CONNECTIONS: SqlState = SqlState(Cow::Borrowed("53300")); + pub const TOO_MANY_CONNECTIONS: SqlState = SqlState(Inner::E53300); /// 53400 - pub const CONFIGURATION_LIMIT_EXCEEDED: SqlState = SqlState(Cow::Borrowed("53400")); + pub const CONFIGURATION_LIMIT_EXCEEDED: SqlState = SqlState(Inner::E53400); /// 54000 - pub const PROGRAM_LIMIT_EXCEEDED: SqlState = SqlState(Cow::Borrowed("54000")); + pub const PROGRAM_LIMIT_EXCEEDED: SqlState = SqlState(Inner::E54000); /// 54001 - pub const STATEMENT_TOO_COMPLEX: SqlState = SqlState(Cow::Borrowed("54001")); + pub const STATEMENT_TOO_COMPLEX: SqlState = SqlState(Inner::E54001); /// 54011 - pub const TOO_MANY_COLUMNS: SqlState = SqlState(Cow::Borrowed("54011")); + pub const TOO_MANY_COLUMNS: SqlState = SqlState(Inner::E54011); /// 54023 - pub const TOO_MANY_ARGUMENTS: SqlState = SqlState(Cow::Borrowed("54023")); + pub const TOO_MANY_ARGUMENTS: SqlState = SqlState(Inner::E54023); /// 55000 - pub const OBJECT_NOT_IN_PREREQUISITE_STATE: SqlState = SqlState(Cow::Borrowed("55000")); + pub const OBJECT_NOT_IN_PREREQUISITE_STATE: SqlState = SqlState(Inner::E55000); /// 55006 - pub const OBJECT_IN_USE: SqlState = SqlState(Cow::Borrowed("55006")); + pub const OBJECT_IN_USE: SqlState = SqlState(Inner::E55006); /// 55P02 - pub const CANT_CHANGE_RUNTIME_PARAM: SqlState = SqlState(Cow::Borrowed("55P02")); + pub const CANT_CHANGE_RUNTIME_PARAM: SqlState = SqlState(Inner::E55P02); /// 55P03 - pub const LOCK_NOT_AVAILABLE: SqlState = SqlState(Cow::Borrowed("55P03")); + pub const LOCK_NOT_AVAILABLE: SqlState = SqlState(Inner::E55P03); /// 55P04 - pub const UNSAFE_NEW_ENUM_VALUE_USAGE: SqlState = SqlState(Cow::Borrowed("55P04")); + pub const UNSAFE_NEW_ENUM_VALUE_USAGE: SqlState = SqlState(Inner::E55P04); /// 57000 - pub const OPERATOR_INTERVENTION: SqlState = SqlState(Cow::Borrowed("57000")); + pub const OPERATOR_INTERVENTION: SqlState = SqlState(Inner::E57000); /// 57014 - pub const QUERY_CANCELED: SqlState = SqlState(Cow::Borrowed("57014")); + pub const QUERY_CANCELED: SqlState = SqlState(Inner::E57014); /// 57P01 - pub const ADMIN_SHUTDOWN: SqlState = SqlState(Cow::Borrowed("57P01")); + pub const ADMIN_SHUTDOWN: SqlState = SqlState(Inner::E57P01); /// 57P02 - pub const CRASH_SHUTDOWN: SqlState = SqlState(Cow::Borrowed("57P02")); + pub const CRASH_SHUTDOWN: SqlState = SqlState(Inner::E57P02); /// 57P03 - pub const CANNOT_CONNECT_NOW: SqlState = SqlState(Cow::Borrowed("57P03")); + pub const CANNOT_CONNECT_NOW: SqlState = SqlState(Inner::E57P03); /// 57P04 - pub const DATABASE_DROPPED: SqlState = SqlState(Cow::Borrowed("57P04")); + pub const DATABASE_DROPPED: SqlState = SqlState(Inner::E57P04); /// 58000 - pub const SYSTEM_ERROR: SqlState = SqlState(Cow::Borrowed("58000")); + pub const SYSTEM_ERROR: SqlState = SqlState(Inner::E58000); /// 58030 - pub const IO_ERROR: SqlState = SqlState(Cow::Borrowed("58030")); + pub const IO_ERROR: SqlState = SqlState(Inner::E58030); /// 58P01 - pub const UNDEFINED_FILE: SqlState = SqlState(Cow::Borrowed("58P01")); + pub const UNDEFINED_FILE: SqlState = SqlState(Inner::E58P01); /// 58P02 - pub const DUPLICATE_FILE: SqlState = SqlState(Cow::Borrowed("58P02")); + pub const DUPLICATE_FILE: SqlState = SqlState(Inner::E58P02); /// 72000 - pub const SNAPSHOT_TOO_OLD: SqlState = SqlState(Cow::Borrowed("72000")); + pub const SNAPSHOT_TOO_OLD: SqlState = SqlState(Inner::E72000); /// F0000 - pub const CONFIG_FILE_ERROR: SqlState = SqlState(Cow::Borrowed("F0000")); + pub const CONFIG_FILE_ERROR: SqlState = SqlState(Inner::EF0000); /// F0001 - pub const LOCK_FILE_EXISTS: SqlState = SqlState(Cow::Borrowed("F0001")); + pub const LOCK_FILE_EXISTS: SqlState = SqlState(Inner::EF0001); /// HV000 - pub const FDW_ERROR: SqlState = SqlState(Cow::Borrowed("HV000")); + pub const FDW_ERROR: SqlState = SqlState(Inner::EHV000); /// HV005 - pub const FDW_COLUMN_NAME_NOT_FOUND: SqlState = SqlState(Cow::Borrowed("HV005")); + pub const FDW_COLUMN_NAME_NOT_FOUND: SqlState = SqlState(Inner::EHV005); /// HV002 - pub const FDW_DYNAMIC_PARAMETER_VALUE_NEEDED: SqlState = SqlState(Cow::Borrowed("HV002")); + pub const FDW_DYNAMIC_PARAMETER_VALUE_NEEDED: SqlState = SqlState(Inner::EHV002); /// HV010 - pub const FDW_FUNCTION_SEQUENCE_ERROR: SqlState = SqlState(Cow::Borrowed("HV010")); + pub const FDW_FUNCTION_SEQUENCE_ERROR: SqlState = SqlState(Inner::EHV010); /// HV021 - pub const FDW_INCONSISTENT_DESCRIPTOR_INFORMATION: SqlState = SqlState(Cow::Borrowed("HV021")); + pub const FDW_INCONSISTENT_DESCRIPTOR_INFORMATION: SqlState = SqlState(Inner::EHV021); /// HV024 - pub const FDW_INVALID_ATTRIBUTE_VALUE: SqlState = SqlState(Cow::Borrowed("HV024")); + pub const FDW_INVALID_ATTRIBUTE_VALUE: SqlState = SqlState(Inner::EHV024); /// HV007 - pub const FDW_INVALID_COLUMN_NAME: SqlState = SqlState(Cow::Borrowed("HV007")); + pub const FDW_INVALID_COLUMN_NAME: SqlState = SqlState(Inner::EHV007); /// HV008 - pub const FDW_INVALID_COLUMN_NUMBER: SqlState = SqlState(Cow::Borrowed("HV008")); + pub const FDW_INVALID_COLUMN_NUMBER: SqlState = SqlState(Inner::EHV008); /// HV004 - pub const FDW_INVALID_DATA_TYPE: SqlState = SqlState(Cow::Borrowed("HV004")); + pub const FDW_INVALID_DATA_TYPE: SqlState = SqlState(Inner::EHV004); /// HV006 - pub const FDW_INVALID_DATA_TYPE_DESCRIPTORS: SqlState = SqlState(Cow::Borrowed("HV006")); + pub const FDW_INVALID_DATA_TYPE_DESCRIPTORS: SqlState = SqlState(Inner::EHV006); /// HV091 - pub const FDW_INVALID_DESCRIPTOR_FIELD_IDENTIFIER: SqlState = SqlState(Cow::Borrowed("HV091")); + pub const FDW_INVALID_DESCRIPTOR_FIELD_IDENTIFIER: SqlState = SqlState(Inner::EHV091); /// HV00B - pub const FDW_INVALID_HANDLE: SqlState = SqlState(Cow::Borrowed("HV00B")); + pub const FDW_INVALID_HANDLE: SqlState = SqlState(Inner::EHV00B); /// HV00C - pub const FDW_INVALID_OPTION_INDEX: SqlState = SqlState(Cow::Borrowed("HV00C")); + pub const FDW_INVALID_OPTION_INDEX: SqlState = SqlState(Inner::EHV00C); /// HV00D - pub const FDW_INVALID_OPTION_NAME: SqlState = SqlState(Cow::Borrowed("HV00D")); + pub const FDW_INVALID_OPTION_NAME: SqlState = SqlState(Inner::EHV00D); /// 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(Inner::EHV090); /// HV00A - pub const FDW_INVALID_STRING_FORMAT: SqlState = SqlState(Cow::Borrowed("HV00A")); + pub const FDW_INVALID_STRING_FORMAT: SqlState = SqlState(Inner::EHV00A); /// HV009 - pub const FDW_INVALID_USE_OF_NULL_POINTER: SqlState = SqlState(Cow::Borrowed("HV009")); + pub const FDW_INVALID_USE_OF_NULL_POINTER: SqlState = SqlState(Inner::EHV009); /// HV014 - pub const FDW_TOO_MANY_HANDLES: SqlState = SqlState(Cow::Borrowed("HV014")); + pub const FDW_TOO_MANY_HANDLES: SqlState = SqlState(Inner::EHV014); /// HV001 - pub const FDW_OUT_OF_MEMORY: SqlState = SqlState(Cow::Borrowed("HV001")); + pub const FDW_OUT_OF_MEMORY: SqlState = SqlState(Inner::EHV001); /// HV00P - pub const FDW_NO_SCHEMAS: SqlState = SqlState(Cow::Borrowed("HV00P")); + pub const FDW_NO_SCHEMAS: SqlState = SqlState(Inner::EHV00P); /// HV00J - pub const FDW_OPTION_NAME_NOT_FOUND: SqlState = SqlState(Cow::Borrowed("HV00J")); + pub const FDW_OPTION_NAME_NOT_FOUND: SqlState = SqlState(Inner::EHV00J); /// HV00K - pub const FDW_REPLY_HANDLE: SqlState = SqlState(Cow::Borrowed("HV00K")); + pub const FDW_REPLY_HANDLE: SqlState = SqlState(Inner::EHV00K); /// HV00Q - pub const FDW_SCHEMA_NOT_FOUND: SqlState = SqlState(Cow::Borrowed("HV00Q")); + pub const FDW_SCHEMA_NOT_FOUND: SqlState = SqlState(Inner::EHV00Q); /// HV00R - pub const FDW_TABLE_NOT_FOUND: SqlState = SqlState(Cow::Borrowed("HV00R")); + pub const FDW_TABLE_NOT_FOUND: SqlState = SqlState(Inner::EHV00R); /// HV00L - pub const FDW_UNABLE_TO_CREATE_EXECUTION: SqlState = SqlState(Cow::Borrowed("HV00L")); + pub const FDW_UNABLE_TO_CREATE_EXECUTION: SqlState = SqlState(Inner::EHV00L); /// HV00M - pub const FDW_UNABLE_TO_CREATE_REPLY: SqlState = SqlState(Cow::Borrowed("HV00M")); + pub const FDW_UNABLE_TO_CREATE_REPLY: SqlState = SqlState(Inner::EHV00M); /// HV00N - pub const FDW_UNABLE_TO_ESTABLISH_CONNECTION: SqlState = SqlState(Cow::Borrowed("HV00N")); + pub const FDW_UNABLE_TO_ESTABLISH_CONNECTION: SqlState = SqlState(Inner::EHV00N); /// P0000 - pub const PLPGSQL_ERROR: SqlState = SqlState(Cow::Borrowed("P0000")); + pub const PLPGSQL_ERROR: SqlState = SqlState(Inner::EP0000); /// P0001 - pub const RAISE_EXCEPTION: SqlState = SqlState(Cow::Borrowed("P0001")); + pub const RAISE_EXCEPTION: SqlState = SqlState(Inner::EP0001); /// P0002 - pub const NO_DATA_FOUND: SqlState = SqlState(Cow::Borrowed("P0002")); + pub const NO_DATA_FOUND: SqlState = SqlState(Inner::EP0002); /// P0003 - pub const TOO_MANY_ROWS: SqlState = SqlState(Cow::Borrowed("P0003")); + pub const TOO_MANY_ROWS: SqlState = SqlState(Inner::EP0003); /// P0004 - pub const ASSERT_FAILURE: SqlState = SqlState(Cow::Borrowed("P0004")); + pub const ASSERT_FAILURE: SqlState = SqlState(Inner::EP0004); /// XX000 - pub const INTERNAL_ERROR: SqlState = SqlState(Cow::Borrowed("XX000")); + pub const INTERNAL_ERROR: SqlState = SqlState(Inner::EXX000); /// XX001 - pub const DATA_CORRUPTED: SqlState = SqlState(Cow::Borrowed("XX001")); + pub const DATA_CORRUPTED: SqlState = SqlState(Inner::EXX001); /// XX002 - pub const INDEX_CORRUPTED: SqlState = SqlState(Cow::Borrowed("XX002")); + pub const INDEX_CORRUPTED: SqlState = SqlState(Inner::EXX002); } + +#[derive(PartialEq, Eq, Clone, Debug)] +enum Inner { + E00000, + E01000, + E0100C, + E01008, + E01003, + E01007, + E01006, + E01004, + E01P01, + E02000, + E02001, + E03000, + E08000, + E08003, + E08006, + E08001, + E08004, + E08007, + E08P01, + E09000, + E0A000, + E0B000, + E0F000, + E0F001, + E0L000, + E0LP01, + E0P000, + E0Z000, + E0Z002, + E20000, + E21000, + E22000, + E2202E, + E22021, + E22008, + E22012, + E22005, + E2200B, + E22022, + E22015, + E2201E, + E22014, + E22016, + E2201F, + E2201G, + E22018, + E22007, + E22019, + E2200D, + E22025, + E22P06, + E22010, + E22023, + E22013, + E2201B, + E2201W, + E2201X, + E2202H, + E2202G, + E22009, + E2200C, + E2200G, + E22004, + E22002, + E22003, + E2200H, + E22026, + E22001, + E22011, + E22027, + E22024, + E2200F, + E22P01, + E22P02, + E22P03, + E22P04, + E22P05, + E2200L, + E2200M, + E2200N, + E2200S, + E2200T, + E22030, + E22031, + E22032, + E22033, + E22034, + E22035, + E22036, + E22037, + E22038, + E22039, + E2203A, + E2203B, + E2203C, + E2203D, + E2203E, + E2203F, + E23000, + E23001, + E23502, + E23503, + E23505, + E23514, + E23P01, + E24000, + E25000, + E25001, + E25002, + E25008, + E25003, + E25004, + E25005, + E25006, + E25007, + E25P01, + E25P02, + E25P03, + E26000, + E27000, + E28000, + E28P01, + E2B000, + E2BP01, + E2D000, + E2F000, + E2F005, + E2F002, + E2F003, + E2F004, + E34000, + E38000, + E38001, + E38002, + E38003, + E38004, + E39000, + E39001, + E39004, + E39P01, + E39P02, + E39P03, + E3B000, + E3B001, + E3D000, + E3F000, + E40000, + E40002, + E40001, + E40003, + E40P01, + E42000, + E42601, + E42501, + E42846, + E42803, + E42P20, + E42P19, + E42830, + E42602, + E42622, + E42939, + E42804, + E42P18, + E42P21, + E42P22, + E42809, + E428C9, + E42703, + E42883, + E42P01, + E42P02, + E42704, + E42701, + E42P03, + E42P04, + E42723, + E42P05, + E42P06, + E42P07, + E42712, + E42710, + E42702, + E42725, + E42P08, + E42P09, + E42P10, + E42611, + E42P11, + E42P12, + E42P13, + E42P14, + E42P15, + E42P16, + E42P17, + E44000, + E53000, + E53100, + E53200, + E53300, + E53400, + E54000, + E54001, + E54011, + E54023, + E55000, + E55006, + E55P02, + E55P03, + E55P04, + E57000, + E57014, + E57P01, + E57P02, + E57P03, + E57P04, + E58000, + E58030, + E58P01, + E58P02, + E72000, + EF0000, + EF0001, + EHV000, + EHV005, + EHV002, + EHV010, + EHV021, + EHV024, + EHV007, + EHV008, + EHV004, + EHV006, + EHV091, + EHV00B, + EHV00C, + EHV00D, + EHV090, + EHV00A, + EHV009, + EHV014, + EHV001, + EHV00P, + EHV00J, + EHV00K, + EHV00Q, + EHV00R, + EHV00L, + EHV00M, + EHV00N, + EP0000, + EP0001, + EP0002, + EP0003, + EP0004, + EXX000, + EXX001, + EXX002, + Other(Box), +} + #[rustfmt::skip] static SQLSTATE_MAP: phf::Map<&'static str, SqlState> = ::phf::Map { From 91ce9cdeec624511f79b39debfcf12bdac62178e Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Sat, 24 Apr 2021 10:34:51 -0400 Subject: [PATCH 02/59] fix clippy --- codegen/src/sqlstate.rs | 1 + tokio-postgres/src/error/sqlstate.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/codegen/src/sqlstate.rs b/codegen/src/sqlstate.rs index ea3045654..d21b92eec 100644 --- a/codegen/src/sqlstate.rs +++ b/codegen/src/sqlstate.rs @@ -113,6 +113,7 @@ fn make_inner(codes: &LinkedHashMap>, file: &mut BufWriter Date: Sun, 25 Apr 2021 10:52:25 -0400 Subject: [PATCH 03/59] Release v0.7.2 --- tokio-postgres/CHANGELOG.md | 8 +++++++- tokio-postgres/Cargo.toml | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/tokio-postgres/CHANGELOG.md b/tokio-postgres/CHANGELOG.md index 7cc6c7071..3a7aa2ae7 100644 --- a/tokio-postgres/CHANGELOG.md +++ b/tokio-postgres/CHANGELOG.md @@ -1,6 +1,12 @@ # Change Log -## v0.7.1 - 2020-04-03 +## v0.7.2 - 2021-04-25 + +### Fixed + +* `SqlState` constants can now be used in `match` patterns. + +## v0.7.1 - 2021-04-03 ### Added diff --git a/tokio-postgres/Cargo.toml b/tokio-postgres/Cargo.toml index b1d093d4b..780c31963 100644 --- a/tokio-postgres/Cargo.toml +++ b/tokio-postgres/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tokio-postgres" -version = "0.7.1" +version = "0.7.2" authors = ["Steven Fackler "] edition = "2018" license = "MIT/Apache-2.0" From 20f0d76459a20b934c9863c7638bd94f4fee506f Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 29 Apr 2021 20:58:01 +0000 Subject: [PATCH 04/59] Upgrade to GitHub-native Dependabot --- .github/dependabot.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 000000000..a64a91b02 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,12 @@ +version: 2 +updates: +- package-ecosystem: cargo + directory: "/" + schedule: + interval: daily + time: "13:00" + open-pull-requests-limit: 10 + ignore: + - dependency-name: socket2 + versions: + - 0.4.0 From 0f0de8c34d3858e188079060b75dd818ae469115 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Thu, 29 Apr 2021 17:00:22 -0400 Subject: [PATCH 05/59] Update dependabot.yml --- .github/dependabot.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index a64a91b02..1332f8eb5 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -6,7 +6,3 @@ updates: interval: daily time: "13:00" open-pull-requests-limit: 10 - ignore: - - dependency-name: socket2 - versions: - - 0.4.0 From 83616fadb5c0b88b34d1f83478ac6d46546d2b31 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 29 Apr 2021 21:02:13 +0000 Subject: [PATCH 06/59] Update hmac requirement from 0.10 to 0.11 Updates the requirements on [hmac](https://github.com/RustCrypto/MACs) to permit the latest version. - [Release notes](https://github.com/RustCrypto/MACs/releases) - [Commits](https://github.com/RustCrypto/MACs/compare/hmac-v0.10.0...hmac-v0.11.0) Signed-off-by: dependabot[bot] --- postgres-protocol/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/postgres-protocol/Cargo.toml b/postgres-protocol/Cargo.toml index 4fd288697..d4ae8c301 100644 --- a/postgres-protocol/Cargo.toml +++ b/postgres-protocol/Cargo.toml @@ -13,7 +13,7 @@ base64 = "0.13" byteorder = "1.0" bytes = "1.0" fallible-iterator = "0.2" -hmac = "0.10" +hmac = "0.11" md-5 = "0.9" memchr = "2.0" rand = "0.8" From 4e8b9078a194c6b65bdff6882a76b8361a53a02e Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Thu, 29 Apr 2021 17:07:24 -0400 Subject: [PATCH 07/59] fix build --- postgres-protocol/src/authentication/sasl.rs | 17 +++++++++-------- postgres-protocol/src/password/mod.rs | 8 ++++---- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/postgres-protocol/src/authentication/sasl.rs b/postgres-protocol/src/authentication/sasl.rs index 7c0d1754f..a3704ce16 100644 --- a/postgres-protocol/src/authentication/sasl.rs +++ b/postgres-protocol/src/authentication/sasl.rs @@ -33,7 +33,8 @@ fn normalize(pass: &[u8]) -> Vec { } pub(crate) fn hi(str: &[u8], salt: &[u8], i: u32) -> [u8; 32] { - let mut hmac = Hmac::::new_varkey(str).expect("HMAC is able to accept all key sizes"); + let mut hmac = + Hmac::::new_from_slice(str).expect("HMAC is able to accept all key sizes"); hmac.update(salt); hmac.update(&[0, 0, 0, 1]); let mut prev = hmac.finalize().into_bytes(); @@ -41,7 +42,7 @@ pub(crate) fn hi(str: &[u8], salt: &[u8], i: u32) -> [u8; 32] { let mut hi = prev; for _ in 1..i { - let mut hmac = Hmac::::new_varkey(str).expect("already checked above"); + let mut hmac = Hmac::::new_from_slice(str).expect("already checked above"); hmac.update(&prev); prev = hmac.finalize().into_bytes(); @@ -195,7 +196,7 @@ impl ScramSha256 { let salted_password = hi(&password, &salt, parsed.iteration_count); - let mut hmac = Hmac::::new_varkey(&salted_password) + let mut hmac = Hmac::::new_from_slice(&salted_password) .expect("HMAC is able to accept all key sizes"); hmac.update(b"Client Key"); let client_key = hmac.finalize().into_bytes(); @@ -214,8 +215,8 @@ impl ScramSha256 { let auth_message = format!("n=,r={},{},{}", client_nonce, message, self.message); - let mut hmac = - Hmac::::new_varkey(&stored_key).expect("HMAC is able to accept all key sizes"); + let mut hmac = Hmac::::new_from_slice(&stored_key) + .expect("HMAC is able to accept all key sizes"); hmac.update(auth_message.as_bytes()); let client_signature = hmac.finalize().into_bytes(); @@ -266,13 +267,13 @@ impl ScramSha256 { Err(e) => return Err(io::Error::new(io::ErrorKind::InvalidInput, e)), }; - let mut hmac = Hmac::::new_varkey(&salted_password) + let mut hmac = Hmac::::new_from_slice(&salted_password) .expect("HMAC is able to accept all key sizes"); hmac.update(b"Server Key"); let server_key = hmac.finalize().into_bytes(); - let mut hmac = - Hmac::::new_varkey(&server_key).expect("HMAC is able to accept all key sizes"); + let mut hmac = Hmac::::new_from_slice(&server_key) + .expect("HMAC is able to accept all key sizes"); hmac.update(auth_message.as_bytes()); hmac.verify(&verifier) .map_err(|_| io::Error::new(io::ErrorKind::InvalidInput, "SCRAM verification error")) diff --git a/postgres-protocol/src/password/mod.rs b/postgres-protocol/src/password/mod.rs index ccb95c79b..1b32ae8f8 100644 --- a/postgres-protocol/src/password/mod.rs +++ b/postgres-protocol/src/password/mod.rs @@ -61,8 +61,8 @@ pub(crate) fn scram_sha_256_salt(password: &[u8], salt: [u8; SCRAM_DEFAULT_SALT_ let salted_password = sasl::hi(&prepared, &salt, SCRAM_DEFAULT_ITERATIONS); // client key - let mut hmac = - Hmac::::new_varkey(&salted_password).expect("HMAC is able to accept all key sizes"); + let mut hmac = Hmac::::new_from_slice(&salted_password) + .expect("HMAC is able to accept all key sizes"); hmac.update(b"Client Key"); let client_key = hmac.finalize().into_bytes(); @@ -72,8 +72,8 @@ pub(crate) fn scram_sha_256_salt(password: &[u8], salt: [u8; SCRAM_DEFAULT_SALT_ let stored_key = hash.finalize_fixed(); // server key - let mut hmac = - Hmac::::new_varkey(&salted_password).expect("HMAC is able to accept all key sizes"); + let mut hmac = Hmac::::new_from_slice(&salted_password) + .expect("HMAC is able to accept all key sizes"); hmac.update(b"Server Key"); let server_key = hmac.finalize().into_bytes(); From a84a45d88ed157c8756d5e54b2b13467721e5d12 Mon Sep 17 00:00:00 2001 From: Erik Johnston Date: Fri, 14 May 2021 14:59:07 +0100 Subject: [PATCH 08/59] Fix deadlock when pipelining statements. When executing statements in parallel there is a race where we prepare the type info queries multiple times, and so insert into the type info caches multiple times. This resulted in any existing cached `Statement` to be dropped, running its destructor which attempts to take out the state lock that is already being held, resulting in a deadlock. Fixes #772. --- tokio-postgres/src/client.rs | 45 +++++++++++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 3 deletions(-) diff --git a/tokio-postgres/src/client.rs b/tokio-postgres/src/client.rs index f19005e55..b417c1396 100644 --- a/tokio-postgres/src/client.rs +++ b/tokio-postgres/src/client.rs @@ -55,8 +55,17 @@ impl Responses { } struct State { + /// A cached prepared statement for basic information for a type from its + /// OID. Corresponds to [TYPEINFO_QUERY](prepare::TYPEINFO_QUERY) (or its + /// fallback). typeinfo: Option, + /// A cached prepared statement for getting information for a composite type + /// from its OID. Corresponds to + /// [TYPEINFO_QUERY](prepare::TYPEINFO_COMPOSITE_QUERY). typeinfo_composite: Option, + /// A cached prepared statement for getting information for a composite type + /// from its OID. Corresponds to + /// [TYPEINFO_QUERY](prepare::TYPEINFO_COMPOSITE_QUERY) (or its fallback). typeinfo_enum: Option, types: HashMap, buf: BytesMut, @@ -86,7 +95,17 @@ impl InnerClient { } pub fn set_typeinfo(&self, statement: &Statement) { - self.state.lock().typeinfo = Some(statement.clone()); + // We only insert the statement if there isn't already a cached + // statement (this is safe as they are prepared statements for the same + // query). + // + // Note: We need to be sure that we don't drop a Statement while holding + // the state lock as its drop handling will call `with_buf`, which tries + // to take the lock. + let mut state = self.state.lock(); + if state.typeinfo.is_none() { + state.typeinfo = Some(statement.clone()); + } } pub fn typeinfo_composite(&self) -> Option { @@ -94,7 +113,17 @@ impl InnerClient { } pub fn set_typeinfo_composite(&self, statement: &Statement) { - self.state.lock().typeinfo_composite = Some(statement.clone()); + // We only insert the statement if there isn't already a cached + // statement (this is safe as they are prepared statements for the same + // query). + // + // Note: We need to be sure that we don't drop a Statement while holding + // the state lock as its drop handling will call `with_buf`, which tries + // to take the lock. + let mut state = self.state.lock(); + if state.typeinfo_composite.is_none() { + state.typeinfo_composite = Some(statement.clone()); + } } pub fn typeinfo_enum(&self) -> Option { @@ -102,7 +131,17 @@ impl InnerClient { } pub fn set_typeinfo_enum(&self, statement: &Statement) { - self.state.lock().typeinfo_enum = Some(statement.clone()); + // We only insert the statement if there isn't already a cached + // statement (this is safe as they are prepared statements for the same + // query). + // + // Note: We need to be sure that we don't drop a Statement while holding + // the state lock as its drop handling will call `with_buf`, which tries + // to take the lock. + let mut state = self.state.lock(); + if state.typeinfo_enum.is_none() { + state.typeinfo_enum = Some(statement.clone()); + } } pub fn type_(&self, oid: Oid) -> Option { From b7215c60d9584a8fd4245cc85ccce8aba998637d Mon Sep 17 00:00:00 2001 From: Erik Johnston Date: Fri, 14 May 2021 15:20:36 +0100 Subject: [PATCH 09/59] Split State into two. There is no reason for the buffer and typeinfo caches to share the same lock. By splitting them it means we a) get slightly better performance, but more importantly b) it makes it harder to accidentally deadlock. --- tokio-postgres/src/client.rs | 81 +++++++++++++++++------------------- 1 file changed, 38 insertions(+), 43 deletions(-) diff --git a/tokio-postgres/src/client.rs b/tokio-postgres/src/client.rs index b417c1396..4e8babf1d 100644 --- a/tokio-postgres/src/client.rs +++ b/tokio-postgres/src/client.rs @@ -54,26 +54,32 @@ impl Responses { } } -struct State { - /// A cached prepared statement for basic information for a type from its +/// A cache of type info and prepared statements for fetching type info +/// (corresponding to the queries in the [prepare](prepare) module). +#[derive(Default)] +struct CachedTypeInfo { + /// A statement for basic information for a type from its /// OID. Corresponds to [TYPEINFO_QUERY](prepare::TYPEINFO_QUERY) (or its /// fallback). typeinfo: Option, - /// A cached prepared statement for getting information for a composite type - /// from its OID. Corresponds to - /// [TYPEINFO_QUERY](prepare::TYPEINFO_COMPOSITE_QUERY). + /// A statement for getting information for a composite type from its OID. + /// Corresponds to [TYPEINFO_QUERY](prepare::TYPEINFO_COMPOSITE_QUERY). typeinfo_composite: Option, - /// A cached prepared statement for getting information for a composite type - /// from its OID. Corresponds to - /// [TYPEINFO_QUERY](prepare::TYPEINFO_COMPOSITE_QUERY) (or its fallback). + /// A statement for getting information for a composite type from its OID. + /// Corresponds to [TYPEINFO_QUERY](prepare::TYPEINFO_COMPOSITE_QUERY) (or + /// its fallback). typeinfo_enum: Option, + + /// Cache of types already looked up. types: HashMap, - buf: BytesMut, } pub struct InnerClient { sender: mpsc::UnboundedSender, - state: Mutex, + cached_typeinfo: Mutex, + + /// A buffer to use when writing out postgres commands. + buffer: Mutex, } impl InnerClient { @@ -91,7 +97,7 @@ impl InnerClient { } pub fn typeinfo(&self) -> Option { - self.state.lock().typeinfo.clone() + self.cached_typeinfo.lock().typeinfo.clone() } pub fn set_typeinfo(&self, statement: &Statement) { @@ -102,67 +108,61 @@ impl InnerClient { // Note: We need to be sure that we don't drop a Statement while holding // the state lock as its drop handling will call `with_buf`, which tries // to take the lock. - let mut state = self.state.lock(); - if state.typeinfo.is_none() { - state.typeinfo = Some(statement.clone()); + let mut cache = self.cached_typeinfo.lock(); + if cache.typeinfo.is_none() { + cache.typeinfo = Some(statement.clone()); } } pub fn typeinfo_composite(&self) -> Option { - self.state.lock().typeinfo_composite.clone() + self.cached_typeinfo.lock().typeinfo_composite.clone() } pub fn set_typeinfo_composite(&self, statement: &Statement) { // We only insert the statement if there isn't already a cached // statement (this is safe as they are prepared statements for the same // query). - // - // Note: We need to be sure that we don't drop a Statement while holding - // the state lock as its drop handling will call `with_buf`, which tries - // to take the lock. - let mut state = self.state.lock(); - if state.typeinfo_composite.is_none() { - state.typeinfo_composite = Some(statement.clone()); + let mut cache = self.cached_typeinfo.lock(); + if cache.typeinfo_composite.is_none() { + cache.typeinfo_composite = Some(statement.clone()); } } pub fn typeinfo_enum(&self) -> Option { - self.state.lock().typeinfo_enum.clone() + self.cached_typeinfo.lock().typeinfo_enum.clone() } pub fn set_typeinfo_enum(&self, statement: &Statement) { // We only insert the statement if there isn't already a cached // statement (this is safe as they are prepared statements for the same // query). - // - // Note: We need to be sure that we don't drop a Statement while holding - // the state lock as its drop handling will call `with_buf`, which tries - // to take the lock. - let mut state = self.state.lock(); - if state.typeinfo_enum.is_none() { - state.typeinfo_enum = Some(statement.clone()); + let mut cache = self.cached_typeinfo.lock(); + if cache.typeinfo_enum.is_none() { + cache.typeinfo_enum = Some(statement.clone()); } } pub fn type_(&self, oid: Oid) -> Option { - self.state.lock().types.get(&oid).cloned() + self.cached_typeinfo.lock().types.get(&oid).cloned() } pub fn set_type(&self, oid: Oid, type_: &Type) { - self.state.lock().types.insert(oid, type_.clone()); + self.cached_typeinfo.lock().types.insert(oid, type_.clone()); } pub fn clear_type_cache(&self) { - self.state.lock().types.clear(); + self.cached_typeinfo.lock().types.clear(); } + /// Call the given function with a buffer to be used when writing out + /// postgres commands. pub fn with_buf(&self, f: F) -> R where F: FnOnce(&mut BytesMut) -> R, { - let mut state = self.state.lock(); - let r = f(&mut state.buf); - state.buf.clear(); + let mut buffer = self.buffer.lock(); + let r = f(&mut buffer); + buffer.clear(); r } } @@ -199,13 +199,8 @@ impl Client { Client { inner: Arc::new(InnerClient { sender, - state: Mutex::new(State { - typeinfo: None, - typeinfo_composite: None, - typeinfo_enum: None, - types: HashMap::new(), - buf: BytesMut::new(), - }), + cached_typeinfo: Default::default(), + buffer: Default::default(), }), #[cfg(feature = "runtime")] socket_config: None, From 844a1bd145c0099ea1a31de145a6ecc8fc2a699b Mon Sep 17 00:00:00 2001 From: Erik Johnston Date: Sat, 15 May 2021 10:25:14 +0100 Subject: [PATCH 10/59] Revert change back to always setting the cached statement --- tokio-postgres/src/client.rs | 28 +++------------------------- 1 file changed, 3 insertions(+), 25 deletions(-) diff --git a/tokio-postgres/src/client.rs b/tokio-postgres/src/client.rs index 4e8babf1d..4a099d941 100644 --- a/tokio-postgres/src/client.rs +++ b/tokio-postgres/src/client.rs @@ -101,17 +101,7 @@ impl InnerClient { } pub fn set_typeinfo(&self, statement: &Statement) { - // We only insert the statement if there isn't already a cached - // statement (this is safe as they are prepared statements for the same - // query). - // - // Note: We need to be sure that we don't drop a Statement while holding - // the state lock as its drop handling will call `with_buf`, which tries - // to take the lock. - let mut cache = self.cached_typeinfo.lock(); - if cache.typeinfo.is_none() { - cache.typeinfo = Some(statement.clone()); - } + self.cached_typeinfo.lock().typeinfo = Some(statement.clone()); } pub fn typeinfo_composite(&self) -> Option { @@ -119,13 +109,7 @@ impl InnerClient { } pub fn set_typeinfo_composite(&self, statement: &Statement) { - // We only insert the statement if there isn't already a cached - // statement (this is safe as they are prepared statements for the same - // query). - let mut cache = self.cached_typeinfo.lock(); - if cache.typeinfo_composite.is_none() { - cache.typeinfo_composite = Some(statement.clone()); - } + self.cached_typeinfo.lock().typeinfo_composite = Some(statement.clone()); } pub fn typeinfo_enum(&self) -> Option { @@ -133,13 +117,7 @@ impl InnerClient { } pub fn set_typeinfo_enum(&self, statement: &Statement) { - // We only insert the statement if there isn't already a cached - // statement (this is safe as they are prepared statements for the same - // query). - let mut cache = self.cached_typeinfo.lock(); - if cache.typeinfo_enum.is_none() { - cache.typeinfo_enum = Some(statement.clone()); - } + self.cached_typeinfo.lock().typeinfo_enum = Some(statement.clone()); } pub fn type_(&self, oid: Oid) -> Option { From 52de2693670ee4b1a6d571f176ea4dd44117db43 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Tue, 18 May 2021 20:47:26 -0400 Subject: [PATCH 11/59] fix clippy --- postgres-protocol/src/message/backend.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/postgres-protocol/src/message/backend.rs b/postgres-protocol/src/message/backend.rs index 68b5aa6e5..45e5c4074 100644 --- a/postgres-protocol/src/message/backend.rs +++ b/postgres-protocol/src/message/backend.rs @@ -450,9 +450,9 @@ impl CopyDataBody { } pub struct CopyInResponseBody { - storage: Bytes, - len: u16, format: u8, + len: u16, + storage: Bytes, } impl CopyInResponseBody { @@ -504,9 +504,9 @@ impl<'a> FallibleIterator for ColumnFormats<'a> { } pub struct CopyOutResponseBody { - storage: Bytes, - len: u16, format: u8, + len: u16, + storage: Bytes, } impl CopyOutResponseBody { From ca6d4b816221214798bc68f2b182f9fa822e115f Mon Sep 17 00:00:00 2001 From: Petros Angelatos Date: Mon, 24 May 2021 17:54:24 +0200 Subject: [PATCH 12/59] tokio-postgres: buffer sockets to avoid excessive syscalls The current implementation forwards all read requests to the operating system through the socket causing excessive system calls. The effect is magnified when the underlying Socket is wrapped around a TLS implementation. This commit changes the underlying socket to be read-buffered by default with a buffer size of 16K, following the implementation of the official client. Signed-off-by: Petros Angelatos --- postgres-native-tls/src/lib.rs | 5 +++-- postgres-openssl/src/lib.rs | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/postgres-native-tls/src/lib.rs b/postgres-native-tls/src/lib.rs index 70e34812d..2f2e6e6ad 100644 --- a/postgres-native-tls/src/lib.rs +++ b/postgres-native-tls/src/lib.rs @@ -51,7 +51,7 @@ use std::future::Future; use std::io; use std::pin::Pin; use std::task::{Context, Poll}; -use tokio::io::{AsyncRead, AsyncWrite, ReadBuf}; +use tokio::io::{AsyncRead, AsyncWrite, BufReader, ReadBuf}; use tokio_postgres::tls; #[cfg(feature = "runtime")] use tokio_postgres::tls::MakeTlsConnect; @@ -115,6 +115,7 @@ where type Future = Pin, native_tls::Error>> + Send>>; fn connect(self, stream: S) -> Self::Future { + let stream = BufReader::with_capacity(8192, stream); let future = async move { let stream = self.connector.connect(&self.domain, stream).await?; @@ -126,7 +127,7 @@ where } /// The stream returned by `TlsConnector`. -pub struct TlsStream(tokio_native_tls::TlsStream); +pub struct TlsStream(tokio_native_tls::TlsStream>); impl AsyncRead for TlsStream where diff --git a/postgres-openssl/src/lib.rs b/postgres-openssl/src/lib.rs index dce3dff5d..f3c0b9309 100644 --- a/postgres-openssl/src/lib.rs +++ b/postgres-openssl/src/lib.rs @@ -57,7 +57,7 @@ use std::pin::Pin; #[cfg(feature = "runtime")] use std::sync::Arc; use std::task::{Context, Poll}; -use tokio::io::{AsyncRead, AsyncWrite, ReadBuf}; +use tokio::io::{AsyncRead, AsyncWrite, BufReader, ReadBuf}; use tokio_openssl::SslStream; use tokio_postgres::tls; #[cfg(feature = "runtime")] @@ -140,6 +140,7 @@ where type Future = Pin, Self::Error>> + Send>>; fn connect(self, stream: S) -> Self::Future { + let stream = BufReader::with_capacity(8192, stream); let future = async move { let ssl = self.ssl.into_ssl(&self.domain)?; let mut stream = SslStream::new(ssl, stream)?; @@ -182,7 +183,7 @@ impl Error for ConnectError { } /// The stream returned by `TlsConnector`. -pub struct TlsStream(SslStream); +pub struct TlsStream(SslStream>); impl AsyncRead for TlsStream where From b03ffcd043722ec74d1075514bf9ad8e061954b8 Mon Sep 17 00:00:00 2001 From: Marcin Pajkowski Date: Sat, 29 May 2021 23:43:22 +0200 Subject: [PATCH 13/59] expose SimpleQueryRow's column names --- tokio-postgres/src/row.rs | 19 +++++++++++++++++-- tokio-postgres/src/simple_query.rs | 21 +++++++++++++++++++-- tokio-postgres/tests/test/main.rs | 4 ++++ 3 files changed, 40 insertions(+), 4 deletions(-) diff --git a/tokio-postgres/src/row.rs b/tokio-postgres/src/row.rs index 842216ad2..e3ed696c1 100644 --- a/tokio-postgres/src/row.rs +++ b/tokio-postgres/src/row.rs @@ -1,6 +1,7 @@ //! Rows. use crate::row::sealed::{AsName, Sealed}; +use crate::simple_query::SimpleColumn; use crate::statement::Column; use crate::types::{FromSql, Type, WrongType}; use crate::{Error, Statement}; @@ -188,16 +189,25 @@ impl Row { } } +impl AsName for SimpleColumn { + fn as_name(&self) -> &str { + self.name() + } +} + /// A row of data returned from the database by a simple query. pub struct SimpleQueryRow { - columns: Arc<[String]>, + columns: Arc<[SimpleColumn]>, body: DataRowBody, ranges: Vec>>, } impl SimpleQueryRow { #[allow(clippy::new_ret_no_self)] - pub(crate) fn new(columns: Arc<[String]>, body: DataRowBody) -> Result { + pub(crate) fn new( + columns: Arc<[SimpleColumn]>, + body: DataRowBody, + ) -> Result { let ranges = body.ranges().collect().map_err(Error::parse)?; Ok(SimpleQueryRow { columns, @@ -206,6 +216,11 @@ impl SimpleQueryRow { }) } + /// Returns information about the columns of data in the row. + pub fn columns(&self) -> &[SimpleColumn] { + &self.columns + } + /// Determines if the row contains no values. pub fn is_empty(&self) -> bool { self.len() == 0 diff --git a/tokio-postgres/src/simple_query.rs b/tokio-postgres/src/simple_query.rs index 82ac35664..ade2e1d6d 100644 --- a/tokio-postgres/src/simple_query.rs +++ b/tokio-postgres/src/simple_query.rs @@ -14,6 +14,22 @@ use std::pin::Pin; use std::sync::Arc; use std::task::{Context, Poll}; +/// Information about a column of a single query row. +pub struct SimpleColumn { + name: String, +} + +impl SimpleColumn { + pub(crate) fn new(name: String) -> SimpleColumn { + SimpleColumn { name } + } + + /// Returns the name of the column. + pub fn name(&self) -> &str { + &self.name + } +} + pub async fn simple_query(client: &InnerClient, query: &str) -> Result { debug!("executing simple query: {}", query); @@ -56,7 +72,7 @@ pin_project! { /// A stream of simple query results. pub struct SimpleQueryStream { responses: Responses, - columns: Option>, + columns: Option>, #[pin] _p: PhantomPinned, } @@ -86,10 +102,11 @@ impl Stream for SimpleQueryStream { Message::RowDescription(body) => { let columns = body .fields() - .map(|f| Ok(f.name().to_string())) + .map(|f| Ok(SimpleColumn::new(f.name().to_string()))) .collect::>() .map_err(Error::parse)? .into(); + *this.columns = Some(columns); } Message::DataRow(body) => { diff --git a/tokio-postgres/tests/test/main.rs b/tokio-postgres/tests/test/main.rs index c367dbea3..c0b4bf202 100644 --- a/tokio-postgres/tests/test/main.rs +++ b/tokio-postgres/tests/test/main.rs @@ -282,6 +282,8 @@ async fn simple_query() { } match &messages[2] { SimpleQueryMessage::Row(row) => { + assert_eq!(row.columns().get(0).map(|c| c.name()), Some("id")); + assert_eq!(row.columns().get(1).map(|c| c.name()), Some("name")); assert_eq!(row.get(0), Some("1")); assert_eq!(row.get(1), Some("steven")); } @@ -289,6 +291,8 @@ async fn simple_query() { } match &messages[3] { SimpleQueryMessage::Row(row) => { + assert_eq!(row.columns().get(0).map(|c| c.name()), Some("id")); + assert_eq!(row.columns().get(1).map(|c| c.name()), Some("name")); assert_eq!(row.get(0), Some("2")); assert_eq!(row.get(1), Some("joe")); } From a8383dcc2970d5720ee8097c48c1d4c507a24eab Mon Sep 17 00:00:00 2001 From: Tim Anderson Date: Thu, 3 Jun 2021 10:54:37 +1000 Subject: [PATCH 14/59] Add support for eui48 version 1.0 --- postgres-types/Cargo.toml | 2 ++ postgres-types/src/eui48_1.rs | 27 ++++++++++++++++++++++ postgres-types/src/lib.rs | 2 ++ postgres/Cargo.toml | 1 + postgres/src/lib.rs | 3 ++- tokio-postgres/Cargo.toml | 2 ++ tokio-postgres/src/lib.rs | 3 ++- tokio-postgres/tests/test/types/eui48_1.rs | 18 +++++++++++++++ tokio-postgres/tests/test/types/mod.rs | 2 ++ 9 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 postgres-types/src/eui48_1.rs create mode 100644 tokio-postgres/tests/test/types/eui48_1.rs diff --git a/postgres-types/Cargo.toml b/postgres-types/Cargo.toml index 1d7f2cc9a..b258cee12 100644 --- a/postgres-types/Cargo.toml +++ b/postgres-types/Cargo.toml @@ -15,6 +15,7 @@ derive = ["postgres-derive"] with-bit-vec-0_6 = ["bit-vec-06"] with-chrono-0_4 = ["chrono-04"] with-eui48-0_4 = ["eui48-04"] +with-eui48-1 = ["eui48-1"] with-geo-types-0_6 = ["geo-types-06"] with-geo-types-0_7 = ["geo-types-0_7"] with-serde_json-1 = ["serde-1", "serde_json-1"] @@ -30,6 +31,7 @@ postgres-derive = { version = "0.4.0", optional = true, path = "../postgres-deri bit-vec-06 = { version = "0.6", package = "bit-vec", optional = true } chrono-04 = { version = "0.4.16", package = "chrono", default-features = false, features = ["clock"], optional = true } eui48-04 = { version = "0.4", package = "eui48", optional = true } +eui48-1 = { version = "1.0", package = "eui48", optional = true } geo-types-06 = { version = "0.6", package = "geo-types", optional = true } geo-types-0_7 = { version = "0.7", package = "geo-types", optional = true } serde-1 = { version = "1.0", package = "serde", optional = true } diff --git a/postgres-types/src/eui48_1.rs b/postgres-types/src/eui48_1.rs new file mode 100644 index 000000000..4c35e63ce --- /dev/null +++ b/postgres-types/src/eui48_1.rs @@ -0,0 +1,27 @@ +use bytes::BytesMut; +use eui48_1::MacAddress; +use postgres_protocol::types; +use std::error::Error; + +use crate::{FromSql, IsNull, ToSql, Type}; + +impl<'a> FromSql<'a> for MacAddress { + fn from_sql(_: &Type, raw: &[u8]) -> Result> { + let bytes = types::macaddr_from_sql(raw)?; + Ok(MacAddress::new(bytes)) + } + + accepts!(MACADDR); +} + +impl ToSql for MacAddress { + fn to_sql(&self, _: &Type, w: &mut BytesMut) -> Result> { + let mut bytes = [0; 6]; + bytes.copy_from_slice(self.as_bytes()); + types::macaddr_to_sql(bytes, w); + Ok(IsNull::No) + } + + accepts!(MACADDR); + to_sql_checked!(); +} diff --git a/postgres-types/src/lib.rs b/postgres-types/src/lib.rs index 5c483bd76..ed6f75cf5 100644 --- a/postgres-types/src/lib.rs +++ b/postgres-types/src/lib.rs @@ -194,6 +194,8 @@ mod bit_vec_06; mod chrono_04; #[cfg(feature = "with-eui48-0_4")] mod eui48_04; +#[cfg(feature = "with-eui48-1")] +mod eui48_1; #[cfg(feature = "with-geo-types-0_6")] mod geo_types_06; #[cfg(feature = "with-geo-types-0_7")] diff --git a/postgres/Cargo.toml b/postgres/Cargo.toml index 18219782d..c7c0746f0 100644 --- a/postgres/Cargo.toml +++ b/postgres/Cargo.toml @@ -24,6 +24,7 @@ circle-ci = { repository = "sfackler/rust-postgres" } with-bit-vec-0_6 = ["tokio-postgres/with-bit-vec-0_6"] with-chrono-0_4 = ["tokio-postgres/with-chrono-0_4"] with-eui48-0_4 = ["tokio-postgres/with-eui48-0_4"] +with-eui48-1 = ["tokio-postgres/with-eui48-1"] with-geo-types-0_6 = ["tokio-postgres/with-geo-types-0_6"] with-geo-types-0_7 = ["tokio-postgres/with-geo-types-0_7"] with-serde_json-1 = ["tokio-postgres/with-serde_json-1"] diff --git a/postgres/src/lib.rs b/postgres/src/lib.rs index 4513aeef7..7d96bfd9f 100644 --- a/postgres/src/lib.rs +++ b/postgres/src/lib.rs @@ -55,7 +55,8 @@ //! | ------- | ----------- | ------------------ | ------- | //! | `with-bit-vec-0_6` | Enable support for the `bit-vec` crate. | [bit-vec](https://crates.io/crates/bit-vec) 0.6 | no | //! | `with-chrono-0_4` | Enable support for the `chrono` crate. | [chrono](https://crates.io/crates/chrono) 0.4 | no | -//! | `with-eui48-0_4` | Enable support for the `eui48` crate. | [eui48](https://crates.io/crates/eui48) 0.4 | no | +//! | `with-eui48-0_4` | Enable support for the 0.4 version of the `eui48` crate. | [eui48](https://crates.io/crates/eui48) 0.4 | no | +//! | `with-eui48-1` | Enable support for the 1.0 version of the `eui48` crate. | [eui48](https://crates.io/crates/eui48) 1.0 | no | //! | `with-geo-types-0_6` | Enable support for the 0.6 version of the `geo-types` crate. | [geo-types](https://crates.io/crates/geo-types/0.6.0) 0.6 | no | //! | `with-geo-types-0_7` | Enable support for the 0.7 version of the `geo-types` crate. | [geo-types](https://crates.io/crates/geo-types/0.7.0) 0.7 | no | //! | `with-serde_json-1` | Enable support for the `serde_json` crate. | [serde_json](https://crates.io/crates/serde_json) 1.0 | no | diff --git a/tokio-postgres/Cargo.toml b/tokio-postgres/Cargo.toml index 780c31963..fa1b50397 100644 --- a/tokio-postgres/Cargo.toml +++ b/tokio-postgres/Cargo.toml @@ -30,6 +30,7 @@ runtime = ["tokio/net", "tokio/time"] with-bit-vec-0_6 = ["postgres-types/with-bit-vec-0_6"] with-chrono-0_4 = ["postgres-types/with-chrono-0_4"] with-eui48-0_4 = ["postgres-types/with-eui48-0_4"] +with-eui48-1 = ["postgres-types/with-eui48-1"] with-geo-types-0_6 = ["postgres-types/with-geo-types-0_6"] with-geo-types-0_7 = ["postgres-types/with-geo-types-0_7"] with-serde_json-1 = ["postgres-types/with-serde_json-1"] @@ -61,6 +62,7 @@ criterion = "0.3" bit-vec-06 = { version = "0.6", package = "bit-vec" } chrono-04 = { version = "0.4", package = "chrono", default-features = false } eui48-04 = { version = "0.4", package = "eui48" } +eui48-1 = { version = "1.0", package = "eui48" } geo-types-06 = { version = "0.6", package = "geo-types" } geo-types-07 = { version = "0.7", package = "geo-types" } serde-1 = { version = "1.0", package = "serde" } diff --git a/tokio-postgres/src/lib.rs b/tokio-postgres/src/lib.rs index 77713bb11..6dd0b0151 100644 --- a/tokio-postgres/src/lib.rs +++ b/tokio-postgres/src/lib.rs @@ -106,7 +106,8 @@ //! | `runtime` | Enable convenience API for the connection process based on the `tokio` crate. | [tokio](https://crates.io/crates/tokio) 1.0 with the features `net` and `time` | yes | //! | `with-bit-vec-0_6` | Enable support for the `bit-vec` crate. | [bit-vec](https://crates.io/crates/bit-vec) 0.6 | no | //! | `with-chrono-0_4` | Enable support for the `chrono` crate. | [chrono](https://crates.io/crates/chrono) 0.4 | no | -//! | `with-eui48-0_4` | Enable support for the `eui48` crate. | [eui48](https://crates.io/crates/eui48) 0.4 | no | +//! | `with-eui48-0_4` | Enable support for the 0.4 version of the `eui48` crate. | [eui48](https://crates.io/crates/eui48) 0.4 | no | +//! | `with-eui48-1` | Enable support for the 1.0 version of the `eui48` crate. | [eui48](https://crates.io/crates/eui48) 1.0 | no | //! | `with-geo-types-0_6` | Enable support for the 0.6 version of the `geo-types` crate. | [geo-types](https://crates.io/crates/geo-types/0.6.0) 0.6 | no | //! | `with-geo-types-0_7` | Enable support for the 0.7 version of the `geo-types` crate. | [geo-types](https://crates.io/crates/geo-types/0.7.0) 0.7 | no | //! | `with-serde_json-1` | Enable support for the `serde_json` crate. | [serde_json](https://crates.io/crates/serde_json) 1.0 | no | diff --git a/tokio-postgres/tests/test/types/eui48_1.rs b/tokio-postgres/tests/test/types/eui48_1.rs new file mode 100644 index 000000000..0c22e9e87 --- /dev/null +++ b/tokio-postgres/tests/test/types/eui48_1.rs @@ -0,0 +1,18 @@ +use eui48_1::MacAddress; + +use crate::types::test_type; + +#[tokio::test] +async fn test_eui48_params() { + test_type( + "MACADDR", + &[ + ( + Some(MacAddress::parse_str("12-34-56-AB-CD-EF").unwrap()), + "'12-34-56-ab-cd-ef'", + ), + (None, "NULL"), + ], + ) + .await +} diff --git a/tokio-postgres/tests/test/types/mod.rs b/tokio-postgres/tests/test/types/mod.rs index bc31ece71..85eed0e27 100644 --- a/tokio-postgres/tests/test/types/mod.rs +++ b/tokio-postgres/tests/test/types/mod.rs @@ -19,6 +19,8 @@ mod bit_vec_06; mod chrono_04; #[cfg(feature = "with-eui48-0_4")] mod eui48_04; +#[cfg(feature = "with-eui48-1")] +mod eui48_1; #[cfg(feature = "with-geo-types-0_6")] mod geo_types_06; #[cfg(feature = "with-geo-types-0_7")] From 57cacb65fe24762ccfc7889c06b9e906a6408588 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Mon, 21 Jun 2021 21:30:41 -0400 Subject: [PATCH 15/59] Upgrade phf --- codegen/Cargo.toml | 2 +- tokio-postgres/Cargo.toml | 2 +- tokio-postgres/src/error/sqlstate.rs | 552 +++++++++++++-------------- 3 files changed, 278 insertions(+), 278 deletions(-) diff --git a/codegen/Cargo.toml b/codegen/Cargo.toml index 8ff4d58be..fc02751cf 100644 --- a/codegen/Cargo.toml +++ b/codegen/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" authors = ["Steven Fackler "] [dependencies] -phf_codegen = "0.8" +phf_codegen = "0.9" regex = "1.0" marksman_escape = "0.1" linked-hash-map = "0.5" diff --git a/tokio-postgres/Cargo.toml b/tokio-postgres/Cargo.toml index fa1b50397..3a1537a87 100644 --- a/tokio-postgres/Cargo.toml +++ b/tokio-postgres/Cargo.toml @@ -47,7 +47,7 @@ log = "0.4" parking_lot = "0.11" percent-encoding = "2.0" pin-project-lite = "0.2" -phf = "0.8" +phf = "0.9" postgres-protocol = { version = "0.6.1", path = "../postgres-protocol" } postgres-types = { version = "0.2.1", path = "../postgres-types" } socket2 = "0.4" diff --git a/tokio-postgres/src/error/sqlstate.rs b/tokio-postgres/src/error/sqlstate.rs index 125124d12..1996d9b13 100644 --- a/tokio-postgres/src/error/sqlstate.rs +++ b/tokio-postgres/src/error/sqlstate.rs @@ -1340,319 +1340,319 @@ enum Inner { #[rustfmt::skip] static SQLSTATE_MAP: phf::Map<&'static str, SqlState> = ::phf::Map { - key: 732231254413039614, + key: 12913932095322966823, disps: ::phf::Slice::Static(&[ - (0, 6), + (0, 12), + (0, 18), + (0, 25), + (0, 109), + (0, 147), + (0, 74), (0, 0), - (0, 218), - (0, 11), - (0, 31), - (0, 91), - (0, 55), + (7, 117), + (5, 221), + (0, 26), + (1, 45), + (0, 93), + (0, 25), + (0, 61), + (1, 221), + (10, 17), (0, 77), - (0, 72), + (2, 3), + (0, 216), + (0, 0), (0, 1), - (0, 73), - (1, 159), - (4, 4), - (0, 18), - (2, 100), - (0, 19), - (0, 16), - (0, 22), - (0, 51), + (1, 168), + (0, 64), + (0, 2), + (0, 7), + (1, 37), + (0, 83), + (3, 24), (0, 0), + (0, 109), + (18, 9), + (1, 230), (0, 0), - (1, 2), - (2, 177), - (0, 10), - (1, 192), + (0, 4), + (0, 171), (0, 0), - (5, 245), - (0, 106), - (6, 243), - (47, 195), - (0, 146), - (4, 154), - (0, 2), - (4, 78), - (0, 196), - (0, 8), - (2, 146), - (0, 15), - (0, 170), - (0, 5), - (10, 18), - (0, 30), - (0, 33), - (0, 2), + (34, 97), + (2, 126), + (44, 49), + (5, 182), + (0, 1), + (0, 1), + (0, 71), + (0, 4), + (5, 164), (0, 0), - (47, 181), - (0, 144), - (39, 231), - (39, 173), - (0, 57), - (0, 7), - (1, 154), + (0, 96), + (13, 58), + (0, 58), + (0, 242), + (0, 72), + (16, 53), ]), entries: ::phf::Slice::Static(&[ - ("22P04", SqlState::BAD_COPY_FILE_FORMAT), - ("39001", SqlState::E_R_I_E_INVALID_SQLSTATE_RETURNED), - ("2201F", SqlState::INVALID_ARGUMENT_FOR_POWER_FUNCTION), - ("54000", SqlState::PROGRAM_LIMIT_EXCEEDED), - ("2200T", SqlState::INVALID_XML_PROCESSING_INSTRUCTION), - ("01000", SqlState::WARNING), - ("02000", SqlState::NO_DATA), - ("40003", SqlState::T_R_STATEMENT_COMPLETION_UNKNOWN), - ("42702", SqlState::AMBIGUOUS_COLUMN), - ("HV000", SqlState::FDW_ERROR), - ("2203A", SqlState::SQL_JSON_MEMBER_NOT_FOUND), - ("22021", SqlState::CHARACTER_NOT_IN_REPERTOIRE), - ("HV006", SqlState::FDW_INVALID_DATA_TYPE_DESCRIPTORS), - ("40000", SqlState::TRANSACTION_ROLLBACK), - ("57P01", SqlState::ADMIN_SHUTDOWN), ("22034", SqlState::MORE_THAN_ONE_SQL_JSON_ITEM), - ("54023", SqlState::TOO_MANY_ARGUMENTS), - ("22027", SqlState::TRIM_ERROR), - ("2203C", SqlState::SQL_JSON_OBJECT_NOT_FOUND), - ("22P06", SqlState::NONSTANDARD_USE_OF_ESCAPE_CHARACTER), - ("72000", SqlState::SNAPSHOT_TOO_OLD), - ("25004", SqlState::INAPPROPRIATE_ISOLATION_LEVEL_FOR_BRANCH_TRANSACTION), - ("2BP01", SqlState::DEPENDENT_OBJECTS_STILL_EXIST), - ("42P11", SqlState::INVALID_CURSOR_DEFINITION), - ("HV00J", SqlState::FDW_OPTION_NAME_NOT_FOUND), - ("42804", SqlState::DATATYPE_MISMATCH), - ("39004", SqlState::E_R_I_E_NULL_VALUE_NOT_ALLOWED), + ("40P01", SqlState::T_R_DEADLOCK_DETECTED), ("42703", SqlState::UNDEFINED_COLUMN), - ("2203E", SqlState::TOO_MANY_JSON_OBJECT_MEMBERS), - ("42P12", SqlState::INVALID_DATABASE_DEFINITION), - ("23503", SqlState::FOREIGN_KEY_VIOLATION), - ("25003", SqlState::INAPPROPRIATE_ACCESS_MODE_FOR_BRANCH_TRANSACTION), - ("22P03", SqlState::INVALID_BINARY_REPRESENTATION), - ("40002", SqlState::T_R_INTEGRITY_CONSTRAINT_VIOLATION), - ("58030", SqlState::IO_ERROR), - ("01004", SqlState::WARNING_STRING_DATA_RIGHT_TRUNCATION), - ("22019", SqlState::INVALID_ESCAPE_CHARACTER), - ("42P20", SqlState::WINDOWING_ERROR), - ("3D000", SqlState::INVALID_CATALOG_NAME), - ("22001", SqlState::STRING_DATA_RIGHT_TRUNCATION), - ("F0000", SqlState::CONFIG_FILE_ERROR), - ("25005", SqlState::NO_ACTIVE_SQL_TRANSACTION_FOR_BRANCH_TRANSACTION), - ("42883", SqlState::UNDEFINED_FUNCTION), - ("42P06", SqlState::DUPLICATE_SCHEMA), - ("42P17", SqlState::INVALID_OBJECT_DEFINITION), - ("HV002", SqlState::FDW_DYNAMIC_PARAMETER_VALUE_NEEDED), - ("0F001", SqlState::L_E_INVALID_SPECIFICATION), - ("57014", SqlState::QUERY_CANCELED), - ("22033", SqlState::INVALID_SQL_JSON_SUBSCRIPT), - ("2F004", SqlState::S_R_E_READING_SQL_DATA_NOT_PERMITTED), - ("42611", SqlState::INVALID_COLUMN_DEFINITION), - ("42939", SqlState::RESERVED_NAME), - ("0P000", SqlState::INVALID_ROLE_SPECIFICATION), - ("53200", SqlState::OUT_OF_MEMORY), - ("42809", SqlState::WRONG_OBJECT_TYPE), - ("2202H", SqlState::INVALID_TABLESAMPLE_ARGUMENT), - ("42P16", SqlState::INVALID_TABLE_DEFINITION), - ("24000", SqlState::INVALID_CURSOR_STATE), - ("42P13", SqlState::INVALID_FUNCTION_DEFINITION), - ("22007", SqlState::INVALID_DATETIME_FORMAT), - ("2D000", SqlState::INVALID_TRANSACTION_TERMINATION), - ("53100", SqlState::DISK_FULL), - ("P0003", SqlState::TOO_MANY_ROWS), - ("22016", SqlState::INVALID_ARGUMENT_FOR_NTH_VALUE), - ("2F002", SqlState::S_R_E_MODIFYING_SQL_DATA_NOT_PERMITTED), - ("42830", SqlState::INVALID_FOREIGN_KEY), - ("27000", SqlState::TRIGGERED_DATA_CHANGE_VIOLATION), - ("0Z002", SqlState::STACKED_DIAGNOSTICS_ACCESSED_WITHOUT_ACTIVE_HANDLER), - ("53000", SqlState::INSUFFICIENT_RESOURCES), - ("23502", SqlState::NOT_NULL_VIOLATION), - ("XX000", SqlState::INTERNAL_ERROR), - ("58P01", SqlState::UNDEFINED_FILE), - ("42601", SqlState::SYNTAX_ERROR), - ("02001", SqlState::NO_ADDITIONAL_DYNAMIC_RESULT_SETS_RETURNED), - ("42P09", SqlState::AMBIGUOUS_ALIAS), - ("22P02", SqlState::INVALID_TEXT_REPRESENTATION), - ("55P02", SqlState::CANT_CHANGE_RUNTIME_PARAM), - ("2F003", SqlState::S_R_E_PROHIBITED_SQL_STATEMENT_ATTEMPTED), - ("53300", SqlState::TOO_MANY_CONNECTIONS), - ("25P02", SqlState::IN_FAILED_SQL_TRANSACTION), - ("42P03", SqlState::DUPLICATE_CURSOR), - ("XX002", SqlState::INDEX_CORRUPTED), - ("22010", SqlState::INVALID_INDICATOR_PARAMETER_VALUE), - ("01006", SqlState::WARNING_PRIVILEGE_NOT_REVOKED), - ("3B001", SqlState::S_E_INVALID_SPECIFICATION), - ("42P21", SqlState::COLLATION_MISMATCH), ("42P07", SqlState::DUPLICATE_TABLE), - ("22013", SqlState::INVALID_PRECEDING_OR_FOLLOWING_SIZE), - ("0Z000", SqlState::DIAGNOSTICS_EXCEPTION), ("55P04", SqlState::UNSAFE_NEW_ENUM_VALUE_USAGE), - ("42000", SqlState::SYNTAX_ERROR_OR_ACCESS_RULE_VIOLATION), - ("XX001", SqlState::DATA_CORRUPTED), - ("25008", SqlState::HELD_CURSOR_REQUIRES_SAME_ISOLATION_LEVEL), - ("HV00M", SqlState::FDW_UNABLE_TO_CREATE_REPLY), - ("39000", SqlState::EXTERNAL_ROUTINE_INVOCATION_EXCEPTION), - ("22032", SqlState::INVALID_JSON_TEXT), ("25006", SqlState::READ_ONLY_SQL_TRANSACTION), - ("01P01", SqlState::WARNING_DEPRECATED_FEATURE), - ("42725", SqlState::AMBIGUOUS_FUNCTION), - ("42602", SqlState::INVALID_NAME), - ("2201W", SqlState::INVALID_ROW_COUNT_IN_LIMIT_CLAUSE), - ("42P05", SqlState::DUPLICATE_PSTATEMENT), + ("2201X", SqlState::INVALID_ROW_COUNT_IN_RESULT_OFFSET_CLAUSE), ("HV021", SqlState::FDW_INCONSISTENT_DESCRIPTOR_INFORMATION), - ("57P03", SqlState::CANNOT_CONNECT_NOW), - ("58P02", SqlState::DUPLICATE_FILE), - ("42P22", SqlState::INDETERMINATE_COLLATION), - ("0B000", SqlState::INVALID_TRANSACTION_INITIATION), - ("0100C", SqlState::WARNING_DYNAMIC_RESULT_SETS_RETURNED), - ("22015", SqlState::INTERVAL_FIELD_OVERFLOW), - ("2200S", SqlState::INVALID_XML_COMMENT), - ("2200M", SqlState::INVALID_XML_DOCUMENT), - ("HV001", SqlState::FDW_OUT_OF_MEMORY), - ("25001", SqlState::ACTIVE_SQL_TRANSACTION), - ("22002", SqlState::NULL_VALUE_NO_INDICATOR_PARAMETER), + ("42P02", SqlState::UNDEFINED_PARAMETER), + ("HV00C", SqlState::FDW_INVALID_OPTION_INDEX), + ("08003", SqlState::CONNECTION_DOES_NOT_EXIST), + ("02000", SqlState::NO_DATA), + ("24000", SqlState::INVALID_CURSOR_STATE), + ("2203C", SqlState::SQL_JSON_OBJECT_NOT_FOUND), + ("42601", SqlState::SYNTAX_ERROR), + ("22012", SqlState::DIVISION_BY_ZERO), + ("2203B", SqlState::SQL_JSON_NUMBER_NOT_FOUND), + ("P0003", SqlState::TOO_MANY_ROWS), + ("57P04", SqlState::DATABASE_DROPPED), + ("27000", SqlState::TRIGGERED_DATA_CHANGE_VIOLATION), + ("42P08", SqlState::AMBIGUOUS_PARAMETER), + ("3F000", SqlState::INVALID_SCHEMA_NAME), + ("42883", SqlState::UNDEFINED_FUNCTION), + ("20000", SqlState::CASE_NOT_FOUND), + ("2200G", SqlState::MOST_SPECIFIC_TYPE_MISMATCH), + ("42939", SqlState::RESERVED_NAME), + ("42602", SqlState::INVALID_NAME), + ("HV004", SqlState::FDW_INVALID_DATA_TYPE), + ("HV007", SqlState::FDW_INVALID_COLUMN_NAME), ("2F005", SqlState::S_R_E_FUNCTION_EXECUTED_NO_RETURN_STATEMENT), - ("428C9", SqlState::GENERATED_ALWAYS), - ("25P01", SqlState::NO_ACTIVE_SQL_TRANSACTION), - ("HV091", SqlState::FDW_INVALID_DESCRIPTOR_FIELD_IDENTIFIER), - ("2200C", SqlState::INVALID_USE_OF_ESCAPE_CHARACTER), - ("HV008", SqlState::FDW_INVALID_COLUMN_NUMBER), - ("2200F", SqlState::ZERO_LENGTH_CHARACTER_STRING), - ("54001", SqlState::STATEMENT_TOO_COMPLEX), + ("22030", SqlState::DUPLICATE_JSON_OBJECT_KEY_VALUE), + ("53100", SqlState::DISK_FULL), + ("HV005", SqlState::FDW_COLUMN_NAME_NOT_FOUND), + ("2200H", SqlState::SEQUENCE_GENERATOR_LIMIT_EXCEEDED), + ("2201W", SqlState::INVALID_ROW_COUNT_IN_LIMIT_CLAUSE), ("42712", SqlState::DUPLICATE_ALIAS), - ("HV00A", SqlState::FDW_INVALID_STRING_FORMAT), - ("42710", SqlState::DUPLICATE_OBJECT), - ("54011", SqlState::TOO_MANY_COLUMNS), - ("42P19", SqlState::INVALID_RECURSION), - ("42501", SqlState::INSUFFICIENT_PRIVILEGE), + ("42622", SqlState::NAME_TOO_LONG), + ("22035", SqlState::NO_SQL_JSON_ITEM), + ("42P18", SqlState::INDETERMINATE_DATATYPE), + ("39P01", SqlState::E_R_I_E_TRIGGER_PROTOCOL_VIOLATED), + ("01000", SqlState::WARNING), + ("2F004", SqlState::S_R_E_READING_SQL_DATA_NOT_PERMITTED), + ("22023", SqlState::INVALID_PARAMETER_VALUE), + ("2200T", SqlState::INVALID_XML_PROCESSING_INSTRUCTION), + ("22013", SqlState::INVALID_PRECEDING_OR_FOLLOWING_SIZE), + ("57P01", SqlState::ADMIN_SHUTDOWN), + ("2202E", SqlState::ARRAY_ELEMENT_ERROR), + ("22018", SqlState::INVALID_CHARACTER_VALUE_FOR_CAST), + ("0F000", SqlState::LOCATOR_EXCEPTION), + ("2D000", SqlState::INVALID_TRANSACTION_TERMINATION), + ("HV009", SqlState::FDW_INVALID_USE_OF_NULL_POINTER), ("57000", SqlState::OPERATOR_INTERVENTION), ("25002", SqlState::BRANCH_TRANSACTION_ALREADY_ACTIVE), - ("22039", SqlState::SQL_JSON_ARRAY_NOT_FOUND), - ("P0002", SqlState::NO_DATA_FOUND), + ("25004", SqlState::INAPPROPRIATE_ISOLATION_LEVEL_FOR_BRANCH_TRANSACTION), + ("22009", SqlState::INVALID_TIME_ZONE_DISPLACEMENT_VALUE), + ("HV090", SqlState::FDW_INVALID_STRING_LENGTH_OR_BUFFER_LENGTH), + ("42725", SqlState::AMBIGUOUS_FUNCTION), + ("2F003", SqlState::S_R_E_PROHIBITED_SQL_STATEMENT_ATTEMPTED), + ("44000", SqlState::WITH_CHECK_OPTION_VIOLATION), + ("22032", SqlState::INVALID_JSON_TEXT), + ("22036", SqlState::NON_NUMERIC_SQL_JSON_ITEM), + ("2201E", SqlState::INVALID_ARGUMENT_FOR_LOG), + ("25P02", SqlState::IN_FAILED_SQL_TRANSACTION), + ("22001", SqlState::STRING_DATA_RIGHT_TRUNCATION), + ("2201F", SqlState::INVALID_ARGUMENT_FOR_POWER_FUNCTION), + ("01006", SqlState::WARNING_PRIVILEGE_NOT_REVOKED), + ("428C9", SqlState::GENERATED_ALWAYS), + ("22003", SqlState::NUMERIC_VALUE_OUT_OF_RANGE), + ("22P01", SqlState::FLOATING_POINT_EXCEPTION), + ("HV00M", SqlState::FDW_UNABLE_TO_CREATE_REPLY), ("2201G", SqlState::INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION), - ("22012", SqlState::DIVISION_BY_ZERO), - ("42P10", SqlState::INVALID_COLUMN_REFERENCE), + ("34000", SqlState::INVALID_CURSOR_NAME), + ("42846", SqlState::CANNOT_COERCE), + ("2201B", SqlState::INVALID_REGULAR_EXPRESSION), + ("2202G", SqlState::INVALID_TABLESAMPLE_REPEAT), + ("42704", SqlState::UNDEFINED_OBJECT), + ("72000", SqlState::SNAPSHOT_TOO_OLD), + ("53400", SqlState::CONFIGURATION_LIMIT_EXCEEDED), + ("HV00L", SqlState::FDW_UNABLE_TO_CREATE_EXECUTION), + ("2B000", SqlState::DEPENDENT_PRIVILEGE_DESCRIPTORS_STILL_EXIST), + ("22010", SqlState::INVALID_INDICATOR_PARAMETER_VALUE), + ("54001", SqlState::STATEMENT_TOO_COMPLEX), + ("53200", SqlState::OUT_OF_MEMORY), + ("38001", SqlState::E_R_E_CONTAINING_SQL_NOT_PERMITTED), + ("22022", SqlState::INDICATOR_OVERFLOW), + ("2203E", SqlState::TOO_MANY_JSON_OBJECT_MEMBERS), + ("XX000", SqlState::INTERNAL_ERROR), + ("22025", SqlState::INVALID_ESCAPE_SEQUENCE), + ("09000", SqlState::TRIGGERED_ACTION_EXCEPTION), + ("HV008", SqlState::FDW_INVALID_COLUMN_NUMBER), + ("25P01", SqlState::NO_ACTIVE_SQL_TRANSACTION), + ("23505", SqlState::UNIQUE_VIOLATION), + ("3B000", SqlState::SAVEPOINT_EXCEPTION), + ("F0000", SqlState::CONFIG_FILE_ERROR), + ("54011", SqlState::TOO_MANY_COLUMNS), + ("XX002", SqlState::INDEX_CORRUPTED), + ("2203F", SqlState::SQL_JSON_SCALAR_REQUIRED), + ("42P12", SqlState::INVALID_DATABASE_DEFINITION), ("HV00B", SqlState::FDW_INVALID_HANDLE), - ("38003", SqlState::E_R_E_PROHIBITED_SQL_STATEMENT_ATTEMPTED), + ("55006", SqlState::OBJECT_IN_USE), + ("42P01", SqlState::UNDEFINED_TABLE), ("25P03", SqlState::IDLE_IN_TRANSACTION_SESSION_TIMEOUT), - ("F0001", SqlState::LOCK_FILE_EXISTS), - ("08001", SqlState::SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION), - ("2203D", SqlState::TOO_MANY_JSON_ARRAY_ELEMENTS), - ("P0000", SqlState::PLPGSQL_ERROR), - ("28000", SqlState::INVALID_AUTHORIZATION_SPECIFICATION), - ("2200D", SqlState::INVALID_ESCAPE_OCTET), - ("55P03", SqlState::LOCK_NOT_AVAILABLE), - ("23505", SqlState::UNIQUE_VIOLATION), - ("39P01", SqlState::E_R_I_E_TRIGGER_PROTOCOL_VIOLATED), - ("44000", SqlState::WITH_CHECK_OPTION_VIOLATION), - ("22030", SqlState::DUPLICATE_JSON_OBJECT_KEY_VALUE), + ("22037", SqlState::NON_UNIQUE_KEYS_IN_A_JSON_OBJECT), + ("2203A", SqlState::SQL_JSON_MEMBER_NOT_FOUND), ("P0004", SqlState::ASSERT_FAILURE), - ("2200G", SqlState::MOST_SPECIFIC_TYPE_MISMATCH), - ("2F000", SqlState::SQL_ROUTINE_EXCEPTION), - ("26000", SqlState::INVALID_SQL_STATEMENT_NAME), - ("2202G", SqlState::INVALID_TABLESAMPLE_REPEAT), - ("22003", SqlState::NUMERIC_VALUE_OUT_OF_RANGE), + ("58000", SqlState::SYSTEM_ERROR), + ("42P21", SqlState::COLLATION_MISMATCH), + ("57P02", SqlState::CRASH_SHUTDOWN), + ("42830", SqlState::INVALID_FOREIGN_KEY), + ("0LP01", SqlState::INVALID_GRANT_OPERATION), + ("22P02", SqlState::INVALID_TEXT_REPRESENTATION), + ("22039", SqlState::SQL_JSON_ARRAY_NOT_FOUND), + ("28P01", SqlState::INVALID_PASSWORD), + ("22011", SqlState::SUBSTRING_ERROR), + ("HV00J", SqlState::FDW_OPTION_NAME_NOT_FOUND), + ("2200C", SqlState::INVALID_USE_OF_ESCAPE_CHARACTER), + ("08006", SqlState::CONNECTION_FAILURE), + ("22021", SqlState::CHARACTER_NOT_IN_REPERTOIRE), ("21000", SqlState::CARDINALITY_VIOLATION), - ("0A000", SqlState::FEATURE_NOT_SUPPORTED), - ("HV014", SqlState::FDW_TOO_MANY_HANDLES), - ("08004", SqlState::SQLSERVER_REJECTED_ESTABLISHMENT_OF_SQLCONNECTION), - ("38001", SqlState::E_R_E_CONTAINING_SQL_NOT_PERMITTED), - ("01003", SqlState::WARNING_NULL_VALUE_ELIMINATED_IN_SET_FUNCTION), - ("08007", SqlState::TRANSACTION_RESOLUTION_UNKNOWN), - ("HV00D", SqlState::FDW_INVALID_OPTION_NAME), + ("42803", SqlState::GROUPING_ERROR), + ("00000", SqlState::SUCCESSFUL_COMPLETION), + ("42P16", SqlState::INVALID_TABLE_DEFINITION), ("38002", SqlState::E_R_E_MODIFYING_SQL_DATA_NOT_PERMITTED), + ("57P03", SqlState::CANNOT_CONNECT_NOW), + ("01004", SqlState::WARNING_STRING_DATA_RIGHT_TRUNCATION), ("HV00K", SqlState::FDW_REPLY_HANDLE), - ("23P01", SqlState::EXCLUSION_VIOLATION), - ("42P04", SqlState::DUPLICATE_DATABASE), - ("22025", SqlState::INVALID_ESCAPE_SEQUENCE), - ("HV007", SqlState::FDW_INVALID_COLUMN_NAME), - ("34000", SqlState::INVALID_CURSOR_NAME), - ("HV00L", SqlState::FDW_UNABLE_TO_CREATE_EXECUTION), - ("HV009", SqlState::FDW_INVALID_USE_OF_NULL_POINTER), - ("38000", SqlState::EXTERNAL_ROUTINE_EXCEPTION), - ("2B000", SqlState::DEPENDENT_PRIVILEGE_DESCRIPTORS_STILL_EXIST), - ("00000", SqlState::SUCCESSFUL_COMPLETION), - ("58000", SqlState::SYSTEM_ERROR), - ("2201E", SqlState::INVALID_ARGUMENT_FOR_LOG), - ("HV024", SqlState::FDW_INVALID_ATTRIBUTE_VALUE), + ("42P06", SqlState::DUPLICATE_SCHEMA), + ("54000", SqlState::PROGRAM_LIMIT_EXCEEDED), + ("2200S", SqlState::INVALID_XML_COMMENT), + ("42000", SqlState::SYNTAX_ERROR_OR_ACCESS_RULE_VIOLATION), + ("42P03", SqlState::DUPLICATE_CURSOR), + ("HV002", SqlState::FDW_DYNAMIC_PARAMETER_VALUE_NEEDED), + ("2202H", SqlState::INVALID_TABLESAMPLE_ARGUMENT), + ("08001", SqlState::SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION), + ("0L000", SqlState::INVALID_GRANTOR), ("2200L", SqlState::NOT_AN_XML_DOCUMENT), - ("2203B", SqlState::SQL_JSON_NUMBER_NOT_FOUND), - ("42846", SqlState::CANNOT_COERCE), - ("22035", SqlState::NO_SQL_JSON_ITEM), - ("HV005", SqlState::FDW_COLUMN_NAME_NOT_FOUND), - ("20000", SqlState::CASE_NOT_FOUND), - ("40001", SqlState::T_R_SERIALIZATION_FAILURE), + ("HV006", SqlState::FDW_INVALID_DATA_TYPE_DESCRIPTORS), + ("55000", SqlState::OBJECT_NOT_IN_PREREQUISITE_STATE), + ("58P01", SqlState::UNDEFINED_FILE), + ("0B000", SqlState::INVALID_TRANSACTION_INITIATION), ("22000", SqlState::DATA_EXCEPTION), + ("HV00R", SqlState::FDW_TABLE_NOT_FOUND), + ("2F002", SqlState::S_R_E_MODIFYING_SQL_DATA_NOT_PERMITTED), + ("01007", SqlState::WARNING_PRIVILEGE_NOT_GRANTED), + ("42P19", SqlState::INVALID_RECURSION), + ("22016", SqlState::INVALID_ARGUMENT_FOR_NTH_VALUE), + ("42702", SqlState::AMBIGUOUS_COLUMN), + ("25005", SqlState::NO_ACTIVE_SQL_TRANSACTION_FOR_BRANCH_TRANSACTION), + ("22004", SqlState::NULL_VALUE_NOT_ALLOWED), + ("42P05", SqlState::DUPLICATE_PSTATEMENT), + ("39001", SqlState::E_R_I_E_INVALID_SQLSTATE_RETURNED), ("22038", SqlState::SINGLETON_SQL_JSON_ITEM_REQUIRED), - ("42P14", SqlState::INVALID_PSTATEMENT_DEFINITION), + ("22008", SqlState::DATETIME_FIELD_OVERFLOW), + ("38003", SqlState::E_R_E_PROHIBITED_SQL_STATEMENT_ATTEMPTED), + ("53000", SqlState::INSUFFICIENT_RESOURCES), + ("3B001", SqlState::S_E_INVALID_SPECIFICATION), + ("28000", SqlState::INVALID_AUTHORIZATION_SPECIFICATION), + ("P0000", SqlState::PLPGSQL_ERROR), + ("38000", SqlState::EXTERNAL_ROUTINE_EXCEPTION), + ("22019", SqlState::INVALID_ESCAPE_CHARACTER), + ("22015", SqlState::INTERVAL_FIELD_OVERFLOW), + ("42710", SqlState::DUPLICATE_OBJECT), + ("2200M", SqlState::INVALID_XML_DOCUMENT), + ("HV000", SqlState::FDW_ERROR), + ("22P05", SqlState::UNTRANSLATABLE_CHARACTER), + ("0100C", SqlState::WARNING_DYNAMIC_RESULT_SETS_RETURNED), + ("55P02", SqlState::CANT_CHANGE_RUNTIME_PARAM), + ("01003", SqlState::WARNING_NULL_VALUE_ELIMINATED_IN_SET_FUNCTION), + ("2200N", SqlState::INVALID_XML_CONTENT), + ("2F000", SqlState::SQL_ROUTINE_EXCEPTION), + ("08007", SqlState::TRANSACTION_RESOLUTION_UNKNOWN), + ("2200B", SqlState::ESCAPE_CHARACTER_CONFLICT), + ("22P03", SqlState::INVALID_BINARY_REPRESENTATION), + ("42P09", SqlState::AMBIGUOUS_ALIAS), + ("39004", SqlState::E_R_I_E_NULL_VALUE_NOT_ALLOWED), + ("23502", SqlState::NOT_NULL_VIOLATION), + ("2203D", SqlState::TOO_MANY_JSON_ARRAY_ELEMENTS), + ("42P15", SqlState::INVALID_SCHEMA_DEFINITION), + ("08004", SqlState::SQLSERVER_REJECTED_ESTABLISHMENT_OF_SQLCONNECTION), + ("HV00N", SqlState::FDW_UNABLE_TO_ESTABLISH_CONNECTION), + ("0A000", SqlState::FEATURE_NOT_SUPPORTED), + ("57014", SqlState::QUERY_CANCELED), + ("22033", SqlState::INVALID_SQL_JSON_SUBSCRIPT), + ("0F001", SqlState::L_E_INVALID_SPECIFICATION), + ("HV00A", SqlState::FDW_INVALID_STRING_FORMAT), ("39P02", SqlState::E_R_I_E_SRF_PROTOCOL_VIOLATED), + ("42701", SqlState::DUPLICATE_COLUMN), + ("42611", SqlState::INVALID_COLUMN_DEFINITION), + ("HV001", SqlState::FDW_OUT_OF_MEMORY), + ("HV091", SqlState::FDW_INVALID_DESCRIPTOR_FIELD_IDENTIFIER), + ("23P01", SqlState::EXCLUSION_VIOLATION), + ("F0001", SqlState::LOCK_FILE_EXISTS), + ("42501", SqlState::INSUFFICIENT_PRIVILEGE), + ("22026", SqlState::STRING_DATA_LENGTH_MISMATCH), + ("54023", SqlState::TOO_MANY_ARGUMENTS), ("01008", SqlState::WARNING_IMPLICIT_ZERO_BIT_PADDING), - ("42P15", SqlState::INVALID_SCHEMA_DEFINITION), - ("55006", SqlState::OBJECT_IN_USE), - ("2203F", SqlState::SQL_JSON_SCALAR_REQUIRED), - ("22014", SqlState::INVALID_ARGUMENT_FOR_NTILE), + ("42P04", SqlState::DUPLICATE_DATABASE), + ("22027", SqlState::TRIM_ERROR), + ("53300", SqlState::TOO_MANY_CONNECTIONS), + ("0Z002", SqlState::STACKED_DIAGNOSTICS_ACCESSED_WITHOUT_ACTIVE_HANDLER), + ("42P14", SqlState::INVALID_PSTATEMENT_DEFINITION), + ("P0001", SqlState::RAISE_EXCEPTION), + ("HV014", SqlState::FDW_TOO_MANY_HANDLES), + ("40002", SqlState::T_R_INTEGRITY_CONSTRAINT_VIOLATION), + ("3D000", SqlState::INVALID_CATALOG_NAME), ("03000", SqlState::SQL_STATEMENT_NOT_YET_COMPLETE), - ("22008", SqlState::DATETIME_FIELD_OVERFLOW), - ("08006", SqlState::CONNECTION_FAILURE), - ("42P01", SqlState::UNDEFINED_TABLE), - ("40P01", SqlState::T_R_DEADLOCK_DETECTED), - ("0L000", SqlState::INVALID_GRANTOR), + ("22024", SqlState::UNTERMINATED_C_STRING), + ("42P13", SqlState::INVALID_FUNCTION_DEFINITION), + ("08000", SqlState::CONNECTION_EXCEPTION), + ("25007", SqlState::SCHEMA_AND_DATA_STATEMENT_MIXING_NOT_SUPPORTED), + ("40001", SqlState::T_R_SERIALIZATION_FAILURE), + ("25001", SqlState::ACTIVE_SQL_TRANSACTION), + ("HV00Q", SqlState::FDW_SCHEMA_NOT_FOUND), + ("22P04", SqlState::BAD_COPY_FILE_FORMAT), + ("XX001", SqlState::DATA_CORRUPTED), + ("23503", SqlState::FOREIGN_KEY_VIOLATION), + ("23514", SqlState::CHECK_VIOLATION), + ("42809", SqlState::WRONG_OBJECT_TYPE), + ("2200F", SqlState::ZERO_LENGTH_CHARACTER_STRING), + ("2BP01", SqlState::DEPENDENT_OBJECTS_STILL_EXIST), + ("25008", SqlState::HELD_CURSOR_REQUIRES_SAME_ISOLATION_LEVEL), + ("55P03", SqlState::LOCK_NOT_AVAILABLE), + ("42P22", SqlState::INDETERMINATE_COLLATION), + ("HV00D", SqlState::FDW_INVALID_OPTION_NAME), + ("42P17", SqlState::INVALID_OBJECT_DEFINITION), + ("23001", SqlState::RESTRICT_VIOLATION), + ("22P06", SqlState::NONSTANDARD_USE_OF_ESCAPE_CHARACTER), + ("22031", SqlState::INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION), + ("2200D", SqlState::INVALID_ESCAPE_OCTET), + ("0Z000", SqlState::DIAGNOSTICS_EXCEPTION), + ("HV024", SqlState::FDW_INVALID_ATTRIBUTE_VALUE), ("22005", SqlState::ERROR_IN_ASSIGNMENT), - ("42622", SqlState::NAME_TOO_LONG), - ("57P04", SqlState::DATABASE_DROPPED), - ("42803", SqlState::GROUPING_ERROR), - ("22P01", SqlState::FLOATING_POINT_EXCEPTION), - ("42P18", SqlState::INDETERMINATE_DATATYPE), + ("58P02", SqlState::DUPLICATE_FILE), + ("HV00P", SqlState::FDW_NO_SCHEMAS), + ("42P10", SqlState::INVALID_COLUMN_REFERENCE), + ("42P20", SqlState::WINDOWING_ERROR), + ("25000", SqlState::INVALID_TRANSACTION_STATE), ("38004", SqlState::E_R_E_READING_SQL_DATA_NOT_PERMITTED), - ("39P03", SqlState::E_R_I_E_EVENT_TRIGGER_PROTOCOL_VIOLATED), - ("2200N", SqlState::INVALID_XML_CONTENT), - ("57P02", SqlState::CRASH_SHUTDOWN), + ("01P01", SqlState::WARNING_DEPRECATED_FEATURE), + ("40000", SqlState::TRANSACTION_ROLLBACK), + ("58030", SqlState::IO_ERROR), + ("26000", SqlState::INVALID_SQL_STATEMENT_NAME), + ("22007", SqlState::INVALID_DATETIME_FORMAT), ("23000", SqlState::INTEGRITY_CONSTRAINT_VIOLATION), - ("0F000", SqlState::LOCATOR_EXCEPTION), - ("08000", SqlState::CONNECTION_EXCEPTION), - ("2202E", SqlState::ARRAY_ELEMENT_ERROR), - ("22024", SqlState::UNTERMINATED_C_STRING), + ("0P000", SqlState::INVALID_ROLE_SPECIFICATION), + ("22014", SqlState::INVALID_ARGUMENT_FOR_NTILE), + ("P0002", SqlState::NO_DATA_FOUND), + ("39P03", SqlState::E_R_I_E_EVENT_TRIGGER_PROTOCOL_VIOLATED), + ("39000", SqlState::EXTERNAL_ROUTINE_INVOCATION_EXCEPTION), + ("42P11", SqlState::INVALID_CURSOR_DEFINITION), + ("HV010", SqlState::FDW_FUNCTION_SEQUENCE_ERROR), + ("22002", SqlState::NULL_VALUE_NO_INDICATOR_PARAMETER), ("08P01", SqlState::PROTOCOL_VIOLATION), - ("22023", SqlState::INVALID_PARAMETER_VALUE), - ("22031", SqlState::INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION), - ("HV00P", SqlState::FDW_NO_SCHEMAS), - ("23514", SqlState::CHECK_VIOLATION), - ("HV00Q", SqlState::FDW_SCHEMA_NOT_FOUND), - ("22P05", SqlState::UNTRANSLATABLE_CHARACTER), - ("53400", SqlState::CONFIGURATION_LIMIT_EXCEEDED), - ("3F000", SqlState::INVALID_SCHEMA_NAME), - ("22037", SqlState::NON_UNIQUE_KEYS_IN_A_JSON_OBJECT), - ("22004", SqlState::NULL_VALUE_NOT_ALLOWED), - ("2200B", SqlState::ESCAPE_CHARACTER_CONFLICT), - ("HV090", SqlState::FDW_INVALID_STRING_LENGTH_OR_BUFFER_LENGTH), - ("HV00R", SqlState::FDW_TABLE_NOT_FOUND), ("42723", SqlState::DUPLICATE_FUNCTION), - ("22009", SqlState::INVALID_TIME_ZONE_DISPLACEMENT_VALUE), - ("HV00N", SqlState::FDW_UNABLE_TO_ESTABLISH_CONNECTION), - ("3B000", SqlState::SAVEPOINT_EXCEPTION), - ("22018", SqlState::INVALID_CHARACTER_VALUE_FOR_CAST), - ("HV004", SqlState::FDW_INVALID_DATA_TYPE), - ("08003", SqlState::CONNECTION_DOES_NOT_EXIST), - ("42P02", SqlState::UNDEFINED_PARAMETER), - ("23001", SqlState::RESTRICT_VIOLATION), - ("HV00C", SqlState::FDW_INVALID_OPTION_INDEX), - ("HV010", SqlState::FDW_FUNCTION_SEQUENCE_ERROR), - ("28P01", SqlState::INVALID_PASSWORD), - ("55000", SqlState::OBJECT_NOT_IN_PREREQUISITE_STATE), - ("2201X", SqlState::INVALID_ROW_COUNT_IN_RESULT_OFFSET_CLAUSE), - ("P0001", SqlState::RAISE_EXCEPTION), - ("25000", SqlState::INVALID_TRANSACTION_STATE), - ("42704", SqlState::UNDEFINED_OBJECT), - ("22022", SqlState::INDICATOR_OVERFLOW), - ("09000", SqlState::TRIGGERED_ACTION_EXCEPTION), - ("22026", SqlState::STRING_DATA_LENGTH_MISMATCH), - ("01007", SqlState::WARNING_PRIVILEGE_NOT_GRANTED), - ("2200H", SqlState::SEQUENCE_GENERATOR_LIMIT_EXCEEDED), - ("25007", SqlState::SCHEMA_AND_DATA_STATEMENT_MIXING_NOT_SUPPORTED), - ("42701", SqlState::DUPLICATE_COLUMN), - ("42P08", SqlState::AMBIGUOUS_PARAMETER), - ("2201B", SqlState::INVALID_REGULAR_EXPRESSION), - ("22036", SqlState::NON_NUMERIC_SQL_JSON_ITEM), - ("22011", SqlState::SUBSTRING_ERROR), - ("0LP01", SqlState::INVALID_GRANT_OPERATION), + ("40003", SqlState::T_R_STATEMENT_COMPLETION_UNKNOWN), + ("25003", SqlState::INAPPROPRIATE_ACCESS_MODE_FOR_BRANCH_TRANSACTION), + ("02001", SqlState::NO_ADDITIONAL_DYNAMIC_RESULT_SETS_RETURNED), + ("42804", SqlState::DATATYPE_MISMATCH), ]), }; From 8f7481a86cb4c4cf5658a0c8ba2cbe3cd7cb6d54 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Wed, 23 Jun 2021 20:02:51 -0400 Subject: [PATCH 16/59] fix clippy --- postgres-protocol/src/types/test.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/postgres-protocol/src/types/test.rs b/postgres-protocol/src/types/test.rs index 8796ab31b..09edeee3a 100644 --- a/postgres-protocol/src/types/test.rs +++ b/postgres-protocol/src/types/test.rs @@ -6,6 +6,7 @@ use super::*; use crate::IsNull; #[test] +#[allow(clippy::bool_assert_comparison)] fn bool() { let mut buf = BytesMut::new(); bool_to_sql(true, &mut buf); @@ -113,7 +114,7 @@ fn array() { .unwrap(); let array = array_from_sql(&buf).unwrap(); - assert_eq!(array.has_nulls(), true); + assert!(array.has_nulls()); assert_eq!(array.element_type(), 10); assert_eq!(array.dimensions().collect::>().unwrap(), dimensions); assert_eq!(array.values().collect::>().unwrap(), values); @@ -150,7 +151,7 @@ fn non_null_array() { .unwrap(); let array = array_from_sql(&buf).unwrap(); - assert_eq!(array.has_nulls(), false); + assert!(array.has_nulls()); assert_eq!(array.element_type(), 10); assert_eq!(array.dimensions().collect::>().unwrap(), dimensions); assert_eq!(array.values().collect::>().unwrap(), values); From 3eb5a4dab94e95df071949a31e7765031511c8cf Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Wed, 23 Jun 2021 20:15:57 -0400 Subject: [PATCH 17/59] actually fix clippy --- postgres-protocol/src/types/test.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/postgres-protocol/src/types/test.rs b/postgres-protocol/src/types/test.rs index 09edeee3a..7c20cf3ed 100644 --- a/postgres-protocol/src/types/test.rs +++ b/postgres-protocol/src/types/test.rs @@ -151,7 +151,7 @@ fn non_null_array() { .unwrap(); let array = array_from_sql(&buf).unwrap(); - assert!(array.has_nulls()); + assert!(!array.has_nulls()); assert_eq!(array.element_type(), 10); assert_eq!(array.dimensions().collect::>().unwrap(), dimensions); assert_eq!(array.values().collect::>().unwrap(), values); From 3b7b8000ce2d135883c248dd11d02e376a4aa678 Mon Sep 17 00:00:00 2001 From: JR Smith Date: Thu, 1 Jul 2021 16:04:19 -0400 Subject: [PATCH 18/59] Made requirement of setting feature flags to access derive macros more explicit in the documentation. --- postgres-types/src/lib.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/postgres-types/src/lib.rs b/postgres-types/src/lib.rs index ed6f75cf5..1973f3d0e 100644 --- a/postgres-types/src/lib.rs +++ b/postgres-types/src/lib.rs @@ -6,7 +6,12 @@ //! # Derive //! //! If the `derive` cargo feature is enabled, you can derive `ToSql` and `FromSql` implementations for custom Postgres -//! types. +//! types. Explicitly, modify your `Cargo.toml` file to include the following: +//! +//! ```toml +//! [dependencies] +//! postgres-types = { version = "0.X.X", features = ["derive"] } +//! ``` //! //! ## Enums //! From 6c1542f634ae0d7733811024cd63835045f75784 Mon Sep 17 00:00:00 2001 From: Lukas Kalbertodt Date: Tue, 13 Jul 2021 11:21:11 +0200 Subject: [PATCH 19/59] Add `FromSql` and `ToSql` impls for arrays (guarded behind feature) This is feature-gated because those impls require Rust 1.51. --- postgres-types/Cargo.toml | 2 + postgres-types/src/lib.rs | 66 ++++++++++++++++++++++++-- postgres/Cargo.toml | 1 + tokio-postgres/Cargo.toml | 1 + tokio-postgres/tests/test/types/mod.rs | 14 +++++- 5 files changed, 79 insertions(+), 5 deletions(-) diff --git a/postgres-types/Cargo.toml b/postgres-types/Cargo.toml index b258cee12..4fd69f613 100644 --- a/postgres-types/Cargo.toml +++ b/postgres-types/Cargo.toml @@ -12,6 +12,7 @@ categories = ["database"] [features] derive = ["postgres-derive"] +array-impls = ["array-init"] with-bit-vec-0_6 = ["bit-vec-06"] with-chrono-0_4 = ["chrono-04"] with-eui48-0_4 = ["eui48-04"] @@ -28,6 +29,7 @@ fallible-iterator = "0.2" postgres-protocol = { version = "0.6.1", path = "../postgres-protocol" } postgres-derive = { version = "0.4.0", optional = true, path = "../postgres-derive" } +array-init = { version = "2", optional = true } bit-vec-06 = { version = "0.6", package = "bit-vec", optional = true } chrono-04 = { version = "0.4.16", package = "chrono", default-features = false, features = ["clock"], optional = true } eui48-04 = { version = "0.4", package = "eui48", optional = true } diff --git a/postgres-types/src/lib.rs b/postgres-types/src/lib.rs index 1973f3d0e..4c559b95a 100644 --- a/postgres-types/src/lib.rs +++ b/postgres-types/src/lib.rs @@ -428,8 +428,10 @@ impl WrongType { /// /// # Arrays /// -/// `FromSql` is implemented for `Vec` where `T` implements `FromSql`, and -/// corresponds to one-dimensional Postgres arrays. +/// `FromSql` is implemented for `Vec` and `[T; N]` where `T` implements +/// `FromSql`, and corresponds to one-dimensional Postgres arrays. **Note:** +/// the impl for arrays only exist when the Cargo feature `array-impls` is +/// enabled. pub trait FromSql<'a>: Sized { /// Creates a new value of this type from a buffer of data of the specified /// Postgres `Type` in its binary format. @@ -513,6 +515,47 @@ impl<'a, T: FromSql<'a>> FromSql<'a> for Vec { } } +#[cfg(feature = "array-impls")] +impl<'a, T: FromSql<'a>, const N: usize> FromSql<'a> for [T; N] { + fn from_sql(ty: &Type, raw: &'a [u8]) -> Result> { + let member_type = match *ty.kind() { + Kind::Array(ref member) => member, + _ => panic!("expected array type"), + }; + + let array = types::array_from_sql(raw)?; + if array.dimensions().count()? > 1 { + return Err("array contains too many dimensions".into()); + } + + let mut values = array.values(); + let out = array_init::try_array_init(|i| { + let v = values + .next()? + .ok_or_else(|| -> Box { + format!("too few elements in array (expected {}, got {})", N, i).into() + })?; + T::from_sql_nullable(member_type, v) + })?; + if values.next()?.is_some() { + return Err(format!( + "excess elements in array (expected {}, got more than that)", + N, + ) + .into()); + } + + Ok(out) + } + + fn accepts(ty: &Type) -> bool { + match *ty.kind() { + Kind::Array(ref inner) => T::accepts(inner), + _ => false, + } + } +} + impl<'a> FromSql<'a> for Vec { fn from_sql(_: &Type, raw: &'a [u8]) -> Result, Box> { Ok(types::bytea_from_sql(raw).to_owned()) @@ -691,8 +734,10 @@ pub enum IsNull { /// /// # Arrays /// -/// `ToSql` is implemented for `Vec` and `&[T]` where `T` implements `ToSql`, -/// and corresponds to one-dimensional Postgres arrays with an index offset of 1. +/// `ToSql` is implemented for `Vec`, `&[T]` and `[T; N]` where `T` +/// implements `ToSql`, and corresponds to one-dimensional Postgres arrays with +/// an index offset of 1. **Note:** the impl for arrays only exist when the +/// Cargo feature `array-impls` is enabled. pub trait ToSql: fmt::Debug { /// Converts the value of `self` into the binary format of the specified /// Postgres `Type`, appending it to `out`. @@ -808,6 +853,19 @@ impl<'a> ToSql for &'a [u8] { to_sql_checked!(); } +#[cfg(feature = "array-impls")] +impl ToSql for [T; N] { + fn to_sql(&self, ty: &Type, w: &mut BytesMut) -> Result> { + <&[T] as ToSql>::to_sql(&&self[..], ty, w) + } + + fn accepts(ty: &Type) -> bool { + <&[T] as ToSql>::accepts(ty) + } + + to_sql_checked!(); +} + impl ToSql for Vec { fn to_sql(&self, ty: &Type, w: &mut BytesMut) -> Result> { <&[T] as ToSql>::to_sql(&&**self, ty, w) diff --git a/postgres/Cargo.toml b/postgres/Cargo.toml index c7c0746f0..ca1d0b232 100644 --- a/postgres/Cargo.toml +++ b/postgres/Cargo.toml @@ -21,6 +21,7 @@ all-features = true circle-ci = { repository = "sfackler/rust-postgres" } [features] +array-impls = ["tokio-postgres/array-impls"] with-bit-vec-0_6 = ["tokio-postgres/with-bit-vec-0_6"] with-chrono-0_4 = ["tokio-postgres/with-chrono-0_4"] with-eui48-0_4 = ["tokio-postgres/with-eui48-0_4"] diff --git a/tokio-postgres/Cargo.toml b/tokio-postgres/Cargo.toml index 3a1537a87..edffde49a 100644 --- a/tokio-postgres/Cargo.toml +++ b/tokio-postgres/Cargo.toml @@ -27,6 +27,7 @@ circle-ci = { repository = "sfackler/rust-postgres" } default = ["runtime"] runtime = ["tokio/net", "tokio/time"] +array-impls = ["postgres-types/array-impls"] with-bit-vec-0_6 = ["postgres-types/with-bit-vec-0_6"] with-chrono-0_4 = ["postgres-types/with-chrono-0_4"] with-eui48-0_4 = ["postgres-types/with-eui48-0_4"] diff --git a/tokio-postgres/tests/test/types/mod.rs b/tokio-postgres/tests/test/types/mod.rs index 85eed0e27..54a111b3a 100644 --- a/tokio-postgres/tests/test/types/mod.rs +++ b/tokio-postgres/tests/test/types/mod.rs @@ -350,7 +350,7 @@ async fn test_hstore_params() { } #[tokio::test] -async fn test_array_params() { +async fn test_array_vec_params() { test_type( "integer[]", &[ @@ -363,6 +363,18 @@ async fn test_array_params() { .await; } +#[cfg(feature = "array-impls")] +#[tokio::test] +async fn test_array_array_params() { + test_type("integer[]", &[(Some([1i32, 2i32]), "ARRAY[1,2]")]).await; + test_type("text[]", &[(Some(["peter".to_string()]), "ARRAY['peter']")]).await; + test_type( + "integer[]", + &[(Some([] as [i32; 0]), "ARRAY[]"), (None, "NULL")], + ) + .await; +} + #[allow(clippy::eq_op)] async fn test_nan_param(sql_type: &str) where From 06952e2bb09bdcc404b82f24774c5ada756a360f Mon Sep 17 00:00:00 2001 From: Lukas Kalbertodt Date: Tue, 13 Jul 2021 14:38:11 +0200 Subject: [PATCH 20/59] Use Rust 1.51 in CI We needed to bump the version because the `array-impls` feature requires const generics. --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4a95dbe0c..8b3a3420d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -59,7 +59,7 @@ jobs: - uses: actions/checkout@v2 - uses: sfackler/actions/rustup@master with: - version: 1.46.0 + version: 1.51.0 - run: echo "::set-output name=version::$(rustc --version)" id: rust-version - uses: actions/cache@v1 From 24928ebce3b7b5480d33a0593b8d89c1c4a11081 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 15 Jul 2021 13:10:25 +0000 Subject: [PATCH 21/59] Update env_logger requirement from 0.8 to 0.9 Updates the requirements on [env_logger](https://github.com/env-logger-rs/env_logger) to permit the latest version. - [Release notes](https://github.com/env-logger-rs/env_logger/releases) - [Changelog](https://github.com/env-logger-rs/env_logger/blob/main/CHANGELOG.md) - [Commits](https://github.com/env-logger-rs/env_logger/compare/v0.8.0...v0.9.0) --- updated-dependencies: - dependency-name: env_logger dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- tokio-postgres/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tokio-postgres/Cargo.toml b/tokio-postgres/Cargo.toml index edffde49a..db3a65f32 100644 --- a/tokio-postgres/Cargo.toml +++ b/tokio-postgres/Cargo.toml @@ -57,7 +57,7 @@ tokio-util = { version = "0.6", features = ["codec"] } [dev-dependencies] tokio = { version = "1.0", features = ["full"] } -env_logger = "0.8" +env_logger = "0.9" criterion = "0.3" bit-vec-06 = { version = "0.6", package = "bit-vec" } From da4e323578e868ff720d409e7c63dc41fa00bd3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ale=C5=A1=20Bizjak?= Date: Sun, 25 Jul 2021 22:02:28 +0200 Subject: [PATCH 22/59] Implement BorrowToSql for an additional type. Closes #811. --- postgres-types/src/lib.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/postgres-types/src/lib.rs b/postgres-types/src/lib.rs index 4c559b95a..59ec4f811 100644 --- a/postgres-types/src/lib.rs +++ b/postgres-types/src/lib.rs @@ -1042,6 +1042,19 @@ impl BorrowToSql for &dyn ToSql { } } +impl sealed::Sealed for &(dyn ToSql + Sync) {} + +/// In async contexts it is sometimes necessary to have the additional +/// Sync requirement on parameters for queries since this enables the +/// resulting Futures to be Send, hence usable in, e.g., tokio::spawn. +/// This instance is provided for those cases. +impl BorrowToSql for &(dyn ToSql + Sync) { + #[inline] + fn borrow_to_sql(&self) -> &dyn ToSql { + *self + } +} + impl sealed::Sealed for T where T: ToSql {} impl BorrowToSql for T From be0c85ac0b985986b7ffdf8e68cc91294481c2e2 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Tue, 10 Aug 2021 20:30:27 -0400 Subject: [PATCH 23/59] Update phf --- codegen/Cargo.toml | 2 +- tokio-postgres/Cargo.toml | 2 +- tokio-postgres/src/error/sqlstate.rs | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/codegen/Cargo.toml b/codegen/Cargo.toml index fc02751cf..14bebccf2 100644 --- a/codegen/Cargo.toml +++ b/codegen/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" authors = ["Steven Fackler "] [dependencies] -phf_codegen = "0.9" +phf_codegen = "0.10" regex = "1.0" marksman_escape = "0.1" linked-hash-map = "0.5" diff --git a/tokio-postgres/Cargo.toml b/tokio-postgres/Cargo.toml index db3a65f32..1bedf6b57 100644 --- a/tokio-postgres/Cargo.toml +++ b/tokio-postgres/Cargo.toml @@ -48,7 +48,7 @@ log = "0.4" parking_lot = "0.11" percent-encoding = "2.0" pin-project-lite = "0.2" -phf = "0.9" +phf = "0.10" postgres-protocol = { version = "0.6.1", path = "../postgres-protocol" } postgres-types = { version = "0.2.1", path = "../postgres-types" } socket2 = "0.4" diff --git a/tokio-postgres/src/error/sqlstate.rs b/tokio-postgres/src/error/sqlstate.rs index 1996d9b13..71648a948 100644 --- a/tokio-postgres/src/error/sqlstate.rs +++ b/tokio-postgres/src/error/sqlstate.rs @@ -1341,7 +1341,7 @@ enum Inner { static SQLSTATE_MAP: phf::Map<&'static str, SqlState> = ::phf::Map { key: 12913932095322966823, - disps: ::phf::Slice::Static(&[ + disps: &[ (0, 12), (0, 18), (0, 25), @@ -1394,8 +1394,8 @@ static SQLSTATE_MAP: phf::Map<&'static str, SqlState> = (0, 242), (0, 72), (16, 53), - ]), - entries: ::phf::Slice::Static(&[ + ], + entries: &[ ("22034", SqlState::MORE_THAN_ONE_SQL_JSON_ITEM), ("40P01", SqlState::T_R_DEADLOCK_DETECTED), ("42703", SqlState::UNDEFINED_COLUMN), @@ -1654,5 +1654,5 @@ static SQLSTATE_MAP: phf::Map<&'static str, SqlState> = ("25003", SqlState::INAPPROPRIATE_ACCESS_MODE_FOR_BRANCH_TRANSACTION), ("02001", SqlState::NO_ADDITIONAL_DYNAMIC_RESULT_SETS_RETURNED), ("42804", SqlState::DATATYPE_MISMATCH), - ]), + ], }; From a8a35eb6db62b878b168c5c53110be8d6a393b4c Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Tue, 10 Aug 2021 21:07:20 -0400 Subject: [PATCH 24/59] fix clippy --- postgres-derive/src/tosql.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/postgres-derive/src/tosql.rs b/postgres-derive/src/tosql.rs index a1c87b0ff..1808e787d 100644 --- a/postgres-derive/src/tosql.rs +++ b/postgres-derive/src/tosql.rs @@ -30,7 +30,7 @@ pub fn expand_derive_tosql(input: DeriveInput) -> Result { .. }) if fields.unnamed.len() == 1 => { let field = fields.unnamed.first().unwrap(); - (accepts::domain_body(&name, &field), domain_body()) + (accepts::domain_body(&name, field), domain_body()) } Data::Struct(DataStruct { fields: Fields::Named(ref fields), From 3e4be865318ddd4a6b4493d689703db32ca3d184 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Tue, 10 Aug 2021 21:17:50 -0400 Subject: [PATCH 25/59] more clippy --- postgres-types/src/lib.rs | 2 +- tokio-postgres/src/config.rs | 8 ++++---- tokio-postgres/src/prepare.rs | 8 ++++---- tokio-postgres/src/transaction.rs | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/postgres-types/src/lib.rs b/postgres-types/src/lib.rs index 59ec4f811..4dd87c71c 100644 --- a/postgres-types/src/lib.rs +++ b/postgres-types/src/lib.rs @@ -909,7 +909,7 @@ impl<'a> ToSql for &'a str { impl<'a> ToSql for Cow<'a, str> { fn to_sql(&self, ty: &Type, w: &mut BytesMut) -> Result> { - <&str as ToSql>::to_sql(&&self.as_ref(), ty, w) + <&str as ToSql>::to_sql(&self.as_ref(), ty, w) } fn accepts(ty: &Type) -> bool { diff --git a/tokio-postgres/src/config.rs b/tokio-postgres/src/config.rs index 111487173..eb4e5bdc5 100644 --- a/tokio-postgres/src/config.rs +++ b/tokio-postgres/src/config.rs @@ -390,19 +390,19 @@ impl Config { fn param(&mut self, key: &str, value: &str) -> Result<(), Error> { match key { "user" => { - self.user(&value); + self.user(value); } "password" => { self.password(value); } "dbname" => { - self.dbname(&value); + self.dbname(value); } "options" => { - self.options(&value); + self.options(value); } "application_name" => { - self.application_name(&value); + self.application_name(value); } "sslmode" => { let mode = match value { diff --git a/tokio-postgres/src/prepare.rs b/tokio-postgres/src/prepare.rs index 49397debf..7a6163415 100644 --- a/tokio-postgres/src/prepare.rs +++ b/tokio-postgres/src/prepare.rs @@ -86,7 +86,7 @@ pub async fn prepare( let mut parameters = vec![]; let mut it = parameter_description.parameters(); while let Some(oid) = it.next().map_err(Error::parse)? { - let type_ = get_type(&client, oid).await?; + let type_ = get_type(client, oid).await?; parameters.push(type_); } @@ -94,13 +94,13 @@ pub async fn prepare( if let Some(row_description) = row_description { let mut it = row_description.fields(); while let Some(field) = it.next().map_err(Error::parse)? { - let type_ = get_type(&client, field.type_oid()).await?; + let type_ = get_type(client, field.type_oid()).await?; let column = Column::new(field.name().to_string(), type_); columns.push(column); } } - Ok(Statement::new(&client, name, parameters, columns)) + Ok(Statement::new(client, name, parameters, columns)) } fn prepare_rec<'a>( @@ -120,7 +120,7 @@ fn encode(client: &InnerClient, name: &str, query: &str, types: &[Type]) -> Resu client.with_buf(|buf| { frontend::parse(name, query, types.iter().map(Type::oid), buf).map_err(Error::encode)?; - frontend::describe(b'S', &name, buf).map_err(Error::encode)?; + frontend::describe(b'S', name, buf).map_err(Error::encode)?; frontend::sync(buf); Ok(buf.split().freeze()) }) diff --git a/tokio-postgres/src/transaction.rs b/tokio-postgres/src/transaction.rs index a1aa7611f..b72b119bf 100644 --- a/tokio-postgres/src/transaction.rs +++ b/tokio-postgres/src/transaction.rs @@ -201,7 +201,7 @@ impl<'a> Transaction<'a> { I: IntoIterator, I::IntoIter: ExactSizeIterator, { - let statement = statement.__convert().into_statement(&self.client).await?; + let statement = statement.__convert().into_statement(self.client).await?; bind::bind(self.client.inner(), statement, params).await } From be0d71fad51b9ea070493ed44a2ab15557635b85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lauren=C8=9Biu=20Nicola?= Date: Thu, 23 Sep 2021 19:28:02 +0300 Subject: [PATCH 26/59] Add support for time 0.3 --- postgres-types/Cargo.toml | 2 + postgres-types/src/lib.rs | 2 + postgres-types/src/time_03.rs | 108 +++++++++++++++ postgres/Cargo.toml | 1 + postgres/src/lib.rs | 3 +- tokio-postgres/Cargo.toml | 3 +- tokio-postgres/src/lib.rs | 3 +- tokio-postgres/tests/test/types/mod.rs | 2 + tokio-postgres/tests/test/types/time_03.rs | 149 +++++++++++++++++++++ 9 files changed, 270 insertions(+), 3 deletions(-) create mode 100644 postgres-types/src/time_03.rs create mode 100644 tokio-postgres/tests/test/types/time_03.rs diff --git a/postgres-types/Cargo.toml b/postgres-types/Cargo.toml index 4fd69f613..8fc6ed107 100644 --- a/postgres-types/Cargo.toml +++ b/postgres-types/Cargo.toml @@ -22,6 +22,7 @@ with-geo-types-0_7 = ["geo-types-0_7"] with-serde_json-1 = ["serde-1", "serde_json-1"] with-uuid-0_8 = ["uuid-08"] with-time-0_2 = ["time-02"] +with-time-0_3 = ["time-03"] [dependencies] bytes = "1.0" @@ -40,3 +41,4 @@ serde-1 = { version = "1.0", package = "serde", optional = true } serde_json-1 = { version = "1.0", package = "serde_json", optional = true } uuid-08 = { version = "0.8", package = "uuid", optional = true } time-02 = { version = "0.2", package = "time", optional = true } +time-03 = { version = "0.3", package = "time", default-features = false, optional = true } diff --git a/postgres-types/src/lib.rs b/postgres-types/src/lib.rs index 4dd87c71c..2a953db2f 100644 --- a/postgres-types/src/lib.rs +++ b/postgres-types/src/lib.rs @@ -209,6 +209,8 @@ mod geo_types_07; mod serde_json_1; #[cfg(feature = "with-time-0_2")] mod time_02; +#[cfg(feature = "with-time-0_3")] +mod time_03; #[cfg(feature = "with-uuid-0_8")] mod uuid_08; diff --git a/postgres-types/src/time_03.rs b/postgres-types/src/time_03.rs new file mode 100644 index 000000000..f136fab7c --- /dev/null +++ b/postgres-types/src/time_03.rs @@ -0,0 +1,108 @@ +use bytes::BytesMut; +use postgres_protocol::types; +use std::convert::TryFrom; +use std::error::Error; +use time_03::{Date, Duration, OffsetDateTime, PrimitiveDateTime, Time, UtcOffset}; + +use crate::{FromSql, IsNull, ToSql, Type}; + +fn base() -> PrimitiveDateTime { + PrimitiveDateTime::new(Date::from_ordinal_date(2000, 1).unwrap(), Time::MIDNIGHT) +} + +impl<'a> FromSql<'a> for PrimitiveDateTime { + fn from_sql(_: &Type, raw: &[u8]) -> Result> { + let t = types::timestamp_from_sql(raw)?; + Ok(base() + Duration::microseconds(t)) + } + + accepts!(TIMESTAMP); +} + +impl ToSql for PrimitiveDateTime { + fn to_sql(&self, _: &Type, w: &mut BytesMut) -> Result> { + let time = match i64::try_from((*self - base()).whole_microseconds()) { + Ok(time) => time, + Err(_) => return Err("value too large to transmit".into()), + }; + types::timestamp_to_sql(time, w); + Ok(IsNull::No) + } + + accepts!(TIMESTAMP); + to_sql_checked!(); +} + +impl<'a> FromSql<'a> for OffsetDateTime { + fn from_sql(type_: &Type, raw: &[u8]) -> Result> { + let primitive = PrimitiveDateTime::from_sql(type_, raw)?; + Ok(primitive.assume_utc()) + } + + accepts!(TIMESTAMPTZ); +} + +impl ToSql for OffsetDateTime { + fn to_sql( + &self, + type_: &Type, + w: &mut BytesMut, + ) -> Result> { + let utc_datetime = self.to_offset(UtcOffset::UTC); + let date = utc_datetime.date(); + let time = utc_datetime.time(); + let primitive = PrimitiveDateTime::new(date, time); + primitive.to_sql(type_, w) + } + + accepts!(TIMESTAMPTZ); + to_sql_checked!(); +} + +impl<'a> FromSql<'a> for Date { + fn from_sql(_: &Type, raw: &[u8]) -> Result> { + let jd = types::date_from_sql(raw)?; + Ok(base().date() + Duration::days(i64::from(jd))) + } + + accepts!(DATE); +} + +impl ToSql for Date { + fn to_sql(&self, _: &Type, w: &mut BytesMut) -> Result> { + let jd = (*self - base().date()).whole_days(); + if jd > i64::from(i32::max_value()) || jd < i64::from(i32::min_value()) { + return Err("value too large to transmit".into()); + } + + types::date_to_sql(jd as i32, w); + Ok(IsNull::No) + } + + accepts!(DATE); + to_sql_checked!(); +} + +impl<'a> FromSql<'a> for Time { + fn from_sql(_: &Type, raw: &[u8]) -> Result> { + let usec = types::time_from_sql(raw)?; + Ok(Time::MIDNIGHT + Duration::microseconds(usec)) + } + + accepts!(TIME); +} + +impl ToSql for Time { + fn to_sql(&self, _: &Type, w: &mut BytesMut) -> Result> { + let delta = *self - Time::MIDNIGHT; + let time = match i64::try_from(delta.whole_microseconds()) { + Ok(time) => time, + Err(_) => return Err("value too large to transmit".into()), + }; + types::time_to_sql(time, w); + Ok(IsNull::No) + } + + accepts!(TIME); + to_sql_checked!(); +} diff --git a/postgres/Cargo.toml b/postgres/Cargo.toml index ca1d0b232..3d1c20234 100644 --- a/postgres/Cargo.toml +++ b/postgres/Cargo.toml @@ -31,6 +31,7 @@ with-geo-types-0_7 = ["tokio-postgres/with-geo-types-0_7"] with-serde_json-1 = ["tokio-postgres/with-serde_json-1"] with-uuid-0_8 = ["tokio-postgres/with-uuid-0_8"] with-time-0_2 = ["tokio-postgres/with-time-0_2"] +with-time-0_3 = ["tokio-postgres/with-time-0_3"] [dependencies] bytes = "1.0" diff --git a/postgres/src/lib.rs b/postgres/src/lib.rs index 7d96bfd9f..a599532e4 100644 --- a/postgres/src/lib.rs +++ b/postgres/src/lib.rs @@ -61,7 +61,8 @@ //! | `with-geo-types-0_7` | Enable support for the 0.7 version of the `geo-types` crate. | [geo-types](https://crates.io/crates/geo-types/0.7.0) 0.7 | no | //! | `with-serde_json-1` | Enable support for the `serde_json` crate. | [serde_json](https://crates.io/crates/serde_json) 1.0 | no | //! | `with-uuid-0_8` | Enable support for the `uuid` crate. | [uuid](https://crates.io/crates/uuid) 0.8 | no | -//! | `with-time-0_2` | Enable support for the `time` crate. | [time](https://crates.io/crates/time) 0.2 | no | +//! | `with-time-0_2` | Enable support for the 0.2 version of the `time` crate. | [time](https://crates.io/crates/time/0.2.0) 0.2 | no | +//! | `with-time-0_3` | Enable support for the 0.3 version of the `time` crate. | [time](https://crates.io/crates/time/0.3.0) 0.3 | no | #![warn(clippy::all, rust_2018_idioms, missing_docs)] pub use fallible_iterator; diff --git a/tokio-postgres/Cargo.toml b/tokio-postgres/Cargo.toml index 1bedf6b57..d35a323a1 100644 --- a/tokio-postgres/Cargo.toml +++ b/tokio-postgres/Cargo.toml @@ -37,6 +37,7 @@ with-geo-types-0_7 = ["postgres-types/with-geo-types-0_7"] with-serde_json-1 = ["postgres-types/with-serde_json-1"] with-uuid-0_8 = ["postgres-types/with-uuid-0_8"] with-time-0_2 = ["postgres-types/with-time-0_2"] +with-time-0_3 = ["postgres-types/with-time-0_3"] [dependencies] async-trait = "0.1" @@ -70,4 +71,4 @@ serde-1 = { version = "1.0", package = "serde" } serde_json-1 = { version = "1.0", package = "serde_json" } uuid-08 = { version = "0.8", package = "uuid" } time-02 = { version = "0.2", package = "time" } - +time-03 = { version = "0.3", package = "time", features = ["parsing"] } diff --git a/tokio-postgres/src/lib.rs b/tokio-postgres/src/lib.rs index 6dd0b0151..e9516e0b3 100644 --- a/tokio-postgres/src/lib.rs +++ b/tokio-postgres/src/lib.rs @@ -112,7 +112,8 @@ //! | `with-geo-types-0_7` | Enable support for the 0.7 version of the `geo-types` crate. | [geo-types](https://crates.io/crates/geo-types/0.7.0) 0.7 | no | //! | `with-serde_json-1` | Enable support for the `serde_json` crate. | [serde_json](https://crates.io/crates/serde_json) 1.0 | no | //! | `with-uuid-0_8` | Enable support for the `uuid` crate. | [uuid](https://crates.io/crates/uuid) 0.8 | no | -//! | `with-time-0_2` | Enable support for the `time` crate. | [time](https://crates.io/crates/time) 0.2 | no | +//! | `with-time-0_2` | Enable support for the 0.2 version of the `time` crate. | [time](https://crates.io/crates/time/0.2.0) 0.2 | no | +//! | `with-time-0_3` | Enable support for the 0.3 version of the `time` crate. | [time](https://crates.io/crates/time/0.3.0) 0.3 | no | #![doc(html_root_url = "https://docs.rs/tokio-postgres/0.7")] #![warn(rust_2018_idioms, clippy::all, missing_docs)] diff --git a/tokio-postgres/tests/test/types/mod.rs b/tokio-postgres/tests/test/types/mod.rs index 54a111b3a..604e2de32 100644 --- a/tokio-postgres/tests/test/types/mod.rs +++ b/tokio-postgres/tests/test/types/mod.rs @@ -29,6 +29,8 @@ mod geo_types_07; mod serde_json_1; #[cfg(feature = "with-time-0_2")] mod time_02; +#[cfg(feature = "with-time-0_3")] +mod time_03; #[cfg(feature = "with-uuid-0_8")] mod uuid_08; diff --git a/tokio-postgres/tests/test/types/time_03.rs b/tokio-postgres/tests/test/types/time_03.rs new file mode 100644 index 000000000..df013c9bf --- /dev/null +++ b/tokio-postgres/tests/test/types/time_03.rs @@ -0,0 +1,149 @@ +use time_03::{format_description, OffsetDateTime, PrimitiveDateTime}; +use tokio_postgres::types::{Date, Timestamp}; + +use crate::types::test_type; + +// time 0.2 does not [yet?] support parsing fractional seconds +// https://github.com/time-rs/time/issues/226 + +#[tokio::test] +async fn test_primitive_date_time_params() { + fn make_check(time: &str) -> (Option, &str) { + let format = + format_description::parse("'[year]-[month]-[day] [hour]:[minute]:[second]'").unwrap(); + (Some(PrimitiveDateTime::parse(time, &format).unwrap()), time) + } + test_type( + "TIMESTAMP", + &[ + make_check("'1970-01-01 00:00:00'"), // .010000000 + make_check("'1965-09-25 11:19:33'"), // .100314000 + make_check("'2010-02-09 23:11:45'"), // .120200000 + (None, "NULL"), + ], + ) + .await; +} + +#[tokio::test] +async fn test_with_special_primitive_date_time_params() { + fn make_check(time: &str) -> (Timestamp, &str) { + let format = + format_description::parse("'[year]-[month]-[day] [hour]:[minute]:[second]'").unwrap(); + ( + Timestamp::Value(PrimitiveDateTime::parse(time, &format).unwrap()), + time, + ) + } + test_type( + "TIMESTAMP", + &[ + make_check("'1970-01-01 00:00:00'"), // .010000000 + make_check("'1965-09-25 11:19:33'"), // .100314000 + make_check("'2010-02-09 23:11:45'"), // .120200000 + (Timestamp::PosInfinity, "'infinity'"), + (Timestamp::NegInfinity, "'-infinity'"), + ], + ) + .await; +} + +#[tokio::test] +async fn test_offset_date_time_params() { + fn make_check(time: &str) -> (Option, &str) { + let format = + format_description::parse("'[year]-[month]-[day] [hour]:[minute]:[second] [offset_hour sign:mandatory][offset_minute]'").unwrap(); + (Some(OffsetDateTime::parse(time, &format).unwrap()), time) + } + test_type( + "TIMESTAMP WITH TIME ZONE", + &[ + make_check("'1970-01-01 00:00:00 +0000'"), // .010000000 + make_check("'1965-09-25 11:19:33 +0000'"), // .100314000 + make_check("'2010-02-09 23:11:45 +0000'"), // .120200000 + (None, "NULL"), + ], + ) + .await; +} + +#[tokio::test] +async fn test_with_special_offset_date_time_params() { + fn make_check(time: &str) -> (Timestamp, &str) { + let format = + format_description::parse("'[year]-[month]-[day] [hour]:[minute]:[second] [offset_hour sign:mandatory][offset_minute]'").unwrap(); + ( + Timestamp::Value(OffsetDateTime::parse(time, &format).unwrap()), + time, + ) + } + test_type( + "TIMESTAMP WITH TIME ZONE", + &[ + make_check("'1970-01-01 00:00:00 +0000'"), // .010000000 + make_check("'1965-09-25 11:19:33 +0000'"), // .100314000 + make_check("'2010-02-09 23:11:45 +0000'"), // .120200000 + (Timestamp::PosInfinity, "'infinity'"), + (Timestamp::NegInfinity, "'-infinity'"), + ], + ) + .await; +} + +#[tokio::test] +async fn test_date_params() { + fn make_check(date: &str) -> (Option, &str) { + let format = format_description::parse("'[year]-[month]-[day]'").unwrap(); + (Some(time_03::Date::parse(date, &format).unwrap()), date) + } + test_type( + "DATE", + &[ + make_check("'1970-01-01'"), + make_check("'1965-09-25'"), + make_check("'2010-02-09'"), + (None, "NULL"), + ], + ) + .await; +} + +#[tokio::test] +async fn test_with_special_date_params() { + fn make_check(date: &str) -> (Date, &str) { + let format = format_description::parse("'[year]-[month]-[day]'").unwrap(); + ( + Date::Value(time_03::Date::parse(date, &format).unwrap()), + date, + ) + } + test_type( + "DATE", + &[ + make_check("'1970-01-01'"), + make_check("'1965-09-25'"), + make_check("'2010-02-09'"), + (Date::PosInfinity, "'infinity'"), + (Date::NegInfinity, "'-infinity'"), + ], + ) + .await; +} + +#[tokio::test] +async fn test_time_params() { + fn make_check(time: &str) -> (Option, &str) { + let format = format_description::parse("'[hour]:[minute]:[second]'").unwrap(); + (Some(time_03::Time::parse(time, &format).unwrap()), time) + } + test_type( + "TIME", + &[ + make_check("'00:00:00'"), // .010000000 + make_check("'11:19:33'"), // .100314000 + make_check("'23:11:45'"), // .120200000 + (None, "NULL"), + ], + ) + .await; +} From 34d8b77644880dbaef1bcd7e8aa246dc59e90d11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lauren=C8=9Biu=20Nicola?= Date: Fri, 24 Sep 2021 08:41:18 +0300 Subject: [PATCH 27/59] Add feature gates for doctests --- postgres-native-tls/src/lib.rs | 6 ++++++ postgres-openssl/src/lib.rs | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/postgres-native-tls/src/lib.rs b/postgres-native-tls/src/lib.rs index 2f2e6e6ad..a06f185b5 100644 --- a/postgres-native-tls/src/lib.rs +++ b/postgres-native-tls/src/lib.rs @@ -4,10 +4,12 @@ //! //! ```no_run //! use native_tls::{Certificate, TlsConnector}; +//! # #[cfg(feature = "runtime")] //! use postgres_native_tls::MakeTlsConnector; //! use std::fs; //! //! # fn main() -> Result<(), Box> { +//! # #[cfg(feature = "runtime")] { //! let cert = fs::read("database_cert.pem")?; //! let cert = Certificate::from_pem(&cert)?; //! let connector = TlsConnector::builder() @@ -19,6 +21,7 @@ //! "host=localhost user=postgres sslmode=require", //! connector, //! ); +//! # } //! //! // ... //! # Ok(()) @@ -27,10 +30,12 @@ //! //! ```no_run //! use native_tls::{Certificate, TlsConnector}; +//! # #[cfg(feature = "runtime")] //! use postgres_native_tls::MakeTlsConnector; //! use std::fs; //! //! # fn main() -> Result<(), Box> { +//! # #[cfg(feature = "runtime")] { //! let cert = fs::read("database_cert.pem")?; //! let cert = Certificate::from_pem(&cert)?; //! let connector = TlsConnector::builder() @@ -42,6 +47,7 @@ //! "host=localhost user=postgres sslmode=require", //! connector, //! )?; +//! # } //! # Ok(()) //! # } //! ``` diff --git a/postgres-openssl/src/lib.rs b/postgres-openssl/src/lib.rs index f3c0b9309..49fc2807c 100644 --- a/postgres-openssl/src/lib.rs +++ b/postgres-openssl/src/lib.rs @@ -4,9 +4,11 @@ //! //! ```no_run //! use openssl::ssl::{SslConnector, SslMethod}; +//! # #[cfg(feature = "runtime")] //! use postgres_openssl::MakeTlsConnector; //! //! # fn main() -> Result<(), Box> { +//! # #[cfg(feature = "runtime")] { //! let mut builder = SslConnector::builder(SslMethod::tls())?; //! builder.set_ca_file("database_cert.pem")?; //! let connector = MakeTlsConnector::new(builder.build()); @@ -15,6 +17,7 @@ //! "host=localhost user=postgres sslmode=require", //! connector, //! ); +//! # } //! //! // ... //! # Ok(()) @@ -23,9 +26,11 @@ //! //! ```no_run //! use openssl::ssl::{SslConnector, SslMethod}; +//! # #[cfg(feature = "runtime")] //! use postgres_openssl::MakeTlsConnector; //! //! # fn main() -> Result<(), Box> { +//! # #[cfg(feature = "runtime")] { //! let mut builder = SslConnector::builder(SslMethod::tls())?; //! builder.set_ca_file("database_cert.pem")?; //! let connector = MakeTlsConnector::new(builder.build()); @@ -34,6 +39,7 @@ //! "host=localhost user=postgres sslmode=require", //! connector, //! )?; +//! # } //! //! // ... //! # Ok(()) From c7785d0b10bf629b1dbf915d24f370d5e11da4f4 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Wed, 29 Sep 2021 19:24:46 -0400 Subject: [PATCH 28/59] Release postgres-types v0.2.2 --- postgres-types/CHANGELOG.md | 8 ++++++++ postgres-types/Cargo.toml | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/postgres-types/CHANGELOG.md b/postgres-types/CHANGELOG.md index 83bc4d1fd..f8b2835eb 100644 --- a/postgres-types/CHANGELOG.md +++ b/postgres-types/CHANGELOG.md @@ -1,5 +1,13 @@ # Change Log +## v0.2.2 - 2021-09-29 + +### Added + +* Added support for `eui48` 1.0 via the `with-eui48-1` feature. +* Added `ToSql` and `FromSql` implementations for array types via the `array-impls` feature. +* Added support for `time` 0.3 via the `with-time-0_3` feature. + ## v0.2.1 - 2021-04-03 ### Added diff --git a/postgres-types/Cargo.toml b/postgres-types/Cargo.toml index 8fc6ed107..7eca3fbcf 100644 --- a/postgres-types/Cargo.toml +++ b/postgres-types/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "postgres-types" -version = "0.2.1" +version = "0.2.2" authors = ["Steven Fackler "] edition = "2018" license = "MIT/Apache-2.0" From 349c38b1fe77eae6b27a2ca65d760bff984382e7 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Wed, 29 Sep 2021 19:27:15 -0400 Subject: [PATCH 29/59] Release postgres-protocol v0.6.2 --- postgres-protocol/CHANGELOG.md | 6 ++++++ postgres-protocol/Cargo.toml | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/postgres-protocol/CHANGELOG.md b/postgres-protocol/CHANGELOG.md index 7a51cb192..eb37f5883 100644 --- a/postgres-protocol/CHANGELOG.md +++ b/postgres-protocol/CHANGELOG.md @@ -1,5 +1,11 @@ # Change Log +## v0.6.2 - 2021-09-29 + +### Changed + +* Upgraded `hmac`. + ## v0.6.1 - 2021-04-03 ### Added diff --git a/postgres-protocol/Cargo.toml b/postgres-protocol/Cargo.toml index d4ae8c301..a4ed3e907 100644 --- a/postgres-protocol/Cargo.toml +++ b/postgres-protocol/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "postgres-protocol" -version = "0.6.1" +version = "0.6.2" authors = ["Steven Fackler "] edition = "2018" description = "Low level Postgres protocol APIs" From 8542d078bfcd88dcb92ceae7ec9d17364586f3a2 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Wed, 29 Sep 2021 19:34:32 -0400 Subject: [PATCH 30/59] Release tokio-postgres v0.7.2 --- tokio-postgres/CHANGELOG.md | 13 +++++++++++++ tokio-postgres/Cargo.toml | 4 ++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/tokio-postgres/CHANGELOG.md b/tokio-postgres/CHANGELOG.md index 3a7aa2ae7..2c2ea5bc8 100644 --- a/tokio-postgres/CHANGELOG.md +++ b/tokio-postgres/CHANGELOG.md @@ -1,5 +1,18 @@ # Change Log +## v0.7.2 - 2021-09-29 + +### Fixed + +* Fixed a deadlock when pipelined requests concurrently prepare cached typeinfo queries. + +### Added + +* Added `SimpleQueryRow::columns`. +* Added support for `eui48` 1.0 via the `with-eui48-1` feature. +* Added `FromSql` and `ToSql` implementations for arrays via the `array-impls` feature. +* Added support for `time` 0.3 via the `with-time-0_3` feature. + ## v0.7.2 - 2021-04-25 ### Fixed diff --git a/tokio-postgres/Cargo.toml b/tokio-postgres/Cargo.toml index d35a323a1..65f65d641 100644 --- a/tokio-postgres/Cargo.toml +++ b/tokio-postgres/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tokio-postgres" -version = "0.7.2" +version = "0.7.3" authors = ["Steven Fackler "] edition = "2018" license = "MIT/Apache-2.0" @@ -51,7 +51,7 @@ percent-encoding = "2.0" pin-project-lite = "0.2" phf = "0.10" postgres-protocol = { version = "0.6.1", path = "../postgres-protocol" } -postgres-types = { version = "0.2.1", path = "../postgres-types" } +postgres-types = { version = "0.2.2", path = "../postgres-types" } socket2 = "0.4" tokio = { version = "1.0", features = ["io-util"] } tokio-util = { version = "0.6", features = ["codec"] } From d45461614aca87022c17a2cc26b22325bf161fa5 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Wed, 29 Sep 2021 19:38:29 -0400 Subject: [PATCH 31/59] Release postgres v0.19.2 --- postgres/CHANGELOG.md | 9 +++++++++ postgres/Cargo.toml | 4 ++-- tokio-postgres/CHANGELOG.md | 2 +- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/postgres/CHANGELOG.md b/postgres/CHANGELOG.md index e68dedc5b..6af8d914b 100644 --- a/postgres/CHANGELOG.md +++ b/postgres/CHANGELOG.md @@ -1,5 +1,14 @@ # Change Log +## v0.19.2 - 2021-09-29 + +### Added + +* Added `SimpleQueryRow::columns`. +* Added support for `eui48` 1.0 via the `with-eui48-1` feature. +* Added `FromSql` and `ToSql` implementations for arrays via the `array-impls` feature. +* Added support for `time` 0.3 via the `with-time-0_3` feature. + ## v0.19.1 - 2021-04-03 ### Added diff --git a/postgres/Cargo.toml b/postgres/Cargo.toml index 3d1c20234..b61e42aca 100644 --- a/postgres/Cargo.toml +++ b/postgres/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "postgres" -version = "0.19.1" +version = "0.19.2" authors = ["Steven Fackler "] edition = "2018" license = "MIT/Apache-2.0" @@ -37,7 +37,7 @@ with-time-0_3 = ["tokio-postgres/with-time-0_3"] bytes = "1.0" fallible-iterator = "0.2" futures = "0.3" -tokio-postgres = { version = "0.7.1", path = "../tokio-postgres" } +tokio-postgres = { version = "0.7.2", path = "../tokio-postgres" } tokio = { version = "1.0", features = ["rt", "time"] } log = "0.4" diff --git a/tokio-postgres/CHANGELOG.md b/tokio-postgres/CHANGELOG.md index 2c2ea5bc8..9e70c0045 100644 --- a/tokio-postgres/CHANGELOG.md +++ b/tokio-postgres/CHANGELOG.md @@ -1,6 +1,6 @@ # Change Log -## v0.7.2 - 2021-09-29 +## v0.7.3 - 2021-09-29 ### Fixed From b2df11579f8b49728d3096b6bd6da0b7ab27ccf0 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Tue, 19 Oct 2021 19:36:14 -0400 Subject: [PATCH 32/59] Fix commit-time error reporting Closes #832 --- tokio-postgres/src/query.rs | 25 ++++++++++++++----------- tokio-postgres/tests/test/main.rs | 26 ++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 11 deletions(-) diff --git a/tokio-postgres/src/query.rs b/tokio-postgres/src/query.rs index f139ed915..cdb952190 100644 --- a/tokio-postgres/src/query.rs +++ b/tokio-postgres/src/query.rs @@ -99,11 +99,12 @@ where }; let mut responses = start(client, buf).await?; + let mut rows = 0; loop { match responses.next().await? { Message::DataRow(_) => {} Message::CommandComplete(body) => { - let rows = body + rows = body .tag() .map_err(Error::parse)? .rsplit(' ') @@ -111,9 +112,9 @@ where .unwrap() .parse() .unwrap_or(0); - return Ok(rows); } - Message::EmptyQueryResponse => return Ok(0), + Message::EmptyQueryResponse => rows = 0, + Message::ReadyForQuery(_) => return Ok(rows), _ => return Err(Error::unexpected_message()), } } @@ -203,15 +204,17 @@ impl Stream for RowStream { fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let this = self.project(); - match ready!(this.responses.poll_next(cx)?) { - Message::DataRow(body) => { - Poll::Ready(Some(Ok(Row::new(this.statement.clone(), body)?))) + loop { + match ready!(this.responses.poll_next(cx)?) { + Message::DataRow(body) => { + return Poll::Ready(Some(Ok(Row::new(this.statement.clone(), body)?))) + } + Message::EmptyQueryResponse + | Message::CommandComplete(_) + | Message::PortalSuspended => {} + Message::ReadyForQuery(_) => return Poll::Ready(None), + _ => return Poll::Ready(Some(Err(Error::unexpected_message()))), } - Message::EmptyQueryResponse - | Message::CommandComplete(_) - | Message::PortalSuspended => Poll::Ready(None), - Message::ErrorResponse(body) => Poll::Ready(Some(Err(Error::db(body)))), - _ => Poll::Ready(Some(Err(Error::unexpected_message()))), } } } diff --git a/tokio-postgres/tests/test/main.rs b/tokio-postgres/tests/test/main.rs index c0b4bf202..31d7fa295 100644 --- a/tokio-postgres/tests/test/main.rs +++ b/tokio-postgres/tests/test/main.rs @@ -805,3 +805,29 @@ async fn query_opt() { .err() .unwrap(); } + +#[tokio::test] +async fn deferred_constraint() { + let client = connect("user=postgres").await; + + client + .batch_execute( + " + CREATE TEMPORARY TABLE t ( + i INT, + UNIQUE (i) DEFERRABLE INITIALLY DEFERRED + ); + ", + ) + .await + .unwrap(); + + client + .execute("INSERT INTO t (i) VALUES (1)", &[]) + .await + .unwrap(); + client + .execute("INSERT INTO t (i) VALUES (1)", &[]) + .await + .unwrap_err(); +} From 0adcf58555fa1a5f42bdab512ea462ca993cad62 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Tue, 19 Oct 2021 19:58:49 -0400 Subject: [PATCH 33/59] Release tokio-postgres v0.7.4 --- tokio-postgres/CHANGELOG.md | 6 ++++++ tokio-postgres/Cargo.toml | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/tokio-postgres/CHANGELOG.md b/tokio-postgres/CHANGELOG.md index 9e70c0045..34b4fc1d9 100644 --- a/tokio-postgres/CHANGELOG.md +++ b/tokio-postgres/CHANGELOG.md @@ -1,5 +1,11 @@ # Change Log +## v0.7.4 - 2021-10-19 + +### Fixed + +* Fixed reporting of commit-time errors triggered by deferred constraints. + ## v0.7.3 - 2021-09-29 ### Fixed diff --git a/tokio-postgres/Cargo.toml b/tokio-postgres/Cargo.toml index 65f65d641..17286dc21 100644 --- a/tokio-postgres/Cargo.toml +++ b/tokio-postgres/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tokio-postgres" -version = "0.7.3" +version = "0.7.4" authors = ["Steven Fackler "] edition = "2018" license = "MIT/Apache-2.0" From f6189a95f24af45068ecfd6e3c4e6b71ac8e43fe Mon Sep 17 00:00:00 2001 From: ilslv Date: Thu, 28 Oct 2021 12:10:30 +0300 Subject: [PATCH 34/59] Fix transaction not being rolled back on `Client::transaction()` `Future` dropped before completion --- tokio-postgres/src/client.rs | 41 +++++++++- tokio-postgres/tests/test/main.rs | 122 +++++++++++++++++++++++++++++- 2 files changed, 159 insertions(+), 4 deletions(-) diff --git a/tokio-postgres/src/client.rs b/tokio-postgres/src/client.rs index 4a099d941..dea77da94 100644 --- a/tokio-postgres/src/client.rs +++ b/tokio-postgres/src/client.rs @@ -1,4 +1,4 @@ -use crate::codec::BackendMessages; +use crate::codec::{BackendMessages, FrontendMessage}; use crate::config::{Host, SslMode}; use crate::connection::{Request, RequestMessages}; use crate::copy_out::CopyOutStream; @@ -19,7 +19,7 @@ use fallible_iterator::FallibleIterator; use futures::channel::mpsc; use futures::{future, pin_mut, ready, StreamExt, TryStreamExt}; use parking_lot::Mutex; -use postgres_protocol::message::backend::Message; +use postgres_protocol::message::{backend::Message, frontend}; use postgres_types::BorrowToSql; use std::collections::HashMap; use std::fmt; @@ -488,7 +488,42 @@ impl Client { /// /// The transaction will roll back by default - use the `commit` method to commit it. pub async fn transaction(&mut self) -> Result, Error> { - self.batch_execute("BEGIN").await?; + struct RollbackIfNotDone<'me> { + client: &'me Client, + done: bool, + } + + impl<'a> Drop for RollbackIfNotDone<'a> { + fn drop(&mut self) { + if self.done { + return; + } + + let buf = self.client.inner().with_buf(|buf| { + frontend::query("ROLLBACK", buf).unwrap(); + buf.split().freeze() + }); + let _ = self + .client + .inner() + .send(RequestMessages::Single(FrontendMessage::Raw(buf))); + } + } + + // This is done, as `Future` created by this method can be dropped after + // `RequestMessages` is synchronously send to the `Connection` by + // `batch_execute()`, but before `Responses` is asynchronously polled to + // completion. In that case `Transaction` won't be created and thus + // won't be rolled back. + { + let mut cleaner = RollbackIfNotDone { + client: self, + done: false, + }; + self.batch_execute("BEGIN").await?; + cleaner.done = true; + } + Ok(Transaction::new(self)) } diff --git a/tokio-postgres/tests/test/main.rs b/tokio-postgres/tests/test/main.rs index 31d7fa295..dcfbc5308 100644 --- a/tokio-postgres/tests/test/main.rs +++ b/tokio-postgres/tests/test/main.rs @@ -3,9 +3,12 @@ use bytes::{Bytes, BytesMut}; use futures::channel::mpsc; use futures::{ - future, join, pin_mut, stream, try_join, FutureExt, SinkExt, StreamExt, TryStreamExt, + future, join, pin_mut, stream, try_join, Future, FutureExt, SinkExt, StreamExt, TryStreamExt, }; +use pin_project_lite::pin_project; use std::fmt::Write; +use std::pin::Pin; +use std::task::{Context, Poll}; use std::time::Duration; use tokio::net::TcpStream; use tokio::time; @@ -22,6 +25,35 @@ mod parse; mod runtime; mod types; +pin_project! { + /// Polls `F` at most `polls_left` times returning `Some(F::Output)` if + /// [`Future`] returned [`Poll::Ready`] or [`None`] otherwise. + struct Cancellable { + #[pin] + fut: F, + polls_left: usize, + } +} + +impl Future for Cancellable { + type Output = Option; + + fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll { + let this = self.project(); + match this.fut.poll(ctx) { + Poll::Ready(r) => Poll::Ready(Some(r)), + Poll::Pending => { + *this.polls_left = this.polls_left.saturating_sub(1); + if *this.polls_left == 0 { + Poll::Ready(None) + } else { + Poll::Pending + } + } + } + } +} + async fn connect_raw(s: &str) -> Result<(Client, Connection), Error> { let socket = TcpStream::connect("127.0.0.1:5433").await.unwrap(); let config = s.parse::().unwrap(); @@ -35,6 +67,20 @@ async fn connect(s: &str) -> Client { client } +async fn current_transaction_id(client: &Client) -> i64 { + client + .query("SELECT txid_current()", &[]) + .await + .unwrap() + .pop() + .unwrap() + .get::<_, i64>("txid_current") +} + +async fn in_transaction(client: &Client) -> bool { + current_transaction_id(client).await == current_transaction_id(client).await +} + #[tokio::test] async fn plain_password_missing() { connect_raw("user=pass_user dbname=postgres") @@ -377,6 +423,80 @@ async fn transaction_rollback() { assert_eq!(rows.len(), 0); } +#[tokio::test] +async fn transaction_future_cancellation() { + let mut client = connect("user=postgres").await; + + for i in 0.. { + let done = { + let txn = client.transaction(); + let fut = Cancellable { + fut: txn, + polls_left: i, + }; + fut.await + .map(|res| res.expect("transaction failed")) + .is_some() + }; + + assert!(!in_transaction(&client).await); + + if done { + break; + } + } +} + +#[tokio::test] +async fn transaction_commit_future_cancellation() { + let mut client = connect("user=postgres").await; + + for i in 0.. { + let done = { + let txn = client.transaction().await.unwrap(); + let commit = txn.commit(); + let fut = Cancellable { + fut: commit, + polls_left: i, + }; + fut.await + .map(|res| res.expect("transaction failed")) + .is_some() + }; + + assert!(!in_transaction(&client).await); + + if done { + break; + } + } +} + +#[tokio::test] +async fn transaction_rollback_future_cancellation() { + let mut client = connect("user=postgres").await; + + for i in 0.. { + let done = { + let txn = client.transaction().await.unwrap(); + let rollback = txn.rollback(); + let fut = Cancellable { + fut: rollback, + polls_left: i, + }; + fut.await + .map(|res| res.expect("transaction failed")) + .is_some() + }; + + assert!(!in_transaction(&client).await); + + if done { + break; + } + } +} + #[tokio::test] async fn transaction_rollback_drop() { let mut client = connect("user=postgres").await; From 24b01add826f0844df1eb75f64cac42eda88bcd6 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Thu, 28 Oct 2021 19:08:38 -0400 Subject: [PATCH 35/59] Don't use a built container for test postgres --- .github/workflows/ci.yml | 6 +----- docker-compose.yml | 8 ++++++-- docker/Dockerfile | 3 --- 3 files changed, 7 insertions(+), 10 deletions(-) delete mode 100644 docker/Dockerfile diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8b3a3420d..e38dea88d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -50,13 +50,9 @@ jobs: test: name: test runs-on: ubuntu-latest - services: - postgres: - image: sfackler/rust-postgres-test:6 - ports: - - 5433:5433 steps: - uses: actions/checkout@v2 + - run: docker compose up -d - uses: sfackler/actions/rustup@master with: version: 1.51.0 diff --git a/docker-compose.yml b/docker-compose.yml index d44fbe866..0ed44148d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,6 +1,10 @@ version: '2' services: postgres: - image: "sfackler/rust-postgres-test:6" + image: postgres:14 ports: - - 5433:5433 + - 5433:5433 + volumes: + - ./docker/sql_setup.sh:/docker-entrypoint-initdb.d/sql_setup.sh + environment: + POSTGRES_PASSWORD: postgres diff --git a/docker/Dockerfile b/docker/Dockerfile deleted file mode 100644 index 1dd7f3db6..000000000 --- a/docker/Dockerfile +++ /dev/null @@ -1,3 +0,0 @@ -FROM postgres:12 - -COPY sql_setup.sh /docker-entrypoint-initdb.d/ From a47a8edf98763846003b51f88fc116704bd7c64a Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Thu, 28 Oct 2021 19:16:57 -0400 Subject: [PATCH 36/59] Remove src/url.rs from THIRD_PARTY It hasn't existed in the project for quite a while --- THIRD_PARTY | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/THIRD_PARTY b/THIRD_PARTY index 80336ea0f..05e5ac435 100644 --- a/THIRD_PARTY +++ b/THIRD_PARTY @@ -27,33 +27,3 @@ BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - -------------------------------------------------------------------------------- - -* src/url.rs has been copied from Rust - -Copyright (c) 2014 The Rust Project Developers - -Permission is hereby granted, free of charge, to any -person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the -Software without restriction, including without -limitation the rights to use, copy, modify, merge, -publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software -is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions -of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF -ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR -IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. From 33703689e0addf1af4ac34762391020630c2b7be Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Thu, 28 Oct 2021 19:22:13 -0400 Subject: [PATCH 37/59] Clean up licenses --- LICENSE | 20 --- LICENSE-APACHE | 201 ++++++++++++++++++++++++++++ LICENSE-MIT | 22 ++++ postgres-derive/LICENSE-APACHE | 202 +---------------------------- postgres-derive/LICENSE-MIT | 23 +--- postgres-native-tls/LICENSE-APACHE | 2 +- postgres-native-tls/LICENSE-MIT | 2 +- postgres-openssl/LICENSE-APACHE | 2 +- postgres-openssl/LICENSE-MIT | 2 +- postgres-protocol/LICENSE-APACHE | 202 +---------------------------- postgres-protocol/LICENSE-MIT | 23 +--- postgres-types/LICENSE-APACHE | 202 +---------------------------- postgres-types/LICENSE-MIT | 23 +--- postgres/LICENSE-APACHE | 202 +---------------------------- postgres/LICENSE-MIT | 23 +--- tokio-postgres/LICENSE-APACHE | 202 +---------------------------- tokio-postgres/LICENSE-MIT | 23 +--- 17 files changed, 237 insertions(+), 1139 deletions(-) delete mode 100644 LICENSE create mode 100644 LICENSE-APACHE create mode 100644 LICENSE-MIT mode change 100644 => 120000 postgres-derive/LICENSE-APACHE mode change 100644 => 120000 postgres-derive/LICENSE-MIT mode change 100644 => 120000 postgres-protocol/LICENSE-APACHE mode change 100644 => 120000 postgres-protocol/LICENSE-MIT mode change 100644 => 120000 postgres-types/LICENSE-APACHE mode change 100644 => 120000 postgres-types/LICENSE-MIT mode change 100644 => 120000 postgres/LICENSE-APACHE mode change 100644 => 120000 postgres/LICENSE-MIT mode change 100644 => 120000 tokio-postgres/LICENSE-APACHE mode change 100644 => 120000 tokio-postgres/LICENSE-MIT diff --git a/LICENSE b/LICENSE deleted file mode 100644 index c7e577c00..000000000 --- a/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2013-2017 Steven Fackler - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/LICENSE-APACHE b/LICENSE-APACHE new file mode 100644 index 000000000..16fe87b06 --- /dev/null +++ b/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/LICENSE-MIT b/LICENSE-MIT new file mode 100644 index 000000000..71803aea1 --- /dev/null +++ b/LICENSE-MIT @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2016 Steven Fackler + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/postgres-derive/LICENSE-APACHE b/postgres-derive/LICENSE-APACHE deleted file mode 100644 index 16fe87b06..000000000 --- a/postgres-derive/LICENSE-APACHE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - -2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - -3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - -4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - -5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - -6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - -8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - -APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - -Copyright [yyyy] [name of copyright owner] - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/postgres-derive/LICENSE-APACHE b/postgres-derive/LICENSE-APACHE new file mode 120000 index 000000000..965b606f3 --- /dev/null +++ b/postgres-derive/LICENSE-APACHE @@ -0,0 +1 @@ +../LICENSE-APACHE \ No newline at end of file diff --git a/postgres-derive/LICENSE-MIT b/postgres-derive/LICENSE-MIT deleted file mode 100644 index 71803aea1..000000000 --- a/postgres-derive/LICENSE-MIT +++ /dev/null @@ -1,22 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2016 Steven Fackler - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - diff --git a/postgres-derive/LICENSE-MIT b/postgres-derive/LICENSE-MIT new file mode 120000 index 000000000..76219eb72 --- /dev/null +++ b/postgres-derive/LICENSE-MIT @@ -0,0 +1 @@ +../LICENSE-MIT \ No newline at end of file diff --git a/postgres-native-tls/LICENSE-APACHE b/postgres-native-tls/LICENSE-APACHE index b9e46b0fc..965b606f3 120000 --- a/postgres-native-tls/LICENSE-APACHE +++ b/postgres-native-tls/LICENSE-APACHE @@ -1 +1 @@ -../tokio-postgres/LICENSE-APACHE \ No newline at end of file +../LICENSE-APACHE \ No newline at end of file diff --git a/postgres-native-tls/LICENSE-MIT b/postgres-native-tls/LICENSE-MIT index 162832a42..76219eb72 120000 --- a/postgres-native-tls/LICENSE-MIT +++ b/postgres-native-tls/LICENSE-MIT @@ -1 +1 @@ -../tokio-postgres/LICENSE-MIT \ No newline at end of file +../LICENSE-MIT \ No newline at end of file diff --git a/postgres-openssl/LICENSE-APACHE b/postgres-openssl/LICENSE-APACHE index b9e46b0fc..965b606f3 120000 --- a/postgres-openssl/LICENSE-APACHE +++ b/postgres-openssl/LICENSE-APACHE @@ -1 +1 @@ -../tokio-postgres/LICENSE-APACHE \ No newline at end of file +../LICENSE-APACHE \ No newline at end of file diff --git a/postgres-openssl/LICENSE-MIT b/postgres-openssl/LICENSE-MIT index 162832a42..76219eb72 120000 --- a/postgres-openssl/LICENSE-MIT +++ b/postgres-openssl/LICENSE-MIT @@ -1 +1 @@ -../tokio-postgres/LICENSE-MIT \ No newline at end of file +../LICENSE-MIT \ No newline at end of file diff --git a/postgres-protocol/LICENSE-APACHE b/postgres-protocol/LICENSE-APACHE deleted file mode 100644 index 16fe87b06..000000000 --- a/postgres-protocol/LICENSE-APACHE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - -2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - -3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - -4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - -5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - -6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - -8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - -APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - -Copyright [yyyy] [name of copyright owner] - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/postgres-protocol/LICENSE-APACHE b/postgres-protocol/LICENSE-APACHE new file mode 120000 index 000000000..965b606f3 --- /dev/null +++ b/postgres-protocol/LICENSE-APACHE @@ -0,0 +1 @@ +../LICENSE-APACHE \ No newline at end of file diff --git a/postgres-protocol/LICENSE-MIT b/postgres-protocol/LICENSE-MIT deleted file mode 100644 index 71803aea1..000000000 --- a/postgres-protocol/LICENSE-MIT +++ /dev/null @@ -1,22 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2016 Steven Fackler - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - diff --git a/postgres-protocol/LICENSE-MIT b/postgres-protocol/LICENSE-MIT new file mode 120000 index 000000000..76219eb72 --- /dev/null +++ b/postgres-protocol/LICENSE-MIT @@ -0,0 +1 @@ +../LICENSE-MIT \ No newline at end of file diff --git a/postgres-types/LICENSE-APACHE b/postgres-types/LICENSE-APACHE deleted file mode 100644 index 16fe87b06..000000000 --- a/postgres-types/LICENSE-APACHE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - -2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - -3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - -4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - -5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - -6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - -8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - -APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - -Copyright [yyyy] [name of copyright owner] - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/postgres-types/LICENSE-APACHE b/postgres-types/LICENSE-APACHE new file mode 120000 index 000000000..965b606f3 --- /dev/null +++ b/postgres-types/LICENSE-APACHE @@ -0,0 +1 @@ +../LICENSE-APACHE \ No newline at end of file diff --git a/postgres-types/LICENSE-MIT b/postgres-types/LICENSE-MIT deleted file mode 100644 index 71803aea1..000000000 --- a/postgres-types/LICENSE-MIT +++ /dev/null @@ -1,22 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2016 Steven Fackler - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - diff --git a/postgres-types/LICENSE-MIT b/postgres-types/LICENSE-MIT new file mode 120000 index 000000000..76219eb72 --- /dev/null +++ b/postgres-types/LICENSE-MIT @@ -0,0 +1 @@ +../LICENSE-MIT \ No newline at end of file diff --git a/postgres/LICENSE-APACHE b/postgres/LICENSE-APACHE deleted file mode 100644 index 16fe87b06..000000000 --- a/postgres/LICENSE-APACHE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - -2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - -3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - -4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - -5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - -6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - -8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - -APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - -Copyright [yyyy] [name of copyright owner] - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/postgres/LICENSE-APACHE b/postgres/LICENSE-APACHE new file mode 120000 index 000000000..965b606f3 --- /dev/null +++ b/postgres/LICENSE-APACHE @@ -0,0 +1 @@ +../LICENSE-APACHE \ No newline at end of file diff --git a/postgres/LICENSE-MIT b/postgres/LICENSE-MIT deleted file mode 100644 index 71803aea1..000000000 --- a/postgres/LICENSE-MIT +++ /dev/null @@ -1,22 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2016 Steven Fackler - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - diff --git a/postgres/LICENSE-MIT b/postgres/LICENSE-MIT new file mode 120000 index 000000000..76219eb72 --- /dev/null +++ b/postgres/LICENSE-MIT @@ -0,0 +1 @@ +../LICENSE-MIT \ No newline at end of file diff --git a/tokio-postgres/LICENSE-APACHE b/tokio-postgres/LICENSE-APACHE deleted file mode 100644 index 16fe87b06..000000000 --- a/tokio-postgres/LICENSE-APACHE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - -2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - -3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - -4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - -5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - -6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - -8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - -APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - -Copyright [yyyy] [name of copyright owner] - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/tokio-postgres/LICENSE-APACHE b/tokio-postgres/LICENSE-APACHE new file mode 120000 index 000000000..965b606f3 --- /dev/null +++ b/tokio-postgres/LICENSE-APACHE @@ -0,0 +1 @@ +../LICENSE-APACHE \ No newline at end of file diff --git a/tokio-postgres/LICENSE-MIT b/tokio-postgres/LICENSE-MIT deleted file mode 100644 index 71803aea1..000000000 --- a/tokio-postgres/LICENSE-MIT +++ /dev/null @@ -1,22 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2016 Steven Fackler - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - diff --git a/tokio-postgres/LICENSE-MIT b/tokio-postgres/LICENSE-MIT new file mode 120000 index 000000000..76219eb72 --- /dev/null +++ b/tokio-postgres/LICENSE-MIT @@ -0,0 +1 @@ +../LICENSE-MIT \ No newline at end of file From 8bb5712406c7c3c9763daa553de525cad55785d4 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Thu, 28 Oct 2021 19:32:33 -0400 Subject: [PATCH 38/59] Implement ToStatement for String Closes #794 --- tokio-postgres/src/to_statement.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tokio-postgres/src/to_statement.rs b/tokio-postgres/src/to_statement.rs index 3ff82493c..427f77dd7 100644 --- a/tokio-postgres/src/to_statement.rs +++ b/tokio-postgres/src/to_statement.rs @@ -47,3 +47,11 @@ impl ToStatement for str { } impl Sealed for str {} + +impl ToStatement for String { + fn __convert(&self) -> ToStatementType<'_> { + ToStatementType::Query(self) + } +} + +impl Sealed for String {} From 84fa5fa1d007e95e18bef95f01e9a065ccf1e415 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Fri, 29 Oct 2021 21:33:07 -0400 Subject: [PATCH 39/59] Release tokio-postgres v0.7.5 --- tokio-postgres/CHANGELOG.md | 6 ++++++ tokio-postgres/Cargo.toml | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/tokio-postgres/CHANGELOG.md b/tokio-postgres/CHANGELOG.md index 34b4fc1d9..eca196f06 100644 --- a/tokio-postgres/CHANGELOG.md +++ b/tokio-postgres/CHANGELOG.md @@ -1,5 +1,11 @@ # Change Log +## v0.7.5 - 2021-10-29 + +### Fixed + +* Fixed a bug where the client could enter into a transaction if the `Client::transaction` future was dropped before completion. + ## v0.7.4 - 2021-10-19 ### Fixed diff --git a/tokio-postgres/Cargo.toml b/tokio-postgres/Cargo.toml index 17286dc21..5974fe64f 100644 --- a/tokio-postgres/Cargo.toml +++ b/tokio-postgres/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tokio-postgres" -version = "0.7.4" +version = "0.7.5" authors = ["Steven Fackler "] edition = "2018" license = "MIT/Apache-2.0" From dc591ff2ca5a51e4f7f3543e1321292b5a1dadea Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Tue, 23 Nov 2021 23:40:00 -0500 Subject: [PATCH 40/59] Fix handling of raw ident fields in derive --- postgres-derive-test/src/composites.rs | 23 +++++++++++++++++++++++ postgres-derive/src/composites.rs | 8 +++++++- postgres-derive/src/fromsql.rs | 6 +++--- 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/postgres-derive-test/src/composites.rs b/postgres-derive-test/src/composites.rs index 5efd3944c..ed60bf48f 100644 --- a/postgres-derive-test/src/composites.rs +++ b/postgres-derive-test/src/composites.rs @@ -215,3 +215,26 @@ fn wrong_type() { .unwrap_err(); assert!(err.source().unwrap().is::()); } + +#[test] +fn raw_ident_field() { + #[derive(FromSql, ToSql, Debug, PartialEq)] + #[postgres(name = "inventory_item")] + struct InventoryItem { + r#type: String, + } + + let mut conn = Client::connect("user=postgres host=localhost port=5433", NoTls).unwrap(); + conn.batch_execute( + "CREATE TYPE pg_temp.inventory_item AS ( + type TEXT + )", + ) + .unwrap(); + + let item = InventoryItem { + r#type: "foo".to_owned(), + }; + + test_type(&mut conn, "inventory_item", &[(item, "ROW('foo')")]); +} diff --git a/postgres-derive/src/composites.rs b/postgres-derive/src/composites.rs index f5599d375..c1e495154 100644 --- a/postgres-derive/src/composites.rs +++ b/postgres-derive/src/composites.rs @@ -14,7 +14,13 @@ impl Field { let ident = raw.ident.as_ref().unwrap().clone(); Ok(Field { - name: overrides.name.unwrap_or_else(|| ident.to_string()), + name: overrides.name.unwrap_or_else(|| { + let name = ident.to_string(); + match name.strip_prefix("r#") { + Some(name) => name.to_string(), + None => name, + } + }), ident, type_: raw.ty.clone(), }) diff --git a/postgres-derive/src/fromsql.rs b/postgres-derive/src/fromsql.rs index e1ab6ffa7..3a59d6226 100644 --- a/postgres-derive/src/fromsql.rs +++ b/postgres-derive/src/fromsql.rs @@ -1,5 +1,5 @@ -use proc_macro2::{Span, TokenStream}; -use quote::quote; +use proc_macro2::TokenStream; +use quote::{format_ident, quote}; use std::iter; use syn::{Data, DataStruct, DeriveInput, Error, Fields, Ident}; @@ -119,7 +119,7 @@ fn domain_body(ident: &Ident, field: &syn::Field) -> TokenStream { fn composite_body(ident: &Ident, fields: &[Field]) -> TokenStream { let temp_vars = &fields .iter() - .map(|f| Ident::new(&format!("__{}", f.ident), Span::call_site())) + .map(|f| format_ident!("__{}", f.ident)) .collect::>(); let field_names = &fields.iter().map(|f| &f.name).collect::>(); let field_idents = &fields.iter().map(|f| &f.ident).collect::>(); From c5591c810ccba977bbf819b5d290d30e26300a3f Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Tue, 23 Nov 2021 23:50:27 -0500 Subject: [PATCH 41/59] Release postgres-derive v0.4.1 --- postgres-derive/CHANGELOG.md | 6 ++++++ postgres-derive/Cargo.toml | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/postgres-derive/CHANGELOG.md b/postgres-derive/CHANGELOG.md index 354f6f277..9bb3a752f 100644 --- a/postgres-derive/CHANGELOG.md +++ b/postgres-derive/CHANGELOG.md @@ -1,5 +1,11 @@ # Change Log +## v0.4.1 - 2021-11-23 + +### Fixed + +* Fixed handling of struct fields using raw identifiers. + ## v0.4.0 - 2019-12-23 No changes diff --git a/postgres-derive/Cargo.toml b/postgres-derive/Cargo.toml index 293c294a0..1ce243a58 100644 --- a/postgres-derive/Cargo.toml +++ b/postgres-derive/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "postgres-derive" -version = "0.4.0" +version = "0.4.1" authors = ["Steven Fackler "] license = "MIT/Apache-2.0" edition = "2018" From 8ead6e6c69e049c6b7ca67432e781a7429f76056 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Wed, 8 Dec 2021 18:30:44 -0500 Subject: [PATCH 42/59] Update hash crates --- postgres-protocol/Cargo.toml | 6 +++--- postgres-protocol/src/authentication/sasl.rs | 4 ++-- postgres-protocol/src/password/mod.rs | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/postgres-protocol/Cargo.toml b/postgres-protocol/Cargo.toml index a4ed3e907..638778f22 100644 --- a/postgres-protocol/Cargo.toml +++ b/postgres-protocol/Cargo.toml @@ -13,9 +13,9 @@ base64 = "0.13" byteorder = "1.0" bytes = "1.0" fallible-iterator = "0.2" -hmac = "0.11" -md-5 = "0.9" +hmac = "0.12" +md-5 = "0.10" memchr = "2.0" rand = "0.8" -sha2 = "0.9" +sha2 = "0.10" stringprep = "0.1" diff --git a/postgres-protocol/src/authentication/sasl.rs b/postgres-protocol/src/authentication/sasl.rs index a3704ce16..ea2f55cad 100644 --- a/postgres-protocol/src/authentication/sasl.rs +++ b/postgres-protocol/src/authentication/sasl.rs @@ -1,6 +1,6 @@ //! SASL-based authentication support. -use hmac::{Hmac, Mac, NewMac}; +use hmac::{Hmac, Mac}; use rand::{self, Rng}; use sha2::digest::FixedOutput; use sha2::{Digest, Sha256}; @@ -275,7 +275,7 @@ impl ScramSha256 { let mut hmac = Hmac::::new_from_slice(&server_key) .expect("HMAC is able to accept all key sizes"); hmac.update(auth_message.as_bytes()); - hmac.verify(&verifier) + hmac.verify_slice(&verifier) .map_err(|_| io::Error::new(io::ErrorKind::InvalidInput, "SCRAM verification error")) } } diff --git a/postgres-protocol/src/password/mod.rs b/postgres-protocol/src/password/mod.rs index 1b32ae8f8..a60687bbe 100644 --- a/postgres-protocol/src/password/mod.rs +++ b/postgres-protocol/src/password/mod.rs @@ -7,7 +7,7 @@ //! end up in logs pg_stat displays, etc. use crate::authentication::sasl; -use hmac::{Hmac, Mac, NewMac}; +use hmac::{Hmac, Mac}; use md5::Md5; use rand::RngCore; use sha2::digest::FixedOutput; From 76cd380e5a70d76f4f73219385e906ea3d6be7f9 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Wed, 8 Dec 2021 18:35:18 -0500 Subject: [PATCH 43/59] clippy --- tokio-postgres/src/config.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tokio-postgres/src/config.rs b/tokio-postgres/src/config.rs index eb4e5bdc5..c026cca4f 100644 --- a/tokio-postgres/src/config.rs +++ b/tokio-postgres/src/config.rs @@ -780,7 +780,7 @@ impl<'a> UrlParser<'a> { } fn take_all(&mut self) -> &'a str { - mem::replace(&mut self.s, "") + mem::take(&mut self.s) } fn eat_byte(&mut self) { From 630f179892c9030119bf80df97aa05fef2dea525 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Fri, 10 Dec 2021 19:21:59 -0500 Subject: [PATCH 44/59] Release postgres-protocol v0.6.3 --- postgres-protocol/CHANGELOG.md | 6 ++++++ postgres-protocol/Cargo.toml | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/postgres-protocol/CHANGELOG.md b/postgres-protocol/CHANGELOG.md index eb37f5883..5d9cecd01 100644 --- a/postgres-protocol/CHANGELOG.md +++ b/postgres-protocol/CHANGELOG.md @@ -1,5 +1,11 @@ # Change Log +## v0.6.3 - 2021-12-10 + +### Changed + +* Upgraded `hmac`, `md-5` and `sha`. + ## v0.6.2 - 2021-09-29 ### Changed diff --git a/postgres-protocol/Cargo.toml b/postgres-protocol/Cargo.toml index 638778f22..2010e88ad 100644 --- a/postgres-protocol/Cargo.toml +++ b/postgres-protocol/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "postgres-protocol" -version = "0.6.2" +version = "0.6.3" authors = ["Steven Fackler "] edition = "2018" description = "Low level Postgres protocol APIs" From c516805275aaaf106e8e512f53a9b0234f707583 Mon Sep 17 00:00:00 2001 From: Lachezar Lechev Date: Thu, 16 Dec 2021 10:21:22 +0200 Subject: [PATCH 45/59] impl BorrowToSql for: - Box - Box --- postgres-types/src/lib.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/postgres-types/src/lib.rs b/postgres-types/src/lib.rs index 2a953db2f..010b06adc 100644 --- a/postgres-types/src/lib.rs +++ b/postgres-types/src/lib.rs @@ -1044,6 +1044,23 @@ impl BorrowToSql for &dyn ToSql { } } +impl sealed::Sealed for Box {} + +impl BorrowToSql for Box { + #[inline] + fn borrow_to_sql(&self) -> &dyn ToSql { + self.as_ref() + } +} + +impl sealed::Sealed for Box {} +impl BorrowToSql for Box { + #[inline] + fn borrow_to_sql(&self) -> &dyn ToSql { + self.as_ref() + } +} + impl sealed::Sealed for &(dyn ToSql + Sync) {} /// In async contexts it is sometimes necessary to have the additional From 35f4c0aeefef139e682ebead2db47397be513e6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Obr=C3=A9jan?= Date: Sun, 26 Dec 2021 19:13:03 +0100 Subject: [PATCH 46/59] Implement `ToSql` & `FromSql` for `Box` --- postgres-types/src/lib.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/postgres-types/src/lib.rs b/postgres-types/src/lib.rs index 2a953db2f..84354cf3b 100644 --- a/postgres-types/src/lib.rs +++ b/postgres-types/src/lib.rs @@ -584,6 +584,18 @@ impl<'a> FromSql<'a> for String { } } +impl<'a> FromSql<'a> for Box { + fn from_sql(_: &Type, raw: &'a [u8]) -> Result, Box> { + types::text_from_sql(raw) + .map(ToString::to_string) + .map(String::into_boxed_str) + } + + fn accepts(ty: &Type) -> bool { + <&str as FromSql>::accepts(ty) + } +} + impl<'a> FromSql<'a> for &'a str { fn from_sql(_: &Type, raw: &'a [u8]) -> Result<&'a str, Box> { types::text_from_sql(raw) @@ -933,6 +945,18 @@ impl ToSql for String { to_sql_checked!(); } +impl ToSql for Box { + fn to_sql(&self, ty: &Type, w: &mut BytesMut) -> Result> { + <&str as ToSql>::to_sql(&&**self, ty, w) + } + + fn accepts(ty: &Type) -> bool { + <&str as ToSql>::accepts(ty) + } + + to_sql_checked!(); +} + macro_rules! simple_to { ($t:ty, $f:ident, $($expected:ident),+) => { impl ToSql for $t { From 4561d44661d0367c5f7792eaf8086351b7eb673f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Obr=C3=A9jan?= Date: Sun, 26 Dec 2021 20:43:14 +0100 Subject: [PATCH 47/59] Add `#[postgres(transparent)]` --- .../src/compile-fail/invalid-transparent.rs | 35 ++++++ .../compile-fail/invalid-transparent.stderr | 49 ++++++++ postgres-derive-test/src/lib.rs | 1 + postgres-derive-test/src/transparent.rs | 18 +++ postgres-derive/src/accepts.rs | 8 ++ postgres-derive/src/fromsql.rs | 37 +++++- postgres-derive/src/lib.rs | 7 +- postgres-derive/src/overrides.rs | 20 +++- postgres-derive/src/tosql.rs | 107 ++++++++++++------ postgres-types/src/lib.rs | 15 +++ 10 files changed, 251 insertions(+), 46 deletions(-) create mode 100644 postgres-derive-test/src/compile-fail/invalid-transparent.rs create mode 100644 postgres-derive-test/src/compile-fail/invalid-transparent.stderr create mode 100644 postgres-derive-test/src/transparent.rs diff --git a/postgres-derive-test/src/compile-fail/invalid-transparent.rs b/postgres-derive-test/src/compile-fail/invalid-transparent.rs new file mode 100644 index 000000000..43bd48266 --- /dev/null +++ b/postgres-derive-test/src/compile-fail/invalid-transparent.rs @@ -0,0 +1,35 @@ +use postgres_types::{FromSql, ToSql}; + +#[derive(ToSql, Debug)] +#[postgres(transparent)] +struct ToSqlTransparentStruct { + a: i32 +} + +#[derive(FromSql, Debug)] +#[postgres(transparent)] +struct FromSqlTransparentStruct { + a: i32 +} + +#[derive(ToSql, Debug)] +#[postgres(transparent)] +enum ToSqlTransparentEnum { + Foo +} + +#[derive(FromSql, Debug)] +#[postgres(transparent)] +enum FromSqlTransparentEnum { + Foo +} + +#[derive(ToSql, Debug)] +#[postgres(transparent)] +struct ToSqlTransparentTwoFieldTupleStruct(i32, i32); + +#[derive(FromSql, Debug)] +#[postgres(transparent)] +struct FromSqlTransparentTwoFieldTupleStruct(i32, i32); + +fn main() {} diff --git a/postgres-derive-test/src/compile-fail/invalid-transparent.stderr b/postgres-derive-test/src/compile-fail/invalid-transparent.stderr new file mode 100644 index 000000000..42e49f874 --- /dev/null +++ b/postgres-derive-test/src/compile-fail/invalid-transparent.stderr @@ -0,0 +1,49 @@ +error: #[postgres(transparent)] may only be applied to single field tuple structs + --> src/compile-fail/invalid-transparent.rs:4:1 + | +4 | / #[postgres(transparent)] +5 | | struct ToSqlTransparentStruct { +6 | | a: i32 +7 | | } + | |_^ + +error: #[postgres(transparent)] may only be applied to single field tuple structs + --> src/compile-fail/invalid-transparent.rs:10:1 + | +10 | / #[postgres(transparent)] +11 | | struct FromSqlTransparentStruct { +12 | | a: i32 +13 | | } + | |_^ + +error: #[postgres(transparent)] may only be applied to single field tuple structs + --> src/compile-fail/invalid-transparent.rs:16:1 + | +16 | / #[postgres(transparent)] +17 | | enum ToSqlTransparentEnum { +18 | | Foo +19 | | } + | |_^ + +error: #[postgres(transparent)] may only be applied to single field tuple structs + --> src/compile-fail/invalid-transparent.rs:22:1 + | +22 | / #[postgres(transparent)] +23 | | enum FromSqlTransparentEnum { +24 | | Foo +25 | | } + | |_^ + +error: #[postgres(transparent)] may only be applied to single field tuple structs + --> src/compile-fail/invalid-transparent.rs:28:1 + | +28 | / #[postgres(transparent)] +29 | | struct ToSqlTransparentTwoFieldTupleStruct(i32, i32); + | |_____________________________________________________^ + +error: #[postgres(transparent)] may only be applied to single field tuple structs + --> src/compile-fail/invalid-transparent.rs:32:1 + | +32 | / #[postgres(transparent)] +33 | | struct FromSqlTransparentTwoFieldTupleStruct(i32, i32); + | |_______________________________________________________^ diff --git a/postgres-derive-test/src/lib.rs b/postgres-derive-test/src/lib.rs index 7da75af8f..279ed1419 100644 --- a/postgres-derive-test/src/lib.rs +++ b/postgres-derive-test/src/lib.rs @@ -7,6 +7,7 @@ use std::fmt; mod composites; mod domains; mod enums; +mod transparent; pub fn test_type(conn: &mut Client, sql_type: &str, checks: &[(T, S)]) where diff --git a/postgres-derive-test/src/transparent.rs b/postgres-derive-test/src/transparent.rs new file mode 100644 index 000000000..1614553d2 --- /dev/null +++ b/postgres-derive-test/src/transparent.rs @@ -0,0 +1,18 @@ +use postgres::{Client, NoTls}; +use postgres_types::{FromSql, ToSql}; + +#[test] +fn round_trip() { + #[derive(FromSql, ToSql, Debug, PartialEq)] + #[postgres(transparent)] + struct UserId(i32); + + assert_eq!( + Client::connect("user=postgres host=localhost port=5433", NoTls) + .unwrap() + .query_one("SELECT $1::integer", &[&UserId(123)]) + .unwrap() + .get::<_, UserId>(0), + UserId(123) + ); +} diff --git a/postgres-derive/src/accepts.rs b/postgres-derive/src/accepts.rs index 530badd0b..63473863a 100644 --- a/postgres-derive/src/accepts.rs +++ b/postgres-derive/src/accepts.rs @@ -6,6 +6,14 @@ use syn::Ident; use crate::composites::Field; use crate::enums::Variant; +pub fn transparent_body(field: &syn::Field) -> TokenStream { + let ty = &field.ty; + + quote! { + <#ty as ::postgres_types::ToSql>::accepts(type_) + } +} + pub fn domain_body(name: &str, field: &syn::Field) -> TokenStream { let ty = &field.ty; diff --git a/postgres-derive/src/fromsql.rs b/postgres-derive/src/fromsql.rs index 3a59d6226..c89cbb5e2 100644 --- a/postgres-derive/src/fromsql.rs +++ b/postgres-derive/src/fromsql.rs @@ -11,9 +11,36 @@ use crate::overrides::Overrides; pub fn expand_derive_fromsql(input: DeriveInput) -> Result { let overrides = Overrides::extract(&input.attrs)?; + if overrides.name.is_some() && overrides.transparent { + return Err(Error::new_spanned( + &input, + "#[postgres(transparent)] is not allowed with #[postgres(name = \"...\")]", + )); + } + let name = overrides.name.unwrap_or_else(|| input.ident.to_string()); - let (accepts_body, to_sql_body) = match input.data { + let (accepts_body, to_sql_body) = if overrides.transparent { + match input.data { + Data::Struct(DataStruct { + fields: Fields::Unnamed(ref fields), + .. + }) if fields.unnamed.len() == 1 => { + let field = fields.unnamed.first().unwrap(); + ( + accepts::transparent_body(field), + transparent_body(&input.ident, field), + ) + } + _ => { + return Err(Error::new_spanned( + input, + "#[postgres(transparent)] may only be applied to single field tuple structs", + )) + } + } + } else { + match input.data { Data::Enum(ref data) => { let variants = data .variants @@ -55,6 +82,7 @@ pub fn expand_derive_fromsql(input: DeriveInput) -> Result { "#[derive(FromSql)] may only be applied to structs, single field tuple structs, and enums", )) } + } }; let ident = &input.ident; @@ -77,6 +105,13 @@ pub fn expand_derive_fromsql(input: DeriveInput) -> Result { Ok(out) } +fn transparent_body(ident: &Ident, field: &syn::Field) -> TokenStream { + let ty = &field.ty; + quote! { + <#ty as postgres_types::FromSql>::from_sql(_type, buf).map(#ident) + } +} + fn enum_body(ident: &Ident, variants: &[Variant]) -> TokenStream { let variant_names = variants.iter().map(|v| &v.name); let idents = iter::repeat(ident); diff --git a/postgres-derive/src/lib.rs b/postgres-derive/src/lib.rs index fd17b9de6..98e6add24 100644 --- a/postgres-derive/src/lib.rs +++ b/postgres-derive/src/lib.rs @@ -4,6 +4,7 @@ extern crate proc_macro; use proc_macro::TokenStream; +use syn::parse_macro_input; mod accepts; mod composites; @@ -14,7 +15,8 @@ mod tosql; #[proc_macro_derive(ToSql, attributes(postgres))] pub fn derive_tosql(input: TokenStream) -> TokenStream { - let input = syn::parse(input).unwrap(); + let input = parse_macro_input!(input); + tosql::expand_derive_tosql(input) .unwrap_or_else(|e| e.to_compile_error()) .into() @@ -22,7 +24,8 @@ pub fn derive_tosql(input: TokenStream) -> TokenStream { #[proc_macro_derive(FromSql, attributes(postgres))] pub fn derive_fromsql(input: TokenStream) -> TokenStream { - let input = syn::parse(input).unwrap(); + let input = parse_macro_input!(input); + fromsql::expand_derive_fromsql(input) .unwrap_or_else(|e| e.to_compile_error()) .into() diff --git a/postgres-derive/src/overrides.rs b/postgres-derive/src/overrides.rs index 08e6f3a77..c00d5a94b 100644 --- a/postgres-derive/src/overrides.rs +++ b/postgres-derive/src/overrides.rs @@ -2,17 +2,18 @@ use syn::{Attribute, Error, Lit, Meta, NestedMeta}; pub struct Overrides { pub name: Option, + pub transparent: bool, } impl Overrides { pub fn extract(attrs: &[Attribute]) -> Result { - let mut overrides = Overrides { name: None }; + let mut overrides = Overrides { + name: None, + transparent: false, + }; for attr in attrs { - let attr = match attr.parse_meta() { - Ok(meta) => meta, - Err(_) => continue, - }; + let attr = attr.parse_meta()?; if !attr.path().is_ident("postgres") { continue; @@ -39,7 +40,14 @@ impl Overrides { overrides.name = Some(value); } - bad => return Err(Error::new_spanned(bad, "expected a name-value meta item")), + NestedMeta::Meta(Meta::Path(ref path)) => { + if !path.is_ident("transparent") { + return Err(Error::new_spanned(path, "unknown override")); + } + + overrides.transparent = true; + } + bad => return Err(Error::new_spanned(bad, "unknown attribute")), } } } diff --git a/postgres-derive/src/tosql.rs b/postgres-derive/src/tosql.rs index 1808e787d..96f261385 100644 --- a/postgres-derive/src/tosql.rs +++ b/postgres-derive/src/tosql.rs @@ -11,46 +11,73 @@ use crate::overrides::Overrides; pub fn expand_derive_tosql(input: DeriveInput) -> Result { let overrides = Overrides::extract(&input.attrs)?; + if overrides.name.is_some() && overrides.transparent { + return Err(Error::new_spanned( + &input, + "#[postgres(transparent)] is not allowed with #[postgres(name = \"...\")]", + )); + } + let name = overrides.name.unwrap_or_else(|| input.ident.to_string()); - let (accepts_body, to_sql_body) = match input.data { - Data::Enum(ref data) => { - let variants = data - .variants - .iter() - .map(Variant::parse) - .collect::, _>>()?; - ( - accepts::enum_body(&name, &variants), - enum_body(&input.ident, &variants), - ) - } - Data::Struct(DataStruct { - fields: Fields::Unnamed(ref fields), - .. - }) if fields.unnamed.len() == 1 => { - let field = fields.unnamed.first().unwrap(); - (accepts::domain_body(&name, field), domain_body()) - } - Data::Struct(DataStruct { - fields: Fields::Named(ref fields), - .. - }) => { - let fields = fields - .named - .iter() - .map(Field::parse) - .collect::, _>>()?; - ( - accepts::composite_body(&name, "ToSql", &fields), - composite_body(&fields), - ) + let (accepts_body, to_sql_body) = if overrides.transparent { + match input.data { + Data::Struct(DataStruct { + fields: Fields::Unnamed(ref fields), + .. + }) if fields.unnamed.len() == 1 => { + let field = fields.unnamed.first().unwrap(); + + (accepts::transparent_body(field), transparent_body()) + } + _ => { + return Err(Error::new_spanned( + input, + "#[postgres(transparent)] may only be applied to single field tuple structs", + )); + } } - _ => { - return Err(Error::new_spanned( - input, - "#[derive(ToSql)] may only be applied to structs, single field tuple structs, and enums", - )); + } else { + match input.data { + Data::Enum(ref data) => { + let variants = data + .variants + .iter() + .map(Variant::parse) + .collect::, _>>()?; + ( + accepts::enum_body(&name, &variants), + enum_body(&input.ident, &variants), + ) + } + Data::Struct(DataStruct { + fields: Fields::Unnamed(ref fields), + .. + }) if fields.unnamed.len() == 1 => { + let field = fields.unnamed.first().unwrap(); + + (accepts::domain_body(&name, field), domain_body()) + } + Data::Struct(DataStruct { + fields: Fields::Named(ref fields), + .. + }) => { + let fields = fields + .named + .iter() + .map(Field::parse) + .collect::, _>>()?; + ( + accepts::composite_body(&name, "ToSql", &fields), + composite_body(&fields), + ) + } + _ => { + return Err(Error::new_spanned( + input, + "#[derive(ToSql)] may only be applied to structs, single field tuple structs, and enums", + )); + } } }; @@ -78,6 +105,12 @@ pub fn expand_derive_tosql(input: DeriveInput) -> Result { Ok(out) } +fn transparent_body() -> TokenStream { + quote! { + postgres_types::ToSql::to_sql(&self.0, _type, buf) + } +} + fn enum_body(ident: &Ident, variants: &[Variant]) -> TokenStream { let idents = iter::repeat(ident); let variant_idents = variants.iter().map(|v| &v.ident); diff --git a/postgres-types/src/lib.rs b/postgres-types/src/lib.rs index 2a953db2f..e409051e8 100644 --- a/postgres-types/src/lib.rs +++ b/postgres-types/src/lib.rs @@ -55,6 +55,21 @@ //! struct SessionId(Vec); //! ``` //! +//! ## Newtypes +//! +//! The `#[postgres(transparent)]` attribute can be used on a single-field tuple struct to create a +//! Rust-only wrapper type that will use the [`ToSql`] & [`FromSql`] implementation of the inner +//! value : +//! ```rust +//! # #[cfg(feature = "derive")] +//! use postgres_types::{ToSql, FromSql}; +//! +//! # #[cfg(feature = "derive")] +//! #[derive(Debug, ToSql, FromSql)] +//! #[postgres(transparent)] +//! struct UserId(i32); +//! ``` +//! //! ## Composites //! //! Postgres composite types correspond to structs in Rust: From 842e5cfdcb2c3f4fec3d394ccd1e8b91e2e8985b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 31 Jan 2022 13:15:32 +0000 Subject: [PATCH 48/59] Update parking_lot requirement from 0.11 to 0.12 Updates the requirements on [parking_lot](https://github.com/Amanieu/parking_lot) to permit the latest version. - [Release notes](https://github.com/Amanieu/parking_lot/releases) - [Changelog](https://github.com/Amanieu/parking_lot/blob/master/CHANGELOG.md) - [Commits](https://github.com/Amanieu/parking_lot/compare/0.11.0...0.12.0) --- updated-dependencies: - dependency-name: parking_lot dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- tokio-postgres/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tokio-postgres/Cargo.toml b/tokio-postgres/Cargo.toml index 5974fe64f..7d898e269 100644 --- a/tokio-postgres/Cargo.toml +++ b/tokio-postgres/Cargo.toml @@ -46,7 +46,7 @@ byteorder = "1.0" fallible-iterator = "0.2" futures = "0.3" log = "0.4" -parking_lot = "0.11" +parking_lot = "0.12" percent-encoding = "2.0" pin-project-lite = "0.2" phf = "0.10" From a07a39cc875b95565908125d66c1dfb6682d406a Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Mon, 31 Jan 2022 09:11:29 -0500 Subject: [PATCH 49/59] Update ci.yml --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e38dea88d..520d665f8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -55,7 +55,7 @@ jobs: - run: docker compose up -d - uses: sfackler/actions/rustup@master with: - version: 1.51.0 + version: 1.53.0 - run: echo "::set-output name=version::$(rustc --version)" id: rust-version - uses: actions/cache@v1 From 7fd748ba96d3056a1a2315799661d7e9e849deb7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 11 Feb 2022 13:47:41 +0000 Subject: [PATCH 50/59] Update tokio-util requirement from 0.6 to 0.7 Updates the requirements on [tokio-util](https://github.com/tokio-rs/tokio) to permit the latest version. - [Release notes](https://github.com/tokio-rs/tokio/releases) - [Commits](https://github.com/tokio-rs/tokio/commits) --- updated-dependencies: - dependency-name: tokio-util dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- tokio-postgres/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tokio-postgres/Cargo.toml b/tokio-postgres/Cargo.toml index 7d898e269..94371af51 100644 --- a/tokio-postgres/Cargo.toml +++ b/tokio-postgres/Cargo.toml @@ -54,7 +54,7 @@ postgres-protocol = { version = "0.6.1", path = "../postgres-protocol" } postgres-types = { version = "0.2.2", path = "../postgres-types" } socket2 = "0.4" tokio = { version = "1.0", features = ["io-util"] } -tokio-util = { version = "0.6", features = ["codec"] } +tokio-util = { version = "0.7", features = ["codec"] } [dev-dependencies] tokio = { version = "1.0", features = ["full"] } From 9685f9c532f10bd99339e2dcddaad3b462c5b687 Mon Sep 17 00:00:00 2001 From: Tim Anderson Date: Wed, 16 Mar 2022 14:13:36 +1000 Subject: [PATCH 51/59] Add ToSql / FromSql for IpInet and IpCidr from cidr crate --- postgres-types/Cargo.toml | 2 ++ postgres-types/src/cidr_02.rs | 44 +++++++++++++++++++++++++++++++++++ postgres-types/src/lib.rs | 2 ++ 3 files changed, 48 insertions(+) create mode 100644 postgres-types/src/cidr_02.rs diff --git a/postgres-types/Cargo.toml b/postgres-types/Cargo.toml index 7eca3fbcf..1954d51bb 100644 --- a/postgres-types/Cargo.toml +++ b/postgres-types/Cargo.toml @@ -14,6 +14,7 @@ categories = ["database"] derive = ["postgres-derive"] array-impls = ["array-init"] with-bit-vec-0_6 = ["bit-vec-06"] +with-cidr-0_2 = ["cidr-02"] with-chrono-0_4 = ["chrono-04"] with-eui48-0_4 = ["eui48-04"] with-eui48-1 = ["eui48-1"] @@ -32,6 +33,7 @@ postgres-derive = { version = "0.4.0", optional = true, path = "../postgres-deri array-init = { version = "2", optional = true } bit-vec-06 = { version = "0.6", package = "bit-vec", optional = true } +cidr-02 = { version = "0.2", package = "cidr", optional = true } chrono-04 = { version = "0.4.16", package = "chrono", default-features = false, features = ["clock"], optional = true } eui48-04 = { version = "0.4", package = "eui48", optional = true } eui48-1 = { version = "1.0", package = "eui48", optional = true } diff --git a/postgres-types/src/cidr_02.rs b/postgres-types/src/cidr_02.rs new file mode 100644 index 000000000..46e904483 --- /dev/null +++ b/postgres-types/src/cidr_02.rs @@ -0,0 +1,44 @@ +use bytes::BytesMut; +use cidr_02::{IpCidr, IpInet}; +use postgres_protocol::types; +use std::error::Error; + +use crate::{FromSql, IsNull, ToSql, Type}; + +impl<'a> FromSql<'a> for IpCidr { + fn from_sql(_: &Type, raw: &[u8]) -> Result> { + let inet = types::inet_from_sql(raw)?; + Ok(IpCidr::new(inet.addr(), inet.netmask()).expect("postgres cidr type has zeroed host portion")) + } + + accepts!(CIDR); +} + +impl ToSql for IpCidr { + fn to_sql(&self, _: &Type, w: &mut BytesMut) -> Result> { + types::inet_to_sql(self.first_address(), self.network_length(), w); + Ok(IsNull::No) + } + + accepts!(CIDR); + to_sql_checked!(); +} + +impl<'a> FromSql<'a> for IpInet { + fn from_sql(_: &Type, raw: &[u8]) -> Result> { + let inet = types::inet_from_sql(raw)?; + Ok(IpInet::new(inet.addr(), inet.netmask()).expect("postgres enforces maximum length of netmask")) + } + + accepts!(INET); +} + +impl ToSql for IpInet { + fn to_sql(&self, _: &Type, w: &mut BytesMut) -> Result> { + types::inet_to_sql(self.address(), self.network_length(), w); + Ok(IsNull::No) + } + + accepts!(INET); + to_sql_checked!(); +} diff --git a/postgres-types/src/lib.rs b/postgres-types/src/lib.rs index 0247b90b7..b1a45bab1 100644 --- a/postgres-types/src/lib.rs +++ b/postgres-types/src/lib.rs @@ -210,6 +210,8 @@ where #[cfg(feature = "with-bit-vec-0_6")] mod bit_vec_06; +#[cfg(feature = "with-cidr-0_2")] +mod cidr_02; #[cfg(feature = "with-chrono-0_4")] mod chrono_04; #[cfg(feature = "with-eui48-0_4")] From dd7bc073f7a7dfd1a1dd9c3e90e5d9d1630a2824 Mon Sep 17 00:00:00 2001 From: Tim Anderson Date: Wed, 16 Mar 2022 14:32:50 +1000 Subject: [PATCH 52/59] Document cidr type conversion and run rustfmt --- postgres-types/Cargo.toml | 2 +- postgres-types/src/cidr_02.rs | 6 ++++-- postgres-types/src/lib.rs | 6 ++++-- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/postgres-types/Cargo.toml b/postgres-types/Cargo.toml index 1954d51bb..9d470f37b 100644 --- a/postgres-types/Cargo.toml +++ b/postgres-types/Cargo.toml @@ -33,8 +33,8 @@ postgres-derive = { version = "0.4.0", optional = true, path = "../postgres-deri array-init = { version = "2", optional = true } bit-vec-06 = { version = "0.6", package = "bit-vec", optional = true } -cidr-02 = { version = "0.2", package = "cidr", optional = true } chrono-04 = { version = "0.4.16", package = "chrono", default-features = false, features = ["clock"], optional = true } +cidr-02 = { version = "0.2", package = "cidr", optional = true } eui48-04 = { version = "0.4", package = "eui48", optional = true } eui48-1 = { version = "1.0", package = "eui48", optional = true } geo-types-06 = { version = "0.6", package = "geo-types", optional = true } diff --git a/postgres-types/src/cidr_02.rs b/postgres-types/src/cidr_02.rs index 46e904483..d4e4965c5 100644 --- a/postgres-types/src/cidr_02.rs +++ b/postgres-types/src/cidr_02.rs @@ -8,7 +8,8 @@ use crate::{FromSql, IsNull, ToSql, Type}; impl<'a> FromSql<'a> for IpCidr { fn from_sql(_: &Type, raw: &[u8]) -> Result> { let inet = types::inet_from_sql(raw)?; - Ok(IpCidr::new(inet.addr(), inet.netmask()).expect("postgres cidr type has zeroed host portion")) + Ok(IpCidr::new(inet.addr(), inet.netmask()) + .expect("postgres cidr type has zeroed host portion")) } accepts!(CIDR); @@ -27,7 +28,8 @@ impl ToSql for IpCidr { impl<'a> FromSql<'a> for IpInet { fn from_sql(_: &Type, raw: &[u8]) -> Result> { let inet = types::inet_from_sql(raw)?; - Ok(IpInet::new(inet.addr(), inet.netmask()).expect("postgres enforces maximum length of netmask")) + Ok(IpInet::new(inet.addr(), inet.netmask()) + .expect("postgres enforces maximum length of netmask")) } accepts!(INET); diff --git a/postgres-types/src/lib.rs b/postgres-types/src/lib.rs index b1a45bab1..394f938ff 100644 --- a/postgres-types/src/lib.rs +++ b/postgres-types/src/lib.rs @@ -210,10 +210,10 @@ where #[cfg(feature = "with-bit-vec-0_6")] mod bit_vec_06; -#[cfg(feature = "with-cidr-0_2")] -mod cidr_02; #[cfg(feature = "with-chrono-0_4")] mod chrono_04; +#[cfg(feature = "with-cidr-0_2")] +mod cidr_02; #[cfg(feature = "with-eui48-0_4")] mod eui48_04; #[cfg(feature = "with-eui48-1")] @@ -438,6 +438,8 @@ impl WrongType { /// | `uuid::Uuid` | UUID | /// | `bit_vec::BitVec` | BIT, VARBIT | /// | `eui48::MacAddress` | MACADDR | +/// | `cidr::InetCidr` | CIDR | +/// | `cidr::InetAddr` | INET | /// /// # Nullability /// From 27039f6c3a9f05a41b657f1db5489d055363e2a8 Mon Sep 17 00:00:00 2001 From: Tim Anderson Date: Thu, 17 Mar 2022 09:31:13 +1000 Subject: [PATCH 53/59] Change error handling in `cidr` `FromSql` implementations --- postgres-types/src/cidr_02.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/postgres-types/src/cidr_02.rs b/postgres-types/src/cidr_02.rs index d4e4965c5..2de952c3c 100644 --- a/postgres-types/src/cidr_02.rs +++ b/postgres-types/src/cidr_02.rs @@ -8,8 +8,7 @@ use crate::{FromSql, IsNull, ToSql, Type}; impl<'a> FromSql<'a> for IpCidr { fn from_sql(_: &Type, raw: &[u8]) -> Result> { let inet = types::inet_from_sql(raw)?; - Ok(IpCidr::new(inet.addr(), inet.netmask()) - .expect("postgres cidr type has zeroed host portion")) + Ok(IpCidr::new(inet.addr(), inet.netmask())?) } accepts!(CIDR); @@ -28,8 +27,7 @@ impl ToSql for IpCidr { impl<'a> FromSql<'a> for IpInet { fn from_sql(_: &Type, raw: &[u8]) -> Result> { let inet = types::inet_from_sql(raw)?; - Ok(IpInet::new(inet.addr(), inet.netmask()) - .expect("postgres enforces maximum length of netmask")) + Ok(IpInet::new(inet.addr(), inet.netmask())?) } accepts!(INET); From 944b72974f751ecd6ac72447af753cec7b88320e Mon Sep 17 00:00:00 2001 From: Matt Oliver Date: Thu, 3 Mar 2022 00:06:46 -0600 Subject: [PATCH 54/59] Add ltree, lquery and ltxtquery support --- postgres-protocol/Cargo.toml | 2 +- postgres-protocol/src/types/mod.rs | 16 ++++++ postgres-types/Cargo.toml | 4 +- postgres-types/src/lib.rs | 44 +++++++++++---- tokio-postgres/Cargo.toml | 6 +-- tokio-postgres/tests/test/types/mod.rs | 75 ++++++++++++++++++++++++++ 6 files changed, 131 insertions(+), 16 deletions(-) diff --git a/postgres-protocol/Cargo.toml b/postgres-protocol/Cargo.toml index 2010e88ad..a4716907b 100644 --- a/postgres-protocol/Cargo.toml +++ b/postgres-protocol/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "postgres-protocol" -version = "0.6.3" +version = "0.6.4" authors = ["Steven Fackler "] edition = "2018" description = "Low level Postgres protocol APIs" diff --git a/postgres-protocol/src/types/mod.rs b/postgres-protocol/src/types/mod.rs index a595f5a30..5939d9f00 100644 --- a/postgres-protocol/src/types/mod.rs +++ b/postgres-protocol/src/types/mod.rs @@ -1059,3 +1059,19 @@ impl Inet { self.netmask } } + +/// Serializes a Postgres l{tree,query,txtquery} string +#[inline] +pub fn ltree_to_sql(v: &str, buf: &mut BytesMut) { + // A version number is prepended to an Ltree string per spec + buf.put_u8(1); + // Append the rest of the query + buf.put_slice(v.as_bytes()); +} + +/// Deserialize a Postgres l{tree,query,txtquery} string +#[inline] +pub fn ltree_from_sql(buf: &[u8]) -> Result<&str, StdBox> { + // Remove the version number from the front of the string per spec + Ok(str::from_utf8(&buf[1..])?) +} diff --git a/postgres-types/Cargo.toml b/postgres-types/Cargo.toml index 9d470f37b..000d71ea0 100644 --- a/postgres-types/Cargo.toml +++ b/postgres-types/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "postgres-types" -version = "0.2.2" +version = "0.2.3" authors = ["Steven Fackler "] edition = "2018" license = "MIT/Apache-2.0" @@ -28,7 +28,7 @@ with-time-0_3 = ["time-03"] [dependencies] bytes = "1.0" fallible-iterator = "0.2" -postgres-protocol = { version = "0.6.1", path = "../postgres-protocol" } +postgres-protocol = { version = "0.6.4", path = "../postgres-protocol" } postgres-derive = { version = "0.4.0", optional = true, path = "../postgres-derive" } array-init = { version = "2", optional = true } diff --git a/postgres-types/src/lib.rs b/postgres-types/src/lib.rs index 394f938ff..bf7a1caee 100644 --- a/postgres-types/src/lib.rs +++ b/postgres-types/src/lib.rs @@ -594,8 +594,8 @@ impl<'a> FromSql<'a> for &'a [u8] { } impl<'a> FromSql<'a> for String { - fn from_sql(_: &Type, raw: &'a [u8]) -> Result> { - types::text_from_sql(raw).map(ToString::to_string) + fn from_sql(ty: &Type, raw: &'a [u8]) -> Result> { + <&str as FromSql>::from_sql(ty, raw).map(ToString::to_string) } fn accepts(ty: &Type) -> bool { @@ -604,8 +604,8 @@ impl<'a> FromSql<'a> for String { } impl<'a> FromSql<'a> for Box { - fn from_sql(_: &Type, raw: &'a [u8]) -> Result, Box> { - types::text_from_sql(raw) + fn from_sql(ty: &Type, raw: &'a [u8]) -> Result, Box> { + <&str as FromSql>::from_sql(ty, raw) .map(ToString::to_string) .map(String::into_boxed_str) } @@ -616,14 +616,26 @@ impl<'a> FromSql<'a> for Box { } impl<'a> FromSql<'a> for &'a str { - fn from_sql(_: &Type, raw: &'a [u8]) -> Result<&'a str, Box> { - types::text_from_sql(raw) + fn from_sql(ty: &Type, raw: &'a [u8]) -> Result<&'a str, Box> { + match *ty { + ref ty if ( + ty.name() == "ltree" || + ty.name() == "lquery" || + ty.name() == "ltxtquery" + ) => types::ltree_from_sql(raw), + _ => types::text_from_sql(raw) + } } fn accepts(ty: &Type) -> bool { match *ty { Type::VARCHAR | Type::TEXT | Type::BPCHAR | Type::NAME | Type::UNKNOWN => true, - ref ty if ty.name() == "citext" => true, + ref ty if ( + ty.name() == "citext" || + ty.name() == "ltree" || + ty.name() == "lquery" || + ty.name() == "ltxtquery" + ) => true, _ => false, } } @@ -924,15 +936,27 @@ impl ToSql for Vec { } impl<'a> ToSql for &'a str { - fn to_sql(&self, _: &Type, w: &mut BytesMut) -> Result> { - types::text_to_sql(*self, w); + fn to_sql(&self, ty: &Type, w: &mut BytesMut) -> Result> { + match ty { + ref ty if ( + ty.name() == "ltree" || + ty.name() == "lquery" || + ty.name() == "ltxtquery" + ) => types::ltree_to_sql(*self, w), + _ => types::text_to_sql(*self, w) + } Ok(IsNull::No) } fn accepts(ty: &Type) -> bool { match *ty { Type::VARCHAR | Type::TEXT | Type::BPCHAR | Type::NAME | Type::UNKNOWN => true, - ref ty if ty.name() == "citext" => true, + ref ty if ( + ty.name() == "citext" || + ty.name() == "ltree" || + ty.name() == "lquery" || + ty.name() == "ltxtquery" + ) => true, _ => false, } } diff --git a/tokio-postgres/Cargo.toml b/tokio-postgres/Cargo.toml index 94371af51..82e71fb1c 100644 --- a/tokio-postgres/Cargo.toml +++ b/tokio-postgres/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tokio-postgres" -version = "0.7.5" +version = "0.7.6" authors = ["Steven Fackler "] edition = "2018" license = "MIT/Apache-2.0" @@ -50,8 +50,8 @@ parking_lot = "0.12" percent-encoding = "2.0" pin-project-lite = "0.2" phf = "0.10" -postgres-protocol = { version = "0.6.1", path = "../postgres-protocol" } -postgres-types = { version = "0.2.2", path = "../postgres-types" } +postgres-protocol = { version = "0.6.4", path = "../postgres-protocol" } +postgres-types = { version = "0.2.3", path = "../postgres-types" } socket2 = "0.4" tokio = { version = "1.0", features = ["io-util"] } tokio-util = { version = "0.7", features = ["codec"] } diff --git a/tokio-postgres/tests/test/types/mod.rs b/tokio-postgres/tests/test/types/mod.rs index 604e2de32..0ec329a4f 100644 --- a/tokio-postgres/tests/test/types/mod.rs +++ b/tokio-postgres/tests/test/types/mod.rs @@ -648,3 +648,78 @@ async fn inet() { ) .await; } + +#[tokio::test] +async fn ltree() { + let client = connect("user=postgres").await; + client.execute("CREATE EXTENSION IF NOT EXISTS ltree;", &[]).await.unwrap(); + + test_type("ltree", &[ + (Some("b.c.d".to_owned()), "'b.c.d'"), + (None, "NULL"), + ]).await; +} + +#[tokio::test] +async fn ltree_any() { + let client = connect("user=postgres").await; + client.execute("CREATE EXTENSION IF NOT EXISTS ltree;", &[]).await.unwrap(); + + test_type("ltree[]", &[ + (Some(vec![]), "ARRAY[]"), + (Some(vec!["a.b.c".to_string()]), "ARRAY['a.b.c']"), + (Some(vec!["a.b.c".to_string(), "e.f.g".to_string()]), "ARRAY['a.b.c','e.f.g']"), + (None, "NULL"), + ]).await; +} + +#[tokio::test] +async fn lquery() { + let client = connect("user=postgres").await; + client.execute("CREATE EXTENSION IF NOT EXISTS ltree;", &[]).await.unwrap(); + + test_type("lquery", &[ + (Some("b.c.d".to_owned()), "'b.c.d'"), + (Some("b.c.*".to_owned()), "'b.c.*'"), + (Some("b.*{1,2}.d|e".to_owned()), "'b.*{1,2}.d|e'"), + (None, "NULL"), + ]).await; +} + +#[tokio::test] +async fn lquery_any() { + let client = connect("user=postgres").await; + client.execute("CREATE EXTENSION IF NOT EXISTS ltree;", &[]).await.unwrap(); + + test_type("lquery[]", &[ + (Some(vec![]), "ARRAY[]"), + (Some(vec!["b.c.*".to_string()]), "ARRAY['b.c.*']"), + (Some(vec!["b.c.*".to_string(), "b.*{1,2}.d|e".to_string()]), "ARRAY['b.c.*','b.*{1,2}.d|e']"), + (None, "NULL"), + ]).await; +} + +#[tokio::test] +async fn ltxtquery() { + let client = connect("user=postgres").await; + client.execute("CREATE EXTENSION IF NOT EXISTS ltree;", &[]).await.unwrap(); + + test_type("ltxtquery", &[ + (Some("b & c & d".to_owned()), "'b & c & d'"), + (Some("b@* & !c".to_owned()), "'b@* & !c'"), + (None, "NULL"), + ]).await; +} + +#[tokio::test] +async fn ltxtquery_any() { + let client = connect("user=postgres").await; + client.execute("CREATE EXTENSION IF NOT EXISTS ltree;", &[]).await.unwrap(); + + test_type("ltxtquery[]", &[ + (Some(vec![]), "ARRAY[]"), + (Some(vec!["b & c & d".to_string()]), "ARRAY['b & c & d']"), + (Some(vec!["b & c & d".to_string(), "b@* & !c".to_string()]), "ARRAY['b & c & d','b@* & !c']"), + (None, "NULL"), + ]).await; +} From 6ae60d6d09cb32eb8eca645488e5d86d4f2a33bb Mon Sep 17 00:00:00 2001 From: Matt Oliver Date: Thu, 3 Mar 2022 08:20:29 -0600 Subject: [PATCH 55/59] Add types to type docs --- postgres-types/src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/postgres-types/src/lib.rs b/postgres-types/src/lib.rs index bf7a1caee..9580fb5c1 100644 --- a/postgres-types/src/lib.rs +++ b/postgres-types/src/lib.rs @@ -407,6 +407,7 @@ impl WrongType { /// | `f32` | REAL | /// | `f64` | DOUBLE PRECISION | /// | `&str`/`String` | VARCHAR, CHAR(n), TEXT, CITEXT, NAME, UNKNOWN | +/// | | LTREE, LQUERY, LTXTQUERY | /// | `&[u8]`/`Vec` | BYTEA | /// | `HashMap>` | HSTORE | /// | `SystemTime` | TIMESTAMP, TIMESTAMP WITH TIME ZONE | @@ -739,6 +740,7 @@ pub enum IsNull { /// | `f32` | REAL | /// | `f64` | DOUBLE PRECISION | /// | `&str`/`String` | VARCHAR, CHAR(n), TEXT, CITEXT, NAME | +/// | | LTREE, LQUERY, LTXTQUERY | /// | `&[u8]`/`Vec` | BYTEA | /// | `HashMap>` | HSTORE | /// | `SystemTime` | TIMESTAMP, TIMESTAMP WITH TIME ZONE | From d9d283e131e3577bd82b292bbc8fa045c70e98fa Mon Sep 17 00:00:00 2001 From: Matt Oliver Date: Sat, 5 Mar 2022 14:55:07 -0600 Subject: [PATCH 56/59] Split out ltree,query,txtquery protocol parsers, add tests, rust fmt --- postgres-protocol/src/types/mod.rs | 51 +++++++++- postgres-protocol/src/types/test.rs | 116 +++++++++++++++++++++- postgres-types/src/lib.rs | 50 +++++----- tokio-postgres/tests/test/types/mod.rs | 128 +++++++++++++++++-------- 4 files changed, 274 insertions(+), 71 deletions(-) diff --git a/postgres-protocol/src/types/mod.rs b/postgres-protocol/src/types/mod.rs index 5939d9f00..05f515f76 100644 --- a/postgres-protocol/src/types/mod.rs +++ b/postgres-protocol/src/types/mod.rs @@ -1060,18 +1060,59 @@ impl Inet { } } -/// Serializes a Postgres l{tree,query,txtquery} string +/// Serializes a Postgres ltree string #[inline] pub fn ltree_to_sql(v: &str, buf: &mut BytesMut) { - // A version number is prepended to an Ltree string per spec + // A version number is prepended to an ltree string per spec buf.put_u8(1); // Append the rest of the query buf.put_slice(v.as_bytes()); } -/// Deserialize a Postgres l{tree,query,txtquery} string +/// Deserialize a Postgres ltree string #[inline] pub fn ltree_from_sql(buf: &[u8]) -> Result<&str, StdBox> { - // Remove the version number from the front of the string per spec - Ok(str::from_utf8(&buf[1..])?) + match buf { + // Remove the version number from the front of the ltree per spec + [1u8, rest @ ..] => Ok(str::from_utf8(rest)?), + _ => Err("ltree version 1 only supported".into()), + } +} + +/// Serializes a Postgres lquery string +#[inline] +pub fn lquery_to_sql(v: &str, buf: &mut BytesMut) { + // A version number is prepended to an lquery string per spec + buf.put_u8(1); + // Append the rest of the query + buf.put_slice(v.as_bytes()); +} + +/// Deserialize a Postgres lquery string +#[inline] +pub fn lquery_from_sql(buf: &[u8]) -> Result<&str, StdBox> { + match buf { + // Remove the version number from the front of the lquery per spec + [1u8, rest @ ..] => Ok(str::from_utf8(rest)?), + _ => Err("lquery version 1 only supported".into()), + } +} + +/// Serializes a Postgres ltxtquery string +#[inline] +pub fn ltxtquery_to_sql(v: &str, buf: &mut BytesMut) { + // A version number is prepended to an ltxtquery string per spec + buf.put_u8(1); + // Append the rest of the query + buf.put_slice(v.as_bytes()); +} + +/// Deserialize a Postgres ltxtquery string +#[inline] +pub fn ltxtquery_from_sql(buf: &[u8]) -> Result<&str, StdBox> { + match buf { + // Remove the version number from the front of the ltxtquery per spec + [1u8, rest @ ..] => Ok(str::from_utf8(rest)?), + _ => Err("ltxtquery version 1 only supported".into()), + } } diff --git a/postgres-protocol/src/types/test.rs b/postgres-protocol/src/types/test.rs index 7c20cf3ed..1ce49b66f 100644 --- a/postgres-protocol/src/types/test.rs +++ b/postgres-protocol/src/types/test.rs @@ -1,4 +1,4 @@ -use bytes::BytesMut; +use bytes::{Buf, BytesMut}; use fallible_iterator::FallibleIterator; use std::collections::HashMap; @@ -156,3 +156,117 @@ fn non_null_array() { assert_eq!(array.dimensions().collect::>().unwrap(), dimensions); assert_eq!(array.values().collect::>().unwrap(), values); } + +#[test] +fn ltree_sql() { + let mut query = vec![1u8]; + query.extend_from_slice("A.B.C".as_bytes()); + + let mut buf = BytesMut::new(); + + ltree_to_sql("A.B.C", &mut buf); + + assert_eq!(query.as_slice(), buf.chunk()); +} + +#[test] +fn ltree_str() { + let mut query = vec![1u8]; + query.extend_from_slice("A.B.C".as_bytes()); + + let success = match ltree_from_sql(query.as_slice()) { + Ok(_) => true, + _ => false, + }; + + assert!(success) +} + +#[test] +fn ltree_wrong_version() { + let mut query = vec![2u8]; + query.extend_from_slice("A.B.C".as_bytes()); + + let success = match ltree_from_sql(query.as_slice()) { + Err(_) => true, + _ => false, + }; + + assert!(success) +} + +#[test] +fn lquery_sql() { + let mut query = vec![1u8]; + query.extend_from_slice("A.B.C".as_bytes()); + + let mut buf = BytesMut::new(); + + lquery_to_sql("A.B.C", &mut buf); + + assert_eq!(query.as_slice(), buf.chunk()); +} + +#[test] +fn lquery_str() { + let mut query = vec![1u8]; + query.extend_from_slice("A.B.C".as_bytes()); + + let success = match lquery_from_sql(query.as_slice()) { + Ok(_) => true, + _ => false, + }; + + assert!(success) +} + +#[test] +fn lquery_wrong_version() { + let mut query = vec![2u8]; + query.extend_from_slice("A.B.C".as_bytes()); + + let success = match lquery_from_sql(query.as_slice()) { + Err(_) => true, + _ => false, + }; + + assert!(success) +} + +#[test] +fn ltxtquery_sql() { + let mut query = vec![1u8]; + query.extend_from_slice("a & b*".as_bytes()); + + let mut buf = BytesMut::new(); + + ltree_to_sql("a & b*", &mut buf); + + assert_eq!(query.as_slice(), buf.chunk()); +} + +#[test] +fn ltxtquery_str() { + let mut query = vec![1u8]; + query.extend_from_slice("a & b*".as_bytes()); + + let success = match ltree_from_sql(query.as_slice()) { + Ok(_) => true, + _ => false, + }; + + assert!(success) +} + +#[test] +fn ltxtquery_wrong_version() { + let mut query = vec![2u8]; + query.extend_from_slice("a & b*".as_bytes()); + + let success = match ltree_from_sql(query.as_slice()) { + Err(_) => true, + _ => false, + }; + + assert!(success) +} diff --git a/postgres-types/src/lib.rs b/postgres-types/src/lib.rs index 9580fb5c1..d029d3948 100644 --- a/postgres-types/src/lib.rs +++ b/postgres-types/src/lib.rs @@ -619,24 +619,24 @@ impl<'a> FromSql<'a> for Box { impl<'a> FromSql<'a> for &'a str { fn from_sql(ty: &Type, raw: &'a [u8]) -> Result<&'a str, Box> { match *ty { - ref ty if ( - ty.name() == "ltree" || - ty.name() == "lquery" || - ty.name() == "ltxtquery" - ) => types::ltree_from_sql(raw), - _ => types::text_from_sql(raw) + ref ty if ty.name() == "ltree" => types::ltree_from_sql(raw), + ref ty if ty.name() == "lquery" => types::lquery_from_sql(raw), + ref ty if ty.name() == "ltxtquery" => types::ltxtquery_from_sql(raw), + _ => types::text_from_sql(raw), } } fn accepts(ty: &Type) -> bool { match *ty { Type::VARCHAR | Type::TEXT | Type::BPCHAR | Type::NAME | Type::UNKNOWN => true, - ref ty if ( - ty.name() == "citext" || - ty.name() == "ltree" || - ty.name() == "lquery" || - ty.name() == "ltxtquery" - ) => true, + ref ty + if (ty.name() == "citext" + || ty.name() == "ltree" + || ty.name() == "lquery" + || ty.name() == "ltxtquery") => + { + true + } _ => false, } } @@ -939,13 +939,11 @@ impl ToSql for Vec { impl<'a> ToSql for &'a str { fn to_sql(&self, ty: &Type, w: &mut BytesMut) -> Result> { - match ty { - ref ty if ( - ty.name() == "ltree" || - ty.name() == "lquery" || - ty.name() == "ltxtquery" - ) => types::ltree_to_sql(*self, w), - _ => types::text_to_sql(*self, w) + match *ty { + ref ty if ty.name() == "ltree" => types::ltree_to_sql(*self, w), + ref ty if ty.name() == "lquery" => types::lquery_to_sql(*self, w), + ref ty if ty.name() == "ltxtquery" => types::ltxtquery_to_sql(*self, w), + _ => types::text_to_sql(*self, w), } Ok(IsNull::No) } @@ -953,12 +951,14 @@ impl<'a> ToSql for &'a str { fn accepts(ty: &Type) -> bool { match *ty { Type::VARCHAR | Type::TEXT | Type::BPCHAR | Type::NAME | Type::UNKNOWN => true, - ref ty if ( - ty.name() == "citext" || - ty.name() == "ltree" || - ty.name() == "lquery" || - ty.name() == "ltxtquery" - ) => true, + ref ty + if (ty.name() == "citext" + || ty.name() == "ltree" + || ty.name() == "lquery" + || ty.name() == "ltxtquery") => + { + true + } _ => false, } } diff --git a/tokio-postgres/tests/test/types/mod.rs b/tokio-postgres/tests/test/types/mod.rs index 0ec329a4f..f69932e55 100644 --- a/tokio-postgres/tests/test/types/mod.rs +++ b/tokio-postgres/tests/test/types/mod.rs @@ -652,74 +652,122 @@ async fn inet() { #[tokio::test] async fn ltree() { let client = connect("user=postgres").await; - client.execute("CREATE EXTENSION IF NOT EXISTS ltree;", &[]).await.unwrap(); + client + .execute("CREATE EXTENSION IF NOT EXISTS ltree;", &[]) + .await + .unwrap(); - test_type("ltree", &[ - (Some("b.c.d".to_owned()), "'b.c.d'"), - (None, "NULL"), - ]).await; + test_type( + "ltree", + &[(Some("b.c.d".to_owned()), "'b.c.d'"), (None, "NULL")], + ) + .await; } #[tokio::test] async fn ltree_any() { let client = connect("user=postgres").await; - client.execute("CREATE EXTENSION IF NOT EXISTS ltree;", &[]).await.unwrap(); + client + .execute("CREATE EXTENSION IF NOT EXISTS ltree;", &[]) + .await + .unwrap(); - test_type("ltree[]", &[ - (Some(vec![]), "ARRAY[]"), - (Some(vec!["a.b.c".to_string()]), "ARRAY['a.b.c']"), - (Some(vec!["a.b.c".to_string(), "e.f.g".to_string()]), "ARRAY['a.b.c','e.f.g']"), - (None, "NULL"), - ]).await; + test_type( + "ltree[]", + &[ + (Some(vec![]), "ARRAY[]"), + (Some(vec!["a.b.c".to_string()]), "ARRAY['a.b.c']"), + ( + Some(vec!["a.b.c".to_string(), "e.f.g".to_string()]), + "ARRAY['a.b.c','e.f.g']", + ), + (None, "NULL"), + ], + ) + .await; } #[tokio::test] async fn lquery() { let client = connect("user=postgres").await; - client.execute("CREATE EXTENSION IF NOT EXISTS ltree;", &[]).await.unwrap(); + client + .execute("CREATE EXTENSION IF NOT EXISTS ltree;", &[]) + .await + .unwrap(); - test_type("lquery", &[ - (Some("b.c.d".to_owned()), "'b.c.d'"), - (Some("b.c.*".to_owned()), "'b.c.*'"), - (Some("b.*{1,2}.d|e".to_owned()), "'b.*{1,2}.d|e'"), - (None, "NULL"), - ]).await; + test_type( + "lquery", + &[ + (Some("b.c.d".to_owned()), "'b.c.d'"), + (Some("b.c.*".to_owned()), "'b.c.*'"), + (Some("b.*{1,2}.d|e".to_owned()), "'b.*{1,2}.d|e'"), + (None, "NULL"), + ], + ) + .await; } #[tokio::test] async fn lquery_any() { let client = connect("user=postgres").await; - client.execute("CREATE EXTENSION IF NOT EXISTS ltree;", &[]).await.unwrap(); + client + .execute("CREATE EXTENSION IF NOT EXISTS ltree;", &[]) + .await + .unwrap(); - test_type("lquery[]", &[ - (Some(vec![]), "ARRAY[]"), - (Some(vec!["b.c.*".to_string()]), "ARRAY['b.c.*']"), - (Some(vec!["b.c.*".to_string(), "b.*{1,2}.d|e".to_string()]), "ARRAY['b.c.*','b.*{1,2}.d|e']"), - (None, "NULL"), - ]).await; + test_type( + "lquery[]", + &[ + (Some(vec![]), "ARRAY[]"), + (Some(vec!["b.c.*".to_string()]), "ARRAY['b.c.*']"), + ( + Some(vec!["b.c.*".to_string(), "b.*{1,2}.d|e".to_string()]), + "ARRAY['b.c.*','b.*{1,2}.d|e']", + ), + (None, "NULL"), + ], + ) + .await; } #[tokio::test] async fn ltxtquery() { let client = connect("user=postgres").await; - client.execute("CREATE EXTENSION IF NOT EXISTS ltree;", &[]).await.unwrap(); + client + .execute("CREATE EXTENSION IF NOT EXISTS ltree;", &[]) + .await + .unwrap(); - test_type("ltxtquery", &[ - (Some("b & c & d".to_owned()), "'b & c & d'"), - (Some("b@* & !c".to_owned()), "'b@* & !c'"), - (None, "NULL"), - ]).await; + test_type( + "ltxtquery", + &[ + (Some("b & c & d".to_owned()), "'b & c & d'"), + (Some("b@* & !c".to_owned()), "'b@* & !c'"), + (None, "NULL"), + ], + ) + .await; } #[tokio::test] async fn ltxtquery_any() { let client = connect("user=postgres").await; - client.execute("CREATE EXTENSION IF NOT EXISTS ltree;", &[]).await.unwrap(); - - test_type("ltxtquery[]", &[ - (Some(vec![]), "ARRAY[]"), - (Some(vec!["b & c & d".to_string()]), "ARRAY['b & c & d']"), - (Some(vec!["b & c & d".to_string(), "b@* & !c".to_string()]), "ARRAY['b & c & d','b@* & !c']"), - (None, "NULL"), - ]).await; + client + .execute("CREATE EXTENSION IF NOT EXISTS ltree;", &[]) + .await + .unwrap(); + + test_type( + "ltxtquery[]", + &[ + (Some(vec![]), "ARRAY[]"), + (Some(vec!["b & c & d".to_string()]), "ARRAY['b & c & d']"), + ( + Some(vec!["b & c & d".to_string(), "b@* & !c".to_string()]), + "ARRAY['b & c & d','b@* & !c']", + ), + (None, "NULL"), + ], + ) + .await; } From 6fae6552ecc5e6755360bd33e9ede3e51b7eb566 Mon Sep 17 00:00:00 2001 From: Matt Oliver Date: Wed, 16 Mar 2022 21:20:34 -0500 Subject: [PATCH 57/59] Fix tests, replace match with matches! --- docker/sql_setup.sh | 1 + postgres-protocol/src/types/test.rs | 42 ++++---------------------- tokio-postgres/tests/test/types/mod.rs | 36 ---------------------- 3 files changed, 7 insertions(+), 72 deletions(-) diff --git a/docker/sql_setup.sh b/docker/sql_setup.sh index 422dcbda9..0315ac805 100755 --- a/docker/sql_setup.sh +++ b/docker/sql_setup.sh @@ -96,4 +96,5 @@ psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" <<-EOSQL CREATE ROLE ssl_user LOGIN; CREATE EXTENSION hstore; CREATE EXTENSION citext; + CREATE EXTENSION ltree; EOSQL diff --git a/postgres-protocol/src/types/test.rs b/postgres-protocol/src/types/test.rs index 1ce49b66f..6f1851fc2 100644 --- a/postgres-protocol/src/types/test.rs +++ b/postgres-protocol/src/types/test.rs @@ -174,12 +174,7 @@ fn ltree_str() { let mut query = vec![1u8]; query.extend_from_slice("A.B.C".as_bytes()); - let success = match ltree_from_sql(query.as_slice()) { - Ok(_) => true, - _ => false, - }; - - assert!(success) + assert!(matches!(ltree_from_sql(query.as_slice()), Ok(_))) } #[test] @@ -187,12 +182,7 @@ fn ltree_wrong_version() { let mut query = vec![2u8]; query.extend_from_slice("A.B.C".as_bytes()); - let success = match ltree_from_sql(query.as_slice()) { - Err(_) => true, - _ => false, - }; - - assert!(success) + assert!(matches!(ltree_from_sql(query.as_slice()), Err(_))) } #[test] @@ -212,12 +202,7 @@ fn lquery_str() { let mut query = vec![1u8]; query.extend_from_slice("A.B.C".as_bytes()); - let success = match lquery_from_sql(query.as_slice()) { - Ok(_) => true, - _ => false, - }; - - assert!(success) + assert!(matches!(lquery_from_sql(query.as_slice()), Ok(_))) } #[test] @@ -225,12 +210,7 @@ fn lquery_wrong_version() { let mut query = vec![2u8]; query.extend_from_slice("A.B.C".as_bytes()); - let success = match lquery_from_sql(query.as_slice()) { - Err(_) => true, - _ => false, - }; - - assert!(success) + assert!(matches!(lquery_from_sql(query.as_slice()), Err(_))) } #[test] @@ -250,12 +230,7 @@ fn ltxtquery_str() { let mut query = vec![1u8]; query.extend_from_slice("a & b*".as_bytes()); - let success = match ltree_from_sql(query.as_slice()) { - Ok(_) => true, - _ => false, - }; - - assert!(success) + assert!(matches!(ltree_from_sql(query.as_slice()), Ok(_))) } #[test] @@ -263,10 +238,5 @@ fn ltxtquery_wrong_version() { let mut query = vec![2u8]; query.extend_from_slice("a & b*".as_bytes()); - let success = match ltree_from_sql(query.as_slice()) { - Err(_) => true, - _ => false, - }; - - assert!(success) + assert!(matches!(ltree_from_sql(query.as_slice()), Err(_))) } diff --git a/tokio-postgres/tests/test/types/mod.rs b/tokio-postgres/tests/test/types/mod.rs index f69932e55..de700d791 100644 --- a/tokio-postgres/tests/test/types/mod.rs +++ b/tokio-postgres/tests/test/types/mod.rs @@ -651,12 +651,6 @@ async fn inet() { #[tokio::test] async fn ltree() { - let client = connect("user=postgres").await; - client - .execute("CREATE EXTENSION IF NOT EXISTS ltree;", &[]) - .await - .unwrap(); - test_type( "ltree", &[(Some("b.c.d".to_owned()), "'b.c.d'"), (None, "NULL")], @@ -666,12 +660,6 @@ async fn ltree() { #[tokio::test] async fn ltree_any() { - let client = connect("user=postgres").await; - client - .execute("CREATE EXTENSION IF NOT EXISTS ltree;", &[]) - .await - .unwrap(); - test_type( "ltree[]", &[ @@ -689,12 +677,6 @@ async fn ltree_any() { #[tokio::test] async fn lquery() { - let client = connect("user=postgres").await; - client - .execute("CREATE EXTENSION IF NOT EXISTS ltree;", &[]) - .await - .unwrap(); - test_type( "lquery", &[ @@ -709,12 +691,6 @@ async fn lquery() { #[tokio::test] async fn lquery_any() { - let client = connect("user=postgres").await; - client - .execute("CREATE EXTENSION IF NOT EXISTS ltree;", &[]) - .await - .unwrap(); - test_type( "lquery[]", &[ @@ -732,12 +708,6 @@ async fn lquery_any() { #[tokio::test] async fn ltxtquery() { - let client = connect("user=postgres").await; - client - .execute("CREATE EXTENSION IF NOT EXISTS ltree;", &[]) - .await - .unwrap(); - test_type( "ltxtquery", &[ @@ -751,12 +721,6 @@ async fn ltxtquery() { #[tokio::test] async fn ltxtquery_any() { - let client = connect("user=postgres").await; - client - .execute("CREATE EXTENSION IF NOT EXISTS ltree;", &[]) - .await - .unwrap(); - test_type( "ltxtquery[]", &[ From 3802f9e7371fa13d79bf22d9815da07e63c4eee9 Mon Sep 17 00:00:00 2001 From: Julius de Bruijn Date: Wed, 22 Jul 2020 15:29:12 +0200 Subject: [PATCH 58/59] Configuration to disable internal stmt cache This enables usage with pgBouncer's transaction mode. Typically when using the transaction mode, a client gets a new connection from pgBouncer for every new transaction. It's quite useful and allows one to use prepared statements in this mode. The workflow goes: ```sql -- start a new transaction BEGIN -- deallocate all stored statements from the server to prevent -- collisions DEALLOCATE ALL -- run the queries here -- .. -- .. COMMIT -- or ROLLBACK ``` Now in a case where the query uses custom types such as enums, what tokio-postgres does is it fetches the type info for the given type, stores the info to the cache and also caches the statements for fetching the info to the client. Now when we have two tables with different custom types in both of them, we can imagine the following workflow: ```rust // first query client.simple_query("BEGIN")?; client.simple_query("DEALLOCATE ALL")?; let stmt = client.prepare("SELECT \"public\".\"User\".\"id\", \"public\".\"User\".\"userType\" FROM \"public\".\"User\" WHERE 1=1 OFFSET $1")?; dbg!(client.query(&stmt, &[&0i64])?); client.simple_query("COMMIT")?; // second query client.simple_query("BEGIN")?; client.simple_query("DEALLOCATE ALL")?; let stmt = client.prepare("SELECT \"public\".\"Work\".\"id\", \"public\".\"Work\".\"workType\" FROM \"public\".\"Work\" WHERE 1=1 OFFSET $1")?; dbg!(client.query(&stmt, &[&0i64])?); client.simple_query("COMMIT")?; ``` The `userType` and `workType` are both enums, and the preparing of the second query will give an error `prepared statement "s1" does not exist`, where `s1` is the query to the `pg_catalog` for the type info. The change here gives an extra flag for the client to disable caching of statements. --- .direnv/cache-pre278406.d3f7e969b98 | 1 + .direnv/drv | 1 + .envrc | 1 + postgres/src/config.rs | 15 +++++++++++++ shell.nix | 14 ++++++++++++ tokio-postgres/src/client.rs | 33 +++++++++++++++++++++++------ tokio-postgres/src/config.rs | 17 +++++++++++++++ tokio-postgres/src/connect_raw.rs | 8 ++++++- 8 files changed, 83 insertions(+), 7 deletions(-) create mode 100644 .direnv/cache-pre278406.d3f7e969b98 create mode 120000 .direnv/drv create mode 100644 .envrc create mode 100644 shell.nix diff --git a/.direnv/cache-pre278406.d3f7e969b98 b/.direnv/cache-pre278406.d3f7e969b98 new file mode 100644 index 000000000..e42ff2183 --- /dev/null +++ b/.direnv/cache-pre278406.d3f7e969b98 @@ -0,0 +1 @@ +export $'depsTargetTarget'='';export $'phases'=$'nobuildPhase';export NIX_ENFORCE_NO_NATIVE=1;export XDG_DATA_DIRS=$'/nix/store/8nwgidwa623jkz09wn0rjvcs07jjval3-patchelf-0.12/share';export NIX_SSL_CERT_FILE=$'/no-cert-file.crt';export HOST_PATH=$'/nix/store/ra609mrrl92jirph1zbahcb06pxmjhcl-openssl-1.1.1j-bin/bin:/nix/store/7hgm9nfh4c6fs3qxma9472la2hcp5x03-pkg-config-wrapper-0.29.2/bin:/nix/store/yzygh1nkk6sj3hrdrq8lqfg0hff80ww5-libkrb5-1.18-dev/bin:/nix/store/f059zv2fl9ml1q53qj5wbwi8xiim28g1-libkrb5-1.18/bin:/nix/store/9fkdn82nzxgkxyax3m9qdh2knj7apaa5-coreutils-8.32/bin:/nix/store/7nx8fqzpi5nsbi07md1qb1gbf9fscf9i-findutils-4.7.0/bin:/nix/store/7v1xa3528d5frr55d3dhl991zx7by169-diffutils-3.7/bin:/nix/store/ij7k48dhdrda13gcp3lbpi507b2awnmr-gnused-4.8/bin:/nix/store/ia1dn8zyi07phxkx02c0wwqc7v7c54nl-gnugrep-3.6/bin:/nix/store/9sscma6kgp35kb70bi8pms35ppk7j35r-gawk-5.1.0/bin:/nix/store/hxpycgfpdnmnc9iwxakxr037k0bvdq97-gnutar-1.32/bin:/nix/store/89kh3d91b9i9mqh39fj6xdff1sw81m9f-gzip-1.10/bin:/nix/store/vw1lcig1bkncmsmhif27h8hq1gaxldhg-bzip2-1.0.6.0.2-bin/bin:/nix/store/n7vham7g9lgwb7v83sk5nl7akk3zspvq-gnumake-4.3/bin:/nix/store/w65ydq10abi813fi7d5j7afdcrxj3aqq-bash-4.4-p23/bin:/nix/store/lsr2s27gbqxny7layxjab55dlqzrl1v2-patch-2.7.6/bin:/nix/store/sg3h64z6a7mxmap8zgrhhjscpri5b5vn-xz-5.2.5-bin/bin';export $'buildInputs'=$'/nix/store/kic4qky3myhflpf8x6zqq332vqj4wa23-openssl-1.1.1j-dev /nix/store/7hgm9nfh4c6fs3qxma9472la2hcp5x03-pkg-config-wrapper-0.29.2 /nix/store/g2h7j8n4cl8396zvma3qkyf326n0p6d5-stdenv-linux /nix/store/wqc643blcnnw2k9m2r9vc4jd3nk22377-clang-7.1.0-lib /nix/store/yzygh1nkk6sj3hrdrq8lqfg0hff80ww5-libkrb5-1.18-dev';export $'propagatedNativeBuildInputs'='';export LD=$'ld';export SOURCE_DATE_EPOCH=315532800;export $'depsTargetTargetPropagated'='';export OBJCOPY=$'objcopy';export RANLIB=$'ranlib';export AR=$'ar';export NIX_CC=$'/nix/store/pqiwg1jw0s7qzdi4m9xbps2jb98fsxbx-gcc-wrapper-10.2.0';export NIX_BINTOOLS=$'/nix/store/r7v3x5a68a4mxc2kh04cmyzx7xq00w2g-binutils-wrapper-2.35.1';export TEMPDIR=$'/run/user/1000';export LOGNAME=$'pimeys';export CC=$'gcc';export STRIP=$'strip';export PKG_CONFIG_PATH_FOR_TARGET=$'/nix/store/kic4qky3myhflpf8x6zqq332vqj4wa23-openssl-1.1.1j-dev/lib/pkgconfig:/nix/store/yzygh1nkk6sj3hrdrq8lqfg0hff80ww5-libkrb5-1.18-dev/lib/pkgconfig';export HOME=$'/home/pimeys';export $'configureFlags'='';export $'shellHook'='';export NIX_BUILD_TOP=$'/run/user/1000';export __ETC_PROFILE_SOURCED=1;export $'out'=$'/nix/store/z4kmx9zl4dfg558lzlf5ayw111jd75kj-nix-shell';export $'system'=$'x86_64-linux';export TMPDIR=$'/run/user/1000';export $'name'=$'nix-shell';export NM=$'nm';export PKG_CONFIG_FOR_TARGET=$'pkg-config';export _=$'/nix/store/p579xdpm0prfjhhbxibhrrjcyix172ln-direnv-2.28.0/bin/direnv';export $'builder'=$'/nix/store/w65ydq10abi813fi7d5j7afdcrxj3aqq-bash-4.4-p23/bin/bash';export $'strictDeps'='';export NIX_CFLAGS_COMPILE=$' -frandom-seed=z4kmx9zl4d -isystem /nix/store/kic4qky3myhflpf8x6zqq332vqj4wa23-openssl-1.1.1j-dev/include -isystem /nix/store/yzygh1nkk6sj3hrdrq8lqfg0hff80ww5-libkrb5-1.18-dev/include -isystem /nix/store/kic4qky3myhflpf8x6zqq332vqj4wa23-openssl-1.1.1j-dev/include -isystem /nix/store/yzygh1nkk6sj3hrdrq8lqfg0hff80ww5-libkrb5-1.18-dev/include';export OBJDUMP=$'objdump';export STRINGS=$'strings';export $'outputs'=$'out';export $'NIX_BINTOOLS_WRAPPER_TARGET_HOST_x86_64_unknown_linux_gnu'=1;export PATH=$'/nix/store/mshinwyjb1imfpdjmrpbbh3r7zz5sn6x-bash-interactive-4.4-p23/bin:/nix/store/8nwgidwa623jkz09wn0rjvcs07jjval3-patchelf-0.12/bin:/nix/store/pqiwg1jw0s7qzdi4m9xbps2jb98fsxbx-gcc-wrapper-10.2.0/bin:/nix/store/xrb5qsxpvhpm0irr9ykfqpvj8a6sk4xh-gcc-10.2.0/bin:/nix/store/b6p5cspsidkc2bpljhwz7d0nbmgrx5z0-glibc-2.32-37-bin/bin:/nix/store/9fkdn82nzxgkxyax3m9qdh2knj7apaa5-coreutils-8.32/bin:/nix/store/r7v3x5a68a4mxc2kh04cmyzx7xq00w2g-binutils-wrapper-2.35.1/bin:/nix/store/xdii8qvch5h8chyp0z2is2qzky565w68-binutils-2.35.1/bin:/nix/store/b6p5cspsidkc2bpljhwz7d0nbmgrx5z0-glibc-2.32-37-bin/bin:/nix/store/9fkdn82nzxgkxyax3m9qdh2knj7apaa5-coreutils-8.32/bin:/nix/store/ra609mrrl92jirph1zbahcb06pxmjhcl-openssl-1.1.1j-bin/bin:/nix/store/7hgm9nfh4c6fs3qxma9472la2hcp5x03-pkg-config-wrapper-0.29.2/bin:/nix/store/yzygh1nkk6sj3hrdrq8lqfg0hff80ww5-libkrb5-1.18-dev/bin:/nix/store/f059zv2fl9ml1q53qj5wbwi8xiim28g1-libkrb5-1.18/bin:/nix/store/9fkdn82nzxgkxyax3m9qdh2knj7apaa5-coreutils-8.32/bin:/nix/store/7nx8fqzpi5nsbi07md1qb1gbf9fscf9i-findutils-4.7.0/bin:/nix/store/7v1xa3528d5frr55d3dhl991zx7by169-diffutils-3.7/bin:/nix/store/ij7k48dhdrda13gcp3lbpi507b2awnmr-gnused-4.8/bin:/nix/store/ia1dn8zyi07phxkx02c0wwqc7v7c54nl-gnugrep-3.6/bin:/nix/store/9sscma6kgp35kb70bi8pms35ppk7j35r-gawk-5.1.0/bin:/nix/store/hxpycgfpdnmnc9iwxakxr037k0bvdq97-gnutar-1.32/bin:/nix/store/89kh3d91b9i9mqh39fj6xdff1sw81m9f-gzip-1.10/bin:/nix/store/vw1lcig1bkncmsmhif27h8hq1gaxldhg-bzip2-1.0.6.0.2-bin/bin:/nix/store/n7vham7g9lgwb7v83sk5nl7akk3zspvq-gnumake-4.3/bin:/nix/store/w65ydq10abi813fi7d5j7afdcrxj3aqq-bash-4.4-p23/bin:/nix/store/lsr2s27gbqxny7layxjab55dlqzrl1v2-patch-2.7.6/bin:/nix/store/sg3h64z6a7mxmap8zgrhhjscpri5b5vn-xz-5.2.5-bin/bin';export NIX_STORE=$'/nix/store';export $'doInstallCheck'='';export IN_NIX_SHELL=$'pure';export SHELL=$'/nix/store/mshinwyjb1imfpdjmrpbbh3r7zz5sn6x-bash-interactive-4.4-p23/bin/bash';export LIBCLANG_PATH=$'/nix/store/wqc643blcnnw2k9m2r9vc4jd3nk22377-clang-7.1.0-lib/lib';export READELF=$'readelf';export TMP=$'/run/user/1000';export $'propagatedBuildInputs'='';export SSL_CERT_FILE=$'/no-cert-file.crt';export TERM=$'xterm-256color';export NIX_LDFLAGS=$'-rpath /nix/store/z4kmx9zl4dfg558lzlf5ayw111jd75kj-nix-shell/lib64 -rpath /nix/store/z4kmx9zl4dfg558lzlf5ayw111jd75kj-nix-shell/lib -L/nix/store/1pzq6yh1r415ykizk6zw61z5jlkx9994-openssl-1.1.1j/lib -L/nix/store/wqc643blcnnw2k9m2r9vc4jd3nk22377-clang-7.1.0-lib/lib -L/nix/store/f059zv2fl9ml1q53qj5wbwi8xiim28g1-libkrb5-1.18/lib -L/nix/store/1pzq6yh1r415ykizk6zw61z5jlkx9994-openssl-1.1.1j/lib -L/nix/store/wqc643blcnnw2k9m2r9vc4jd3nk22377-clang-7.1.0-lib/lib -L/nix/store/f059zv2fl9ml1q53qj5wbwi8xiim28g1-libkrb5-1.18/lib';export $'shell'=$'/nix/store/w65ydq10abi813fi7d5j7afdcrxj3aqq-bash-4.4-p23/bin/bash';export NIX_INDENT_MAKE=1;export TEMP=$'/run/user/1000';export DISPLAY=$':1';export USER=$'pimeys';export $'depsBuildBuild'='';export $'nativeBuildInputs'='';export NIX_HARDENING_ENABLE=$'fortify stackprotector pic strictoverflow format relro bindnow';export $'depsBuildTargetPropagated'='';export PAGER=$'less -R';export $'NIX_PKG_CONFIG_WRAPPER_TARGET_TARGET_x86_64_unknown_linux_gnu'=1;export $'depsBuildBuildPropagated'='';export $'depsBuildTarget'='';export $'NIX_CC_WRAPPER_TARGET_HOST_x86_64_unknown_linux_gnu'=1;export SHLVL=4;export $'depsHostHost'='';export $'patches'='';export $'nobuildPhase'=$'echo\necho "This derivation is not meant to be built, aborting";\necho\nexit 1\n';export AS=$'as';export CXX=$'g++';export $'depsHostHostPropagated'='';export NIX_BUILD_CORES=32;export SIZE=$'size';export $'stdenv'=$'/nix/store/6c47azxacncswc1pllzj28zfzqw40d7c-stdenv-linux';export CONFIG_SHELL=$'/nix/store/w65ydq10abi813fi7d5j7afdcrxj3aqq-bash-4.4-p23/bin/bash';export $'doCheck'=''; diff --git a/.direnv/drv b/.direnv/drv new file mode 120000 index 000000000..455fc4503 --- /dev/null +++ b/.direnv/drv @@ -0,0 +1 @@ +/nix/store/y6sw1ry62ik9v6qv4zl59ari6g1swrxd-nix-shell.drv \ No newline at end of file diff --git a/.envrc b/.envrc new file mode 100644 index 000000000..1d953f4bd --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ +use nix diff --git a/postgres/src/config.rs b/postgres/src/config.rs index c8dffa330..7afd1e355 100644 --- a/postgres/src/config.rs +++ b/postgres/src/config.rs @@ -328,6 +328,21 @@ impl Config { self } + /// When enabled, the client skips all internal caching for statements, + /// allowing usage with pgBouncer's transaction mode and clearing of + /// statements in the session with `DEALLOCATE ALL`. + /// + /// Defaults to `false`. + pub fn pgbouncer_mode(&mut self, enable: bool) -> &mut Config { + self.config.pgbouncer_mode(enable); + self + } + + /// Gets the pgBouncer mode status. + pub fn get_pgbouncer_mode(&self) -> bool { + self.config.get_pgbouncer_mode() + } + /// Opens a connection to a PostgreSQL database. pub fn connect(&self, tls: T) -> Result where diff --git a/shell.nix b/shell.nix new file mode 100644 index 000000000..deedbab21 --- /dev/null +++ b/shell.nix @@ -0,0 +1,14 @@ +{ pkgs ? import {} }: + +with pkgs; + +mkShell { + LIBCLANG_PATH="${pkgs.llvmPackages.libclang}/lib"; + buildInputs = with pkgs; [ + openssl + pkg-config + clangStdenv + llvmPackages.libclang + kerberos + ]; +} diff --git a/tokio-postgres/src/client.rs b/tokio-postgres/src/client.rs index dea77da94..79978be43 100644 --- a/tokio-postgres/src/client.rs +++ b/tokio-postgres/src/client.rs @@ -80,6 +80,7 @@ pub struct InnerClient { /// A buffer to use when writing out postgres commands. buffer: Mutex, + pgbouncer_mode: bool, } impl InnerClient { @@ -97,27 +98,45 @@ impl InnerClient { } pub fn typeinfo(&self) -> Option { - self.cached_typeinfo.lock().typeinfo.clone() + if self.pgbouncer_mode { + None + } else { + self.cached_typeinfo.lock().typeinfo.clone() + } } pub fn set_typeinfo(&self, statement: &Statement) { - self.cached_typeinfo.lock().typeinfo = Some(statement.clone()); + if !self.pgbouncer_mode { + self.cached_typeinfo.lock().typeinfo = Some(statement.clone()); + } } pub fn typeinfo_composite(&self) -> Option { - self.cached_typeinfo.lock().typeinfo_composite.clone() + if self.pgbouncer_mode { + None + } else { + self.cached_typeinfo.lock().typeinfo_composite.clone() + } } pub fn set_typeinfo_composite(&self, statement: &Statement) { - self.cached_typeinfo.lock().typeinfo_composite = Some(statement.clone()); + if !self.pgbouncer_mode { + self.cached_typeinfo.lock().typeinfo_composite = Some(statement.clone()); + } } pub fn typeinfo_enum(&self) -> Option { - self.cached_typeinfo.lock().typeinfo_enum.clone() + if self.pgbouncer_mode { + self.cached_typeinfo.lock().typeinfo_enum.clone() + } else { + None + } } pub fn set_typeinfo_enum(&self, statement: &Statement) { - self.cached_typeinfo.lock().typeinfo_enum = Some(statement.clone()); + if !self.pgbouncer_mode { + self.cached_typeinfo.lock().typeinfo_enum = Some(statement.clone()); + } } pub fn type_(&self, oid: Oid) -> Option { @@ -173,12 +192,14 @@ impl Client { ssl_mode: SslMode, process_id: i32, secret_key: i32, + pgbouncer_mode: bool, ) -> Client { Client { inner: Arc::new(InnerClient { sender, cached_typeinfo: Default::default(), buffer: Default::default(), + pgbouncer_mode, }), #[cfg(feature = "runtime")] socket_config: None, diff --git a/tokio-postgres/src/config.rs b/tokio-postgres/src/config.rs index c026cca4f..19335dcc4 100644 --- a/tokio-postgres/src/config.rs +++ b/tokio-postgres/src/config.rs @@ -159,6 +159,7 @@ pub struct Config { pub(crate) keepalives_idle: Duration, pub(crate) target_session_attrs: TargetSessionAttrs, pub(crate) channel_binding: ChannelBinding, + pub(crate) pgbouncer_mode: bool, } impl Default for Config { @@ -184,6 +185,7 @@ impl Config { keepalives_idle: Duration::from_secs(2 * 60 * 60), target_session_attrs: TargetSessionAttrs::Any, channel_binding: ChannelBinding::Prefer, + pgbouncer_mode: false, } } @@ -387,6 +389,21 @@ impl Config { self.channel_binding } + /// When enabled, the client skips all internal caching for statements, + /// allowing usage with pgBouncer's transaction mode and clearing of + /// statements in the session with `DEALLOCATE ALL`. + /// + /// Defaults to `false`. + pub fn pgbouncer_mode(&mut self, enable: bool) -> &mut Config { + self.pgbouncer_mode = enable; + self + } + + /// Gets the pgBouncer mode status. + pub fn get_pgbouncer_mode(&self) -> bool { + self.pgbouncer_mode + } + fn param(&mut self, key: &str, value: &str) -> Result<(), Error> { match key { "user" => { diff --git a/tokio-postgres/src/connect_raw.rs b/tokio-postgres/src/connect_raw.rs index 3c6658481..d72c8e87b 100644 --- a/tokio-postgres/src/connect_raw.rs +++ b/tokio-postgres/src/connect_raw.rs @@ -100,7 +100,13 @@ where let (process_id, secret_key, parameters) = read_info(&mut stream).await?; let (sender, receiver) = mpsc::unbounded(); - let client = Client::new(sender, config.ssl_mode, process_id, secret_key); + let client = Client::new( + sender, + config.ssl_mode, + process_id, + secret_key, + config.pgbouncer_mode, + ); let connection = Connection::new(stream.inner, stream.delayed, parameters, receiver); Ok((client, connection)) From 130e3664ac4e4c715b8857572c73278282fe8bb6 Mon Sep 17 00:00:00 2001 From: Julius de Bruijn Date: Mon, 22 Mar 2021 18:06:50 +0100 Subject: [PATCH 59/59] Allow vendoring openssl --- postgres-native-tls/Cargo.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/postgres-native-tls/Cargo.toml b/postgres-native-tls/Cargo.toml index 8180cd012..1b201ac8d 100644 --- a/postgres-native-tls/Cargo.toml +++ b/postgres-native-tls/Cargo.toml @@ -14,12 +14,13 @@ circle-ci = { repository = "sfackler/rust-postgres" } [features] default = ["runtime"] runtime = ["tokio-postgres/runtime"] +vendored-openssl = ["tokio-native-tls/vendored-openssl", "native-tls/vendored"] [dependencies] futures = "0.3" native-tls = "0.2" tokio = "1.0" -tokio-native-tls = "0.3" +tokio-native-tls = { git = "https://github.com/pimeys/tls", branch = "vendored-openssl" } tokio-postgres = { version = "0.7.0", path = "../tokio-postgres", default-features = false } [dev-dependencies]