@@ -345,19 +345,35 @@ impl CommittedState {
345345 Ok ( ( ) )
346346 }
347347
348+ pub ( super ) fn replay_truncate ( & mut self , table_id : TableId ) -> Result < ( ) > {
349+ // Get the table for mutation.
350+ // If it was dropped, avoid an error and just ignore the row instead.
351+ let ( table, blob_store, ..) = match self . get_table_and_blob_store_mut ( table_id) {
352+ Ok ( t) => t,
353+ Err ( _) if self . table_dropped . contains ( & table_id) => return Ok ( ( ) ) ,
354+ Err ( e) => return Err ( e) ,
355+ } ;
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 < ( ) > {
349366 // Get the table for mutation.
350367 // If it was dropped, avoid an error and just ignore the row instead.
351- let table = match self . tables . get_mut ( & table_id) {
352- Some ( t) => t,
353- None if self . table_dropped . contains ( & table_id) => return Ok ( ( ) ) ,
354- None => return Err ( TableError :: IdNotFoundState ( table_id ) . into ( ) ) ,
368+ let ( table, blob_store , _ , page_pool ) = match self . get_table_and_blob_store_mut ( table_id) {
369+ Ok ( t) => t,
370+ Err ( _ ) if self . table_dropped . contains ( & table_id) => return Ok ( ( ) ) ,
371+ Err ( e ) => return Err ( e ) ,
355372 } ;
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
@@ -488,9 +504,9 @@ impl CommittedState {
488504 for index_row in rows {
489505 let index_id = index_row. index_id ;
490506 let table_id = index_row. table_id ;
491- let ( Some ( table) , blob_store, index_id_map) = self . get_table_and_blob_store_mut ( table_id ) else {
492- panic ! ( "Cannot create index for table which doesn't exist in committed state" ) ;
493- } ;
507+ let ( table, blob_store, index_id_map, _ ) = self
508+ . get_table_and_blob_store_mut ( table_id )
509+ . expect ( "index should exist in committed state; cannot create it" ) ;
494510 let algo: IndexAlgorithm = index_row. index_algorithm . into ( ) ;
495511 let columns: ColSet = algo. columns ( ) . into ( ) ;
496512 let is_unique = unique_constraints. contains ( & ( table_id, columns) ) ;
@@ -591,8 +607,7 @@ impl CommittedState {
591607 "Cannot get TX_STATE RowPointer from CommittedState." ,
592608 ) ;
593609 let table = self
594- . tables
595- . get ( & table_id)
610+ . get_table ( table_id)
596611 . expect ( "Attempt to get COMMITTED_STATE row from table not present in tables." ) ;
597612 // TODO(perf, deep-integration): Use `get_row_ref_unchecked`.
598613 table. get_row_ref ( & self . blob_store , row_ptr) . unwrap ( )
@@ -672,17 +687,18 @@ impl CommittedState {
672687
673688 if !deletes. is_empty ( ) {
674689 let table_name = & * table. get_schema ( ) . table_name ;
675- // TODO(centril): Pass this along to record truncated tables.
676- let _truncated = table. row_count == 0 ;
677- tx_data. set_deletes_for_table ( table_id, table_name, deletes. into ( ) ) ;
690+ let truncated = table. row_count == 0 ;
691+ tx_data. set_deletes_for_table ( table_id, table_name, deletes. into ( ) , truncated) ;
678692 }
679693 }
680694
681695 for ( table_id, row_ptrs) in delete_tables {
682- if let ( Some ( table) , blob_store, _) = self . get_table_and_blob_store_mut ( table_id) {
683- delete_rows ( tx_data, table_id, table, blob_store, row_ptrs. len ( ) , row_ptrs. iter ( ) ) ;
684- } else if !row_ptrs. is_empty ( ) {
685- panic ! ( "Deletion for non-existent table {table_id:?}... huh?" ) ;
696+ match self . get_table_and_blob_store_mut ( table_id) {
697+ Ok ( ( table, blob_store, ..) ) => {
698+ delete_rows ( tx_data, table_id, table, blob_store, row_ptrs. len ( ) , row_ptrs. iter ( ) )
699+ }
700+ Err ( _) if !row_ptrs. is_empty ( ) => panic ! ( "Deletion for non-existent table {table_id:?}... huh?" ) ,
701+ Err ( _) => { }
686702 }
687703 }
688704
@@ -861,12 +877,21 @@ impl CommittedState {
861877 pub ( super ) fn get_table_and_blob_store_mut (
862878 & mut self ,
863879 table_id : TableId ,
864- ) -> ( Option < & mut Table > , & mut dyn BlobStore , & mut IndexIdMap ) {
865- (
866- self . tables . get_mut ( & table_id) ,
880+ ) -> Result < ( & mut Table , & mut dyn BlobStore , & mut IndexIdMap , & PagePool ) > {
881+ // NOTE(centril): `TableError` is a fairly large type.
882+ // Not making this lazy made `TableError::drop` show up in perf.
883+ // TODO(centril): Box all the errors.
884+ #[ allow( clippy:: unnecessary_lazy_evaluations) ]
885+ let table = self
886+ . tables
887+ . get_mut ( & table_id)
888+ . ok_or_else ( || TableError :: IdNotFoundState ( table_id) ) ?;
889+ Ok ( (
890+ table,
867891 & mut self . blob_store as & mut dyn BlobStore ,
868892 & mut self . index_id_map ,
869- )
893+ & self . page_pool ,
894+ ) )
870895 }
871896
872897 fn make_table ( schema : Arc < TableSchema > ) -> Table {
0 commit comments