mirror of
https://github.com/GreptimeTeam/greptimedb.git
synced 2026-01-08 22:32:55 +00:00
refactor: remove unused PartitionDef (#6573)
* refactor: remove unused PartitionDef Signed-off-by: Zhenchi <zhongzc_arch@outlook.com> * fix snafu Signed-off-by: Zhenchi <zhongzc_arch@outlook.com> --------- Signed-off-by: Zhenchi <zhongzc_arch@outlook.com>
This commit is contained in:
@@ -138,6 +138,7 @@ impl TableMetadataAllocator {
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
// If the table has no partitions, we need to create a default region.
|
||||
if region_routes.is_empty() {
|
||||
region_routes.push(RegionRoute {
|
||||
region: Region {
|
||||
|
||||
@@ -606,7 +606,6 @@ impl From<DropTableTask> for PbDropTableTask {
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub struct CreateTableTask {
|
||||
pub create_table: CreateTableExpr,
|
||||
// TODO(zhongzc): change to `Vec<PartitionExpr>`
|
||||
pub partitions: Vec<Partition>,
|
||||
pub table_info: RawTableInfo,
|
||||
}
|
||||
|
||||
@@ -482,21 +482,6 @@ where
|
||||
Ok(values)
|
||||
}
|
||||
|
||||
impl From<LegacyPartition> for PbPartition {
|
||||
fn from(p: LegacyPartition) -> Self {
|
||||
let expression = if !p.value_list.is_empty() {
|
||||
String::from_utf8_lossy(&p.value_list[0]).to_string()
|
||||
} else {
|
||||
"".to_string()
|
||||
};
|
||||
|
||||
Self {
|
||||
expression,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
@@ -419,13 +419,6 @@ pub enum Error {
|
||||
source: datatypes::error::Error,
|
||||
},
|
||||
|
||||
#[snafu(display("Failed to deserialize partition in meta to partition def"))]
|
||||
DeserializePartition {
|
||||
#[snafu(implicit)]
|
||||
location: Location,
|
||||
source: partition::error::Error,
|
||||
},
|
||||
|
||||
#[snafu(display("Failed to describe schema for given statement"))]
|
||||
DescribeStatement {
|
||||
#[snafu(implicit)]
|
||||
@@ -851,6 +844,13 @@ pub enum Error {
|
||||
#[snafu(implicit)]
|
||||
location: Location,
|
||||
},
|
||||
|
||||
#[snafu(display("Failed to convert partition expression to protobuf"))]
|
||||
PartitionExprToPb {
|
||||
source: partition::error::Error,
|
||||
#[snafu(implicit)]
|
||||
location: Location,
|
||||
},
|
||||
}
|
||||
|
||||
pub type Result<T> = std::result::Result<T, Error>;
|
||||
@@ -891,6 +891,7 @@ impl ErrorExt for Error {
|
||||
| Error::InvalidPartition { .. }
|
||||
| Error::PhysicalExpr { .. }
|
||||
| Error::InvalidJsonFormat { .. }
|
||||
| Error::PartitionExprToPb { .. }
|
||||
| Error::CursorNotFound { .. }
|
||||
| Error::CursorExists { .. }
|
||||
| Error::CreatePartitionRules { .. } => StatusCode::InvalidArguments,
|
||||
@@ -947,8 +948,7 @@ impl ErrorExt for Error {
|
||||
| Error::DescribeStatement { source, .. } => source.status_code(),
|
||||
Error::AlterExprToRequest { source, .. } => source.status_code(),
|
||||
Error::External { source, .. } => source.status_code(),
|
||||
Error::DeserializePartition { source, .. }
|
||||
| Error::FindTablePartitionRule { source, .. }
|
||||
Error::FindTablePartitionRule { source, .. }
|
||||
| Error::SplitInsert { source, .. }
|
||||
| Error::SplitDelete { source, .. }
|
||||
| Error::FindRegionLeader { source, .. } => source.status_code(),
|
||||
|
||||
@@ -43,7 +43,6 @@ use common_meta::rpc::ddl::{
|
||||
CreateFlowTask, DdlTask, DropFlowTask, DropViewTask, SubmitDdlTaskRequest,
|
||||
SubmitDdlTaskResponse,
|
||||
};
|
||||
use common_meta::rpc::router::{LegacyPartition, LegacyPartition as MetaPartition};
|
||||
use common_query::Output;
|
||||
use common_sql::convert::sql_value_to_value;
|
||||
use common_telemetry::{debug, info, tracing, warn};
|
||||
@@ -56,7 +55,6 @@ use datatypes::value::Value;
|
||||
use lazy_static::lazy_static;
|
||||
use partition::expr::{Operand, PartitionExpr, RestrictedOp};
|
||||
use partition::multi_dim::MultiDimPartitionRule;
|
||||
use partition::partition::{PartitionBound, PartitionDef};
|
||||
use query::parser::QueryStatement;
|
||||
use query::plan::extract_and_rewrite_full_table_names;
|
||||
use query::query_engine::DefaultSerializer;
|
||||
@@ -85,9 +83,9 @@ use table::TableRef;
|
||||
use crate::error::{
|
||||
self, AlterExprToRequestSnafu, BuildDfLogicalPlanSnafu, CatalogSnafu, ColumnDataTypeSnafu,
|
||||
ColumnNotFoundSnafu, ConvertSchemaSnafu, CreateLogicalTablesSnafu, CreateTableInfoSnafu,
|
||||
DeserializePartitionSnafu, EmptyDdlExprSnafu, ExternalSnafu, ExtractTableNamesSnafu,
|
||||
FlowNotFoundSnafu, InvalidPartitionRuleSnafu, InvalidPartitionSnafu, InvalidSqlSnafu,
|
||||
InvalidTableNameSnafu, InvalidViewNameSnafu, InvalidViewStmtSnafu, Result, SchemaInUseSnafu,
|
||||
EmptyDdlExprSnafu, ExternalSnafu, ExtractTableNamesSnafu, FlowNotFoundSnafu,
|
||||
InvalidPartitionRuleSnafu, InvalidPartitionSnafu, InvalidSqlSnafu, InvalidTableNameSnafu,
|
||||
InvalidViewNameSnafu, InvalidViewStmtSnafu, PartitionExprToPbSnafu, Result, SchemaInUseSnafu,
|
||||
SchemaNotFoundSnafu, SchemaReadOnlySnafu, SubstraitCodecSnafu, TableAlreadyExistsSnafu,
|
||||
TableMetadataManagerSnafu, TableNotFoundSnafu, UnrecognizedTableOptionSnafu,
|
||||
ViewAlreadyExistsSnafu,
|
||||
@@ -1337,11 +1335,14 @@ impl StatementExecutor {
|
||||
async fn create_table_procedure(
|
||||
&self,
|
||||
create_table: CreateTableExpr,
|
||||
partitions: Vec<LegacyPartition>,
|
||||
partitions: Vec<PartitionExpr>,
|
||||
table_info: RawTableInfo,
|
||||
query_context: QueryContextRef,
|
||||
) -> Result<SubmitDdlTaskResponse> {
|
||||
let partitions = partitions.into_iter().map(Into::into).collect();
|
||||
let partitions = partitions
|
||||
.into_iter()
|
||||
.map(|expr| expr.as_pb_partition().context(PartitionExprToPbSnafu))
|
||||
.collect::<Result<Vec<_>>>()?;
|
||||
|
||||
let request = SubmitDdlTaskRequest {
|
||||
query_context,
|
||||
@@ -1533,36 +1534,24 @@ impl StatementExecutor {
|
||||
}
|
||||
}
|
||||
|
||||
/// Parse partition statement [Partitions] into [MetaPartition] and partition columns.
|
||||
/// Parse partition statement [Partitions] into [PartitionExpr] and partition columns.
|
||||
pub fn parse_partitions(
|
||||
create_table: &CreateTableExpr,
|
||||
partitions: Option<Partitions>,
|
||||
query_ctx: &QueryContextRef,
|
||||
) -> Result<(Vec<MetaPartition>, Vec<String>)> {
|
||||
) -> Result<(Vec<PartitionExpr>, Vec<String>)> {
|
||||
// If partitions are not defined by user, use the timestamp column (which has to be existed) as
|
||||
// the partition column, and create only one partition.
|
||||
let partition_columns = find_partition_columns(&partitions)?;
|
||||
let partition_entries =
|
||||
let partition_exprs =
|
||||
find_partition_entries(create_table, &partitions, &partition_columns, query_ctx)?;
|
||||
|
||||
// Validates partition
|
||||
let exprs = partition_entries.clone();
|
||||
let exprs = partition_exprs.clone();
|
||||
MultiDimPartitionRule::try_new(partition_columns.clone(), vec![], exprs, true)
|
||||
.context(InvalidPartitionSnafu)?;
|
||||
|
||||
// TODO(zhongzc): change to PartitionExpr
|
||||
let meta_partitions: Vec<MetaPartition> = partition_entries
|
||||
.into_iter()
|
||||
.map(|x| {
|
||||
MetaPartition::try_from(PartitionDef::new(
|
||||
partition_columns.clone(),
|
||||
vec![PartitionBound::Expr(x)],
|
||||
))
|
||||
})
|
||||
.collect::<std::result::Result<_, _>>()
|
||||
.context(DeserializePartitionSnafu)?;
|
||||
|
||||
Ok((meta_partitions, partition_columns))
|
||||
Ok((partition_exprs, partition_columns))
|
||||
}
|
||||
|
||||
/// Verifies an alter and returns whether it is necessary to perform the alter.
|
||||
@@ -1720,7 +1709,7 @@ fn find_partition_columns(partitions: &Option<Partitions>) -> Result<Vec<String>
|
||||
|
||||
/// Parse [Partitions] into a group of partition entries.
|
||||
///
|
||||
/// Returns a list of [PartitionBound], each of which defines a partition.
|
||||
/// Returns a list of [PartitionExpr], each of which defines a partition.
|
||||
fn find_partition_entries(
|
||||
create_table: &CreateTableExpr,
|
||||
partitions: &Option<Partitions>,
|
||||
|
||||
@@ -20,13 +20,12 @@ use common_meta::key::table_route::TableRouteValue;
|
||||
use common_meta::key::TableMetadataManager;
|
||||
use common_meta::kv_backend::KvBackendRef;
|
||||
use common_meta::peer::Peer;
|
||||
use common_meta::rpc::router::{Region, RegionRoute};
|
||||
use common_meta::rpc::router::{LegacyPartition, Region, RegionRoute};
|
||||
use datatypes::prelude::ConcreteDataType;
|
||||
use datatypes::schema::{ColumnSchema, SchemaBuilder};
|
||||
use moka::future::CacheBuilder;
|
||||
use partition::expr::{Operand, PartitionExpr, RestrictedOp};
|
||||
use partition::manager::{PartitionRuleManager, PartitionRuleManagerRef};
|
||||
use partition::partition::{PartitionBound, PartitionDef};
|
||||
use store_api::storage::RegionNumber;
|
||||
use table::metadata::{TableInfo, TableInfoBuilder, TableMetaBuilder};
|
||||
|
||||
@@ -163,18 +162,10 @@ pub(crate) async fn create_partition_rule_manager(
|
||||
id: 1.into(),
|
||||
name: "r3".to_string(),
|
||||
// Keep the old partition definition to test compatibility.
|
||||
partition: Some(
|
||||
PartitionDef::new(
|
||||
vec!["a".to_string()],
|
||||
vec![PartitionBound::Expr(PartitionExpr::new(
|
||||
Operand::Column("a".to_string()),
|
||||
RestrictedOp::GtEq,
|
||||
Operand::Value(datatypes::value::Value::Int32(50)),
|
||||
))],
|
||||
)
|
||||
.try_into()
|
||||
.unwrap(),
|
||||
),
|
||||
partition: Some(LegacyPartition {
|
||||
column_list: vec![b"a".to_vec()],
|
||||
value_list: vec![b"{\"Expr\":{\"lhs\":{\"Column\":\"a\"},\"op\":\"GtEq\",\"rhs\":{\"Value\":{\"Int32\":50}}}}".to_vec()],
|
||||
}),
|
||||
attrs: BTreeMap::new(),
|
||||
partition_expr: Default::default(),
|
||||
},
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
use std::fmt::{Debug, Display, Formatter};
|
||||
use std::sync::Arc;
|
||||
|
||||
use api::v1::meta::Partition;
|
||||
use datafusion_common::{ScalarValue, ToDFSchema};
|
||||
use datafusion_expr::execution_props::ExecutionProps;
|
||||
use datafusion_expr::Expr;
|
||||
@@ -291,6 +292,14 @@ impl PartitionExpr {
|
||||
_ => Ok(None),
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts [Self] to [Partition].
|
||||
pub fn as_pb_partition(&self) -> error::Result<Partition> {
|
||||
Ok(Partition {
|
||||
expression: self.as_json_str()?,
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for PartitionExpr {
|
||||
|
||||
@@ -14,18 +14,15 @@
|
||||
|
||||
use std::any::Any;
|
||||
use std::collections::HashMap;
|
||||
use std::fmt::{Debug, Display, Formatter};
|
||||
use std::fmt::Debug;
|
||||
use std::sync::Arc;
|
||||
|
||||
use common_meta::rpc::router::LegacyPartition as MetaPartition;
|
||||
use datatypes::arrow::array::{BooleanArray, RecordBatch};
|
||||
use datatypes::prelude::Value;
|
||||
use itertools::Itertools;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use snafu::ResultExt;
|
||||
use store_api::storage::RegionNumber;
|
||||
|
||||
use crate::error::{self, Error, Result};
|
||||
use crate::error::Result;
|
||||
|
||||
pub type PartitionRuleRef = Arc<dyn PartitionRule>;
|
||||
|
||||
@@ -58,106 +55,6 @@ pub enum PartitionBound {
|
||||
Expr(crate::expr::PartitionExpr),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct PartitionDef {
|
||||
partition_columns: Vec<String>,
|
||||
partition_bounds: Vec<PartitionBound>,
|
||||
}
|
||||
|
||||
impl Display for PartitionBound {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::Value(v) => write!(f, "{}", v),
|
||||
Self::MaxValue => write!(f, "MAXVALUE"),
|
||||
Self::Expr(e) => write!(f, "{}", e),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for PartitionDef {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"{}",
|
||||
self.partition_bounds
|
||||
.iter()
|
||||
.map(|b| format!("{b}"))
|
||||
.join(", ")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl PartitionDef {
|
||||
pub fn new(partition_columns: Vec<String>, partition_bounds: Vec<PartitionBound>) -> Self {
|
||||
Self {
|
||||
partition_columns,
|
||||
partition_bounds,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn partition_columns(&self) -> &Vec<String> {
|
||||
&self.partition_columns
|
||||
}
|
||||
|
||||
pub fn partition_bounds(&self) -> &Vec<PartitionBound> {
|
||||
&self.partition_bounds
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<&MetaPartition> for PartitionDef {
|
||||
type Error = Error;
|
||||
|
||||
fn try_from(partition: &MetaPartition) -> Result<Self> {
|
||||
let MetaPartition {
|
||||
column_list,
|
||||
value_list,
|
||||
} = partition;
|
||||
|
||||
let partition_columns = column_list
|
||||
.iter()
|
||||
.map(|x| String::from_utf8_lossy(x).to_string())
|
||||
.collect::<Vec<String>>();
|
||||
|
||||
let partition_bounds = value_list
|
||||
.iter()
|
||||
.map(|x| serde_json::from_str(&String::from_utf8_lossy(x)))
|
||||
.collect::<std::result::Result<Vec<PartitionBound>, serde_json::Error>>()
|
||||
.context(error::DeserializeJsonSnafu)?;
|
||||
|
||||
Ok(PartitionDef {
|
||||
partition_columns,
|
||||
partition_bounds,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<PartitionDef> for MetaPartition {
|
||||
type Error = Error;
|
||||
|
||||
fn try_from(partition: PartitionDef) -> Result<Self> {
|
||||
let PartitionDef {
|
||||
partition_columns: columns,
|
||||
partition_bounds: bounds,
|
||||
} = partition;
|
||||
|
||||
let column_list = columns
|
||||
.into_iter()
|
||||
.map(|x| x.into_bytes())
|
||||
.collect::<Vec<Vec<u8>>>();
|
||||
|
||||
let value_list = bounds
|
||||
.into_iter()
|
||||
.map(|x| serde_json::to_string(&x).map(|s| s.into_bytes()))
|
||||
.collect::<std::result::Result<Vec<Vec<u8>>, serde_json::Error>>()
|
||||
.context(error::SerializeJsonSnafu)?;
|
||||
|
||||
Ok(MetaPartition {
|
||||
column_list,
|
||||
value_list,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub struct RegionMask {
|
||||
array: BooleanArray,
|
||||
selected_rows: usize,
|
||||
@@ -199,57 +96,3 @@ impl RegionMask {
|
||||
self.selected_rows
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_partition_def() {
|
||||
// PartitionDef -> MetaPartition
|
||||
let def = PartitionDef {
|
||||
partition_columns: vec!["a".to_string(), "b".to_string()],
|
||||
partition_bounds: vec![
|
||||
PartitionBound::MaxValue,
|
||||
PartitionBound::Value(1_i32.into()),
|
||||
],
|
||||
};
|
||||
assert_eq!("MAXVALUE, 1", def.to_string());
|
||||
|
||||
let partition: MetaPartition = def.try_into().unwrap();
|
||||
assert_eq!(
|
||||
r#"{"column_list":["a","b"],"value_list":["\"MaxValue\"","{\"Value\":{\"Int32\":1}}"]}"#,
|
||||
serde_json::to_string(&partition).unwrap(),
|
||||
);
|
||||
|
||||
// MetaPartition -> PartitionDef
|
||||
let partition = &MetaPartition {
|
||||
column_list: vec![b"a".to_vec(), b"b".to_vec()],
|
||||
value_list: vec![
|
||||
b"\"MaxValue\"".to_vec(),
|
||||
b"{\"Value\":{\"Int32\":1}}".to_vec(),
|
||||
],
|
||||
};
|
||||
let def: PartitionDef = partition.try_into().unwrap();
|
||||
assert_eq!(
|
||||
def.partition_columns,
|
||||
vec!["a".to_string(), "b".to_string()]
|
||||
);
|
||||
assert_eq!(
|
||||
def.partition_bounds,
|
||||
vec![
|
||||
PartitionBound::MaxValue,
|
||||
PartitionBound::Value(1_i32.into())
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_partition_bound() {
|
||||
let b1 = PartitionBound::Value(1_i32.into());
|
||||
let b2 = PartitionBound::Value(100_i32.into());
|
||||
let b3 = PartitionBound::MaxValue;
|
||||
assert!(b1 < b2);
|
||||
assert!(b2 < b3);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,14 +16,13 @@ use std::sync::Arc;
|
||||
|
||||
use common_query::AddColumnLocation;
|
||||
use datatypes::types::cast;
|
||||
use partition::partition::PartitionDef;
|
||||
use rand::Rng;
|
||||
use snafu::{ensure, OptionExt};
|
||||
|
||||
use crate::error::{self, Result};
|
||||
use crate::generator::Random;
|
||||
use crate::ir::alter_expr::{AlterTableOperation, AlterTableOption};
|
||||
use crate::ir::create_expr::ColumnOption;
|
||||
use crate::ir::create_expr::{ColumnOption, PartitionDef};
|
||||
use crate::ir::{AlterTableExpr, Column, CreateTableExpr, Ident};
|
||||
|
||||
pub type TableContextRef = Arc<TableContext>;
|
||||
|
||||
@@ -18,7 +18,6 @@ use datatypes::data_type::ConcreteDataType;
|
||||
use datatypes::value::Value;
|
||||
use derive_builder::Builder;
|
||||
use partition::expr::{Operand, PartitionExpr, RestrictedOp};
|
||||
use partition::partition::{PartitionBound, PartitionDef};
|
||||
use rand::seq::SliceRandom;
|
||||
use rand::Rng;
|
||||
use snafu::{ensure, ResultExt};
|
||||
@@ -28,9 +27,11 @@ use crate::context::TableContextRef;
|
||||
use crate::error::{self, Error, Result};
|
||||
use crate::fake::{random_capitalize_map, MappedGenerator, WordGenerator};
|
||||
use crate::generator::{ColumnOptionGenerator, ConcreteDataTypeGenerator, Random};
|
||||
use crate::ir::create_expr::{ColumnOption, CreateDatabaseExprBuilder, CreateTableExprBuilder};
|
||||
use crate::ir::create_expr::{
|
||||
ColumnOption, CreateDatabaseExprBuilder, CreateTableExprBuilder, PartitionDef,
|
||||
};
|
||||
use crate::ir::{
|
||||
column_options_generator, generate_columns, generate_partition_bounds, generate_random_value,
|
||||
column_options_generator, generate_columns, generate_partition_bounds,
|
||||
partible_column_options_generator, primary_key_options_generator, ts_column_options_generator,
|
||||
Column, ColumnTypeGenerator, CreateDatabaseExpr, CreateTableExpr, Ident,
|
||||
PartibleColumnTypeGenerator, StringColumnTypeGenerator, TsColumnTypeGenerator,
|
||||
@@ -108,25 +109,6 @@ impl<R: Rng + 'static> Generator<CreateTableExpr, R> for CreateTableExprGenerato
|
||||
self.ts_column_options_generator.as_ref(),
|
||||
)
|
||||
.remove(0);
|
||||
|
||||
if need_partible_column {
|
||||
// Generates partition bounds.
|
||||
let mut partition_bounds = Vec::with_capacity(self.partition);
|
||||
for _ in 0..self.partition - 1 {
|
||||
partition_bounds.push(PartitionBound::Value(generate_random_value(
|
||||
rng,
|
||||
&column.column_type,
|
||||
None,
|
||||
)));
|
||||
partition_bounds.sort();
|
||||
}
|
||||
partition_bounds.push(PartitionBound::MaxValue);
|
||||
builder.partition(PartitionDef::new(
|
||||
vec![name.value.to_string()],
|
||||
partition_bounds,
|
||||
));
|
||||
}
|
||||
|
||||
columns.push(column);
|
||||
} else {
|
||||
// Generates the partible column.
|
||||
@@ -202,16 +184,16 @@ fn generate_partition_def(
|
||||
column_name: Ident,
|
||||
) -> PartitionDef {
|
||||
let bounds = generate_partition_bounds(&column_type, partitions - 1);
|
||||
let mut partition_bounds = Vec::with_capacity(partitions);
|
||||
let mut partition_exprs = Vec::with_capacity(partitions);
|
||||
|
||||
let first_bound = bounds[0].clone();
|
||||
partition_bounds.push(PartitionBound::Expr(PartitionExpr::new(
|
||||
partition_exprs.push(PartitionExpr::new(
|
||||
Operand::Column(column_name.to_string()),
|
||||
RestrictedOp::Lt,
|
||||
Operand::Value(first_bound),
|
||||
)));
|
||||
));
|
||||
for bound_idx in 1..bounds.len() {
|
||||
partition_bounds.push(PartitionBound::Expr(PartitionExpr::new(
|
||||
partition_exprs.push(PartitionExpr::new(
|
||||
Operand::Expr(PartitionExpr::new(
|
||||
Operand::Column(column_name.to_string()),
|
||||
RestrictedOp::GtEq,
|
||||
@@ -223,16 +205,19 @@ fn generate_partition_def(
|
||||
RestrictedOp::Lt,
|
||||
Operand::Value(bounds[bound_idx].clone()),
|
||||
)),
|
||||
)));
|
||||
));
|
||||
}
|
||||
let last_bound = bounds.last().unwrap().clone();
|
||||
partition_bounds.push(PartitionBound::Expr(PartitionExpr::new(
|
||||
partition_exprs.push(PartitionExpr::new(
|
||||
Operand::Column(column_name.to_string()),
|
||||
RestrictedOp::GtEq,
|
||||
Operand::Value(last_bound),
|
||||
)));
|
||||
));
|
||||
|
||||
PartitionDef::new(vec![column_name.to_string()], partition_bounds)
|
||||
PartitionDef {
|
||||
columns: vec![column_name.to_string()],
|
||||
exprs: partition_exprs,
|
||||
}
|
||||
}
|
||||
|
||||
/// Generate a physical table with 2 columns: ts of TimestampType::Millisecond as time index and val of Float64Type.
|
||||
@@ -413,7 +398,7 @@ mod tests {
|
||||
assert_eq!(expr.engine, "mito2");
|
||||
assert!(expr.if_not_exists);
|
||||
assert_eq!(expr.columns.len(), 10);
|
||||
assert_eq!(expr.partition.unwrap().partition_bounds().len(), 3);
|
||||
assert_eq!(expr.partition.unwrap().exprs.len(), 3);
|
||||
|
||||
let expr = CreateTableExprGeneratorBuilder::default()
|
||||
.columns(10)
|
||||
@@ -440,7 +425,7 @@ mod tests {
|
||||
.unwrap();
|
||||
|
||||
let serialized = serde_json::to_string(&expr).unwrap();
|
||||
let expected = r#"{"table_name":{"value":"quasi","quote_style":null},"columns":[{"name":{"value":"mOLEsTIAs","quote_style":null},"column_type":{"Float64":{}},"options":["PrimaryKey","Null"]},{"name":{"value":"CUMQUe","quote_style":null},"column_type":{"Timestamp":{"Second":null}},"options":["TimeIndex"]},{"name":{"value":"NaTus","quote_style":null},"column_type":{"Int64":{}},"options":[]},{"name":{"value":"EXPeDITA","quote_style":null},"column_type":{"Float64":{}},"options":[]},{"name":{"value":"ImPEDiT","quote_style":null},"column_type":{"Float32":{}},"options":[{"DefaultValue":{"Float32":0.56425774}}]},{"name":{"value":"ADIpisci","quote_style":null},"column_type":{"Float32":{}},"options":["PrimaryKey"]},{"name":{"value":"deBITIs","quote_style":null},"column_type":{"Float32":{}},"options":[{"DefaultValue":{"Float32":0.31315368}}]},{"name":{"value":"toTaM","quote_style":null},"column_type":{"Int32":{}},"options":["NotNull"]},{"name":{"value":"QuI","quote_style":null},"column_type":{"Float32":{}},"options":[{"DefaultValue":{"Float32":0.39941502}}]},{"name":{"value":"INVeNtOre","quote_style":null},"column_type":{"Boolean":null},"options":["PrimaryKey"]}],"if_not_exists":true,"partition":{"partition_columns":["mOLEsTIAs"],"partition_bounds":[{"Expr":{"lhs":{"Column":"mOLEsTIAs"},"op":"Lt","rhs":{"Value":{"Float64":5.992310449541053e307}}}},{"Expr":{"lhs":{"Expr":{"lhs":{"Column":"mOLEsTIAs"},"op":"GtEq","rhs":{"Value":{"Float64":5.992310449541053e307}}}},"op":"And","rhs":{"Expr":{"lhs":{"Column":"mOLEsTIAs"},"op":"Lt","rhs":{"Value":{"Float64":1.1984620899082105e308}}}}}},{"Expr":{"lhs":{"Column":"mOLEsTIAs"},"op":"GtEq","rhs":{"Value":{"Float64":1.1984620899082105e308}}}}]},"engine":"mito2","options":{},"primary_keys":[0,5,9]}"#;
|
||||
let expected = r#"{"table_name":{"value":"quasi","quote_style":null},"columns":[{"name":{"value":"mOLEsTIAs","quote_style":null},"column_type":{"Float64":{}},"options":["PrimaryKey","Null"]},{"name":{"value":"CUMQUe","quote_style":null},"column_type":{"Timestamp":{"Second":null}},"options":["TimeIndex"]},{"name":{"value":"NaTus","quote_style":null},"column_type":{"Int64":{}},"options":[]},{"name":{"value":"EXPeDITA","quote_style":null},"column_type":{"Float64":{}},"options":[]},{"name":{"value":"ImPEDiT","quote_style":null},"column_type":{"Float32":{}},"options":[{"DefaultValue":{"Float32":0.56425774}}]},{"name":{"value":"ADIpisci","quote_style":null},"column_type":{"Float32":{}},"options":["PrimaryKey"]},{"name":{"value":"deBITIs","quote_style":null},"column_type":{"Float32":{}},"options":[{"DefaultValue":{"Float32":0.31315368}}]},{"name":{"value":"toTaM","quote_style":null},"column_type":{"Int32":{}},"options":["NotNull"]},{"name":{"value":"QuI","quote_style":null},"column_type":{"Float32":{}},"options":[{"DefaultValue":{"Float32":0.39941502}}]},{"name":{"value":"INVeNtOre","quote_style":null},"column_type":{"Boolean":null},"options":["PrimaryKey"]}],"if_not_exists":true,"partition":{"columns":["mOLEsTIAs"],"exprs":[{"lhs":{"Column":"mOLEsTIAs"},"op":"Lt","rhs":{"Value":{"Float64":5.992310449541053e307}}},{"lhs":{"Expr":{"lhs":{"Column":"mOLEsTIAs"},"op":"GtEq","rhs":{"Value":{"Float64":5.992310449541053e307}}}},"op":"And","rhs":{"Expr":{"lhs":{"Column":"mOLEsTIAs"},"op":"Lt","rhs":{"Value":{"Float64":1.1984620899082105e308}}}}},{"lhs":{"Column":"mOLEsTIAs"},"op":"GtEq","rhs":{"Value":{"Float64":1.1984620899082105e308}}}]},"engine":"mito2","options":{},"primary_keys":[0,5,9]}"#;
|
||||
assert_eq!(expected, serialized);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ use std::fmt::Display;
|
||||
|
||||
use datatypes::value::Value;
|
||||
use derive_builder::Builder;
|
||||
use partition::partition::PartitionDef;
|
||||
use partition::expr::PartitionExpr;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::ir::{Column, Ident};
|
||||
@@ -70,6 +70,12 @@ pub struct CreateTableExpr {
|
||||
pub primary_keys: Vec<usize>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct PartitionDef {
|
||||
pub columns: Vec<String>,
|
||||
pub exprs: Vec<PartitionExpr>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Builder, Clone, Serialize, Deserialize)]
|
||||
pub struct CreateDatabaseExpr {
|
||||
#[builder(setter(into))]
|
||||
|
||||
@@ -13,8 +13,6 @@
|
||||
// limitations under the License.
|
||||
|
||||
use datatypes::data_type::ConcreteDataType;
|
||||
use datatypes::value::Value;
|
||||
use partition::partition::PartitionBound;
|
||||
use sql::statements::concrete_data_type_to_sql_data_type;
|
||||
|
||||
use crate::error::{Error, Result};
|
||||
@@ -76,28 +74,17 @@ impl CreateTableExprTranslator {
|
||||
input.partition.as_ref().map(|partition| {
|
||||
format!(
|
||||
"PARTITION ON COLUMNS({}) (\n{}\n)",
|
||||
partition.partition_columns().join(", "),
|
||||
partition.columns.join(", "),
|
||||
partition
|
||||
.partition_bounds()
|
||||
.exprs
|
||||
.iter()
|
||||
.map(Self::format_partition_bound)
|
||||
.map(|expr| expr.to_parser_expr().to_string())
|
||||
.collect::<Vec<_>>()
|
||||
.join(",\n")
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
fn format_partition_bound(bound: &PartitionBound) -> String {
|
||||
match bound {
|
||||
PartitionBound::Value(v) => match v {
|
||||
Value::String(v) => format!("'{}'", v.as_utf8()),
|
||||
_ => format!("{v}"),
|
||||
},
|
||||
PartitionBound::MaxValue => "MAXVALUE".to_string(),
|
||||
PartitionBound::Expr(expr) => expr.to_parser_expr().to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
fn format_column_type(column_type: &ConcreteDataType) -> String {
|
||||
// Safety: We don't use the `Dictionary` type
|
||||
concrete_data_type_to_sql_data_type(column_type)
|
||||
@@ -183,10 +170,9 @@ impl CreateDatabaseExprTranslator {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use partition::expr::{Operand, PartitionExpr, RestrictedOp};
|
||||
use partition::partition::{PartitionBound, PartitionDef};
|
||||
|
||||
use super::CreateTableExprTranslator;
|
||||
use crate::ir::create_expr::{CreateDatabaseExprBuilder, CreateTableExprBuilder};
|
||||
use crate::ir::create_expr::{CreateDatabaseExprBuilder, CreateTableExprBuilder, PartitionDef};
|
||||
use crate::test_utils;
|
||||
use crate::translator::DslTranslator;
|
||||
|
||||
@@ -198,15 +184,15 @@ mod tests {
|
||||
.table_name("system_metrics")
|
||||
.engine("mito")
|
||||
.primary_keys(vec![0, 1])
|
||||
.partition(PartitionDef::new(
|
||||
vec!["idc".to_string()],
|
||||
vec![
|
||||
PartitionBound::Expr(PartitionExpr::new(
|
||||
.partition(PartitionDef {
|
||||
columns: vec!["idc".to_string()],
|
||||
exprs: vec![
|
||||
PartitionExpr::new(
|
||||
Operand::Column("idc".to_string()),
|
||||
RestrictedOp::Lt,
|
||||
Operand::Value(datatypes::value::Value::Int32(10)),
|
||||
)),
|
||||
PartitionBound::Expr(PartitionExpr::new(
|
||||
),
|
||||
PartitionExpr::new(
|
||||
Operand::Expr(PartitionExpr::new(
|
||||
Operand::Column("idc".to_string()),
|
||||
RestrictedOp::GtEq,
|
||||
@@ -218,14 +204,14 @@ mod tests {
|
||||
RestrictedOp::Lt,
|
||||
Operand::Value(datatypes::value::Value::Int32(50)),
|
||||
)),
|
||||
)),
|
||||
PartitionBound::Expr(PartitionExpr::new(
|
||||
),
|
||||
PartitionExpr::new(
|
||||
Operand::Column("idc".to_string()),
|
||||
RestrictedOp::GtEq,
|
||||
Operand::Value(datatypes::value::Value::Int32(50)),
|
||||
)),
|
||||
),
|
||||
],
|
||||
))
|
||||
})
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user