Skip to main content

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