Skip to content

Commit 893f289

Browse files
authored
Feature: Add DuckDB conversion for fixed-size lists / ARRAY type (#4590)
Tracking issue: #4372 Relevant DuckDB docs for their ARRAY type: https://duckdb.org/docs/stable/sql/data_types/array.html Adds conversion methods and an exporter for fixed-size list type to DuckDB. Also adds `vortex-ffi` bindings for fixed-size lists. --------- Signed-off-by: Connor Tsui <connor.tsui20@gmail.com>
1 parent 9fa01f2 commit 893f289

9 files changed

Lines changed: 673 additions & 37 deletions

File tree

vortex-duckdb/src/convert/dtype.rs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,23 @@ impl LogicalType {
9999
}
100100
}
101101

102+
/// Creates a DuckDB fixed-size list logical type with the specified element type and list size.
103+
///
104+
/// Note that DuckDB calls what we call a fixed-size list the ARRAY type.
105+
fn fixed_size_list_type(element_type: LogicalType, list_size: u32) -> VortexResult<Self> {
106+
// SAFETY: We trust that DuckDB correctly gives us a valid pointer or `NULL`.
107+
let ptr = unsafe {
108+
cpp::duckdb_create_array_type(element_type.as_ptr(), list_size as cpp::idx_t)
109+
};
110+
111+
if ptr.is_null() {
112+
vortex_bail!("Failed to create fixed-size list (array) type");
113+
}
114+
115+
// SAFETY: This pointer came directly from DuckDB, and we checked that it was not `NULL`.
116+
Ok(unsafe { Self::own(ptr) })
117+
}
118+
102119
/// Converts temporal extension types to corresponding DuckDB types.
103120
///
104121
/// # Arguments
@@ -315,8 +332,9 @@ impl TryFrom<&DType> for LogicalType {
315332
let element_logical_type = LogicalType::try_from(element_dtype.as_ref())?;
316333
return LogicalType::list_type(element_logical_type);
317334
}
318-
DType::FixedSizeList(..) => {
319-
unimplemented!("TODO(connor)[FixedSizeList]")
335+
DType::FixedSizeList(element_dtype, list_size, _) => {
336+
let element_logical_type = LogicalType::try_from(element_dtype.as_ref())?;
337+
return LogicalType::fixed_size_list_type(element_logical_type, *list_size);
320338
}
321339
DType::Extension(ext_dtype) => {
322340
if datetime::is_temporal_ext_type(ext_dtype.id()) {

vortex-duckdb/src/duckdb/logical_type.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,18 @@ impl LogicalType {
3131
unsafe { Self::own(duckdb_create_list_type(element_dtype.as_ptr())) }
3232
}
3333

34+
pub fn new_array(element_dtype: DUCKDB_TYPE, array_size: u32) -> Self {
35+
let element_dtype = Self::new(element_dtype);
36+
37+
// SAFETY: The element_dtype is created by `Self::new` which ensures it is valid.
38+
unsafe {
39+
Self::own(duckdb_create_array_type(
40+
element_dtype.as_ptr(),
41+
array_size as idx_t,
42+
))
43+
}
44+
}
45+
3446
pub fn as_type_id(&self) -> DUCKDB_TYPE {
3547
unsafe { duckdb_get_type_id(self.as_ptr()) }
3648
}
@@ -52,6 +64,10 @@ impl LogicalType {
5264
unsafe { LogicalType::own(duckdb_array_type_child_type(self.as_ptr())) }
5365
}
5466

67+
pub fn array_type_array_size(&self) -> idx_t {
68+
unsafe { duckdb_array_type_array_size(self.as_ptr()) }
69+
}
70+
5571
pub fn list_child_type(&self) -> Self {
5672
unsafe { LogicalType::own(duckdb_list_type_child_type(self.as_ptr())) }
5773
}

vortex-duckdb/src/duckdb/vector.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,13 @@ impl Vector {
228228
unsafe { Self::borrow(cpp::duckdb_list_vector_get_child(self.as_ptr())) }
229229
}
230230

231+
pub fn array_vector_get_child(&self) -> Self {
232+
// SAFETY: duckdb_array_vector_get_child dereferences the vector pointer which must be
233+
// valid and point to an ARRAY type vector. The returned child vector is borrowed and
234+
// remains valid as long as the parent vector is valid.
235+
unsafe { Self::borrow(cpp::duckdb_array_vector_get_child(self.as_ptr())) }
236+
}
237+
231238
pub fn list_vector_set_size(&self, size: u64) -> VortexResult<()> {
232239
let state = unsafe { cpp::duckdb_list_vector_set_size(self.as_ptr(), size) };
233240
match state {

0 commit comments

Comments
 (0)