use libduckdb_sys::{
duckdb_validity_row_is_valid, duckdb_validity_set_row_invalid, duckdb_validity_set_row_valid,
duckdb_vector, duckdb_vector_ensure_validity_writable, duckdb_vector_get_validity, idx_t,
};
pub struct ValidityBitmap<'v> {
validity: *mut u64,
_phantom: std::marker::PhantomData<&'v mut duckdb_vector>,
}
impl ValidityBitmap<'_> {
pub unsafe fn ensure_writable(vector: duckdb_vector) -> Self {
unsafe { duckdb_vector_ensure_validity_writable(vector) };
let validity = unsafe { duckdb_vector_get_validity(vector) };
Self {
validity,
_phantom: std::marker::PhantomData,
}
}
pub unsafe fn get_read_only(vector: duckdb_vector) -> Self {
let validity = unsafe { duckdb_vector_get_validity(vector) };
Self {
validity,
_phantom: std::marker::PhantomData,
}
}
#[inline]
pub unsafe fn row_is_valid(&self, idx: idx_t) -> bool {
if self.validity.is_null() {
return true;
}
unsafe { duckdb_validity_row_is_valid(self.validity, idx) }
}
#[inline]
pub unsafe fn set_row_invalid(&mut self, idx: idx_t) {
debug_assert!(
!self.validity.is_null(),
"set_row_invalid called on a non-writable bitmap"
);
unsafe { duckdb_validity_set_row_invalid(self.validity, idx) };
}
#[inline]
pub unsafe fn set_row_valid(&mut self, idx: idx_t) {
debug_assert!(
!self.validity.is_null(),
"set_row_valid called on a non-writable bitmap"
);
unsafe { duckdb_validity_set_row_valid(self.validity, idx) };
}
#[must_use]
#[inline]
pub const fn as_raw(&self) -> *mut u64 {
self.validity
}
}
#[cfg(test)]
mod tests {
#[test]
fn read_only_with_null_ptr() {
use super::ValidityBitmap;
use libduckdb_sys::duckdb_vector;
let bm = ValidityBitmap {
validity: std::ptr::null_mut(),
_phantom: std::marker::PhantomData::<&mut duckdb_vector>,
};
assert!(unsafe { bm.row_is_valid(0) });
}
}