datafusion_functions/string/
uuid.rs1use std::sync::Arc;
19
20use arrow::datatypes::DataType;
21use arrow::datatypes::DataType::Utf8;
22use rand::Rng;
23use uuid::Uuid;
24
25use crate::strings::GenericStringArrayBuilder;
26use datafusion_common::{Result, assert_or_internal_err};
27use datafusion_expr::{ColumnarValue, Documentation, Volatility};
28use datafusion_expr::{ScalarFunctionArgs, ScalarUDFImpl, Signature};
29use datafusion_macros::user_doc;
30
31#[user_doc(
32 doc_section(label = "String Functions"),
33 description = "Returns [`UUID v4`](https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_%28random%29) string value which is unique per row.",
34 syntax_example = "uuid()",
35 sql_example = r#"```sql
36> select uuid();
37+--------------------------------------+
38| uuid() |
39+--------------------------------------+
40| 6ec17ef8-1934-41cc-8d59-d0c8f9eea1f0 |
41+--------------------------------------+
42```"#
43)]
44#[derive(Debug, PartialEq, Eq, Hash)]
45pub struct UuidFunc {
46 signature: Signature,
47}
48
49impl Default for UuidFunc {
50 fn default() -> Self {
51 Self::new()
52 }
53}
54
55impl UuidFunc {
56 pub fn new() -> Self {
57 Self {
58 signature: Signature::nullary(Volatility::Volatile),
59 }
60 }
61}
62
63impl ScalarUDFImpl for UuidFunc {
64 fn name(&self) -> &str {
65 "uuid"
66 }
67
68 fn signature(&self) -> &Signature {
69 &self.signature
70 }
71
72 fn return_type(&self, _arg_types: &[DataType]) -> Result<DataType> {
73 Ok(Utf8)
74 }
75
76 fn invoke_with_args(&self, args: ScalarFunctionArgs) -> Result<ColumnarValue> {
79 assert_or_internal_err!(
80 args.args.is_empty(),
81 "{} function does not accept arguments",
82 self.name()
83 );
84
85 let mut rng = rand::rng();
87 let mut randoms = vec![0u128; args.number_rows];
88 rng.fill(&mut randoms[..]);
89
90 let mut builder = GenericStringArrayBuilder::<i32>::with_capacity(
91 args.number_rows,
92 args.number_rows * 36,
93 );
94
95 let mut buffer = [0u8; 36];
96 for x in &mut randoms {
97 *x = *x & 0xFFFFFFFFFFFF4FFFBFFFFFFFFFFFFFFF | 0x40008000000000000000;
99 let uuid = Uuid::from_u128(*x);
100 let fmt = uuid::fmt::Hyphenated::from_uuid(uuid);
101 builder.append_value(fmt.encode_lower(&mut buffer));
102 }
103
104 Ok(ColumnarValue::Array(Arc::new(builder.finish(None)?)))
105 }
106
107 fn documentation(&self) -> Option<&Documentation> {
108 self.doc()
109 }
110}