mirror of
https://github.com/GreptimeTeam/greptimedb.git
synced 2026-05-24 08:50:40 +00:00
refactor: separate the quote char and value (#3455)
refactor: use ident instead of string
This commit is contained in:
@@ -16,13 +16,13 @@ use std::sync::Arc;
|
||||
|
||||
use partition::partition::PartitionDef;
|
||||
|
||||
use crate::ir::{Column, CreateTableExpr};
|
||||
use crate::ir::{Column, CreateTableExpr, Ident};
|
||||
|
||||
pub type TableContextRef = Arc<TableContext>;
|
||||
|
||||
/// TableContext stores table info.
|
||||
pub struct TableContext {
|
||||
pub name: String,
|
||||
pub name: Ident,
|
||||
pub columns: Vec<Column>,
|
||||
|
||||
// GreptimeDB specific options
|
||||
@@ -41,7 +41,7 @@ impl From<&CreateTableExpr> for TableContext {
|
||||
}: &CreateTableExpr,
|
||||
) -> Self {
|
||||
Self {
|
||||
name: name.to_string(),
|
||||
name: name.clone(),
|
||||
columns: columns.clone(),
|
||||
partition: partition.clone(),
|
||||
primary_keys: primary_keys.clone(),
|
||||
|
||||
@@ -21,6 +21,7 @@ use rand::Rng;
|
||||
|
||||
use crate::generator::Random;
|
||||
use crate::impl_random;
|
||||
use crate::ir::Ident;
|
||||
|
||||
lazy_static! {
|
||||
pub static ref LOREM_WORDS: Vec<String> = include_str!("data/lorem_words")
|
||||
@@ -49,7 +50,7 @@ macro_rules! faker_impl_from_values {
|
||||
pub struct Word(String);
|
||||
faker_impl_from_values!(Word, LOREM_WORDS);
|
||||
pub struct WordGenerator;
|
||||
impl_random!(String, WordGenerator, LOREM_WORDS);
|
||||
impl_random!(Ident, WordGenerator, LOREM_WORDS);
|
||||
|
||||
pub struct MappedGenerator<T, F, R, V>
|
||||
where
|
||||
@@ -63,15 +64,19 @@ where
|
||||
_v: PhantomData<V>,
|
||||
}
|
||||
|
||||
pub fn random_capitalize_map<R: Rng + 'static>(rng: &mut R, s: String) -> String {
|
||||
let mut v = s.chars().collect::<Vec<_>>();
|
||||
pub fn random_capitalize_map<R: Rng + 'static>(rng: &mut R, s: Ident) -> Ident {
|
||||
let mut v = s.value.chars().collect::<Vec<_>>();
|
||||
|
||||
let select = rng.gen_range(0..s.len());
|
||||
for idx in (0..s.len()).choose_multiple(rng, select) {
|
||||
let str_len = s.value.len();
|
||||
let select = rng.gen_range(0..str_len);
|
||||
for idx in (0..str_len).choose_multiple(rng, select) {
|
||||
v[idx] = v[idx].to_uppercase().next().unwrap();
|
||||
}
|
||||
|
||||
v.into_iter().collect::<String>()
|
||||
Ident {
|
||||
quote_style: s.quote_style,
|
||||
value: v.into_iter().collect::<String>(),
|
||||
}
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
@@ -98,12 +103,15 @@ pub fn is_keyword_or_contain_uppercase(s: &str) -> bool {
|
||||
|
||||
pub fn make_backtick_map<R: Rng + 'static, F: Fn(&str) -> bool>(
|
||||
f: F,
|
||||
) -> impl Fn(&mut R, String) -> String {
|
||||
move |_rng, s| -> String {
|
||||
let need = f(&s);
|
||||
) -> impl Fn(&mut R, Ident) -> Ident {
|
||||
move |_rng, s| -> Ident {
|
||||
let need = f(&s.value);
|
||||
|
||||
if need {
|
||||
format!("`{s}`")
|
||||
Ident {
|
||||
value: s.value,
|
||||
quote_style: Some('`'),
|
||||
}
|
||||
} else {
|
||||
s
|
||||
}
|
||||
@@ -112,12 +120,15 @@ pub fn make_backtick_map<R: Rng + 'static, F: Fn(&str) -> bool>(
|
||||
|
||||
pub fn make_quote_map<R: Rng + 'static, F: Fn(&str) -> bool>(
|
||||
f: F,
|
||||
) -> impl Fn(&mut R, String) -> String {
|
||||
move |_rng, s| -> String {
|
||||
let need = f(&s);
|
||||
) -> impl Fn(&mut R, Ident) -> Ident {
|
||||
move |_rng, s| -> Ident {
|
||||
let need = f(&s.value);
|
||||
|
||||
if need {
|
||||
format!("\"{s}\"")
|
||||
Ident {
|
||||
value: s.value,
|
||||
quote_style: Some('"'),
|
||||
}
|
||||
} else {
|
||||
s
|
||||
}
|
||||
@@ -125,36 +136,39 @@ pub fn make_quote_map<R: Rng + 'static, F: Fn(&str) -> bool>(
|
||||
}
|
||||
|
||||
/// Adds backticks if it contains uppercase chars.
|
||||
pub fn auto_backtick_map<R: Rng + 'static>(_rng: &mut R, s: String) -> String {
|
||||
let need = s.chars().any(|c| c.is_uppercase());
|
||||
pub fn auto_backtick_map<R: Rng + 'static>(_rng: &mut R, s: Ident) -> Ident {
|
||||
let need = s.value.chars().any(|c| c.is_uppercase());
|
||||
|
||||
if need {
|
||||
format!("`{s}`")
|
||||
Ident {
|
||||
value: s.value,
|
||||
quote_style: Some('`'),
|
||||
}
|
||||
} else {
|
||||
s
|
||||
}
|
||||
}
|
||||
|
||||
/// Adds backticks if it contains uppercase chars.
|
||||
pub fn uppercase_and_keyword_backtick_map<R: Rng + 'static>(rng: &mut R, s: String) -> String {
|
||||
pub fn uppercase_and_keyword_backtick_map<R: Rng + 'static>(rng: &mut R, s: Ident) -> Ident {
|
||||
make_backtick_map(is_keyword_or_contain_uppercase)(rng, s)
|
||||
}
|
||||
|
||||
/// Adds quotes if it contains uppercase chars.
|
||||
pub fn auto_quote_map<R: Rng + 'static>(rng: &mut R, s: String) -> String {
|
||||
pub fn auto_quote_map<R: Rng + 'static>(rng: &mut R, s: Ident) -> Ident {
|
||||
make_quote_map(contain_uppercase_char)(rng, s)
|
||||
}
|
||||
|
||||
/// Adds quotes if it contains uppercase chars.
|
||||
pub fn uppercase_and_keyword_quote_map<R: Rng + 'static>(rng: &mut R, s: String) -> String {
|
||||
pub fn uppercase_and_keyword_quote_map<R: Rng + 'static>(rng: &mut R, s: Ident) -> Ident {
|
||||
make_quote_map(is_keyword_or_contain_uppercase)(rng, s)
|
||||
}
|
||||
|
||||
pub fn merge_two_word_map_fn<R: Rng>(
|
||||
f1: impl Fn(&mut R, String) -> String,
|
||||
f2: impl Fn(&mut R, String) -> String,
|
||||
) -> impl Fn(&mut R, String) -> String {
|
||||
move |rng, s| -> String {
|
||||
f1: impl Fn(&mut R, Ident) -> Ident,
|
||||
f2: impl Fn(&mut R, Ident) -> Ident,
|
||||
) -> impl Fn(&mut R, Ident) -> Ident {
|
||||
move |rng, s| -> Ident {
|
||||
let s = f1(rng, s);
|
||||
f2(rng, s)
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ macro_rules! impl_random {
|
||||
while result.len() != amount {
|
||||
result.insert($values.choose(rng).unwrap().clone());
|
||||
}
|
||||
let mut result = result.into_iter().collect::<Vec<_>>();
|
||||
let mut result = result.into_iter().map(Into::into).collect::<Vec<_>>();
|
||||
// Shuffles the result slice.
|
||||
result.shuffle(rng);
|
||||
result
|
||||
|
||||
@@ -25,7 +25,7 @@ use crate::fake::WordGenerator;
|
||||
use crate::generator::{ColumnOptionGenerator, ConcreteDataTypeGenerator, Generator, Random};
|
||||
use crate::ir::alter_expr::{AlterTableExpr, AlterTableOperation};
|
||||
use crate::ir::{
|
||||
column_options_generator, droppable_columns, generate_columns, ColumnTypeGenerator,
|
||||
column_options_generator, droppable_columns, generate_columns, ColumnTypeGenerator, Ident,
|
||||
};
|
||||
|
||||
/// Generates the [AlterTableOperation::AddColumn] of [AlterTableExpr].
|
||||
@@ -36,7 +36,7 @@ pub struct AlterExprAddColumnGenerator<R: Rng + 'static> {
|
||||
#[builder(default)]
|
||||
location: bool,
|
||||
#[builder(default = "Box::new(WordGenerator)")]
|
||||
name_generator: Box<dyn Random<String, R>>,
|
||||
name_generator: Box<dyn Random<Ident, R>>,
|
||||
#[builder(default = "Box::new(column_options_generator)")]
|
||||
column_options_generator: ColumnOptionGenerator<R>,
|
||||
#[builder(default = "Box::new(ColumnTypeGenerator)")]
|
||||
@@ -74,7 +74,7 @@ impl<R: Rng + 'static> Generator<AlterTableExpr, R> for AlterExprAddColumnGenera
|
||||
)
|
||||
.remove(0);
|
||||
Ok(AlterTableExpr {
|
||||
table_name: self.table_ctx.name.to_string(),
|
||||
table_name: self.table_ctx.name.clone(),
|
||||
alter_options: AlterTableOperation::AddColumn { column, location },
|
||||
})
|
||||
}
|
||||
@@ -95,11 +95,9 @@ impl<R: Rng> Generator<AlterTableExpr, R> for AlterExprDropColumnGenerator<R> {
|
||||
fn generate(&self, rng: &mut R) -> Result<AlterTableExpr> {
|
||||
let droppable = droppable_columns(&self.table_ctx.columns);
|
||||
ensure!(!droppable.is_empty(), error::DroppableColumnsSnafu);
|
||||
let name = droppable[rng.gen_range(0..droppable.len())]
|
||||
.name
|
||||
.to_string();
|
||||
let name = droppable[rng.gen_range(0..droppable.len())].name.clone();
|
||||
Ok(AlterTableExpr {
|
||||
table_name: self.table_ctx.name.to_string(),
|
||||
table_name: self.table_ctx.name.clone(),
|
||||
alter_options: AlterTableOperation::DropColumn { name },
|
||||
})
|
||||
}
|
||||
@@ -111,7 +109,7 @@ impl<R: Rng> Generator<AlterTableExpr, R> for AlterExprDropColumnGenerator<R> {
|
||||
pub struct AlterExprRenameGenerator<R: Rng> {
|
||||
table_ctx: TableContextRef,
|
||||
#[builder(default = "Box::new(WordGenerator)")]
|
||||
name_generator: Box<dyn Random<String, R>>,
|
||||
name_generator: Box<dyn Random<Ident, R>>,
|
||||
}
|
||||
|
||||
impl<R: Rng> Generator<AlterTableExpr, R> for AlterExprRenameGenerator<R> {
|
||||
@@ -120,7 +118,7 @@ impl<R: Rng> Generator<AlterTableExpr, R> for AlterExprRenameGenerator<R> {
|
||||
fn generate(&self, rng: &mut R) -> Result<AlterTableExpr> {
|
||||
let new_table_name = self.name_generator.gen(rng);
|
||||
Ok(AlterTableExpr {
|
||||
table_name: self.table_ctx.name.to_string(),
|
||||
table_name: self.table_ctx.name.clone(),
|
||||
alter_options: AlterTableOperation::RenameTable { new_table_name },
|
||||
})
|
||||
}
|
||||
@@ -155,7 +153,7 @@ mod tests {
|
||||
.generate(&mut rng)
|
||||
.unwrap();
|
||||
let serialized = serde_json::to_string(&expr).unwrap();
|
||||
let expected = r#"{"table_name":"animI","alter_options":{"AddColumn":{"column":{"name":"velit","column_type":{"Int32":{}},"options":[{"DefaultValue":{"Int32":853246610}}]},"location":null}}}"#;
|
||||
let expected = r#"{"table_name":{"value":"animI","quote_style":null},"alter_options":{"AddColumn":{"column":{"name":{"value":"velit","quote_style":null},"column_type":{"Int32":{}},"options":[{"DefaultValue":{"Int32":853246610}}]},"location":null}}}"#;
|
||||
assert_eq!(expected, serialized);
|
||||
|
||||
let expr = AlterExprRenameGeneratorBuilder::default()
|
||||
@@ -165,8 +163,7 @@ mod tests {
|
||||
.generate(&mut rng)
|
||||
.unwrap();
|
||||
let serialized = serde_json::to_string(&expr).unwrap();
|
||||
let expected =
|
||||
r#"{"table_name":"animI","alter_options":{"RenameTable":{"new_table_name":"iure"}}}"#;
|
||||
let expected = r#"{"table_name":{"value":"animI","quote_style":null},"alter_options":{"RenameTable":{"new_table_name":{"value":"iure","quote_style":null}}}}"#;
|
||||
assert_eq!(expected, serialized);
|
||||
|
||||
let expr = AlterExprDropColumnGeneratorBuilder::default()
|
||||
@@ -176,7 +173,7 @@ mod tests {
|
||||
.generate(&mut rng)
|
||||
.unwrap();
|
||||
let serialized = serde_json::to_string(&expr).unwrap();
|
||||
let expected = r#"{"table_name":"animI","alter_options":{"DropColumn":{"name":"toTAm"}}}"#;
|
||||
let expected = r#"{"table_name":{"value":"animI","quote_style":null},"alter_options":{"DropColumn":{"name":{"value":"toTAm","quote_style":null}}}}"#;
|
||||
assert_eq!(expected, serialized);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ use crate::ir::create_expr::CreateTableExprBuilder;
|
||||
use crate::ir::{
|
||||
column_options_generator, generate_columns, generate_random_value,
|
||||
partible_column_options_generator, ts_column_options_generator, ColumnTypeGenerator,
|
||||
CreateTableExpr, PartibleColumnTypeGenerator, TsColumnTypeGenerator,
|
||||
CreateTableExpr, Ident, PartibleColumnTypeGenerator, TsColumnTypeGenerator,
|
||||
};
|
||||
|
||||
#[derive(Builder)]
|
||||
@@ -39,7 +39,7 @@ pub struct CreateTableExprGenerator<R: Rng + 'static> {
|
||||
if_not_exists: bool,
|
||||
#[builder(setter(into))]
|
||||
name: String,
|
||||
name_generator: Box<dyn Random<String, R>>,
|
||||
name_generator: Box<dyn Random<Ident, R>>,
|
||||
ts_column_type_generator: ConcreteDataTypeGenerator<R>,
|
||||
column_type_generator: ConcreteDataTypeGenerator<R>,
|
||||
partible_column_type_generator: ConcreteDataTypeGenerator<R>,
|
||||
@@ -93,7 +93,7 @@ impl<R: Rng + 'static> Generator<CreateTableExpr, R> for CreateTableExprGenerato
|
||||
let name = column_names.pop().unwrap();
|
||||
let column = generate_columns(
|
||||
rng,
|
||||
vec![name.to_string()],
|
||||
vec![name.clone()],
|
||||
self.ts_column_type_generator.as_ref(),
|
||||
self.ts_column_options_generator.as_ref(),
|
||||
)
|
||||
@@ -111,7 +111,10 @@ impl<R: Rng + 'static> Generator<CreateTableExpr, R> for CreateTableExprGenerato
|
||||
partition_bounds.sort();
|
||||
}
|
||||
partition_bounds.push(PartitionBound::MaxValue);
|
||||
builder.partition(PartitionDef::new(vec![name], partition_bounds));
|
||||
builder.partition(PartitionDef::new(
|
||||
vec![name.value.to_string()],
|
||||
partition_bounds,
|
||||
));
|
||||
}
|
||||
|
||||
columns.push(column);
|
||||
@@ -122,7 +125,7 @@ impl<R: Rng + 'static> Generator<CreateTableExpr, R> for CreateTableExprGenerato
|
||||
let name = column_names.pop().unwrap();
|
||||
let column = generate_columns(
|
||||
rng,
|
||||
vec![name.to_string()],
|
||||
vec![name.clone()],
|
||||
self.partible_column_type_generator.as_ref(),
|
||||
self.partible_column_options_generator.as_ref(),
|
||||
)
|
||||
@@ -139,7 +142,10 @@ impl<R: Rng + 'static> Generator<CreateTableExpr, R> for CreateTableExprGenerato
|
||||
partition_bounds.sort();
|
||||
}
|
||||
partition_bounds.push(PartitionBound::MaxValue);
|
||||
builder.partition(PartitionDef::new(vec![name], partition_bounds));
|
||||
builder.partition(PartitionDef::new(
|
||||
vec![name.value.to_string()],
|
||||
partition_bounds,
|
||||
));
|
||||
columns.push(column);
|
||||
}
|
||||
// Generates the ts column.
|
||||
@@ -230,7 +236,7 @@ mod tests {
|
||||
.unwrap();
|
||||
|
||||
let serialized = serde_json::to_string(&expr).unwrap();
|
||||
let expected = r#"{"table_name":"tEmporIbUS","columns":[{"name":"IMpEdIT","column_type":{"String":null},"options":["PrimaryKey","NotNull"]},{"name":"natuS","column_type":{"Timestamp":{"Nanosecond":null}},"options":["TimeIndex"]},{"name":"ADIPisCI","column_type":{"Int16":{}},"options":[{"DefaultValue":{"Int16":4864}}]},{"name":"EXpEdita","column_type":{"Int64":{}},"options":["PrimaryKey"]},{"name":"cUlpA","column_type":{"Float64":{}},"options":["NotNull"]},{"name":"MOLeStIAs","column_type":{"Boolean":null},"options":["Null"]},{"name":"cUmquE","column_type":{"Float32":{}},"options":[{"DefaultValue":{"Float32":0.21569687}}]},{"name":"toTAm","column_type":{"Float64":{}},"options":["NotNull"]},{"name":"deBitIs","column_type":{"Float32":{}},"options":["Null"]},{"name":"QUi","column_type":{"Int64":{}},"options":["Null"]}],"if_not_exists":true,"partition":{"partition_columns":["IMpEdIT"],"partition_bounds":[{"Value":{"String":""}},{"Value":{"String":""}},"MaxValue"]},"engine":"mito2","options":{},"primary_keys":[0,3]}"#;
|
||||
let expected = r#"{"table_name":{"value":"tEmporIbUS","quote_style":null},"columns":[{"name":{"value":"IMpEdIT","quote_style":null},"column_type":{"String":null},"options":["PrimaryKey","NotNull"]},{"name":{"value":"natuS","quote_style":null},"column_type":{"Timestamp":{"Nanosecond":null}},"options":["TimeIndex"]},{"name":{"value":"ADIPisCI","quote_style":null},"column_type":{"Int16":{}},"options":[{"DefaultValue":{"Int16":4864}}]},{"name":{"value":"EXpEdita","quote_style":null},"column_type":{"Int64":{}},"options":["PrimaryKey"]},{"name":{"value":"cUlpA","quote_style":null},"column_type":{"Float64":{}},"options":["NotNull"]},{"name":{"value":"MOLeStIAs","quote_style":null},"column_type":{"Boolean":null},"options":["Null"]},{"name":{"value":"cUmquE","quote_style":null},"column_type":{"Float32":{}},"options":[{"DefaultValue":{"Float32":0.21569687}}]},{"name":{"value":"toTAm","quote_style":null},"column_type":{"Float64":{}},"options":["NotNull"]},{"name":{"value":"deBitIs","quote_style":null},"column_type":{"Float32":{}},"options":["Null"]},{"name":{"value":"QUi","quote_style":null},"column_type":{"Int64":{}},"options":["Null"]}],"if_not_exists":true,"partition":{"partition_columns":["IMpEdIT"],"partition_bounds":[{"Value":{"String":""}},{"Value":{"String":""}},"MaxValue"]},"engine":"mito2","options":{},"primary_keys":[0,3]}"#;
|
||||
assert_eq!(expected, serialized);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,8 +22,8 @@ use crate::context::TableContextRef;
|
||||
use crate::error::{Error, Result};
|
||||
use crate::fake::WordGenerator;
|
||||
use crate::generator::{Generator, Random};
|
||||
use crate::ir::generate_random_value;
|
||||
use crate::ir::insert_expr::InsertIntoExpr;
|
||||
use crate::ir::{generate_random_value, Ident};
|
||||
|
||||
/// Generates [InsertIntoExpr].
|
||||
#[derive(Builder)]
|
||||
@@ -33,7 +33,7 @@ pub struct InsertExprGenerator<R: Rng + 'static> {
|
||||
#[builder(default = "1")]
|
||||
rows: usize,
|
||||
#[builder(default = "Box::new(WordGenerator)")]
|
||||
word_generator: Box<dyn Random<String, R>>,
|
||||
word_generator: Box<dyn Random<Ident, R>>,
|
||||
#[builder(default)]
|
||||
_phantom: PhantomData<R>,
|
||||
}
|
||||
|
||||
@@ -19,6 +19,8 @@ pub(crate) mod create_expr;
|
||||
pub(crate) mod insert_expr;
|
||||
pub(crate) mod select_expr;
|
||||
|
||||
use core::fmt;
|
||||
|
||||
pub use alter_expr::AlterTableExpr;
|
||||
pub use create_expr::CreateTableExpr;
|
||||
use datatypes::data_type::ConcreteDataType;
|
||||
@@ -76,7 +78,7 @@ pub struct PartibleColumnTypeGenerator;
|
||||
pub fn generate_random_value<R: Rng>(
|
||||
rng: &mut R,
|
||||
datatype: &ConcreteDataType,
|
||||
random_str: Option<&dyn Random<String, R>>,
|
||||
random_str: Option<&dyn Random<Ident, R>>,
|
||||
) -> Value {
|
||||
match datatype {
|
||||
&ConcreteDataType::Boolean(_) => Value::from(rng.gen::<bool>()),
|
||||
@@ -86,7 +88,7 @@ pub fn generate_random_value<R: Rng>(
|
||||
ConcreteDataType::Float32(_) => Value::from(rng.gen::<f32>()),
|
||||
ConcreteDataType::Float64(_) => Value::from(rng.gen::<f64>()),
|
||||
ConcreteDataType::String(_) => match random_str {
|
||||
Some(random) => Value::from(random.gen(rng)),
|
||||
Some(random) => Value::from(random.gen(rng).value),
|
||||
None => Value::from(rng.gen::<char>().to_string()),
|
||||
},
|
||||
ConcreteDataType::Date(_) => Value::from(rng.gen::<i32>()),
|
||||
@@ -97,11 +99,69 @@ pub fn generate_random_value<R: Rng>(
|
||||
}
|
||||
}
|
||||
|
||||
/// An identifier.
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||
pub struct Ident {
|
||||
pub value: String,
|
||||
pub quote_style: Option<char>,
|
||||
}
|
||||
|
||||
impl Ident {
|
||||
/// Creates a new identifier with the given value and no quotes.
|
||||
pub fn new<S>(value: S) -> Self
|
||||
where
|
||||
S: Into<String>,
|
||||
{
|
||||
Ident {
|
||||
value: value.into(),
|
||||
quote_style: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a new quoted identifier with the given quote and value.
|
||||
pub fn with_quote<S>(quote: char, value: S) -> Self
|
||||
where
|
||||
S: Into<String>,
|
||||
{
|
||||
Ident {
|
||||
value: value.into(),
|
||||
quote_style: Some(quote),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&str> for Ident {
|
||||
fn from(value: &str) -> Self {
|
||||
Ident {
|
||||
value: value.to_string(),
|
||||
quote_style: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<String> for Ident {
|
||||
fn from(value: String) -> Self {
|
||||
Ident {
|
||||
value,
|
||||
quote_style: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Ident {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self.quote_style {
|
||||
Some(q) => write!(f, "{q}{}{q}", self.value),
|
||||
None => f.write_str(&self.value),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The IR column.
|
||||
#[derive(Debug, Builder, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
|
||||
pub struct Column {
|
||||
#[builder(setter(into))]
|
||||
pub name: String,
|
||||
pub name: Ident,
|
||||
pub column_type: ConcreteDataType,
|
||||
#[builder(default, setter(into))]
|
||||
pub options: Vec<ColumnOption>,
|
||||
@@ -192,7 +252,7 @@ pub fn ts_column_options_generator<R: Rng + 'static>(
|
||||
/// Generates columns with given `names`.
|
||||
pub fn generate_columns<R: Rng + 'static>(
|
||||
rng: &mut R,
|
||||
names: impl IntoIterator<Item = String>,
|
||||
names: impl IntoIterator<Item = Ident>,
|
||||
types: &(impl Random<ConcreteDataType, R> + ?Sized),
|
||||
options: impl Fn(&mut R, &ConcreteDataType) -> Vec<ColumnOption>,
|
||||
) -> Vec<Column> {
|
||||
@@ -218,12 +278,12 @@ mod tests {
|
||||
fn test_droppable_columns() {
|
||||
let columns = vec![
|
||||
Column {
|
||||
name: "hi".to_string(),
|
||||
name: "hi".into(),
|
||||
column_type: ConcreteDataType::uint64_datatype(),
|
||||
options: vec![ColumnOption::PrimaryKey],
|
||||
},
|
||||
Column {
|
||||
name: "foo".to_string(),
|
||||
name: "foo".into(),
|
||||
column_type: ConcreteDataType::uint64_datatype(),
|
||||
options: vec![ColumnOption::TimeIndex],
|
||||
},
|
||||
@@ -233,12 +293,12 @@ mod tests {
|
||||
|
||||
let columns = vec![
|
||||
Column {
|
||||
name: "hi".to_string(),
|
||||
name: "hi".into(),
|
||||
column_type: ConcreteDataType::uint64_datatype(),
|
||||
options: vec![],
|
||||
},
|
||||
Column {
|
||||
name: "foo".to_string(),
|
||||
name: "foo".into(),
|
||||
column_type: ConcreteDataType::uint64_datatype(),
|
||||
options: vec![],
|
||||
},
|
||||
|
||||
@@ -16,11 +16,11 @@ use common_query::AddColumnLocation;
|
||||
use derive_builder::Builder;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::ir::Column;
|
||||
use crate::ir::{Column, Ident};
|
||||
|
||||
#[derive(Debug, Builder, Clone, Serialize, Deserialize)]
|
||||
pub struct AlterTableExpr {
|
||||
pub table_name: String,
|
||||
pub table_name: Ident,
|
||||
pub alter_options: AlterTableOperation,
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ pub enum AlterTableOperation {
|
||||
location: Option<AddColumnLocation>,
|
||||
},
|
||||
/// `DROP COLUMN <name>`
|
||||
DropColumn { name: String },
|
||||
DropColumn { name: Ident },
|
||||
/// `RENAME <new_table_name>`
|
||||
RenameTable { new_table_name: String },
|
||||
RenameTable { new_table_name: Ident },
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ use derive_builder::Builder;
|
||||
use partition::partition::PartitionDef;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::ir::Column;
|
||||
use crate::ir::{Column, Ident};
|
||||
|
||||
// The column options
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Hash)]
|
||||
@@ -50,7 +50,7 @@ impl Display for ColumnOption {
|
||||
#[derive(Debug, Builder, Clone, Serialize, Deserialize)]
|
||||
pub struct CreateTableExpr {
|
||||
#[builder(setter(into))]
|
||||
pub table_name: String,
|
||||
pub table_name: Ident,
|
||||
pub columns: Vec<Column>,
|
||||
#[builder(default)]
|
||||
pub if_not_exists: bool,
|
||||
|
||||
@@ -20,35 +20,35 @@ use crate::ir::Column;
|
||||
|
||||
pub fn new_test_ctx() -> TableContext {
|
||||
TableContext {
|
||||
name: "test".to_string(),
|
||||
name: "test".into(),
|
||||
columns: vec![
|
||||
Column {
|
||||
name: "host".to_string(),
|
||||
name: "host".into(),
|
||||
column_type: ConcreteDataType::string_datatype(),
|
||||
options: vec![ColumnOption::PrimaryKey],
|
||||
},
|
||||
Column {
|
||||
name: "idc".to_string(),
|
||||
name: "idc".into(),
|
||||
column_type: ConcreteDataType::string_datatype(),
|
||||
options: vec![ColumnOption::PrimaryKey],
|
||||
},
|
||||
Column {
|
||||
name: "cpu_util".to_string(),
|
||||
name: "cpu_util".into(),
|
||||
column_type: ConcreteDataType::float64_datatype(),
|
||||
options: vec![],
|
||||
},
|
||||
Column {
|
||||
name: "memory_util".to_string(),
|
||||
name: "memory_util".into(),
|
||||
column_type: ConcreteDataType::float64_datatype(),
|
||||
options: vec![],
|
||||
},
|
||||
Column {
|
||||
name: "disk_util".to_string(),
|
||||
name: "disk_util".into(),
|
||||
column_type: ConcreteDataType::float64_datatype(),
|
||||
options: vec![],
|
||||
},
|
||||
Column {
|
||||
name: "ts".to_string(),
|
||||
name: "ts".into(),
|
||||
column_type: ConcreteDataType::timestamp_millisecond_datatype(),
|
||||
options: vec![ColumnOption::TimeIndex],
|
||||
},
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use std::fmt::Display;
|
||||
|
||||
use common_query::AddColumnLocation;
|
||||
use datatypes::data_type::ConcreteDataType;
|
||||
use sql::statements::concrete_data_type_to_sql_data_type;
|
||||
@@ -41,16 +43,16 @@ impl DslTranslator<AlterTableExpr, String> for AlterTableExprTranslator {
|
||||
}
|
||||
|
||||
impl AlterTableExprTranslator {
|
||||
fn format_drop(name: &str, column: &str) -> String {
|
||||
fn format_drop(name: impl Display, column: impl Display) -> String {
|
||||
format!("ALTER TABLE {name} DROP COLUMN {column};")
|
||||
}
|
||||
|
||||
fn format_rename(name: &str, new_name: &str) -> String {
|
||||
fn format_rename(name: impl Display, new_name: impl Display) -> String {
|
||||
format!("ALTER TABLE {name} RENAME {new_name};")
|
||||
}
|
||||
|
||||
fn format_add_column(
|
||||
name: &str,
|
||||
name: impl Display,
|
||||
column: &Column,
|
||||
location: &Option<AddColumnLocation>,
|
||||
) -> String {
|
||||
@@ -119,10 +121,10 @@ mod tests {
|
||||
#[test]
|
||||
fn test_alter_table_expr() {
|
||||
let alter_expr = AlterTableExpr {
|
||||
table_name: "test".to_string(),
|
||||
table_name: "test".into(),
|
||||
alter_options: AlterTableOperation::AddColumn {
|
||||
column: Column {
|
||||
name: "host".to_string(),
|
||||
name: "host".into(),
|
||||
column_type: ConcreteDataType::string_datatype(),
|
||||
options: vec![ColumnOption::PrimaryKey],
|
||||
},
|
||||
@@ -137,9 +139,9 @@ mod tests {
|
||||
);
|
||||
|
||||
let alter_expr = AlterTableExpr {
|
||||
table_name: "test".to_string(),
|
||||
table_name: "test".into(),
|
||||
alter_options: AlterTableOperation::RenameTable {
|
||||
new_table_name: "foo".to_string(),
|
||||
new_table_name: "foo".into(),
|
||||
},
|
||||
};
|
||||
|
||||
@@ -147,10 +149,8 @@ mod tests {
|
||||
assert_eq!("ALTER TABLE test RENAME foo;", output);
|
||||
|
||||
let alter_expr = AlterTableExpr {
|
||||
table_name: "test".to_string(),
|
||||
alter_options: AlterTableOperation::DropColumn {
|
||||
name: "foo".to_string(),
|
||||
},
|
||||
table_name: "test".into(),
|
||||
alter_options: AlterTableOperation::DropColumn { name: "foo".into() },
|
||||
};
|
||||
|
||||
let output = AlterTableExprTranslator.translate(&alter_expr).unwrap();
|
||||
|
||||
@@ -25,7 +25,7 @@ impl DslTranslator<InsertIntoExpr, String> for InsertIntoExprTranslator {
|
||||
let columns = input
|
||||
.columns
|
||||
.iter()
|
||||
.map(|c| c.name.as_str())
|
||||
.map(|c| c.name.to_string())
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
.to_string();
|
||||
|
||||
@@ -25,7 +25,7 @@ impl DslTranslator<SelectExpr, String> for SelectExprTranslator {
|
||||
let columns = input
|
||||
.columns
|
||||
.iter()
|
||||
.map(|c| c.name.as_str())
|
||||
.map(|c| c.name.to_string())
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
.to_string();
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use std::fmt::Display;
|
||||
|
||||
use datatypes::data_type::ConcreteDataType;
|
||||
use sql::statements::concrete_data_type_to_sql_data_type;
|
||||
|
||||
@@ -41,15 +43,15 @@ impl DslTranslator<AlterTableExpr, String> for AlterTableExprTranslator {
|
||||
}
|
||||
|
||||
impl AlterTableExprTranslator {
|
||||
fn format_drop(name: &str, column: &str) -> String {
|
||||
fn format_drop(name: impl Display, column: impl Display) -> String {
|
||||
format!("ALTER TABLE {name} DROP COLUMN {column};")
|
||||
}
|
||||
|
||||
fn format_rename(name: &str, new_name: &str) -> String {
|
||||
fn format_rename(name: impl Display, new_name: impl Display) -> String {
|
||||
format!("ALTER TABLE {name} RENAME TO {new_name};")
|
||||
}
|
||||
|
||||
fn format_add_column(name: &str, column: &Column) -> String {
|
||||
fn format_add_column(name: impl Display, column: &Column) -> String {
|
||||
format!(
|
||||
"{};",
|
||||
vec![format!(
|
||||
@@ -116,10 +118,10 @@ mod tests {
|
||||
#[test]
|
||||
fn test_alter_table_expr() {
|
||||
let alter_expr = AlterTableExpr {
|
||||
table_name: "test".to_string(),
|
||||
table_name: "test".into(),
|
||||
alter_options: AlterTableOperation::AddColumn {
|
||||
column: Column {
|
||||
name: "host".to_string(),
|
||||
name: "host".into(),
|
||||
column_type: ConcreteDataType::string_datatype(),
|
||||
options: vec![ColumnOption::PrimaryKey],
|
||||
},
|
||||
@@ -132,9 +134,9 @@ mod tests {
|
||||
assert_eq!("ALTER TABLE test ADD COLUMN host STRING;", output);
|
||||
|
||||
let alter_expr = AlterTableExpr {
|
||||
table_name: "test".to_string(),
|
||||
table_name: "test".into(),
|
||||
alter_options: AlterTableOperation::RenameTable {
|
||||
new_table_name: "foo".to_string(),
|
||||
new_table_name: "foo".into(),
|
||||
},
|
||||
};
|
||||
|
||||
@@ -142,10 +144,8 @@ mod tests {
|
||||
assert_eq!("ALTER TABLE test RENAME TO foo;", output);
|
||||
|
||||
let alter_expr = AlterTableExpr {
|
||||
table_name: "test".to_string(),
|
||||
alter_options: AlterTableOperation::DropColumn {
|
||||
name: "foo".to_string(),
|
||||
},
|
||||
table_name: "test".into(),
|
||||
alter_options: AlterTableOperation::DropColumn { name: "foo".into() },
|
||||
};
|
||||
|
||||
let output = AlterTableExprTranslator.translate(&alter_expr).unwrap();
|
||||
|
||||
Reference in New Issue
Block a user