refactor: not allowed int64 type as time index (#2460)

* refactor: remove is_timestamp_compatible.

* chore: fmt

* refactor: remove int64 to timestamp match

* chore

* chore: apply suggestions from code review

Co-authored-by: dennis zhuang <killme2008@gmail.com>

* chore: fmt

---------

Co-authored-by: dennis zhuang <killme2008@gmail.com>
This commit is contained in:
Wei
2023-09-22 14:28:02 +08:00
committed by GitHub
parent c6e95ffe63
commit aef9e7bfc3
21 changed files with 19 additions and 135 deletions

View File

@@ -179,6 +179,10 @@ impl ConcreteDataType {
)
}
pub fn is_timestamp(&self) -> bool {
matches!(self, ConcreteDataType::Timestamp(_))
}
pub fn numerics() -> Vec<ConcreteDataType> {
vec![
ConcreteDataType::int8_datatype(),
@@ -217,9 +221,6 @@ impl ConcreteDataType {
/// Try to cast data type as a [`TimestampType`].
pub fn as_timestamp(&self) -> Option<TimestampType> {
match self {
ConcreteDataType::Int64(_) => {
Some(TimestampType::Millisecond(TimestampMillisecondType))
}
ConcreteDataType::Timestamp(t) => Some(*t),
_ => None,
}
@@ -473,10 +474,6 @@ pub trait DataType: std::fmt::Debug + Send + Sync {
/// Creates a mutable vector with given `capacity` of this type.
fn create_mutable_vector(&self, capacity: usize) -> Box<dyn MutableVector>;
/// Returns true if the data type is compatible with timestamp type so we can
/// use it as a timestamp.
fn is_timestamp_compatible(&self) -> bool;
/// Casts the value to specific DataType.
/// Return None if cast failed.
fn try_cast(&self, from: Value) -> Option<Value>;
@@ -596,41 +593,6 @@ mod tests {
);
}
#[test]
fn test_is_timestamp_compatible() {
assert!(ConcreteDataType::timestamp_datatype(TimeUnit::Second).is_timestamp_compatible());
assert!(
ConcreteDataType::timestamp_datatype(TimeUnit::Millisecond).is_timestamp_compatible()
);
assert!(
ConcreteDataType::timestamp_datatype(TimeUnit::Microsecond).is_timestamp_compatible()
);
assert!(
ConcreteDataType::timestamp_datatype(TimeUnit::Nanosecond).is_timestamp_compatible()
);
assert!(ConcreteDataType::timestamp_second_datatype().is_timestamp_compatible());
assert!(ConcreteDataType::timestamp_millisecond_datatype().is_timestamp_compatible());
assert!(ConcreteDataType::timestamp_microsecond_datatype().is_timestamp_compatible());
assert!(ConcreteDataType::timestamp_nanosecond_datatype().is_timestamp_compatible());
assert!(ConcreteDataType::int64_datatype().is_timestamp_compatible());
assert!(!ConcreteDataType::null_datatype().is_timestamp_compatible());
assert!(!ConcreteDataType::binary_datatype().is_timestamp_compatible());
assert!(!ConcreteDataType::boolean_datatype().is_timestamp_compatible());
assert!(!ConcreteDataType::date_datatype().is_timestamp_compatible());
assert!(!ConcreteDataType::datetime_datatype().is_timestamp_compatible());
assert!(!ConcreteDataType::string_datatype().is_timestamp_compatible());
assert!(!ConcreteDataType::int32_datatype().is_timestamp_compatible());
assert!(!ConcreteDataType::uint64_datatype().is_timestamp_compatible());
assert!(!ConcreteDataType::time_second_datatype().is_timestamp_compatible());
assert!(!ConcreteDataType::time_millisecond_datatype().is_timestamp_compatible());
assert!(!ConcreteDataType::time_microsecond_datatype().is_timestamp_compatible());
assert!(!ConcreteDataType::time_nanosecond_datatype().is_timestamp_compatible());
assert!(!ConcreteDataType::duration_second_datatype().is_timestamp_compatible());
assert!(!ConcreteDataType::duration_millisecond_datatype().is_timestamp_compatible());
assert!(!ConcreteDataType::duration_microsecond_datatype().is_timestamp_compatible());
assert!(!ConcreteDataType::duration_nanosecond_datatype().is_timestamp_compatible());
}
#[test]
fn test_is_null() {
assert!(ConcreteDataType::null_datatype().is_null());

View File

@@ -23,7 +23,6 @@ use arrow::datatypes::{Field, Schema as ArrowSchema};
use datafusion_common::DFSchemaRef;
use snafu::{ensure, ResultExt};
use crate::data_type::DataType;
use crate::error::{self, DuplicateColumnSnafu, Error, ProjectArrowSchemaSnafu, Result};
pub use crate::schema::column_schema::{ColumnSchema, Metadata, COMMENT_KEY, TIME_INDEX_KEY};
pub use crate::schema::constraint::ColumnDefaultConstraint;
@@ -269,7 +268,7 @@ fn validate_timestamp_index(column_schemas: &[ColumnSchema], timestamp_index: us
let column_schema = &column_schemas[timestamp_index];
ensure!(
column_schema.data_type.is_timestamp_compatible(),
column_schema.data_type.is_timestamp(),
error::InvalidTimestampIndexSnafu {
index: timestamp_index,
}

View File

@@ -81,7 +81,7 @@ impl ColumnDefaultConstraint {
error::UnsupportedDefaultExprSnafu { expr }
);
ensure!(
data_type.is_timestamp_compatible(),
data_type.is_timestamp(),
error::DefaultValueTypeSnafu {
reason: "return value of the function must has timestamp type",
}
@@ -199,7 +199,7 @@ fn create_current_timestamp_vector(
let current_timestamp_vector = TimestampMillisecondVector::from_values(
std::iter::repeat(util::current_time_millis()).take(num_rows),
);
if data_type.is_timestamp_compatible() {
if data_type.is_timestamp() {
current_timestamp_vector.cast(data_type)
} else {
error::DefaultValueTypeSnafu {
@@ -350,15 +350,8 @@ mod tests {
// Int64 type.
let data_type = ConcreteDataType::int64_datatype();
let v = constraint
.create_default_vector(&data_type, false, 4)
.unwrap();
assert_eq!(4, v.len());
assert!(
matches!(v.get(0), Value::Int64(_)),
"v {:?} is not timestamp",
v.get(0)
);
let v = constraint.create_default_vector(&data_type, false, 4);
assert!(v.is_err());
let constraint = ColumnDefaultConstraint::Function("no".to_string());
let data_type = ConcreteDataType::timestamp_millisecond_datatype();

View File

@@ -54,10 +54,6 @@ impl DataType for BinaryType {
Box::new(BinaryVectorBuilder::with_capacity(capacity))
}
fn is_timestamp_compatible(&self) -> bool {
false
}
fn try_cast(&self, from: Value) -> Option<Value> {
match from {
Value::Binary(v) => Some(Value::Binary(v)),

View File

@@ -54,10 +54,6 @@ impl DataType for BooleanType {
Box::new(BooleanVectorBuilder::with_capacity(capacity))
}
fn is_timestamp_compatible(&self) -> bool {
false
}
fn try_cast(&self, from: Value) -> Option<Value> {
match from {
Value::Boolean(v) => Some(Value::Boolean(v)),

View File

@@ -52,10 +52,6 @@ impl DataType for DateType {
Box::new(DateVectorBuilder::with_capacity(capacity))
}
fn is_timestamp_compatible(&self) -> bool {
false
}
fn try_cast(&self, from: Value) -> Option<Value> {
match from {
Value::Int32(v) => Some(Value::Date(Date::from(v))),

View File

@@ -50,10 +50,6 @@ impl DataType for DateTimeType {
Box::new(DateTimeVectorBuilder::with_capacity(capacity))
}
fn is_timestamp_compatible(&self) -> bool {
false
}
fn try_cast(&self, from: Value) -> Option<Value> {
match from {
Value::Int64(v) => Some(Value::DateTime(DateTime::from(v))),

View File

@@ -85,10 +85,6 @@ impl DataType for DictionaryType {
unimplemented!()
}
fn is_timestamp_compatible(&self) -> bool {
false
}
fn try_cast(&self, _: Value) -> Option<Value> {
None
}

View File

@@ -98,9 +98,6 @@ macro_rules! impl_data_type_for_duration {
Box::new([<Duration $unit Vector Builder>]::with_capacity(capacity))
}
fn is_timestamp_compatible(&self) -> bool {
false
}
fn try_cast(&self, _: Value) -> Option<Value> {
// TODO(QuenKar): Implement casting for duration types.

View File

@@ -86,9 +86,6 @@ macro_rules! impl_data_type_for_interval {
Box::new([<Interval $unit Vector Builder>]::with_capacity(capacity))
}
fn is_timestamp_compatible(&self) -> bool {
false
}
fn try_cast(&self, _: Value) -> Option<Value> {
// TODO(QuenKar): Implement casting for interval types.

View File

@@ -76,10 +76,6 @@ impl DataType for ListType {
))
}
fn is_timestamp_compatible(&self) -> bool {
false
}
fn try_cast(&self, from: Value) -> Option<Value> {
match from {
Value::List(v) => Some(Value::List(v)),

View File

@@ -52,10 +52,6 @@ impl DataType for NullType {
Box::<NullVectorBuilder>::default()
}
fn is_timestamp_compatible(&self) -> bool {
false
}
// Unconditional cast other type to Value::Null
fn try_cast(&self, _from: Value) -> Option<Value> {
Some(Value::Null)

View File

@@ -271,9 +271,6 @@ macro_rules! define_non_timestamp_primitive {
Box::new(PrimitiveVectorBuilder::<$DataType>::with_capacity(capacity))
}
fn is_timestamp_compatible(&self) -> bool {
false
}
fn try_cast(&self, from: Value) -> Option<Value> {
match from {
@@ -373,10 +370,6 @@ impl DataType for Int64Type {
Box::new(PrimitiveVectorBuilder::<Int64Type>::with_capacity(capacity))
}
fn is_timestamp_compatible(&self) -> bool {
true
}
fn try_cast(&self, from: Value) -> Option<Value> {
match from {
Value::Boolean(v) => bool_to_numeric(v).map(Value::Int64),
@@ -424,10 +417,6 @@ impl DataType for Int32Type {
Box::new(PrimitiveVectorBuilder::<Int32Type>::with_capacity(capacity))
}
fn is_timestamp_compatible(&self) -> bool {
false
}
fn try_cast(&self, from: Value) -> Option<Value> {
match from {
Value::Boolean(v) => bool_to_numeric(v).map(Value::Int32),

View File

@@ -54,10 +54,6 @@ impl DataType for StringType {
Box::new(StringVectorBuilder::with_capacity(capacity))
}
fn is_timestamp_compatible(&self) -> bool {
false
}
fn try_cast(&self, from: Value) -> Option<Value> {
if from.logical_type_id() == self.logical_type_id() {
return Some(from);

View File

@@ -112,10 +112,6 @@ macro_rules! impl_data_type_for_time {
Box::new([<Time $unit Vector Builder>]::with_capacity(capacity))
}
fn is_timestamp_compatible(&self) -> bool {
false
}
fn try_cast(&self, from: Value) -> Option<Value> {
match from {
Value::$TargetType(v) => Some(Value::Time(Time::new(v as i64, TimeUnit::$unit))),

View File

@@ -129,10 +129,6 @@ macro_rules! impl_data_type_for_timestamp {
Box::new([<Timestamp $unit Vector Builder>]::with_capacity(capacity))
}
fn is_timestamp_compatible(&self) -> bool {
true
}
fn try_cast(&self, from: Value)-> Option<Value>{
match from {
Value::Timestamp(v) => v.convert_to(TimeUnit::$unit).map(Value::Timestamp),

View File

@@ -198,7 +198,6 @@ impl Value {
/// Cast Value to timestamp. Return None if value is not a valid timestamp data type.
pub fn as_timestamp(&self) -> Option<Timestamp> {
match self {
Value::Int64(v) => Some(Timestamp::new_millisecond(*v)),
Value::Timestamp(t) => Some(*t),
_ => None,
}
@@ -388,7 +387,6 @@ pub fn duration_to_scalar_value(unit: TimeUnit, val: Option<i64>) -> ScalarValue
/// Return `None` if given scalar value cannot be converted to a valid timestamp.
pub fn scalar_value_to_timestamp(scalar: &ScalarValue) -> Option<Timestamp> {
match scalar {
ScalarValue::Int64(val) => val.map(Timestamp::new_millisecond),
ScalarValue::Utf8(Some(s)) => match Timestamp::from_str(s) {
Ok(t) => Some(t),
Err(e) => {