diff --git a/crates/core/src/sql/compiler.rs b/crates/core/src/sql/compiler.rs index 7db86d1f7e..6c94be71c5 100644 --- a/crates/core/src/sql/compiler.rs +++ b/crates/core/src/sql/compiler.rs @@ -24,7 +24,7 @@ pub fn compile_sql(db: &RelationalDB, tx: &MutTxId, sql_text: &str) -> Result Result Result { +fn compile_statement(db: &RelationalDB, statement: SqlAst) -> Result { let q = match statement { SqlAst::Select { from, @@ -270,7 +270,7 @@ fn compile_statement(statement: SqlAst) -> Result { } => compile_drop(name, kind, table_access)?, }; - Ok(q.optimize()) + Ok(q.optimize(Some(db.address()))) } #[cfg(test)] @@ -1052,7 +1052,7 @@ mod tests { // Optimize the query plan for the incremental update. let expr = query::to_mem_table(expr, &insert); - let expr = expr.optimize(); + let expr = expr.optimize(Some(db.address())); let QueryExpr { source: diff --git a/crates/core/src/subscription/subscription.rs b/crates/core/src/subscription/subscription.rs index 75b12b8095..9f69b3a748 100644 --- a/crates/core/src/subscription/subscription.rs +++ b/crates/core/src/subscription/subscription.rs @@ -591,7 +591,7 @@ impl<'a> IncrementalJoin<'a> { let mut inserts = { // Replan query after replacing left table with virtual table, // since join order may need to be reversed. - let lhs_virt = query::to_mem_table(self.expr.clone(), &self.lhs.inserts()).optimize(); + let lhs_virt = query::to_mem_table(self.expr.clone(), &self.lhs.inserts()).optimize(Some(db.address())); let rhs_virt = self.to_mem_table_rhs(self.rhs.inserts()); // {A+ join B} @@ -617,7 +617,7 @@ impl<'a> IncrementalJoin<'a> { let mut deletes = { // Replan query after replacing left table with virtual table, // since join order may need to be reversed. - let lhs_virt = query::to_mem_table(self.expr.clone(), &self.lhs.deletes()).optimize(); + let lhs_virt = query::to_mem_table(self.expr.clone(), &self.lhs.deletes()).optimize(Some(db.address())); let rhs_virt = self.to_mem_table_rhs(self.rhs.deletes()); // {A- join B} diff --git a/crates/core/src/vm.rs b/crates/core/src/vm.rs index dd2ebc4791..8e47f7da69 100644 --- a/crates/core/src/vm.rs +++ b/crates/core/src/vm.rs @@ -3,6 +3,7 @@ use std::collections::HashMap; use std::ops::RangeBounds; use itertools::Itertools; +use spacetimedb_lib::Address; use tracing::debug; use crate::db::cursor::{CatalogCursor, IndexCursor, TableCursor}; @@ -395,6 +396,10 @@ impl<'db, 'tx> DbProgram<'db, 'tx> { } impl ProgramVm for DbProgram<'_, '_> { + fn address(&self) -> Option
{ + Some(self.db.address()) + } + fn env(&self) -> &EnvDb { &self.env } diff --git a/crates/vm/src/eval.rs b/crates/vm/src/eval.rs index 5ba873879c..b1873b21c4 100644 --- a/crates/vm/src/eval.rs +++ b/crates/vm/src/eval.rs @@ -77,7 +77,7 @@ fn build_typed(p: &mut P, node: Expr) -> ExprOpt { } } Expr::Crud(q) => { - let q = q.optimize(); + let q = q.optimize(p.address()); match q { CrudExpr::Query(q) => { let source = build_query_opt(q); diff --git a/crates/vm/src/expr.rs b/crates/vm/src/expr.rs index c1372b0180..bbe80b12cf 100644 --- a/crates/vm/src/expr.rs +++ b/crates/vm/src/expr.rs @@ -9,7 +9,7 @@ use crate::errors::{ErrorKind, ErrorLang, ErrorType, ErrorVm}; use crate::functions::{FunDef, Param}; use crate::operator::{Op, OpCmp, OpLogic, OpQuery}; use crate::types::Ty; -use spacetimedb_lib::Identity; +use spacetimedb_lib::{Address, Identity}; use spacetimedb_primitives::*; use spacetimedb_sats::algebraic_type::AlgebraicType; use spacetimedb_sats::algebraic_value::AlgebraicValue; @@ -476,9 +476,9 @@ pub enum CrudExpr { } impl CrudExpr { - pub fn optimize(self) -> Self { + pub fn optimize(self, db: Option
) -> Self { match self { - CrudExpr::Query(x) => CrudExpr::Query(x.optimize()), + CrudExpr::Query(x) => CrudExpr::Query(x.optimize(db)), _ => self, } } @@ -1129,7 +1129,7 @@ impl QueryExpr { // // Ex. SELECT Left.* FROM Left JOIN Right ON Left.id = Right.id ... // where `Left` has an index defined on `id`. - fn try_index_join(mut query: QueryExpr) -> QueryExpr { + fn try_index_join(mut query: QueryExpr, _db: Option
) -> QueryExpr { // We expect 2 and only 2 operations - a join followed by a wildcard projection. if query.query.len() != 2 { return query; @@ -1325,7 +1325,7 @@ impl QueryExpr { }) } - pub fn optimize(self) -> Self { + pub fn optimize(self, db: Option
) -> Self { let mut q = Self { source: self.source.clone(), query: Vec::with_capacity(self.query.len()), @@ -1350,11 +1350,11 @@ impl QueryExpr { Query::Select(op) => { q = Self::optimize_select(q, op, &tables); } - Query::JoinInner(join) => q = q.with_join_inner(join.rhs.optimize(), join.col_lhs, join.col_rhs), + Query::JoinInner(join) => q = q.with_join_inner(join.rhs.optimize(db), join.col_lhs, join.col_rhs), _ => q.query.push(query), }; } - Self::try_index_join(q) + Self::try_index_join(q, db) } } diff --git a/crates/vm/src/program.rs b/crates/vm/src/program.rs index c9c378a5ea..89042df197 100644 --- a/crates/vm/src/program.rs +++ b/crates/vm/src/program.rs @@ -2,6 +2,7 @@ //! //! It carries an [EnvDb] with the functions, idents, types. use spacetimedb_lib::identity::AuthCtx; +use spacetimedb_lib::Address; use spacetimedb_sats::relation::{MemTable, RelIter, Relation, Table}; use std::collections::HashMap; @@ -66,6 +67,7 @@ pub trait ProgramVm { env.functions.ops = ops } + fn address(&self) -> Option
; fn env(&self) -> &EnvDb; fn env_mut(&mut self) -> &mut EnvDb; fn ctx(&self) -> &dyn ProgramVm; @@ -151,6 +153,10 @@ impl Program { } impl ProgramVm for Program { + fn address(&self) -> Option
{ + None + } + fn env(&self) -> &EnvDb { &self.env }