reifydb_function/is/
type.rs1use reifydb_core::value::column::data::ColumnData;
5use reifydb_type::value::{Value, r#type::Type};
6
7use crate::{ScalarFunction, ScalarFunctionContext, error::ScalarFunctionError};
8
9pub struct IsType;
10
11impl IsType {
12 pub fn new() -> Self {
13 Self
14 }
15}
16
17impl ScalarFunction for IsType {
18 fn scalar(&self, ctx: ScalarFunctionContext) -> crate::error::ScalarFunctionResult<ColumnData> {
19 let columns = ctx.columns;
20 let row_count = ctx.row_count;
21
22 if columns.len() != 2 {
23 return Err(ScalarFunctionError::ArityMismatch {
24 function: ctx.fragment.clone(),
25 expected: 2,
26 actual: columns.len(),
27 });
28 }
29
30 let value_column = columns.get(0).unwrap();
31 let type_column = columns.get(1).unwrap();
32
33 let target_type = match type_column.data().get_value(0) {
37 Value::Any(boxed) => match boxed.as_ref() {
38 Value::Type(t) => t.clone(),
39 _ => {
40 return Err(ScalarFunctionError::InvalidArgumentType {
41 function: ctx.fragment.clone(),
42 argument_index: 1,
43 expected: vec![Type::Any],
44 actual: boxed.get_type(),
45 });
46 }
47 },
48 Value::None {
49 ..
50 } => Type::Option(Box::new(Type::Any)),
51 other => {
52 return Err(ScalarFunctionError::InvalidArgumentType {
53 function: ctx.fragment.clone(),
54 argument_index: 1,
55 expected: vec![Type::Any],
56 actual: other.get_type(),
57 });
58 }
59 };
60
61 let data: Vec<bool> = (0..row_count)
63 .map(|i| {
64 let vtype = value_column.data().get_value(i).get_type();
65 if target_type == Type::Option(Box::new(Type::Any)) {
66 vtype.is_option()
67 } else {
68 vtype == target_type
69 }
70 })
71 .collect();
72
73 Ok(ColumnData::bool(data))
74 }
75
76 fn return_type(&self, _input_types: &[Type]) -> Type {
77 Type::Boolean
78 }
79}