@@ -7,6 +7,7 @@ use arrow::datatypes::{DataType, Field, Schema};
7
7
use async_trait:: async_trait;
8
8
use futures_util:: StreamExt ;
9
9
use rusqlite:: types:: Value ;
10
+ use rusqlite:: Column ;
10
11
11
12
use crate :: api:: RawArrowData ;
12
13
use crate :: api:: { serialize_preview, ArrowData } ;
@@ -58,7 +59,7 @@ impl Connection for SqliteDialect {
58
59
}
59
60
60
61
async fn show_column ( & self , schema : Option < & str > , table : & str ) -> anyhow:: Result < RawArrowData > {
61
- let sql = format ! ( "PRAGMA table_info( {table})" ) ;
62
+ let sql = format ! ( "select * from pragma_table_info(' {table}' )" ) ;
62
63
self . query ( & sql, 0 , 0 ) . await
63
64
}
64
65
}
@@ -76,6 +77,7 @@ impl SqliteDialect {
76
77
Ok ( rusqlite:: Connection :: open ( & self . path ) ?)
77
78
}
78
79
80
+ #[ allow( clippy:: unused_async) ]
79
81
async fn _query ( & self , sql : & str , _limit : usize , _offset : usize ) -> anyhow:: Result < RawArrowData > {
80
82
let conn = self . connect ( ) ?;
81
83
let mut stmt = conn. prepare ( sql) ?;
@@ -88,23 +90,7 @@ impl SqliteDialect {
88
90
name : col. name ( ) . to_string ( ) ,
89
91
r#type : col. decl_type ( ) . unwrap_or_default ( ) . to_string ( ) ,
90
92
} ) ;
91
- let typ = if let Some ( decl_type) = col. decl_type ( ) {
92
- match decl_type {
93
- "INTEGER" => DataType :: Int64 ,
94
- "REAL" => DataType :: Float64 ,
95
- "BOOLEAN" => DataType :: Boolean ,
96
- "DATE" => DataType :: Utf8 ,
97
- "DATETIME" => DataType :: Utf8 ,
98
- "TIME" => DataType :: Utf8 ,
99
- decl_type if decl_type. starts_with ( "NUMERIC" ) => DataType :: Utf8 ,
100
- decl_type if decl_type. starts_with ( "NVARCHAR" ) => DataType :: Utf8 ,
101
- "BLOB" => DataType :: Binary ,
102
- "NULL" => DataType :: Null ,
103
- _ => DataType :: Utf8 ,
104
- }
105
- } else {
106
- DataType :: Null
107
- } ;
93
+ let typ = Self :: arrow_type ( & col) ;
108
94
let field = Field :: new ( col. name ( ) , typ, true ) ;
109
95
fields. push ( field) ;
110
96
println ! ( "{:?} {:?}" , col. name( ) , col. decl_type( ) )
@@ -136,6 +122,28 @@ impl SqliteDialect {
136
122
titles : Some ( titles) ,
137
123
} )
138
124
}
125
+
126
+ fn arrow_type ( col : & Column ) -> DataType {
127
+ if let Some ( decl_type) = col. decl_type ( ) {
128
+ match decl_type {
129
+ "INTEGER" => DataType :: Int64 ,
130
+ "REAL" => DataType :: Float64 ,
131
+ "BOOLEAN" => DataType :: Boolean ,
132
+ "DATE" => DataType :: Utf8 ,
133
+ "DATETIME" => DataType :: Utf8 ,
134
+ "TIME" => DataType :: Utf8 ,
135
+ decl_type if decl_type. starts_with ( "NUMERIC" ) => DataType :: Utf8 ,
136
+ decl_type if decl_type. starts_with ( "NVARCHAR" ) => DataType :: Utf8 ,
137
+ "BLOB" => DataType :: Binary ,
138
+ "NULL" => DataType :: Null ,
139
+ _ => DataType :: Utf8 ,
140
+ }
141
+ } else {
142
+ DataType :: Utf8
143
+ }
144
+ }
145
+
146
+ #[ allow( clippy:: unused_async) ]
139
147
pub ( crate ) async fn _table_row_count ( & self , table : & str , cond : & str ) -> anyhow:: Result < usize > {
140
148
let conn = self . connect ( ) ?;
141
149
let sql = self . _table_count_sql ( table, cond) ;
@@ -205,6 +213,8 @@ impl SqliteDialect {
205
213
titles : None ,
206
214
} )
207
215
}
216
+
217
+ #[ allow( clippy:: unused_async) ]
208
218
async fn get_tables ( & self ) -> anyhow:: Result < Vec < Table > > {
209
219
let conn = self . connect ( ) ?;
210
220
let sql = r#"
@@ -232,14 +242,14 @@ impl SqliteDialect {
232
242
pub fn convert_arrow ( value : & Value , typ : & str ) -> ArrayRef {
233
243
match value {
234
244
Value :: Integer ( i) => {
235
- if typ. starts_with ( "NUMERIC" ) {
245
+ if typ. starts_with ( "NUMERIC" ) || typ . is_empty ( ) {
236
246
Arc :: new ( StringArray :: from ( vec ! [ i. to_string( ) ] ) ) as ArrayRef
237
247
} else {
238
248
Arc :: new ( Int64Array :: from ( vec ! [ ( * i) ] ) ) as ArrayRef
239
249
}
240
250
}
241
251
Value :: Real ( f) => {
242
- if typ. starts_with ( "NUMERIC" ) {
252
+ if typ. starts_with ( "NUMERIC" ) || typ . is_empty ( ) {
243
253
Arc :: new ( StringArray :: from ( vec ! [ f. to_string( ) ] ) ) as ArrayRef
244
254
} else {
245
255
Arc :: new ( Float64Array :: from ( vec ! [ ( * f) ] ) ) as ArrayRef
@@ -292,17 +302,20 @@ pub fn convert_to_strings(values: &[Value]) -> Vec<Option<String>> {
292
302
293
303
#[ allow( dead_code) ]
294
304
pub fn convert_to_i64s ( values : & [ Value ] ) -> Vec < Option < i64 > > {
295
- values. iter ( ) . map ( |v| convert_to_i64 ( v ) ) . collect ( )
305
+ values. iter ( ) . map ( convert_to_i64) . collect ( )
296
306
}
297
307
298
308
#[ allow( dead_code) ]
299
309
pub fn convert_to_f64s ( values : & [ Value ] ) -> Vec < Option < f64 > > {
300
- values. iter ( ) . map ( |v| convert_to_f64 ( v ) ) . collect ( )
310
+ values. iter ( ) . map ( convert_to_f64) . collect ( )
301
311
}
302
312
303
313
#[ tokio:: test]
304
314
async fn test_tables ( ) {
305
- let _ = SqliteDialect {
315
+ use arrow:: util:: pretty:: print_batches;
316
+ let d = SqliteDialect {
306
317
path : String :: from ( r"" ) ,
307
318
} ;
319
+ let res = d. query ( "" , 0 , 0 ) . await . unwrap ( ) ;
320
+ let _ = print_batches ( & [ res. batch ] ) ;
308
321
}
0 commit comments