reifydb_routine/function/uuid/
v7.rs1use reifydb_core::value::column::{ColumnWithName, buffer::ColumnBuffer, columns::Columns};
5use reifydb_type::value::{r#type::Type, uuid::Uuid7};
6use uuid::Uuid;
7
8use crate::routine::{Function, FunctionKind, Routine, RoutineInfo, context::FunctionContext, error::RoutineError};
9
10pub struct UuidV7 {
11 info: RoutineInfo,
12}
13
14impl Default for UuidV7 {
15 fn default() -> Self {
16 Self::new()
17 }
18}
19
20impl UuidV7 {
21 pub fn new() -> Self {
22 Self {
23 info: RoutineInfo::new("uuid::v7"),
24 }
25 }
26}
27
28impl<'a> Routine<FunctionContext<'a>> for UuidV7 {
29 fn info(&self) -> &RoutineInfo {
30 &self.info
31 }
32
33 fn return_type(&self, _input_types: &[Type]) -> Type {
34 Type::Uuid7
35 }
36
37 fn execute(&self, ctx: &mut FunctionContext<'a>, args: &Columns) -> Result<Columns, RoutineError> {
38 if args.len() > 1 {
39 return Err(RoutineError::FunctionArityMismatch {
40 function: ctx.fragment.clone(),
41 expected: 0,
42 actual: args.len(),
43 });
44 }
45
46 if args.is_empty() {
47 let uuid = Uuid7::generate(&ctx.runtime_context.clock, &ctx.runtime_context.rng);
48 let result_data = ColumnBuffer::uuid7(vec![uuid]);
49 return Ok(Columns::new(vec![ColumnWithName::new(ctx.fragment.clone(), result_data)]));
50 }
51
52 let column = &args[0];
53 let (data, bitvec) = column.unwrap_option();
54 let row_count = data.len();
55
56 match data {
57 ColumnBuffer::Utf8 {
58 container,
59 ..
60 } => {
61 let mut result = Vec::with_capacity(row_count);
62 for i in 0..row_count {
63 let s = container.get(i).unwrap();
64 let parsed = Uuid::parse_str(s).map_err(|e| {
65 RoutineError::FunctionExecutionFailed {
66 function: ctx.fragment.clone(),
67 reason: format!("invalid UUID string '{}': {}", s, e),
68 }
69 })?;
70 if parsed.get_version_num() != 7 {
71 return Err(RoutineError::FunctionExecutionFailed {
72 function: ctx.fragment.clone(),
73 reason: format!(
74 "expected UUID v7, got v{}",
75 parsed.get_version_num()
76 ),
77 });
78 }
79 result.push(Uuid7::from(parsed));
80 }
81 let result_data = ColumnBuffer::uuid7(result);
82 let final_data = match bitvec {
83 Some(bv) => ColumnBuffer::Option {
84 inner: Box::new(result_data),
85 bitvec: bv.clone(),
86 },
87 None => result_data,
88 };
89 Ok(Columns::new(vec![ColumnWithName::new(ctx.fragment.clone(), final_data)]))
90 }
91 other => Err(RoutineError::FunctionInvalidArgumentType {
92 function: ctx.fragment.clone(),
93 argument_index: 0,
94 expected: vec![Type::Utf8],
95 actual: other.get_type(),
96 }),
97 }
98 }
99}
100
101impl Function for UuidV7 {
102 fn kinds(&self) -> &[FunctionKind] {
103 &[FunctionKind::Scalar]
104 }
105}