Skip to content

Commit 0a46cf5

Browse files
authored
alter_table_row_type: write changes to st_column (#3196)
# Description of Changes `fn alter_table_row_type` now writes the new row type to `st_column`. This is not a fix for the adding-variants problem, but it does get us closer. # API and ABI breaking changes None # Expected complexity level and risk 2, system tables stuff is always risky. # Testing `test_alter_table_row_type_is_transactional` is amended with assertions.
1 parent d850559 commit 0a46cf5

File tree

3 files changed

+44
-13
lines changed

3 files changed

+44
-13
lines changed

crates/datastore/src/locking_tx_datastore/datastore.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3284,7 +3284,13 @@ mod tests {
32843284
AlgebraicType::sum([("ba", AlgebraicType::U16), ("bb", AlgebraicType::U8)])
32853285
]
32863286
);
3287-
commit(&datastore, tx)?;
3287+
let tx_data = commit(&datastore, tx)?;
3288+
// Ensure the change has been persisted in the commitlog.
3289+
let to_product = |col: &ColumnSchema| value_serialize(&StColumnRow::from(col.clone())).into_product().unwrap();
3290+
let (_, inserts) = tx_data.inserts().find(|(id, _)| **id == ST_COLUMN_ID).unwrap();
3291+
assert_eq!(&**inserts, [to_product(&columns[1])].as_slice());
3292+
let (_, deletes) = tx_data.deletes().find(|(id, _)| **id == ST_COLUMN_ID).unwrap();
3293+
assert_eq!(&**deletes, [to_product(&columns_original[1])].as_slice());
32883294

32893295
// Check that we can successfully scan using the new schema type post commit.
32903296
let tx = begin_tx(&datastore);

crates/datastore/src/locking_tx_datastore/mut_tx.rs

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -216,16 +216,8 @@ impl MutTxId {
216216

217217
// Generate the full definition of the table, with the generated indexes, constraints, sequences...
218218

219-
// Insert the columns into `st_columns`
220-
for col in table_schema.columns() {
221-
let row = StColumnRow {
222-
table_id: col.table_id,
223-
col_pos: col.col_pos,
224-
col_name: col.col_name.clone(),
225-
col_type: col.col_type.clone().into(),
226-
};
227-
self.insert_via_serialize_bsatn(ST_COLUMN_ID, &row)?;
228-
}
219+
// Insert the columns into `st_column`.
220+
self.insert_st_column(table_schema.columns())?;
229221

230222
let schedule = table_schema.schedule.clone();
231223
let mut schema_internal = table_schema;
@@ -279,6 +271,15 @@ impl MutTxId {
279271
Ok(table_id)
280272
}
281273

274+
/// Insert `columns` into `st_column`.
275+
fn insert_st_column(&mut self, columns: &[ColumnSchema]) -> Result<()> {
276+
columns.iter().try_for_each(|col| {
277+
let row: StColumnRow = col.clone().into();
278+
self.insert_via_serialize_bsatn(ST_COLUMN_ID, &row)?;
279+
Ok(())
280+
})
281+
}
282+
282283
fn create_table_internal(&mut self, schema: Arc<TableSchema>) {
283284
// Construct the in memory tables.
284285
let table_id = schema.table_id;
@@ -319,6 +320,11 @@ impl MutTxId {
319320
Ok(RowTypeForTable::Arc(self.schema_for_table(table_id)?))
320321
}
321322

323+
/// Drops all the columns of `table_id` in `st_column`.
324+
fn drop_st_column(&mut self, table_id: TableId) -> Result<()> {
325+
self.delete_col_eq(ST_COLUMN_ID, StColumnFields::TableId.col_id(), &table_id.into())
326+
}
327+
322328
pub fn drop_table(&mut self, table_id: TableId) -> Result<()> {
323329
let schema = &*self.schema_for_table(table_id)?;
324330

@@ -336,7 +342,7 @@ impl MutTxId {
336342

337343
// Drop the table and their columns
338344
self.delete_col_eq(ST_TABLE_ID, StTableFields::TableId.col_id(), &table_id.into())?;
339-
self.delete_col_eq(ST_COLUMN_ID, StColumnFields::TableId.col_id(), &table_id.into())?;
345+
self.drop_st_column(table_id)?;
340346

341347
if let Some(schedule) = &schema.schedule {
342348
self.delete_col_eq(
@@ -464,11 +470,19 @@ impl MutTxId {
464470
column_schemas.iter_mut().for_each(|c| c.table_id = table_id);
465471

466472
// Try to change the tables into what we want.
467-
let old_column_schemas = tx_table.change_columns_to(column_schemas).map_err(TableError::from)?;
473+
let old_column_schemas = tx_table
474+
.change_columns_to(column_schemas.clone())
475+
.map_err(TableError::from)?;
468476
// SAFETY: `commit_table` should have a schema identical to that of `tx_table`
469477
// prior to changing it just now.
470478
unsafe { commit_table.set_layout_and_schema_to(tx_table) };
471479

480+
// Update system tables.
481+
// We'll simply remove all rows in `st_columns` and then add the new ones.
482+
// The datastore takes care of not persisting any no-op delete/inserts to the commitlog.
483+
self.drop_st_column(table_id)?;
484+
self.insert_st_column(&column_schemas)?;
485+
472486
// Remember the pending change so we can undo if necessary.
473487
self.push_schema_change(PendingSchemaChange::TableAlterRowType(table_id, old_column_schemas));
474488

crates/datastore/src/system_tables.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -568,6 +568,17 @@ impl From<StColumnRow> for ColumnSchema {
568568
}
569569
}
570570

571+
impl From<ColumnSchema> for StColumnRow {
572+
fn from(column: ColumnSchema) -> Self {
573+
Self {
574+
table_id: column.table_id,
575+
col_pos: column.col_pos,
576+
col_name: column.col_name,
577+
col_type: column.col_type.into(),
578+
}
579+
}
580+
}
581+
571582
/// System Table [ST_INDEX_NAME]
572583
///
573584
/// | index_id | table_id | index_name | index_algorithm |

0 commit comments

Comments
 (0)