Skip to main content

duckfn/value_types/
wrapper_types.rs

1//! 「物理表示相同、语义不同」的 DuckDB 包装类型。
2//!
3//! 同一个物理表示(`i64` / `i128` / `u128` / `u64`)在不同 DuckDB 逻辑类型下含义不同
4//! (时间戳精度、时间、日期、UUID...),因此用 newtype 包装,避免映射歧义。
5//!
6//! Wrapper types for DuckDB logical types that share a physical representation but differ in
7//! semantics. The same physical layout (`i64` / `i128` / `u128` / `u64`) means different
8//! things under different DuckDB logical types (timestamp precision, time, date, UUID, ...),
9//! so newtypes are used to remove the ambiguity.
10
11use std::fmt::Debug;
12use crate::value_types::duck_value_type::{DuckValueReader, DuckValueType, DuckValueWriter};
13use quack_rs::interval::DuckInterval;
14use quack_rs::prelude::{LogicalType, TypeId, Value, VectorReader, VectorWriter};
15use crate::DuckResult;
16
17/// DuckDB `TIMESTAMP`(微秒精度,无时区)。
18///
19/// DuckDB `TIMESTAMP` (microsecond precision, without time zone).
20//TypeId::Timestamp
21#[derive(Default,Debug, Clone, Copy, PartialEq, Eq)]
22pub struct DuckTimestamp {
23    /// 自 Unix 纪元(1970-01-01)起的微秒数。
24    ///
25    /// Microseconds since the Unix epoch (1970-01-01).
26    pub micros_since_epoch: i64,
27}
28
29/// `DuckValueType` 实现:按 `TIMESTAMP` 读写。
30///
31/// `DuckValueType` implementation: reads and writes as `TIMESTAMP`.
32impl DuckValueType for DuckTimestamp {
33    fn type_id() -> TypeId {
34        TypeId::Timestamp
35    }
36
37    fn read_valid_by_vector_reader(reader: &VectorReader, row: usize) -> Self {
38        Self {
39            micros_since_epoch: unsafe { reader.read_timestamp(row) },
40        }
41    }
42
43    fn write_valid_to_vector_writer(writer: &mut VectorWriter, idx: usize, v: &Self) {
44        unsafe { writer.write_timestamp(idx, v.micros_since_epoch) }
45    }
46    fn read_by_duck_value_valid_simple(value: &Value) -> Self {
47        Self{
48            micros_since_epoch:value.as_timestamp()
49        }
50    }
51}
52
53/// DuckDB `TIMESTAMP WITH TIME ZONE`(微秒精度,UTC)。
54///
55/// `TIMESTAMPTZ` 与 `TIMESTAMP` 共用同一种 `i64` 存储,单位也是**微秒**(不是毫秒):
56/// quack-rs 的 `read_timestamp_tz` / `Value::as_timestamp_tz` 都按微秒返回。
57///
58/// DuckDB `TIMESTAMP WITH TIME ZONE` (microsecond precision, UTC). `TIMESTAMPTZ` shares
59/// `TIMESTAMP`'s `i64` storage and its unit is **microseconds**, not milliseconds: quack-rs'
60/// `read_timestamp_tz` and `Value::as_timestamp_tz` both return microseconds.
61// TypeId::TimestampTz
62#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)]
63pub struct DuckTimestampTz {
64    /// 自 Unix 纪元起的微秒数(UTC)。
65    ///
66    /// Microseconds since the Unix epoch (UTC).
67    pub micros_since_epoch: i64,
68}
69
70// pub const unsafe fn write_timestamp_tz(&mut self, idx: usize, micros_since_epoch: i64) {
71
72/// `DuckValueType` 实现:按 `TIMESTAMP WITH TIME ZONE` 读写。
73///
74/// `DuckValueType` implementation: reads and writes as `TIMESTAMP WITH TIME ZONE`.
75impl DuckValueType for DuckTimestampTz {
76    fn type_id() -> TypeId {
77        TypeId::TimestampTz
78    }
79    fn read_valid_by_vector_reader(reader: &VectorReader, row: usize) -> Self {
80        Self {
81            micros_since_epoch: unsafe { reader.read_timestamp_tz(row) },
82        }
83    }
84    fn write_valid_to_vector_writer(writer: &mut VectorWriter, idx: usize, v: &Self) {
85        unsafe { writer.write_timestamp_tz(idx, v.micros_since_epoch) }
86    }
87    fn read_by_duck_value_valid_simple(value: &Value) -> Self {
88        Self{
89            micros_since_epoch:value.as_timestamp_tz()
90        }
91    }
92
93}
94
95/// DuckDB `TIMESTAMP_S`(秒精度)。
96///
97/// DuckDB `TIMESTAMP_S` (second precision).
98// TypeId::TimestampS
99// pub const unsafe fn write_timestamp_s(&mut self, idx: usize, seconds_since_epoch: i64) {
100#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)]
101pub struct DuckTimestampS {
102    /// 自 Unix 纪元起的秒数。
103    ///
104    /// Seconds since the Unix epoch.
105    pub seconds_since_epoch: i64,
106}
107
108/// `DuckValueType` 实现:按 `TIMESTAMP_S` 读写。
109///
110/// `DuckValueType` implementation: reads and writes as `TIMESTAMP_S`.
111impl DuckValueType for DuckTimestampS {
112    fn type_id() -> TypeId {
113        TypeId::TimestampS
114    }
115    fn read_valid_by_vector_reader(reader: &VectorReader, row: usize) -> Self {
116        Self {
117            seconds_since_epoch: unsafe { reader.read_timestamp_s(row) },
118        }
119    }
120    fn write_valid_to_vector_writer(writer: &mut VectorWriter, idx: usize, v: &Self) {
121        unsafe { writer.write_timestamp_s(idx, v.seconds_since_epoch) }
122    }
123    fn read_by_duck_value_valid_simple(value: &Value) -> Self {
124        Self{
125            seconds_since_epoch:value.as_timestamp_s()
126        }
127    }
128}
129
130/// DuckDB `TIMESTAMP_MS`(毫秒精度)。
131///
132/// DuckDB `TIMESTAMP_MS` (millisecond precision).
133// TypeId::TimestampMs
134// pub const unsafe fn write_timestamp_ms(&mut self, idx: usize, millis_since_epoch: i64) {
135#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)]
136pub struct DuckTimestampMs {
137    /// 自 Unix 纪元起的毫秒数。
138    ///
139    /// Milliseconds since the Unix epoch.
140    pub millis_since_epoch: i64,
141}
142
143/// `DuckValueType` 实现:按 `TIMESTAMP_MS` 读写。
144///
145/// `DuckValueType` implementation: reads and writes as `TIMESTAMP_MS`.
146impl DuckValueType for DuckTimestampMs {
147    fn type_id() -> TypeId {
148        TypeId::TimestampMs
149    }
150    fn read_valid_by_vector_reader(reader: &VectorReader, row: usize) -> Self {
151        Self {
152            millis_since_epoch: unsafe { reader.read_timestamp_ms(row) },
153        }
154    }
155    fn write_valid_to_vector_writer(writer: &mut VectorWriter, idx: usize, v: &Self) {
156        unsafe { writer.write_timestamp_ms(idx, v.millis_since_epoch) }
157    }
158    fn read_by_duck_value_valid_simple(value: &Value) -> Self {
159        Self{
160            millis_since_epoch:value.as_timestamp_ms()
161        }
162    }
163}
164
165/// DuckDB `TIMESTAMP_NS`(纳秒精度)。
166///
167/// DuckDB `TIMESTAMP_NS` (nanosecond precision).
168#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)]
169pub struct DuckTimestampNs {
170    /// 自 Unix 纪元起的纳秒数。
171    ///
172    /// Nanoseconds since the Unix epoch.
173    pub nanos_since_epoch: i64,
174}
175
176/// `DuckValueType` 实现:按 `TIMESTAMP_NS` 读写。
177///
178/// `DuckValueType` implementation: reads and writes as `TIMESTAMP_NS`.
179impl DuckValueType for DuckTimestampNs {
180    fn type_id() -> TypeId {
181        TypeId::TimestampNs
182    }
183    fn read_valid_by_vector_reader(reader: &VectorReader, row: usize) -> Self {
184        Self {
185            nanos_since_epoch: unsafe { reader.read_timestamp_ns(row) },
186        }
187    }
188    fn write_valid_to_vector_writer(writer: &mut VectorWriter, idx: usize, v: &Self) {
189        unsafe { writer.write_timestamp_ns(idx, v.nanos_since_epoch) }
190    }
191    fn read_by_duck_value_valid_simple(value: &Value) -> Self {
192        Self{
193            nanos_since_epoch:value.as_timestamp_ns()
194        }
195    }
196}
197
198/// DuckDB `TIME WITH TIME ZONE`。
199///
200/// DuckDB `TIME WITH TIME ZONE`.
201// TypeId::TimeTz
202// pub const unsafe fn write_time_tz(&mut self, idx: usize, bits: u64) {
203#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)]
204pub struct DuckTimeTz {
205    /// 时间的位编码(微秒 + 时区偏移,按 DuckDB 内部格式打包)。
206    ///
207    /// Bit-packed representation of the time (microseconds plus time-zone offset, in DuckDB's
208    /// internal format).
209    pub bits: u64,
210}
211
212/// `DuckValueType` 实现:按 `TIME WITH TIME ZONE` 读写。
213///
214/// `DuckValueType` implementation: reads and writes as `TIME WITH TIME ZONE`.
215impl DuckValueType for DuckTimeTz {
216    fn type_id() -> TypeId {
217        TypeId::TimeTz
218    }
219    fn read_valid_by_vector_reader(reader: &VectorReader, row: usize) -> Self {
220        Self {
221            bits: unsafe { reader.read_time_tz(row) },
222        }
223    }
224    fn write_valid_to_vector_writer(writer: &mut VectorWriter, idx: usize, v: &Self) {
225        unsafe { writer.write_time_tz(idx, v.bits) }
226    }
227    fn read_by_duck_value_valid_simple(value: &Value) -> Self {
228        Self{
229            bits:value.as_time_tz()
230        }
231    }
232}
233
234/// 定点小数 `DECIMAL(WIDTH, SCALE)`:用 i128 存未缩放整数。
235///
236/// 实际值是 `unscaled / 10^SCALE`;`WIDTH` 与 `SCALE` 由常量泛型参数决定,
237/// 从而在类型层面区分 `DECIMAL(18, 2)` 与 `DECIMAL(18, 4)` 等。
238///
239/// Fixed-point decimal `DECIMAL(WIDTH, SCALE)` backed by an unscaled i128. The real value is
240/// `unscaled / 10^SCALE`; `WIDTH` and `SCALE` are const generic parameters, so `DECIMAL(18, 2)`
241/// and `DECIMAL(18, 4)` are distinct types.
242#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)]
243pub struct DuckDecimal<const WIDTH: u8, const SCALE: u8> {
244    /// 未缩放的整数值。
245    ///
246    /// The unscaled integer value.
247    pub unscaled: i128,
248}
249
250/// `DuckValueType` 实现:按 `DECIMAL(WIDTH, SCALE)` 读写。
251///
252/// `DuckValueType` implementation: reads and writes as `DECIMAL(WIDTH, SCALE)`.
253impl<const WIDTH: u8, const SCALE: u8> DuckValueType for DuckDecimal<WIDTH, SCALE> {
254    fn type_id() -> TypeId {
255        TypeId::Decimal
256    }
257    fn logical_type() -> LogicalType {
258        LogicalType::decimal(WIDTH, SCALE)
259    }
260    fn read_by_duck_value_valid_simple(value: &Value) -> Self {
261        Self {
262            unscaled: value.as_decimal().value,
263        }
264    }
265    /// DECIMAL 的 `read_valid` 需要 `WIDTH` 才能解出未缩放值,因此整体重写。
266    ///
267    /// DECIMAL's `read_valid` needs `WIDTH` to decode the unscaled value, so it is overridden
268    /// as a whole.
269    fn read_valid(reader: &DuckValueReader, row: usize) -> Option<Self> {
270        Some(Self {
271            unscaled: unsafe { reader.vector_reader.read_decimal(row, WIDTH) },
272        })
273    }
274    /// 同理,写入时需要把 `WIDTH` 传给底层 writer。
275    ///
276    /// Likewise, writing must pass `WIDTH` down to the underlying writer.
277    fn write_valid(writer: &mut DuckValueWriter, idx: usize, vo: &Self) {
278        unsafe { writer.vector_writer.write_decimal(idx, WIDTH, vo.unscaled) }
279    }
280}
281
282/// DuckDB `DATE`(自纪元起的天数)。
283///
284/// DuckDB `DATE` (days since the epoch).
285#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)]
286pub struct DuckDate {
287    /// 自 1970-01-01 起的天数(可为负)。
288    ///
289    /// Days since 1970-01-01 (may be negative).
290    pub days_since_epoch: i32,
291}
292
293/// `DuckValueType` 实现:按 `DATE` 读写。
294///
295/// `DuckValueType` implementation: reads and writes as `DATE`.
296impl DuckValueType for DuckDate {
297    fn type_id() -> TypeId {
298        TypeId::Date
299    }
300    fn read_valid_by_vector_reader(reader: &VectorReader, row: usize) -> Self {
301        Self {
302            days_since_epoch: unsafe { reader.read_date(row) },
303        }
304    }
305    fn write_valid_to_vector_writer(writer: &mut VectorWriter, idx: usize, v: &Self) {
306        unsafe { writer.write_date(idx, v.days_since_epoch) }
307    }
308    fn read_by_duck_value_valid_simple(value: &Value) -> Self {
309        Self{
310            days_since_epoch:value.as_date()
311        }
312    }
313}
314
315/// DuckDB `TIME`(自午夜起的微秒数)。
316///
317/// DuckDB `TIME` (microseconds since midnight).
318// pub const unsafe fn write_time(&mut self, idx: usize, micros_since_midnight: i64) {
319#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)]
320pub struct DuckTime {
321    /// 自 00:00:00 起的微秒数。
322    ///
323    /// Microseconds since 00:00:00.
324    pub micros_since_midnight: i64,
325}
326
327/// `DuckValueType` 实现:按 `TIME` 读写。
328///
329/// `DuckValueType` implementation: reads and writes as `TIME`.
330impl DuckValueType for DuckTime {
331    fn type_id() -> TypeId {
332        TypeId::Time
333    }
334    fn read_valid_by_vector_reader(reader: &VectorReader, row: usize) -> Self {
335        Self {
336            micros_since_midnight: unsafe { reader.read_time(row) },
337        }
338    }
339    fn write_valid_to_vector_writer(writer: &mut VectorWriter, idx: usize, v: &Self) {
340        unsafe { writer.write_time(idx, v.micros_since_midnight) }
341    }
342    fn read_by_duck_value_valid_simple(value: &Value) -> Self {
343        Self{
344            micros_since_midnight:value.as_time()
345        }
346    }
347}
348
349/// DuckDB `TIME_NS`(自 00:00:00 起的纳秒数)。
350///
351/// 需要开启 `duckdb-1-5` feature:`TIME_NS` 是 DuckDB 1.5 新增的类型,
352/// quack-rs 里对应的 `TypeId::TimeNs` 由该 feature 门控。
353///
354/// DuckDB `TIME_NS` (nanoseconds since midnight). Requires the `duckdb-1-5` feature:
355/// `TIME_NS` was added in DuckDB 1.5, and quack-rs gates `TypeId::TimeNs` behind that feature.
356#[cfg(feature = "duckdb-1-5")]
357#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)]
358pub struct DuckTimeNs {
359    /// 自 00:00:00 起的纳秒数。
360    ///
361    /// Nanoseconds since 00:00:00.
362    pub nanos_since_midnight: i64,
363}
364
365/// `DuckValueType` 实现:按 `TIME_NS` 读写。
366///
367/// `DuckValueType` implementation: reads and writes as `TIME_NS`.
368#[cfg(feature = "duckdb-1-5")]
369impl DuckValueType for DuckTimeNs {
370    fn type_id() -> TypeId {
371        TypeId::TimeNs
372    }
373    fn read_valid_by_vector_reader(reader: &VectorReader, row: usize) -> Self {
374        // TIME_NS 在向量里就是一个 i64(纳秒)。quack-rs 0.16 还没有 read_time_ns,
375        // 因此直接读底层槽位。
376        //
377        // A TIME_NS slot is a plain i64 (nanoseconds). quack-rs 0.16 has no `read_time_ns`
378        // yet, so the underlying slot is read directly.
379        Self {
380            nanos_since_midnight: unsafe { reader.read_i64(row) },
381        }
382    }
383    fn write_valid_to_vector_writer(writer: &mut VectorWriter, idx: usize, v: &Self) {
384        unsafe { writer.write_i64(idx, v.nanos_since_midnight) }
385    }
386    fn read_by_duck_value_valid_simple(value: &Value) -> Self {
387        Self {
388            nanos_since_midnight: value.as_time_ns(),
389        }
390    }
391}
392
393/// DuckDB `BLOB`(任意字节串)。
394///
395/// DuckDB `BLOB` (an arbitrary byte string).
396// pub unsafe fn read_blob(&self, idx: usize) -> &[u8] {
397// pub unsafe fn write_blob(&mut self, idx: usize, value: &[u8]) {
398#[derive(Default, Debug, Clone, PartialEq, Eq)]
399pub struct DuckBlob {
400    /// 字节内容。
401    ///
402    /// The byte contents.
403    pub value: Vec<u8>,
404}
405
406/// `DuckValueType` 实现:按 `BLOB` 读写。
407///
408/// `DuckValueType` implementation: reads and writes as `BLOB`.
409impl DuckValueType for DuckBlob {
410    fn type_id() -> TypeId {
411        TypeId::Blob
412    }
413    fn read_valid_by_vector_reader(reader: &VectorReader, row: usize) -> Self {
414        Self {
415            value: unsafe { reader.read_blob(row).to_vec() },
416        }
417    }
418    fn write_valid_to_vector_writer(writer: &mut VectorWriter, idx: usize, v: &Self) {
419        unsafe { writer.write_blob(idx, v.value.as_slice()) }
420
421    }
422    /// `Value::as_blob` 会失败,因此返回 `DuckResult`。
423    ///
424    /// `Value::as_blob` is fallible, hence the `DuckResult`.
425    fn read_by_duck_value_valid(value: &Value) -> DuckResult<Self> {
426        Ok(Self{
427            value:value.as_blob()?
428        })
429    }
430}
431
432/// DuckDB `UUID`(128 位)。
433///
434/// DuckDB `UUID` (128 bits).
435#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)]
436pub struct DuckUuid {
437    /// UUID 的 128 位表示。
438    ///
439    /// The 128-bit UUID value.
440    pub value: u128,
441}
442
443/// `DuckValueType` 实现:按 `UUID` 读写。
444///
445/// `DuckValueType` implementation: reads and writes as `UUID`.
446impl DuckValueType for DuckUuid {
447    fn type_id() -> TypeId {
448        TypeId::Uuid
449    }
450    fn read_valid_by_vector_reader(reader: &VectorReader, row: usize) -> Self {
451        Self {
452            value: unsafe { reader.read_uuid(row) },
453        }
454    }
455    fn write_valid_to_vector_writer(writer: &mut VectorWriter, idx: usize, v: &Self) {
456        unsafe { writer.write_uuid(idx, v.value) }
457    }
458    fn read_by_duck_value_valid_simple(value: &Value) -> Self {
459        Self{
460            value:value.as_uuid()
461        }
462    }
463}
464
465/// DuckDB `INTERVAL`:直接复用 quack-rs 的 [`DuckInterval`]。
466///
467/// DuckDB `INTERVAL`: reuses quack-rs' [`DuckInterval`] directly.
468///
469/// `DuckValueType` 实现:按 `INTERVAL` 读写。
470///
471/// `DuckValueType` implementation: reads and writes as `INTERVAL`.
472//TypeId::Interval
473impl DuckValueType for DuckInterval {
474    fn type_id() -> TypeId {
475        TypeId::Interval
476    }
477    fn read_valid_by_vector_reader(reader: &VectorReader, row: usize) -> Self {
478        unsafe { reader.read_interval(row) }
479    }
480    fn write_valid_to_vector_writer(writer: &mut VectorWriter, idx: usize, v: &Self) {
481        unsafe { writer.write_interval(idx, *v) }
482    }
483    fn read_by_duck_value_valid_simple(value: &Value) -> Self {
484        value.as_interval()
485    }
486}