diff --git a/simulator/generation/expr.rs b/simulator/generation/expr.rs index e9e7da184..244f831c0 100644 --- a/simulator/generation/expr.rs +++ b/simulator/generation/expr.rs @@ -60,103 +60,84 @@ where // Freestyling generation impl ArbitraryFrom<&SimulatorEnv> for Expr { fn arbitrary_from(rng: &mut R, t: &SimulatorEnv) -> Self { - // Loop until we get an implmeneted expression - loop { - let choice = rng.gen_range(0..25); - let expr = match choice { - 0 => Expr::Between { + let choice = rng.gen_range(0..13); + let expr = match choice { + 0 => Expr::Between { + lhs: Box::arbitrary_from(rng, t), + not: rng.gen_bool(0.5), + start: Box::arbitrary_from(rng, t), + end: Box::arbitrary_from(rng, t), + }, + 1 => Expr::Binary( + Box::arbitrary_from(rng, t), + Operator::arbitrary(rng), + Box::arbitrary_from(rng, t), + ), + 2 => Expr::Case { + base: Option::arbitrary_from(rng, t), + when_then_pairs: { + let size = rng.gen_range(0..5); + (0..size) + .into_iter() + .map(|_| (Self::arbitrary_from(rng, t), Self::arbitrary_from(rng, t))) + .collect() + }, + else_expr: Option::arbitrary_from(rng, t), + }, + 3 => Expr::Cast { + expr: Box::arbitrary_from(rng, t), + type_name: Option::arbitrary(rng), + }, + 4 => Expr::Collate(Box::arbitrary_from(rng, t), CollateName::arbitrary(rng).0), + 5 => Expr::InList { + lhs: Box::arbitrary_from(rng, t), + not: rng.gen_bool(0.5), + rhs: Option::arbitrary_from(rng, t), + }, + 6 => Expr::IsNull(Box::arbitrary_from(rng, t)), + 7 => { + let op = LikeOperator::arbitrary_from(rng, t); + let escape = if matches!(op, LikeOperator::Like) { + Option::arbitrary_from(rng, t) + } else { + None + }; + Expr::Like { lhs: Box::arbitrary_from(rng, t), not: rng.gen_bool(0.5), - start: Box::arbitrary_from(rng, t), - end: Box::arbitrary_from(rng, t), - }, - 1 => Expr::Binary( - Box::arbitrary_from(rng, t), - Operator::arbitrary(rng), - Box::arbitrary_from(rng, t), - ), - 2 => Expr::Case { - base: Option::arbitrary_from(rng, t), - when_then_pairs: { - let size = rng.gen_range(0..5); - (0..size) - .into_iter() - .map(|_| (Self::arbitrary_from(rng, t), Self::arbitrary_from(rng, t))) - .collect() - }, - else_expr: Option::arbitrary_from(rng, t), - }, - 3 => Expr::Cast { - expr: Box::arbitrary_from(rng, t), - type_name: Option::arbitrary(rng), - }, - 4 => Expr::Collate(Box::arbitrary_from(rng, t), CollateName::arbitrary(rng).0), - // TODO: Skip Column as this is not generated by Parser Normally - 5 => continue, - // TODO: Skip DoublyQualified for now - 6 => continue, - // TODO: skip Exists for now - 7 => continue, - // TODO: skip Function Call for now - 8 => continue, - // TODO: skip Function Call Star for now - 9 => continue, - // TODO: skip ID for now - 10 => continue, - 11 => Expr::InList { - lhs: Box::arbitrary_from(rng, t), - not: rng.gen_bool(0.5), - rhs: Option::arbitrary_from(rng, t), - }, - // TODO: skip InSelect as still need to implement ArbitratyFrom for Select - 12 => continue, - // TODO: skip InTable - 13 => continue, - 14 => Expr::IsNull(Box::arbitrary_from(rng, t)), - 15 => { - let op = LikeOperator::arbitrary_from(rng, t); - let escape = if matches!(op, LikeOperator::Like) { - Option::arbitrary_from(rng, t) - } else { - None - }; - Expr::Like { - lhs: Box::arbitrary_from(rng, t), - not: rng.gen_bool(0.5), - op, - rhs: Box::arbitrary_from(rng, t), - escape, - } + op, + rhs: Box::arbitrary_from(rng, t), + escape, } - 16 => Expr::Literal(ast::Literal::arbitrary_from(rng, t)), - // TODO: skip Name - 17 => continue, - 18 => Expr::NotNull(Box::arbitrary_from(rng, t)), - // TODO: only support one paranthesized expression - 19 => Expr::Parenthesized(vec![Expr::arbitrary_from(rng, t)]), - 20 => { - let table_idx = pick_index(t.tables.len(), rng); - let table = &t.tables[table_idx]; - let col_idx = pick_index(table.columns.len(), rng); - let col = &table.columns[col_idx]; - Expr::Qualified(Name(table.name.clone()), Name(col.name.clone())) - } - // TODO: skip Raise - 21 => continue, - // TODO: skip RowId not emitted by parser - 22 => continue, - // TODO: skip subquery - 23 => continue, - 24 => Expr::Unary( - UnaryOperator::arbitrary_from(rng, t), - Box::arbitrary_from(rng, t), - ), - // TODO: skip Variable as it does not make much sense for the simulator - 25 => continue, - _ => unreachable!(), - }; - break expr; - } + } + 8 => Expr::Literal(ast::Literal::arbitrary_from(rng, t)), + 9 => Expr::NotNull(Box::arbitrary_from(rng, t)), + // TODO: only supports one paranthesized expression + 10 => Expr::Parenthesized(vec![Expr::arbitrary_from(rng, t)]), + 11 => { + let table_idx = pick_index(t.tables.len(), rng); + let table = &t.tables[table_idx]; + let col_idx = pick_index(table.columns.len(), rng); + let col = &table.columns[col_idx]; + Expr::Qualified(Name(table.name.clone()), Name(col.name.clone())) + } + 12 => Expr::Unary( + UnaryOperator::arbitrary_from(rng, t), + Box::arbitrary_from(rng, t), + ), + // TODO: skip Exists for now + // TODO: skip Function Call for now + // TODO: skip Function Call Star for now + // TODO: skip ID for now + // TODO: skip InSelect as still need to implement ArbitratyFrom for Select + // TODO: skip InTable + // TODO: skip Name + // TODO: Skip DoublyQualified for now + // TODO: skip Raise + // TODO: skip subquery + _ => unreachable!(), + }; + expr } }