@@ -16,19 +16,16 @@ use std::sync::Arc;
1616// Bulk fetch implementation using columnar buffers instead of row-by-row fetching
1717// This provides significant performance improvements by fetching rows in batches
1818// and avoiding the slow `next_row()` method from odbc-api
19-
19+ # [ derive ( Debug ) ]
2020struct ColumnBinding {
2121 column : OdbcColumn ,
2222 buffer_desc : BufferDesc ,
2323}
2424
25- fn build_bindings < C > (
25+ fn build_bindings < C : Cursor > (
2626 cursor : & mut C ,
27- buffer_settings : & OdbcBufferSettings ,
28- ) -> Result < Vec < ColumnBinding > , Error >
29- where
30- C : ResultSetMetadata ,
31- {
27+ max_column_size : usize ,
28+ ) -> Result < Vec < ColumnBinding > , Error > {
3229 let column_count = cursor. num_result_cols ( ) . unwrap_or ( 0 ) ;
3330 let mut bindings = Vec :: with_capacity ( column_count as usize ) ;
3431 for index in 1 ..=column_count {
@@ -37,18 +34,18 @@ where
3734 . col_nullability ( index as u16 )
3835 . unwrap_or ( Nullability :: Unknown )
3936 . could_be_nullable ( ) ;
40- let buffer_desc = map_buffer_desc (
41- cursor,
42- index as u16 ,
43- & column. type_info ,
44- nullable,
45- buffer_settings,
46- ) ?;
37+ let buffer_desc = map_buffer_desc ( & column. type_info , nullable, max_column_size) ?;
4738 bindings. push ( ColumnBinding {
4839 column,
4940 buffer_desc,
5041 } ) ;
5142 }
43+ dbg ! ( & bindings) ;
44+ log:: trace!(
45+ "built {} ODBC batch column bindings: {:?}" ,
46+ bindings. len( ) ,
47+ bindings
48+ ) ;
5249 Ok ( bindings)
5350}
5451
@@ -131,14 +128,15 @@ fn to_param(arg: OdbcArgumentValue) -> Box<dyn odbc_api::parameter::InputParamet
131128 }
132129}
133130
134- fn handle_cursor < C > ( mut cursor : C , tx : & ExecuteSender , buffer_settings : OdbcBufferSettings )
135- where
136- C : Cursor + ResultSetMetadata ,
137- {
131+ fn handle_cursor < C : Cursor + ResultSetMetadata > (
132+ mut cursor : C ,
133+ tx : & ExecuteSender ,
134+ buffer_settings : OdbcBufferSettings ,
135+ ) {
138136 match buffer_settings. max_column_size {
139- Some ( _ ) => {
137+ Some ( max_column_size ) => {
140138 // Buffered mode - use batch fetching with columnar buffers
141- let bindings = match build_bindings ( & mut cursor, & buffer_settings ) {
139+ let bindings = match build_bindings ( & mut cursor, max_column_size ) {
142140 Ok ( b) => b,
143141 Err ( e) => {
144142 send_error ( tx, e) ;
@@ -197,34 +195,17 @@ where
197195 }
198196}
199197
200- fn map_buffer_desc < C > (
201- _cursor : & mut C ,
202- _column_index : u16 ,
198+ fn map_buffer_desc (
203199 type_info : & OdbcTypeInfo ,
204200 nullable : bool ,
205- buffer_settings : & OdbcBufferSettings ,
206- ) -> Result < BufferDesc , Error >
207- where
208- C : ResultSetMetadata ,
209- {
201+ max_column_size : usize ,
202+ ) -> Result < BufferDesc , Error > {
210203 use odbc_api:: DataType ;
211204
205+ // Some drivers report datatype lengths that are smaller than the actual data,
206+ // so we cannot use it to build the BufferDesc.
212207 let data_type = type_info. data_type ( ) ;
213-
214- // Helper function to determine buffer length with fallback
215- let max_column_size = buffer_settings. max_column_size . unwrap_or ( 4096 ) ;
216-
217- let buffer_length = |length : Option < std:: num:: NonZeroUsize > | {
218- if let Some ( length) = length {
219- if length. get ( ) < 255 {
220- length. get ( )
221- } else {
222- max_column_size
223- }
224- } else {
225- max_column_size
226- }
227- } ;
208+ let max_str_len = max_column_size;
228209
229210 let buffer_desc = match data_type {
230211 // Integer types - all map to I64
@@ -241,31 +222,22 @@ where
241222 DataType :: Time { .. } => BufferDesc :: Time { nullable } ,
242223 DataType :: Timestamp { .. } => BufferDesc :: Timestamp { nullable } ,
243224 // Binary types
244- DataType :: Binary { length }
245- | DataType :: Varbinary { length }
246- | DataType :: LongVarbinary { length } => BufferDesc :: Binary {
247- length : buffer_length ( length ) ,
248- } ,
225+ DataType :: Binary { .. } | DataType :: Varbinary { .. } | DataType :: LongVarbinary { .. } => {
226+ BufferDesc :: Binary {
227+ length : max_column_size ,
228+ }
229+ }
249230 // Text types
250- DataType :: Char { length }
251- | DataType :: WChar { length }
252- | DataType :: Varchar { length }
253- | DataType :: WVarchar { length }
254- | DataType :: LongVarchar { length }
255- | DataType :: WLongVarchar { length }
256- | DataType :: Other {
257- column_size : length,
258- ..
259- } => BufferDesc :: Text {
260- max_str_len : buffer_length ( length) ,
261- } ,
231+ DataType :: Char { .. }
232+ | DataType :: WChar { .. }
233+ | DataType :: Varchar { .. }
234+ | DataType :: WVarchar { .. }
235+ | DataType :: LongVarchar { .. }
236+ | DataType :: WLongVarchar { .. }
237+ | DataType :: Other { .. } => BufferDesc :: Text { max_str_len } ,
262238 // Fallback cases
263- DataType :: Unknown => BufferDesc :: Text {
264- max_str_len : max_column_size,
265- } ,
266- DataType :: Decimal { .. } | DataType :: Numeric { .. } => BufferDesc :: Text {
267- max_str_len : max_column_size,
268- } ,
239+ DataType :: Unknown => BufferDesc :: Text { max_str_len } ,
240+ DataType :: Decimal { .. } | DataType :: Numeric { .. } => BufferDesc :: Text { max_str_len } ,
269241 } ;
270242
271243 Ok ( buffer_desc)
0 commit comments