refactor: separate the quote char and value (#3455)

refactor: use ident instead of string
This commit is contained in:
Weny Xu
2024-03-07 16:24:09 +08:00
committed by GitHub
parent a218f12bd9
commit 3f3ef2e7af
14 changed files with 172 additions and 95 deletions

View File

@@ -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(),

View File

@@ -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)
}

View File

@@ -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

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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>,
}

View File

@@ -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![],
},

View File

@@ -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 },
}

View File

@@ -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,

View File

@@ -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],
},

View File

@@ -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();

View File

@@ -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();

View File

@@ -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();

View File

@@ -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();