@@ -6,6 +6,7 @@ use std::os::raw as libc;
66use super :: stmt:: Statement ;
77use mysql:: MysqlType ;
88use result:: QueryResult ;
9+ use sql_types:: IsSigned ;
910
1011pub struct Binds {
1112 data : Vec < BindData > ,
@@ -14,20 +15,20 @@ pub struct Binds {
1415impl Binds {
1516 pub fn from_input_data < Iter > ( input : Iter ) -> Self
1617 where
17- Iter : IntoIterator < Item = ( MysqlType , Option < Vec < u8 > > ) > ,
18+ Iter : IntoIterator < Item = ( MysqlType , IsSigned , Option < Vec < u8 > > ) > ,
1819 {
1920 let data = input
2021 . into_iter ( )
21- . map ( |( tpe, bytes) | BindData :: for_input ( tpe, bytes) )
22+ . map ( |( tpe, sign , bytes) | BindData :: for_input ( tpe, is_signed_to_my_bool ( sign ) , bytes) )
2223 . collect ( ) ;
2324
2425 Binds { data : data }
2526 }
2627
27- pub fn from_output_types ( types : Vec < MysqlType > ) -> Self {
28+ pub fn from_output_types ( types : Vec < ( MysqlType , IsSigned ) > ) -> Self {
2829 let data = types
2930 . into_iter ( )
30- . map ( mysql_type_to_ffi_type)
31+ . map ( | ( ty , sign ) | ( mysql_type_to_ffi_type ( ty ) , is_signed_to_my_bool ( sign ) ) )
3132 . map ( BindData :: for_output)
3233 . collect ( ) ;
3334
@@ -37,7 +38,7 @@ impl Binds {
3738 pub fn from_result_metadata ( fields : & [ ffi:: MYSQL_FIELD ] ) -> Self {
3839 let data = fields
3940 . iter ( )
40- . map ( |field| field. type_ )
41+ . map ( |field| ( field. type_ , is_field_unsigned ( field ) ) )
4142 . map ( BindData :: for_output)
4243 . collect ( ) ;
4344
@@ -89,10 +90,11 @@ struct BindData {
8990 length : libc:: c_ulong ,
9091 is_null : ffi:: my_bool ,
9192 is_truncated : Option < ffi:: my_bool > ,
93+ is_unsigned : ffi:: my_bool ,
9294}
9395
9496impl BindData {
95- fn for_input ( tpe : MysqlType , data : Option < Vec < u8 > > ) -> Self {
97+ fn for_input ( tpe : MysqlType , is_unsigned : ffi :: my_bool , data : Option < Vec < u8 > > ) -> Self {
9698 let is_null = if data. is_none ( ) { 1 } else { 0 } ;
9799 let bytes = data. unwrap_or_default ( ) ;
98100 let length = bytes. len ( ) as libc:: c_ulong ;
@@ -103,10 +105,11 @@ impl BindData {
103105 length : length,
104106 is_null : is_null,
105107 is_truncated : None ,
108+ is_unsigned,
106109 }
107110 }
108111
109- fn for_output ( tpe : ffi:: enum_field_types ) -> Self {
112+ fn for_output ( ( tpe, is_unsigned ) : ( ffi:: enum_field_types , ffi :: my_bool ) ) -> Self {
110113 let bytes = known_buffer_size_for_ffi_type ( tpe)
111114 . map ( |len| vec ! [ 0 ; len] )
112115 . unwrap_or_default ( ) ;
@@ -118,6 +121,7 @@ impl BindData {
118121 length : length,
119122 is_null : 0 ,
120123 is_truncated : Some ( 0 ) ,
124+ is_unsigned,
121125 }
122126 }
123127
@@ -151,6 +155,7 @@ impl BindData {
151155 bind. buffer_length = self . bytes . capacity ( ) as libc:: c_ulong ;
152156 bind. length = & mut self . length ;
153157 bind. is_null = & mut self . is_null ;
158+ bind. is_unsigned = self . is_unsigned ;
154159
155160 if let Some ( ref mut is_truncated) = self . is_truncated {
156161 bind. error = is_truncated;
@@ -236,3 +241,15 @@ fn known_buffer_size_for_ffi_type(tpe: ffi::enum_field_types) -> Option<usize> {
236241 _ => None ,
237242 }
238243}
244+
245+ fn is_field_unsigned ( field : & ffi:: MYSQL_FIELD ) -> ffi:: my_bool {
246+ const UNSIGNED_FLAG : libc:: c_uint = 32 ;
247+ ( field. flags & UNSIGNED_FLAG > 0 ) as _
248+ }
249+
250+ fn is_signed_to_my_bool ( sign : IsSigned ) -> ffi:: my_bool {
251+ match sign {
252+ IsSigned :: Signed => false as _ ,
253+ IsSigned :: Unsigned => true as _ ,
254+ }
255+ }
0 commit comments