More flexible Emitter via stateful operators

This commit is contained in:
jussisaurio
2024-08-17 12:55:16 +03:00
parent d70eb6b3d7
commit e8c894e532
6 changed files with 572 additions and 525 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -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,
}
}

View File

@@ -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)

View File

@@ -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,

View File

@@ -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);
}

View File

@@ -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>> {