mirror of
https://github.com/t8y2/dbx.git
synced 2026-10-21 08:13:34 +00:00
@@ -167,6 +167,10 @@ pub fn build_executable_object_source_statements(input: EditableObjectSourceSqlI
|
||||
return Ok(executable_informix_view_statements(input.schema.as_deref(), &input.name, source));
|
||||
}
|
||||
|
||||
if input.database_type == DatabaseType::Mysql && input.object_type == ObjectSourceKind::View {
|
||||
return Ok(vec![executable_mysql_view_ddl(source)]);
|
||||
}
|
||||
|
||||
if is_mysql_like(input.database_type)
|
||||
&& matches!(input.object_type, ObjectSourceKind::Function | ObjectSourceKind::Procedure)
|
||||
{
|
||||
@@ -455,6 +459,23 @@ fn executable_oracle_routine_ddl(source: &str) -> String {
|
||||
ensure_semicolon(trimmed)
|
||||
}
|
||||
|
||||
fn executable_mysql_view_ddl(source: &str) -> String {
|
||||
let trimmed = source.trim();
|
||||
let statement_start = leading_sql_statement_start(trimmed);
|
||||
let executable = &trimmed[statement_start..];
|
||||
let create_view = Regex::new(
|
||||
r"(?is)^CREATE\s+(?:OR\s+REPLACE\s+)?(?:ALGORITHM\s*=\s*(?:UNDEFINED|MERGE|TEMPTABLE)\s+)?(?:DEFINER\s*=\s*(?:(?:`(?:``|[^`])+`|'(?:''|[^'])+'|[^\s]+)\s*@\s*(?:`(?:``|[^`])+`|'(?:''|[^'])+'|[^\s]+)|CURRENT_USER(?:\(\))?)\s+)?(?:SQL\s+SECURITY\s+(?:DEFINER|INVOKER)\s+)?VIEW\s+",
|
||||
)
|
||||
.unwrap();
|
||||
if create_view.is_match(executable) {
|
||||
let create = Regex::new(r"(?i)^CREATE\s+(?:OR\s+REPLACE\s+)?").unwrap();
|
||||
let replaced = create.replace(executable, "ALTER ");
|
||||
return ensure_semicolon(&format!("{}{}", &trimmed[..statement_start], replaced));
|
||||
}
|
||||
|
||||
ensure_semicolon(trimmed)
|
||||
}
|
||||
|
||||
fn executable_informix_view_statements(schema: Option<&str>, name: &str, source: &str) -> Vec<String> {
|
||||
let (target_name, create_tail) = informix_view_definition(schema, name, source);
|
||||
if source_starts_with_alter(source.trim()) {
|
||||
@@ -1785,6 +1806,53 @@ mod tests {
|
||||
assert_eq!(sql, "CREATE PROCEDURE `refresh_cache`() BEGIN SELECT 1; END;");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mysql_view_source_opened_for_editing_uses_alter_view() {
|
||||
let source = "CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`%` SQL SECURITY DEFINER VIEW `new_view` AS select `base_plugins`.`id` AS `id` from `base_plugins`";
|
||||
let expected = "ALTER ALGORITHM=UNDEFINED DEFINER=`root`@`%` SQL SECURITY DEFINER VIEW `new_view` AS select `base_plugins`.`id` AS `id` from `base_plugins`;";
|
||||
let input = EditableObjectSourceSqlInput {
|
||||
database_type: DatabaseType::Mysql,
|
||||
object_type: ObjectSourceKind::View,
|
||||
schema: Some("dol_test".to_string()),
|
||||
name: "new_view".to_string(),
|
||||
source: source.to_string(),
|
||||
};
|
||||
|
||||
assert_eq!(build_editable_object_source(input.clone()), expected);
|
||||
assert_eq!(build_executable_object_source_sql(input).unwrap(), expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mysql_view_create_source_preserves_leading_comments() {
|
||||
let source =
|
||||
"-- keep this view note\n/* and this block */\nCREATE OR REPLACE VIEW `new_view` AS SELECT 1 AS `id`";
|
||||
let sql = build_executable_object_source_sql(EditableObjectSourceSqlInput {
|
||||
database_type: DatabaseType::Mysql,
|
||||
object_type: ObjectSourceKind::View,
|
||||
schema: Some("dol_test".to_string()),
|
||||
name: "new_view".to_string(),
|
||||
source: source.to_string(),
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(sql, "-- keep this view note\n/* and this block */\nALTER VIEW `new_view` AS SELECT 1 AS `id`;");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mysql_view_alter_source_remains_unchanged() {
|
||||
let source = "ALTER ALGORITHM=MERGE VIEW `new_view` AS SELECT 2 AS `id`;";
|
||||
let sql = build_executable_object_source_sql(EditableObjectSourceSqlInput {
|
||||
database_type: DatabaseType::Mysql,
|
||||
object_type: ObjectSourceKind::View,
|
||||
schema: Some("dol_test".to_string()),
|
||||
name: "new_view".to_string(),
|
||||
source: source.to_string(),
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(sql, source);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn opengauss_procedure_source_omits_gsql_trailing_slash() {
|
||||
let source = "CREATE OR REPLACE PROCEDURE public.refresh_cache()\nAS DECLARE BEGIN\n NULL;\nEND;\n/";
|
||||
|
||||
Reference in New Issue
Block a user