Skip to content

Commit 51bd8c5

Browse files
committed
Rm if exists
1 parent 7624205 commit 51bd8c5

11 files changed

Lines changed: 90 additions & 42 deletions

crates/vespertide-planner/src/validate.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2027,4 +2027,19 @@ mod tests {
20272027
_ => panic!("Expected InvalidAutoIncrement error"),
20282028
}
20292029
}
2030+
2031+
#[test]
2032+
fn validate_inline_primary_key_bool_does_not_check_auto_increment() {
2033+
// PrimaryKeySyntax::Bool(true) has no auto_increment field, so validation
2034+
// should pass even on a non-integer column.
2035+
let mut col_def = col("code", ColumnType::Simple(SimpleColumnType::Text));
2036+
col_def.primary_key = Some(PrimaryKeySyntax::Bool(true));
2037+
2038+
let table_def = table("items", vec![col_def], vec![]);
2039+
let result = validate_table(&table_def, &std::collections::HashMap::new());
2040+
assert!(
2041+
result.is_ok(),
2042+
"Bool primary key should not trigger auto_increment validation"
2043+
);
2044+
}
20302045
}

crates/vespertide-query/src/sql/add_constraint.rs

Lines changed: 2 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ pub fn build_add_constraint(
2323
let table_def = current_schema.iter().find(|t| t.name == table).ok_or_else(|| QueryError::Other(format!("Table '{}' not found in current schema. SQLite requires current schema information to add constraints.", table)))?;
2424

2525
// Create new constraints with the added primary key constraint
26-
let mut new_constraints = table_def.constraints.clone();
26+
let mut new_constraints: Vec<TableConstraint> = table_def.constraints.clone();
2727
new_constraints.push(constraint.clone());
2828

2929
let temp_table = format!("{}_temp", table);
@@ -92,14 +92,6 @@ pub fn build_add_constraint(
9292
}
9393
}
9494
TableConstraint::Unique { name, columns } => {
95-
// On SQLite, skip if this constraint already exists in the schema —
96-
// a prior temp table rebuild in the same migration already recreated it.
97-
if *backend == DatabaseBackend::Sqlite
98-
&& let Some(table_def) = current_schema.iter().find(|t| t.name == table)
99-
&& table_def.constraints.contains(constraint)
100-
{
101-
return Ok(vec![]);
102-
}
10395
// Always generate a proper name: uq_{table}_{key} or uq_{table}_{columns}
10496
let index_name =
10597
super::helpers::build_unique_constraint_name(table, columns, name.as_deref());
@@ -127,26 +119,8 @@ pub fn build_add_constraint(
127119
let table_def = current_schema.iter().find(|t| t.name == table).ok_or_else(|| QueryError::Other(format!("Table '{}' not found in current schema. SQLite requires current schema information to add constraints.", table)))?;
128120

129121
// Create new constraints with the added foreign key constraint
130-
// Dedup: check if this FK already exists (e.g. from inline normalization)
131122
let mut new_constraints = table_def.constraints.clone();
132-
let fk_already_exists = new_constraints.iter().any(|c| {
133-
if let TableConstraint::ForeignKey {
134-
columns: existing_cols,
135-
ref_table: existing_ref,
136-
ref_columns: existing_ref_cols,
137-
..
138-
} = c
139-
{
140-
columns == existing_cols
141-
&& ref_table == existing_ref
142-
&& ref_columns == existing_ref_cols
143-
} else {
144-
false
145-
}
146-
});
147-
if !fk_already_exists {
148-
new_constraints.push(constraint.clone());
149-
}
123+
new_constraints.push(constraint.clone());
150124

151125
let temp_table = format!("{}_temp", table);
152126

@@ -216,14 +190,6 @@ pub fn build_add_constraint(
216190
}
217191
}
218192
TableConstraint::Index { name, columns } => {
219-
// On SQLite, skip if this constraint already exists in the schema —
220-
// a prior temp table rebuild in the same migration already recreated it.
221-
if *backend == DatabaseBackend::Sqlite
222-
&& let Some(table_def) = current_schema.iter().find(|t| t.name == table)
223-
&& table_def.constraints.contains(constraint)
224-
{
225-
return Ok(vec![]);
226-
}
227193
let index_name = vespertide_naming::build_index_name(table, columns, name.as_deref());
228194
let mut idx = Index::create()
229195
.table(Alias::new(table))

crates/vespertide-query/src/sql/delete_column.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ mod tests {
277277
assert!(alter_sql.contains("DROP COLUMN"));
278278

279279
let drop_type_sql = result[1].build(DatabaseBackend::Postgres);
280-
assert!(drop_type_sql.contains("DROP TYPE IF EXISTS \"users_status\""));
280+
assert!(drop_type_sql.contains("DROP TYPE \"users_status\""));
281281

282282
// MySQL and SQLite should have empty DROP TYPE
283283
let drop_type_mysql = result[1].build(DatabaseBackend::MySql);

crates/vespertide-query/src/sql/helpers.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -319,8 +319,8 @@ pub fn build_drop_enum_type_sql(
319319
// Generate the same unique type name used in CREATE TYPE
320320
let type_name = build_enum_type_name(table, name);
321321

322-
// PostgreSQL: DROP TYPE IF EXISTS {table}_{name}
323-
let pg_sql = format!("DROP TYPE IF EXISTS \"{}\"", type_name);
322+
// PostgreSQL: DROP TYPE {table}_{name}
323+
let pg_sql = format!("DROP TYPE \"{}\"", type_name);
324324

325325
// MySQL/SQLite: No action needed
326326
Some(super::types::RawSql::per_backend(

crates/vespertide-query/src/sql/mod.rs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1388,4 +1388,52 @@ mod tests {
13881388
assert_snapshot!(sql);
13891389
});
13901390
}
1391+
1392+
#[rstest]
1393+
#[case::delete_enum_column_postgres(DatabaseBackend::Postgres)]
1394+
#[case::delete_enum_column_mysql(DatabaseBackend::MySql)]
1395+
#[case::delete_enum_column_sqlite(DatabaseBackend::Sqlite)]
1396+
fn test_delete_column_with_enum_type(#[case] backend: DatabaseBackend) {
1397+
// Deleting a column with an enum type — SQLite uses temp table approach,
1398+
// Postgres drops the enum type, MySQL uses simple DROP COLUMN.
1399+
let action = MigrationAction::DeleteColumn {
1400+
table: "orders".into(),
1401+
column: "status".into(),
1402+
};
1403+
let schema = vec![TableDef {
1404+
name: "orders".into(),
1405+
description: None,
1406+
columns: vec![
1407+
col("id", ColumnType::Simple(SimpleColumnType::Integer)),
1408+
ColumnDef {
1409+
name: "status".into(),
1410+
r#type: ColumnType::Complex(vespertide_core::ComplexColumnType::Enum {
1411+
name: "order_status".into(),
1412+
values: vespertide_core::EnumValues::String(vec![
1413+
"pending".into(),
1414+
"shipped".into(),
1415+
]),
1416+
}),
1417+
nullable: false,
1418+
default: None,
1419+
comment: None,
1420+
primary_key: None,
1421+
unique: None,
1422+
index: None,
1423+
foreign_key: None,
1424+
},
1425+
],
1426+
constraints: vec![],
1427+
}];
1428+
let result = build_action_queries(&backend, &action, &schema).unwrap();
1429+
let sql = result
1430+
.iter()
1431+
.map(|q| q.build(backend))
1432+
.collect::<Vec<_>>()
1433+
.join(";\n");
1434+
1435+
with_settings!({ snapshot_suffix => format!("delete_enum_column_{:?}", backend) }, {
1436+
assert_snapshot!(sql);
1437+
});
1438+
}
13911439
}

crates/vespertide-query/src/sql/modify_column_type.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ pub fn build_modify_column_type(
256256
// Use table-prefixed enum type name
257257
let old_type_name = super::helpers::build_enum_type_name(table, old_name);
258258
queries.push(BuiltQuery::Raw(super::types::RawSql::per_backend(
259-
format!("DROP TYPE IF EXISTS \"{}\"", old_type_name),
259+
format!("DROP TYPE \"{}\"", old_type_name),
260260
String::new(),
261261
String::new(),
262262
)));

crates/vespertide-query/src/sql/snapshots/vespertide_query__sql__modify_column_type__tests__modify_enum_types@modify_enum_types_enum_name_changed_postgres.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@ expression: sql
44
---
55
CREATE TYPE "users_new_status" AS ENUM ('active', 'inactive');
66
ALTER TABLE "users" ALTER COLUMN "status" TYPE users_new_status;
7-
DROP TYPE IF EXISTS "users_old_status"
7+
DROP TYPE "users_old_status"

crates/vespertide-query/src/sql/snapshots/vespertide_query__sql__modify_column_type__tests__modify_enum_types@modify_enum_types_enum_to_text_postgres.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ source: crates/vespertide-query/src/sql/modify_column_type.rs
33
expression: sql
44
---
55
ALTER TABLE "users" ALTER COLUMN "status" TYPE text;
6-
DROP TYPE IF EXISTS "users_user_status"
6+
DROP TYPE "users_user_status"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
source: crates/vespertide-query/src/sql/mod.rs
3+
expression: sql
4+
---
5+
ALTER TABLE `orders` DROP COLUMN `status`;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
source: crates/vespertide-query/src/sql/mod.rs
3+
expression: sql
4+
---
5+
ALTER TABLE "orders" DROP COLUMN "status";
6+
DROP TYPE "orders_order_status"

0 commit comments

Comments
 (0)