@@ -43,7 +43,7 @@ pub struct AutoMigratePlan<'def> {
43
43
/// There is also an implied check: that the schema in the database is compatible with the old ModuleDef.
44
44
pub prechecks : Vec < AutoMigratePrecheck < ' def > > ,
45
45
/// The migration steps to perform.
46
- /// Order should not matter, as the steps are independent .
46
+ /// Order matters: `Remove`s of a particular `Def` must be ordered before `Add`s .
47
47
pub steps : Vec < AutoMigrateStep < ' def > > ,
48
48
}
49
49
@@ -59,29 +59,46 @@ pub enum AutoMigratePrecheck<'def> {
59
59
/// A step in an automatic migration.
60
60
#[ derive( PartialEq , Eq , Debug , PartialOrd , Ord ) ]
61
61
pub enum AutoMigrateStep < ' def > {
62
+ // It is important FOR CORRECTNESS that `Remove` variants are declared before `Add` variants in this enum!
63
+ //
64
+ // The ordering is used to sort the steps of an auto-migration.
65
+ // If adds go before removes, the following can occur:
66
+ //
67
+ // 1. `AddIndex("my_special_boy)`
68
+ // 2. `RemoveIndex("my_special_boy)`
69
+ //
70
+ // You see the problem.
71
+ //
72
+ // For now, we just ensure that we declare all `Remove` variants before `Add` variants
73
+ // and let `#[derive(PartialOrd)]` take care of the rest.
74
+ // TODO: when this enum is made serializable, a more durable fix will be needed here.
75
+ // Probably we will want to have separate arrays of add and remove steps.
76
+ //
77
+ /// Remove an index.
78
+ RemoveIndex ( <IndexDef as ModuleDefLookup >:: Key < ' def > ) ,
79
+ /// Remove a constraint.
80
+ RemoveConstraint ( <ConstraintDef as ModuleDefLookup >:: Key < ' def > ) ,
81
+ /// Remove a sequence.
82
+ RemoveSequence ( <SequenceDef as ModuleDefLookup >:: Key < ' def > ) ,
83
+ /// Remove a schedule annotation from a table.
84
+ RemoveSchedule ( <ScheduleDef as ModuleDefLookup >:: Key < ' def > ) ,
85
+ /// Remove a row-level security query.
86
+ RemoveRowLevelSecurity ( <RawRowLevelSecurityDefV9 as ModuleDefLookup >:: Key < ' def > ) ,
87
+
62
88
/// Add a table, including all indexes, constraints, and sequences.
63
89
/// There will NOT be separate steps in the plan for adding indexes, constraints, and sequences.
64
90
AddTable ( <TableDef as ModuleDefLookup >:: Key < ' def > ) ,
65
91
/// Add an index.
66
92
AddIndex ( <IndexDef as ModuleDefLookup >:: Key < ' def > ) ,
67
- /// Remove an index.
68
- RemoveIndex ( <IndexDef as ModuleDefLookup >:: Key < ' def > ) ,
69
- /// Remove a constraint.
70
- RemoveConstraint ( <ConstraintDef as ModuleDefLookup >:: Key < ' def > ) ,
71
93
/// Add a sequence.
72
94
AddSequence ( <SequenceDef as ModuleDefLookup >:: Key < ' def > ) ,
73
- /// Remove a sequence.
74
- RemoveSequence ( <SequenceDef as ModuleDefLookup >:: Key < ' def > ) ,
75
- /// Change the access of a table.
76
- ChangeAccess ( <TableDef as ModuleDefLookup >:: Key < ' def > ) ,
77
95
/// Add a schedule annotation to a table.
78
96
AddSchedule ( <ScheduleDef as ModuleDefLookup >:: Key < ' def > ) ,
79
- /// Remove a schedule annotation from a table.
80
- RemoveSchedule ( <ScheduleDef as ModuleDefLookup >:: Key < ' def > ) ,
81
97
/// Add a row-level security query.
82
98
AddRowLevelSecurity ( <RawRowLevelSecurityDefV9 as ModuleDefLookup >:: Key < ' def > ) ,
83
- /// Remove a row-level security query.
84
- RemoveRowLevelSecurity ( <RawRowLevelSecurityDefV9 as ModuleDefLookup >:: Key < ' def > ) ,
99
+
100
+ /// Change the access of a table.
101
+ ChangeAccess ( <TableDef as ModuleDefLookup >:: Key < ' def > ) ,
85
102
}
86
103
87
104
/// Something that might prevent an automatic migration.
@@ -412,9 +429,14 @@ fn auto_migrate_constraints(plan: &mut AutoMigratePlan, new_tables: &HashSet<&Id
412
429
. collect_all_errors ( )
413
430
}
414
431
415
- // Because we can refer to many tables and fields on the row level-security query, we need to remove all of them,
416
- // then add the new ones, instead of trying to track the graph of dependencies.
417
432
fn auto_migrate_row_level_security ( plan : & mut AutoMigratePlan ) -> Result < ( ) > {
433
+ // Because we can refer to many tables and fields on the row level-security query, we need to remove all of them,
434
+ // then add the new ones, instead of trying to track the graph of dependencies.
435
+ // When pretty-printing, steps to remove and re-add a row-level-security policy are not shown,
436
+ // since they are an implementation detail that will be surprising to users.
437
+ // TODO: change this to not add-and-remove unchanged policies, and hand the responsibility for reinitializing
438
+ // queries to the `core` crate instead.
439
+ // When you do this, you will need to update `pretty_print.rs`.
418
440
for rls in plan. old . row_level_security ( ) {
419
441
plan. steps . push ( AutoMigrateStep :: RemoveRowLevelSecurity ( rls. key ( ) ) ) ;
420
442
}
0 commit comments