Skip to content
This repository has been archived by the owner on Sep 2, 2022. It is now read-only.

Commit

Permalink
database-introspection: Fix on delete actions for MySQL
Browse files Browse the repository at this point in the history
  • Loading branch information
aknuds1 committed Aug 22, 2019
1 parent 6146c81 commit 0ed8a17
Show file tree
Hide file tree
Showing 2 changed files with 125 additions and 1 deletion.
13 changes: 12 additions & 1 deletion server/prisma-rs/libs/database-introspection/src/mysql.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,17 @@ impl IntrospectionConnector {
.get("ordinal_position")
.and_then(|x| x.as_i64())
.expect("get ordinal_position");
let on_delete_action = match row
.get("delete_rule")
.and_then(|x| x.to_string())
.expect("get delete_rule").to_lowercase().as_str() {
"cascade" => ForeignKeyAction::Cascade,
"set null" => ForeignKeyAction::SetNull,
"set default" => ForeignKeyAction::SetDefault,
"restrict" => ForeignKeyAction::Restrict,
"no action" => ForeignKeyAction::NoAction,
s @ _ => panic!(format!("Unrecognized on delete action '{}'", s)),
};
match intermediate_fks.get_mut(&constraint_name) {
Some(fk) => {
let pos = ord_pos as usize - 1;
Expand All @@ -202,7 +213,7 @@ impl IntrospectionConnector {
columns: vec![column],
referenced_table,
referenced_columns: vec![referenced_column],
on_delete_action: ForeignKeyAction::NoAction,
on_delete_action,
};
intermediate_fks.insert(constraint_name, fk);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1516,6 +1516,119 @@ fn postgres_foreign_key_on_delete_must_be_handled() {
);
}

#[test]
fn mysql_foreign_key_on_delete_must_be_handled() {
setup();

// NB: We don't test the SET DEFAULT variety since it isn't supported on InnoDB and will
// just cause an error
let sql = format!(
"CREATE TABLE {0}.City (id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY);
CREATE TABLE {0}.User (
id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY,
city INTEGER, FOREIGN KEY(city) REFERENCES City (id) ON DELETE NO ACTION,
city_cascade INTEGER, FOREIGN KEY(city_cascade) REFERENCES City (id) ON DELETE CASCADE,
city_restrict INTEGER, FOREIGN KEY(city_restrict) REFERENCES City (id) ON DELETE RESTRICT,
city_set_null INTEGER, FOREIGN KEY(city_set_null) REFERENCES City (id) ON DELETE SET NULL
)",
SCHEMA
);
let inspector = get_mysql_connector(&sql);

let schema = inspector.introspect(SCHEMA).expect("introspection");
let mut table = schema.get_table("User").expect("get User table").to_owned();
table.foreign_keys.sort_unstable_by_key(|fk| fk.columns.clone());

assert_eq!(
table,
Table {
name: "User".to_string(),
columns: vec![
Column {
name: "city".to_string(),
tpe: ColumnType {
raw: "int".to_string(),
family: ColumnTypeFamily::Int,
},
arity: ColumnArity::Nullable,
default: None,
auto_increment: false,
},
Column {
name: "city_cascade".to_string(),
tpe: ColumnType {
raw: "int".to_string(),
family: ColumnTypeFamily::Int,
},
arity: ColumnArity::Nullable,
default: None,
auto_increment: false,
},
Column {
name: "city_restrict".to_string(),
tpe: ColumnType {
raw: "int".to_string(),
family: ColumnTypeFamily::Int,
},
arity: ColumnArity::Nullable,
default: None,
auto_increment: false,
},
Column {
name: "city_set_null".to_string(),
tpe: ColumnType {
raw: "int".to_string(),
family: ColumnTypeFamily::Int,
},
arity: ColumnArity::Nullable,
default: None,
auto_increment: false,
},
Column {
name: "id".to_string(),
tpe: ColumnType {
raw: "int".to_string(),
family: ColumnTypeFamily::Int,
},
arity: ColumnArity::Required,
default: None,
auto_increment: true,
},
],
indices: vec![],
primary_key: Some(PrimaryKey {
columns: vec!["id".to_string()],
}),
foreign_keys: vec![
ForeignKey {
columns: vec!["city".to_string()],
referenced_columns: vec!["id".to_string()],
referenced_table: "City".to_string(),
on_delete_action: ForeignKeyAction::NoAction,
},
ForeignKey {
columns: vec!["city_cascade".to_string()],
referenced_columns: vec!["id".to_string()],
referenced_table: "City".to_string(),
on_delete_action: ForeignKeyAction::Cascade,
},
ForeignKey {
columns: vec!["city_restrict".to_string()],
referenced_columns: vec!["id".to_string()],
referenced_table: "City".to_string(),
on_delete_action: ForeignKeyAction::Restrict,
},
ForeignKey {
columns: vec!["city_set_null".to_string()],
referenced_columns: vec!["id".to_string()],
referenced_table: "City".to_string(),
on_delete_action: ForeignKeyAction::SetNull,
},
],
}
);
}

#[test]
fn postgres_enums_must_work() {
setup();
Expand Down

0 comments on commit 0ed8a17

Please sign in to comment.