mirror of
https://github.com/t8y2/dbx.git
synced 2026-10-21 03:49:30 +00:00
@@ -1020,6 +1020,20 @@ pub(super) fn build_sqlite_existing_column_sql(
|
||||
statements
|
||||
}
|
||||
|
||||
pub(super) fn build_duckdb_existing_column_sql(table: &str, column: &EditableStructureColumn) -> Vec<String> {
|
||||
let Some(original) = &column.original else {
|
||||
return Vec::new();
|
||||
};
|
||||
if column.name == original.name {
|
||||
return Vec::new();
|
||||
}
|
||||
vec![format!(
|
||||
"ALTER TABLE {table} RENAME COLUMN {} TO {};",
|
||||
quote_ident(StructureDialect::DuckDb, &original.name),
|
||||
quote_ident(StructureDialect::DuckDb, &column.name)
|
||||
)]
|
||||
}
|
||||
|
||||
pub(super) fn build_questdb_existing_column_sql(table: &str, column: &EditableStructureColumn) -> Vec<String> {
|
||||
let Some(original) = &column.original else {
|
||||
return Vec::new();
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
use super::column_alter::{
|
||||
build_clickhouse_existing_column_sql, build_dameng_existing_column_sql, build_doris_existing_column_sql,
|
||||
build_h2_existing_column_sql, build_informix_existing_column_sql, build_iris_existing_column_sql,
|
||||
build_mysql_existing_column_clause, build_oracle_like_existing_column_sql, build_oscar_existing_column_sql,
|
||||
build_postgres_existing_column_sql, build_questdb_existing_column_sql, build_sqlite_existing_column_sql,
|
||||
build_sqlserver_existing_column_sql, build_xugu_existing_column_sql, dameng_drops_identity,
|
||||
has_column_extra_change, has_existing_column_attribute_change, validate_dameng_existing_identity_change,
|
||||
build_duckdb_existing_column_sql, build_h2_existing_column_sql, build_informix_existing_column_sql,
|
||||
build_iris_existing_column_sql, build_mysql_existing_column_clause, build_oracle_like_existing_column_sql,
|
||||
build_oscar_existing_column_sql, build_postgres_existing_column_sql, build_questdb_existing_column_sql,
|
||||
build_sqlite_existing_column_sql, build_sqlserver_existing_column_sql, build_xugu_existing_column_sql,
|
||||
dameng_drops_identity, has_column_extra_change, has_existing_column_attribute_change,
|
||||
validate_dameng_existing_identity_change,
|
||||
};
|
||||
use super::column_format::{
|
||||
column_definition, has_dameng_identity, is_dameng_identity_compatible_type, is_mysql_character_data_type,
|
||||
@@ -291,6 +292,7 @@ pub(super) fn build_column_sql(options: &TableStructureSqlOptions, warnings: &mu
|
||||
warnings,
|
||||
)),
|
||||
StructureDialect::Sqlite => statements.extend(build_sqlite_existing_column_sql(&table, column, warnings)),
|
||||
StructureDialect::DuckDb => statements.extend(build_duckdb_existing_column_sql(&table, column)),
|
||||
StructureDialect::Questdb => statements.extend(build_questdb_existing_column_sql(&table, column)),
|
||||
_ => warnings.push(format!("Editing existing columns is not supported for {database_label} yet.")),
|
||||
}
|
||||
|
||||
@@ -4123,6 +4123,81 @@ fn builds_duckdb_create_table_statements() {
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(feature = "duckdb-sidecar")]
|
||||
fn existing_duckdb_column(name: &str) -> EditableStructureColumn {
|
||||
let mut existing = column(name);
|
||||
existing.original = Some(ColumnInfo {
|
||||
name: name.to_string(),
|
||||
data_type: existing.data_type.clone(),
|
||||
is_nullable: existing.is_nullable,
|
||||
column_default: None,
|
||||
..Default::default()
|
||||
});
|
||||
existing
|
||||
}
|
||||
|
||||
#[cfg(feature = "duckdb-sidecar")]
|
||||
#[test]
|
||||
fn duckdb_column_rename_generates_quoted_sql() {
|
||||
let mut renamed = existing_duckdb_column("old_name");
|
||||
renamed.name = "new_name".to_string();
|
||||
|
||||
let result =
|
||||
build_table_structure_change_sql(structure_change_options(DatabaseType::DuckDb, None, "events", vec![renamed]));
|
||||
|
||||
assert!(result.warnings.is_empty(), "{:?}", result.warnings);
|
||||
assert_eq!(result.statements, vec![r#"ALTER TABLE "events" RENAME COLUMN "old_name" TO "new_name";"#]);
|
||||
}
|
||||
|
||||
#[cfg(feature = "duckdb-sidecar")]
|
||||
#[test]
|
||||
fn duckdb_column_rename_quotes_special_identifiers() {
|
||||
let mut renamed = existing_duckdb_column("old \"code\"");
|
||||
renamed.name = "select value".to_string();
|
||||
|
||||
let result = build_table_structure_change_sql(structure_change_options(
|
||||
DatabaseType::DuckDb,
|
||||
None,
|
||||
"event log",
|
||||
vec![renamed],
|
||||
));
|
||||
|
||||
assert!(result.warnings.is_empty(), "{:?}", result.warnings);
|
||||
assert_eq!(result.statements, vec![r#"ALTER TABLE "event log" RENAME COLUMN "old ""code""" TO "select value";"#]);
|
||||
}
|
||||
|
||||
#[cfg(feature = "duckdb-sidecar")]
|
||||
#[test]
|
||||
fn duckdb_column_rename_ignores_unchanged_columns() {
|
||||
let unchanged = existing_duckdb_column("event_id");
|
||||
|
||||
let result = build_table_structure_change_sql(structure_change_options(
|
||||
DatabaseType::DuckDb,
|
||||
None,
|
||||
"events",
|
||||
vec![unchanged],
|
||||
));
|
||||
|
||||
assert!(result.statements.is_empty());
|
||||
assert!(result.warnings.is_empty());
|
||||
}
|
||||
|
||||
#[cfg(feature = "duckdb-sidecar")]
|
||||
#[test]
|
||||
fn duckdb_column_rename_with_unsupported_attribute_change_fails_closed() {
|
||||
let mut changed = existing_duckdb_column("event_id");
|
||||
changed.name = "renamed_id".to_string();
|
||||
changed.data_type = "BIGINT".to_string();
|
||||
changed.is_nullable = false;
|
||||
changed.default_value = "42".to_string();
|
||||
|
||||
let result =
|
||||
build_table_structure_change_sql(structure_change_options(DatabaseType::DuckDb, None, "events", vec![changed]));
|
||||
|
||||
assert!(result.statements.is_empty());
|
||||
assert_eq!(result.warnings, vec!["Editing existing columns is not supported for duckdb yet."]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn builds_clickhouse_nullable_comment_and_reorder_statements() {
|
||||
let mut source = column("source");
|
||||
|
||||
Reference in New Issue
Block a user