@@ -821,7 +821,7 @@ impl RelationalDB {
821821
822822 let is_ephemeral_tables = |table_id : & TableId | -> bool {
823823 tx_data
824- . ephermal_tables ( )
824+ . ephemeral_tables ( )
825825 . map ( |etables| etables. contains ( table_id) )
826826 . unwrap_or ( false )
827827 } ;
@@ -2494,6 +2494,90 @@ mod tests {
24942494 Ok ( ( ) )
24952495 }
24962496
2497+ fn setup_view ( stdb : & TestDB ) -> ResultTest < ( ViewId , TableId , ModuleDef , ViewDef ) > {
2498+ let module_def = view_module_def ( ) ;
2499+ let view_def = module_def. view ( "my_view" ) . unwrap ( ) ;
2500+
2501+ let mut tx = begin_mut_tx ( stdb) ;
2502+ let ( view_id, table_id) = stdb. create_view ( & mut tx, & module_def, view_def) ?;
2503+ stdb. commit_tx ( tx) ?;
2504+
2505+ Ok ( ( view_id, table_id, module_def. clone ( ) , view_def. clone ( ) ) )
2506+ }
2507+
2508+ fn insert_view_row (
2509+ stdb : & TestDB ,
2510+ view_id : ViewId ,
2511+ table_id : TableId ,
2512+ typespace : & Typespace ,
2513+ row_type : AlgebraicTypeRef ,
2514+ sender : Identity ,
2515+ v : u8 ,
2516+ ) -> ResultTest < ( ) > {
2517+ let to_bstan = |pv : & ProductValue | {
2518+ Bytes :: from ( to_vec ( & AlgebraicValue :: Array ( [ pv. clone ( ) ] . into ( ) ) ) . expect ( "bstan serialization failed" ) )
2519+ } ;
2520+
2521+ let row_pv = |v : u8 | ProductValue :: from_iter ( vec ! [ AlgebraicValue :: U8 ( v) ] ) ;
2522+
2523+ let mut tx = begin_mut_tx ( stdb) ;
2524+ tx. subscribe_view ( view_id, ArgId :: SENTINEL , sender) ?;
2525+ stdb. materialize_view ( & mut tx, table_id, sender, row_type, to_bstan ( & row_pv ( v) ) , typespace) ?;
2526+ stdb. commit_tx ( tx) ?;
2527+
2528+ Ok ( ( ) )
2529+ }
2530+
2531+ fn project_views ( stdb : & TestDB , table_id : TableId , sender : Identity ) -> Vec < ProductValue > {
2532+ let tx = begin_tx ( stdb) ;
2533+
2534+ stdb. iter_by_col_eq ( & tx, table_id, 0 , & sender. into ( ) )
2535+ . unwrap ( )
2536+ . map ( |row| {
2537+ let pv = row. to_product_value ( ) ;
2538+ ProductValue {
2539+ elements : pv. elements . iter ( ) . skip ( 1 ) . cloned ( ) . collect ( ) ,
2540+ }
2541+ } )
2542+ . collect ( )
2543+ }
2544+
2545+
2546+ #[ test]
2547+ fn test_view_tables_are_ephemeral ( ) -> ResultTest < ( ) > {
2548+ let stdb = TestDB :: durable ( ) ?;
2549+
2550+ let ( view_id, table_id, module_def, view_def) = setup_view ( & stdb) ?;
2551+ let row_type = view_def. product_type_ref ;
2552+ let typespace = module_def. typespace ( ) ;
2553+
2554+ // Write some rows (reusing the same helper)
2555+ insert_view_row ( & stdb, view_id, table_id, typespace, row_type, Identity :: ONE , 10 ) ?;
2556+ insert_view_row ( & stdb, view_id, table_id, typespace, row_type, Identity :: ZERO , 20 ) ?;
2557+
2558+ assert ! (
2559+ !project_views( & stdb, table_id, Identity :: ZERO ) . is_empty( ) ,
2560+ "View table should NOT be empty after insert"
2561+ ) ;
2562+
2563+ // Reopen the database — view tables must not persist
2564+ let stdb = stdb. reopen ( ) ?;
2565+
2566+ // Validate that the view's backing table has been removed
2567+ assert ! (
2568+ project_views( & stdb, table_id, Identity :: ZERO ) . is_empty( ) ,
2569+ "View table should be empty after reopening the database"
2570+ ) ;
2571+
2572+ let tx = begin_mut_tx ( & stdb) ;
2573+ let subs_rows = tx. lookup_st_view_subs ( view_id) ?;
2574+ assert ! (
2575+ subs_rows. is_empty( ) ,
2576+ "st_view_subs should be empty after reopening the database"
2577+ ) ;
2578+ Ok ( ( ) )
2579+ }
2580+
24972581 #[ test]
24982582 fn test_table_name ( ) -> ResultTest < ( ) > {
24992583 let stdb = TestDB :: durable ( ) ?;
0 commit comments