mirror of
https://github.com/aljazceru/turso.git
synced 2026-02-23 00:45:37 +01:00
Rename SelectQueryType to QueryDestination
This commit is contained in:
@@ -16,7 +16,7 @@ use super::main_loop::{
|
||||
};
|
||||
use super::order_by::{emit_order_by, init_order_by, SortMetadata};
|
||||
use super::plan::{
|
||||
JoinOrderMember, Operation, SelectPlan, SelectQueryType, TableReference, UpdatePlan,
|
||||
JoinOrderMember, Operation, QueryDestination, SelectPlan, TableReference, UpdatePlan,
|
||||
};
|
||||
use super::schema::ParseSchema;
|
||||
use super::select::emit_simple_count;
|
||||
@@ -263,9 +263,9 @@ fn emit_program_for_compound_select(
|
||||
|
||||
let mut union_dedupe_index = if requires_union_deduplication {
|
||||
let dedupe_index = get_union_dedupe_index(program, &first);
|
||||
first.query_type = SelectQueryType::UnionArm {
|
||||
index_cursor_id: dedupe_index.0,
|
||||
dedupe_index: dedupe_index.1.clone(),
|
||||
first.query_destination = QueryDestination::EphemeralIndex {
|
||||
cursor_id: dedupe_index.0,
|
||||
index: dedupe_index.1.clone(),
|
||||
};
|
||||
Some(dedupe_index)
|
||||
} else {
|
||||
@@ -307,9 +307,9 @@ fn emit_program_for_compound_select(
|
||||
}
|
||||
|
||||
if requires_union_deduplication {
|
||||
select.query_type = SelectQueryType::UnionArm {
|
||||
index_cursor_id: union_dedupe_index.as_ref().unwrap().0,
|
||||
dedupe_index: union_dedupe_index.as_ref().unwrap().1.clone(),
|
||||
select.query_destination = QueryDestination::EphemeralIndex {
|
||||
cursor_id: union_dedupe_index.as_ref().unwrap().0,
|
||||
index: union_dedupe_index.as_ref().unwrap().1.clone(),
|
||||
};
|
||||
} else if let Some((dedupe_cursor_id, dedupe_index)) = union_dedupe_index.take() {
|
||||
// When there are no more UNION operators left, all the deduplicated rows from the preceding union arms need to be emitted
|
||||
|
||||
@@ -30,7 +30,7 @@ use super::{
|
||||
order_by::{order_by_sorter_insert, sorter_insert},
|
||||
plan::{
|
||||
convert_where_to_vtab_constraint, Aggregate, GroupBy, IterationDirection, JoinOrderMember,
|
||||
Operation, Search, SeekDef, SelectPlan, SelectQueryType, TableReference, WhereTerm,
|
||||
Operation, QueryDestination, Search, SeekDef, SelectPlan, TableReference, WhereTerm,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -466,8 +466,8 @@ pub fn open_loop(
|
||||
}
|
||||
Table::FromClauseSubquery(from_clause_subquery) => {
|
||||
let (yield_reg, coroutine_implementation_start) =
|
||||
match &from_clause_subquery.plan.query_type {
|
||||
SelectQueryType::Subquery {
|
||||
match &from_clause_subquery.plan.query_destination {
|
||||
QueryDestination::CoroutineYield {
|
||||
yield_reg,
|
||||
coroutine_implementation_start,
|
||||
} => (*yield_reg, *coroutine_implementation_start),
|
||||
|
||||
@@ -309,22 +309,29 @@ pub enum Plan {
|
||||
Update(UpdatePlan),
|
||||
}
|
||||
|
||||
/// The type of the query, either top level or subquery
|
||||
/// The destination of the results of a query.
|
||||
/// Typically, the results of a query are returned to the caller.
|
||||
/// However, there are some cases where the results are not returned to the caller,
|
||||
/// but rather are yielded to a parent query via coroutine, or stored in a temp table,
|
||||
/// later used by the parent query.
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum SelectQueryType {
|
||||
TopLevel,
|
||||
Subquery {
|
||||
/// The register that holds the program offset that handles jumping to/from the subquery.
|
||||
pub enum QueryDestination {
|
||||
/// The results of the query are returned to the caller.
|
||||
ResultRows,
|
||||
/// The results of the query are yielded to a parent query via coroutine.
|
||||
CoroutineYield {
|
||||
/// The register that holds the program offset that handles jumping to/from the coroutine.
|
||||
yield_reg: usize,
|
||||
/// The index of the first instruction in the bytecode that implements the subquery.
|
||||
/// The index of the first instruction in the bytecode that implements the coroutine.
|
||||
coroutine_implementation_start: BranchOffset,
|
||||
},
|
||||
/// One arm of a UNION query, so its results need to be fed into a temp index for deduplication.
|
||||
UnionArm {
|
||||
/// The cursor ID of the temp index that will be used to deduplicate the results.
|
||||
index_cursor_id: CursorID,
|
||||
/// The deduplication index.
|
||||
dedupe_index: Arc<Index>,
|
||||
/// The results of the query are stored in an ephemeral index,
|
||||
/// later used by the parent query.
|
||||
EphemeralIndex {
|
||||
/// The cursor ID of the ephemeral index that will be used to store the results.
|
||||
cursor_id: CursorID,
|
||||
/// The index that will be used to store the results.
|
||||
index: Arc<Index>,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -438,8 +445,8 @@ pub struct SelectPlan {
|
||||
pub offset: Option<isize>,
|
||||
/// query contains a constant condition that is always false
|
||||
pub contains_constant_false_condition: bool,
|
||||
/// query type (top level or subquery)
|
||||
pub query_type: SelectQueryType,
|
||||
/// the destination of the resulting rows from this plan.
|
||||
pub query_destination: QueryDestination,
|
||||
/// whether the query is DISTINCT
|
||||
pub distinctness: Distinctness,
|
||||
/// values: https://sqlite.org/syntax/select-core.html
|
||||
@@ -486,7 +493,10 @@ impl SelectPlan {
|
||||
pub fn is_simple_count(&self) -> bool {
|
||||
if !self.where_clause.is_empty()
|
||||
|| self.aggregates.len() != 1
|
||||
|| matches!(self.query_type, SelectQueryType::Subquery { .. })
|
||||
|| matches!(
|
||||
self.query_destination,
|
||||
QueryDestination::CoroutineYield { .. }
|
||||
)
|
||||
|| self.table_references.len() != 1
|
||||
|| self.result_columns.len() != 1
|
||||
|| self.group_by.is_some()
|
||||
|
||||
@@ -2,7 +2,7 @@ use super::{
|
||||
expr::walk_expr,
|
||||
plan::{
|
||||
Aggregate, ColumnUsedMask, Distinctness, EvalAt, IterationDirection, JoinInfo,
|
||||
JoinOrderMember, Operation, Plan, ResultSetColumn, SelectPlan, SelectQueryType,
|
||||
JoinOrderMember, Operation, Plan, QueryDestination, ResultSetColumn, SelectPlan,
|
||||
TableReference, WhereTerm,
|
||||
},
|
||||
select::prepare_select_plan,
|
||||
@@ -298,7 +298,7 @@ fn parse_from_clause_table<'a>(
|
||||
else {
|
||||
crate::bail_parse_error!("Only non-compound SELECT queries are currently supported in FROM clause subqueries");
|
||||
};
|
||||
subplan.query_type = SelectQueryType::Subquery {
|
||||
subplan.query_destination = QueryDestination::CoroutineYield {
|
||||
yield_reg: usize::MAX, // will be set later in bytecode emission
|
||||
coroutine_implementation_start: BranchOffset::Placeholder, // will be set later in bytecode emission
|
||||
};
|
||||
@@ -455,8 +455,7 @@ pub fn parse_from<'a>(
|
||||
let Plan::Select(mut cte_plan) = cte_plan else {
|
||||
crate::bail_parse_error!("Only SELECT queries are currently supported in CTEs");
|
||||
};
|
||||
// CTE can be rewritten as a subquery.
|
||||
cte_plan.query_type = SelectQueryType::Subquery {
|
||||
cte_plan.query_destination = QueryDestination::CoroutineYield {
|
||||
yield_reg: usize::MAX, // will be set later in bytecode emission
|
||||
coroutine_implementation_start: BranchOffset::Placeholder, // will be set later in bytecode emission
|
||||
};
|
||||
|
||||
@@ -10,7 +10,7 @@ use crate::{
|
||||
use super::{
|
||||
emitter::{LimitCtx, Resolver},
|
||||
expr::translate_expr,
|
||||
plan::{Distinctness, SelectPlan, SelectQueryType},
|
||||
plan::{Distinctness, QueryDestination, SelectPlan},
|
||||
};
|
||||
|
||||
/// Emits the bytecode for:
|
||||
@@ -85,16 +85,16 @@ pub fn emit_result_row_and_limit(
|
||||
reg_limit_offset_sum: Option<usize>,
|
||||
label_on_limit_reached: Option<BranchOffset>,
|
||||
) -> Result<()> {
|
||||
match &plan.query_type {
|
||||
SelectQueryType::TopLevel => {
|
||||
match &plan.query_destination {
|
||||
QueryDestination::ResultRows => {
|
||||
program.emit_insn(Insn::ResultRow {
|
||||
start_reg: result_columns_start_reg,
|
||||
count: plan.result_columns.len(),
|
||||
});
|
||||
}
|
||||
SelectQueryType::UnionArm {
|
||||
index_cursor_id,
|
||||
dedupe_index,
|
||||
QueryDestination::EphemeralIndex {
|
||||
cursor_id: index_cursor_id,
|
||||
index: dedupe_index,
|
||||
} => {
|
||||
let record_reg = program.alloc_register();
|
||||
program.emit_insn(Insn::MakeRecord {
|
||||
@@ -111,7 +111,7 @@ pub fn emit_result_row_and_limit(
|
||||
flags: IdxInsertFlags::new(),
|
||||
});
|
||||
}
|
||||
SelectQueryType::Subquery { yield_reg, .. } => {
|
||||
QueryDestination::CoroutineYield { yield_reg, .. } => {
|
||||
program.emit_insn(Insn::Yield {
|
||||
yield_reg: *yield_reg,
|
||||
end_offset: BranchOffset::Offset(0),
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
use super::emitter::{emit_program, TranslateCtx};
|
||||
use super::plan::{select_star, Distinctness, JoinOrderMember, Operation, Search, SelectQueryType};
|
||||
use super::plan::{
|
||||
select_star, Distinctness, JoinOrderMember, Operation, QueryDestination, Search,
|
||||
};
|
||||
use super::planner::Scope;
|
||||
use crate::function::{AggFunc, ExtFunc, Func};
|
||||
use crate::schema::Table;
|
||||
@@ -235,7 +237,7 @@ fn prepare_one_select_plan<'a>(
|
||||
limit: None,
|
||||
offset: None,
|
||||
contains_constant_false_condition: false,
|
||||
query_type: SelectQueryType::TopLevel,
|
||||
query_destination: QueryDestination::ResultRows,
|
||||
distinctness: Distinctness::from_ast(distinctness.as_ref()),
|
||||
values: vec![],
|
||||
};
|
||||
@@ -549,7 +551,7 @@ fn prepare_one_select_plan<'a>(
|
||||
limit: None,
|
||||
offset: None,
|
||||
contains_constant_false_condition: false,
|
||||
query_type: SelectQueryType::TopLevel,
|
||||
query_destination: QueryDestination::ResultRows,
|
||||
distinctness: Distinctness::NonDistinct,
|
||||
values,
|
||||
};
|
||||
|
||||
@@ -7,7 +7,7 @@ use crate::{
|
||||
use super::{
|
||||
emitter::{emit_query, LimitCtx, Resolver, TranslateCtx},
|
||||
main_loop::LoopLabels,
|
||||
plan::{SelectPlan, SelectQueryType, TableReference},
|
||||
plan::{QueryDestination, SelectPlan, TableReference},
|
||||
};
|
||||
|
||||
/// Emit the subqueries contained in the FROM clause.
|
||||
@@ -51,8 +51,8 @@ pub fn emit_subquery<'a>(
|
||||
) -> Result<usize> {
|
||||
let yield_reg = program.alloc_register();
|
||||
let coroutine_implementation_start_offset = program.allocate_label();
|
||||
match &mut plan.query_type {
|
||||
SelectQueryType::Subquery {
|
||||
match &mut plan.query_destination {
|
||||
QueryDestination::CoroutineYield {
|
||||
yield_reg: y,
|
||||
coroutine_implementation_start,
|
||||
} => {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use crate::translate::emitter::Resolver;
|
||||
use crate::translate::expr::{translate_expr_no_constant_opt, NoConstantOptReason};
|
||||
use crate::translate::plan::{SelectPlan, SelectQueryType};
|
||||
use crate::translate::plan::{QueryDestination, SelectPlan};
|
||||
use crate::vdbe::builder::ProgramBuilder;
|
||||
use crate::vdbe::insn::Insn;
|
||||
use crate::vdbe::BranchOffset;
|
||||
@@ -16,12 +16,12 @@ pub fn emit_values(
|
||||
return Ok(start_reg);
|
||||
}
|
||||
|
||||
let reg_result_cols_start = match plan.query_type {
|
||||
SelectQueryType::TopLevel => emit_toplevel_values(program, plan, resolver)?,
|
||||
SelectQueryType::Subquery { yield_reg, .. } => {
|
||||
let reg_result_cols_start = match plan.query_destination {
|
||||
QueryDestination::ResultRows => emit_toplevel_values(program, plan, resolver)?,
|
||||
QueryDestination::CoroutineYield { yield_reg, .. } => {
|
||||
emit_values_in_subquery(program, plan, resolver, yield_reg)?
|
||||
}
|
||||
SelectQueryType::UnionArm { .. } => unreachable!(),
|
||||
QueryDestination::EphemeralIndex { .. } => unreachable!(),
|
||||
};
|
||||
Ok(reg_result_cols_start)
|
||||
}
|
||||
@@ -44,20 +44,20 @@ fn emit_values_when_single_row(
|
||||
NoConstantOptReason::RegisterReuse,
|
||||
)?;
|
||||
}
|
||||
match plan.query_type {
|
||||
SelectQueryType::TopLevel => {
|
||||
match plan.query_destination {
|
||||
QueryDestination::ResultRows => {
|
||||
program.emit_insn(Insn::ResultRow {
|
||||
start_reg,
|
||||
count: row_len,
|
||||
});
|
||||
}
|
||||
SelectQueryType::Subquery { yield_reg, .. } => {
|
||||
QueryDestination::CoroutineYield { yield_reg, .. } => {
|
||||
program.emit_insn(Insn::Yield {
|
||||
yield_reg,
|
||||
end_offset: BranchOffset::Offset(0),
|
||||
});
|
||||
}
|
||||
SelectQueryType::UnionArm { .. } => unreachable!(),
|
||||
QueryDestination::EphemeralIndex { .. } => unreachable!(),
|
||||
}
|
||||
Ok(start_reg)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user