Skip to content

Commit 2d46b69

Browse files
authored
feat: support type TimeStamp (#271)
* feat: TimeStamp types that support precision and time zones, as well as conversion of related types, are implemented. Added precision support for the Time type. current_timestamp function added * Added tests on time32 and time64 operators * Corrected a mistake
1 parent 1af504a commit 2d46b69

File tree

14 files changed

+1133
-67
lines changed

14 files changed

+1133
-67
lines changed

docs/features.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ let kite_sql = DataBaseBuilder::path("./data")
133133
- Right
134134
- Full
135135
- Cross (Natural\Using)
136+
- [x] Exists
136137
- [x] Group By
137138
- [x] Having
138139
- [x] Order By
@@ -170,4 +171,5 @@ let kite_sql = DataBaseBuilder::path("./data")
170171
- Date
171172
- DateTime
172173
- Time
174+
- TimeStamp
173175
- Tuple

src/db.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use crate::expression::function::table::TableFunctionImpl;
66
use crate::expression::function::FunctionSummary;
77
use crate::function::char_length::CharLength;
88
use crate::function::current_date::CurrentDate;
9+
use crate::function::current_timestamp::CurrentTimeStamp;
910
use crate::function::lower::Lower;
1011
use crate::function::numbers::Numbers;
1112
use crate::function::octet_length::OctetLength;
@@ -61,6 +62,7 @@ impl DataBaseBuilder {
6162
builder =
6263
builder.register_scala_function(CharLength::new("character_length".to_lowercase()));
6364
builder = builder.register_scala_function(CurrentDate::new());
65+
builder = builder.register_scala_function(CurrentTimeStamp::new());
6466
builder = builder.register_scala_function(Lower::new());
6567
builder = builder.register_scala_function(OctetLength::new());
6668
builder = builder.register_scala_function(Upper::new());

src/function/current_timestamp.rs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
use crate::catalog::ColumnRef;
2+
use crate::errors::DatabaseError;
3+
use crate::expression::function::scala::FuncMonotonicity;
4+
use crate::expression::function::scala::ScalarFunctionImpl;
5+
use crate::expression::function::FunctionSummary;
6+
use crate::expression::ScalarExpression;
7+
use crate::types::tuple::Tuple;
8+
use crate::types::value::DataValue;
9+
use crate::types::LogicalType;
10+
use chrono::Utc;
11+
use serde::Deserialize;
12+
use serde::Serialize;
13+
use std::sync::Arc;
14+
15+
#[derive(Debug, Serialize, Deserialize)]
16+
pub(crate) struct CurrentTimeStamp {
17+
summary: FunctionSummary,
18+
}
19+
20+
impl CurrentTimeStamp {
21+
#[allow(unused_mut)]
22+
pub(crate) fn new() -> Arc<Self> {
23+
let function_name = "current_timestamp".to_lowercase();
24+
25+
Arc::new(Self {
26+
summary: FunctionSummary {
27+
name: function_name,
28+
arg_types: Vec::new(),
29+
},
30+
})
31+
}
32+
}
33+
34+
#[typetag::serde]
35+
impl ScalarFunctionImpl for CurrentTimeStamp {
36+
#[allow(unused_variables, clippy::redundant_closure_call)]
37+
fn eval(
38+
&self,
39+
_: &[ScalarExpression],
40+
_: Option<(&Tuple, &[ColumnRef])>,
41+
) -> Result<DataValue, DatabaseError> {
42+
Ok(DataValue::Time64(Utc::now().timestamp(), 0, false))
43+
}
44+
45+
fn monotonicity(&self) -> Option<FuncMonotonicity> {
46+
todo!()
47+
}
48+
49+
fn return_type(&self) -> &LogicalType {
50+
&LogicalType::TimeStamp(None, false)
51+
}
52+
53+
fn summary(&self) -> &FunctionSummary {
54+
&self.summary
55+
}
56+
}

src/function/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
pub(crate) mod char_length;
22
pub(crate) mod current_date;
3+
pub(crate) mod current_timestamp;
34
pub(crate) mod lower;
45
pub(crate) mod numbers;
56
pub(crate) mod octet_length;

src/optimizer/core/histogram.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -329,14 +329,20 @@ impl Histogram {
329329
}
330330
_ => unreachable!(),
331331
},
332-
LogicalType::Date | LogicalType::DateTime | LogicalType::Time => match value {
332+
LogicalType::Date
333+
| LogicalType::DateTime
334+
| LogicalType::Time(_, _)
335+
| LogicalType::TimeStamp(_, _) => match value {
333336
DataValue::Date32(value) => DataValue::Int32(*value)
334337
.cast(&LogicalType::Double)?
335338
.double(),
336339
DataValue::Date64(value) => DataValue::Int64(*value)
337340
.cast(&LogicalType::Double)?
338341
.double(),
339-
DataValue::Time(value) => DataValue::UInt32(*value)
342+
DataValue::Time32(value, ..) => DataValue::UInt32(*value)
343+
.cast(&LogicalType::Double)?
344+
.double(),
345+
DataValue::Time64(value, ..) => DataValue::Int64(*value)
340346
.cast(&LogicalType::Double)?
341347
.double(),
342348
_ => unreachable!(),

src/types/evaluator/mod.rs

Lines changed: 184 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ pub mod int32;
99
pub mod int64;
1010
pub mod int8;
1111
pub mod null;
12-
pub mod time;
12+
pub mod time32;
13+
pub mod time64;
1314
pub mod tuple;
1415
pub mod uint16;
1516
pub mod uint32;
@@ -30,7 +31,8 @@ use crate::types::evaluator::int32::*;
3031
use crate::types::evaluator::int64::*;
3132
use crate::types::evaluator::int8::*;
3233
use crate::types::evaluator::null::NullBinaryEvaluator;
33-
use crate::types::evaluator::time::*;
34+
use crate::types::evaluator::time32::*;
35+
use crate::types::evaluator::time64::*;
3436
use crate::types::evaluator::tuple::{
3537
TupleEqBinaryEvaluator, TupleGtBinaryEvaluator, TupleGtEqBinaryEvaluator,
3638
TupleLtBinaryEvaluator, TupleLtEqBinaryEvaluator, TupleNotEqBinaryEvaluator,
@@ -191,7 +193,28 @@ impl EvaluatorFactory {
191193
LogicalType::Double => numeric_binary_evaluator!(Float64, op, LogicalType::Double),
192194
LogicalType::Date => numeric_binary_evaluator!(Date, op, LogicalType::Date),
193195
LogicalType::DateTime => numeric_binary_evaluator!(DateTime, op, LogicalType::DateTime),
194-
LogicalType::Time => numeric_binary_evaluator!(Time, op, LogicalType::Time),
196+
LogicalType::Time(_, _) => match op {
197+
BinaryOperator::Plus => Ok(BinaryEvaluatorBox(Arc::new(TimePlusBinaryEvaluator))),
198+
BinaryOperator::Minus => Ok(BinaryEvaluatorBox(Arc::new(TimeMinusBinaryEvaluator))),
199+
BinaryOperator::Gt => Ok(BinaryEvaluatorBox(Arc::new(TimeGtBinaryEvaluator))),
200+
BinaryOperator::GtEq => Ok(BinaryEvaluatorBox(Arc::new(TimeGtEqBinaryEvaluator))),
201+
BinaryOperator::Lt => Ok(BinaryEvaluatorBox(Arc::new(TimeLtBinaryEvaluator))),
202+
BinaryOperator::LtEq => Ok(BinaryEvaluatorBox(Arc::new(TimeLtEqBinaryEvaluator))),
203+
BinaryOperator::Eq => Ok(BinaryEvaluatorBox(Arc::new(TimeEqBinaryEvaluator))),
204+
BinaryOperator::NotEq => Ok(BinaryEvaluatorBox(Arc::new(TimeNotEqBinaryEvaluator))),
205+
_ => Err(DatabaseError::UnsupportedBinaryOperator(ty, op)),
206+
},
207+
LogicalType::TimeStamp(_, _) => match op {
208+
BinaryOperator::Gt => Ok(BinaryEvaluatorBox(Arc::new(Time64GtBinaryEvaluator))),
209+
BinaryOperator::GtEq => Ok(BinaryEvaluatorBox(Arc::new(Time64GtEqBinaryEvaluator))),
210+
BinaryOperator::Lt => Ok(BinaryEvaluatorBox(Arc::new(Time64LtBinaryEvaluator))),
211+
BinaryOperator::LtEq => Ok(BinaryEvaluatorBox(Arc::new(Time64LtEqBinaryEvaluator))),
212+
BinaryOperator::Eq => Ok(BinaryEvaluatorBox(Arc::new(Time64EqBinaryEvaluator))),
213+
BinaryOperator::NotEq => {
214+
Ok(BinaryEvaluatorBox(Arc::new(Time64NotEqBinaryEvaluator)))
215+
}
216+
_ => Err(DatabaseError::UnsupportedBinaryOperator(ty, op)),
217+
},
195218
LogicalType::Decimal(_, _) => numeric_binary_evaluator!(Decimal, op, ty),
196219
LogicalType::Boolean => match op {
197220
BinaryOperator::And => Ok(BinaryEvaluatorBox(Arc::new(BooleanAndBinaryEvaluator))),
@@ -1032,6 +1055,164 @@ mod test {
10321055
Ok(())
10331056
}
10341057

1058+
#[test]
1059+
fn test_binary_op_time32_and_time64() -> Result<(), DatabaseError> {
1060+
let evaluator_time32 =
1061+
EvaluatorFactory::binary_create(LogicalType::Time(None, false), BinaryOperator::Plus)?;
1062+
assert_eq!(
1063+
evaluator_time32.0.binary_eval(
1064+
&DataValue::Time32(4190119896, 3, false),
1065+
&DataValue::Time32(2621204256, 4, false),
1066+
),
1067+
DataValue::Time32(2618593017, 4, false)
1068+
);
1069+
assert_eq!(
1070+
evaluator_time32.0.binary_eval(
1071+
&DataValue::Time32(4190175696, 3, false),
1072+
&DataValue::Time32(2621224256, 4, false),
1073+
),
1074+
DataValue::Null
1075+
);
1076+
1077+
let evaluator_time32 =
1078+
EvaluatorFactory::binary_create(LogicalType::Time(None, false), BinaryOperator::Minus)?;
1079+
assert_eq!(
1080+
evaluator_time32.0.binary_eval(
1081+
&DataValue::Time32(4190119896, 3, false),
1082+
&DataValue::Time32(2621204256, 4, false),
1083+
),
1084+
DataValue::Null
1085+
);
1086+
assert_eq!(
1087+
evaluator_time32.0.binary_eval(
1088+
&DataValue::Time32(2621204256, 4, false),
1089+
&DataValue::Time32(4190119896, 3, false),
1090+
),
1091+
DataValue::Time32(2375496, 4, false)
1092+
);
1093+
1094+
let evaluator_time32 =
1095+
EvaluatorFactory::binary_create(LogicalType::Time(None, false), BinaryOperator::Gt)?;
1096+
let evaluator_time64 = EvaluatorFactory::binary_create(
1097+
LogicalType::TimeStamp(None, false),
1098+
BinaryOperator::Gt,
1099+
)?;
1100+
assert_eq!(
1101+
evaluator_time32.0.binary_eval(
1102+
&DataValue::Time32(2621204256, 4, false),
1103+
&DataValue::Time32(4190119896, 3, false),
1104+
),
1105+
DataValue::Boolean(true)
1106+
);
1107+
assert_eq!(
1108+
evaluator_time32.0.binary_eval(
1109+
&DataValue::Time32(4190119896, 3, false),
1110+
&DataValue::Time32(2621204256, 4, false),
1111+
),
1112+
DataValue::Boolean(false)
1113+
);
1114+
assert_eq!(
1115+
evaluator_time64.0.binary_eval(
1116+
&DataValue::Time64(1736055775154814, 6, false),
1117+
&DataValue::Time64(1738734177256, 3, false),
1118+
),
1119+
DataValue::Boolean(false)
1120+
);
1121+
assert_eq!(
1122+
evaluator_time64.0.binary_eval(
1123+
&DataValue::Time64(1738734177256, 3, false),
1124+
&DataValue::Time64(1736055775154814, 6, false),
1125+
),
1126+
DataValue::Boolean(true)
1127+
);
1128+
1129+
let evaluator_time32 =
1130+
EvaluatorFactory::binary_create(LogicalType::Time(None, false), BinaryOperator::GtEq)?;
1131+
let evaluator_time64 = EvaluatorFactory::binary_create(
1132+
LogicalType::TimeStamp(None, false),
1133+
BinaryOperator::GtEq,
1134+
)?;
1135+
assert_eq!(
1136+
evaluator_time32.0.binary_eval(
1137+
&DataValue::Time32(2621204256, 4, false),
1138+
&DataValue::Time32(4190119896, 3, false),
1139+
),
1140+
DataValue::Boolean(true)
1141+
);
1142+
assert_eq!(
1143+
evaluator_time32.0.binary_eval(
1144+
&DataValue::Time32(4190119896, 3, false),
1145+
&DataValue::Time32(2621204256, 4, false),
1146+
),
1147+
DataValue::Boolean(false)
1148+
);
1149+
assert_eq!(
1150+
evaluator_time32.0.binary_eval(
1151+
&DataValue::Time32(4190119896, 3, false),
1152+
&DataValue::Time32(2618828760, 4, false),
1153+
),
1154+
DataValue::Boolean(true)
1155+
);
1156+
assert_eq!(
1157+
evaluator_time64.0.binary_eval(
1158+
&DataValue::Time64(1736055775154814, 6, false),
1159+
&DataValue::Time64(1738734177256, 3, false),
1160+
),
1161+
DataValue::Boolean(false)
1162+
);
1163+
assert_eq!(
1164+
evaluator_time64.0.binary_eval(
1165+
&DataValue::Time64(1738734177256, 3, false),
1166+
&DataValue::Time64(1736055775154814, 6, false),
1167+
),
1168+
DataValue::Boolean(true)
1169+
);
1170+
assert_eq!(
1171+
evaluator_time64.0.binary_eval(
1172+
&DataValue::Time64(1738734177256, 3, false),
1173+
&DataValue::Time64(1738734177256000, 6, false),
1174+
),
1175+
DataValue::Boolean(true)
1176+
);
1177+
1178+
let evaluator_time32 =
1179+
EvaluatorFactory::binary_create(LogicalType::Time(None, false), BinaryOperator::Eq)?;
1180+
let evaluator_time64 = EvaluatorFactory::binary_create(
1181+
LogicalType::TimeStamp(None, false),
1182+
BinaryOperator::Eq,
1183+
)?;
1184+
assert_eq!(
1185+
evaluator_time32.0.binary_eval(
1186+
&DataValue::Time32(4190119896, 3, false),
1187+
&DataValue::Time32(2621204256, 4, false),
1188+
),
1189+
DataValue::Boolean(false)
1190+
);
1191+
assert_eq!(
1192+
evaluator_time32.0.binary_eval(
1193+
&DataValue::Time32(4190119896, 3, false),
1194+
&DataValue::Time32(2618828760, 4, false),
1195+
),
1196+
DataValue::Boolean(true)
1197+
);
1198+
assert_eq!(
1199+
evaluator_time64.0.binary_eval(
1200+
&DataValue::Time64(1738734177256, 3, false),
1201+
&DataValue::Time64(1736055775154814, 6, false),
1202+
),
1203+
DataValue::Boolean(false)
1204+
);
1205+
assert_eq!(
1206+
evaluator_time64.0.binary_eval(
1207+
&DataValue::Time64(1738734177256, 3, false),
1208+
&DataValue::Time64(1738734177256000, 6, false),
1209+
),
1210+
DataValue::Boolean(true)
1211+
);
1212+
1213+
Ok(())
1214+
}
1215+
10351216
#[test]
10361217
fn test_reference_serialization() -> Result<(), DatabaseError> {
10371218
let mut cursor = Cursor::new(Vec::new());

src/types/evaluator/time.rs

Lines changed: 0 additions & 8 deletions
This file was deleted.

0 commit comments

Comments
 (0)