mirror of
https://github.com/GreptimeTeam/greptimedb.git
synced 2026-06-02 21:30:38 +00:00
refactor!: remove datetime type (#5506)
* feat remove datetime type * chore: fix unit test * chore: add column test * refactor: move create and alter validation to one place * chore: minor refactor ut * refactor: rename expr_factory to expr_helper * chore: remove unnecessary args
This commit is contained in:
@@ -14,37 +14,12 @@
|
||||
|
||||
use api::helper;
|
||||
use api::v1::column::Values;
|
||||
use api::v1::{Column, CreateTableExpr};
|
||||
use common_base::BitVec;
|
||||
use datatypes::data_type::{ConcreteDataType, DataType};
|
||||
use datatypes::prelude::VectorRef;
|
||||
use snafu::{ensure, ResultExt};
|
||||
use table::metadata::TableId;
|
||||
use table::table_reference::TableReference;
|
||||
|
||||
use crate::error::{CreateVectorSnafu, Result, UnexpectedValuesLengthSnafu};
|
||||
use crate::util;
|
||||
use crate::util::ColumnExpr;
|
||||
|
||||
/// Try to build create table request from insert data.
|
||||
pub fn build_create_expr_from_insertion(
|
||||
catalog_name: &str,
|
||||
schema_name: &str,
|
||||
table_id: Option<TableId>,
|
||||
table_name: &str,
|
||||
columns: &[Column],
|
||||
engine: &str,
|
||||
) -> Result<CreateTableExpr> {
|
||||
let table_name = TableReference::full(catalog_name, schema_name, table_name);
|
||||
let column_exprs = ColumnExpr::from_columns(columns);
|
||||
util::build_create_table_expr(
|
||||
table_id,
|
||||
&table_name,
|
||||
column_exprs,
|
||||
engine,
|
||||
"Created on insertion",
|
||||
)
|
||||
}
|
||||
|
||||
pub(crate) fn add_values_to_builder(
|
||||
data_type: ConcreteDataType,
|
||||
@@ -87,276 +62,7 @@ fn is_null(null_mask: &BitVec, idx: usize) -> Option<bool> {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::sync::Arc;
|
||||
use std::{assert_eq, vec};
|
||||
|
||||
use api::helper::ColumnDataTypeWrapper;
|
||||
use api::v1::column::Values;
|
||||
use api::v1::column_data_type_extension::TypeExt;
|
||||
use api::v1::{
|
||||
Column, ColumnDataType, ColumnDataTypeExtension, Decimal128, DecimalTypeExtension,
|
||||
IntervalMonthDayNano, SemanticType,
|
||||
};
|
||||
use common_base::BitVec;
|
||||
use common_catalog::consts::MITO_ENGINE;
|
||||
use common_time::interval::IntervalUnit;
|
||||
use common_time::timestamp::TimeUnit;
|
||||
use datatypes::data_type::ConcreteDataType;
|
||||
use datatypes::schema::{ColumnSchema, SchemaBuilder};
|
||||
use snafu::ResultExt;
|
||||
|
||||
use super::*;
|
||||
use crate::error;
|
||||
use crate::error::ColumnDataTypeSnafu;
|
||||
|
||||
#[inline]
|
||||
fn build_column_schema(
|
||||
column_name: &str,
|
||||
datatype: i32,
|
||||
nullable: bool,
|
||||
) -> error::Result<ColumnSchema> {
|
||||
let datatype_wrapper =
|
||||
ColumnDataTypeWrapper::try_new(datatype, None).context(ColumnDataTypeSnafu)?;
|
||||
|
||||
Ok(ColumnSchema::new(
|
||||
column_name,
|
||||
datatype_wrapper.into(),
|
||||
nullable,
|
||||
))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_build_create_table_request() {
|
||||
let table_id = Some(10);
|
||||
let table_name = "test_metric";
|
||||
|
||||
assert!(
|
||||
build_create_expr_from_insertion("", "", table_id, table_name, &[], MITO_ENGINE)
|
||||
.is_err()
|
||||
);
|
||||
|
||||
let insert_batch = mock_insert_batch();
|
||||
|
||||
let create_expr = build_create_expr_from_insertion(
|
||||
"",
|
||||
"",
|
||||
table_id,
|
||||
table_name,
|
||||
&insert_batch.0,
|
||||
MITO_ENGINE,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(table_id, create_expr.table_id.map(|x| x.id));
|
||||
assert_eq!(table_name, create_expr.table_name);
|
||||
assert_eq!("Created on insertion".to_string(), create_expr.desc);
|
||||
assert_eq!(
|
||||
vec![create_expr.column_defs[0].name.clone()],
|
||||
create_expr.primary_keys
|
||||
);
|
||||
|
||||
let column_defs = create_expr.column_defs;
|
||||
assert_eq!(column_defs[5].name, create_expr.time_index);
|
||||
assert_eq!(7, column_defs.len());
|
||||
|
||||
assert_eq!(
|
||||
ConcreteDataType::string_datatype(),
|
||||
ConcreteDataType::from(
|
||||
ColumnDataTypeWrapper::try_new(
|
||||
column_defs
|
||||
.iter()
|
||||
.find(|c| c.name == "host")
|
||||
.unwrap()
|
||||
.data_type,
|
||||
None
|
||||
)
|
||||
.unwrap()
|
||||
)
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
ConcreteDataType::float64_datatype(),
|
||||
ConcreteDataType::from(
|
||||
ColumnDataTypeWrapper::try_new(
|
||||
column_defs
|
||||
.iter()
|
||||
.find(|c| c.name == "cpu")
|
||||
.unwrap()
|
||||
.data_type,
|
||||
None
|
||||
)
|
||||
.unwrap()
|
||||
)
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
ConcreteDataType::float64_datatype(),
|
||||
ConcreteDataType::from(
|
||||
ColumnDataTypeWrapper::try_new(
|
||||
column_defs
|
||||
.iter()
|
||||
.find(|c| c.name == "memory")
|
||||
.unwrap()
|
||||
.data_type,
|
||||
None
|
||||
)
|
||||
.unwrap()
|
||||
)
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
ConcreteDataType::time_datatype(TimeUnit::Millisecond),
|
||||
ConcreteDataType::from(
|
||||
ColumnDataTypeWrapper::try_new(
|
||||
column_defs
|
||||
.iter()
|
||||
.find(|c| c.name == "time")
|
||||
.unwrap()
|
||||
.data_type,
|
||||
None
|
||||
)
|
||||
.unwrap()
|
||||
)
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
ConcreteDataType::interval_datatype(IntervalUnit::MonthDayNano),
|
||||
ConcreteDataType::from(
|
||||
ColumnDataTypeWrapper::try_new(
|
||||
column_defs
|
||||
.iter()
|
||||
.find(|c| c.name == "interval")
|
||||
.unwrap()
|
||||
.data_type,
|
||||
None
|
||||
)
|
||||
.unwrap()
|
||||
)
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
ConcreteDataType::timestamp_millisecond_datatype(),
|
||||
ConcreteDataType::from(
|
||||
ColumnDataTypeWrapper::try_new(
|
||||
column_defs
|
||||
.iter()
|
||||
.find(|c| c.name == "ts")
|
||||
.unwrap()
|
||||
.data_type,
|
||||
None
|
||||
)
|
||||
.unwrap()
|
||||
)
|
||||
);
|
||||
|
||||
let decimal_column = column_defs.iter().find(|c| c.name == "decimals").unwrap();
|
||||
assert_eq!(
|
||||
ConcreteDataType::decimal128_datatype(38, 10),
|
||||
ConcreteDataType::from(
|
||||
ColumnDataTypeWrapper::try_new(
|
||||
decimal_column.data_type,
|
||||
decimal_column.datatype_extension,
|
||||
)
|
||||
.unwrap()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_find_new_columns() {
|
||||
let mut columns = Vec::with_capacity(1);
|
||||
let cpu_column = build_column_schema("cpu", 10, true).unwrap();
|
||||
let ts_column = build_column_schema("ts", 15, false)
|
||||
.unwrap()
|
||||
.with_time_index(true);
|
||||
columns.push(cpu_column);
|
||||
columns.push(ts_column);
|
||||
|
||||
let schema = Arc::new(SchemaBuilder::try_from(columns).unwrap().build().unwrap());
|
||||
|
||||
assert!(
|
||||
util::extract_new_columns(&schema, ColumnExpr::from_columns(&[]))
|
||||
.unwrap()
|
||||
.is_none()
|
||||
);
|
||||
|
||||
let insert_batch = mock_insert_batch();
|
||||
|
||||
let add_columns =
|
||||
util::extract_new_columns(&schema, ColumnExpr::from_columns(&insert_batch.0))
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(5, add_columns.add_columns.len());
|
||||
let host_column = &add_columns.add_columns[0];
|
||||
assert_eq!(
|
||||
ConcreteDataType::string_datatype(),
|
||||
ConcreteDataType::from(
|
||||
ColumnDataTypeWrapper::try_new(
|
||||
host_column.column_def.as_ref().unwrap().data_type,
|
||||
None
|
||||
)
|
||||
.unwrap()
|
||||
)
|
||||
);
|
||||
assert!(host_column.add_if_not_exists);
|
||||
|
||||
let memory_column = &add_columns.add_columns[1];
|
||||
assert_eq!(
|
||||
ConcreteDataType::float64_datatype(),
|
||||
ConcreteDataType::from(
|
||||
ColumnDataTypeWrapper::try_new(
|
||||
memory_column.column_def.as_ref().unwrap().data_type,
|
||||
None
|
||||
)
|
||||
.unwrap()
|
||||
)
|
||||
);
|
||||
assert!(host_column.add_if_not_exists);
|
||||
|
||||
let time_column = &add_columns.add_columns[2];
|
||||
assert_eq!(
|
||||
ConcreteDataType::time_datatype(TimeUnit::Millisecond),
|
||||
ConcreteDataType::from(
|
||||
ColumnDataTypeWrapper::try_new(
|
||||
time_column.column_def.as_ref().unwrap().data_type,
|
||||
None
|
||||
)
|
||||
.unwrap()
|
||||
)
|
||||
);
|
||||
assert!(host_column.add_if_not_exists);
|
||||
|
||||
let interval_column = &add_columns.add_columns[3];
|
||||
assert_eq!(
|
||||
ConcreteDataType::interval_datatype(IntervalUnit::MonthDayNano),
|
||||
ConcreteDataType::from(
|
||||
ColumnDataTypeWrapper::try_new(
|
||||
interval_column.column_def.as_ref().unwrap().data_type,
|
||||
None
|
||||
)
|
||||
.unwrap()
|
||||
)
|
||||
);
|
||||
assert!(host_column.add_if_not_exists);
|
||||
|
||||
let decimal_column = &add_columns.add_columns[4];
|
||||
assert_eq!(
|
||||
ConcreteDataType::decimal128_datatype(38, 10),
|
||||
ConcreteDataType::from(
|
||||
ColumnDataTypeWrapper::try_new(
|
||||
decimal_column.column_def.as_ref().unwrap().data_type,
|
||||
decimal_column
|
||||
.column_def
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.datatype_extension
|
||||
)
|
||||
.unwrap()
|
||||
)
|
||||
);
|
||||
assert!(host_column.add_if_not_exists);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_null() {
|
||||
@@ -371,127 +77,4 @@ mod tests {
|
||||
assert_eq!(None, is_null(&null_mask, 16));
|
||||
assert_eq!(None, is_null(&null_mask, 99));
|
||||
}
|
||||
|
||||
fn mock_insert_batch() -> (Vec<Column>, u32) {
|
||||
let row_count = 2;
|
||||
|
||||
let host_vals = Values {
|
||||
string_values: vec!["host1".to_string(), "host2".to_string()],
|
||||
..Default::default()
|
||||
};
|
||||
let host_column = Column {
|
||||
column_name: "host".to_string(),
|
||||
semantic_type: SemanticType::Tag as i32,
|
||||
values: Some(host_vals),
|
||||
null_mask: vec![0],
|
||||
datatype: ColumnDataType::String as i32,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let cpu_vals = Values {
|
||||
f64_values: vec![0.31],
|
||||
..Default::default()
|
||||
};
|
||||
let cpu_column = Column {
|
||||
column_name: "cpu".to_string(),
|
||||
semantic_type: SemanticType::Field as i32,
|
||||
values: Some(cpu_vals),
|
||||
null_mask: vec![2],
|
||||
datatype: ColumnDataType::Float64 as i32,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let mem_vals = Values {
|
||||
f64_values: vec![0.1],
|
||||
..Default::default()
|
||||
};
|
||||
let mem_column = Column {
|
||||
column_name: "memory".to_string(),
|
||||
semantic_type: SemanticType::Field as i32,
|
||||
values: Some(mem_vals),
|
||||
null_mask: vec![1],
|
||||
datatype: ColumnDataType::Float64 as i32,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let time_vals = Values {
|
||||
time_millisecond_values: vec![100, 101],
|
||||
..Default::default()
|
||||
};
|
||||
let time_column = Column {
|
||||
column_name: "time".to_string(),
|
||||
semantic_type: SemanticType::Field as i32,
|
||||
values: Some(time_vals),
|
||||
null_mask: vec![0],
|
||||
datatype: ColumnDataType::TimeMillisecond as i32,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let interval1 = IntervalMonthDayNano {
|
||||
months: 1,
|
||||
days: 2,
|
||||
nanoseconds: 3,
|
||||
};
|
||||
let interval2 = IntervalMonthDayNano {
|
||||
months: 4,
|
||||
days: 5,
|
||||
nanoseconds: 6,
|
||||
};
|
||||
let interval_vals = Values {
|
||||
interval_month_day_nano_values: vec![interval1, interval2],
|
||||
..Default::default()
|
||||
};
|
||||
let interval_column = Column {
|
||||
column_name: "interval".to_string(),
|
||||
semantic_type: SemanticType::Field as i32,
|
||||
values: Some(interval_vals),
|
||||
null_mask: vec![0],
|
||||
datatype: ColumnDataType::IntervalMonthDayNano as i32,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let ts_vals = Values {
|
||||
timestamp_millisecond_values: vec![100, 101],
|
||||
..Default::default()
|
||||
};
|
||||
let ts_column = Column {
|
||||
column_name: "ts".to_string(),
|
||||
semantic_type: SemanticType::Timestamp as i32,
|
||||
values: Some(ts_vals),
|
||||
null_mask: vec![0],
|
||||
datatype: ColumnDataType::TimestampMillisecond as i32,
|
||||
..Default::default()
|
||||
};
|
||||
let decimal_vals = Values {
|
||||
decimal128_values: vec![Decimal128 { hi: 0, lo: 123 }, Decimal128 { hi: 0, lo: 456 }],
|
||||
..Default::default()
|
||||
};
|
||||
let decimal_column = Column {
|
||||
column_name: "decimals".to_string(),
|
||||
semantic_type: SemanticType::Field as i32,
|
||||
values: Some(decimal_vals),
|
||||
null_mask: vec![0],
|
||||
datatype: ColumnDataType::Decimal128 as i32,
|
||||
datatype_extension: Some(ColumnDataTypeExtension {
|
||||
type_ext: Some(TypeExt::DecimalType(DecimalTypeExtension {
|
||||
precision: 38,
|
||||
scale: 10,
|
||||
})),
|
||||
}),
|
||||
options: None,
|
||||
};
|
||||
|
||||
(
|
||||
vec![
|
||||
host_column,
|
||||
cpu_column,
|
||||
mem_column,
|
||||
time_column,
|
||||
interval_column,
|
||||
ts_column,
|
||||
decimal_column,
|
||||
],
|
||||
row_count,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,4 +19,3 @@ pub mod insert;
|
||||
pub mod util;
|
||||
|
||||
pub use alter::{alter_expr_to_request, create_table_schema};
|
||||
pub use insert::build_create_expr_from_insertion;
|
||||
|
||||
@@ -236,3 +236,414 @@ pub fn extract_new_columns(
|
||||
}))
|
||||
}
|
||||
}
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::sync::Arc;
|
||||
use std::{assert_eq, vec};
|
||||
|
||||
use api::helper::ColumnDataTypeWrapper;
|
||||
use api::v1::column::Values;
|
||||
use api::v1::column_data_type_extension::TypeExt;
|
||||
use api::v1::{
|
||||
Column, ColumnDataType, ColumnDataTypeExtension, Decimal128, DecimalTypeExtension,
|
||||
IntervalMonthDayNano, SemanticType,
|
||||
};
|
||||
use common_catalog::consts::MITO_ENGINE;
|
||||
use common_time::interval::IntervalUnit;
|
||||
use common_time::timestamp::TimeUnit;
|
||||
use datatypes::data_type::ConcreteDataType;
|
||||
use datatypes::schema::{ColumnSchema, SchemaBuilder};
|
||||
use snafu::ResultExt;
|
||||
|
||||
use super::*;
|
||||
use crate::error;
|
||||
use crate::error::ColumnDataTypeSnafu;
|
||||
|
||||
#[inline]
|
||||
fn build_column_schema(
|
||||
column_name: &str,
|
||||
datatype: i32,
|
||||
nullable: bool,
|
||||
) -> error::Result<ColumnSchema> {
|
||||
let datatype_wrapper =
|
||||
ColumnDataTypeWrapper::try_new(datatype, None).context(ColumnDataTypeSnafu)?;
|
||||
|
||||
Ok(ColumnSchema::new(
|
||||
column_name,
|
||||
datatype_wrapper.into(),
|
||||
nullable,
|
||||
))
|
||||
}
|
||||
|
||||
fn build_create_expr_from_insertion(
|
||||
catalog_name: &str,
|
||||
schema_name: &str,
|
||||
table_id: Option<TableId>,
|
||||
table_name: &str,
|
||||
columns: &[Column],
|
||||
engine: &str,
|
||||
) -> Result<CreateTableExpr> {
|
||||
let table_name = TableReference::full(catalog_name, schema_name, table_name);
|
||||
let column_exprs = ColumnExpr::from_columns(columns);
|
||||
build_create_table_expr(
|
||||
table_id,
|
||||
&table_name,
|
||||
column_exprs,
|
||||
engine,
|
||||
"Created on insertion",
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_build_create_table_request() {
|
||||
let table_id = Some(10);
|
||||
let table_name = "test_metric";
|
||||
|
||||
assert!(
|
||||
build_create_expr_from_insertion("", "", table_id, table_name, &[], MITO_ENGINE)
|
||||
.is_err()
|
||||
);
|
||||
|
||||
let insert_batch = mock_insert_batch();
|
||||
|
||||
let create_expr = build_create_expr_from_insertion(
|
||||
"",
|
||||
"",
|
||||
table_id,
|
||||
table_name,
|
||||
&insert_batch.0,
|
||||
MITO_ENGINE,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(table_id, create_expr.table_id.map(|x| x.id));
|
||||
assert_eq!(table_name, create_expr.table_name);
|
||||
assert_eq!("Created on insertion".to_string(), create_expr.desc);
|
||||
assert_eq!(
|
||||
vec![create_expr.column_defs[0].name.clone()],
|
||||
create_expr.primary_keys
|
||||
);
|
||||
|
||||
let column_defs = create_expr.column_defs;
|
||||
assert_eq!(column_defs[5].name, create_expr.time_index);
|
||||
assert_eq!(7, column_defs.len());
|
||||
|
||||
assert_eq!(
|
||||
ConcreteDataType::string_datatype(),
|
||||
ConcreteDataType::from(
|
||||
ColumnDataTypeWrapper::try_new(
|
||||
column_defs
|
||||
.iter()
|
||||
.find(|c| c.name == "host")
|
||||
.unwrap()
|
||||
.data_type,
|
||||
None
|
||||
)
|
||||
.unwrap()
|
||||
)
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
ConcreteDataType::float64_datatype(),
|
||||
ConcreteDataType::from(
|
||||
ColumnDataTypeWrapper::try_new(
|
||||
column_defs
|
||||
.iter()
|
||||
.find(|c| c.name == "cpu")
|
||||
.unwrap()
|
||||
.data_type,
|
||||
None
|
||||
)
|
||||
.unwrap()
|
||||
)
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
ConcreteDataType::float64_datatype(),
|
||||
ConcreteDataType::from(
|
||||
ColumnDataTypeWrapper::try_new(
|
||||
column_defs
|
||||
.iter()
|
||||
.find(|c| c.name == "memory")
|
||||
.unwrap()
|
||||
.data_type,
|
||||
None
|
||||
)
|
||||
.unwrap()
|
||||
)
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
ConcreteDataType::time_datatype(TimeUnit::Millisecond),
|
||||
ConcreteDataType::from(
|
||||
ColumnDataTypeWrapper::try_new(
|
||||
column_defs
|
||||
.iter()
|
||||
.find(|c| c.name == "time")
|
||||
.unwrap()
|
||||
.data_type,
|
||||
None
|
||||
)
|
||||
.unwrap()
|
||||
)
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
ConcreteDataType::interval_datatype(IntervalUnit::MonthDayNano),
|
||||
ConcreteDataType::from(
|
||||
ColumnDataTypeWrapper::try_new(
|
||||
column_defs
|
||||
.iter()
|
||||
.find(|c| c.name == "interval")
|
||||
.unwrap()
|
||||
.data_type,
|
||||
None
|
||||
)
|
||||
.unwrap()
|
||||
)
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
ConcreteDataType::timestamp_millisecond_datatype(),
|
||||
ConcreteDataType::from(
|
||||
ColumnDataTypeWrapper::try_new(
|
||||
column_defs
|
||||
.iter()
|
||||
.find(|c| c.name == "ts")
|
||||
.unwrap()
|
||||
.data_type,
|
||||
None
|
||||
)
|
||||
.unwrap()
|
||||
)
|
||||
);
|
||||
|
||||
let decimal_column = column_defs.iter().find(|c| c.name == "decimals").unwrap();
|
||||
assert_eq!(
|
||||
ConcreteDataType::decimal128_datatype(38, 10),
|
||||
ConcreteDataType::from(
|
||||
ColumnDataTypeWrapper::try_new(
|
||||
decimal_column.data_type,
|
||||
decimal_column.datatype_extension,
|
||||
)
|
||||
.unwrap()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_find_new_columns() {
|
||||
let mut columns = Vec::with_capacity(1);
|
||||
let cpu_column = build_column_schema("cpu", 10, true).unwrap();
|
||||
let ts_column = build_column_schema("ts", 15, false)
|
||||
.unwrap()
|
||||
.with_time_index(true);
|
||||
columns.push(cpu_column);
|
||||
columns.push(ts_column);
|
||||
|
||||
let schema = Arc::new(SchemaBuilder::try_from(columns).unwrap().build().unwrap());
|
||||
|
||||
assert!(extract_new_columns(&schema, ColumnExpr::from_columns(&[]))
|
||||
.unwrap()
|
||||
.is_none());
|
||||
|
||||
let insert_batch = mock_insert_batch();
|
||||
|
||||
let add_columns = extract_new_columns(&schema, ColumnExpr::from_columns(&insert_batch.0))
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(5, add_columns.add_columns.len());
|
||||
let host_column = &add_columns.add_columns[0];
|
||||
assert_eq!(
|
||||
ConcreteDataType::string_datatype(),
|
||||
ConcreteDataType::from(
|
||||
ColumnDataTypeWrapper::try_new(
|
||||
host_column.column_def.as_ref().unwrap().data_type,
|
||||
None
|
||||
)
|
||||
.unwrap()
|
||||
)
|
||||
);
|
||||
assert!(host_column.add_if_not_exists);
|
||||
|
||||
let memory_column = &add_columns.add_columns[1];
|
||||
assert_eq!(
|
||||
ConcreteDataType::float64_datatype(),
|
||||
ConcreteDataType::from(
|
||||
ColumnDataTypeWrapper::try_new(
|
||||
memory_column.column_def.as_ref().unwrap().data_type,
|
||||
None
|
||||
)
|
||||
.unwrap()
|
||||
)
|
||||
);
|
||||
assert!(host_column.add_if_not_exists);
|
||||
|
||||
let time_column = &add_columns.add_columns[2];
|
||||
assert_eq!(
|
||||
ConcreteDataType::time_datatype(TimeUnit::Millisecond),
|
||||
ConcreteDataType::from(
|
||||
ColumnDataTypeWrapper::try_new(
|
||||
time_column.column_def.as_ref().unwrap().data_type,
|
||||
None
|
||||
)
|
||||
.unwrap()
|
||||
)
|
||||
);
|
||||
assert!(host_column.add_if_not_exists);
|
||||
|
||||
let interval_column = &add_columns.add_columns[3];
|
||||
assert_eq!(
|
||||
ConcreteDataType::interval_datatype(IntervalUnit::MonthDayNano),
|
||||
ConcreteDataType::from(
|
||||
ColumnDataTypeWrapper::try_new(
|
||||
interval_column.column_def.as_ref().unwrap().data_type,
|
||||
None
|
||||
)
|
||||
.unwrap()
|
||||
)
|
||||
);
|
||||
assert!(host_column.add_if_not_exists);
|
||||
|
||||
let decimal_column = &add_columns.add_columns[4];
|
||||
assert_eq!(
|
||||
ConcreteDataType::decimal128_datatype(38, 10),
|
||||
ConcreteDataType::from(
|
||||
ColumnDataTypeWrapper::try_new(
|
||||
decimal_column.column_def.as_ref().unwrap().data_type,
|
||||
decimal_column
|
||||
.column_def
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.datatype_extension
|
||||
)
|
||||
.unwrap()
|
||||
)
|
||||
);
|
||||
assert!(host_column.add_if_not_exists);
|
||||
}
|
||||
|
||||
fn mock_insert_batch() -> (Vec<Column>, u32) {
|
||||
let row_count = 2;
|
||||
|
||||
let host_vals = Values {
|
||||
string_values: vec!["host1".to_string(), "host2".to_string()],
|
||||
..Default::default()
|
||||
};
|
||||
let host_column = Column {
|
||||
column_name: "host".to_string(),
|
||||
semantic_type: SemanticType::Tag as i32,
|
||||
values: Some(host_vals),
|
||||
null_mask: vec![0],
|
||||
datatype: ColumnDataType::String as i32,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let cpu_vals = Values {
|
||||
f64_values: vec![0.31],
|
||||
..Default::default()
|
||||
};
|
||||
let cpu_column = Column {
|
||||
column_name: "cpu".to_string(),
|
||||
semantic_type: SemanticType::Field as i32,
|
||||
values: Some(cpu_vals),
|
||||
null_mask: vec![2],
|
||||
datatype: ColumnDataType::Float64 as i32,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let mem_vals = Values {
|
||||
f64_values: vec![0.1],
|
||||
..Default::default()
|
||||
};
|
||||
let mem_column = Column {
|
||||
column_name: "memory".to_string(),
|
||||
semantic_type: SemanticType::Field as i32,
|
||||
values: Some(mem_vals),
|
||||
null_mask: vec![1],
|
||||
datatype: ColumnDataType::Float64 as i32,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let time_vals = Values {
|
||||
time_millisecond_values: vec![100, 101],
|
||||
..Default::default()
|
||||
};
|
||||
let time_column = Column {
|
||||
column_name: "time".to_string(),
|
||||
semantic_type: SemanticType::Field as i32,
|
||||
values: Some(time_vals),
|
||||
null_mask: vec![0],
|
||||
datatype: ColumnDataType::TimeMillisecond as i32,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let interval1 = IntervalMonthDayNano {
|
||||
months: 1,
|
||||
days: 2,
|
||||
nanoseconds: 3,
|
||||
};
|
||||
let interval2 = IntervalMonthDayNano {
|
||||
months: 4,
|
||||
days: 5,
|
||||
nanoseconds: 6,
|
||||
};
|
||||
let interval_vals = Values {
|
||||
interval_month_day_nano_values: vec![interval1, interval2],
|
||||
..Default::default()
|
||||
};
|
||||
let interval_column = Column {
|
||||
column_name: "interval".to_string(),
|
||||
semantic_type: SemanticType::Field as i32,
|
||||
values: Some(interval_vals),
|
||||
null_mask: vec![0],
|
||||
datatype: ColumnDataType::IntervalMonthDayNano as i32,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let ts_vals = Values {
|
||||
timestamp_millisecond_values: vec![100, 101],
|
||||
..Default::default()
|
||||
};
|
||||
let ts_column = Column {
|
||||
column_name: "ts".to_string(),
|
||||
semantic_type: SemanticType::Timestamp as i32,
|
||||
values: Some(ts_vals),
|
||||
null_mask: vec![0],
|
||||
datatype: ColumnDataType::TimestampMillisecond as i32,
|
||||
..Default::default()
|
||||
};
|
||||
let decimal_vals = Values {
|
||||
decimal128_values: vec![Decimal128 { hi: 0, lo: 123 }, Decimal128 { hi: 0, lo: 456 }],
|
||||
..Default::default()
|
||||
};
|
||||
let decimal_column = Column {
|
||||
column_name: "decimals".to_string(),
|
||||
semantic_type: SemanticType::Field as i32,
|
||||
values: Some(decimal_vals),
|
||||
null_mask: vec![0],
|
||||
datatype: ColumnDataType::Decimal128 as i32,
|
||||
datatype_extension: Some(ColumnDataTypeExtension {
|
||||
type_ext: Some(TypeExt::DecimalType(DecimalTypeExtension {
|
||||
precision: 38,
|
||||
scale: 10,
|
||||
})),
|
||||
}),
|
||||
options: None,
|
||||
};
|
||||
|
||||
(
|
||||
vec![
|
||||
host_column,
|
||||
cpu_column,
|
||||
mem_column,
|
||||
time_column,
|
||||
interval_column,
|
||||
ts_column,
|
||||
decimal_column,
|
||||
],
|
||||
row_count,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ use common_meta::key::table_info::TableInfoValue;
|
||||
use datatypes::prelude::ConcreteDataType;
|
||||
use datatypes::schema::ColumnSchema;
|
||||
use itertools::Itertools;
|
||||
use operator::expr_factory::CreateExprFactory;
|
||||
use operator::expr_helper;
|
||||
use session::context::QueryContextBuilder;
|
||||
use snafu::{OptionExt, ResultExt};
|
||||
use table::table_reference::TableReference;
|
||||
@@ -32,7 +32,6 @@ use crate::adapter::{TableName, WorkerHandle, AUTO_CREATED_PLACEHOLDER_TS_COL};
|
||||
use crate::error::{Error, ExternalSnafu, UnexpectedSnafu};
|
||||
use crate::repr::{ColumnType, RelationDesc, RelationType};
|
||||
use crate::FlowWorkerManager;
|
||||
|
||||
impl FlowWorkerManager {
|
||||
/// Get a worker handle for creating flow, using round robin to select a worker
|
||||
pub(crate) async fn get_worker_handle_for_create_flow(&self) -> &WorkerHandle {
|
||||
@@ -66,19 +65,18 @@ impl FlowWorkerManager {
|
||||
let proto_schema = column_schemas_to_proto(tys.clone(), &pks)?;
|
||||
|
||||
// create sink table
|
||||
let create_expr = CreateExprFactory {}
|
||||
.create_table_expr_by_column_schemas(
|
||||
&TableReference {
|
||||
catalog: &table_name[0],
|
||||
schema: &table_name[1],
|
||||
table: &table_name[2],
|
||||
},
|
||||
&proto_schema,
|
||||
"mito",
|
||||
Some(&format!("Sink table for flow {}", flow_name)),
|
||||
)
|
||||
.map_err(BoxedError::new)
|
||||
.context(ExternalSnafu)?;
|
||||
let create_expr = expr_helper::create_table_expr_by_column_schemas(
|
||||
&TableReference {
|
||||
catalog: &table_name[0],
|
||||
schema: &table_name[1],
|
||||
table: &table_name[2],
|
||||
},
|
||||
&proto_schema,
|
||||
"mito",
|
||||
Some(&format!("Sink table for flow {}", flow_name)),
|
||||
)
|
||||
.map_err(BoxedError::new)
|
||||
.context(ExternalSnafu)?;
|
||||
|
||||
self.submit_create_sink_table_ddl(create_expr).await?;
|
||||
Ok(true)
|
||||
|
||||
@@ -29,7 +29,7 @@ use common_error::ext::BoxedError;
|
||||
use common_grpc_expr::util::ColumnExpr;
|
||||
use common_time::Timezone;
|
||||
use datafusion::sql::planner::object_name_to_table_reference;
|
||||
use datatypes::schema::{ColumnSchema, FulltextAnalyzer, COMMENT_KEY};
|
||||
use datatypes::schema::{ColumnSchema, FulltextAnalyzer, Schema, COMMENT_KEY};
|
||||
use file_engine::FileOptions;
|
||||
use query::sql::{
|
||||
check_file_to_table_schema_compatibility, file_column_schemas_to_table,
|
||||
@@ -54,42 +54,44 @@ use table::table_reference::TableReference;
|
||||
|
||||
use crate::error::{
|
||||
BuildCreateExprOnInsertionSnafu, ColumnDataTypeSnafu, ConvertColumnDefaultConstraintSnafu,
|
||||
ConvertIdentifierSnafu, EncodeJsonSnafu, ExternalSnafu, IllegalPrimaryKeysDefSnafu,
|
||||
InferFileTableSchemaSnafu, InvalidFlowNameSnafu, InvalidSqlSnafu, NotSupportedSnafu,
|
||||
ParseSqlSnafu, PrepareFileTableSnafu, Result, SchemaIncompatibleSnafu,
|
||||
ConvertIdentifierSnafu, EncodeJsonSnafu, ExternalSnafu, FindNewColumnsOnInsertionSnafu,
|
||||
IllegalPrimaryKeysDefSnafu, InferFileTableSchemaSnafu, InvalidFlowNameSnafu, InvalidSqlSnafu,
|
||||
NotSupportedSnafu, ParseSqlSnafu, PrepareFileTableSnafu, Result, SchemaIncompatibleSnafu,
|
||||
UnrecognizedTableOptionSnafu,
|
||||
};
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct CreateExprFactory;
|
||||
pub fn create_table_expr_by_column_schemas(
|
||||
table_name: &TableReference<'_>,
|
||||
column_schemas: &[api::v1::ColumnSchema],
|
||||
engine: &str,
|
||||
desc: Option<&str>,
|
||||
) -> Result<CreateTableExpr> {
|
||||
let column_exprs = ColumnExpr::from_column_schemas(column_schemas);
|
||||
let expr = common_grpc_expr::util::build_create_table_expr(
|
||||
None,
|
||||
table_name,
|
||||
column_exprs,
|
||||
engine,
|
||||
desc.unwrap_or("Created on insertion"),
|
||||
)
|
||||
.context(BuildCreateExprOnInsertionSnafu)?;
|
||||
|
||||
impl CreateExprFactory {
|
||||
pub fn create_table_expr_by_column_schemas(
|
||||
&self,
|
||||
table_name: &TableReference<'_>,
|
||||
column_schemas: &[api::v1::ColumnSchema],
|
||||
engine: &str,
|
||||
desc: Option<&str>,
|
||||
) -> Result<CreateTableExpr> {
|
||||
let column_exprs = ColumnExpr::from_column_schemas(column_schemas);
|
||||
let create_expr = common_grpc_expr::util::build_create_table_expr(
|
||||
None,
|
||||
table_name,
|
||||
column_exprs,
|
||||
engine,
|
||||
desc.unwrap_or("Created on insertion"),
|
||||
)
|
||||
.context(BuildCreateExprOnInsertionSnafu)?;
|
||||
|
||||
Ok(create_expr)
|
||||
}
|
||||
validate_create_expr(&expr)?;
|
||||
Ok(expr)
|
||||
}
|
||||
|
||||
pub(crate) fn extract_add_columns_expr(
|
||||
schema: &Schema,
|
||||
column_exprs: Vec<ColumnExpr>,
|
||||
) -> Result<Option<AddColumns>> {
|
||||
let add_columns = common_grpc_expr::util::extract_new_columns(schema, column_exprs)
|
||||
.context(FindNewColumnsOnInsertionSnafu)?;
|
||||
if let Some(add_columns) = &add_columns {
|
||||
validate_add_columns_expr(add_columns)?;
|
||||
}
|
||||
Ok(add_columns)
|
||||
}
|
||||
|
||||
// When the `CREATE EXTERNAL TABLE` statement is in expanded form, like
|
||||
// ```sql
|
||||
// CREATE EXTERNAL TABLE city (
|
||||
// host string,
|
||||
// ts timestamp,
|
||||
// cpu float64,
|
||||
// memory float64,
|
||||
// TIME INDEX (ts),
|
||||
@@ -173,6 +175,7 @@ pub(crate) async fn create_external_expr(
|
||||
table_id: None,
|
||||
engine: create.engine.to_string(),
|
||||
};
|
||||
|
||||
Ok(expr)
|
||||
}
|
||||
|
||||
@@ -274,8 +277,9 @@ pub fn validate_create_expr(create: &CreateTableExpr) -> Result<()> {
|
||||
}
|
||||
.fail();
|
||||
}
|
||||
// verify do not contain interval type column issue #3235
|
||||
|
||||
for column in &create.column_defs {
|
||||
// verify do not contain interval type column issue #3235
|
||||
if is_interval_type(&column.data_type()) {
|
||||
return InvalidSqlSnafu {
|
||||
err_msg: format!(
|
||||
@@ -285,11 +289,48 @@ pub fn validate_create_expr(create: &CreateTableExpr) -> Result<()> {
|
||||
}
|
||||
.fail();
|
||||
}
|
||||
// verify do not contain datetime type column issue #5489
|
||||
if is_date_time_type(&column.data_type()) {
|
||||
return InvalidSqlSnafu {
|
||||
err_msg: format!(
|
||||
"column name `{}` is datetime type, which is not supported, please use `timestamp` type instead",
|
||||
column.name
|
||||
),
|
||||
}
|
||||
.fail();
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn validate_add_columns_expr(add_columns: &AddColumns) -> Result<()> {
|
||||
for add_column in &add_columns.add_columns {
|
||||
let Some(column_def) = &add_column.column_def else {
|
||||
continue;
|
||||
};
|
||||
if is_date_time_type(&column_def.data_type()) {
|
||||
return InvalidSqlSnafu {
|
||||
err_msg: format!("column name `{}` is datetime type, which is not supported, please use `timestamp` type instead", column_def.name),
|
||||
}
|
||||
.fail();
|
||||
}
|
||||
if is_interval_type(&column_def.data_type()) {
|
||||
return InvalidSqlSnafu {
|
||||
err_msg: format!(
|
||||
"column name `{}` is interval type, which is not supported",
|
||||
column_def.name
|
||||
),
|
||||
}
|
||||
.fail();
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn is_date_time_type(data_type: &ColumnDataType) -> bool {
|
||||
matches!(data_type, ColumnDataType::Datetime)
|
||||
}
|
||||
|
||||
fn is_interval_type(data_type: &ColumnDataType) -> bool {
|
||||
matches!(
|
||||
data_type,
|
||||
@@ -27,7 +27,7 @@ use api::v1::{
|
||||
use catalog::CatalogManagerRef;
|
||||
use client::{OutputData, OutputMeta};
|
||||
use common_catalog::consts::default_engine;
|
||||
use common_grpc_expr::util::{extract_new_columns, ColumnExpr};
|
||||
use common_grpc_expr::util::ColumnExpr;
|
||||
use common_meta::cache::TableFlownodeSetCacheRef;
|
||||
use common_meta::node_manager::{AffectedRows, NodeManagerRef};
|
||||
use common_meta::peer::Peer;
|
||||
@@ -53,10 +53,10 @@ use table::table_reference::TableReference;
|
||||
use table::TableRef;
|
||||
|
||||
use crate::error::{
|
||||
CatalogSnafu, FindNewColumnsOnInsertionSnafu, FindRegionLeaderSnafu, InvalidInsertRequestSnafu,
|
||||
JoinTaskSnafu, RequestInsertsSnafu, Result, TableNotFoundSnafu,
|
||||
CatalogSnafu, FindRegionLeaderSnafu, InvalidInsertRequestSnafu, JoinTaskSnafu,
|
||||
RequestInsertsSnafu, Result, TableNotFoundSnafu,
|
||||
};
|
||||
use crate::expr_factory::CreateExprFactory;
|
||||
use crate::expr_helper;
|
||||
use crate::region_req_factory::RegionRequestFactory;
|
||||
use crate::req_convert::common::preprocess_row_insert_requests;
|
||||
use crate::req_convert::insert::{
|
||||
@@ -690,8 +690,7 @@ impl Inserter {
|
||||
|
||||
let request_schema = req.rows.as_ref().unwrap().schema.as_slice();
|
||||
let column_exprs = ColumnExpr::from_column_schemas(request_schema);
|
||||
let add_columns = extract_new_columns(&table.schema(), column_exprs)
|
||||
.context(FindNewColumnsOnInsertionSnafu)?;
|
||||
let add_columns = expr_helper::extract_add_columns_expr(&table.schema(), column_exprs)?;
|
||||
let Some(add_columns) = add_columns else {
|
||||
return Ok(None);
|
||||
};
|
||||
@@ -807,7 +806,7 @@ fn build_create_table_expr(
|
||||
request_schema: &[ColumnSchema],
|
||||
engine: &str,
|
||||
) -> Result<CreateTableExpr> {
|
||||
CreateExprFactory.create_table_expr_by_column_schemas(table, request_schema, engine, None)
|
||||
expr_helper::create_table_expr_by_column_schemas(table, request_schema, engine, None)
|
||||
}
|
||||
|
||||
/// Result of `create_or_alter_tables_on_demand`.
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
pub mod delete;
|
||||
pub mod error;
|
||||
pub mod expr_factory;
|
||||
pub mod expr_helper;
|
||||
pub mod flow;
|
||||
pub mod insert;
|
||||
pub mod metrics;
|
||||
|
||||
@@ -23,7 +23,7 @@ use store_api::storage::{RegionId, TableId};
|
||||
use table::metadata::{TableInfo, TableInfoRef};
|
||||
|
||||
use crate::error::{ConvertColumnDefaultConstraintSnafu, Result, UnexpectedSnafu};
|
||||
use crate::expr_factory::column_schemas_to_defs;
|
||||
use crate::expr_helper::column_schemas_to_defs;
|
||||
use crate::insert::InstantAndNormalInsertRequests;
|
||||
|
||||
/// Find all columns that have impure default values
|
||||
|
||||
@@ -78,7 +78,7 @@ use crate::error::{
|
||||
SchemaReadOnlySnafu, SubstraitCodecSnafu, TableAlreadyExistsSnafu, TableMetadataManagerSnafu,
|
||||
TableNotFoundSnafu, UnrecognizedTableOptionSnafu, ViewAlreadyExistsSnafu,
|
||||
};
|
||||
use crate::expr_factory;
|
||||
use crate::expr_helper;
|
||||
use crate::statement::show::create_partitions_stmt;
|
||||
|
||||
lazy_static! {
|
||||
@@ -92,7 +92,7 @@ impl StatementExecutor {
|
||||
|
||||
#[tracing::instrument(skip_all)]
|
||||
pub async fn create_table(&self, stmt: CreateTable, ctx: QueryContextRef) -> Result<TableRef> {
|
||||
let create_expr = &mut expr_factory::create_to_expr(&stmt, &ctx)?;
|
||||
let create_expr = &mut expr_helper::create_to_expr(&stmt, &ctx)?;
|
||||
self.create_table_inner(create_expr, stmt.partitions, ctx)
|
||||
.await
|
||||
}
|
||||
@@ -146,7 +146,7 @@ impl StatementExecutor {
|
||||
}
|
||||
});
|
||||
|
||||
let create_expr = &mut expr_factory::create_to_expr(&create_stmt, &ctx)?;
|
||||
let create_expr = &mut expr_helper::create_to_expr(&create_stmt, &ctx)?;
|
||||
self.create_table_inner(create_expr, partitions, ctx).await
|
||||
}
|
||||
|
||||
@@ -156,7 +156,7 @@ impl StatementExecutor {
|
||||
create_expr: CreateExternalTable,
|
||||
ctx: QueryContextRef,
|
||||
) -> Result<TableRef> {
|
||||
let create_expr = &mut expr_factory::create_external_expr(create_expr, &ctx).await?;
|
||||
let create_expr = &mut expr_helper::create_external_expr(create_expr, &ctx).await?;
|
||||
self.create_table_inner(create_expr, None, ctx).await
|
||||
}
|
||||
|
||||
@@ -345,7 +345,7 @@ impl StatementExecutor {
|
||||
query_context: QueryContextRef,
|
||||
) -> Result<Output> {
|
||||
// TODO(ruihang): do some verification
|
||||
let expr = expr_factory::to_create_flow_task_expr(stmt, &query_context)?;
|
||||
let expr = expr_helper::to_create_flow_task_expr(stmt, &query_context)?;
|
||||
|
||||
self.create_flow_inner(expr, query_context).await
|
||||
}
|
||||
@@ -450,7 +450,7 @@ impl StatementExecutor {
|
||||
.encode(&plan, DefaultSerializer)
|
||||
.context(SubstraitCodecSnafu)?;
|
||||
|
||||
let expr = expr_factory::to_create_view_expr(
|
||||
let expr = expr_helper::to_create_view_expr(
|
||||
create_view,
|
||||
encoded_plan.to_vec(),
|
||||
table_names,
|
||||
@@ -945,7 +945,7 @@ impl StatementExecutor {
|
||||
alter_table: AlterTable,
|
||||
query_context: QueryContextRef,
|
||||
) -> Result<Output> {
|
||||
let expr = expr_factory::to_alter_table_expr(alter_table, &query_context)?;
|
||||
let expr = expr_helper::to_alter_table_expr(alter_table, &query_context)?;
|
||||
self.alter_table_inner(expr, query_context).await
|
||||
}
|
||||
|
||||
@@ -1073,7 +1073,7 @@ impl StatementExecutor {
|
||||
alter_expr: AlterDatabase,
|
||||
query_context: QueryContextRef,
|
||||
) -> Result<Output> {
|
||||
let alter_expr = expr_factory::to_alter_database_expr(alter_expr, &query_context)?;
|
||||
let alter_expr = expr_helper::to_alter_database_expr(alter_expr, &query_context)?;
|
||||
self.alter_database_inner(alter_expr, query_context).await
|
||||
}
|
||||
|
||||
@@ -1595,7 +1595,7 @@ mod test {
|
||||
use sql::statements::statement::Statement;
|
||||
|
||||
use super::*;
|
||||
use crate::expr_factory;
|
||||
use crate::expr_helper;
|
||||
|
||||
#[test]
|
||||
fn test_name_is_match() {
|
||||
@@ -1649,7 +1649,7 @@ ENGINE=mito",
|
||||
.unwrap();
|
||||
match &result[0] {
|
||||
Statement::CreateTable(c) => {
|
||||
let expr = expr_factory::create_to_expr(c, &QueryContext::arc()).unwrap();
|
||||
let expr = expr_helper::create_to_expr(c, &QueryContext::arc()).unwrap();
|
||||
let (partitions, _) =
|
||||
parse_partitions(&expr, c.partitions.clone(), &ctx).unwrap();
|
||||
let json = serde_json::to_string(&partitions).unwrap();
|
||||
|
||||
@@ -167,6 +167,7 @@ pub(crate) fn get_type_by_alias(data_type: &DataType) -> Option<DataType> {
|
||||
DataType::UInt64 => Some(DataType::UnsignedBigInt(None)),
|
||||
DataType::Float32 => Some(DataType::Float(None)),
|
||||
DataType::Float64 => Some(DataType::Double),
|
||||
DataType::Datetime(_) => Some(DataType::Timestamp(Some(6), TimezoneInfo::None)),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
@@ -188,7 +189,7 @@ pub(crate) fn get_data_type_by_alias_name(name: &str) -> Option<DataType> {
|
||||
"TIMESTAMP_MS" | "TIMESTAMPMILLISECOND" => {
|
||||
Some(DataType::Timestamp(Some(3), TimezoneInfo::None))
|
||||
}
|
||||
"TIMESTAMP_US" | "TIMESTAMPMICROSECOND" => {
|
||||
"TIMESTAMP_US" | "TIMESTAMPMICROSECOND" | "DATETIME" => {
|
||||
Some(DataType::Timestamp(Some(6), TimezoneInfo::None))
|
||||
}
|
||||
"TIMESTAMP_NS" | "TIMESTAMPNANOSECOND" => {
|
||||
@@ -407,7 +408,7 @@ CREATE TABLE data_types (
|
||||
b BOOLEAN,
|
||||
vb VARBINARY,
|
||||
dt DATE,
|
||||
dtt DATETIME,
|
||||
dtt TIMESTAMP(6),
|
||||
ts0 TIMESTAMP(0),
|
||||
ts3 TIMESTAMP(3),
|
||||
ts6 TIMESTAMP(6),
|
||||
|
||||
@@ -166,7 +166,7 @@ pub async fn test_mysql_crud(store_type: StorageType) {
|
||||
.unwrap();
|
||||
|
||||
sqlx::query(
|
||||
"create table demo(i bigint, ts timestamp time index default current_timestamp, d date default null, dt datetime default null, b blob default null, j json default null, v vector(3) default null)",
|
||||
"create table demo(i bigint, ts timestamp time index default current_timestamp, d date default null, dt timestamp(3) default null, b blob default null, j json default null, v vector(3) default null)",
|
||||
)
|
||||
.execute(&pool)
|
||||
.await
|
||||
@@ -449,7 +449,7 @@ pub async fn test_postgres_crud(store_type: StorageType) {
|
||||
|
||||
for i in 0..10 {
|
||||
let d = NaiveDate::from_yo_opt(2015, 100).unwrap();
|
||||
let dt = d.and_hms_opt(0, 0, 0).unwrap().and_utc().timestamp_millis();
|
||||
let dt = d.and_hms_opt(0, 0, 0).unwrap().and_utc().timestamp_micros();
|
||||
let bytes = "hello".as_bytes();
|
||||
let json = serde_json::json!({
|
||||
"code": i,
|
||||
|
||||
@@ -55,6 +55,10 @@ ALTER TABLE test_alt_table ADD COLUMN m INTEGER;
|
||||
|
||||
Affected Rows: 0
|
||||
|
||||
ALTER TABLE test_alt_table ADD COLUMN dt DATETIME;
|
||||
|
||||
Affected Rows: 0
|
||||
|
||||
-- Should fail issue #5422
|
||||
ALTER TABLE test_alt_table ADD COLUMN n interval;
|
||||
|
||||
@@ -75,6 +79,7 @@ DESC TABLE test_alt_table;
|
||||
| j | TimestampMillisecond | PRI | NO | | TIMESTAMP |
|
||||
| k | String | PRI | YES | | TAG |
|
||||
| m | Int32 | | YES | | FIELD |
|
||||
| dt | TimestampMicrosecond | | YES | | FIELD |
|
||||
+--------+----------------------+-----+------+---------+---------------+
|
||||
|
||||
DROP TABLE test_alt_table;
|
||||
|
||||
@@ -17,6 +17,8 @@ SELECT * FROM test_alt_table WHERE i = 1;
|
||||
-- SQLNESS ARG restart=true
|
||||
ALTER TABLE test_alt_table ADD COLUMN m INTEGER;
|
||||
|
||||
ALTER TABLE test_alt_table ADD COLUMN dt DATETIME;
|
||||
|
||||
-- Should fail issue #5422
|
||||
ALTER TABLE test_alt_table ADD COLUMN n interval;
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ SHOW CREATE TABLE data_types;
|
||||
| | "b" BOOLEAN NULL, |
|
||||
| | "vb" VARBINARY NULL, |
|
||||
| | "dt" DATE NULL, |
|
||||
| | "dtt" DATETIME NULL, |
|
||||
| | "dtt" TIMESTAMP(6) NULL, |
|
||||
| | "ts0" TIMESTAMP(0) NULL, |
|
||||
| | "ts3" TIMESTAMP(3) NULL, |
|
||||
| | "ts6" TIMESTAMP(6) NULL, |
|
||||
@@ -65,7 +65,7 @@ DESC TABLE data_types;
|
||||
| b | Boolean | | YES | | FIELD |
|
||||
| vb | Binary | | YES | | FIELD |
|
||||
| dt | Date | | YES | | FIELD |
|
||||
| dtt | DateTime | | YES | | FIELD |
|
||||
| dtt | TimestampMicrosecond | | YES | | FIELD |
|
||||
| ts0 | TimestampSecond | | YES | | FIELD |
|
||||
| ts3 | TimestampMillisecond | | YES | | FIELD |
|
||||
| ts6 | TimestampMicrosecond | | YES | | FIELD |
|
||||
|
||||
@@ -84,7 +84,11 @@ SELECT date_format('2023-12-06 07:39:46.222'::TIMESTAMP_S, '%Y-%m-%d %H:%M:%S:%3
|
||||
--- datetime not supported yet ---
|
||||
SELECT date_format('2023-12-06 07:39:46.222'::DATETIME, '%Y-%m-%d %H:%M:%S:%3f');
|
||||
|
||||
Error: 1001(Unsupported), Failed to plan SQL: This feature is not implemented: Unsupported SQL type Datetime(None)
|
||||
+-----------------------------------------------------------------------------------------------------------------------------+
|
||||
| date_format(arrow_cast(Utf8("2023-12-06 07:39:46.222"),Utf8("Timestamp(Microsecond, None)")),Utf8("%Y-%m-%d %H:%M:%S:%3f")) |
|
||||
+-----------------------------------------------------------------------------------------------------------------------------+
|
||||
| 2023-12-06 07:39:46:222 |
|
||||
+-----------------------------------------------------------------------------------------------------------------------------+
|
||||
|
||||
SELECT date_format('2023-12-06'::DATE, '%m-%d');
|
||||
|
||||
|
||||
@@ -433,7 +433,7 @@ SELECT * FROM public."all_types" ORDER BY m1 DESC LIMIT 100;
|
||||
+----------+-------+-----+-----------+-------------+-------------+---------------+-------------+---------------+---------------+-----------------+--------+-----------+------------+--------------+--------------+----------------+--------------+----------------+----------------+------------------+-------------+---------------+---------------+-----------------+---------------+-----------------+-----------------+-------------------+-------+---------+---------+-----------+---------+-----------+-----------+-------------+-----------+-------------+-------------+---------------+-------------+---------------+---------------+-----------------+----------+------------+------------+--------------+------------+--------------+--------------+----------------+-----------+-------------+-------------+---------------+-------------+---------------+---------------+-----------------+---------------+-----------------+-----------------+-------------------+-------+---------+---------+-----------+---------+-----------+-----------+-------------+-----------+-------------+-------------+---------------+-----------+-------------+-------------+---------------+-------------+---------------+---------------+-----------------+---------------+-----------------+-----------------+-------------------+---------+-----------+-----------+-------------+-----------+-------------+-------------+---------------+-------------+---------------+---------------+-----------------+---------+-----------+-----------+-------------+-----------+-------------+-------------+---------------+-------------+---------------+---------------+-----------------+----------+------------+------------+--------------+--------------+----------------+----------------+------------------+--------------------+----------------------+----------------------+------------------------+------------------------+--------------------------+--------------------------+----------------------------+--------+----------+----------+------------+------------+--------------+--------------+----------------+------------+---------------------+---------------------+---------------------+---------------------+----------+----------+--------+----------+--------+----------+-------------+---------------+---------+-----------+-----------------+-------------------+-----------+---------------------+----------------+------------+--------------------+------------------------------+------------+--------+----------+--------------+------------+--------+--------+--------+--------+-----+---------------------+
|
||||
| c_serial | c_bit | b1 | c_tinyint | c_tinyint_u | c_tinyint_z | c_tinyint_u_z | c_tinyint_n | c_tinyint_n_n | c_tinyint_n_z | c_tinyint_n_u_z | c_bool | c_boolean | c_smallint | c_smallint_u | c_smallint_z | c_smallint_u_z | c_smallint_n | c_smallint_n_n | c_smallint_n_z | c_smallint_n_u_z | c_mediumint | c_mediumint_u | c_mediumint_z | c_mediumint_u_z | c_mediumint_n | c_mediumint_n_n | c_mediumint_n_z | c_mediumint_n_u_z | c_int | c_int_u | c_int_z | c_int_u_z | c_int_n | c_int_n_n | c_int_n_z | c_int_n_u_z | c_integer | c_integer_u | c_integer_z | c_integer_u_z | c_integer_n | c_integer_n_n | c_integer_n_z | c_integer_n_u_z | c_bigint | c_bigint_u | c_bigint_z | c_bigint_u_z | c_bigint_n | c_bigint_n_n | c_bigint_n_z | c_bigint_n_u_z | c_decimal | c_decimal_u | c_decimal_z | c_decimal_u_z | c_decimal_n | c_decimal_n_u | c_decimal_n_z | c_decimal_n_u_z | c_decimal_n_n | c_decimal_n_n_u | c_decimal_n_n_z | c_decimal_n_n_u_z | c_dec | c_dec_u | c_dec_z | c_dec_u_z | c_dec_n | c_dec_n_u | c_dec_n_z | c_dec_n_u_z | c_dec_n_n | c_dec_n_n_u | c_dec_n_n_z | c_dec_n_n_u_z | c_numeric | c_numeric_u | c_numeric_z | c_numeric_u_z | c_numeric_n | c_numeric_n_u | c_numeric_n_z | c_numeric_n_u_z | c_numeric_n_n | c_numeric_n_n_u | c_numeric_n_n_z | c_numeric_n_n_u_z | c_fixed | c_fixed_u | c_fixed_z | c_fixed_u_z | c_fixed_n | c_fixed_n_u | c_fixed_n_z | c_fixed_n_u_z | c_fixed_n_n | c_fixed_n_n_u | c_fixed_n_n_z | c_fixed_n_n_u_z | c_float | c_float_u | c_float_z | c_float_u_z | c_float_n | c_float_n_u | c_float_n_z | c_float_n_u_z | c_float_n_n | c_float_n_n_u | c_float_n_n_z | c_float_n_n_u_z | c_double | c_double_u | c_double_z | c_double_u_z | c_double_n_n | c_double_n_n_u | c_double_n_n_z | c_double_n_n_u_z | c_double_precision | c_double_precision_u | c_double_precision_z | c_double_precision_u_z | c_double_precision_n_n | c_double_precision_n_n_u | c_double_precision_n_n_z | c_double_precision_n_n_u_z | c_real | c_real_u | c_real_z | c_real_u_z | c_real_n_n | c_real_n_n_u | c_real_n_n_z | c_real_n_n_u_z | c_date | c_datetime | c_datetime_n | c_timestamp | c_timestamp_n | c_time | c_time_n | c_year | c_year_n | c_char | c_char_n | c_character | c_character_n | c_nchar | c_nchar_n | c_national_char | c_national_char_n | c_varchar | c_character_varying | c_long_varchar | c_nvarchar | c_national_varchar | c_national_character_varying | c_tinytext | c_text | c_text_n | c_mediumtext | c_longtext | c_long | c_enum | c_set | c_bit1 | a1 | m1 |
|
||||
+----------+-------+-----+-----------+-------------+-------------+---------------+-------------+---------------+---------------+-----------------+--------+-----------+------------+--------------+--------------+----------------+--------------+----------------+----------------+------------------+-------------+---------------+---------------+-----------------+---------------+-----------------+-----------------+-------------------+-------+---------+---------+-----------+---------+-----------+-----------+-------------+-----------+-------------+-------------+---------------+-------------+---------------+---------------+-----------------+----------+------------+------------+--------------+------------+--------------+--------------+----------------+-----------+-------------+-------------+---------------+-------------+---------------+---------------+-----------------+---------------+-----------------+-----------------+-------------------+-------+---------+---------+-----------+---------+-----------+-----------+-------------+-----------+-------------+-------------+---------------+-----------+-------------+-------------+---------------+-------------+---------------+---------------+-----------------+---------------+-----------------+-----------------+-------------------+---------+-----------+-----------+-------------+-----------+-------------+-------------+---------------+-------------+---------------+---------------+-----------------+---------+-----------+-----------+-------------+-----------+-------------+-------------+---------------+-------------+---------------+---------------+-----------------+----------+------------+------------+--------------+--------------+----------------+----------------+------------------+--------------------+----------------------+----------------------+------------------------+------------------------+--------------------------+--------------------------+----------------------------+--------+----------+----------+------------+------------+--------------+--------------+----------------+------------+---------------------+---------------------+---------------------+---------------------+----------+----------+--------+----------+--------+----------+-------------+---------------+---------+-----------+-----------------+-------------------+-----------+---------------------+----------------+------------+--------------------+------------------------------+------------+--------+----------+--------------+------------+--------+--------+--------+--------+-----+---------------------+
|
||||
| 123457 | 1 | 100 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1.123 | 1.123 | 1.123 | 1.123 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1.123 | 1.123 | 1.123 | 1.123 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1.123 | 1.123 | 1.123 | 1.123 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1.123 | 1.123 | 1.123 | 1.123 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 2024-01-01 | 2024-01-01T00:00:00 | 2024-01-01T00:00:00 | 2024-01-01T00:00:00 | 2024-01-01T00:00:00 | 12:00:00 | 12:00:00 | 2024 | 2024 | A | A | A | A | A | A | A | A | ABC | ABC | ABC | ABC | ABC | ABC | ABC | ABC | ABC | ABC | ABC | ABC | value1 | value1 | 1 | ABC | 2024-01-01T12:00:00 |
|
||||
| 123457 | 1 | 100 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1.123 | 1.123 | 1.123 | 1.123 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1.123 | 1.123 | 1.123 | 1.123 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1.123 | 1.123 | 1.123 | 1.123 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1.123 | 1.123 | 1.123 | 1.123 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 2024-01-01 | 2024-01-01T12:00:00 | 2024-01-01T12:00:00 | 2024-01-01T12:00:00 | 2024-01-01T12:00:00 | 12:00:00 | 12:00:00 | 2024 | 2024 | A | A | A | A | A | A | A | A | ABC | ABC | ABC | ABC | ABC | ABC | ABC | ABC | ABC | ABC | ABC | ABC | value1 | value1 | 1 | ABC | 2024-01-01T12:00:00 |
|
||||
+----------+-------+-----+-----------+-------------+-------------+---------------+-------------+---------------+---------------+-----------------+--------+-----------+------------+--------------+--------------+----------------+--------------+----------------+----------------+------------------+-------------+---------------+---------------+-----------------+---------------+-----------------+-----------------+-------------------+-------+---------+---------+-----------+---------+-----------+-----------+-------------+-----------+-------------+-------------+---------------+-------------+---------------+---------------+-----------------+----------+------------+------------+--------------+------------+--------------+--------------+----------------+-----------+-------------+-------------+---------------+-------------+---------------+---------------+-----------------+---------------+-----------------+-----------------+-------------------+-------+---------+---------+-----------+---------+-----------+-----------+-------------+-----------+-------------+-------------+---------------+-----------+-------------+-------------+---------------+-------------+---------------+---------------+-----------------+---------------+-----------------+-----------------+-------------------+---------+-----------+-----------+-------------+-----------+-------------+-------------+---------------+-------------+---------------+---------------+-----------------+---------+-----------+-----------+-------------+-----------+-------------+-------------+---------------+-------------+---------------+---------------+-----------------+----------+------------+------------+--------------+--------------+----------------+----------------+------------------+--------------------+----------------------+----------------------+------------------------+------------------------+--------------------------+--------------------------+----------------------------+--------+----------+----------+------------+------------+--------------+--------------+----------------+------------+---------------------+---------------------+---------------------+---------------------+----------+----------+--------+----------+--------+----------+-------------+---------------+---------+-----------+-----------------+-------------------+-----------+---------------------+----------------+------------+--------------------+------------------------------+------------+--------+----------+--------------+------------+--------+--------+--------+--------+-----+---------------------+
|
||||
|
||||
DROP TABLE all_types;
|
||||
|
||||
Reference in New Issue
Block a user