1use crate::orm::annotation::AnnotationValue;
2use serde::{Deserialize, Serialize};
3
4pub trait DatabaseFunction {
6 fn to_sql(&self) -> String;
8 fn function_name(&self) -> &'static str;
10}
11
12#[derive(Debug, Clone, Serialize, Deserialize)]
14pub struct Cast {
15 expression: Box<AnnotationValue>,
16 pub target_type: SqlType,
18}
19
20#[derive(Debug, Clone, Serialize, Deserialize)]
21pub enum SqlType {
23 Integer,
25 BigInt,
27 SmallInt,
29 Float,
31 Real,
33 Double,
35 Decimal {
37 precision: Option<u8>,
39 scale: Option<u8>,
41 },
42 Text,
44 Varchar {
46 length: Option<usize>,
48 },
49 Char {
51 length: usize,
53 },
54 Boolean,
56 Date,
58 Time,
60 Timestamp,
62 Json,
64}
65
66impl SqlType {
67 pub fn to_sql(&self) -> String {
79 match self {
80 SqlType::Integer => "INTEGER".to_string(),
81 SqlType::BigInt => "BIGINT".to_string(),
82 SqlType::SmallInt => "SMALLINT".to_string(),
83 SqlType::Float => "FLOAT".to_string(),
84 SqlType::Real => "REAL".to_string(),
85 SqlType::Double => "DOUBLE PRECISION".to_string(),
86 SqlType::Decimal { precision, scale } => match (precision, scale) {
87 (Some(p), Some(s)) => format!("DECIMAL({}, {})", p, s),
88 (Some(p), None) => format!("DECIMAL({})", p),
89 _ => "DECIMAL".to_string(),
90 },
91 SqlType::Text => "TEXT".to_string(),
92 SqlType::Varchar { length } => {
93 if let Some(len) = length {
94 format!("VARCHAR({})", len)
95 } else {
96 "VARCHAR".to_string()
97 }
98 }
99 SqlType::Char { length } => format!("CHAR({})", length),
100 SqlType::Boolean => "BOOLEAN".to_string(),
101 SqlType::Date => "DATE".to_string(),
102 SqlType::Time => "TIME".to_string(),
103 SqlType::Timestamp => "TIMESTAMP".to_string(),
104 SqlType::Json => "JSON".to_string(),
105 }
106 }
107}
108
109impl Cast {
110 pub fn new(expression: AnnotationValue, target_type: SqlType) -> Self {
126 Self {
127 expression: Box::new(expression),
128 target_type,
129 }
130 }
131
132 pub fn expression(&self) -> &AnnotationValue {
148 &self.expression
149 }
150
151 pub fn into_expression(self) -> AnnotationValue {
167 *self.expression
168 }
169 pub fn to_sql(&self) -> String {
185 format!(
186 "CAST({} AS {})",
187 self.expression.to_sql(),
188 self.target_type.to_sql()
189 )
190 }
191}
192
193#[derive(Debug, Clone, Serialize, Deserialize)]
195pub struct Greatest {
196 pub expressions: Vec<AnnotationValue>,
198}
199
200impl Greatest {
201 pub fn new(expressions: Vec<AnnotationValue>) -> Result<Self, String> {
215 if expressions.len() < 2 {
216 return Err("Greatest must take at least two expressions".to_string());
217 }
218 Ok(Self { expressions })
219 }
220 pub fn to_sql(&self) -> String {
223 let exprs: Vec<String> = self.expressions.iter().map(|e| e.to_sql()).collect();
224 format!("GREATEST({})", exprs.join(", "))
225 }
226}
227
228#[derive(Debug, Clone, Serialize, Deserialize)]
230pub struct Least {
231 pub expressions: Vec<AnnotationValue>,
233}
234
235impl Least {
236 pub fn new(expressions: Vec<AnnotationValue>) -> Result<Self, String> {
250 if expressions.len() < 2 {
251 return Err("Least must take at least two expressions".to_string());
252 }
253 Ok(Self { expressions })
254 }
255 pub fn to_sql(&self) -> String {
258 let exprs: Vec<String> = self.expressions.iter().map(|e| e.to_sql()).collect();
259 format!("LEAST({})", exprs.join(", "))
260 }
261}
262
263#[derive(Debug, Clone, Serialize, Deserialize)]
265pub struct NullIf {
266 expr1: Box<AnnotationValue>,
267 expr2: Box<AnnotationValue>,
268}
269
270impl NullIf {
271 pub fn new(expr1: AnnotationValue, expr2: AnnotationValue) -> Self {
286 Self {
287 expr1: Box::new(expr1),
288 expr2: Box::new(expr2),
289 }
290 }
291 pub fn to_sql(&self) -> String {
294 format!("NULLIF({}, {})", self.expr1.to_sql(), self.expr2.to_sql())
295 }
296
297 pub fn expr1(&self) -> &AnnotationValue {
299 &self.expr1
300 }
301
302 pub fn expr2(&self) -> &AnnotationValue {
304 &self.expr2
305 }
306
307 pub fn into_expr1(self) -> AnnotationValue {
309 *self.expr1
310 }
311
312 pub fn into_expr2(self) -> AnnotationValue {
314 *self.expr2
315 }
316}
317
318#[derive(Debug, Clone, Serialize, Deserialize)]
322pub struct Concat {
323 pub expressions: Vec<AnnotationValue>,
325}
326
327impl Concat {
328 pub fn new(expressions: Vec<AnnotationValue>) -> Result<Self, String> {
345 if expressions.len() < 2 {
346 return Err("Concat must take at least two expressions".to_string());
347 }
348 Ok(Self { expressions })
349 }
350 pub fn to_sql(&self) -> String {
366 let exprs: Vec<String> = self.expressions.iter().map(|e| e.to_sql()).collect();
367 format!("CONCAT({})", exprs.join(", "))
368 }
369}
370
371#[derive(Debug, Clone, Serialize, Deserialize)]
373pub struct Upper {
374 expression: Box<AnnotationValue>,
375}
376
377impl Upper {
378 pub fn new(expression: AnnotationValue) -> Self {
391 Self {
392 expression: Box::new(expression),
393 }
394 }
395 pub fn to_sql(&self) -> String {
408 format!("UPPER({})", self.expression.to_sql())
409 }
410
411 pub fn expression(&self) -> &AnnotationValue {
413 &self.expression
414 }
415
416 pub fn into_expression(self) -> AnnotationValue {
418 *self.expression
419 }
420}
421
422#[derive(Debug, Clone, Serialize, Deserialize)]
424pub struct Lower {
425 expression: Box<AnnotationValue>,
426}
427
428impl Lower {
429 pub fn new(expression: AnnotationValue) -> Self {
442 Self {
443 expression: Box::new(expression),
444 }
445 }
446 pub fn to_sql(&self) -> String {
449 format!("LOWER({})", self.expression.to_sql())
450 }
451
452 pub fn expression(&self) -> &AnnotationValue {
454 &self.expression
455 }
456
457 pub fn into_expression(self) -> AnnotationValue {
459 *self.expression
460 }
461}
462
463#[derive(Debug, Clone, Serialize, Deserialize)]
465pub struct Length {
466 expression: Box<AnnotationValue>,
467}
468
469impl Length {
470 pub fn new(expression: AnnotationValue) -> Self {
483 Self {
484 expression: Box::new(expression),
485 }
486 }
487 pub fn to_sql(&self) -> String {
490 format!("LENGTH({})", self.expression.to_sql())
491 }
492
493 pub fn expression(&self) -> &AnnotationValue {
495 &self.expression
496 }
497
498 pub fn into_expression(self) -> AnnotationValue {
500 *self.expression
501 }
502}
503
504#[derive(Debug, Clone, Serialize, Deserialize)]
506pub struct Trim {
507 expression: Box<AnnotationValue>,
508 pub trim_type: TrimType,
510}
511
512#[derive(Debug, Clone, Serialize, Deserialize)]
513pub enum TrimType {
515 Both,
517 Leading,
519 Trailing,
521}
522
523impl Trim {
524 pub fn new(expression: AnnotationValue) -> Self {
537 Self {
538 expression: Box::new(expression),
539 trim_type: TrimType::Both,
540 }
541 }
542 pub fn leading(mut self) -> Self {
545 self.trim_type = TrimType::Leading;
546 self
547 }
548 pub fn trailing(mut self) -> Self {
551 self.trim_type = TrimType::Trailing;
552 self
553 }
554 pub fn to_sql(&self) -> String {
557 match self.trim_type {
558 TrimType::Both => format!("TRIM({})", self.expression.to_sql()),
559 TrimType::Leading => format!("LTRIM({})", self.expression.to_sql()),
560 TrimType::Trailing => format!("RTRIM({})", self.expression.to_sql()),
561 }
562 }
563
564 pub fn expression(&self) -> &AnnotationValue {
566 &self.expression
567 }
568
569 pub fn into_expression(self) -> AnnotationValue {
571 *self.expression
572 }
573}
574
575#[derive(Debug, Clone, Serialize, Deserialize)]
577pub struct Substr {
578 expression: Box<AnnotationValue>,
579 start: Box<AnnotationValue>,
580 length: Option<Box<AnnotationValue>>,
581}
582
583impl Substr {
584 pub fn new(
601 expression: AnnotationValue,
602 start: AnnotationValue,
603 length: Option<AnnotationValue>,
604 ) -> Self {
605 Self {
606 expression: Box::new(expression),
607 start: Box::new(start),
608 length: length.map(Box::new),
609 }
610 }
611 pub fn to_sql(&self) -> String {
614 if let Some(len) = &self.length {
615 format!(
616 "SUBSTR({}, {}, {})",
617 self.expression.to_sql(),
618 self.start.to_sql(),
619 len.to_sql()
620 )
621 } else {
622 format!(
623 "SUBSTR({}, {})",
624 self.expression.to_sql(),
625 self.start.to_sql()
626 )
627 }
628 }
629
630 pub fn expression(&self) -> &AnnotationValue {
632 &self.expression
633 }
634
635 pub fn start(&self) -> &AnnotationValue {
637 &self.start
638 }
639
640 pub fn length(&self) -> Option<&AnnotationValue> {
642 self.length.as_deref()
643 }
644
645 pub fn into_expression(self) -> AnnotationValue {
647 *self.expression
648 }
649
650 pub fn into_start(self) -> AnnotationValue {
652 *self.start
653 }
654
655 pub fn into_length(self) -> Option<AnnotationValue> {
657 self.length.map(|b| *b)
658 }
659}
660
661#[derive(Debug, Clone, Serialize, Deserialize)]
665pub struct Abs {
666 expression: Box<AnnotationValue>,
667}
668
669impl Abs {
670 pub fn new(expression: AnnotationValue) -> Self {
683 Self {
684 expression: Box::new(expression),
685 }
686 }
687 pub fn to_sql(&self) -> String {
690 format!("ABS({})", self.expression.to_sql())
691 }
692
693 pub fn expression(&self) -> &AnnotationValue {
695 &self.expression
696 }
697
698 pub fn into_expression(self) -> AnnotationValue {
700 *self.expression
701 }
702}
703
704#[derive(Debug, Clone, Serialize, Deserialize)]
706pub struct Ceil {
707 expression: Box<AnnotationValue>,
708}
709
710impl Ceil {
711 pub fn new(expression: AnnotationValue) -> Self {
724 Self {
725 expression: Box::new(expression),
726 }
727 }
728 pub fn to_sql(&self) -> String {
731 format!("CEIL({})", self.expression.to_sql())
732 }
733
734 pub fn expression(&self) -> &AnnotationValue {
736 &self.expression
737 }
738
739 pub fn into_expression(self) -> AnnotationValue {
741 *self.expression
742 }
743}
744
745#[derive(Debug, Clone, Serialize, Deserialize)]
747pub struct Floor {
748 expression: Box<AnnotationValue>,
749}
750
751impl Floor {
752 pub fn new(expression: AnnotationValue) -> Self {
765 Self {
766 expression: Box::new(expression),
767 }
768 }
769 pub fn to_sql(&self) -> String {
772 format!("FLOOR({})", self.expression.to_sql())
773 }
774
775 pub fn expression(&self) -> &AnnotationValue {
777 &self.expression
778 }
779
780 pub fn into_expression(self) -> AnnotationValue {
782 *self.expression
783 }
784}
785
786#[derive(Debug, Clone, Serialize, Deserialize)]
788pub struct Round {
789 expression: Box<AnnotationValue>,
790 pub decimals: Option<i32>,
792}
793
794impl Round {
795 pub fn new(expression: AnnotationValue, decimals: Option<i32>) -> Self {
808 Self {
809 expression: Box::new(expression),
810 decimals,
811 }
812 }
813 pub fn to_sql(&self) -> String {
816 if let Some(d) = self.decimals {
817 format!("ROUND({}, {})", self.expression.to_sql(), d)
818 } else {
819 format!("ROUND({})", self.expression.to_sql())
820 }
821 }
822
823 pub fn expression(&self) -> &AnnotationValue {
825 &self.expression
826 }
827
828 pub fn into_expression(self) -> AnnotationValue {
830 *self.expression
831 }
832}
833
834#[derive(Debug, Clone, Serialize, Deserialize)]
836pub struct Mod {
837 dividend: Box<AnnotationValue>,
838 divisor: Box<AnnotationValue>,
839}
840
841impl Mod {
842 pub fn new(dividend: AnnotationValue, divisor: AnnotationValue) -> Self {
857 Self {
858 dividend: Box::new(dividend),
859 divisor: Box::new(divisor),
860 }
861 }
862 pub fn to_sql(&self) -> String {
865 format!("MOD({}, {})", self.dividend.to_sql(), self.divisor.to_sql())
866 }
867
868 pub fn dividend(&self) -> &AnnotationValue {
870 &self.dividend
871 }
872
873 pub fn divisor(&self) -> &AnnotationValue {
875 &self.divisor
876 }
877
878 pub fn into_dividend(self) -> AnnotationValue {
880 *self.dividend
881 }
882
883 pub fn into_divisor(self) -> AnnotationValue {
885 *self.divisor
886 }
887}
888
889#[derive(Debug, Clone, Serialize, Deserialize)]
891pub struct Power {
892 base: Box<AnnotationValue>,
893 exponent: Box<AnnotationValue>,
894}
895
896impl Power {
897 pub fn new(base: AnnotationValue, exponent: AnnotationValue) -> Self {
912 Self {
913 base: Box::new(base),
914 exponent: Box::new(exponent),
915 }
916 }
917 pub fn to_sql(&self) -> String {
920 format!("POWER({}, {})", self.base.to_sql(), self.exponent.to_sql())
921 }
922
923 pub fn base(&self) -> &AnnotationValue {
925 &self.base
926 }
927
928 pub fn exponent(&self) -> &AnnotationValue {
930 &self.exponent
931 }
932
933 pub fn into_base(self) -> AnnotationValue {
935 *self.base
936 }
937
938 pub fn into_exponent(self) -> AnnotationValue {
940 *self.exponent
941 }
942}
943
944#[derive(Debug, Clone, Serialize, Deserialize)]
946pub struct Sqrt {
947 expression: Box<AnnotationValue>,
948}
949
950impl Sqrt {
951 pub fn new(expression: AnnotationValue) -> Self {
964 Self {
965 expression: Box::new(expression),
966 }
967 }
968 pub fn to_sql(&self) -> String {
971 format!("SQRT({})", self.expression.to_sql())
972 }
973
974 pub fn expression(&self) -> &AnnotationValue {
976 &self.expression
977 }
978
979 pub fn into_expression(self) -> AnnotationValue {
981 *self.expression
982 }
983}
984
985#[derive(Debug, Clone, Serialize, Deserialize)]
989pub struct Extract {
990 expression: Box<AnnotationValue>,
991 pub component: ExtractComponent,
993}
994
995#[derive(Debug, Clone, Serialize, Deserialize)]
996pub enum ExtractComponent {
998 Year,
1000 Month,
1002 Day,
1004 Hour,
1006 Minute,
1008 Second,
1010 Week,
1012 Quarter,
1014 WeekDay,
1016 IsoWeekDay,
1018 IsoYear,
1020}
1021
1022impl ExtractComponent {
1023 pub fn to_sql(&self) -> &'static str {
1026 match self {
1027 ExtractComponent::Year => "YEAR",
1028 ExtractComponent::Month => "MONTH",
1029 ExtractComponent::Day => "DAY",
1030 ExtractComponent::Hour => "HOUR",
1031 ExtractComponent::Minute => "MINUTE",
1032 ExtractComponent::Second => "SECOND",
1033 ExtractComponent::Week => "WEEK",
1034 ExtractComponent::Quarter => "QUARTER",
1035 ExtractComponent::WeekDay => "DOW",
1036 ExtractComponent::IsoWeekDay => "ISODOW",
1037 ExtractComponent::IsoYear => "ISOYEAR",
1038 }
1039 }
1040}
1041
1042impl Extract {
1043 pub fn new(expression: AnnotationValue, component: ExtractComponent) -> Self {
1059 Self {
1060 expression: Box::new(expression),
1061 component,
1062 }
1063 }
1064 pub fn year(expression: AnnotationValue) -> Self {
1077 Self::new(expression, ExtractComponent::Year)
1078 }
1079 pub fn month(expression: AnnotationValue) -> Self {
1092 Self::new(expression, ExtractComponent::Month)
1093 }
1094 pub fn day(expression: AnnotationValue) -> Self {
1107 Self::new(expression, ExtractComponent::Day)
1108 }
1109 pub fn hour(expression: AnnotationValue) -> Self {
1122 Self::new(expression, ExtractComponent::Hour)
1123 }
1124 pub fn minute(expression: AnnotationValue) -> Self {
1137 Self::new(expression, ExtractComponent::Minute)
1138 }
1139 pub fn second(expression: AnnotationValue) -> Self {
1152 Self::new(expression, ExtractComponent::Second)
1153 }
1154 pub fn to_sql(&self) -> String {
1167 format!(
1168 "EXTRACT({} FROM {})",
1169 self.component.to_sql(),
1170 self.expression.to_sql()
1171 )
1172 }
1173
1174 pub fn expression(&self) -> &AnnotationValue {
1176 &self.expression
1177 }
1178
1179 pub fn into_expression(self) -> AnnotationValue {
1181 *self.expression
1182 }
1183}
1184
1185#[derive(Debug, Clone, Serialize, Deserialize)]
1187pub struct Now;
1188
1189impl Now {
1190 pub fn new() -> Self {
1201 Self
1202 }
1203 pub fn to_sql(&self) -> String {
1206 "CURRENT_TIMESTAMP".to_string()
1207 }
1208}
1209
1210impl Default for Now {
1211 fn default() -> Self {
1212 Self::new()
1213 }
1214}
1215
1216#[derive(Debug, Clone, Serialize, Deserialize)]
1218pub struct CurrentDate;
1219
1220impl CurrentDate {
1221 pub fn new() -> Self {
1232 Self
1233 }
1234 pub fn to_sql(&self) -> String {
1237 "CURRENT_DATE".to_string()
1238 }
1239}
1240
1241impl Default for CurrentDate {
1242 fn default() -> Self {
1243 Self::new()
1244 }
1245}
1246
1247#[derive(Debug, Clone, Serialize, Deserialize)]
1249pub struct CurrentTime;
1250
1251impl CurrentTime {
1252 pub fn new() -> Self {
1263 Self
1264 }
1265 pub fn to_sql(&self) -> String {
1268 "CURRENT_TIME".to_string()
1269 }
1270}
1271
1272impl Default for CurrentTime {
1273 fn default() -> Self {
1274 Self::new()
1275 }
1276}
1277
1278#[cfg(test)]
1279mod tests {
1280 use super::*;
1281 use crate::orm::annotation::Value;
1282 use crate::orm::expressions::F;
1283
1284 #[test]
1285 fn test_cast_to_integer() {
1286 let cast = Cast::new(AnnotationValue::Field(F::new("price")), SqlType::Integer);
1287 assert_eq!(cast.to_sql(), "CAST(\"price\" AS INTEGER)");
1288 }
1289
1290 #[test]
1291 fn test_cast_to_varchar() {
1292 let cast = Cast::new(
1293 AnnotationValue::Field(F::new("id")),
1294 SqlType::Varchar { length: Some(50) },
1295 );
1296 assert_eq!(cast.to_sql(), "CAST(\"id\" AS VARCHAR(50))");
1297 }
1298
1299 #[test]
1300 fn test_greatest() {
1301 let greatest = Greatest::new(vec![
1302 AnnotationValue::Field(F::new("price1")),
1303 AnnotationValue::Field(F::new("price2")),
1304 AnnotationValue::Value(Value::Int(100)),
1305 ])
1306 .unwrap();
1307 assert_eq!(greatest.to_sql(), "GREATEST(\"price1\", \"price2\", 100)");
1308 }
1309
1310 #[test]
1311 fn test_least() {
1312 let least = Least::new(vec![
1313 AnnotationValue::Field(F::new("score1")),
1314 AnnotationValue::Field(F::new("score2")),
1315 ])
1316 .unwrap();
1317 assert_eq!(least.to_sql(), "LEAST(\"score1\", \"score2\")");
1318 }
1319
1320 #[test]
1321 fn test_nullif() {
1322 let nullif = NullIf::new(
1323 AnnotationValue::Field(F::new("status")),
1324 AnnotationValue::Value(Value::String("inactive".into())),
1325 );
1326 assert_eq!(nullif.to_sql(), "NULLIF(\"status\", 'inactive')");
1327 }
1328
1329 #[test]
1330 fn test_concat() {
1331 let concat = Concat::new(vec![
1332 AnnotationValue::Field(F::new("first_name")),
1333 AnnotationValue::Value(Value::String(" ".into())),
1334 AnnotationValue::Field(F::new("last_name")),
1335 ])
1336 .unwrap();
1337 assert_eq!(
1338 concat.to_sql(),
1339 "CONCAT(\"first_name\", ' ', \"last_name\")"
1340 );
1341 }
1342
1343 #[test]
1344 fn test_upper() {
1345 let upper = Upper::new(AnnotationValue::Field(F::new("name")));
1346 assert_eq!(upper.to_sql(), "UPPER(\"name\")");
1347 }
1348
1349 #[test]
1350 fn test_lower() {
1351 let lower = Lower::new(AnnotationValue::Field(F::new("email")));
1352 assert_eq!(lower.to_sql(), "LOWER(\"email\")");
1353 }
1354
1355 #[test]
1356 fn test_length() {
1357 let length = Length::new(AnnotationValue::Field(F::new("description")));
1358 assert_eq!(length.to_sql(), "LENGTH(\"description\")");
1359 }
1360
1361 #[test]
1362 fn test_trim() {
1363 let trim = Trim::new(AnnotationValue::Field(F::new("name")));
1364 assert_eq!(trim.to_sql(), "TRIM(\"name\")");
1365 }
1366
1367 #[test]
1368 fn test_trim_leading() {
1369 let trim = Trim::new(AnnotationValue::Field(F::new("name"))).leading();
1370 assert_eq!(trim.to_sql(), "LTRIM(\"name\")");
1371 }
1372
1373 #[test]
1374 fn test_substr() {
1375 let substr = Substr::new(
1376 AnnotationValue::Field(F::new("description")),
1377 AnnotationValue::Value(Value::Int(1)),
1378 Some(AnnotationValue::Value(Value::Int(100))),
1379 );
1380 assert_eq!(substr.to_sql(), "SUBSTR(\"description\", 1, 100)");
1381 }
1382
1383 #[test]
1384 fn test_abs() {
1385 let abs = Abs::new(AnnotationValue::Field(F::new("balance")));
1386 assert_eq!(abs.to_sql(), "ABS(\"balance\")");
1387 }
1388
1389 #[test]
1390 fn test_ceil() {
1391 let ceil = Ceil::new(AnnotationValue::Field(F::new("price")));
1392 assert_eq!(ceil.to_sql(), "CEIL(\"price\")");
1393 }
1394
1395 #[test]
1396 fn test_floor() {
1397 let floor = Floor::new(AnnotationValue::Field(F::new("score")));
1398 assert_eq!(floor.to_sql(), "FLOOR(\"score\")");
1399 }
1400
1401 #[test]
1402 fn test_round() {
1403 let round = Round::new(AnnotationValue::Field(F::new("price")), Some(2));
1404 assert_eq!(round.to_sql(), "ROUND(\"price\", 2)");
1405 }
1406
1407 #[test]
1408 fn test_mod() {
1409 let mod_op = Mod::new(
1410 AnnotationValue::Field(F::new("value")),
1411 AnnotationValue::Value(Value::Int(10)),
1412 );
1413 assert_eq!(mod_op.to_sql(), "MOD(\"value\", 10)");
1414 }
1415
1416 #[test]
1417 fn test_power() {
1418 let power = Power::new(
1419 AnnotationValue::Field(F::new("base")),
1420 AnnotationValue::Value(Value::Int(2)),
1421 );
1422 assert_eq!(power.to_sql(), "POWER(\"base\", 2)");
1423 }
1424
1425 #[test]
1426 fn test_sqrt() {
1427 let sqrt = Sqrt::new(AnnotationValue::Field(F::new("area")));
1428 assert_eq!(sqrt.to_sql(), "SQRT(\"area\")");
1429 }
1430
1431 #[test]
1432 fn test_greatest_minimum_expressions() {
1433 let result = Greatest::new(vec![AnnotationValue::Field(F::new("x"))]);
1434 assert!(result.is_err());
1435 }
1436
1437 #[test]
1438 fn test_least_minimum_expressions() {
1439 let result = Least::new(vec![AnnotationValue::Field(F::new("x"))]);
1440 assert!(result.is_err());
1441 }
1442
1443 #[test]
1444 fn test_concat_minimum_expressions() {
1445 let result = Concat::new(vec![AnnotationValue::Field(F::new("x"))]);
1446 assert!(result.is_err());
1447 }
1448
1449 #[test]
1450 fn test_extract_year() {
1451 let extract = Extract::year(AnnotationValue::Field(F::new("created_at")));
1452 assert_eq!(extract.to_sql(), "EXTRACT(YEAR FROM \"created_at\")");
1453 }
1454
1455 #[test]
1456 fn test_extract_month() {
1457 let extract = Extract::month(AnnotationValue::Field(F::new("order_date")));
1458 assert_eq!(extract.to_sql(), "EXTRACT(MONTH FROM \"order_date\")");
1459 }
1460
1461 #[test]
1462 fn test_extract_day() {
1463 let extract = Extract::day(AnnotationValue::Field(F::new("timestamp")));
1464 assert_eq!(extract.to_sql(), "EXTRACT(DAY FROM \"timestamp\")");
1465 }
1466
1467 #[test]
1468 fn test_extract_hour() {
1469 let extract = Extract::hour(AnnotationValue::Field(F::new("event_time")));
1470 assert_eq!(extract.to_sql(), "EXTRACT(HOUR FROM \"event_time\")");
1471 }
1472
1473 #[test]
1474 fn test_orm_functions_now() {
1475 let now = Now::new();
1476 assert_eq!(now.to_sql(), "CURRENT_TIMESTAMP");
1477 }
1478
1479 #[test]
1480 fn test_current_date() {
1481 let date = CurrentDate::new();
1482 assert_eq!(date.to_sql(), "CURRENT_DATE");
1483 }
1484
1485 #[test]
1486 fn test_current_time() {
1487 let time = CurrentTime::new();
1488 assert_eq!(time.to_sql(), "CURRENT_TIME");
1489 }
1490}