Skip to content

Commit bb06b4c

Browse files
committed
Manually apply: core: Ignore indexed-only constraints when updating #734
1 parent 9436544 commit bb06b4c

File tree

1 file changed

+31
-5
lines changed

1 file changed

+31
-5
lines changed

crates/core/src/db/update.rs

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,9 @@ pub fn schema_updates(
128128
if let Some(known_schema) = known_tables.remove(proposed_table_name) {
129129
let known_schema_def = TableDef::from(known_schema.as_ref().clone());
130130
if !equiv(&known_schema_def, &proposed_schema_def) {
131+
log::warn!("Schema incompatible: {proposed_table_name}");
132+
log::debug!("Existing: {known_schema_def:?}");
133+
log::debug!("Proposed: {proposed_schema_def:?}");
131134
tainted_tables.push(Tainted {
132135
table_name: proposed_table_name.to_owned(),
133136
reason: TaintReason::IncompatibleSchema,
@@ -167,11 +170,30 @@ pub fn schema_updates(
167170
///
168171
/// - `indexes` are never equal, because they only exist in the database
169172
/// - `sequences` are never equal, because they only exist in the database
170-
/// - only `constraints` which have set column attributes can be equal (the
171-
/// module may emit unset attributes)
173+
/// - `constraints` are delicate:
172174
///
173-
/// Thus, `indexes` and `sequences` are ignored, while `constraints` are
174-
/// compared sans any unset attributes.
175+
/// - The number of `constraints` obtained from the module will always be the
176+
/// same as the number of columns, emitting [`Constraints::unset()`] if no
177+
/// specific constraint is defined.
178+
///
179+
/// - Indexes defined using `#[spacetimedb(index, ..)]` will not have a
180+
/// corresponding [`Constraints::indexed()`] constraint (it will be unset).
181+
/// The schema obtained from the database **will** have one such constraint,
182+
/// however.
183+
///
184+
/// - The other possibilities (primary key, autoinc, unique) will have a
185+
/// [`ConstraintDef`] in the module's schema, but no corresponding index
186+
/// or sequence definitions.
187+
///
188+
/// There is no stable API to migrate such changes, so we won't try.
189+
///
190+
/// Thus:
191+
///
192+
/// - `indexes` and `sequences` are ignored
193+
/// - `constraints` are compared sans unset or indexed-only definitions
194+
///
195+
/// A return value of `false` indicates that the table definitions are not
196+
/// compatible.
175197
fn equiv(a: &TableDef, b: &TableDef) -> bool {
176198
let TableDef {
177199
table_name,
@@ -188,7 +210,11 @@ fn equiv(a: &TableDef, b: &TableDef) -> bool {
188210
fn as_set(constraints: &[ConstraintDef]) -> BTreeSet<&ConstraintDef> {
189211
constraints
190212
.iter()
191-
.filter(|c| c.constraints != Constraints::unset())
213+
.filter(|c| {
214+
![Constraints::unset(), Constraints::indexed()]
215+
.iter()
216+
.any(|val| val == &c.constraints)
217+
})
192218
.collect()
193219
}
194220

0 commit comments

Comments
 (0)