diff --git a/sql_generation/generation/predicate/binary.rs b/sql_generation/generation/predicate/binary.rs index e3b52d5ec..25d813c76 100644 --- a/sql_generation/generation/predicate/binary.rs +++ b/sql_generation/generation/predicate/binary.rs @@ -16,44 +16,6 @@ use crate::{ }; impl Predicate { - /// Generate an [ast::Expr::Binary] [Predicate] from a column and [SimValue] - pub fn from_column_binary( - rng: &mut R, - context: &C, - column_name: &str, - value: &SimValue, - ) -> Predicate { - let expr = one_of( - vec![ - Box::new(|_| { - Expr::Binary( - Box::new(Expr::Id(ast::Name::exact(column_name.to_string()))), - ast::Operator::Equals, - Box::new(Expr::Literal(value.into())), - ) - }), - Box::new(|rng| { - let gt_value = GTValue::arbitrary_from(rng, context, value).0; - Expr::Binary( - Box::new(Expr::Id(ast::Name::exact(column_name.to_string()))), - ast::Operator::Greater, - Box::new(Expr::Literal(gt_value.into())), - ) - }), - Box::new(|rng| { - let lt_value = LTValue::arbitrary_from(rng, context, value).0; - Expr::Binary( - Box::new(Expr::Id(ast::Name::exact(column_name.to_string()))), - ast::Operator::Less, - Box::new(Expr::Literal(lt_value.into())), - ) - }), - ], - rng, - ); - Predicate(expr) - } - /// Produces a true [ast::Expr::Binary] [Predicate] that is true for the provided row in the given table pub fn true_binary( rng: &mut R, @@ -117,7 +79,8 @@ impl Predicate { ( 1, Box::new(|rng| { - let lt_value = LTValue::arbitrary_from(rng, context, value).0; + let lt_value = + LTValue::arbitrary_from(rng, context, (value, column.column_type)).0; Some(Expr::Binary( Box::new(ast::Expr::Qualified( ast::Name::from_string(&table_name), @@ -131,7 +94,8 @@ impl Predicate { ( 1, Box::new(|rng| { - let gt_value = GTValue::arbitrary_from(rng, context, value).0; + let gt_value = + GTValue::arbitrary_from(rng, context, (value, column.column_type)).0; Some(Expr::Binary( Box::new(ast::Expr::Qualified( ast::Name::from_string(&table_name), @@ -223,7 +187,8 @@ impl Predicate { ) }), Box::new(|rng| { - let gt_value = GTValue::arbitrary_from(rng, context, value).0; + let gt_value = + GTValue::arbitrary_from(rng, context, (value, column.column_type)).0; Expr::Binary( Box::new(ast::Expr::Qualified( ast::Name::from_string(&table_name), @@ -234,7 +199,8 @@ impl Predicate { ) }), Box::new(|rng| { - let lt_value = LTValue::arbitrary_from(rng, context, value).0; + let lt_value = + LTValue::arbitrary_from(rng, context, (value, column.column_type)).0; Expr::Binary( Box::new(ast::Expr::Qualified( ast::Name::from_string(&table_name), @@ -283,7 +249,12 @@ impl SimplePredicate { ) }), Box::new(|rng| { - let lt_value = LTValue::arbitrary_from(rng, context, column_value).0; + let lt_value = LTValue::arbitrary_from( + rng, + context, + (column_value, column.column.column_type), + ) + .0; Expr::Binary( Box::new(Expr::Qualified( ast::Name::from_string(table_name), @@ -294,7 +265,12 @@ impl SimplePredicate { ) }), Box::new(|rng| { - let gt_value = GTValue::arbitrary_from(rng, context, column_value).0; + let gt_value = GTValue::arbitrary_from( + rng, + context, + (column_value, column.column.column_type), + ) + .0; Expr::Binary( Box::new(Expr::Qualified( ast::Name::from_string(table_name), @@ -341,7 +317,12 @@ impl SimplePredicate { ) }), Box::new(|rng| { - let gt_value = GTValue::arbitrary_from(rng, context, column_value).0; + let gt_value = GTValue::arbitrary_from( + rng, + context, + (column_value, column.column.column_type), + ) + .0; Expr::Binary( Box::new(ast::Expr::Qualified( ast::Name::from_string(table_name), @@ -352,7 +333,12 @@ impl SimplePredicate { ) }), Box::new(|rng| { - let lt_value = LTValue::arbitrary_from(rng, context, column_value).0; + let lt_value = LTValue::arbitrary_from( + rng, + context, + (column_value, column.column.column_type), + ) + .0; Expr::Binary( Box::new(ast::Expr::Qualified( ast::Name::from_string(table_name), diff --git a/sql_generation/generation/predicate/mod.rs b/sql_generation/generation/predicate/mod.rs index d0dd375bb..75546848a 100644 --- a/sql_generation/generation/predicate/mod.rs +++ b/sql_generation/generation/predicate/mod.rs @@ -76,16 +76,6 @@ impl ArbitraryFrom<(&T, bool)> for Predicate { } } -impl ArbitraryFrom<(&str, &SimValue)> for Predicate { - fn arbitrary_from( - rng: &mut R, - context: &C, - (column_name, value): (&str, &SimValue), - ) -> Self { - Predicate::from_column_binary(rng, context, column_name, value) - } -} - impl ArbitraryFrom<(&Table, &Vec)> for Predicate { fn arbitrary_from( rng: &mut R, diff --git a/sql_generation/generation/value/cmp.rs b/sql_generation/generation/value/cmp.rs index 567a59a5e..31c710acd 100644 --- a/sql_generation/generation/value/cmp.rs +++ b/sql_generation/generation/value/cmp.rs @@ -2,32 +2,16 @@ use turso_core::Value; use crate::{ generation::{ArbitraryFrom, GenerationContext}, - model::table::SimValue, + model::table::{ColumnType, SimValue}, }; pub struct LTValue(pub SimValue); -impl ArbitraryFrom<&Vec<&SimValue>> for LTValue { - fn arbitrary_from( - rng: &mut R, - context: &C, - values: &Vec<&SimValue>, - ) -> Self { - if values.is_empty() { - return Self(SimValue(Value::Null)); - } - - // Get value less than all values - let value = Value::exec_min(values.iter().map(|value| &value.0)); - Self::arbitrary_from(rng, context, &SimValue(value)) - } -} - -impl ArbitraryFrom<&SimValue> for LTValue { +impl ArbitraryFrom<(&SimValue, ColumnType)> for LTValue { fn arbitrary_from( rng: &mut R, _context: &C, - value: &SimValue, + (value, _col_type): (&SimValue, ColumnType), ) -> Self { let new_value = match &value.0 { Value::Integer(i) => Value::Integer(rng.random_range(i64::MIN..*i - 1)), @@ -69,7 +53,8 @@ impl ArbitraryFrom<&SimValue> for LTValue { Value::Blob(b) } } - _ => unreachable!(), + // A value with storage class NULL is considered less than any other value (including another value with storage class NULL) + Value::Null => Value::Null, }; Self(SimValue(new_value)) } @@ -77,27 +62,11 @@ impl ArbitraryFrom<&SimValue> for LTValue { pub struct GTValue(pub SimValue); -impl ArbitraryFrom<&Vec<&SimValue>> for GTValue { +impl ArbitraryFrom<(&SimValue, ColumnType)> for GTValue { fn arbitrary_from( rng: &mut R, context: &C, - values: &Vec<&SimValue>, - ) -> Self { - if values.is_empty() { - return Self(SimValue(Value::Null)); - } - // Get value greater than all values - let value = Value::exec_max(values.iter().map(|value| &value.0)); - - Self::arbitrary_from(rng, context, &SimValue(value)) - } -} - -impl ArbitraryFrom<&SimValue> for GTValue { - fn arbitrary_from( - rng: &mut R, - _context: &C, - value: &SimValue, + (value, col_type): (&SimValue, ColumnType), ) -> Self { let new_value = match &value.0 { Value::Integer(i) => Value::Integer(rng.random_range(*i..i64::MAX)), @@ -139,7 +108,10 @@ impl ArbitraryFrom<&SimValue> for GTValue { Value::Blob(b) } } - _ => unreachable!(), + Value::Null => { + // Any value is greater than NULL, except NULL + SimValue::arbitrary_from(rng, context, col_type).0 + } }; Self(SimValue(new_value)) } diff --git a/sql_generation/generation/value/mod.rs b/sql_generation/generation/value/mod.rs index e0c98ad84..5062c9e57 100644 --- a/sql_generation/generation/value/mod.rs +++ b/sql_generation/generation/value/mod.rs @@ -51,8 +51,18 @@ impl ArbitraryFrom<&ColumnType> for SimValue { ColumnType::Integer => Value::Integer(rng.random_range(i64::MIN..i64::MAX)), ColumnType::Float => Value::Float(rng.random_range(-1e10..1e10)), ColumnType::Text => Value::build_text(gen_random_text(rng)), - ColumnType::Blob => Value::Blob(gen_random_text(rng).as_bytes().to_vec()), + ColumnType::Blob => Value::Blob(gen_random_text(rng).into_bytes()), }; SimValue(value) } } + +impl ArbitraryFrom for SimValue { + fn arbitrary_from( + rng: &mut R, + context: &C, + column_type: ColumnType, + ) -> Self { + SimValue::arbitrary_from(rng, context, &column_type) + } +} diff --git a/sql_generation/model/table.rs b/sql_generation/model/table.rs index 1060b8bb8..ceb650900 100644 --- a/sql_generation/model/table.rs +++ b/sql_generation/model/table.rs @@ -98,7 +98,7 @@ impl Display for Column { } } -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Copy, Serialize, Deserialize)] pub enum ColumnType { Integer, Float,