@@ -214,7 +214,15 @@ where
214214    )  -> Result < Tidy ,  T >  { 
215215        let  op = & Arc :: clone ( & self . metrics ) . register ; 
216216        op. run ( async  { 
217-             let  data_writes = data_writes. into_iter ( ) . collect :: < Vec < _ > > ( ) ; 
217+             let  mut  data_writes = data_writes. into_iter ( ) . collect :: < Vec < _ > > ( ) ; 
218+ 
219+             // The txns system requires that all participating data shards have a 
220+             // schema registered. Importantly, we must register a data shard's 
221+             // schema _before_ we publish it to the txns shard. 
222+             for  data_write in  & mut  data_writes { 
223+                 data_write. ensure_schema_registered ( ) . await ; 
224+             } 
225+ 
218226            let  updates = data_writes
219227                . iter ( ) 
220228                . map ( |data_write| { 
@@ -285,45 +293,47 @@ where
285293                } 
286294            } 
287295            for  data_write in  data_writes { 
288-                 let  new_schema_id = data_write. schema_id ( ) ; 
289- 
290296                // If we already have a write handle for a newer version of a table, don't replace 
291297                // it! Currently we only support adding columns to tables with a default value, so 
292298                // the latest/newest schema will always be the most complete. 
293299                // 
294-                 // TODO(alter_table): Revist  when we support dropping columns. 
300+                 // TODO(alter_table): Revisit  when we support dropping columns. 
295301                match  self . datas . data_write_for_commit . get ( & data_write. shard_id ( ) )  { 
296302                    None  => { 
297303                        self . datas 
298304                            . data_write_for_commit 
299305                            . insert ( data_write. shard_id ( ) ,  DataWriteCommit ( data_write) ) ; 
300306                    } 
301307                    Some ( previous)  => { 
302-                         match  ( previous. schema_id ( ) ,  new_schema_id)  { 
303-                             ( Some ( previous_id) ,  None )  => { 
304-                                 mz_ore:: soft_panic_or_log!( 
305-                                     "tried registering a WriteHandle replacing one with a SchemaId prev_schema_id: {:?} shard_id: {:?}" , 
306-                                     previous_id, 
307-                                     previous. shard_id( ) , 
308-                                 ) ; 
309-                             } , 
310-                             ( Some ( previous_id) ,  Some ( new_id) )  if  previous_id > new_id => { 
311-                                 mz_ore:: soft_panic_or_log!( 
312-                                     "tried registering a WriteHandle with an older SchemaId prev_schema_id: {:?} new_schema_id: {:?} shard_id: {:?}" , 
313-                                     previous_id, 
314-                                     new_id, 
315-                                     previous. shard_id( ) , 
316-                                 ) ; 
317-                             } , 
318-                             ( previous_schema_id,  new_schema_id)  => { 
319-                                 if  previous_schema_id. is_none ( )  && new_schema_id. is_none ( )  { 
320-                                     tracing:: warn!( "replacing WriteHandle without any SchemaIds to reason about" ) ; 
321-                                 }  else  { 
322-                                     tracing:: info!( ?previous_schema_id,  ?new_schema_id,  shard_id = ?previous. shard_id( ) ,  "replacing WriteHandle" ) ; 
323-                                 } 
324-                                 self . datas . data_write_for_commit . insert ( data_write. shard_id ( ) ,  DataWriteCommit ( data_write) ) ; 
325-                             } 
308+                         let  new_schema_id = data_write. schema_id ( ) . expect ( "ensured above" ) ; 
309+ 
310+                         if  let  Some ( prev_schema_id)  = previous. schema_id ( ) 
311+                             && prev_schema_id > new_schema_id
312+                         { 
313+                             mz_ore:: soft_panic_or_log!( 
314+                                 "tried registering a WriteHandle with an older SchemaId; \  
315+ , 
316+                                 prev_schema_id, 
317+                                 new_schema_id, 
318+                                 previous. shard_id( ) , 
319+                             ) ; 
320+                             continue ; 
321+                         }  else  if  previous. schema_id ( ) . is_none ( )  { 
322+                             mz_ore:: soft_panic_or_log!( 
323+                                 "encountered data shard without a schema; shard_id: {}" , 
324+                                 previous. shard_id( ) , 
325+                             ) ; 
326326                        } 
327+ 
328+                         tracing:: info!( 
329+                             prev_schema_id = ?previous. schema_id( ) , 
330+                             ?new_schema_id, 
331+                             shard_id = %previous. shard_id( ) , 
332+                             "replacing WriteHandle" 
333+                         ) ; 
334+                         self . datas 
335+                             . data_write_for_commit 
336+                             . insert ( data_write. shard_id ( ) ,  DataWriteCommit ( data_write) ) ; 
327337                    } 
328338                } 
329339            } 
@@ -756,12 +766,8 @@ where
756766            . expect ( "codecs have not changed" ) ; 
757767        let  ( key_schema,  val_schema)  = match  schemas { 
758768            Some ( ( _,  key_schema,  val_schema) )  => ( Arc :: new ( key_schema) ,  Arc :: new ( val_schema) ) , 
759-             // - For new shards we will always have at least one schema 
760-             //   registered by the time we reach this point, because that 
761-             //   happens at txn-registration time. 
762-             // - For pre-existing shards, every txns shard will have had 
763-             //   open_writer called on it at least once in the previous release, 
764-             //   so the schema should exist. 
769+             // We will always have at least one schema registered by the time we reach this point, 
770+             // because that is ensured at txn-registration time. 
765771            None  => unreachable ! ( "data shard {} should have a schema" ,  data_id) , 
766772        } ; 
767773        let  wrapped = self 
0 commit comments