@@ -46,7 +46,7 @@ use spacetimedb_paths::server::{CommitLogDir, ReplicaDir, SnapshotsPath};
4646use spacetimedb_primitives:: * ;
4747use spacetimedb_sats:: algebraic_type:: fmt:: fmt_algebraic_type;
4848use spacetimedb_sats:: memory_usage:: MemoryUsage ;
49- use spacetimedb_sats:: { product , AlgebraicType , AlgebraicValue , ProductType , ProductValue , Typespace } ;
49+ use spacetimedb_sats:: { AlgebraicType , AlgebraicTypeRef , AlgebraicValue , ProductType , ProductValue , Typespace } ;
5050use spacetimedb_schema:: def:: { ModuleDef , TableDef , ViewDef } ;
5151use spacetimedb_schema:: schema:: {
5252 ColumnSchema , IndexSchema , RowLevelSecuritySchema , Schema , SequenceSchema , TableSchema ,
@@ -1531,71 +1531,64 @@ impl RelationalDB {
15311531 tx : & mut MutTxId ,
15321532 view : & str ,
15331533 args : ArgsTuple ,
1534- return_type : AlgebraicType ,
1534+ return_type : AlgebraicTypeRef ,
15351535 bytes : Bytes ,
15361536 typespace : & Typespace ,
15371537 caller_identity : Identity ,
15381538 ) -> Result < ( ) , DBError > {
15391539 // Fetch view metadata
15401540 let st_view_row = tx. lookup_st_view_by_name ( view) ?;
15411541 let table_id = st_view_row. table_id . expect ( "View table must exist for materialization" ) ;
1542+ let view_id = st_view_row. view_id ;
15421543 let is_anonymous = st_view_row. is_anonymous ;
1543-
15441544 let arg_id = tx. get_or_insert_st_view_arg ( args. get_bsatn ( ) ) ?;
15451545
15461546 // Build the filter key for identifying rows to update
1547- let input_args = product ! [
1548- if is_anonymous {
1549- AlgebraicValue :: OptionNone ( )
1550- } else {
1551- AlgebraicValue :: OptionSome ( caller_identity. into( ) )
1552- } ,
1553- AlgebraicValue :: U64 ( arg_id)
1554- ] ;
1547+ let mut input_args = Vec :: new ( ) ;
1548+ if !is_anonymous {
1549+ input_args. push ( AlgebraicValue :: OptionSome ( caller_identity. into ( ) ) ) ;
1550+ }
1551+ if !tx. is_view_parameterized ( view_id) ? {
1552+ input_args. push ( AlgebraicValue :: U64 ( arg_id) ) ;
1553+ }
1554+ let input_args = ProductValue {
1555+ elements : input_args. into_boxed_slice ( ) ,
1556+ } ;
1557+ let col_list: ColList = ( 0 ..input_args. elements . len ( ) ) . collect ( ) ;
15551558
15561559 // Remove stale View entries
15571560 let rows_to_delete: Vec < _ > = self
1558- . iter_by_col_eq_mut ( tx, table_id, [ 0 , 1 ] , & input_args. clone ( ) . into ( ) ) ?
1561+ . iter_by_col_eq_mut ( tx, table_id, col_list , & input_args. clone ( ) . into ( ) ) ?
15591562 . map ( |res| res. pointer ( ) )
15601563 . collect ( ) ;
15611564
15621565 let deleted_count = self . delete ( tx, table_id, rows_to_delete) ;
15631566 trace ! ( "Deleted {deleted_count} stale rows from view table {table_id} for arg_id {arg_id}" ) ;
15641567
15651568 // Deserialize the return value
1566- let seed = spacetimedb_sats:: WithTypespace :: new ( typespace, & return_type) ;
1569+ let seed = spacetimedb_sats:: WithTypespace :: new ( typespace, & return_type) . resolve ( return_type ) ;
15671570 let return_val = seed
15681571 . deserialize ( bsatn:: Deserializer :: new ( & mut & bytes[ ..] ) )
15691572 . map_err ( |e| DatastoreError :: from ( ViewError :: DeserializeReturn ( e. to_string ( ) ) ) ) ?;
15701573
15711574 // Extract products from return value (must be array or option)
1572- let products: Vec < ProductValue > = if return_type. is_array ( ) {
1573- let arr = return_val
1574- . into_array ( )
1575- . expect ( "return_type.is_array() ensures this is an array" ) ;
1576-
1577- arr. into_iter ( ) . map ( |v| v. into_product ( ) . unwrap ( ) ) . collect ( )
1578- } else if return_type. is_option ( ) {
1579- let opt = return_val
1580- . into_option ( )
1581- . expect ( "return_type.is_option() ensures this is an option" ) ;
1582- opt. into_iter ( ) . map ( |v| v. into_product ( ) . unwrap ( ) ) . collect ( )
1583- } else {
1584- return Err ( DatastoreError :: from ( ViewError :: InvalidReturnType ( return_type) ) . into ( ) ) ;
1585- } ;
1575+ let products: Vec < ProductValue > = return_val
1576+ . into_array ( )
1577+ . expect ( "Expected return_val to be an array" )
1578+ . into_iter ( )
1579+ . map ( |v| v. into_product ( ) . expect ( "Expected array elements to be ProductValue" ) )
1580+ . collect ( ) ;
15861581
15871582 // Insert fresh results into the view table
15881583 let mut elements: Vec < AlgebraicValue > =
15891584 Vec :: with_capacity ( input_args. elements . len ( ) + products. first ( ) . map_or ( 0 , |p| p. elements . len ( ) ) ) ;
15901585 for product in products {
15911586 elements. clear ( ) ;
1592- // Build complete row by prepending filter key to product data
1593- let mut elements = Vec :: with_capacity ( input_args. elements . len ( ) + product. elements . len ( ) ) ;
15941587 elements. extend_from_slice ( & input_args. elements ) ;
15951588 elements. extend_from_slice ( & product. elements ) ;
15961589
15971590 let row = ProductValue {
1598- elements : elements. into_boxed_slice ( ) ,
1591+ elements : elements. as_slice ( ) . into ( ) ,
15991592 } ;
16001593
16011594 let row_bytes = row
0 commit comments