duckdb/core/vector/
struct.rs1use std::marker::PhantomData;
2
3use libduckdb_sys::DuckDbString;
4
5use crate::{
6 Result,
7 core::LogicalTypeHandle,
8 ffi::{
9 duckdb_struct_type_child_count, duckdb_struct_type_child_name, duckdb_struct_vector_get_child,
10 duckdb_validity_set_row_invalid, duckdb_vector, duckdb_vector_ensure_validity_writable,
11 duckdb_vector_get_column_type, duckdb_vector_get_validity, duckdb_vector_size,
12 },
13};
14
15use super::{ArrayVector, FlatVector, ListVector, try_vector_row_is_null, vector_row_is_null};
16
17pub struct StructVector<'a> {
21 ptr: duckdb_vector,
22 capacity: usize,
23 _phantom: PhantomData<&'a ()>,
24}
25
26impl<'a> StructVector<'a> {
27 pub(crate) unsafe fn from_raw(ptr: duckdb_vector) -> Self {
32 unsafe { Self::from_raw_with_capacity(ptr, duckdb_vector_size() as usize) }
33 }
34
35 pub(crate) unsafe fn from_raw_with_capacity(ptr: duckdb_vector, capacity: usize) -> Self {
41 Self {
42 ptr,
43 capacity,
44 _phantom: PhantomData,
45 }
46 }
47
48 pub fn child(&self, idx: usize, capacity: usize) -> FlatVector<'a> {
53 assert!(
54 capacity <= self.capacity,
55 "struct child capacity {capacity} exceeds parent capacity {}",
56 self.capacity
57 );
58 unsafe { FlatVector::with_capacity(self.child_ptr(idx), capacity) }
61 }
62
63 pub fn struct_vector_child(&self, idx: usize) -> StructVector<'a> {
68 unsafe { StructVector::from_raw_with_capacity(self.child_ptr(idx), self.capacity) }
69 }
70
71 pub fn list_vector_child(&self, idx: usize) -> ListVector<'a> {
73 unsafe { ListVector::from_raw_with_capacity(self.child_ptr(idx), self.capacity) }
74 }
75
76 pub fn array_vector_child(&self, idx: usize) -> ArrayVector<'a> {
78 unsafe { ArrayVector::from_raw_with_capacity(self.child_ptr(idx), self.capacity) }
79 }
80
81 pub(crate) fn child_ptr(&self, idx: usize) -> duckdb_vector {
82 unsafe { duckdb_struct_vector_get_child(self.ptr, idx as u64) }
83 }
84
85 pub fn logical_type(&self) -> LogicalTypeHandle {
87 unsafe { LogicalTypeHandle::new(duckdb_vector_get_column_type(self.ptr)) }
88 }
89
90 pub fn row_is_null(&self, row: u64) -> bool {
95 vector_row_is_null(self.ptr, row, self.capacity)
96 }
97
98 pub fn try_row_is_null(&self, row: u64) -> Result<bool> {
100 try_vector_row_is_null(self.ptr, row, self.capacity)
101 }
102
103 pub fn child_name(&self, idx: usize) -> DuckDbString {
107 let logical_type = self.logical_type();
108 unsafe {
109 let child_name_ptr = duckdb_struct_type_child_name(logical_type.ptr, idx as u64);
110 if child_name_ptr.is_null() {
111 panic!("child index {idx} out of range");
112 }
113 DuckDbString::from_ptr(child_name_ptr)
114 }
115 }
116
117 pub fn num_children(&self) -> usize {
119 let logical_type = self.logical_type();
120 unsafe { duckdb_struct_type_child_count(logical_type.ptr) as usize }
121 }
122
123 pub fn set_null(&mut self, row: usize) {
125 unsafe {
126 duckdb_vector_ensure_validity_writable(self.ptr);
127 let idx = duckdb_vector_get_validity(self.ptr);
128 duckdb_validity_set_row_invalid(idx, row as u64);
129 }
130 }
131}