duckdb/core/
data_chunk.rs1use super::{
2 logical_type::LogicalTypeHandle,
3 vector::{ArrayVector, FlatVector, ListVector, StructVector},
4};
5use crate::ffi::{
6 duckdb_create_data_chunk, duckdb_data_chunk, duckdb_data_chunk_get_column_count, duckdb_data_chunk_get_size,
7 duckdb_data_chunk_get_vector, duckdb_data_chunk_set_size, duckdb_destroy_data_chunk,
8};
9
10pub struct DataChunkHandle {
12 ptr: duckdb_data_chunk,
14
15 owned: bool,
17}
18
19impl Drop for DataChunkHandle {
20 fn drop(&mut self) {
21 if self.owned && !self.ptr.is_null() {
22 unsafe { duckdb_destroy_data_chunk(&mut self.ptr) }
23 self.ptr = std::ptr::null_mut();
24 }
25 }
26}
27
28impl DataChunkHandle {
29 #[allow(dead_code)]
30 pub(crate) unsafe fn new_unowned(ptr: duckdb_data_chunk) -> Self {
31 Self { ptr, owned: false }
32 }
33
34 pub fn new(logical_types: &[LogicalTypeHandle]) -> Self {
36 let num_columns = logical_types.len();
37 let mut c_types = logical_types.iter().map(|t| t.ptr).collect::<Vec<_>>();
38 let ptr = unsafe { duckdb_create_data_chunk(c_types.as_mut_ptr(), num_columns as u64) };
39 DataChunkHandle { ptr, owned: true }
40 }
41
42 pub fn flat_vector(&self, idx: usize) -> FlatVector {
44 FlatVector::from(unsafe { duckdb_data_chunk_get_vector(self.ptr, idx as u64) })
45 }
46
47 pub fn list_vector(&self, idx: usize) -> ListVector {
49 ListVector::from(unsafe { duckdb_data_chunk_get_vector(self.ptr, idx as u64) })
50 }
51
52 pub fn array_vector(&self, idx: usize) -> ArrayVector {
54 ArrayVector::from(unsafe { duckdb_data_chunk_get_vector(self.ptr, idx as u64) })
55 }
56
57 pub fn struct_vector(&self, idx: usize) -> StructVector {
59 StructVector::from(unsafe { duckdb_data_chunk_get_vector(self.ptr, idx as u64) })
60 }
61
62 pub fn set_len(&self, new_len: usize) {
64 unsafe { duckdb_data_chunk_set_size(self.ptr, new_len as u64) };
65 }
66
67 pub fn len(&self) -> usize {
69 unsafe { duckdb_data_chunk_get_size(self.ptr) as usize }
70 }
71
72 pub fn is_empty(&self) -> bool {
74 self.len() == 0
75 }
76
77 pub fn num_columns(&self) -> usize {
79 unsafe { duckdb_data_chunk_get_column_count(self.ptr) as usize }
80 }
81
82 pub fn get_ptr(&self) -> duckdb_data_chunk {
84 self.ptr
85 }
86}
87
88#[cfg(test)]
89mod test {
90 use super::{super::logical_type::LogicalTypeId, *};
91
92 #[test]
93 fn test_data_chunk_construction() {
94 let dc = DataChunkHandle::new(&[LogicalTypeHandle::from(LogicalTypeId::Integer)]);
95
96 assert_eq!(dc.num_columns(), 1);
97
98 drop(dc);
99 }
100
101 #[test]
102 fn test_vector() {
103 let datachunk = DataChunkHandle::new(&[LogicalTypeHandle::from(LogicalTypeId::Bigint)]);
104 let mut vector = datachunk.flat_vector(0);
105 let data = vector.as_mut_slice::<i64>();
106
107 data[0] = 42;
108 }
109
110 #[test]
111 fn test_logi() {
112 let key = LogicalTypeHandle::from(LogicalTypeId::Varchar);
113
114 let value = LogicalTypeHandle::from(LogicalTypeId::UTinyint);
115
116 let map = LogicalTypeHandle::map(&key, &value);
117
118 assert_eq!(map.id(), LogicalTypeId::Map);
119
120 }
132}