@@ -345,19 +345,35 @@ impl CommittedState {
345345 Ok ( ( ) )
346346 }
347347
348+ pub ( super ) fn replay_truncate ( & mut self , table_id : TableId ) -> Result < ( ) > {
349+ // (1) Table dropped? Avoid an error and just ignore the row instead.
350+ if self . table_dropped . contains ( & table_id) {
351+ return Ok ( ( ) ) ;
352+ }
353+
354+ // Get the table for mutation.
355+ let ( table, blob_store, ..) = self . get_table_and_blob_store_mut ( table_id) ?;
356+
357+ // We do not need to consider a truncation of `st_table` itself,
358+ // as if that happens, the database is bricked.
359+
360+ table. clear ( blob_store) ;
361+
362+ Ok ( ( ) )
363+ }
364+
348365 pub ( super ) fn replay_delete_by_rel ( & mut self , table_id : TableId , row : & ProductValue ) -> Result < ( ) > {
366+ // (1) Table dropped? Avoid an error and just ignore the row instead.
367+ if self . table_dropped . contains ( & table_id) {
368+ return Ok ( ( ) ) ;
369+ }
370+
349371 // Get the table for mutation.
350- let table = match self . tables . get_mut ( & table_id) {
351- Some ( t) => t,
352- // (1) If it was dropped, avoid an error and just ignore the row instead.
353- None if self . table_dropped . contains ( & table_id) => return Ok ( ( ) ) ,
354- None => return Err ( TableError :: IdNotFoundState ( table_id) . into ( ) ) ,
355- } ;
372+ let ( table, blob_store, _, page_pool) = self . get_table_and_blob_store_mut ( table_id) ?;
356373
357374 // Delete the row.
358- let blob_store = & mut self . blob_store ;
359375 table
360- . delete_equal_row ( & self . page_pool , blob_store, row)
376+ . delete_equal_row ( page_pool, blob_store, row)
361377 . map_err ( TableError :: Bflatn ) ?
362378 . ok_or_else ( || anyhow ! ( "Delete for non-existent row when replaying transaction" ) ) ?;
363379
@@ -493,9 +509,9 @@ impl CommittedState {
493509 for index_row in rows {
494510 let index_id = index_row. index_id ;
495511 let table_id = index_row. table_id ;
496- let ( Some ( table) , blob_store, index_id_map) = self . get_table_and_blob_store_mut ( table_id ) else {
497- panic ! ( "Cannot create index for table which doesn't exist in committed state" ) ;
498- } ;
512+ let ( table, blob_store, index_id_map, _ ) = self
513+ . get_table_and_blob_store_mut ( table_id )
514+ . expect ( "index should exist in committed state; cannot create it" ) ;
499515 let algo: IndexAlgorithm = index_row. index_algorithm . into ( ) ;
500516 let columns: ColSet = algo. columns ( ) . into ( ) ;
501517 let is_unique = unique_constraints. contains ( & ( table_id, columns) ) ;
@@ -596,8 +612,7 @@ impl CommittedState {
596612 "Cannot get TX_STATE RowPointer from CommittedState." ,
597613 ) ;
598614 let table = self
599- . tables
600- . get ( & table_id)
615+ . get_table ( table_id)
601616 . expect ( "Attempt to get COMMITTED_STATE row from table not present in tables." ) ;
602617 // TODO(perf, deep-integration): Use `get_row_ref_unchecked`.
603618 table. get_row_ref ( & self . blob_store , row_ptr) . unwrap ( )
@@ -677,17 +692,18 @@ impl CommittedState {
677692
678693 if !deletes. is_empty ( ) {
679694 let table_name = & * table. get_schema ( ) . table_name ;
680- // TODO(centril): Pass this along to record truncated tables.
681- let _truncated = table. row_count == 0 ;
682- tx_data. set_deletes_for_table ( table_id, table_name, deletes. into ( ) ) ;
695+ let truncated = table. row_count == 0 ;
696+ tx_data. set_deletes_for_table ( table_id, table_name, deletes. into ( ) , truncated) ;
683697 }
684698 }
685699
686700 for ( table_id, row_ptrs) in delete_tables {
687- if let ( Some ( table) , blob_store, _) = self . get_table_and_blob_store_mut ( table_id) {
688- delete_rows ( tx_data, table_id, table, blob_store, row_ptrs. len ( ) , row_ptrs. iter ( ) ) ;
689- } else if !row_ptrs. is_empty ( ) {
690- panic ! ( "Deletion for non-existent table {table_id:?}... huh?" ) ;
701+ match self . get_table_and_blob_store_mut ( table_id) {
702+ Ok ( ( table, blob_store, ..) ) => {
703+ delete_rows ( tx_data, table_id, table, blob_store, row_ptrs. len ( ) , row_ptrs. iter ( ) )
704+ }
705+ Err ( _) if !row_ptrs. is_empty ( ) => panic ! ( "Deletion for non-existent table {table_id:?}... huh?" ) ,
706+ Err ( _) => { }
691707 }
692708 }
693709
@@ -866,12 +882,21 @@ impl CommittedState {
866882 pub ( super ) fn get_table_and_blob_store_mut (
867883 & mut self ,
868884 table_id : TableId ,
869- ) -> ( Option < & mut Table > , & mut dyn BlobStore , & mut IndexIdMap ) {
870- (
871- self . tables . get_mut ( & table_id) ,
885+ ) -> Result < ( & mut Table , & mut dyn BlobStore , & mut IndexIdMap , & PagePool ) > {
886+ // NOTE(centril): `TableError` is a fairly large type.
887+ // Not making this lazy made `TableError::drop` show up in perf.
888+ // TODO(centril): Box all the errors.
889+ #[ allow( clippy:: unnecessary_lazy_evaluations) ]
890+ let table = self
891+ . tables
892+ . get_mut ( & table_id)
893+ . ok_or_else ( || TableError :: IdNotFoundState ( table_id) ) ?;
894+ Ok ( (
895+ table,
872896 & mut self . blob_store as & mut dyn BlobStore ,
873897 & mut self . index_id_map ,
874- )
898+ & self . page_pool ,
899+ ) )
875900 }
876901
877902 fn make_table ( schema : Arc < TableSchema > ) -> Table {
0 commit comments