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 #[cfg(feature = "vtab")]
43 pub(crate) unsafe fn new_unowned(ptr: duckdb_data_chunk) -> Self {
44 Self { ptr, owned: false }
45 }
46
47 pub fn new(logical_types: &[LogicalTypeHandle]) -> Self {
49 let num_columns = logical_types.len();
50 let mut c_types = Vec::with_capacity(num_columns);
51 c_types.extend(logical_types.iter().map(|t| t.ptr));
52 let ptr = unsafe { duckdb_create_data_chunk(c_types.as_mut_ptr(), num_columns as u64) };
53 Self { ptr, owned: true }
54 }
55
56 pub fn flat_vector(&self, idx: usize) -> FlatVector<'_> {
58 unsafe { FlatVector::from_raw(duckdb_data_chunk_get_vector(self.ptr, idx as u64)) }
59 }
60
61 pub fn list_vector(&self, idx: usize) -> ListVector<'_> {
63 unsafe { ListVector::from_raw(duckdb_data_chunk_get_vector(self.ptr, idx as u64)) }
64 }
65
66 pub fn array_vector(&self, idx: usize) -> ArrayVector<'_> {
68 unsafe { ArrayVector::from_raw(duckdb_data_chunk_get_vector(self.ptr, idx as u64)) }
69 }
70
71 pub fn struct_vector(&self, idx: usize) -> StructVector<'_> {
73 unsafe { StructVector::from_raw(duckdb_data_chunk_get_vector(self.ptr, idx as u64)) }
74 }
75
76 pub fn set_len(&self, new_len: usize) {
78 unsafe { duckdb_data_chunk_set_size(self.ptr, new_len as u64) };
79 }
80
81 pub fn len(&self) -> usize {
83 unsafe { duckdb_data_chunk_get_size(self.ptr) as usize }
84 }
85
86 pub fn is_empty(&self) -> bool {
88 self.len() == 0
89 }
90
91 pub fn num_columns(&self) -> usize {
93 unsafe { duckdb_data_chunk_get_column_count(self.ptr) as usize }
94 }
95
96 pub fn get_ptr(&self) -> duckdb_data_chunk {
98 self.ptr
99 }
100}
101
102#[cfg(test)]
103mod test {
104 use super::{super::logical_type::LogicalTypeId, *};
105
106 #[test]
107 fn test_data_chunk_construction() {
108 let dc = DataChunkHandle::new(&[LogicalTypeHandle::from(LogicalTypeId::Integer)]);
109
110 assert_eq!(dc.num_columns(), 1);
111
112 drop(dc);
113 }
114
115 #[test]
116 fn test_vector() {
117 let datachunk = DataChunkHandle::new(&[LogicalTypeHandle::from(LogicalTypeId::Bigint)]);
118 let mut vector = datachunk.flat_vector(0);
119 let data = unsafe { vector.as_mut_slice::<i64>() };
120
121 data[0] = 42;
122 }
123
124 #[test]
125 fn test_logi() {
126 let key = LogicalTypeHandle::from(LogicalTypeId::Varchar);
127
128 let value = LogicalTypeHandle::from(LogicalTypeId::UTinyint);
129
130 let map = LogicalTypeHandle::map(&key, &value);
131
132 assert_eq!(map.id(), LogicalTypeId::Map);
133
134 }
146}