Skip to main content

reifydb_function/clock/
set.rs

1// SPDX-License-Identifier: AGPL-3.0-or-later
2// Copyright (c) 2025 ReifyDB
3
4use reifydb_core::value::column::data::ColumnData;
5use reifydb_runtime::clock::Clock;
6use reifydb_type::value::r#type::Type;
7
8use crate::{
9	ScalarFunction, ScalarFunctionContext, ScalarFunctionResult, error::ScalarFunctionError, propagate_options,
10};
11
12pub struct Set;
13
14impl Set {
15	pub fn new() -> Self {
16		Self {}
17	}
18}
19
20impl ScalarFunction for Set {
21	fn scalar(&self, ctx: ScalarFunctionContext) -> ScalarFunctionResult<ColumnData> {
22		if let Some(result) = propagate_options(self, &ctx) {
23			return result;
24		}
25
26		let columns = ctx.columns;
27		let row_count = ctx.row_count;
28
29		if columns.len() != 1 {
30			return Err(ScalarFunctionError::ArityMismatch {
31				function: ctx.fragment.clone(),
32				expected: 1,
33				actual: columns.len(),
34			});
35		}
36
37		let column = columns.get(0).unwrap();
38
39		let millis_u64: u64 = match column.data().get_as::<u64>(0) {
40			Some(v) => v,
41			None if !column.data().is_number() => {
42				return Err(ScalarFunctionError::InvalidArgumentType {
43					function: ctx.fragment.clone(),
44					argument_index: 0,
45					expected: vec![
46						Type::Int1,
47						Type::Int2,
48						Type::Int4,
49						Type::Int8,
50						Type::Int16,
51						Type::Uint1,
52						Type::Uint2,
53						Type::Uint4,
54						Type::Uint8,
55						Type::Uint16,
56						Type::Int,
57						Type::Uint,
58					],
59					actual: column.data().get_type(),
60				});
61			}
62			None => {
63				return Err(ScalarFunctionError::ExecutionFailed {
64					function: ctx.fragment.clone(),
65					reason: "clock::set requires a non-null argument".to_string(),
66				});
67			}
68		};
69
70		match ctx.clock {
71			Clock::Mock(mock) => {
72				mock.set_millis(millis_u64);
73				let millis = mock.now_millis() as i64;
74				let data = vec![millis; row_count];
75				let bitvec = vec![true; row_count];
76				Ok(ColumnData::int8_with_bitvec(data, bitvec))
77			}
78			Clock::Real => Err(ScalarFunctionError::ExecutionFailed {
79				function: ctx.fragment.clone(),
80				reason: "clock::set can only be used with a mock clock".to_string(),
81			}),
82		}
83	}
84
85	fn return_type(&self, _input_types: &[Type]) -> Type {
86		Type::Int8
87	}
88}