sql_cli/sql/functions/
constants.rs

1use anyhow::Result;
2
3use super::{ArgCount, FunctionCategory, FunctionSignature, SqlFunction};
4use crate::data::datatable::DataValue;
5
6/// PI constant function
7pub struct PiFunction;
8
9impl SqlFunction for PiFunction {
10    fn signature(&self) -> FunctionSignature {
11        FunctionSignature {
12            name: "PI",
13            category: FunctionCategory::Constant,
14            arg_count: ArgCount::Fixed(0),
15            description: "Returns the value of π (pi)",
16            returns: "FLOAT",
17            examples: vec!["SELECT PI()", "SELECT radius * 2 * PI() AS circumference"],
18        }
19    }
20
21    fn evaluate(&self, args: &[DataValue]) -> Result<DataValue> {
22        self.validate_args(args)?;
23        Ok(DataValue::Float(std::f64::consts::PI))
24    }
25}
26
27/// E (Euler's number) constant function
28pub struct EFunction;
29
30impl SqlFunction for EFunction {
31    fn signature(&self) -> FunctionSignature {
32        FunctionSignature {
33            name: "E",
34            category: FunctionCategory::Constant,
35            arg_count: ArgCount::Fixed(0),
36            description: "Returns Euler's number (e ≈ 2.71828)",
37            returns: "FLOAT",
38            examples: vec!["SELECT E()", "SELECT POW(E(), x) AS exp_x"],
39        }
40    }
41
42    fn evaluate(&self, args: &[DataValue]) -> Result<DataValue> {
43        self.validate_args(args)?;
44        Ok(DataValue::Float(std::f64::consts::E))
45    }
46}
47
48/// Mass of electron in kg
49pub struct MeFunction;
50
51/// Alias for ME function
52pub struct MassElectronFunction;
53
54impl SqlFunction for MeFunction {
55    fn signature(&self) -> FunctionSignature {
56        FunctionSignature {
57            name: "ME",
58            category: FunctionCategory::Constant,
59            arg_count: ArgCount::Fixed(0),
60            description: "Returns the mass of an electron in kg (9.10938356 × 10^-31)",
61            returns: "FLOAT",
62            examples: vec!["SELECT ME()", "SELECT mass / ME() AS electron_masses"],
63        }
64    }
65
66    fn evaluate(&self, args: &[DataValue]) -> Result<DataValue> {
67        self.validate_args(args)?;
68        Ok(DataValue::Float(9.1093837015e-31))
69    }
70}
71
72impl SqlFunction for MassElectronFunction {
73    fn signature(&self) -> FunctionSignature {
74        FunctionSignature {
75            name: "MASS_ELECTRON",
76            category: FunctionCategory::Constant,
77            arg_count: ArgCount::Fixed(0),
78            description: "Alias for ME() - Returns the mass of an electron in kg",
79            returns: "FLOAT",
80            examples: vec!["SELECT MASS_ELECTRON()"],
81        }
82    }
83
84    fn evaluate(&self, args: &[DataValue]) -> Result<DataValue> {
85        self.validate_args(args)?;
86        Ok(DataValue::Float(9.1093837015e-31))
87    }
88}
89
90#[cfg(test)]
91mod tests {
92    use super::*;
93
94    #[test]
95    fn test_pi_function() {
96        let func = PiFunction;
97        let result = func.evaluate(&[]).unwrap();
98        match result {
99            DataValue::Float(val) => assert!((val - std::f64::consts::PI).abs() < 1e-10),
100            _ => panic!("Expected Float"),
101        }
102    }
103
104    #[test]
105    fn test_pi_with_args_fails() {
106        let func = PiFunction;
107        let result = func.evaluate(&[DataValue::Float(1.0)]);
108        assert!(result.is_err());
109    }
110
111    #[test]
112    fn test_e_function() {
113        let func = EFunction;
114        let result = func.evaluate(&[]).unwrap();
115        match result {
116            DataValue::Float(val) => assert!((val - std::f64::consts::E).abs() < 1e-10),
117            _ => panic!("Expected Float"),
118        }
119    }
120
121    #[test]
122    fn test_me_function() {
123        let func = MeFunction;
124        let result = func.evaluate(&[]).unwrap();
125        match result {
126            DataValue::Float(val) => assert!((val - 9.1093837015e-31).abs() < 1e-40),
127            _ => panic!("Expected Float"),
128        }
129    }
130}