@@ -7,7 +7,7 @@ use crate::{
77} ;
88
99use super :: {
10- frequency, pick, pick_index ,
10+ frequency, pick,
1111 plan:: { Assertion , Interaction , InteractionStats , ResultSet } ,
1212 ArbitraryFrom ,
1313} ;
@@ -66,20 +66,26 @@ impl Property {
6666 Property :: DoubleCreateFailure { .. } => "Double-Create-Failure" . to_string ( ) ,
6767 }
6868 }
69+ /// interactions construct a list of interactions, which is an executable representation of the property.
70+ /// the requirement of property -> vec<interaction> conversion emerges from the need to serialize the property,
71+ /// and `interaction` cannot be serialized directly.
6972 pub ( crate ) fn interactions ( & self ) -> Vec < Interaction > {
7073 match self {
7174 Property :: InsertSelect {
7275 insert,
7376 queries,
7477 select,
7578 } => {
76- // Check that the row is there
77- let row = insert
78- . values
79- . first ( ) // `.first` is safe, because we know we are inserting a row in the insert select property
80- . expect ( "insert query should have at least 1 value" )
81- . clone ( ) ;
79+ // Check that the insert query has at least 1 value
80+ assert ! (
81+ !insert. values. is_empty( ) ,
82+ "insert query should have at least 1 value"
83+ ) ;
8284
85+ // Pick a random row within the insert values
86+ let row = pick ( & insert. values , & mut rand:: thread_rng ( ) ) . clone ( ) ;
87+
88+ // Assume that the table exists
8389 let assumption = Interaction :: Assumption ( Assertion {
8490 message : format ! ( "table {} exists" , insert. table) ,
8591 func : Box :: new ( {
@@ -190,26 +196,18 @@ fn property_insert_select<R: rand::Rng>(
190196) -> Property {
191197 // Get a random table
192198 let table = pick ( & env. tables , rng) ;
193- // Pick a random column
194- let column_index = pick_index ( table. columns . len ( ) , rng) ;
195- let column = & table. columns [ column_index] . clone ( ) ;
196- // Generate a random value of the column type
197- let value = Value :: arbitrary_from ( rng, & column. column_type ) ;
198- // Create a whole new row
199- let mut row = Vec :: new ( ) ;
200- for ( i, column) in table. columns . iter ( ) . enumerate ( ) {
201- if i == column_index {
202- row. push ( value. clone ( ) ) ;
203- } else {
204- let value = Value :: arbitrary_from ( rng, & column. column_type ) ;
205- row. push ( value) ;
206- }
207- }
199+ // Generate rows to insert
200+ let rows = ( 0 ..rng. gen_range ( 1 ..=5 ) )
201+ . map ( |_| Vec :: < Value > :: arbitrary_from ( rng, table) )
202+ . collect :: < Vec < _ > > ( ) ;
203+
204+ // Pick a random row to select
205+ let row = pick ( & rows, rng) . clone ( ) ;
208206
209- // Insert the row
207+ // Insert the rows
210208 let insert_query = Insert {
211209 table : table. name . clone ( ) ,
212- values : vec ! [ row . clone ( ) ] ,
210+ values : rows ,
213211 } ;
214212
215213 // Create random queries respecting the constraints
0 commit comments