Skip to content

Commit f276b25

Browse files
chore(vm): Pass database address to the compiler (#637)
The database address will be needed to optimize joins. In particular it will be used to look up table size metrics.
1 parent 09b2d0f commit f276b25

File tree

6 files changed

+25
-14
lines changed

6 files changed

+25
-14
lines changed

crates/core/src/sql/compiler.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ pub fn compile_sql(db: &RelationalDB, tx: &MutTxId, sql_text: &str) -> Result<Ve
2424
let mut results = Vec::with_capacity(ast.len());
2525

2626
for sql in ast {
27-
results.push(compile_statement(sql).map_err(|error| DBError::Plan {
27+
results.push(compile_statement(db, sql).map_err(|error| DBError::Plan {
2828
sql: sql_text.to_string(),
2929
error,
3030
})?);
@@ -248,7 +248,7 @@ fn compile_drop(name: String, kind: DbType, table_access: StAccess) -> Result<Cr
248248
}
249249

250250
/// Compiles a `SQL` clause
251-
fn compile_statement(statement: SqlAst) -> Result<CrudExpr, PlanError> {
251+
fn compile_statement(db: &RelationalDB, statement: SqlAst) -> Result<CrudExpr, PlanError> {
252252
let q = match statement {
253253
SqlAst::Select {
254254
from,
@@ -270,7 +270,7 @@ fn compile_statement(statement: SqlAst) -> Result<CrudExpr, PlanError> {
270270
} => compile_drop(name, kind, table_access)?,
271271
};
272272

273-
Ok(q.optimize())
273+
Ok(q.optimize(Some(db.address())))
274274
}
275275

276276
#[cfg(test)]
@@ -1052,7 +1052,7 @@ mod tests {
10521052

10531053
// Optimize the query plan for the incremental update.
10541054
let expr = query::to_mem_table(expr, &insert);
1055-
let expr = expr.optimize();
1055+
let expr = expr.optimize(Some(db.address()));
10561056

10571057
let QueryExpr {
10581058
source:

crates/core/src/subscription/subscription.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -591,7 +591,7 @@ impl<'a> IncrementalJoin<'a> {
591591
let mut inserts = {
592592
// Replan query after replacing left table with virtual table,
593593
// since join order may need to be reversed.
594-
let lhs_virt = query::to_mem_table(self.expr.clone(), &self.lhs.inserts()).optimize();
594+
let lhs_virt = query::to_mem_table(self.expr.clone(), &self.lhs.inserts()).optimize(Some(db.address()));
595595
let rhs_virt = self.to_mem_table_rhs(self.rhs.inserts());
596596

597597
// {A+ join B}
@@ -617,7 +617,7 @@ impl<'a> IncrementalJoin<'a> {
617617
let mut deletes = {
618618
// Replan query after replacing left table with virtual table,
619619
// since join order may need to be reversed.
620-
let lhs_virt = query::to_mem_table(self.expr.clone(), &self.lhs.deletes()).optimize();
620+
let lhs_virt = query::to_mem_table(self.expr.clone(), &self.lhs.deletes()).optimize(Some(db.address()));
621621
let rhs_virt = self.to_mem_table_rhs(self.rhs.deletes());
622622

623623
// {A- join B}

crates/core/src/vm.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use std::collections::HashMap;
33
use std::ops::RangeBounds;
44

55
use itertools::Itertools;
6+
use spacetimedb_lib::Address;
67
use tracing::debug;
78

89
use crate::db::cursor::{CatalogCursor, IndexCursor, TableCursor};
@@ -395,6 +396,10 @@ impl<'db, 'tx> DbProgram<'db, 'tx> {
395396
}
396397

397398
impl ProgramVm for DbProgram<'_, '_> {
399+
fn address(&self) -> Option<Address> {
400+
Some(self.db.address())
401+
}
402+
398403
fn env(&self) -> &EnvDb {
399404
&self.env
400405
}

crates/vm/src/eval.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ fn build_typed<P: ProgramVm>(p: &mut P, node: Expr) -> ExprOpt {
7777
}
7878
}
7979
Expr::Crud(q) => {
80-
let q = q.optimize();
80+
let q = q.optimize(p.address());
8181
match q {
8282
CrudExpr::Query(q) => {
8383
let source = build_query_opt(q);

crates/vm/src/expr.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use crate::errors::{ErrorKind, ErrorLang, ErrorType, ErrorVm};
99
use crate::functions::{FunDef, Param};
1010
use crate::operator::{Op, OpCmp, OpLogic, OpQuery};
1111
use crate::types::Ty;
12-
use spacetimedb_lib::Identity;
12+
use spacetimedb_lib::{Address, Identity};
1313
use spacetimedb_primitives::*;
1414
use spacetimedb_sats::algebraic_type::AlgebraicType;
1515
use spacetimedb_sats::algebraic_value::AlgebraicValue;
@@ -476,9 +476,9 @@ pub enum CrudExpr {
476476
}
477477

478478
impl CrudExpr {
479-
pub fn optimize(self) -> Self {
479+
pub fn optimize(self, db: Option<Address>) -> Self {
480480
match self {
481-
CrudExpr::Query(x) => CrudExpr::Query(x.optimize()),
481+
CrudExpr::Query(x) => CrudExpr::Query(x.optimize(db)),
482482
_ => self,
483483
}
484484
}
@@ -1129,7 +1129,7 @@ impl QueryExpr {
11291129
//
11301130
// Ex. SELECT Left.* FROM Left JOIN Right ON Left.id = Right.id ...
11311131
// where `Left` has an index defined on `id`.
1132-
fn try_index_join(mut query: QueryExpr) -> QueryExpr {
1132+
fn try_index_join(mut query: QueryExpr, _db: Option<Address>) -> QueryExpr {
11331133
// We expect 2 and only 2 operations - a join followed by a wildcard projection.
11341134
if query.query.len() != 2 {
11351135
return query;
@@ -1325,7 +1325,7 @@ impl QueryExpr {
13251325
})
13261326
}
13271327

1328-
pub fn optimize(self) -> Self {
1328+
pub fn optimize(self, db: Option<Address>) -> Self {
13291329
let mut q = Self {
13301330
source: self.source.clone(),
13311331
query: Vec::with_capacity(self.query.len()),
@@ -1350,11 +1350,11 @@ impl QueryExpr {
13501350
Query::Select(op) => {
13511351
q = Self::optimize_select(q, op, &tables);
13521352
}
1353-
Query::JoinInner(join) => q = q.with_join_inner(join.rhs.optimize(), join.col_lhs, join.col_rhs),
1353+
Query::JoinInner(join) => q = q.with_join_inner(join.rhs.optimize(db), join.col_lhs, join.col_rhs),
13541354
_ => q.query.push(query),
13551355
};
13561356
}
1357-
Self::try_index_join(q)
1357+
Self::try_index_join(q, db)
13581358
}
13591359
}
13601360

crates/vm/src/program.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
//!
33
//! It carries an [EnvDb] with the functions, idents, types.
44
use spacetimedb_lib::identity::AuthCtx;
5+
use spacetimedb_lib::Address;
56
use spacetimedb_sats::relation::{MemTable, RelIter, Relation, Table};
67
use std::collections::HashMap;
78

@@ -66,6 +67,7 @@ pub trait ProgramVm {
6667
env.functions.ops = ops
6768
}
6869

70+
fn address(&self) -> Option<Address>;
6971
fn env(&self) -> &EnvDb;
7072
fn env_mut(&mut self) -> &mut EnvDb;
7173
fn ctx(&self) -> &dyn ProgramVm;
@@ -151,6 +153,10 @@ impl Program {
151153
}
152154

153155
impl ProgramVm for Program {
156+
fn address(&self) -> Option<Address> {
157+
None
158+
}
159+
154160
fn env(&self) -> &EnvDb {
155161
&self.env
156162
}

0 commit comments

Comments
 (0)