Skip to main content

reifydb_routine/procedure/identity/
inject.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright (c) 2025 ReifyDB
3
4use std::sync::LazyLock;
5
6use reifydb_core::value::column::{ColumnWithName, buffer::ColumnBuffer, columns::Columns};
7use reifydb_type::{
8	fragment::Fragment,
9	params::Params,
10	value::{Value, r#type::Type},
11};
12
13use crate::routine::{Routine, RoutineInfo, context::ProcedureContext, error::RoutineError};
14
15static INFO: LazyLock<RoutineInfo> = LazyLock::new(|| RoutineInfo::new("identity::inject"));
16
17/// Procedure that injects a new identity into the current session.
18///
19/// Takes 1 positional parameter: the IdentityId to inject.
20/// Returns a single-column result containing the IdentityId value;
21/// the VM intercepts this result and updates its identity accordingly.
22pub struct IdentityInject;
23
24impl Default for IdentityInject {
25	fn default() -> Self {
26		Self::new()
27	}
28}
29
30impl IdentityInject {
31	pub fn new() -> Self {
32		Self
33	}
34}
35
36impl<'a, 'tx> Routine<ProcedureContext<'a, 'tx>> for IdentityInject {
37	fn info(&self) -> &RoutineInfo {
38		&INFO
39	}
40
41	fn return_type(&self, _input_types: &[Type]) -> Type {
42		Type::IdentityId
43	}
44
45	fn execute(&self, ctx: &mut ProcedureContext<'a, 'tx>, _args: &Columns) -> Result<Columns, RoutineError> {
46		let identity_id = match ctx.params {
47			Params::Positional(args) if args.len() == 1 => match &args[0] {
48				Value::IdentityId(id) => *id,
49				other => {
50					return Err(RoutineError::ProcedureInvalidArgumentType {
51						procedure: Fragment::internal("identity::inject"),
52						argument_index: 0,
53						expected: vec![Type::IdentityId],
54						actual: other.get_type(),
55					});
56				}
57			},
58			Params::Positional(args) => {
59				return Err(RoutineError::ProcedureArityMismatch {
60					procedure: Fragment::internal("identity::inject"),
61					expected: 1,
62					actual: args.len(),
63				});
64			}
65			_ => {
66				return Err(RoutineError::ProcedureArityMismatch {
67					procedure: Fragment::internal("identity::inject"),
68					expected: 1,
69					actual: 0,
70				});
71			}
72		};
73
74		let col = ColumnWithName::new("identity_id", ColumnBuffer::identity_id(vec![identity_id]));
75		Ok(Columns::new(vec![col]))
76	}
77}