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