11use crate :: column:: ColumnIndex ;
22use crate :: database:: HasValueRef ;
33use crate :: error:: Error ;
4- use crate :: odbc:: { Odbc , OdbcColumn , OdbcValue } ;
4+ use crate :: odbc:: { Odbc , OdbcColumn , OdbcValueRef } ;
55use crate :: row:: Row ;
6- use crate :: value :: Value ;
6+ use std :: sync :: Arc ;
77
88#[ derive( Debug , Clone ) ]
9- pub struct OdbcRow {
9+ pub struct OdbcBatch {
1010 pub ( crate ) columns : Vec < OdbcColumn > ,
11- pub ( crate ) values : Vec < OdbcValue > ,
11+ pub ( crate ) column_data : Vec < Arc < crate :: odbc:: ColumnData > > ,
12+ }
13+
14+ #[ derive( Debug , Clone ) ]
15+ pub struct OdbcRow {
16+ pub ( crate ) row_index : usize ,
17+ pub ( crate ) batch : Arc < OdbcBatch > ,
1218}
1319
1420impl Row for OdbcRow {
1521 type Database = Odbc ;
1622
1723 fn columns ( & self ) -> & [ OdbcColumn ] {
18- & self . columns
24+ & self . batch . columns
1925 }
2026
2127 fn try_get_raw < I > (
@@ -25,21 +31,21 @@ impl Row for OdbcRow {
2531 where
2632 I : ColumnIndex < Self > ,
2733 {
28- let idx = index. index ( self ) ?;
29- let value = & self . values [ idx] ;
30- Ok ( value. as_ref ( ) )
34+ let column_index = index. index ( self ) ?;
35+ Ok ( OdbcValueRef :: new ( & self . batch , self . row_index , column_index) )
3136 }
3237}
3338
3439impl ColumnIndex < OdbcRow > for & str {
3540 fn index ( & self , row : & OdbcRow ) -> Result < usize , Error > {
3641 // Try exact match first (for performance)
37- if let Some ( pos) = row. columns . iter ( ) . position ( |col| col. name == * self ) {
42+ if let Some ( pos) = row. batch . columns . iter ( ) . position ( |col| col. name == * self ) {
3843 return Ok ( pos) ;
3944 }
4045
4146 // Fall back to case-insensitive match (for databases like Snowflake)
42- row. columns
47+ row. batch
48+ . columns
4349 . iter ( )
4450 . position ( |col| col. name . eq_ignore_ascii_case ( self ) )
4551 . ok_or_else ( || Error :: ColumnNotFound ( ( * self ) . into ( ) ) )
@@ -56,6 +62,7 @@ mod private {
5662impl From < OdbcRow > for crate :: any:: AnyRow {
5763 fn from ( row : OdbcRow ) -> Self {
5864 let columns = row
65+ . batch
5966 . columns
6067 . iter ( )
6168 . map ( |col| crate :: any:: AnyColumn {
@@ -81,58 +88,48 @@ mod tests {
8188 use std:: sync:: Arc ;
8289
8390 fn create_test_row ( ) -> OdbcRow {
84- use crate :: odbc:: OdbcValue ;
91+ let columns = vec ! [
92+ OdbcColumn {
93+ name: "lowercase_col" . to_string( ) ,
94+ type_info: OdbcTypeInfo :: new( DataType :: Integer ) ,
95+ ordinal: 0 ,
96+ } ,
97+ OdbcColumn {
98+ name: "UPPERCASE_COL" . to_string( ) ,
99+ type_info: OdbcTypeInfo :: new( DataType :: Varchar { length: None } ) ,
100+ ordinal: 1 ,
101+ } ,
102+ OdbcColumn {
103+ name: "MixedCase_Col" . to_string( ) ,
104+ type_info: OdbcTypeInfo :: new( DataType :: Double ) ,
105+ ordinal: 2 ,
106+ } ,
107+ ] ;
108+
109+ let column_data = vec ! [
110+ ColumnData {
111+ values: OdbcValueVec :: NullableBigInt ( vec![ Some ( 42 ) ] ) ,
112+ type_info: OdbcTypeInfo :: new( DataType :: Integer ) ,
113+ nulls: vec![ false ] ,
114+ } ,
115+ ColumnData {
116+ values: OdbcValueVec :: Text ( vec![ Some ( "test" . to_string( ) ) ] ) ,
117+ type_info: OdbcTypeInfo :: new( DataType :: Varchar { length: None } ) ,
118+ nulls: vec![ false ] ,
119+ } ,
120+ ColumnData {
121+ values: OdbcValueVec :: NullableDouble ( vec![ Some ( std:: f64 :: consts:: PI ) ] ) ,
122+ type_info: OdbcTypeInfo :: new( DataType :: Double ) ,
123+ nulls: vec![ false ] ,
124+ } ,
125+ ] ;
85126
86127 OdbcRow {
87- columns : vec ! [
88- OdbcColumn {
89- name: "lowercase_col" . to_string( ) ,
90- type_info: OdbcTypeInfo :: new( DataType :: Integer ) ,
91- ordinal: 0 ,
92- } ,
93- OdbcColumn {
94- name: "UPPERCASE_COL" . to_string( ) ,
95- type_info: OdbcTypeInfo :: new( DataType :: Varchar { length: None } ) ,
96- ordinal: 1 ,
97- } ,
98- OdbcColumn {
99- name: "MixedCase_Col" . to_string( ) ,
100- type_info: OdbcTypeInfo :: new( DataType :: Double ) ,
101- ordinal: 2 ,
102- } ,
103- ] ,
104- values : vec ! [
105- {
106- let column = ColumnData {
107- values: OdbcValueVec :: NullableBigInt ( vec![ Some ( 42 ) ] ) ,
108- type_info: OdbcTypeInfo :: new( DataType :: Integer ) ,
109- } ;
110- OdbcValue {
111- column_data: Arc :: new( column) ,
112- row_index: 0 ,
113- }
114- } ,
115- {
116- let column = ColumnData {
117- values: OdbcValueVec :: Text ( vec![ Some ( "test" . to_string( ) ) ] ) ,
118- type_info: OdbcTypeInfo :: new( DataType :: Varchar { length: None } ) ,
119- } ;
120- OdbcValue {
121- column_data: Arc :: new( column) ,
122- row_index: 0 ,
123- }
124- } ,
125- {
126- let column = ColumnData {
127- values: OdbcValueVec :: NullableDouble ( vec![ Some ( std:: f64 :: consts:: PI ) ] ) ,
128- type_info: OdbcTypeInfo :: new( DataType :: Double ) ,
129- } ;
130- OdbcValue {
131- column_data: Arc :: new( column) ,
132- row_index: 0 ,
133- }
134- } ,
135- ] ,
128+ row_index : 0 ,
129+ batch : Arc :: new ( OdbcBatch {
130+ columns,
131+ column_data,
132+ } ) ,
136133 }
137134 }
138135
0 commit comments