mirror of
https://github.com/aljazceru/turso.git
synced 2026-02-18 06:24:56 +01:00
sim: add order by to some queries
This commit is contained in:
@@ -688,6 +688,7 @@ impl Property {
|
||||
columns: select.body.select.columns.clone(),
|
||||
from: select.body.select.from.clone(),
|
||||
where_clause: p_true,
|
||||
order_by: None,
|
||||
}),
|
||||
compounds: vec![
|
||||
CompoundSelect {
|
||||
@@ -697,6 +698,7 @@ impl Property {
|
||||
columns: select.body.select.columns.clone(),
|
||||
from: select.body.select.from.clone(),
|
||||
where_clause: p_false,
|
||||
order_by: None,
|
||||
}),
|
||||
},
|
||||
CompoundSelect {
|
||||
@@ -706,6 +708,7 @@ impl Property {
|
||||
columns: select.body.select.columns.clone(),
|
||||
from: select.body.select.from.clone(),
|
||||
where_clause: p_null,
|
||||
order_by: None,
|
||||
}),
|
||||
},
|
||||
],
|
||||
|
||||
@@ -2,7 +2,7 @@ use crate::generation::{Arbitrary, ArbitraryFrom, ArbitrarySizedFrom, Shadow};
|
||||
use crate::model::query::predicate::Predicate;
|
||||
use crate::model::query::select::{
|
||||
CompoundOperator, CompoundSelect, Distinctness, FromClause, JoinTable, JoinType, JoinedTable,
|
||||
ResultColumn, SelectBody, SelectInner,
|
||||
OrderBy, ResultColumn, SelectBody, SelectInner,
|
||||
};
|
||||
use crate::model::query::update::Update;
|
||||
use crate::model::query::{Create, Delete, Drop, Insert, Query, Select};
|
||||
@@ -10,7 +10,7 @@ use crate::model::table::{SimValue, Table};
|
||||
use crate::SimulatorEnv;
|
||||
use itertools::Itertools;
|
||||
use rand::Rng;
|
||||
use turso_sqlite3_parser::ast::Expr;
|
||||
use turso_sqlite3_parser::ast::{Expr, SortOrder};
|
||||
|
||||
use super::property::Remaining;
|
||||
use super::{backtrack, frequency, pick};
|
||||
@@ -85,6 +85,46 @@ impl ArbitraryFrom<&SimulatorEnv> for SelectInner {
|
||||
.expect("Failed to shadow FromClause")
|
||||
.into_table();
|
||||
|
||||
let order_by = 'order_by: {
|
||||
if rng.gen_bool(0.3) {
|
||||
let order_by_table_candidates = from
|
||||
.joins
|
||||
.iter()
|
||||
.map(|j| j.table.clone())
|
||||
.chain(std::iter::once(from.table.clone()))
|
||||
.collect::<Vec<_>>();
|
||||
let cuml_col_count = join_table.columns.len();
|
||||
let order_by_col_count =
|
||||
(rng.gen::<f64>() * rng.gen::<f64>() * (cuml_col_count as f64)) as usize; // skew towards 0
|
||||
if order_by_col_count == 0 {
|
||||
break 'order_by None;
|
||||
}
|
||||
let mut col_names = std::collections::HashSet::new();
|
||||
let mut order_by_cols = Vec::new();
|
||||
while order_by_cols.len() < order_by_col_count {
|
||||
let table = pick(&order_by_table_candidates, rng);
|
||||
let table = tables.iter().find(|t| t.name == *table).unwrap();
|
||||
let col = pick(&table.columns, rng);
|
||||
let col_name = format!("{}.{}", table.name, col.name);
|
||||
if col_names.insert(col_name.clone()) {
|
||||
order_by_cols.push((
|
||||
col_name,
|
||||
if rng.gen_bool(0.5) {
|
||||
SortOrder::Asc
|
||||
} else {
|
||||
SortOrder::Desc
|
||||
},
|
||||
));
|
||||
}
|
||||
}
|
||||
Some(OrderBy {
|
||||
columns: order_by_cols,
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
};
|
||||
|
||||
SelectInner {
|
||||
distinctness: if env.opts.experimental_indexes {
|
||||
Distinctness::arbitrary(rng)
|
||||
@@ -94,6 +134,7 @@ impl ArbitraryFrom<&SimulatorEnv> for SelectInner {
|
||||
columns: vec![ResultColumn::Star],
|
||||
from: Some(from),
|
||||
where_clause: Predicate::arbitrary_from(rng, &join_table),
|
||||
order_by,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ use anyhow::Context;
|
||||
pub use ast::Distinctness;
|
||||
use itertools::Itertools;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use turso_sqlite3_parser::ast::{self, fmt::ToTokens};
|
||||
use turso_sqlite3_parser::ast::{self, fmt::ToTokens, SortOrder};
|
||||
|
||||
use crate::{
|
||||
generation::Shadow,
|
||||
@@ -63,6 +63,7 @@ impl Select {
|
||||
columns: vec![ResultColumn::Expr(expr)],
|
||||
from: None,
|
||||
where_clause: Predicate::true_(),
|
||||
order_by: None,
|
||||
}),
|
||||
compounds: Vec::new(),
|
||||
},
|
||||
@@ -87,6 +88,7 @@ impl Select {
|
||||
joins: Vec::new(),
|
||||
}),
|
||||
where_clause,
|
||||
order_by: None,
|
||||
}),
|
||||
compounds: Vec::new(),
|
||||
},
|
||||
@@ -140,6 +142,11 @@ pub struct SelectBody {
|
||||
pub compounds: Vec<CompoundSelect>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub struct OrderBy {
|
||||
pub columns: Vec<(String, SortOrder)>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub struct SelectInner {
|
||||
/// `DISTINCT`
|
||||
@@ -150,6 +157,8 @@ pub struct SelectInner {
|
||||
pub from: Option<FromClause>,
|
||||
/// `WHERE` clause
|
||||
pub where_clause: Predicate,
|
||||
/// `ORDER BY` clause
|
||||
pub order_by: Option<OrderBy>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
@@ -496,7 +505,19 @@ impl Select {
|
||||
.collect(),
|
||||
),
|
||||
},
|
||||
order_by: None,
|
||||
order_by: self.body.select.order_by.as_ref().map(|o| {
|
||||
o.columns
|
||||
.iter()
|
||||
.map(|(name, order)| ast::SortedColumn {
|
||||
expr: ast::Expr::Id(ast::Id(name.clone())),
|
||||
order: match order {
|
||||
SortOrder::Asc => Some(ast::SortOrder::Asc),
|
||||
SortOrder::Desc => Some(ast::SortOrder::Desc),
|
||||
},
|
||||
nulls: None,
|
||||
})
|
||||
.collect()
|
||||
}),
|
||||
limit: self.limit.map(|l| {
|
||||
Box::new(ast::Limit {
|
||||
expr: ast::Expr::Literal(ast::Literal::Numeric(l.to_string())),
|
||||
|
||||
Reference in New Issue
Block a user