fix(iotdb): use tree SQL for table cleanup

This commit is contained in:
t8y2 2026-06-09 22:26:42 +08:00
parent 35692bc53b
commit 56e1895e91
1 changed files with 46 additions and 3 deletions

View File

@ -1,7 +1,7 @@
use serde::{Deserialize, Serialize};
use crate::models::connection::DatabaseType;
use crate::sql_dialect::{is_schema_aware, quote_table_identifier};
use crate::sql_dialect::{is_schema_aware, qualified_table_name, quote_table_identifier};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
@ -162,7 +162,11 @@ pub fn build_drop_object_sql(options: DropObjectSqlOptions) -> String {
}
pub fn build_drop_table_sql(options: TableAdminSqlOptions) -> String {
format!("DROP TABLE {};", qualified_name(options.database_type, options.schema.as_deref(), &options.table_name))
let table = qualified_name(options.database_type, options.schema.as_deref(), &options.table_name);
if matches!(options.database_type, Some(DatabaseType::Iotdb)) {
return format!("DELETE TIMESERIES {};", iotdb_timeseries_pattern(&table));
}
format!("DROP TABLE {table};")
}
pub fn build_drop_table_child_object_sql(options: DropTableChildObjectSqlOptions) -> Result<String, String> {
@ -242,13 +246,16 @@ pub fn build_empty_table_sql(options: TableAdminSqlOptions) -> String {
Some(DatabaseType::ClickHouse) => format!("ALTER TABLE {table} DELETE WHERE 1 = 1;"),
Some(DatabaseType::Bigquery) => format!("DELETE FROM {table} WHERE TRUE;"),
Some(DatabaseType::Cassandra | DatabaseType::Hive | DatabaseType::Kylin) => format!("TRUNCATE TABLE {table};"),
Some(DatabaseType::Iotdb) => format!("DELETE FROM {};", iotdb_timeseries_pattern(&table)),
_ => format!("DELETE FROM {table};"),
}
}
pub fn build_truncate_table_sql(options: TableAdminSqlOptions) -> String {
let table = qualified_name(options.database_type, options.schema.as_deref(), &options.table_name);
if matches!(options.database_type, Some(DatabaseType::Sqlite | DatabaseType::DuckDb)) {
if matches!(options.database_type, Some(DatabaseType::Iotdb)) {
format!("DELETE FROM {};", iotdb_timeseries_pattern(&table))
} else if matches!(options.database_type, Some(DatabaseType::Sqlite | DatabaseType::DuckDb)) {
format!("DELETE FROM {table};")
} else {
format!("TRUNCATE TABLE {table};")
@ -409,6 +416,9 @@ fn quote_rename_identifier(database_type: Option<DatabaseType>, name: &str) -> S
}
fn qualified_name(database_type: Option<DatabaseType>, schema: Option<&str>, name: &str) -> String {
if matches!(database_type, Some(DatabaseType::Iotdb)) {
return qualified_table_name(database_type, schema, name);
}
if database_type.is_some_and(is_schema_aware) && schema.is_some_and(|schema| !schema.is_empty()) {
format!(
"{}.{}",
@ -420,6 +430,15 @@ fn qualified_name(database_type: Option<DatabaseType>, schema: Option<&str>, nam
}
}
fn iotdb_timeseries_pattern(path: &str) -> String {
let path = path.trim().trim_end_matches(';');
if path.ends_with(".*") || path.ends_with(".**") {
path.to_string()
} else {
format!("{path}.*")
}
}
fn sqlserver_object_name(schema: Option<&str>, name: &str) -> String {
schema
.filter(|schema| !schema.is_empty())
@ -559,6 +578,30 @@ mod tests {
}),
"DELETE FROM \"events\";"
);
assert_eq!(
build_drop_table_sql(TableAdminSqlOptions {
database_type: Some(DatabaseType::Iotdb),
schema: Some("root.test".to_string()),
table_name: "DCU_101".to_string(),
}),
"DELETE TIMESERIES root.test.DCU_101.*;"
);
assert_eq!(
build_empty_table_sql(TableAdminSqlOptions {
database_type: Some(DatabaseType::Iotdb),
schema: Some("root.test".to_string()),
table_name: "root.test.DCU_101".to_string(),
}),
"DELETE FROM root.test.DCU_101.*;"
);
assert_eq!(
build_truncate_table_sql(TableAdminSqlOptions {
database_type: Some(DatabaseType::Iotdb),
schema: Some("root.test".to_string()),
table_name: "DCU_101".to_string(),
}),
"DELETE FROM root.test.DCU_101.*;"
);
}
#[test]