@@ -6,10 +6,10 @@ use crate::{
6
6
Error ,
7
7
} ;
8
8
use arrow:: record_batch:: RecordBatch ;
9
- use ffi:: duckdb_append_data_chunk;
9
+ use ffi:: { duckdb_append_data_chunk, duckdb_vector_size } ;
10
10
11
11
impl Appender < ' _ > {
12
- /// Append one record_batch
12
+ /// Append one record batch
13
13
///
14
14
/// ## Example
15
15
///
@@ -28,19 +28,35 @@ impl Appender<'_> {
28
28
/// Will return `Err` if append column count not the same with the table schema
29
29
#[ inline]
30
30
pub fn append_record_batch ( & mut self , record_batch : RecordBatch ) -> Result < ( ) > {
31
- let schema = record_batch. schema ( ) ;
32
- let mut logical_type: Vec < LogicalTypeHandle > = vec ! [ ] ;
33
- for field in schema. fields ( ) {
34
- let logical_t = to_duckdb_logical_type ( field. data_type ( ) )
35
- . map_err ( |_op| Error :: ArrowTypeToDuckdbType ( field. to_string ( ) , field. data_type ( ) . clone ( ) ) ) ?;
36
- logical_type. push ( logical_t) ;
37
- }
31
+ let logical_types: Vec < LogicalTypeHandle > = record_batch
32
+ . schema ( )
33
+ . fields ( )
34
+ . iter ( )
35
+ . map ( |field| {
36
+ to_duckdb_logical_type ( field. data_type ( ) )
37
+ . map_err ( |_op| Error :: ArrowTypeToDuckdbType ( field. to_string ( ) , field. data_type ( ) . clone ( ) ) )
38
+ } )
39
+ . collect :: < Result < Vec < _ > , _ > > ( ) ?;
40
+
41
+ let vector_size = unsafe { duckdb_vector_size ( ) } as usize ;
42
+ let num_rows = record_batch. num_rows ( ) ;
43
+
44
+ // Process record batch in chunks that fit within DuckDB's vector size
45
+ let mut offset = 0 ;
46
+ while offset < num_rows {
47
+ let slice_len = std:: cmp:: min ( vector_size, num_rows - offset) ;
48
+ let slice = record_batch. slice ( offset, slice_len) ;
49
+
50
+ let mut data_chunk = DataChunkHandle :: new ( & logical_types) ;
51
+ record_batch_to_duckdb_data_chunk ( & slice, & mut data_chunk) . map_err ( |_op| Error :: AppendError ) ?;
38
52
39
- let mut data_chunk = DataChunkHandle :: new ( & logical_type ) ;
40
- record_batch_to_duckdb_data_chunk ( & record_batch , & mut data_chunk ) . map_err ( |_op| Error :: AppendError ) ?;
53
+ let rc = unsafe { duckdb_append_data_chunk ( self . app , data_chunk . get_ptr ( ) ) } ;
54
+ result_from_duckdb_appender ( rc , & mut self . app ) ?;
41
55
42
- let rc = unsafe { duckdb_append_data_chunk ( self . app , data_chunk. get_ptr ( ) ) } ;
43
- result_from_duckdb_appender ( rc, & mut self . app )
56
+ offset += slice_len;
57
+ }
58
+
59
+ Ok ( ( ) )
44
60
}
45
61
}
46
62
0 commit comments