mirror of
https://github.com/aljazceru/turso.git
synced 2025-12-17 08:34:19 +01:00
generate self-inserts with nested subqueries
This commit is contained in:
@@ -7,12 +7,12 @@ use serde::{Deserialize, Serialize};
|
||||
use sql_generation::model::query::select::SelectTable;
|
||||
use sql_generation::model::{
|
||||
query::{
|
||||
alter_table::{AlterTable, AlterTableType}, pragma::Pragma, select::{CompoundOperator, FromClause, ResultColumn, SelectInner}, transaction::{Begin, Commit, Rollback}, update::Update, Create, CreateIndex,
|
||||
Delete,
|
||||
Drop,
|
||||
DropIndex,
|
||||
Insert,
|
||||
Select,
|
||||
Create, CreateIndex, Delete, Drop, DropIndex, Insert, Select,
|
||||
alter_table::{AlterTable, AlterTableType},
|
||||
pragma::Pragma,
|
||||
select::{CompoundOperator, FromClause, ResultColumn, SelectInner},
|
||||
transaction::{Begin, Commit, Rollback},
|
||||
update::Update,
|
||||
},
|
||||
table::{Index, JoinTable, JoinType, SimValue, Table, TableContext},
|
||||
};
|
||||
@@ -323,6 +323,7 @@ impl Shadow for Drop {
|
||||
impl Shadow for Insert {
|
||||
type Result = anyhow::Result<Vec<Vec<SimValue>>>;
|
||||
|
||||
//FIXME this doesn't handle type affinity
|
||||
fn shadow(&self, tables: &mut ShadowTablesMut) -> Self::Result {
|
||||
match self {
|
||||
Insert::Values { table, values } => {
|
||||
@@ -381,7 +382,6 @@ impl Shadow for FromClause {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
for join in &self.joins {
|
||||
let joined_table = tables
|
||||
.iter()
|
||||
|
||||
@@ -184,6 +184,7 @@ pub fn gen_random_text<R: Rng + ?Sized>(rng: &mut R) -> String {
|
||||
}
|
||||
}
|
||||
|
||||
//FIXME this can hang if count > items.len() or if there are duplicates
|
||||
pub fn pick_unique<'a, T: PartialEq, R: Rng + ?Sized>(
|
||||
items: &'a [T],
|
||||
count: usize,
|
||||
|
||||
@@ -4,7 +4,10 @@ use crate::generation::{
|
||||
};
|
||||
use crate::model::query::alter_table::{AlterTable, AlterTableType, AlterTableTypeDiscriminants};
|
||||
use crate::model::query::predicate::Predicate;
|
||||
use crate::model::query::select::{CompoundOperator, CompoundSelect, Distinctness, FromClause, OrderBy, ResultColumn, SelectBody, SelectInner, SelectTable};
|
||||
use crate::model::query::select::{
|
||||
CompoundOperator, CompoundSelect, Distinctness, FromClause, OrderBy, ResultColumn, SelectBody,
|
||||
SelectInner, SelectTable,
|
||||
};
|
||||
use crate::model::query::update::Update;
|
||||
use crate::model::query::{Create, CreateIndex, Delete, Drop, DropIndex, Insert, Select};
|
||||
use crate::model::table::{
|
||||
@@ -81,7 +84,10 @@ impl Arbitrary for FromClause {
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
FromClause { table: SelectTable::Table(name), joins }
|
||||
FromClause {
|
||||
table: SelectTable::Table(name),
|
||||
joins,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,6 +152,7 @@ impl Arbitrary for SelectInner {
|
||||
}
|
||||
|
||||
impl ArbitrarySized for SelectInner {
|
||||
//FIXME this can generate SELECT statements containing fewer columns than the num_result_columns parameter.
|
||||
fn arbitrary_sized<R: Rng + ?Sized, C: GenerationContext>(
|
||||
rng: &mut R,
|
||||
env: &C,
|
||||
@@ -282,13 +289,35 @@ impl Arbitrary for Insert {
|
||||
})
|
||||
};
|
||||
|
||||
let gen_self_select = |rng: &mut R| {
|
||||
let gen_nested_self_insert = |rng: &mut R| {
|
||||
let table = pick(env.tables(), rng);
|
||||
if table.rows.is_empty() {
|
||||
return None;
|
||||
|
||||
const MAX_SELF_INSERT_DEPTH: i32 = 5;
|
||||
let nesting_depth = rng.random_range(1..=MAX_SELF_INSERT_DEPTH);
|
||||
|
||||
let mut select = Select::simple(
|
||||
table.name.clone(),
|
||||
Predicate::arbitrary_from(rng, env, table),
|
||||
);
|
||||
|
||||
for _ in 1..nesting_depth {
|
||||
select = Select {
|
||||
body: SelectBody {
|
||||
select: Box::new(SelectInner {
|
||||
distinctness: Distinctness::All,
|
||||
columns: vec![ResultColumn::Star],
|
||||
from: Some(FromClause {
|
||||
table: SelectTable::Select(select),
|
||||
joins: Vec::new(),
|
||||
}),
|
||||
where_clause: Predicate::true_(),
|
||||
order_by: None,
|
||||
}),
|
||||
compounds: Vec::new(),
|
||||
},
|
||||
limit: None,
|
||||
};
|
||||
}
|
||||
let predicate = Predicate::true_();
|
||||
let select = Select::simple(table.name.clone(), predicate);
|
||||
|
||||
Some(Insert::Select {
|
||||
table: table.name.clone(),
|
||||
@@ -297,10 +326,13 @@ impl Arbitrary for Insert {
|
||||
};
|
||||
|
||||
backtrack(
|
||||
vec![(1, Box::new(gen_values)), (1, Box::new(gen_self_select))],
|
||||
vec![
|
||||
(1, Box::new(gen_values)),
|
||||
(1, Box::new(gen_nested_self_insert)),
|
||||
],
|
||||
rng,
|
||||
)
|
||||
.expect("backtrack with these arguments should not return None")
|
||||
.expect("backtrack with these arguments should not return None")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user