fix(mysql): preserve functional index expressions

This commit is contained in:
t8y2 committed 2026-07-26 09:09:22 +08:00
1 parent ae9403acc4
commit 0c7e3577bd
4 files changed
+218 -27

No files matched your search

@@ -116,6 +116,16 @@ pub(super) fn mysql_index_parts(index_type: &str) -> (String, String) {
}
}
fn mysql_index_column_sql(column: &str) -> String {
let trimmed = column.trim();
// Keep the wrapped expression from MySQL metadata instead of quoting it as a column identifier.
if trimmed.starts_with("((") && trimmed.ends_with("))") {
trimmed.to_string()
} else {
quote_ident(StructureDialect::Mysql, column)
}
}
pub(super) fn build_drop_index_sql(
database_type: Option<DatabaseType>,
dialect: StructureDialect,
@@ -160,7 +170,17 @@ pub(super) fn build_create_index_statements(
}
let unique = if index.is_unique { "UNIQUE " } else { "" };
let cols = columns.iter().map(|column| quote_ident(dialect, column)).collect::<Vec<_>>().join(", ");
let cols = columns
.iter()
.map(|column| {
if dialect == StructureDialect::Mysql {
mysql_index_column_sql(column)
} else {
quote_ident(dialect, column)
}
})
.collect::<Vec<_>>()
.join(", ");
let idx_type = normalized_index_type(index);
let mut type_prefix = String::new();
let mut using_clause = String::new();
@@ -1240,6 +1240,31 @@ fn mysql_create_unique_index_with_comment_and_btree() {
);
}
#[test]
fn mysql_create_functional_index_preserves_key_part_syntax() {
let functional_key_part = "((case when (`STATUS` = _utf8mb4'online') then _utf8mb4'online' else NULL end))";
let mut idx = index("test_UNIQUE", &["attr", "attr2", functional_key_part]);
idx.is_unique = true;
let result = build_table_structure_change_sql(TableStructureSqlOptions {
database_type: Some(DatabaseType::Mysql),
schema: None,
table_name: "test".to_string(),
columns: Vec::new(),
indexes: vec![idx],
foreign_keys: Vec::new(),
triggers: Vec::new(),
table_comment: None,
original_table_comment: None,
});
assert_eq!(result.warnings, Vec::<String>::new());
assert_eq!(
result.statements,
vec![format!("CREATE UNIQUE INDEX `test_UNIQUE` ON `test` (`attr`, `attr2`, {functional_key_part});")]
);
}
#[test]
fn mysql_add_timestamp_column_drops_invalid_precision() {
let mut created_at = column("created_at");