mirror of
https://github.com/aljazceru/turso.git
synced 2026-02-23 08:55:40 +01:00
More flexible Emitter via stateful operators
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -37,6 +37,7 @@ fn use_indexes(
|
||||
predicates: filter,
|
||||
table_identifier,
|
||||
id,
|
||||
..
|
||||
} => {
|
||||
if filter.is_none() {
|
||||
return Ok(());
|
||||
@@ -75,6 +76,7 @@ fn use_indexes(
|
||||
rowid_predicate,
|
||||
predicates: predicates_owned,
|
||||
id: *id,
|
||||
step: 0,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,10 @@ impl Display for Plan {
|
||||
Order
|
||||
Project
|
||||
Scan
|
||||
|
||||
Operators also have a unique ID, which is used to identify them in the query plan and attach metadata.
|
||||
They also have a step counter, which is used to track the current step in the operator's execution.
|
||||
TODO: perhaps 'step' shouldn't be in this struct, since it's an execution time concept, not a plan time concept.
|
||||
*/
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum Operator {
|
||||
@@ -38,6 +42,7 @@ pub enum Operator {
|
||||
id: usize,
|
||||
source: Box<Operator>,
|
||||
aggregates: Vec<Aggregate>,
|
||||
step: usize,
|
||||
},
|
||||
// Filter operator
|
||||
// This operator is used to filter rows from the source operator.
|
||||
@@ -62,6 +67,7 @@ pub enum Operator {
|
||||
table_identifier: String,
|
||||
rowid_predicate: ast::Expr,
|
||||
predicates: Option<Vec<ast::Expr>>,
|
||||
step: usize,
|
||||
},
|
||||
// Limit operator
|
||||
// This operator is used to limit the number of rows returned by the source operator.
|
||||
@@ -69,6 +75,7 @@ pub enum Operator {
|
||||
id: usize,
|
||||
source: Box<Operator>,
|
||||
limit: usize,
|
||||
step: usize,
|
||||
},
|
||||
// Join operator
|
||||
// This operator is used to join two source operators.
|
||||
@@ -80,6 +87,7 @@ pub enum Operator {
|
||||
right: Box<Operator>,
|
||||
predicates: Option<Vec<ast::Expr>>,
|
||||
outer: bool,
|
||||
step: usize,
|
||||
},
|
||||
// Order operator
|
||||
// This operator is used to sort the rows returned by the source operator.
|
||||
@@ -87,6 +95,7 @@ pub enum Operator {
|
||||
id: usize,
|
||||
source: Box<Operator>,
|
||||
key: Vec<(ast::Expr, Direction)>,
|
||||
step: usize,
|
||||
},
|
||||
// Projection operator
|
||||
// This operator is used to project columns from the source operator.
|
||||
@@ -98,6 +107,7 @@ pub enum Operator {
|
||||
id: usize,
|
||||
source: Box<Operator>,
|
||||
expressions: Vec<ProjectionColumn>,
|
||||
step: usize,
|
||||
},
|
||||
// Scan operator
|
||||
// This operator is used to scan a table.
|
||||
@@ -109,6 +119,7 @@ pub enum Operator {
|
||||
table: Rc<BTreeTable>,
|
||||
table_identifier: String,
|
||||
predicates: Option<Vec<ast::Expr>>,
|
||||
step: usize,
|
||||
},
|
||||
// Nothing operator
|
||||
// This operator is used to represent an empty query.
|
||||
@@ -484,7 +495,7 @@ pub fn get_table_ref_bitmask_for_ast_expr<'a>(
|
||||
let matching_table = tables
|
||||
.iter()
|
||||
.enumerate()
|
||||
.find(|(_, (table, t_id))| *t_id == tbl);
|
||||
.find(|(_, (_, t_id))| *t_id == tbl);
|
||||
|
||||
if matching_table.is_none() {
|
||||
crate::bail_parse_error!("introspect: table not found: {}", &tbl)
|
||||
|
||||
@@ -156,12 +156,14 @@ pub fn prepare_select_plan<'a>(schema: &Schema, select: ast::Select) -> Result<P
|
||||
source: Box::new(operator),
|
||||
aggregates: aggregate_expressions,
|
||||
id: operator_id_counter.get_next_id(),
|
||||
step: 0,
|
||||
}
|
||||
} else if !scalar_expressions.is_empty() {
|
||||
operator = Operator::Projection {
|
||||
source: Box::new(operator),
|
||||
expressions: scalar_expressions,
|
||||
id: operator_id_counter.get_next_id(),
|
||||
step: 0,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -200,6 +202,7 @@ pub fn prepare_select_plan<'a>(schema: &Schema, select: ast::Select) -> Result<P
|
||||
source: Box::new(operator),
|
||||
key,
|
||||
id: operator_id_counter.get_next_id(),
|
||||
step: 0,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -215,6 +218,7 @@ pub fn prepare_select_plan<'a>(schema: &Schema, select: ast::Select) -> Result<P
|
||||
source: Box::new(operator),
|
||||
limit: l,
|
||||
id: operator_id_counter.get_next_id(),
|
||||
step: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -265,6 +269,7 @@ fn parse_from(
|
||||
predicates: None,
|
||||
table_identifier: first_table.1.clone(),
|
||||
id: operator_id_counter.get_next_id(),
|
||||
step: 0,
|
||||
};
|
||||
|
||||
let mut tables = vec![first_table];
|
||||
@@ -278,6 +283,7 @@ fn parse_from(
|
||||
predicates,
|
||||
outer,
|
||||
id: operator_id_counter.get_next_id(),
|
||||
step: 0,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -343,6 +349,7 @@ fn parse_join(
|
||||
predicates: None,
|
||||
table_identifier: table.1.clone(),
|
||||
id: operator_id_counter.get_next_id(),
|
||||
step: 0,
|
||||
},
|
||||
outer,
|
||||
predicates,
|
||||
|
||||
@@ -70,18 +70,7 @@ impl ProgramBuilder {
|
||||
cursor
|
||||
}
|
||||
|
||||
pub fn has_cursor_emitted_seekrowid(&self, cursor_id: CursorID) -> bool {
|
||||
(self.seekrowid_emitted_bitmask & (1 << cursor_id)) != 0
|
||||
}
|
||||
|
||||
fn set_cursor_emitted_seekrowid(&mut self, cursor_id: CursorID) {
|
||||
self.seekrowid_emitted_bitmask |= 1 << cursor_id;
|
||||
}
|
||||
|
||||
fn _emit_insn(&mut self, insn: Insn) {
|
||||
if let Insn::SeekRowid { cursor_id, .. } = insn {
|
||||
self.set_cursor_emitted_seekrowid(cursor_id);
|
||||
}
|
||||
self.insns.push(insn);
|
||||
}
|
||||
|
||||
|
||||
@@ -106,7 +106,7 @@ impl Cursor for Sorter {
|
||||
}
|
||||
|
||||
fn get_null_flag(&self) -> bool {
|
||||
todo!();
|
||||
false
|
||||
}
|
||||
|
||||
fn exists(&mut self, key: &OwnedValue) -> Result<CursorResult<bool>> {
|
||||
|
||||
Reference in New Issue
Block a user