@@ -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.
175197fn 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