@@ -2,7 +2,7 @@ use assert_matches::assert_matches;
22use bytes:: Bytes ;
33use scylla_macros:: DeserializeRow ;
44
5- use crate :: frame:: response:: result:: { ColumnSpec , ColumnType } ;
5+ use crate :: frame:: response:: result:: { ColumnSpec , ColumnType , TableSpec } ;
66use crate :: types:: deserialize:: row:: BuiltinDeserializationErrorKind ;
77use crate :: types:: deserialize:: { value, DeserializationError , FrameSlice } ;
88
@@ -859,3 +859,49 @@ fn test_struct_deserialization_errors() {
859859 }
860860 }
861861}
862+
863+ #[ test]
864+ fn metadata_does_not_bound_deserialized_rows ( ) {
865+ /* It's important to understand what is a _deserialized row_. It's not just
866+ * an implementor of `DeserializeRow`; there are some implementors of `DeserializeRow`
867+ * who are not yet final rows, but partially deserialized rows that support further
868+ * deserialization - _row deserializers_, such as `ColumnIterator`.
869+ * _Row deserializers_, because they still need to deserialize some row, are naturally
870+ * bound by 'metadata lifetime. However, _rows_ are completely deserialized, so they
871+ * should not be bound by 'metadata - only by 'frame. This test asserts that.
872+ */
873+
874+ // We don't care about the actual deserialized data - all `Err`s is OK.
875+ // This test's goal is only to compile, asserting that lifetimes are correct.
876+ let bytes = Bytes :: new ( ) ;
877+
878+ // By this binding, we require that the deserialized rows live longer than metadata.
879+ let _decoded_results = {
880+ // Metadata's lifetime is limited to this scope.
881+
882+ fn col_spec < ' a > ( name : & ' a str , typ : ColumnType < ' a > ) -> ColumnSpec < ' a > {
883+ ColumnSpec :: borrowed ( name, typ, TableSpec :: borrowed ( "ks" , "tbl" ) )
884+ }
885+
886+ let row_typ = & [
887+ col_spec ( "bytes" , ColumnType :: Blob ) ,
888+ col_spec ( "text" , ColumnType :: Text ) ,
889+ ] ;
890+
891+ // Tuple
892+ let decoded_tuple_res = deserialize :: < ( & [ u8 ] , & str ) > ( row_typ, & bytes) ;
893+
894+ // Custom struct
895+ #[ derive( DeserializeRow ) ]
896+ #[ scylla( crate =crate ) ]
897+ struct MyRow < ' frame > {
898+ #[ allow( dead_code) ]
899+ bytes : & ' frame [ u8 ] ,
900+ #[ allow( dead_code) ]
901+ text : & ' frame str ,
902+ }
903+ let decoded_custom_struct_res = deserialize :: < MyRow > ( row_typ, & bytes) ;
904+
905+ ( decoded_tuple_res, decoded_custom_struct_res)
906+ } ;
907+ }
0 commit comments