feat: add QuestDB support
Thanks @ptma!
This commit is contained in:
1 parent
0ae720d950
commit
1afc271c18
51 files changed
+633
-46
No files matched your search
@@ -551,6 +551,29 @@ pub(super) fn build_sqlite_existing_column_sql(
|
||||
statements
|
||||
}
|
||||
|
||||
pub(super) fn build_questdb_existing_column_sql(table: &str, column: &EditableStructureColumn) -> Vec<String> {
|
||||
let Some(original) = &column.original else {
|
||||
return Vec::new();
|
||||
};
|
||||
let mut statements = Vec::new();
|
||||
let current_name = &column.name;
|
||||
if column.name != original.name {
|
||||
statements.push(format!(
|
||||
"ALTER TABLE {table} RENAME COLUMN {} TO {};",
|
||||
quote_ident(StructureDialect::Questdb, &original.name),
|
||||
quote_ident(StructureDialect::Questdb, &column.name)
|
||||
));
|
||||
}
|
||||
if column.data_type.trim() != original.data_type.trim() {
|
||||
statements.push(format!(
|
||||
"ALTER TABLE {table} ALTER COLUMN {} TYPE {};",
|
||||
quote_ident(StructureDialect::Questdb, current_name),
|
||||
column_data_type(StructureDialect::Questdb, column)
|
||||
));
|
||||
}
|
||||
statements
|
||||
}
|
||||
|
||||
pub(super) fn has_existing_column_attribute_change(column: &EditableStructureColumn) -> bool {
|
||||
let Some(original) = &column.original else {
|
||||
return false;
|
||||
|
||||
@@ -5,6 +5,11 @@ use super::util::{clean, format_default_for_sql, normalize_default, quote_ident,
|
||||
pub(super) fn column_definition(dialect: StructureDialect, column: &EditableStructureColumn) -> String {
|
||||
let data_type = column_data_type(dialect, column);
|
||||
let mut parts = vec![quote_ident(dialect, &column.name), data_type];
|
||||
// QuestDB SQL Syntax: ```ALTER TABLE tableName ADD COLUMN [IF NOT EXISTS] columnName typeDef```
|
||||
if dialect == StructureDialect::Questdb {
|
||||
parts.insert(0, "IF NOT EXISTS".to_string());
|
||||
return parts.join(" ");
|
||||
}
|
||||
if !column.is_nullable && !is_oracle_like(dialect) && dialect != StructureDialect::ClickHouse {
|
||||
parts.push("NOT NULL".to_string());
|
||||
}
|
||||
@@ -74,6 +79,9 @@ pub(super) fn column_data_type(dialect: StructureDialect, column: &EditableStruc
|
||||
if dialect == StructureDialect::ManticoreSearch {
|
||||
return manticore_column_type(column);
|
||||
}
|
||||
if dialect == StructureDialect::Questdb {
|
||||
return questdb_column_type(column);
|
||||
}
|
||||
normalize_column_data_type(dialect, &column.data_type)
|
||||
}
|
||||
|
||||
@@ -186,3 +194,22 @@ pub(super) fn unwrap_clickhouse_nullable_type(data_type: &str) -> String {
|
||||
trimmed.to_string()
|
||||
}
|
||||
}
|
||||
|
||||
/// QuestDB 类型处理
|
||||
/// geohash, decimal 这2种类型才能带()
|
||||
pub(super) fn questdb_column_type(column: &EditableStructureColumn) -> String {
|
||||
let data_type = column.data_type.trim().to_ascii_lowercase();
|
||||
let length_types: [&str; 2] = ["geohash", "decimal"];
|
||||
match data_type.find('(') {
|
||||
Some(pos) => {
|
||||
let base_type = &data_type[..pos];
|
||||
let params = &data_type[pos..];
|
||||
if length_types.contains(&base_type) {
|
||||
format!("{}{}", base_type, params)
|
||||
} else {
|
||||
base_type.to_string()
|
||||
}
|
||||
}
|
||||
None => data_type,
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
use super::column_alter::{
|
||||
build_clickhouse_existing_column_sql, build_h2_existing_column_sql, build_informix_existing_column_sql,
|
||||
build_mysql_existing_column_sql, build_oracle_like_existing_column_sql, build_postgres_existing_column_sql,
|
||||
build_sqlite_existing_column_sql, build_sqlserver_existing_column_sql, has_column_extra_change,
|
||||
has_existing_column_attribute_change,
|
||||
build_questdb_existing_column_sql, build_sqlite_existing_column_sql, build_sqlserver_existing_column_sql,
|
||||
has_column_extra_change, has_existing_column_attribute_change,
|
||||
};
|
||||
use super::column_format::column_definition;
|
||||
use super::comments::build_sqlserver_column_comment_sql;
|
||||
@@ -120,6 +120,7 @@ pub(super) fn build_column_sql(options: &TableStructureSqlOptions, warnings: &mu
|
||||
&options.table_name,
|
||||
)),
|
||||
StructureDialect::Sqlite => statements.extend(build_sqlite_existing_column_sql(&table, column, warnings)),
|
||||
StructureDialect::Questdb => statements.extend(build_questdb_existing_column_sql(&table, column)),
|
||||
_ => warnings.push(format!("Editing existing columns is not supported for {database_label} yet.")),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ pub(super) enum StructureDialect {
|
||||
ClickHouse,
|
||||
ManticoreSearch,
|
||||
Informix,
|
||||
Questdb,
|
||||
Unsupported,
|
||||
}
|
||||
|
||||
@@ -116,6 +117,23 @@ pub(super) fn capabilities_for(database_type: Option<DatabaseType>) -> TableStru
|
||||
alter_primary_key: true,
|
||||
..base
|
||||
},
|
||||
Some(DatabaseType::Questdb) => TableStructureCapabilities {
|
||||
dialect: StructureDialect::Questdb,
|
||||
add_column: true,
|
||||
drop_column: true,
|
||||
rename_column: true,
|
||||
alter_existing_column: true,
|
||||
reorder_column: false,
|
||||
comment: false,
|
||||
create_index: false,
|
||||
drop_index: false,
|
||||
rebuild_index: false,
|
||||
index_type: false,
|
||||
index_include: false,
|
||||
index_filter: false,
|
||||
index_comment: false,
|
||||
alter_primary_key: false,
|
||||
},
|
||||
Some(DatabaseType::Redshift | DatabaseType::Vertica) => TableStructureCapabilities {
|
||||
dialect: StructureDialect::Postgres,
|
||||
add_column: true,
|
||||
@@ -254,6 +272,7 @@ pub(super) fn dialect_label(dialect: StructureDialect) -> String {
|
||||
StructureDialect::ClickHouse => "clickhouse",
|
||||
StructureDialect::ManticoreSearch => "manticoresearch",
|
||||
StructureDialect::Informix => "informix",
|
||||
StructureDialect::Questdb => "questdb",
|
||||
StructureDialect::Unsupported => "this database",
|
||||
}
|
||||
.to_string()
|
||||
@@ -272,6 +291,7 @@ pub(super) fn database_type_for_dialect(dialect: StructureDialect) -> Option<Dat
|
||||
StructureDialect::ClickHouse => Some(DatabaseType::ClickHouse),
|
||||
StructureDialect::ManticoreSearch => Some(DatabaseType::ManticoreSearch),
|
||||
StructureDialect::Informix => Some(DatabaseType::Informix),
|
||||
StructureDialect::Questdb => Some(DatabaseType::Questdb),
|
||||
StructureDialect::Unsupported => None,
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,9 @@ pub(super) fn qualified_table(dialect: StructureDialect, schema: Option<&str>, t
|
||||
|
||||
pub(super) fn quote_ident(dialect: StructureDialect, name: &str) -> String {
|
||||
match dialect {
|
||||
StructureDialect::Mysql | StructureDialect::ManticoreSearch => format!("`{}`", name.replace('`', "``")),
|
||||
StructureDialect::Mysql | StructureDialect::ManticoreSearch | StructureDialect::Questdb => {
|
||||
format!("`{}`", name.replace('`', "``"))
|
||||
}
|
||||
StructureDialect::SqlServer => format!("[{}]", name.replace(']', "]]")),
|
||||
StructureDialect::Informix if is_simple_informix_identifier(name) => name.to_string(),
|
||||
_ => format!("\"{}\"", name.replace('"', "\"\"")),
|
||||
|
||||
Reference in new issue
Block a user