1use anyhow::Result;
2
3use super::{ArgCount, FunctionCategory, FunctionSignature, SqlFunction};
4use crate::data::datatable::DataValue;
5
6pub struct MassEarthFunction;
10
11impl SqlFunction for MassEarthFunction {
12 fn signature(&self) -> FunctionSignature {
13 FunctionSignature {
14 name: "MASS_EARTH",
15 category: FunctionCategory::Astronomical,
16 arg_count: ArgCount::Fixed(0),
17 description: "Returns Earth's mass in kg (5.972 × 10^24)",
18 returns: "FLOAT",
19 examples: vec![
20 "SELECT MASS_EARTH()",
21 "SELECT asteroid_mass / MASS_EARTH() AS earth_masses",
22 ],
23 }
24 }
25
26 fn evaluate(&self, args: &[DataValue]) -> Result<DataValue> {
27 self.validate_args(args)?;
28 Ok(DataValue::Float(5.972e24))
29 }
30}
31
32pub struct MassSunFunction;
34
35impl SqlFunction for MassSunFunction {
36 fn signature(&self) -> FunctionSignature {
37 FunctionSignature {
38 name: "MASS_SUN",
39 category: FunctionCategory::Astronomical,
40 arg_count: ArgCount::Fixed(0),
41 description: "Returns the Sun's mass in kg (1.989 × 10^30)",
42 returns: "FLOAT",
43 examples: vec![
44 "SELECT MASS_SUN()",
45 "SELECT star_mass / MASS_SUN() AS solar_masses",
46 ],
47 }
48 }
49
50 fn evaluate(&self, args: &[DataValue]) -> Result<DataValue> {
51 self.validate_args(args)?;
52 Ok(DataValue::Float(1.989e30))
53 }
54}
55
56pub struct MassMoonFunction;
58
59impl SqlFunction for MassMoonFunction {
60 fn signature(&self) -> FunctionSignature {
61 FunctionSignature {
62 name: "MASS_MOON",
63 category: FunctionCategory::Astronomical,
64 arg_count: ArgCount::Fixed(0),
65 description: "Returns the Moon's mass in kg (7.342 × 10^22)",
66 returns: "FLOAT",
67 examples: vec![
68 "SELECT MASS_MOON()",
69 "SELECT satellite_mass / MASS_MOON() AS lunar_masses",
70 ],
71 }
72 }
73
74 fn evaluate(&self, args: &[DataValue]) -> Result<DataValue> {
75 self.validate_args(args)?;
76 Ok(DataValue::Float(7.342e22))
77 }
78}
79
80pub struct MassMercuryFunction;
84
85impl SqlFunction for MassMercuryFunction {
86 fn signature(&self) -> FunctionSignature {
87 FunctionSignature {
88 name: "MASS_MERCURY",
89 category: FunctionCategory::Astronomical,
90 arg_count: ArgCount::Fixed(0),
91 description: "Returns Mercury's mass in kg (3.301 × 10^23)",
92 returns: "FLOAT",
93 examples: vec!["SELECT MASS_MERCURY()"],
94 }
95 }
96
97 fn evaluate(&self, args: &[DataValue]) -> Result<DataValue> {
98 self.validate_args(args)?;
99 Ok(DataValue::Float(3.301e23))
100 }
101}
102
103pub struct MassVenusFunction;
105
106impl SqlFunction for MassVenusFunction {
107 fn signature(&self) -> FunctionSignature {
108 FunctionSignature {
109 name: "MASS_VENUS",
110 category: FunctionCategory::Astronomical,
111 arg_count: ArgCount::Fixed(0),
112 description: "Returns Venus's mass in kg (4.867 × 10^24)",
113 returns: "FLOAT",
114 examples: vec!["SELECT MASS_VENUS()"],
115 }
116 }
117
118 fn evaluate(&self, args: &[DataValue]) -> Result<DataValue> {
119 self.validate_args(args)?;
120 Ok(DataValue::Float(4.867e24))
121 }
122}
123
124pub struct MassMarsFunction;
126
127impl SqlFunction for MassMarsFunction {
128 fn signature(&self) -> FunctionSignature {
129 FunctionSignature {
130 name: "MASS_MARS",
131 category: FunctionCategory::Astronomical,
132 arg_count: ArgCount::Fixed(0),
133 description: "Returns Mars's mass in kg (6.417 × 10^23)",
134 returns: "FLOAT",
135 examples: vec!["SELECT MASS_MARS()"],
136 }
137 }
138
139 fn evaluate(&self, args: &[DataValue]) -> Result<DataValue> {
140 self.validate_args(args)?;
141 Ok(DataValue::Float(6.417e23))
142 }
143}
144
145pub struct MassJupiterFunction;
147
148impl SqlFunction for MassJupiterFunction {
149 fn signature(&self) -> FunctionSignature {
150 FunctionSignature {
151 name: "MASS_JUPITER",
152 category: FunctionCategory::Astronomical,
153 arg_count: ArgCount::Fixed(0),
154 description: "Returns Jupiter's mass in kg (1.898 × 10^27)",
155 returns: "FLOAT",
156 examples: vec![
157 "SELECT MASS_JUPITER()",
158 "SELECT exoplanet_mass / MASS_JUPITER() AS jupiter_masses",
159 ],
160 }
161 }
162
163 fn evaluate(&self, args: &[DataValue]) -> Result<DataValue> {
164 self.validate_args(args)?;
165 Ok(DataValue::Float(1.898e27))
166 }
167}
168
169pub struct MassSaturnFunction;
171
172impl SqlFunction for MassSaturnFunction {
173 fn signature(&self) -> FunctionSignature {
174 FunctionSignature {
175 name: "MASS_SATURN",
176 category: FunctionCategory::Astronomical,
177 arg_count: ArgCount::Fixed(0),
178 description: "Returns Saturn's mass in kg (5.683 × 10^26)",
179 returns: "FLOAT",
180 examples: vec!["SELECT MASS_SATURN()"],
181 }
182 }
183
184 fn evaluate(&self, args: &[DataValue]) -> Result<DataValue> {
185 self.validate_args(args)?;
186 Ok(DataValue::Float(5.683e26))
187 }
188}
189
190pub struct MassUranusFunction;
192
193impl SqlFunction for MassUranusFunction {
194 fn signature(&self) -> FunctionSignature {
195 FunctionSignature {
196 name: "MASS_URANUS",
197 category: FunctionCategory::Astronomical,
198 arg_count: ArgCount::Fixed(0),
199 description: "Returns Uranus's mass in kg (8.681 × 10^25)",
200 returns: "FLOAT",
201 examples: vec!["SELECT MASS_URANUS()"],
202 }
203 }
204
205 fn evaluate(&self, args: &[DataValue]) -> Result<DataValue> {
206 self.validate_args(args)?;
207 Ok(DataValue::Float(8.681e25))
208 }
209}
210
211pub struct MassNeptuneFunction;
213
214impl SqlFunction for MassNeptuneFunction {
215 fn signature(&self) -> FunctionSignature {
216 FunctionSignature {
217 name: "MASS_NEPTUNE",
218 category: FunctionCategory::Astronomical,
219 arg_count: ArgCount::Fixed(0),
220 description: "Returns Neptune's mass in kg (1.024 × 10^26)",
221 returns: "FLOAT",
222 examples: vec!["SELECT MASS_NEPTUNE()"],
223 }
224 }
225
226 fn evaluate(&self, args: &[DataValue]) -> Result<DataValue> {
227 self.validate_args(args)?;
228 Ok(DataValue::Float(1.024e26))
229 }
230}
231
232pub struct RadiusSunFunction;
236
237impl SqlFunction for RadiusSunFunction {
238 fn signature(&self) -> FunctionSignature {
239 FunctionSignature {
240 name: "RADIUS_SUN",
241 category: FunctionCategory::Astronomical,
242 arg_count: ArgCount::Fixed(0),
243 description: "Returns the Sun's radius in meters (6.96 × 10^8)",
244 returns: "FLOAT",
245 examples: vec![
246 "SELECT RADIUS_SUN()",
247 "SELECT star_radius / RADIUS_SUN() AS solar_radii",
248 ],
249 }
250 }
251
252 fn evaluate(&self, args: &[DataValue]) -> Result<DataValue> {
253 self.validate_args(args)?;
254 Ok(DataValue::Float(6.96e8))
255 }
256}
257
258pub struct RadiusEarthFunction;
260
261impl SqlFunction for RadiusEarthFunction {
262 fn signature(&self) -> FunctionSignature {
263 FunctionSignature {
264 name: "RADIUS_EARTH",
265 category: FunctionCategory::Astronomical,
266 arg_count: ArgCount::Fixed(0),
267 description: "Returns Earth's radius in meters (6.371 × 10^6)",
268 returns: "FLOAT",
269 examples: vec![
270 "SELECT RADIUS_EARTH()",
271 "SELECT planet_radius / RADIUS_EARTH() AS earth_radii",
272 ],
273 }
274 }
275
276 fn evaluate(&self, args: &[DataValue]) -> Result<DataValue> {
277 self.validate_args(args)?;
278 Ok(DataValue::Float(6.371e6))
279 }
280}
281
282pub struct RadiusMoonFunction;
284
285impl SqlFunction for RadiusMoonFunction {
286 fn signature(&self) -> FunctionSignature {
287 FunctionSignature {
288 name: "RADIUS_MOON",
289 category: FunctionCategory::Astronomical,
290 arg_count: ArgCount::Fixed(0),
291 description: "Returns the Moon's radius in meters (1.737 × 10^6)",
292 returns: "FLOAT",
293 examples: vec![
294 "SELECT RADIUS_MOON()",
295 "SELECT satellite_radius / RADIUS_MOON() AS lunar_radii",
296 ],
297 }
298 }
299
300 fn evaluate(&self, args: &[DataValue]) -> Result<DataValue> {
301 self.validate_args(args)?;
302 Ok(DataValue::Float(1.737e6))
303 }
304}
305
306pub struct RadiusMercuryFunction;
308
309impl SqlFunction for RadiusMercuryFunction {
310 fn signature(&self) -> FunctionSignature {
311 FunctionSignature {
312 name: "RADIUS_MERCURY",
313 category: FunctionCategory::Astronomical,
314 arg_count: ArgCount::Fixed(0),
315 description: "Returns Mercury's radius in meters (2.440 × 10^6)",
316 returns: "FLOAT",
317 examples: vec!["SELECT RADIUS_MERCURY()"],
318 }
319 }
320
321 fn evaluate(&self, args: &[DataValue]) -> Result<DataValue> {
322 self.validate_args(args)?;
323 Ok(DataValue::Float(2.440e6))
324 }
325}
326
327pub struct RadiusVenusFunction;
329
330impl SqlFunction for RadiusVenusFunction {
331 fn signature(&self) -> FunctionSignature {
332 FunctionSignature {
333 name: "RADIUS_VENUS",
334 category: FunctionCategory::Astronomical,
335 arg_count: ArgCount::Fixed(0),
336 description: "Returns Venus's radius in meters (6.052 × 10^6)",
337 returns: "FLOAT",
338 examples: vec!["SELECT RADIUS_VENUS()"],
339 }
340 }
341
342 fn evaluate(&self, args: &[DataValue]) -> Result<DataValue> {
343 self.validate_args(args)?;
344 Ok(DataValue::Float(6.052e6))
345 }
346}
347
348pub struct RadiusMarsFunction;
350
351impl SqlFunction for RadiusMarsFunction {
352 fn signature(&self) -> FunctionSignature {
353 FunctionSignature {
354 name: "RADIUS_MARS",
355 category: FunctionCategory::Astronomical,
356 arg_count: ArgCount::Fixed(0),
357 description: "Returns Mars's radius in meters (3.390 × 10^6)",
358 returns: "FLOAT",
359 examples: vec!["SELECT RADIUS_MARS()"],
360 }
361 }
362
363 fn evaluate(&self, args: &[DataValue]) -> Result<DataValue> {
364 self.validate_args(args)?;
365 Ok(DataValue::Float(3.390e6))
366 }
367}
368
369pub struct RadiusJupiterFunction;
371
372impl SqlFunction for RadiusJupiterFunction {
373 fn signature(&self) -> FunctionSignature {
374 FunctionSignature {
375 name: "RADIUS_JUPITER",
376 category: FunctionCategory::Astronomical,
377 arg_count: ArgCount::Fixed(0),
378 description: "Returns Jupiter's radius in meters (6.991 × 10^7)",
379 returns: "FLOAT",
380 examples: vec![
381 "SELECT RADIUS_JUPITER()",
382 "SELECT exoplanet_radius / RADIUS_JUPITER() AS jupiter_radii",
383 ],
384 }
385 }
386
387 fn evaluate(&self, args: &[DataValue]) -> Result<DataValue> {
388 self.validate_args(args)?;
389 Ok(DataValue::Float(6.991e7))
390 }
391}
392
393pub struct RadiusSaturnFunction;
395
396impl SqlFunction for RadiusSaturnFunction {
397 fn signature(&self) -> FunctionSignature {
398 FunctionSignature {
399 name: "RADIUS_SATURN",
400 category: FunctionCategory::Astronomical,
401 arg_count: ArgCount::Fixed(0),
402 description: "Returns Saturn's radius in meters (5.823 × 10^7)",
403 returns: "FLOAT",
404 examples: vec!["SELECT RADIUS_SATURN()"],
405 }
406 }
407
408 fn evaluate(&self, args: &[DataValue]) -> Result<DataValue> {
409 self.validate_args(args)?;
410 Ok(DataValue::Float(5.823e7))
411 }
412}
413
414pub struct RadiusUranusFunction;
416
417impl SqlFunction for RadiusUranusFunction {
418 fn signature(&self) -> FunctionSignature {
419 FunctionSignature {
420 name: "RADIUS_URANUS",
421 category: FunctionCategory::Astronomical,
422 arg_count: ArgCount::Fixed(0),
423 description: "Returns Uranus's radius in meters (2.536 × 10^7)",
424 returns: "FLOAT",
425 examples: vec!["SELECT RADIUS_URANUS()"],
426 }
427 }
428
429 fn evaluate(&self, args: &[DataValue]) -> Result<DataValue> {
430 self.validate_args(args)?;
431 Ok(DataValue::Float(2.536e7))
432 }
433}
434
435pub struct RadiusNeptuneFunction;
437
438impl SqlFunction for RadiusNeptuneFunction {
439 fn signature(&self) -> FunctionSignature {
440 FunctionSignature {
441 name: "RADIUS_NEPTUNE",
442 category: FunctionCategory::Astronomical,
443 arg_count: ArgCount::Fixed(0),
444 description: "Returns Neptune's radius in meters (2.462 × 10^7)",
445 returns: "FLOAT",
446 examples: vec!["SELECT RADIUS_NEPTUNE()"],
447 }
448 }
449
450 fn evaluate(&self, args: &[DataValue]) -> Result<DataValue> {
451 self.validate_args(args)?;
452 Ok(DataValue::Float(2.462e7))
453 }
454}
455
456pub struct AuFunction;
460
461impl SqlFunction for AuFunction {
462 fn signature(&self) -> FunctionSignature {
463 FunctionSignature {
464 name: "AU",
465 category: FunctionCategory::Astronomical,
466 arg_count: ArgCount::Fixed(0),
467 description: "Returns one Astronomical Unit in meters (1.496 × 10^11)",
468 returns: "FLOAT",
469 examples: vec!["SELECT AU()", "SELECT distance_m / AU() AS distance_au"],
470 }
471 }
472
473 fn evaluate(&self, args: &[DataValue]) -> Result<DataValue> {
474 self.validate_args(args)?;
475 Ok(DataValue::Float(1.496e11))
476 }
477}
478
479pub struct LightYearFunction;
481
482impl SqlFunction for LightYearFunction {
483 fn signature(&self) -> FunctionSignature {
484 FunctionSignature {
485 name: "LIGHT_YEAR",
486 category: FunctionCategory::Astronomical,
487 arg_count: ArgCount::Fixed(0),
488 description: "Returns one light year in meters (9.461 × 10^15)",
489 returns: "FLOAT",
490 examples: vec![
491 "SELECT LIGHT_YEAR()",
492 "SELECT star_distance / LIGHT_YEAR() AS distance_ly",
493 ],
494 }
495 }
496
497 fn evaluate(&self, args: &[DataValue]) -> Result<DataValue> {
498 self.validate_args(args)?;
499 Ok(DataValue::Float(9.461e15))
500 }
501}
502
503pub struct ParsecFunction;
505
506impl SqlFunction for ParsecFunction {
507 fn signature(&self) -> FunctionSignature {
508 FunctionSignature {
509 name: "PARSEC",
510 category: FunctionCategory::Astronomical,
511 arg_count: ArgCount::Fixed(0),
512 description: "Returns one parsec in meters (3.086 × 10^16)",
513 returns: "FLOAT",
514 examples: vec![
515 "SELECT PARSEC()",
516 "SELECT galaxy_distance / PARSEC() AS distance_pc",
517 ],
518 }
519 }
520
521 fn evaluate(&self, args: &[DataValue]) -> Result<DataValue> {
522 self.validate_args(args)?;
523 Ok(DataValue::Float(3.086e16))
524 }
525}
526
527#[cfg(test)]
528mod tests {
529 use super::*;
530
531 #[test]
532 fn test_mass_earth() {
533 let func = MassEarthFunction;
534 let result = func.evaluate(&[]).unwrap();
535 match result {
536 DataValue::Float(val) => assert_eq!(val, 5.972e24),
537 _ => panic!("Expected Float"),
538 }
539 }
540
541 #[test]
542 fn test_mass_sun() {
543 let func = MassSunFunction;
544 let result = func.evaluate(&[]).unwrap();
545 match result {
546 DataValue::Float(val) => assert_eq!(val, 1.989e30),
547 _ => panic!("Expected Float"),
548 }
549 }
550
551 #[test]
552 fn test_au() {
553 let func = AuFunction;
554 let result = func.evaluate(&[]).unwrap();
555 match result {
556 DataValue::Float(val) => assert_eq!(val, 1.496e11),
557 _ => panic!("Expected Float"),
558 }
559 }
560
561 #[test]
562 fn test_light_year() {
563 let func = LightYearFunction;
564 let result = func.evaluate(&[]).unwrap();
565 match result {
566 DataValue::Float(val) => assert_eq!(val, 9.461e15),
567 _ => panic!("Expected Float"),
568 }
569 }
570}