Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 17 additions & 6 deletions crates/execution/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
use anyhow::Result;
use core::hash::{Hash, Hasher};
use core::ops::RangeBounds;
use spacetimedb_lib::{hash_sender_view_args, identity::AuthCtx, query::Delta, AlgebraicType, Identity};
use spacetimedb_lib::{
hash_empty_view_args, hash_sender_view_args, identity::AuthCtx, query::Delta, AlgebraicType, Identity,
};
use spacetimedb_physical_plan::plan::{
ParamResolver, ParamSlot, ProjectField, TupleField, PARAM_SENDER, PARAM_VIEW_ARG_HASH,
ParamResolver, ParamSlot, ProjectField, TupleField, PARAM_SENDER, PARAM_VIEW_ARG_HASH_EMPTY,
PARAM_VIEW_ARG_HASH_SENDER,
};
use spacetimedb_primitives::{ColList, IndexId, TableId};
use spacetimedb_sats::bsatn::{BufReservedFill, EncodeError, ToBsatn};
Expand All @@ -18,14 +21,16 @@ pub mod pipelined;
#[derive(Debug, Clone, Copy)]
pub struct ExecutionParams {
sender: Identity,
view_arg_hash: u256,
empty_view_arg_hash: u256,
sender_view_arg_hash: u256,
}

impl ExecutionParams {
pub fn from_sender(sender: Identity) -> Self {
Self {
sender,
view_arg_hash: hash_sender_view_args(sender).to_u256(),
empty_view_arg_hash: hash_empty_view_args().to_u256(),
sender_view_arg_hash: hash_sender_view_args(sender).to_u256(),
}
}

Expand All @@ -40,8 +45,14 @@ impl ParamResolver for ExecutionParams {
PARAM_SENDER if ty.is_identity() => self.sender.into(),
PARAM_SENDER if ty.is_bytes() => AlgebraicValue::Bytes(self.sender.to_be_byte_array().into()),
PARAM_SENDER => panic!("unsupported type for :sender: {ty:?}"),
PARAM_VIEW_ARG_HASH if matches!(ty, AlgebraicType::U256) => AlgebraicValue::U256(self.view_arg_hash.into()),
PARAM_VIEW_ARG_HASH => panic!("unsupported type for view arg hash: {ty:?}"),
PARAM_VIEW_ARG_HASH_EMPTY if matches!(ty, AlgebraicType::U256) => {
AlgebraicValue::U256(self.empty_view_arg_hash.into())
}
PARAM_VIEW_ARG_HASH_EMPTY => panic!("unsupported type for empty view arg hash: {ty:?}"),
PARAM_VIEW_ARG_HASH_SENDER if matches!(ty, AlgebraicType::U256) => {
AlgebraicValue::U256(self.sender_view_arg_hash.into())
}
PARAM_VIEW_ARG_HASH_SENDER => panic!("unsupported type for sender view arg hash: {ty:?}"),
ParamSlot(slot) => panic!("unknown physical plan parameter slot: {slot}"),
}
}
Expand Down
21 changes: 11 additions & 10 deletions crates/physical-plan/src/plan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@ use spacetimedb_expr::{
expr::{AggType, CollectViews},
StatementSource,
};
use spacetimedb_lib::{
empty_view_arg_hash_value, query::Delta, sats::size_of::SizeOf, AlgebraicType, AlgebraicValue, ProductValue,
};
use spacetimedb_lib::{query::Delta, sats::size_of::SizeOf, AlgebraicType, AlgebraicValue, ProductValue};
use spacetimedb_primitives::{ColId, ColOrCols, ColSet, IndexId, TableId, ViewId};
use spacetimedb_schema::schema::{IndexSchema, TableSchema, VIEW_ARG_HASH_COL};
use spacetimedb_sql_parser::ast::{BinOp, LogOp};
Expand Down Expand Up @@ -42,7 +40,8 @@ pub trait ParamResolver {
pub struct ParamSlot(pub u16);

pub const PARAM_SENDER: ParamSlot = ParamSlot(0);
pub const PARAM_VIEW_ARG_HASH: ParamSlot = ParamSlot(1);
pub const PARAM_VIEW_ARG_HASH_EMPTY: ParamSlot = ParamSlot(1);
pub const PARAM_VIEW_ARG_HASH_SENDER: ParamSlot = ParamSlot(2);

/// Physical plans always terminate with a projection.
/// This type of projection returns row ids.
Expand Down Expand Up @@ -553,9 +552,10 @@ impl PhysicalPlan {
/// If a view has private arguments, its backing table has an `arg_hash` column.
/// This column tracks which rows belong to which argument tuple.
///
/// As a result, queries over such views cannot read the entire backing table.
/// They must only select the rows corresponding to the caller of the query.
/// Hence we must add an implicit selection over these types of views.
/// As a result, queries over views cannot read the entire backing table.
/// They must only select the rows corresponding to the view arguments used
/// by each view reference. Hence we must add an implicit selection over
/// these types of views.
///
/// Ex.
/// ```sql
Expand All @@ -569,11 +569,12 @@ impl PhysicalPlan {
fn expand_views(self) -> Self {
match self {
Self::TableScan(scan, label) if scan.schema.is_view() => {
let arg_hash = if scan.schema.is_anonymous_view() {
PhysicalExpr::Value(empty_view_arg_hash_value())
let param = if scan.schema.is_anonymous_view() {
PARAM_VIEW_ARG_HASH_EMPTY
} else {
PhysicalExpr::Param(PARAM_VIEW_ARG_HASH, AlgebraicType::U256)
PARAM_VIEW_ARG_HASH_SENDER
};
let arg_hash = PhysicalExpr::Param(param, AlgebraicType::U256);
Self::Filter(
Box::new(Self::TableScan(scan, label)),
PhysicalExpr::BinOp(
Expand Down
Loading