Skip to content

Commit

Permalink
Fixes for performance drop related to missing index selection (#647)
Browse files Browse the repository at this point in the history
* Fix test bootstrap

Merge

Merge

* Fix test & refactor FieldDef

* Added test to check schema validations
  • Loading branch information
mamcx authored Dec 8, 2023
1 parent 683a803 commit 6d7c513
Show file tree
Hide file tree
Showing 8 changed files with 590 additions and 142 deletions.
27 changes: 15 additions & 12 deletions crates/core/src/db/datastore/locking_tx_datastore/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ use spacetimedb_lib::{metrics::METRICS, Address};
use spacetimedb_primitives::*;
use spacetimedb_sats::data_key::{DataKey, ToDataKey};
use spacetimedb_sats::db::def::*;
use spacetimedb_sats::db::error::SchemaErrors;
use spacetimedb_sats::hash::Hash;
use spacetimedb_sats::relation::RelValue;
use spacetimedb_sats::{
Expand Down Expand Up @@ -499,7 +500,7 @@ impl CommittedState {
let mut constraints = Vec::new();
for data_ref in self.iter_by_col_eq(
&ST_CONSTRAINTS_ID,
&NonEmpty::new(StIndexFields::TableId.col_id()),
&NonEmpty::new(StConstraintFields::TableId.col_id()),
&table_id.into(),
)? {
let row = data_ref.view();
Expand Down Expand Up @@ -993,7 +994,11 @@ impl MutTxId {
return Err(TableError::System(table_schema.table_name.clone()).into());
}

table_schema.clone().into_schema(0.into()).validated()?;
table_schema
.clone()
.into_schema(0.into())
.validated()
.map_err(|err| DBError::Schema(SchemaErrors(err)))?;

Ok(())
}
Expand Down Expand Up @@ -1137,7 +1142,7 @@ impl MutTxId {

// Look up the constraints for the table in question.
let mut constraints = Vec::new();
for data_ref in self.iter_by_col_eq(&ctx, &ST_CONSTRAINTS_ID, StIndexFields::TableId, table_id.into())? {
for data_ref in self.iter_by_col_eq(&ctx, &ST_CONSTRAINTS_ID, StConstraintFields::TableId, table_id.into())? {
let row = data_ref.view();

let el = StConstraintRow::try_from(row)?;
Expand Down Expand Up @@ -2973,7 +2978,6 @@ mod tests {
},
])
.with_column_sequence(ColId(0))
.unwrap()
}

#[rustfmt::skip]
Expand All @@ -2986,10 +2990,9 @@ mod tests {
IdxSchema { id: 6, table: 6, col: 0, name: "id_idx", unique: true },
IdxSchema { id: 7, table: 6, col: 1, name: "name_idx", unique: true },
]),

map_array([
ConstraintRow { constraint_id: 6, table_id: 6, columns: col(0), constraints: Constraints::indexed(), constraint_name: "ct_Foo_id_idx_indexed" },
ConstraintRow { constraint_id: 7, table_id: 6, columns: col(1), constraints: Constraints::indexed(), constraint_name: "ct_Foo_name_idx_indexed" }
ConstraintRow { constraint_id: 6, table_id: 6, columns: col(0), constraints: Constraints::unique(), constraint_name: "ct_Foo_id_idx_unique" },
ConstraintRow { constraint_id: 7, table_id: 6, columns: col(1), constraints: Constraints::unique(), constraint_name: "ct_Foo_name_idx_unique" }
]),
map_array([
SequenceRow { id: 4, table: 6, col_pos: 0, name: "seq_Foo_id", start: 1 }
Expand Down Expand Up @@ -3073,7 +3076,7 @@ mod tests {
assert_eq!(query.scan_st_indexes()?, map_array([
IndexRow { id: 0, table: 0, col: col(0), name: "idx_st_table_table_id_primary_key_auto_unique", unique: true },
IndexRow { id: 1, table: 0, col: col(1), name: "idx_st_table_table_name_unique", unique: true },
IndexRow { id: 2, table: 1, col: cols(0, vec![1]), name: "idx_st_columns_table_id_col_pos_unique_unique", unique: true },
IndexRow { id: 2, table: 1, col: cols(0, vec![1]), name: "idx_st_columns_table_id_col_pos_unique", unique: true },
IndexRow { id: 3, table: 2, col: col(0), name: "idx_st_sequence_sequence_id_primary_key_auto_unique", unique: true },
IndexRow { id: 4, table: 3, col: col(0), name: "idx_st_indexes_index_id_primary_key_auto_unique", unique: true },
IndexRow { id: 5, table: 4, col: col(0), name: "idx_st_constraints_constraint_id_primary_key_auto_unique", unique: true },
Expand All @@ -3088,7 +3091,7 @@ mod tests {
#[rustfmt::skip]
assert_eq!(query.scan_st_constraints()?, map_array([
ConstraintRow { constraint_id: 0, table_id: 0, columns: col(0), constraints: Constraints::primary_key_auto(), constraint_name: "ct_st_table_table_id_primary_key_auto" },
ConstraintRow { constraint_id: 1, table_id: 0, columns: col(1), constraints: Constraints::indexed(), constraint_name: "ct_st_table_table_name_unique_indexed" },
ConstraintRow { constraint_id: 1, table_id: 0, columns: col(1), constraints: Constraints::unique(), constraint_name: "ct_st_table_table_name_unique" },
ConstraintRow { constraint_id: 2, table_id: 1, columns: cols(0, vec![1]), constraints: Constraints::unique(), constraint_name: "ct_st_columns_table_id_col_pos_unique" },
ConstraintRow { constraint_id: 3, table_id: 2, columns: col(0), constraints: Constraints::primary_key_auto(), constraint_name: "ct_st_sequence_sequence_id_primary_key_auto" },
ConstraintRow { constraint_id: 4, table_id: 3, columns: col(0), constraints: Constraints::primary_key_auto(), constraint_name: "ct_st_indexes_index_id_primary_key_auto" },
Expand Down Expand Up @@ -3394,7 +3397,7 @@ mod tests {
assert_eq!(index_rows, [
IndexRow { id: 0, table: 0, col: col(0), name: "idx_st_table_table_id_primary_key_auto_unique", unique: true },
IndexRow { id: 1, table: 0, col: col(1), name: "idx_st_table_table_name_unique", unique: true },
IndexRow { id: 2, table: 1, col: cols(0, vec![1]), name: "idx_st_columns_table_id_col_pos_unique_unique", unique: true },
IndexRow { id: 2, table: 1, col: cols(0, vec![1]), name: "idx_st_columns_table_id_col_pos_unique", unique: true },
IndexRow { id: 3, table: 2, col: col(0), name: "idx_st_sequence_sequence_id_primary_key_auto_unique", unique: true },
IndexRow { id: 4, table: 3, col: col(0), name: "idx_st_indexes_index_id_primary_key_auto_unique", unique: true },
IndexRow { id: 5, table: 4, col: col(0), name: "idx_st_constraints_constraint_id_primary_key_auto_unique", unique: true },
Expand Down Expand Up @@ -3437,7 +3440,7 @@ mod tests {
assert_eq!(index_rows, [
IndexRow { id: 0, table: 0, col: col(0), name: "idx_st_table_table_id_primary_key_auto_unique", unique: true },
IndexRow { id: 1, table: 0, col: col(1), name: "idx_st_table_table_name_unique", unique: true },
IndexRow { id: 2, table: 1, col: cols(0, vec![1]), name: "idx_st_columns_table_id_col_pos_unique_unique", unique: true },
IndexRow { id: 2, table: 1, col: cols(0, vec![1]), name: "idx_st_columns_table_id_col_pos_unique", unique: true },
IndexRow { id: 3, table: 2, col: col(0), name: "idx_st_sequence_sequence_id_primary_key_auto_unique", unique: true },
IndexRow { id: 4, table: 3, col: col(0), name: "idx_st_indexes_index_id_primary_key_auto_unique", unique: true },
IndexRow { id: 5, table: 4, col: col(0), name: "idx_st_constraints_constraint_id_primary_key_auto_unique", unique: true },
Expand Down Expand Up @@ -3480,7 +3483,7 @@ mod tests {
assert_eq!(index_rows, [
IndexRow { id: 0, table: 0, col: col(0), name: "idx_st_table_table_id_primary_key_auto_unique", unique: true },
IndexRow { id: 1, table: 0, col: col(1), name: "idx_st_table_table_name_unique", unique: true },
IndexRow { id: 2, table: 1, col: cols(0, vec![1]), name: "idx_st_columns_table_id_col_pos_unique_unique", unique: true },
IndexRow { id: 2, table: 1, col: cols(0, vec![1]), name: "idx_st_columns_table_id_col_pos_unique", unique: true },
IndexRow { id: 3, table: 2, col: col(0), name: "idx_st_sequence_sequence_id_primary_key_auto_unique", unique: true },
IndexRow { id: 4, table: 3, col: col(0), name: "idx_st_indexes_index_id_primary_key_auto_unique", unique: true },
IndexRow { id: 5, table: 4, col: col(0), name: "idx_st_constraints_constraint_id_primary_key_auto_unique", unique: true },
Expand Down
6 changes: 0 additions & 6 deletions crates/core/src/db/datastore/system_tables.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,9 +164,7 @@ pub fn st_table_schema() -> TableSchema {
)
.with_type(StTableType::System)
.with_column_constraint(Constraints::primary_key_auto(), StTableFields::TableId.col_id())
.unwrap()
.with_column_index(StTableFields::TableName.col_id(), true)
.unwrap()
.into_schema(ST_TABLES_ID)
}

Expand All @@ -190,7 +188,6 @@ pub fn st_columns_schema() -> TableSchema {
Constraints::unique(),
(StColumnFields::TableId.col_id(), vec![StColumnFields::ColPos.col_id()]),
)
.unwrap()
.into_schema(ST_COLUMNS_ID)
}

Expand All @@ -214,7 +211,6 @@ pub fn st_indexes_schema() -> TableSchema {
.with_type(StTableType::System)
// TODO: Unique constraint on index name?
.with_column_constraint(Constraints::primary_key_auto(), StIndexFields::IndexId.col_id())
.unwrap()
.into_schema(ST_INDEXES_ID)
}

Expand All @@ -241,7 +237,6 @@ pub(crate) fn st_sequences_schema() -> TableSchema {
.with_type(StTableType::System)
// TODO: Unique constraint on sequence name?
.with_column_constraint(Constraints::primary_key_auto(), StSequenceFields::SequenceId.col_id())
.unwrap()
.into_schema(ST_SEQUENCES_ID)
}

Expand Down Expand Up @@ -269,7 +264,6 @@ pub(crate) fn st_constraints_schema() -> TableSchema {
Constraints::primary_key_auto(),
StConstraintFields::ConstraintId.col_id(),
)
.unwrap()
.into_schema(ST_CONSTRAINTS_ID)
}

Expand Down
7 changes: 2 additions & 5 deletions crates/core/src/db/relational_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -946,7 +946,6 @@ mod tests {
}],
)
.with_column_constraint(Constraints::primary_key_auto(), ColId(0))
.unwrap()
}

#[test]
Expand Down Expand Up @@ -1039,8 +1038,7 @@ mod tests {
col_type: AlgebraicType::I64,
}],
)
.with_column_sequence(ColId(0))
.unwrap();
.with_column_sequence(ColId(0));

let table_id = stdb.create_table(&mut tx, schema)?;

Expand Down Expand Up @@ -1174,8 +1172,7 @@ mod tests {
is_unique: true,
index_type: IndexType::BTree,
}])
.with_column_constraint(Constraints::identity(), ColId(0))
.unwrap();
.with_column_constraint(Constraints::identity(), ColId(0));

let table_id = stdb.create_table(&mut tx, schema)?;

Expand Down
5 changes: 1 addition & 4 deletions crates/core/src/db/update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,6 @@ mod tests {
],
)
.with_column_constraint(Constraints::identity(), ColId(0))
.unwrap()
.with_indexes(vec![IndexDef::btree(
"Person_id_unique".into(),
(ColId(0), vec![ColId(1)]),
Expand All @@ -346,7 +345,6 @@ mod tests {
],
)
.with_column_constraint(Constraints::identity(), ColId(0))
.unwrap()
.with_indexes(vec![IndexDef::btree(
"Person_id_and_name".into(),
(ColId(0), vec![ColId(1)]),
Expand Down Expand Up @@ -401,8 +399,7 @@ mod tests {
},
],
)
.with_column_constraint(Constraints::identity(), ColId(0))
.unwrap()];
.with_column_constraint(Constraints::identity(), ColId(0))];

match schema_updates(current, proposed)? {
SchemaUpdates::Tainted(tainted) => {
Expand Down
4 changes: 2 additions & 2 deletions crates/core/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use spacetimedb_lib::buffer::DecodeError;
use spacetimedb_lib::{PrimaryKey, ProductValue};
use spacetimedb_primitives::*;
use spacetimedb_sats::db::def::IndexDef;
use spacetimedb_sats::db::error::{LibError, RelationError, SchemaError};
use spacetimedb_sats::db::error::{LibError, RelationError, SchemaErrors};
use spacetimedb_sats::hash::Hash;
use spacetimedb_sats::product_value::InvalidFieldError;
use spacetimedb_sats::relation::FieldName;
Expand Down Expand Up @@ -146,7 +146,7 @@ pub enum DBError {
#[error("IndexError: {0}")]
Index(#[from] IndexError),
#[error("SchemaError: {0}")]
Schema(#[from] SchemaError),
Schema(SchemaErrors),
#[error("IOError: {0}.")]
IoError(#[from] std::io::Error),
#[error("ParseIntError: {0}.")]
Expand Down
8 changes: 4 additions & 4 deletions crates/core/src/sql/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,14 +175,14 @@ impl From {

/// Returns all the fields matching `f` as a `Vec<FromField>`,
/// including the ones inside the joins.
pub fn find_field(&self, f: &str) -> Result<Vec<FieldDef>, RelationError> {
pub fn find_field<'a>(&'a self, f: &'a str) -> Result<Vec<FieldDef>, RelationError> {
let field = extract_table_field(f)?;
let fields = self.iter_tables().flat_map(|t| {
t.columns().iter().filter_map(|column| {
if column.col_name == field.field {
Some(FieldDef {
column: column.clone(),
table_name: field.table.unwrap_or(&t.table_name).to_string(),
column,
table_name: field.table.unwrap_or(&t.table_name),
})
} else {
None
Expand All @@ -195,7 +195,7 @@ impl From {

/// Checks if the field `named` matches exactly once in all the tables
/// including the ones inside the joins
pub fn resolve_field(&self, named: &str) -> Result<FieldDef, PlanError> {
pub fn resolve_field<'a>(&'a self, named: &'a str) -> Result<FieldDef, PlanError> {
let fields = self.find_field(named)?;

match fields.len() {
Expand Down
Loading

0 comments on commit 6d7c513

Please sign in to comment.