Skip to content

Commit 61dfc79

Browse files
feat[vortex-duckdb-ext]: add vx duckdb type conversion (#3588)
Signed-off-by: Joe Isaacs <[email protected]>
1 parent dc18375 commit 61dfc79

File tree

2 files changed

+45
-14
lines changed

2 files changed

+45
-14
lines changed

vortex-duckdb-ext/src/convert/dtype.rs

Lines changed: 43 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,11 @@
2626
//! | `Timestamp` | `TIMESTAMP` |
2727
2828
use std::ffi::CString;
29+
use std::sync::Arc;
2930

3031
use vortex::dtype::PType::{F32, F64, I8, I16, I32, I64, U8, U16, U32, U64};
31-
use vortex::dtype::{DType, Nullability, PType, datetime};
32+
use vortex::dtype::datetime::{DATE_ID, TIME_ID, TIMESTAMP_ID, TemporalMetadata, TimeUnit};
33+
use vortex::dtype::{DType, DecimalDType, ExtDType, Nullability, PType, datetime};
3234
use vortex::error::{VortexError, VortexResult, vortex_bail, vortex_err};
3335

3436
use crate::cpp::{self, DUCKDB_TYPE, duckdb_logical_type};
@@ -103,7 +105,7 @@ impl LogicalType {
103105
/// - **Date**: Must use `TimeUnit::D`
104106
/// - **Time**: Must use `TimeUnit::Us`
105107
/// - **Timestamp**: Supports `TimeUnit::Ns`, `Us`, `Ms`, `S`
106-
fn temporal_type(ext_dtype: &vortex::dtype::ExtDType) -> VortexResult<Self> {
108+
fn temporal_type(ext_dtype: &ExtDType) -> VortexResult<Self> {
107109
use vortex::dtype::datetime::{TemporalMetadata, TimeUnit};
108110

109111
let temporal_metadata = TemporalMetadata::try_from(ext_dtype)
@@ -150,6 +152,7 @@ impl FromLogicalType for DType {
150152
) -> VortexResult<DType> {
151153
Ok(match logical_type.as_type_id() {
152154
DUCKDB_TYPE::DUCKDB_TYPE_INVALID => vortex_bail!("invalid duckdb type"),
155+
DUCKDB_TYPE::DUCKDB_TYPE_SQLNULL => DType::Null,
153156
DUCKDB_TYPE::DUCKDB_TYPE_BOOLEAN => DType::Bool(nullability),
154157
DUCKDB_TYPE::DUCKDB_TYPE_TINYINT => DType::Primitive(I8, nullability),
155158
DUCKDB_TYPE::DUCKDB_TYPE_SMALLINT => DType::Primitive(I16, nullability),
@@ -159,20 +162,48 @@ impl FromLogicalType for DType {
159162
DUCKDB_TYPE::DUCKDB_TYPE_USMALLINT => DType::Primitive(U16, nullability),
160163
DUCKDB_TYPE::DUCKDB_TYPE_UINTEGER => DType::Primitive(U32, nullability),
161164
DUCKDB_TYPE::DUCKDB_TYPE_UBIGINT => DType::Primitive(U64, nullability),
162-
DUCKDB_TYPE::DUCKDB_TYPE_FLOAT => DType::Primitive(F32, nullability),
163-
DUCKDB_TYPE::DUCKDB_TYPE_DOUBLE => DType::Primitive(F64, nullability),
164-
DUCKDB_TYPE::DUCKDB_TYPE_TIMESTAMP => todo!(),
165-
DUCKDB_TYPE::DUCKDB_TYPE_DATE => todo!(),
166-
DUCKDB_TYPE::DUCKDB_TYPE_TIME => todo!(),
167-
DUCKDB_TYPE::DUCKDB_TYPE_INTERVAL => todo!(),
168165
DUCKDB_TYPE::DUCKDB_TYPE_HUGEINT => todo!(),
169166
DUCKDB_TYPE::DUCKDB_TYPE_UHUGEINT => todo!(),
167+
DUCKDB_TYPE::DUCKDB_TYPE_FLOAT => DType::Primitive(F32, nullability),
168+
DUCKDB_TYPE::DUCKDB_TYPE_DOUBLE => DType::Primitive(F64, nullability),
169+
170170
DUCKDB_TYPE::DUCKDB_TYPE_VARCHAR => DType::Utf8(nullability),
171171
DUCKDB_TYPE::DUCKDB_TYPE_BLOB => DType::Binary(nullability),
172-
DUCKDB_TYPE::DUCKDB_TYPE_DECIMAL => todo!(),
173-
DUCKDB_TYPE::DUCKDB_TYPE_TIMESTAMP_S => todo!(),
174-
DUCKDB_TYPE::DUCKDB_TYPE_TIMESTAMP_MS => todo!(),
175-
DUCKDB_TYPE::DUCKDB_TYPE_TIMESTAMP_NS => todo!(),
172+
DUCKDB_TYPE::DUCKDB_TYPE_DECIMAL => {
173+
let (width, scale) = logical_type.as_decimal();
174+
DType::Decimal(DecimalDType::new(width, scale.try_into()?), nullability)
175+
}
176+
DUCKDB_TYPE::DUCKDB_TYPE_DATE => DType::Extension(Arc::new(ExtDType::new(
177+
DATE_ID.clone(),
178+
Arc::new(DType::Primitive(I32, nullability)),
179+
Some(TemporalMetadata::Date(TimeUnit::D).into()),
180+
))),
181+
DUCKDB_TYPE::DUCKDB_TYPE_TIME => DType::Extension(Arc::new(ExtDType::new(
182+
TIME_ID.clone(),
183+
Arc::new(DType::Primitive(I64, nullability)),
184+
Some(TemporalMetadata::Date(TimeUnit::Us).into()),
185+
))),
186+
DUCKDB_TYPE::DUCKDB_TYPE_TIMESTAMP_S => DType::Extension(Arc::new(ExtDType::new(
187+
TIMESTAMP_ID.clone(),
188+
Arc::new(DType::Primitive(I32, nullability)),
189+
Some(TemporalMetadata::Timestamp(TimeUnit::S, None).into()),
190+
))),
191+
DUCKDB_TYPE::DUCKDB_TYPE_TIMESTAMP_MS => DType::Extension(Arc::new(ExtDType::new(
192+
TIMESTAMP_ID.clone(),
193+
Arc::new(DType::Primitive(I32, nullability)),
194+
Some(TemporalMetadata::Timestamp(TimeUnit::Ms, None).into()),
195+
))),
196+
DUCKDB_TYPE::DUCKDB_TYPE_TIMESTAMP => DType::Extension(Arc::new(ExtDType::new(
197+
TIMESTAMP_ID.clone(),
198+
Arc::new(DType::Primitive(I64, nullability)),
199+
Some(TemporalMetadata::Timestamp(TimeUnit::Us, None).into()),
200+
))),
201+
DUCKDB_TYPE::DUCKDB_TYPE_TIMESTAMP_NS => DType::Extension(Arc::new(ExtDType::new(
202+
TIMESTAMP_ID.clone(),
203+
Arc::new(DType::Primitive(I64, nullability)),
204+
Some(TemporalMetadata::Timestamp(TimeUnit::Ns, None).into()),
205+
))),
206+
DUCKDB_TYPE::DUCKDB_TYPE_INTERVAL => todo!(),
176207
DUCKDB_TYPE::DUCKDB_TYPE_ENUM => todo!(),
177208
DUCKDB_TYPE::DUCKDB_TYPE_LIST => todo!(),
178209
DUCKDB_TYPE::DUCKDB_TYPE_STRUCT => todo!(),
@@ -185,7 +216,6 @@ impl FromLogicalType for DType {
185216
DUCKDB_TYPE::DUCKDB_TYPE_TIMESTAMP_TZ => todo!(),
186217
DUCKDB_TYPE::DUCKDB_TYPE_ANY => todo!(),
187218
DUCKDB_TYPE::DUCKDB_TYPE_VARINT => todo!(),
188-
DUCKDB_TYPE::DUCKDB_TYPE_SQLNULL => DType::Null,
189219
DUCKDB_TYPE::DUCKDB_TYPE_STRING_LITERAL => todo!(),
190220
DUCKDB_TYPE::DUCKDB_TYPE_INTEGER_LITERAL => todo!(),
191221
})

vortex-duckdb-ext/src/convert/scalar.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ use vortex::dtype::{DType, DecimalDType, ExtDType, PType, match_each_native_simd
2828
use vortex::error::{VortexError, VortexExpect, VortexResult, vortex_bail, vortex_err};
2929
use vortex::scalar::{
3030
BinaryScalar, BoolScalar, DecimalScalar, DecimalValue, ExtScalar, PrimitiveScalar, Scalar,
31-
Utf8Scalar,
31+
ScalarValue, Utf8Scalar,
3232
};
3333

3434
use crate::convert::dtype::FromLogicalType;
@@ -216,6 +216,7 @@ impl TryFrom<Value> for Scalar {
216216
};
217217
match value.logical_type().as_type_id() {
218218
DUCKDB_TYPE::DUCKDB_TYPE_INVALID => vortex_bail!("invalid duckdb type"),
219+
DUCKDB_TYPE::DUCKDB_TYPE_SQLNULL => Ok(Scalar::new(DType::Null, ScalarValue::null())),
219220
DUCKDB_TYPE::DUCKDB_TYPE_BOOLEAN => {
220221
let bool = unsafe { cpp::duckdb_get_bool(value.as_ptr()) };
221222
Ok(Scalar::bool(bool, Nullable))

0 commit comments

Comments
 (0)