Skip to main content

reifydb_engine/expression/
parameter.rs

1// SPDX-License-Identifier: AGPL-3.0-or-later
2// Copyright (c) 2025 ReifyDB
3
4use reifydb_core::{
5	error::diagnostic::engine,
6	value::column::{Column, data::ColumnData},
7};
8use reifydb_rql::expression::ParameterExpression;
9use reifydb_type::{
10	error,
11	fragment::Fragment,
12	value::{Value, r#type::Type},
13};
14
15use crate::{Result, expression::context::EvalContext};
16
17pub(crate) fn parameter_lookup(ctx: &EvalContext, expr: &ParameterExpression) -> Result<Column> {
18	let value = match expr {
19		ParameterExpression::Positional {
20			fragment,
21		} => {
22			let index = fragment.text()[1..]
23				.parse::<usize>()
24				.map_err(|_| error!(engine::invalid_parameter_reference(fragment.clone())))?;
25
26			ctx.params
27				.get_positional(index - 1)
28				.ok_or_else(|| error!(engine::parameter_not_found(fragment.clone())))?
29		}
30		ParameterExpression::Named {
31			fragment,
32		} => {
33			let name = &fragment.text()[1..];
34
35			ctx.params
36				.get_named(name)
37				.ok_or_else(|| error!(engine::parameter_not_found(fragment.clone())))?
38		}
39	};
40
41	let column_data = match value {
42		Value::Boolean(b) => ColumnData::bool(vec![*b; ctx.row_count]),
43		Value::Float4(f) => ColumnData::float4(vec![f.value(); ctx.row_count]),
44		Value::Float8(f) => ColumnData::float8(vec![f.value(); ctx.row_count]),
45		Value::Int1(i) => ColumnData::int1(vec![*i; ctx.row_count]),
46		Value::Int2(i) => ColumnData::int2(vec![*i; ctx.row_count]),
47		Value::Int4(i) => ColumnData::int4(vec![*i; ctx.row_count]),
48		Value::Int8(i) => ColumnData::int8(vec![*i; ctx.row_count]),
49		Value::Int16(i) => ColumnData::int16(vec![*i; ctx.row_count]),
50		Value::Uint1(u) => ColumnData::uint1(vec![*u; ctx.row_count]),
51		Value::Uint2(u) => ColumnData::uint2(vec![*u; ctx.row_count]),
52		Value::Uint4(u) => ColumnData::uint4(vec![*u; ctx.row_count]),
53		Value::Uint8(u) => ColumnData::uint8(vec![*u; ctx.row_count]),
54		Value::Uint16(u) => ColumnData::uint16(vec![*u; ctx.row_count]),
55		Value::Utf8(s) => ColumnData::utf8(vec![s.clone(); ctx.row_count]),
56		Value::Date(d) => ColumnData::date(vec![*d; ctx.row_count]),
57		Value::DateTime(dt) => ColumnData::datetime(vec![*dt; ctx.row_count]),
58		Value::Time(t) => ColumnData::time(vec![*t; ctx.row_count]),
59		Value::Duration(i) => ColumnData::duration(vec![*i; ctx.row_count]),
60		Value::Uuid4(u) => ColumnData::uuid4(vec![*u; ctx.row_count]),
61		Value::Uuid7(u) => ColumnData::uuid7(vec![*u; ctx.row_count]),
62		Value::Blob(b) => ColumnData::blob(vec![b.clone(); ctx.row_count]),
63		Value::IdentityId(id) => ColumnData::identity_id(vec![*id; ctx.row_count]),
64		Value::DictionaryId(v) => ColumnData::dictionary_id(vec![v.clone(); ctx.row_count]),
65		Value::Int(bi) => ColumnData::int(vec![bi.clone(); ctx.row_count]),
66		Value::Uint(bu) => ColumnData::uint(vec![bu.clone(); ctx.row_count]),
67		Value::Decimal(bd) => ColumnData::decimal(vec![bd.clone(); ctx.row_count]),
68		Value::None {
69			..
70		} => ColumnData::none_typed(Type::Boolean, ctx.row_count),
71		Value::Type(_) | Value::Any(_) | Value::List(_) => {
72			unreachable!("Any/Type/List not supported as parameter")
73		}
74	};
75	Ok(Column {
76		name: Fragment::internal("parameter"),
77		data: column_data,
78	})
79}