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::select::SelectTable;
|
||||||
use sql_generation::model::{
|
use sql_generation::model::{
|
||||||
query::{
|
query::{
|
||||||
alter_table::{AlterTable, AlterTableType}, pragma::Pragma, select::{CompoundOperator, FromClause, ResultColumn, SelectInner}, transaction::{Begin, Commit, Rollback}, update::Update, Create, CreateIndex,
|
Create, CreateIndex, Delete, Drop, DropIndex, Insert, Select,
|
||||||
Delete,
|
alter_table::{AlterTable, AlterTableType},
|
||||||
Drop,
|
pragma::Pragma,
|
||||||
DropIndex,
|
select::{CompoundOperator, FromClause, ResultColumn, SelectInner},
|
||||||
Insert,
|
transaction::{Begin, Commit, Rollback},
|
||||||
Select,
|
update::Update,
|
||||||
},
|
},
|
||||||
table::{Index, JoinTable, JoinType, SimValue, Table, TableContext},
|
table::{Index, JoinTable, JoinType, SimValue, Table, TableContext},
|
||||||
};
|
};
|
||||||
@@ -323,6 +323,7 @@ impl Shadow for Drop {
|
|||||||
impl Shadow for Insert {
|
impl Shadow for Insert {
|
||||||
type Result = anyhow::Result<Vec<Vec<SimValue>>>;
|
type Result = anyhow::Result<Vec<Vec<SimValue>>>;
|
||||||
|
|
||||||
|
//FIXME this doesn't handle type affinity
|
||||||
fn shadow(&self, tables: &mut ShadowTablesMut) -> Self::Result {
|
fn shadow(&self, tables: &mut ShadowTablesMut) -> Self::Result {
|
||||||
match self {
|
match self {
|
||||||
Insert::Values { table, values } => {
|
Insert::Values { table, values } => {
|
||||||
@@ -381,7 +382,6 @@ impl Shadow for FromClause {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
for join in &self.joins {
|
for join in &self.joins {
|
||||||
let joined_table = tables
|
let joined_table = tables
|
||||||
.iter()
|
.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>(
|
pub fn pick_unique<'a, T: PartialEq, R: Rng + ?Sized>(
|
||||||
items: &'a [T],
|
items: &'a [T],
|
||||||
count: usize,
|
count: usize,
|
||||||
|
|||||||
@@ -4,7 +4,10 @@ use crate::generation::{
|
|||||||
};
|
};
|
||||||
use crate::model::query::alter_table::{AlterTable, AlterTableType, AlterTableTypeDiscriminants};
|
use crate::model::query::alter_table::{AlterTable, AlterTableType, AlterTableTypeDiscriminants};
|
||||||
use crate::model::query::predicate::Predicate;
|
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::update::Update;
|
||||||
use crate::model::query::{Create, CreateIndex, Delete, Drop, DropIndex, Insert, Select};
|
use crate::model::query::{Create, CreateIndex, Delete, Drop, DropIndex, Insert, Select};
|
||||||
use crate::model::table::{
|
use crate::model::table::{
|
||||||
@@ -81,7 +84,10 @@ impl Arbitrary for FromClause {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
.collect();
|
.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 {
|
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>(
|
fn arbitrary_sized<R: Rng + ?Sized, C: GenerationContext>(
|
||||||
rng: &mut R,
|
rng: &mut R,
|
||||||
env: &C,
|
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);
|
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 {
|
Some(Insert::Select {
|
||||||
table: table.name.clone(),
|
table: table.name.clone(),
|
||||||
@@ -297,10 +326,13 @@ impl Arbitrary for Insert {
|
|||||||
};
|
};
|
||||||
|
|
||||||
backtrack(
|
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,
|
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