Skip to content

Commit eb105ad

Browse files
gefjonCentrilShubham8287
authored
Sort columns in st_column_changed before automigrating. (#3203)
# Description of Changes In `st_column_changed`, `iter_st_column_for_table` returns rows in physical storage order. In simple cases (without unrelated deletes) this will be the same as insertion order, and therefore also the same as sorted order, but in cases with multiple column-changing automigrations the physical storage order of the rows diverges from the correct sorted order. Because this isn't a hot path, we can just call `.sort()` and not worry about it. # API and ABI breaking changes N/a # Expected complexity level and risk 1 # Testing None yet. Needs manual testing with BitCraft update. --------- Signed-off-by: Mazdak Farrokhzad <[email protected]> Co-authored-by: Mazdak Farrokhzad <[email protected]> Co-authored-by: Shubham Mishra <[email protected]>
1 parent 833f750 commit eb105ad

File tree

1 file changed

+10
-2
lines changed

1 file changed

+10
-2
lines changed

crates/datastore/src/locking_tx_datastore/committed_state.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,10 @@ use spacetimedb_lib::{
3232
use spacetimedb_primitives::{ColId, ColList, ColSet, IndexId, TableId};
3333
use spacetimedb_sats::{algebraic_value::de::ValueDeserializer, memory_usage::MemoryUsage, Deserialize};
3434
use spacetimedb_sats::{AlgebraicValue, ProductValue};
35-
use spacetimedb_schema::{def::IndexAlgorithm, schema::TableSchema};
35+
use spacetimedb_schema::{
36+
def::IndexAlgorithm,
37+
schema::{ColumnSchema, TableSchema},
38+
};
3639
use spacetimedb_table::{
3740
blob_store::{BlobStore, HashMapBlobStore},
3841
indexes::{RowPointer, SquashedOffset},
@@ -386,14 +389,19 @@ impl CommittedState {
386389
// we may end up with two definitions for the same `col_pos`.
387390
// Of those two, we're interested in the one we just inserted
388391
// and not the other one, as it is being replaced.
389-
let columns = iter_st_column_for_table(self, &target_table_id.into())?
392+
let mut columns = iter_st_column_for_table(self, &target_table_id.into())?
390393
.filter_map(|row_ref| {
391394
StColumnRow::try_from(row_ref)
392395
.map(|c| (c.col_pos != target_col_id || row_ref.pointer() == row_ptr).then(|| c.into()))
393396
.transpose()
394397
})
395398
.collect::<Result<Vec<_>>>()?;
396399

400+
// Columns in `st_column` are not in general sorted by their `col_pos`,
401+
// though they will happen to be for tables which have never undergone migrations
402+
// because their initial insertion order matches their `col_pos` order.
403+
columns.sort_by_key(|col: &ColumnSchema| col.col_pos);
404+
397405
// Update the columns and layout of the the in-memory table.
398406
if let Some(table) = self.tables.get_mut(&target_table_id) {
399407
table.change_columns_to(columns).map_err(TableError::from)?;

0 commit comments

Comments
 (0)