1use uqa_core::Value;
10
11use crate::ast::ColumnType;
12
13#[derive(Debug, Clone)]
15pub enum SQLParam {
16 Scalar(Value),
17 TypedScalar {
19 value: Value,
20 ty: ColumnType,
21 },
22 Vector(Vec<f32>),
23 Tensor(Vec<Vec<f32>>),
24}
25
26impl SQLParam {
27 pub fn scalar(value: Value) -> Self {
28 Self::Scalar(value)
29 }
30
31 #[must_use]
32 pub fn typed_scalar(value: Value, ty: ColumnType) -> Self {
33 Self::TypedScalar { value, ty }
34 }
35
36 #[must_use]
38 pub fn scalar_value(&self) -> Option<&Value> {
39 match self {
40 Self::Scalar(value) | Self::TypedScalar { value, .. } => Some(value),
41 Self::Vector(_) | Self::Tensor(_) => None,
42 }
43 }
44
45 #[must_use]
47 pub fn declared_scalar_type(&self) -> Option<&ColumnType> {
48 match self {
49 Self::TypedScalar { ty, .. } => Some(ty),
50 Self::Scalar(_) | Self::Vector(_) | Self::Tensor(_) => None,
51 }
52 }
53
54 pub fn vector(v: Vec<f32>) -> Self {
55 Self::Vector(v)
56 }
57
58 pub fn tensor(v: Vec<Vec<f32>>) -> Self {
59 Self::Tensor(v)
60 }
61}
62
63#[cfg(test)]
64mod tests {
65 use super::*;
66
67 #[test]
68 fn typed_scalar_preserves_declared_type_without_changing_scalar_access() {
69 let value = Value::Int(7);
70 let typed = SQLParam::typed_scalar(value.clone(), ColumnType::SmallInteger);
71 assert_eq!(typed.scalar_value(), Some(&value));
72 assert_eq!(
73 typed.declared_scalar_type(),
74 Some(&ColumnType::SmallInteger)
75 );
76
77 let scalar = SQLParam::scalar(value.clone());
78 assert_eq!(scalar.scalar_value(), Some(&value));
79 assert_eq!(scalar.declared_scalar_type(), None);
80 }
81}