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
51impl SqlFunction for MeFunction {
52    fn signature(&self) -> FunctionSignature {
53        FunctionSignature {
54            name: "ME",
55            category: FunctionCategory::Constant,
56            arg_count: ArgCount::Fixed(0),
57            description: "Returns the mass of an electron in kg (9.10938356 × 10^-31)",
58            returns: "FLOAT",
59            examples: vec!["SELECT ME()", "SELECT mass / ME() AS electron_masses"],
60        }
61    }
62
63    fn evaluate(&self, args: &[DataValue]) -> Result<DataValue> {
64        self.validate_args(args)?;
65        Ok(DataValue::Float(9.10938356e-31))
66    }
67}
68
69#[cfg(test)]
70mod tests {
71    use super::*;
72
73    #[test]
74    fn test_pi_function() {
75        let func = PiFunction;
76        let result = func.evaluate(&[]).unwrap();
77        match result {
78            DataValue::Float(val) => assert!((val - std::f64::consts::PI).abs() < 1e-10),
79            _ => panic!("Expected Float"),
80        }
81    }
82
83    #[test]
84    fn test_pi_with_args_fails() {
85        let func = PiFunction;
86        let result = func.evaluate(&[DataValue::Float(1.0)]);
87        assert!(result.is_err());
88    }
89
90    #[test]
91    fn test_e_function() {
92        let func = EFunction;
93        let result = func.evaluate(&[]).unwrap();
94        match result {
95            DataValue::Float(val) => assert!((val - std::f64::consts::E).abs() < 1e-10),
96            _ => panic!("Expected Float"),
97        }
98    }
99
100    #[test]
101    fn test_me_function() {
102        let func = MeFunction;
103        let result = func.evaluate(&[]).unwrap();
104        match result {
105            DataValue::Float(val) => assert!((val - 9.10938356e-31).abs() < 1e-40),
106            _ => panic!("Expected Float"),
107        }
108    }
109}