mirror of
https://github.com/GreptimeTeam/greptimedb.git
synced 2026-05-27 02:10:38 +00:00
feat: Add DROP DEFAULT (#6290)
* feat: Add `DROP DEFAULT` Signed-off-by: Yihai Lin <yihai-lin@foxmail.com> * chore: use `next_token` Signed-off-by: Yihai Lin <yihai-lin@foxmail.com> --------- Signed-off-by: Yihai Lin <yihai-lin@foxmail.com>
This commit is contained in:
@@ -30,7 +30,7 @@ use crate::parsers::utils::{
|
||||
};
|
||||
use crate::statements::alter::{
|
||||
AddColumn, AlterDatabase, AlterDatabaseOperation, AlterTable, AlterTableOperation,
|
||||
KeyValueOption, SetIndexOperation, UnsetIndexOperation,
|
||||
DropDefaultsOperation, KeyValueOption, SetIndexOperation, UnsetIndexOperation,
|
||||
};
|
||||
use crate::statements::statement::Statement;
|
||||
use crate::util::parse_option_string;
|
||||
@@ -156,6 +156,7 @@ impl ParserContext<'_> {
|
||||
.collect();
|
||||
AlterTableOperation::SetTableOptions { options }
|
||||
}
|
||||
Keyword::ALTER => self.parse_alter_columns()?,
|
||||
_ => self.expected(
|
||||
"ADD or DROP or MODIFY or RENAME or SET after ALTER TABLE",
|
||||
self.parser.peek_token(),
|
||||
@@ -168,6 +169,29 @@ impl ParserContext<'_> {
|
||||
Ok(AlterTable::new(table_name, alter_operation))
|
||||
}
|
||||
|
||||
// Parse the following: ALTER TABLE table_name ALTER ...
|
||||
fn parse_alter_columns(&mut self) -> Result<AlterTableOperation> {
|
||||
let _ = self.parser.next_token();
|
||||
let _ = self.parser.next_token();
|
||||
let ts = self.parser.next_token();
|
||||
match ts.token {
|
||||
// Parse `DROP DEFAULT`: ALTER TABLE `table_name` ALTER `a` DROP DEFAULT, ALTER `b` DROP DEFAULT, ...
|
||||
Token::Word(w) if w.keyword == Keyword::DROP => {
|
||||
let ts = self.parser.peek_token();
|
||||
match ts.token {
|
||||
Token::Word(w) if w.keyword == Keyword::DEFAULT => {
|
||||
self.parser.prev_token();
|
||||
self.parser.prev_token();
|
||||
self.parser.prev_token();
|
||||
self.parse_alter_table_drop_default()
|
||||
}
|
||||
_ => self.expected("DEFAULT is expecting after DROP", ts),
|
||||
}
|
||||
}
|
||||
_ => self.expected("DROP after ALTER COLUMN", ts),
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_alter_table_unset(&mut self) -> Result<AlterTableOperation> {
|
||||
let _ = self.parser.next_token();
|
||||
let keys = self
|
||||
@@ -198,6 +222,14 @@ impl ParserContext<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_alter_table_drop_default(&mut self) -> Result<AlterTableOperation> {
|
||||
let columns = self
|
||||
.parser
|
||||
.parse_comma_separated(parse_alter_column_drop_default)
|
||||
.context(error::SyntaxSnafu)?;
|
||||
Ok(AlterTableOperation::DropDefaults { columns })
|
||||
}
|
||||
|
||||
fn parse_alter_table_modify(&mut self) -> Result<AlterTableOperation> {
|
||||
let _ = self.parser.next_token();
|
||||
self.parser
|
||||
@@ -385,6 +417,23 @@ impl ParserContext<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_alter_column_drop_default(
|
||||
parser: &mut Parser,
|
||||
) -> std::result::Result<DropDefaultsOperation, ParserError> {
|
||||
parser.next_token();
|
||||
let column_name = ParserContext::canonicalize_identifier(parser.parse_identifier()?);
|
||||
if parser.parse_keywords(&[Keyword::DROP, Keyword::DEFAULT]) {
|
||||
Ok(DropDefaultsOperation(column_name))
|
||||
} else {
|
||||
let not_drop = parser.peek_token();
|
||||
parser.next_token();
|
||||
let not_default = parser.peek_token();
|
||||
Err(ParserError::ParserError(format!(
|
||||
"Unexpected keyword, expect DROP DEFAULT, got: `{not_drop} {not_default}`"
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
||||
/// Parses a string literal and an optional string literal value.
|
||||
fn parse_string_options(parser: &mut Parser) -> std::result::Result<(String, String), ParserError> {
|
||||
let name = parser.parse_literal_string()?;
|
||||
@@ -1125,4 +1174,42 @@ mod tests {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_alter_drop_default() {
|
||||
let columns = vec![vec!["a"], vec!["a", "b", "c"]];
|
||||
for col in columns {
|
||||
let sql = col
|
||||
.iter()
|
||||
.map(|x| format!("ALTER {x} DROP DEFAULT"))
|
||||
.collect::<Vec<String>>()
|
||||
.join(",");
|
||||
let sql = format!("ALTER TABLE test_table {sql}");
|
||||
let mut result = ParserContext::create_with_dialect(
|
||||
&sql,
|
||||
&GreptimeDbDialect {},
|
||||
ParseOptions::default(),
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(1, result.len());
|
||||
let statement = result.remove(0);
|
||||
assert_matches!(statement, Statement::AlterTable { .. });
|
||||
match statement {
|
||||
Statement::AlterTable(alter_table) => {
|
||||
assert_eq!("test_table", alter_table.table_name().0[0].value);
|
||||
let alter_operation = alter_table.alter_operation();
|
||||
match alter_operation {
|
||||
AlterTableOperation::DropDefaults { columns } => {
|
||||
assert_eq!(col.len(), columns.len());
|
||||
for i in 0..columns.len() {
|
||||
assert_eq!(col[i], columns[i].0.value);
|
||||
}
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,8 +92,15 @@ pub enum AlterTableOperation {
|
||||
UnsetIndex {
|
||||
options: UnsetIndexOperation,
|
||||
},
|
||||
DropDefaults {
|
||||
columns: Vec<DropDefaultsOperation>,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
|
||||
/// `ALTER <column_name> DROP DEFAULT`
|
||||
pub struct DropDefaultsOperation(pub Ident);
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
|
||||
pub enum SetIndexOperation {
|
||||
/// `MODIFY COLUMN <column_name> SET FULLTEXT INDEX [WITH <options>]`
|
||||
@@ -204,6 +211,13 @@ impl Display for AlterTableOperation {
|
||||
write!(f, "MODIFY COLUMN {column_name} UNSET SKIPPING INDEX")
|
||||
}
|
||||
},
|
||||
AlterTableOperation::DropDefaults { columns } => {
|
||||
let columns = columns
|
||||
.iter()
|
||||
.map(|column| format!("ALTER {} DROP DEFAULT", column.0))
|
||||
.join(", ");
|
||||
write!(f, "{columns}")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -487,5 +501,26 @@ ALTER TABLE monitor MODIFY COLUMN a SET INVERTED INDEX"#,
|
||||
unreachable!();
|
||||
}
|
||||
}
|
||||
|
||||
let sql = "ALTER TABLE monitor ALTER a DROP DEFAULT";
|
||||
let stmts =
|
||||
ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default())
|
||||
.unwrap();
|
||||
assert_eq!(1, stmts.len());
|
||||
assert_matches!(&stmts[0], Statement::AlterTable { .. });
|
||||
|
||||
match &stmts[0] {
|
||||
Statement::AlterTable(set) => {
|
||||
let new_sql = format!("\n{}", set);
|
||||
assert_eq!(
|
||||
r#"
|
||||
ALTER TABLE monitor ALTER a DROP DEFAULT"#,
|
||||
&new_sql
|
||||
);
|
||||
}
|
||||
_ => {
|
||||
unreachable!();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user