@@ -315,19 +315,35 @@ impl CommittedState {
315315 Ok ( ( ) )
316316 }
317317
318+ pub ( super ) fn replay_truncate ( & mut self , table_id : TableId ) -> Result < ( ) > {
319+ // (1) Table dropped? Avoid an error and just ignore the row instead.
320+ if self . table_dropped . contains ( & table_id) {
321+ return Ok ( ( ) ) ;
322+ }
323+
324+ // Get the table for mutation.
325+ let ( table, blob_store, ..) = self . get_table_and_blob_store_mut ( table_id) ?;
326+
327+ // We do not need to consider a truncation of `st_table` itself,
328+ // as if that happens, the database is bricked.
329+
330+ table. clear ( blob_store) ;
331+
332+ Ok ( ( ) )
333+ }
334+
318335 pub ( super ) fn replay_delete_by_rel ( & mut self , table_id : TableId , row : & ProductValue ) -> Result < ( ) > {
336+ // (1) Table dropped? Avoid an error and just ignore the row instead.
337+ if self . table_dropped . contains ( & table_id) {
338+ return Ok ( ( ) ) ;
339+ }
340+
319341 // Get the table for mutation.
320- let table = match self . tables . get_mut ( & table_id) {
321- Some ( t) => t,
322- // (1) If it was dropped, avoid an error and just ignore the row instead.
323- None if self . table_dropped . contains ( & table_id) => return Ok ( ( ) ) ,
324- None => return Err ( TableError :: IdNotFoundState ( table_id) . into ( ) ) ,
325- } ;
342+ let ( table, blob_store, _, page_pool) = self . get_table_and_blob_store_mut ( table_id) ?;
326343
327344 // Delete the row.
328- let blob_store = & mut self . blob_store ;
329345 table
330- . delete_equal_row ( & self . page_pool , blob_store, row)
346+ . delete_equal_row ( page_pool, blob_store, row)
331347 . map_err ( TableError :: Bflatn ) ?
332348 . ok_or_else ( || anyhow ! ( "Delete for non-existent row when replaying transaction" ) ) ?;
333349
@@ -461,9 +477,9 @@ impl CommittedState {
461477 for index_row in rows {
462478 let index_id = index_row. index_id ;
463479 let table_id = index_row. table_id ;
464- let ( Some ( table) , blob_store, index_id_map) = self . get_table_and_blob_store_mut ( table_id ) else {
465- panic ! ( "Cannot create index for table which doesn't exist in committed state" ) ;
466- } ;
480+ let ( table, blob_store, index_id_map, _ ) = self
481+ . get_table_and_blob_store_mut ( table_id )
482+ . expect ( "index should exist in committed state; cannot create it" ) ;
467483 let algo: IndexAlgorithm = index_row. index_algorithm . into ( ) ;
468484 let columns: ColSet = algo. columns ( ) . into ( ) ;
469485 let is_unique = unique_constraints. contains ( & ( table_id, columns) ) ;
@@ -564,8 +580,7 @@ impl CommittedState {
564580 "Cannot get TX_STATE RowPointer from CommittedState." ,
565581 ) ;
566582 let table = self
567- . tables
568- . get ( & table_id)
583+ . get_table ( table_id)
569584 . expect ( "Attempt to get COMMITTED_STATE row from table not present in tables." ) ;
570585 // TODO(perf, deep-integration): Use `get_row_ref_unchecked`.
571586 table. get_row_ref ( & self . blob_store , row_ptr) . unwrap ( )
@@ -645,17 +660,18 @@ impl CommittedState {
645660
646661 if !deletes. is_empty ( ) {
647662 let table_name = & * table. get_schema ( ) . table_name ;
648- // TODO(centril): Pass this along to record truncated tables.
649- let _truncated = table. row_count == 0 ;
650- tx_data. set_deletes_for_table ( table_id, table_name, deletes. into ( ) ) ;
663+ let truncated = table. row_count == 0 ;
664+ tx_data. set_deletes_for_table ( table_id, table_name, deletes. into ( ) , truncated) ;
651665 }
652666 }
653667
654668 for ( table_id, row_ptrs) in delete_tables {
655- if let ( Some ( table) , blob_store, _) = self . get_table_and_blob_store_mut ( table_id) {
656- delete_rows ( tx_data, table_id, table, blob_store, row_ptrs. len ( ) , row_ptrs. iter ( ) ) ;
657- } else if !row_ptrs. is_empty ( ) {
658- panic ! ( "Deletion for non-existent table {table_id:?}... huh?" ) ;
669+ match self . get_table_and_blob_store_mut ( table_id) {
670+ Ok ( ( table, blob_store, ..) ) => {
671+ delete_rows ( tx_data, table_id, table, blob_store, row_ptrs. len ( ) , row_ptrs. iter ( ) )
672+ }
673+ Err ( _) if !row_ptrs. is_empty ( ) => panic ! ( "Deletion for non-existent table {table_id:?}... huh?" ) ,
674+ Err ( _) => { }
659675 }
660676 }
661677
@@ -835,12 +851,21 @@ impl CommittedState {
835851 pub ( super ) fn get_table_and_blob_store_mut (
836852 & mut self ,
837853 table_id : TableId ,
838- ) -> ( Option < & mut Table > , & mut dyn BlobStore , & mut IndexIdMap ) {
839- (
840- self . tables . get_mut ( & table_id) ,
854+ ) -> Result < ( & mut Table , & mut dyn BlobStore , & mut IndexIdMap , & PagePool ) > {
855+ // NOTE(centril): `TableError` is a fairly large type.
856+ // Not making this lazy made `TableError::drop` show up in perf.
857+ // TODO(centril): Box all the errors.
858+ #[ allow( clippy:: unnecessary_lazy_evaluations) ]
859+ let table = self
860+ . tables
861+ . get_mut ( & table_id)
862+ . ok_or_else ( || TableError :: IdNotFoundState ( table_id) ) ?;
863+ Ok ( (
864+ table,
841865 & mut self . blob_store as & mut dyn BlobStore ,
842866 & mut self . index_id_map ,
843- )
867+ & self . page_pool ,
868+ ) )
844869 }
845870
846871 fn make_table ( schema : Arc < TableSchema > ) -> Table {
0 commit comments