From 12e9f9d398f992b95239ce0cf7406566b628f771 Mon Sep 17 00:00:00 2001 From: James Gilles Date: Thu, 17 Jul 2025 13:13:36 -0400 Subject: [PATCH 1/5] Enable adding columns in auto migrations in `schema` --- crates/core/src/db/update.rs | 1 + crates/lib/src/db/raw_def/v9.rs | 35 ++++++++++- crates/sats/src/buffer.rs | 2 +- crates/schema/src/auto_migrate.rs | 77 ++++++++++++++++++++--- crates/schema/src/def.rs | 12 ++-- crates/schema/src/def/validate/v9.rs | 92 +++++++++++++++++++++++----- crates/schema/src/error.rs | 12 +++- 7 files changed, 200 insertions(+), 31 deletions(-) diff --git a/crates/core/src/db/update.rs b/crates/core/src/db/update.rs index 0bce2da8fa4..98aebce0628 100644 --- a/crates/core/src/db/update.rs +++ b/crates/core/src/db/update.rs @@ -252,6 +252,7 @@ fn auto_migrate_database( log!(logger, "Removing-row level security `{sql_rls}`"); stdb.drop_row_level_security(tx, sql_rls.clone())?; } + _ => unimplemented!(), } } diff --git a/crates/lib/src/db/raw_def/v9.rs b/crates/lib/src/db/raw_def/v9.rs index e5eedcf716b..2af81e18e30 100644 --- a/crates/lib/src/db/raw_def/v9.rs +++ b/crates/lib/src/db/raw_def/v9.rs @@ -14,6 +14,7 @@ use spacetimedb_primitives::*; use spacetimedb_sats::typespace::TypespaceBuilder; use spacetimedb_sats::AlgebraicType; use spacetimedb_sats::AlgebraicTypeRef; +use spacetimedb_sats::AlgebraicValue; use spacetimedb_sats::ProductType; use spacetimedb_sats::ProductTypeElement; use spacetimedb_sats::SpacetimeType; @@ -361,7 +362,25 @@ pub struct RawRowLevelSecurityDefV9 { #[sats(crate = crate)] #[cfg_attr(feature = "test", derive(PartialEq, Eq, PartialOrd, Ord))] #[non_exhaustive] -pub enum RawMiscModuleExportV9 {} +pub enum RawMiscModuleExportV9 { + ColumnDefaultValue(RawColumnDefaultValueV9), +} + +/// Marks a field as having a particularly default +#[derive(Debug, Clone, SpacetimeType)] +#[sats(crate = crate)] +#[cfg_attr(feature = "test", derive(PartialEq, Eq, PartialOrd, Ord))] +pub struct RawColumnDefaultValueV9 { + /// Must point to a `ProductType` or an error will be thrown during validation. + pub table: RawIdentifier, + + /// Must be the index of a valid column within `ty`. + pub col_id: ColId, + + /// A BSATN-encoded AlgebraicValue valid at `ty`. + /// (We can't use AlgebraicValue directly because it isn't serializable!) + pub value: Box<[u8]>, +} /// A type declaration. /// @@ -794,6 +813,20 @@ impl RawTableDefBuilder<'_> { self } + /// Adds a default value for the field. + /// Note: this sets the value for all other tables defined on the same + pub fn with_default_column_value(self, column: impl Into, value: AlgebraicValue) -> Self { + // Added to misc_exports for backwards-compatibility reasons + self.module_def + .misc_exports + .push(RawMiscModuleExportV9::ColumnDefaultValue(RawColumnDefaultValueV9 { + table: self.table.name.clone(), + col_id: column.into(), + value: spacetimedb_sats::bsatn::to_vec(&value).unwrap().into(), + })); + self + } + /// Build the table and add it to the module, returning the `product_type_ref` of the table. pub fn finish(self) -> AlgebraicTypeRef { self.table.product_type_ref diff --git a/crates/sats/src/buffer.rs b/crates/sats/src/buffer.rs index c3762282c7f..17b58ec488c 100644 --- a/crates/sats/src/buffer.rs +++ b/crates/sats/src/buffer.rs @@ -10,7 +10,7 @@ use core::fmt; use core::str::Utf8Error; /// An error that occurred when decoding. -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] pub enum DecodeError { /// Not enough data was provided in the input. BufferLength { diff --git a/crates/schema/src/auto_migrate.rs b/crates/schema/src/auto_migrate.rs index 3b84a3526c1..7cf268f613c 100644 --- a/crates/schema/src/auto_migrate.rs +++ b/crates/schema/src/auto_migrate.rs @@ -109,6 +109,15 @@ pub enum AutoMigrateStep<'def> { /// /// This should be done before any new indices are added. ChangeColumns(::Key<'def>), + /// Add columns to a table, in a layout-INCOMPATIBLE way. + /// + /// This is a destructive operation that requires first running a `DisconnectAllUsers`. + /// + /// The added columns are guaranteed to be contiguous and at the end of the table. They are also + /// guaranteed to have default values set. + /// + /// This suppresses any `ChangeColumns` steps for the same table. + AddColumns(::Key<'def>), /// Add a table, including all indexes, constraints, and sequences. /// There will NOT be separate steps in the plan for adding indexes, constraints, and sequences. @@ -124,6 +133,9 @@ pub enum AutoMigrateStep<'def> { /// Change the access of a table. ChangeAccess(::Key<'def>), + + /// Disconnect all users connected to the module. + DisconnectAllUsers, } #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)] @@ -137,7 +149,7 @@ pub struct ChangeColumnTypeParts { /// Something that might prevent an automatic migration. #[derive(thiserror::Error, Debug, PartialEq, Eq, PartialOrd, Ord)] pub enum AutoMigrateError { - #[error("Adding a column {column} to table {table} requires a manual migration")] + #[error("Adding a column {column} to table {table} requires a default value annotation")] AddColumn { table: Identifier, column: Identifier }, #[error("Removing a column {column} from table {table} requires a manual migration")] @@ -386,11 +398,18 @@ fn auto_migrate_table<'def>(plan: &mut AutoMigratePlan<'def>, old: &'def TableDe }) .map(|col_diff| -> Result<_> { match col_diff { - Diff::Add { new } => Err(AutoMigrateError::AddColumn { - table: new.table_name.clone(), - column: new.name.clone(), + Diff::Add { new } => { + if new.default_value.is_some() { + // row_type_changed, columns_added + Ok(ProductMonoid(Any(false), Any(true))) + } else { + Err(AutoMigrateError::AddColumn { + table: new.table_name.clone(), + column: new.name.clone(), + } + .into()) + } } - .into()), Diff::Remove { old } => Err(AutoMigrateError::RemoveColumn { table: old.table_name.clone(), column: old.name.clone(), @@ -408,6 +427,7 @@ fn auto_migrate_table<'def>(plan: &mut AutoMigratePlan<'def>, old: &'def TableDe // Note that the diff algorithm relies on `ModuleDefLookup` for `ColumnDef`, // which looks up columns by NAME, NOT position: precisely to allow this step to work! + // We reject changes to let positions_ok = if old.col_id == new.col_id { Ok(()) } else { @@ -417,15 +437,26 @@ fn auto_migrate_table<'def>(plan: &mut AutoMigratePlan<'def>, old: &'def TableDe .into()) }; - (types_ok, positions_ok).combine_errors().map(|(x, _)| x) + (types_ok, positions_ok) + .combine_errors() + .map(|(x, _)| ProductMonoid(x, Any(false))) } } }) - .collect_all_errors::(); + .collect_all_errors::>(); - let ((), Any(row_type_changed)) = (type_ok, columns_ok).combine_errors()?; + let ((), ProductMonoid(Any(row_type_changed), Any(columns_added))) = (type_ok, columns_ok).combine_errors()?; - if row_type_changed { + if columns_added { + if !plan + .steps + .iter() + .any(|step| matches!(step, AutoMigrateStep::DisconnectAllUsers)) + { + plan.steps.push(AutoMigrateStep::DisconnectAllUsers); + } + plan.steps.push(AutoMigrateStep::AddColumns(key)); + } else if row_type_changed { plan.steps.push(AutoMigrateStep::ChangeColumns(key)); } @@ -433,6 +464,7 @@ fn auto_migrate_table<'def>(plan: &mut AutoMigratePlan<'def>, old: &'def TableDe } /// An "any" monoid with `false` as identity and `|` as the operator. +#[derive(Default)] struct Any(bool); impl FromIterator for Any { @@ -448,6 +480,26 @@ impl BitOr for Any { } } +/// A monoid that allows running two `Any`s in parallel. +#[derive(Default)] +struct ProductMonoid(M1, M2); + +impl, M2: BitOr> BitOr for ProductMonoid { + type Output = Self; + + fn bitor(self, rhs: Self) -> Self::Output { + Self(self.0 | rhs.0, self.1 | rhs.1) + } +} + +impl + Default, M2: BitOr + Default> FromIterator> + for ProductMonoid +{ + fn from_iter>>(iter: T) -> Self { + iter.into_iter().reduce(|p1, p2| p1 | p2).unwrap_or_default() + } +} + fn ensure_old_ty_upgradable_to_new( within: bool, old: &ColumnDef, @@ -700,7 +752,7 @@ mod tests { use spacetimedb_data_structures::expect_error_matching; use spacetimedb_lib::{ db::raw_def::{v9::btree, *}, - AlgebraicType, ProductType, ScheduleAt, + AlgebraicType, AlgebraicValue, ProductType, ScheduleAt, }; use spacetimedb_primitives::ColId; use v9::{RawModuleDefV9Builder, TableAccess}; @@ -813,11 +865,13 @@ mod tests { ("id", AlgebraicType::U64), ("name", AlgebraicType::String), ("count", AlgebraicType::U16), + ("freshness", AlgebraicType::U32), // added column! ]), true, ) // add column sequence .with_column_sequence(0) + .with_default_column_value(3, AlgebraicValue::U32(5)) // change access .with_access(TableAccess::Private) .finish(); @@ -963,6 +1017,9 @@ mod tests { steps.contains(&AutoMigrateStep::ChangeColumns(&deliveries)), "{steps:?}" ); + + assert!(steps.contains(&AutoMigrateStep::DisconnectAllUsers), "{steps:?}"); + assert!(steps.contains(&AutoMigrateStep::AddColumns(&bananas)), "{steps:?}"); } #[test] diff --git a/crates/schema/src/def.rs b/crates/schema/src/def.rs index 8553eb31090..f7105a598d6 100644 --- a/crates/schema/src/def.rs +++ b/crates/schema/src/def.rs @@ -32,13 +32,14 @@ use spacetimedb_data_structures::error_stream::{CollectAllErrors, CombineErrors, use spacetimedb_data_structures::map::HashMap; use spacetimedb_lib::db::raw_def; use spacetimedb_lib::db::raw_def::v9::{ - Lifecycle, RawConstraintDataV9, RawConstraintDefV9, RawIdentifier, RawIndexAlgorithm, RawIndexDefV9, - RawModuleDefV9, RawReducerDefV9, RawRowLevelSecurityDefV9, RawScheduleDefV9, RawScopedTypeNameV9, RawSequenceDefV9, - RawSql, RawTableDefV9, RawTypeDefV9, RawUniqueConstraintDataV9, TableAccess, TableType, + Lifecycle, RawColumnDefaultValueV9, RawConstraintDataV9, RawConstraintDefV9, RawIdentifier, RawIndexAlgorithm, + RawIndexDefV9, RawMiscModuleExportV9, RawModuleDefV9, RawReducerDefV9, RawRowLevelSecurityDefV9, RawScheduleDefV9, + RawScopedTypeNameV9, RawSequenceDefV9, RawSql, RawTableDefV9, RawTypeDefV9, RawUniqueConstraintDataV9, TableAccess, + TableType, }; use spacetimedb_lib::{ProductType, RawModuleDef}; use spacetimedb_primitives::{ColId, ColList, ColOrCols, ColSet, ReducerId, TableId}; -use spacetimedb_sats::AlgebraicType; +use spacetimedb_sats::{AlgebraicType, AlgebraicValue}; use spacetimedb_sats::{AlgebraicTypeRef, Typespace}; pub mod deserialize; @@ -659,6 +660,9 @@ pub struct ColumnDef { /// The table this `ColumnDef` is stored in. pub table_name: Identifier, + + /// The default value of this column, if present. + pub default_value: Option, } /// A constraint definition attached to a table. diff --git a/crates/schema/src/def/validate/v9.rs b/crates/schema/src/def/validate/v9.rs index 60e8e458170..73921631436 100644 --- a/crates/schema/src/def/validate/v9.rs +++ b/crates/schema/src/def/validate/v9.rs @@ -7,6 +7,7 @@ use spacetimedb_data_structures::map::HashSet; use spacetimedb_lib::db::default_element_ordering::{product_type_has_default_ordering, sum_type_has_default_ordering}; use spacetimedb_lib::ProductType; use spacetimedb_primitives::col_list; +use spacetimedb_sats::{bsatn::de::Deserializer, de::DeserializeSeed, WithTypespace}; /// Validate a `RawModuleDefV9` and convert it into a `ModuleDef`, /// or return a stream of errors if the definition is invalid. @@ -75,17 +76,22 @@ pub fn validate(def: RawModuleDefV9) -> Result { }) .collect_all_errors::>(); - // It's statically impossible for this assert to fire until `RawMiscModuleExportV9` grows some variants. - assert_eq!( - misc_exports.len(), - 0, - "Misc module exports are not yet supported in ABI v9." - ); - let tables_types_reducers = (tables, types, reducers) .combine_errors() - .and_then(|(tables, types, reducers)| { - check_scheduled_reducers_exist(&tables, &reducers)?; + .and_then(|(mut tables, types, reducers)| { + let sched_exists = check_scheduled_reducers_exist(&tables, &reducers); + let default_values_work = misc_exports + .into_iter() + .map(|export| match export { + RawMiscModuleExportV9::ColumnDefaultValue(fdv) => { + validator.validate_column_default_value(&mut tables, fdv) + } + _ => unimplemented!("unknown misc export"), + }) + .collect_all_errors::<()>(); + + (sched_exists, default_values_work).combine_errors()?; + Ok((tables, types, reducers)) }); @@ -350,6 +356,56 @@ impl ModuleValidator<'_> { }) } + fn validate_column_default_value( + &mut self, + tables: &mut HashMap, + cdv: RawColumnDefaultValueV9, + ) -> Result<()> { + let table_name = identifier(cdv.table.clone())?; + + let table = tables + .get_mut(&table_name) + .ok_or_else(|| ValidationError::TableNotFound { + table: cdv.table.clone(), + })?; + + if table.columns.len() <= cdv.col_id.idx() { + return Err(ValidationError::ColumnNotFound { + table: cdv.table.clone(), + def: cdv.table.clone(), + column: cdv.col_id, + } + .into()); + } + + let col = &mut table.columns[cdv.col_id.idx()]; + // First time we have a type for it, so decode it. + let mut reader = &cdv.value[..]; + println!("{reader:?}"); + let ty = WithTypespace::new(&self.typespace, &col.ty); + let field_value = match ty.deserialize(Deserializer::new(&mut reader)) { + Ok(field_value) => Some(field_value), + Err(decode_error) => { + return Err(ValidationError::ColumnDefaultValueMalformed { + table: cdv.table.clone(), + col_id: cdv.col_id, + err: decode_error, + } + .into()) + } + }; + if col.default_value.is_some() { + return Err(ValidationError::MultipleColumnDefaultValues { + table: cdv.table.clone(), + col_id: cdv.col_id, + } + .into()); + } + col.default_value = field_value.clone(); + + Ok(()) + } + /// Validate a type definition. fn validate_type_def(&mut self, type_def: RawTypeDefV9) -> Result { let RawTypeDefV9 { @@ -503,6 +559,7 @@ impl TableValidator<'_, '_> { ty_for_generate, col_id, table_name, + default_value: None, // filled in later }) } @@ -624,13 +681,12 @@ impl TableValidator<'_, '_> { RawIndexAlgorithm::Direct { column } => self.validate_col_id(&name, column).and_then(|column| { let field = &self.product_type.elements[column.idx()]; let ty = &field.algebraic_type; - use AlgebraicType::*; let is_bad_type = match ty { - U8 | U16 | U32 | U64 => false, - Ref(r) => self.module_validator.typespace[*r] + AlgebraicType::U8 | AlgebraicType::U16 | AlgebraicType::U32 | AlgebraicType::U64 => false, + AlgebraicType::Ref(r) => self.module_validator.typespace[*r] .as_sum() .is_none_or(|s| !s.is_simple_enum()), - Sum(sum) if sum.is_simple_enum() => false, + AlgebraicType::Sum(sum) if sum.is_simple_enum() => false, _ => true, }; if is_bad_type { @@ -916,7 +972,7 @@ mod tests { use spacetimedb_lib::db::raw_def::*; use spacetimedb_lib::ScheduleAt; use spacetimedb_primitives::{ColId, ColList, ColSet}; - use spacetimedb_sats::{AlgebraicType, AlgebraicTypeRef, ProductType}; + use spacetimedb_sats::{AlgebraicType, AlgebraicTypeRef, AlgebraicValue, ProductType, SumValue}; use v9::{Lifecycle, RawIndexAlgorithm, RawModuleDefV9Builder, TableAccess, TableType}; /// This test attempts to exercise every successful path in the validation code. @@ -937,6 +993,8 @@ mod tests { let schedule_at_type = builder.add_type::(); + let red_delicious = AlgebraicValue::Sum(SumValue::new(2, ())); + builder .build_table_with_new_type( "Apples", @@ -953,6 +1011,8 @@ mod tests { .with_unique_constraint(2) .with_index(btree(3), "Apples_type_btree") .with_unique_constraint(3) + .with_default_column_value(2, AlgebraicValue::U16(37)) + .with_default_column_value(3, red_delicious.clone()) .finish(); builder @@ -1020,12 +1080,16 @@ mod tests { assert_eq!(apples_def.columns.len(), 4); assert_eq!(apples_def.columns[0].name, expect_identifier("id")); assert_eq!(apples_def.columns[0].ty, AlgebraicType::U64); + assert_eq!(apples_def.columns[0].default_value, None); assert_eq!(apples_def.columns[1].name, expect_identifier("name")); assert_eq!(apples_def.columns[1].ty, AlgebraicType::String); + assert_eq!(apples_def.columns[1].default_value, None); assert_eq!(apples_def.columns[2].name, expect_identifier("count")); assert_eq!(apples_def.columns[2].ty, AlgebraicType::U16); + assert_eq!(apples_def.columns[2].default_value, Some(AlgebraicValue::U16(37))); assert_eq!(apples_def.columns[3].name, expect_identifier("type")); assert_eq!(apples_def.columns[3].ty, sum_type_ref.into()); + assert_eq!(apples_def.columns[3].default_value, Some(red_delicious)); assert_eq!(expect_resolve(&def.typespace, &apples_def.columns[3].ty), sum_type); assert_eq!(apples_def.primary_key, None); diff --git a/crates/schema/src/error.rs b/crates/schema/src/error.rs index e8fb285f1d6..e7526ad095d 100644 --- a/crates/schema/src/error.rs +++ b/crates/schema/src/error.rs @@ -3,7 +3,7 @@ use spacetimedb_lib::db::raw_def::v9::{Lifecycle, RawIdentifier, RawScopedTypeNa use spacetimedb_lib::{ProductType, SumType}; use spacetimedb_primitives::{ColId, ColList, ColSet}; use spacetimedb_sats::algebraic_type::fmt::fmt_algebraic_type; -use spacetimedb_sats::{AlgebraicType, AlgebraicTypeRef}; +use spacetimedb_sats::{bsatn::DecodeError, AlgebraicType, AlgebraicTypeRef}; use std::borrow::Cow; use std::fmt; @@ -120,6 +120,16 @@ pub enum ValidationError { TableNameReserved { table: Identifier }, #[error("Row-level security invalid: `{error}`, query: `{sql}")] InvalidRowLevelQuery { sql: String, error: String }, + #[error("Failed to deserialize default value for table {table} column {col_id}: {err}")] + ColumnDefaultValueMalformed { + table: RawIdentifier, + col_id: ColId, + err: DecodeError, + }, + #[error("Multiple default values for table {table} column {col_id}")] + MultipleColumnDefaultValues { table: RawIdentifier, col_id: ColId }, + #[error("Table {table} not found")] + TableNotFound { table: RawIdentifier }, } /// A wrapper around an `AlgebraicType` that implements `fmt::Display`. From 605b65f8138691534f11479c2c4ae5c75ebf6d42 Mon Sep 17 00:00:00 2001 From: James Gilles Date: Fri, 18 Jul 2025 14:43:10 -0400 Subject: [PATCH 2/5] Comments --- crates/schema/src/auto_migrate.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/crates/schema/src/auto_migrate.rs b/crates/schema/src/auto_migrate.rs index 7cf268f613c..4cfb17b6a51 100644 --- a/crates/schema/src/auto_migrate.rs +++ b/crates/schema/src/auto_migrate.rs @@ -427,7 +427,10 @@ fn auto_migrate_table<'def>(plan: &mut AutoMigratePlan<'def>, old: &'def TableDe // Note that the diff algorithm relies on `ModuleDefLookup` for `ColumnDef`, // which looks up columns by NAME, NOT position: precisely to allow this step to work! - // We reject changes to + + // Note: We reject changes to positions. This means that, if a column was present in the old version of the table, + // it must be in the same place in the new version of the table. + // This guarantees that any added columns live at the end of the table. let positions_ok = if old.col_id == new.col_id { Ok(()) } else { @@ -439,6 +442,7 @@ fn auto_migrate_table<'def>(plan: &mut AutoMigratePlan<'def>, old: &'def TableDe (types_ok, positions_ok) .combine_errors() + // row_type_changed, column_added .map(|(x, _)| ProductMonoid(x, Any(false))) } } @@ -871,7 +875,7 @@ mod tests { ) // add column sequence .with_column_sequence(0) - .with_default_column_value(3, AlgebraicValue::U32(5)) + .with_default_column_value(3, AlgebraicValue::U32(5)) // we need a new // change access .with_access(TableAccess::Private) .finish(); @@ -1123,7 +1127,7 @@ mod tests { ("sum1", new_sum1_refty.into()), ("prod1", new_prod1_refty.into()), // remove count - ("weight", AlgebraicType::U16), // add weight + ("weight", AlgebraicType::U16), // add weight; we don't set a default, which makes this an error. ]), true, ) @@ -1164,6 +1168,7 @@ mod tests { expect_error_matching!( result, + // This is an error because we didn't set a default value. AutoMigrateError::AddColumn { table, column From 25954ec2e25e55ef6d44b56c7e5bca19d884ec54 Mon Sep 17 00:00:00 2001 From: Shubham Mishra Date: Wed, 23 Jul 2025 13:11:25 +0530 Subject: [PATCH 3/5] ci --- .../Runtime/Internal/Autogen/IndexType.g.cs | 2 +- .../Runtime/Internal/Autogen/Lifecycle.g.cs | 2 +- .../Internal/Autogen/MiscModuleExport.g.cs | 2 +- .../Internal/Autogen/RawColumnDefV8.g.cs | 2 +- .../Autogen/RawColumnDefaultValueV9.g.cs | 42 +++++++++++++++++++ .../Internal/Autogen/RawConstraintDataV9.g.cs | 2 +- .../Internal/Autogen/RawConstraintDefV8.g.cs | 2 +- .../Internal/Autogen/RawConstraintDefV9.g.cs | 2 +- .../Internal/Autogen/RawIndexAlgorithm.g.cs | 2 +- .../Internal/Autogen/RawIndexDefV8.g.cs | 2 +- .../Internal/Autogen/RawIndexDefV9.g.cs | 2 +- .../Autogen/RawMiscModuleExportV9.g.cs | 9 ++-- .../Internal/Autogen/RawModuleDef.g.cs | 2 +- .../Internal/Autogen/RawModuleDefV8.g.cs | 2 +- .../Internal/Autogen/RawModuleDefV9.g.cs | 2 +- .../Internal/Autogen/RawReducerDefV9.g.cs | 2 +- .../Autogen/RawRowLevelSecurityDefV9.g.cs | 2 +- .../Internal/Autogen/RawScheduleDefV9.g.cs | 2 +- .../Internal/Autogen/RawScopedTypeNameV9.g.cs | 2 +- .../Internal/Autogen/RawSequenceDefV8.g.cs | 2 +- .../Internal/Autogen/RawSequenceDefV9.g.cs | 2 +- .../Internal/Autogen/RawTableDefV8.g.cs | 2 +- .../Internal/Autogen/RawTableDefV9.g.cs | 2 +- .../Internal/Autogen/RawTypeDefV9.g.cs | 2 +- .../Autogen/RawUniqueConstraintDataV9.g.cs | 2 +- .../Runtime/Internal/Autogen/ReducerDef.g.cs | 2 +- .../Runtime/Internal/Autogen/TableAccess.g.cs | 2 +- .../Runtime/Internal/Autogen/TableDesc.g.cs | 2 +- .../Runtime/Internal/Autogen/TableType.g.cs | 2 +- .../Runtime/Internal/Autogen/TypeAlias.g.cs | 2 +- .../Runtime/Internal/Autogen/Typespace.g.cs | 2 +- crates/bindings/tests/ui/tables.stderr | 4 +- crates/schema/src/def/validate/v9.rs | 3 +- 33 files changed, 79 insertions(+), 37 deletions(-) create mode 100644 crates/bindings-csharp/Runtime/Internal/Autogen/RawColumnDefaultValueV9.g.cs diff --git a/crates/bindings-csharp/Runtime/Internal/Autogen/IndexType.g.cs b/crates/bindings-csharp/Runtime/Internal/Autogen/IndexType.g.cs index 179e4194e5c..3da796b8680 100644 --- a/crates/bindings-csharp/Runtime/Internal/Autogen/IndexType.g.cs +++ b/crates/bindings-csharp/Runtime/Internal/Autogen/IndexType.g.cs @@ -1,7 +1,7 @@ // THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE // WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. -// This was generated using spacetimedb cli version 1.1.1 (commit 92e49e96f461b4496bdab42facbab2c5d39d20f4). +// This was generated using spacetimedb cli version 1.2.0 (commit 1814483514681baeedb23e1dadd342dac4697ac5). #nullable enable diff --git a/crates/bindings-csharp/Runtime/Internal/Autogen/Lifecycle.g.cs b/crates/bindings-csharp/Runtime/Internal/Autogen/Lifecycle.g.cs index 5d923f87b77..6d65c56932d 100644 --- a/crates/bindings-csharp/Runtime/Internal/Autogen/Lifecycle.g.cs +++ b/crates/bindings-csharp/Runtime/Internal/Autogen/Lifecycle.g.cs @@ -1,7 +1,7 @@ // THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE // WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. -// This was generated using spacetimedb cli version 1.1.1 (commit 92e49e96f461b4496bdab42facbab2c5d39d20f4). +// This was generated using spacetimedb cli version 1.2.0 (commit 1814483514681baeedb23e1dadd342dac4697ac5). #nullable enable diff --git a/crates/bindings-csharp/Runtime/Internal/Autogen/MiscModuleExport.g.cs b/crates/bindings-csharp/Runtime/Internal/Autogen/MiscModuleExport.g.cs index bf43c0bd157..0e4d64351ad 100644 --- a/crates/bindings-csharp/Runtime/Internal/Autogen/MiscModuleExport.g.cs +++ b/crates/bindings-csharp/Runtime/Internal/Autogen/MiscModuleExport.g.cs @@ -1,7 +1,7 @@ // THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE // WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. -// This was generated using spacetimedb cli version 1.1.1 (commit 92e49e96f461b4496bdab42facbab2c5d39d20f4). +// This was generated using spacetimedb cli version 1.2.0 (commit 1814483514681baeedb23e1dadd342dac4697ac5). #nullable enable diff --git a/crates/bindings-csharp/Runtime/Internal/Autogen/RawColumnDefV8.g.cs b/crates/bindings-csharp/Runtime/Internal/Autogen/RawColumnDefV8.g.cs index 1b732435728..127789bb8b3 100644 --- a/crates/bindings-csharp/Runtime/Internal/Autogen/RawColumnDefV8.g.cs +++ b/crates/bindings-csharp/Runtime/Internal/Autogen/RawColumnDefV8.g.cs @@ -1,7 +1,7 @@ // THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE // WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. -// This was generated using spacetimedb cli version 1.1.1 (commit 92e49e96f461b4496bdab42facbab2c5d39d20f4). +// This was generated using spacetimedb cli version 1.2.0 (commit 1814483514681baeedb23e1dadd342dac4697ac5). #nullable enable diff --git a/crates/bindings-csharp/Runtime/Internal/Autogen/RawColumnDefaultValueV9.g.cs b/crates/bindings-csharp/Runtime/Internal/Autogen/RawColumnDefaultValueV9.g.cs new file mode 100644 index 00000000000..475d5b03e96 --- /dev/null +++ b/crates/bindings-csharp/Runtime/Internal/Autogen/RawColumnDefaultValueV9.g.cs @@ -0,0 +1,42 @@ +// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE +// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. + +// This was generated using spacetimedb cli version 1.2.0 (commit 1814483514681baeedb23e1dadd342dac4697ac5). + +#nullable enable + +using System; +using System.Collections.Generic; +using System.Runtime.Serialization; + +namespace SpacetimeDB.Internal +{ + [SpacetimeDB.Type] + [DataContract] + public sealed partial class RawColumnDefaultValueV9 + { + [DataMember(Name = "table")] + public string Table; + [DataMember(Name = "col_id")] + public ushort ColId; + [DataMember(Name = "value")] + public System.Collections.Generic.List Value; + + public RawColumnDefaultValueV9( + string Table, + ushort ColId, + System.Collections.Generic.List Value + ) + { + this.Table = Table; + this.ColId = ColId; + this.Value = Value; + } + + public RawColumnDefaultValueV9() + { + this.Table = ""; + this.Value = new(); + } + } +} diff --git a/crates/bindings-csharp/Runtime/Internal/Autogen/RawConstraintDataV9.g.cs b/crates/bindings-csharp/Runtime/Internal/Autogen/RawConstraintDataV9.g.cs index 610ad02c1d9..2ff1c6b3588 100644 --- a/crates/bindings-csharp/Runtime/Internal/Autogen/RawConstraintDataV9.g.cs +++ b/crates/bindings-csharp/Runtime/Internal/Autogen/RawConstraintDataV9.g.cs @@ -1,7 +1,7 @@ // THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE // WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. -// This was generated using spacetimedb cli version 1.1.1 (commit 92e49e96f461b4496bdab42facbab2c5d39d20f4). +// This was generated using spacetimedb cli version 1.2.0 (commit 1814483514681baeedb23e1dadd342dac4697ac5). #nullable enable diff --git a/crates/bindings-csharp/Runtime/Internal/Autogen/RawConstraintDefV8.g.cs b/crates/bindings-csharp/Runtime/Internal/Autogen/RawConstraintDefV8.g.cs index 534f4602b9f..f1aa5d706f8 100644 --- a/crates/bindings-csharp/Runtime/Internal/Autogen/RawConstraintDefV8.g.cs +++ b/crates/bindings-csharp/Runtime/Internal/Autogen/RawConstraintDefV8.g.cs @@ -1,7 +1,7 @@ // THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE // WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. -// This was generated using spacetimedb cli version 1.1.1 (commit 92e49e96f461b4496bdab42facbab2c5d39d20f4). +// This was generated using spacetimedb cli version 1.2.0 (commit 1814483514681baeedb23e1dadd342dac4697ac5). #nullable enable diff --git a/crates/bindings-csharp/Runtime/Internal/Autogen/RawConstraintDefV9.g.cs b/crates/bindings-csharp/Runtime/Internal/Autogen/RawConstraintDefV9.g.cs index 0fe3a076889..3eb7ad7faad 100644 --- a/crates/bindings-csharp/Runtime/Internal/Autogen/RawConstraintDefV9.g.cs +++ b/crates/bindings-csharp/Runtime/Internal/Autogen/RawConstraintDefV9.g.cs @@ -1,7 +1,7 @@ // THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE // WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. -// This was generated using spacetimedb cli version 1.1.1 (commit 92e49e96f461b4496bdab42facbab2c5d39d20f4). +// This was generated using spacetimedb cli version 1.2.0 (commit 1814483514681baeedb23e1dadd342dac4697ac5). #nullable enable diff --git a/crates/bindings-csharp/Runtime/Internal/Autogen/RawIndexAlgorithm.g.cs b/crates/bindings-csharp/Runtime/Internal/Autogen/RawIndexAlgorithm.g.cs index 92c0bd668c5..4378beed595 100644 --- a/crates/bindings-csharp/Runtime/Internal/Autogen/RawIndexAlgorithm.g.cs +++ b/crates/bindings-csharp/Runtime/Internal/Autogen/RawIndexAlgorithm.g.cs @@ -1,7 +1,7 @@ // THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE // WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. -// This was generated using spacetimedb cli version 1.1.1 (commit 92e49e96f461b4496bdab42facbab2c5d39d20f4). +// This was generated using spacetimedb cli version 1.2.0 (commit 1814483514681baeedb23e1dadd342dac4697ac5). #nullable enable diff --git a/crates/bindings-csharp/Runtime/Internal/Autogen/RawIndexDefV8.g.cs b/crates/bindings-csharp/Runtime/Internal/Autogen/RawIndexDefV8.g.cs index 545bd5509d9..7949c68da0b 100644 --- a/crates/bindings-csharp/Runtime/Internal/Autogen/RawIndexDefV8.g.cs +++ b/crates/bindings-csharp/Runtime/Internal/Autogen/RawIndexDefV8.g.cs @@ -1,7 +1,7 @@ // THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE // WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. -// This was generated using spacetimedb cli version 1.1.1 (commit 92e49e96f461b4496bdab42facbab2c5d39d20f4). +// This was generated using spacetimedb cli version 1.2.0 (commit 1814483514681baeedb23e1dadd342dac4697ac5). #nullable enable diff --git a/crates/bindings-csharp/Runtime/Internal/Autogen/RawIndexDefV9.g.cs b/crates/bindings-csharp/Runtime/Internal/Autogen/RawIndexDefV9.g.cs index af77b50d78c..5bf20c51fef 100644 --- a/crates/bindings-csharp/Runtime/Internal/Autogen/RawIndexDefV9.g.cs +++ b/crates/bindings-csharp/Runtime/Internal/Autogen/RawIndexDefV9.g.cs @@ -1,7 +1,7 @@ // THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE // WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. -// This was generated using spacetimedb cli version 1.1.1 (commit 92e49e96f461b4496bdab42facbab2c5d39d20f4). +// This was generated using spacetimedb cli version 1.2.0 (commit 1814483514681baeedb23e1dadd342dac4697ac5). #nullable enable diff --git a/crates/bindings-csharp/Runtime/Internal/Autogen/RawMiscModuleExportV9.g.cs b/crates/bindings-csharp/Runtime/Internal/Autogen/RawMiscModuleExportV9.g.cs index 95dd443ec8a..8c720392f65 100644 --- a/crates/bindings-csharp/Runtime/Internal/Autogen/RawMiscModuleExportV9.g.cs +++ b/crates/bindings-csharp/Runtime/Internal/Autogen/RawMiscModuleExportV9.g.cs @@ -1,7 +1,7 @@ // THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE // WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. -// This was generated using spacetimedb cli version 1.1.1 (commit 92e49e96f461b4496bdab42facbab2c5d39d20f4). +// This was generated using spacetimedb cli version 1.2.0 (commit 1814483514681baeedb23e1dadd342dac4697ac5). #nullable enable @@ -10,7 +10,8 @@ namespace SpacetimeDB.Internal { [SpacetimeDB.Type] - public enum RawMiscModuleExportV9 - { - } + public partial record RawMiscModuleExportV9 : SpacetimeDB.TaggedEnum<( + RawColumnDefaultValueV9 ColumnDefaultValue, + SpacetimeDB.Unit _Reserved + )>; } diff --git a/crates/bindings-csharp/Runtime/Internal/Autogen/RawModuleDef.g.cs b/crates/bindings-csharp/Runtime/Internal/Autogen/RawModuleDef.g.cs index c5fe737780a..f6f9f80d136 100644 --- a/crates/bindings-csharp/Runtime/Internal/Autogen/RawModuleDef.g.cs +++ b/crates/bindings-csharp/Runtime/Internal/Autogen/RawModuleDef.g.cs @@ -1,7 +1,7 @@ // THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE // WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. -// This was generated using spacetimedb cli version 1.1.1 (commit 92e49e96f461b4496bdab42facbab2c5d39d20f4). +// This was generated using spacetimedb cli version 1.2.0 (commit 1814483514681baeedb23e1dadd342dac4697ac5). #nullable enable diff --git a/crates/bindings-csharp/Runtime/Internal/Autogen/RawModuleDefV8.g.cs b/crates/bindings-csharp/Runtime/Internal/Autogen/RawModuleDefV8.g.cs index 61e273c77a2..225d217074c 100644 --- a/crates/bindings-csharp/Runtime/Internal/Autogen/RawModuleDefV8.g.cs +++ b/crates/bindings-csharp/Runtime/Internal/Autogen/RawModuleDefV8.g.cs @@ -1,7 +1,7 @@ // THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE // WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. -// This was generated using spacetimedb cli version 1.1.1 (commit 92e49e96f461b4496bdab42facbab2c5d39d20f4). +// This was generated using spacetimedb cli version 1.2.0 (commit 1814483514681baeedb23e1dadd342dac4697ac5). #nullable enable diff --git a/crates/bindings-csharp/Runtime/Internal/Autogen/RawModuleDefV9.g.cs b/crates/bindings-csharp/Runtime/Internal/Autogen/RawModuleDefV9.g.cs index 5a7a975a33e..66173638fe6 100644 --- a/crates/bindings-csharp/Runtime/Internal/Autogen/RawModuleDefV9.g.cs +++ b/crates/bindings-csharp/Runtime/Internal/Autogen/RawModuleDefV9.g.cs @@ -1,7 +1,7 @@ // THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE // WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. -// This was generated using spacetimedb cli version 1.1.1 (commit 92e49e96f461b4496bdab42facbab2c5d39d20f4). +// This was generated using spacetimedb cli version 1.2.0 (commit 1814483514681baeedb23e1dadd342dac4697ac5). #nullable enable diff --git a/crates/bindings-csharp/Runtime/Internal/Autogen/RawReducerDefV9.g.cs b/crates/bindings-csharp/Runtime/Internal/Autogen/RawReducerDefV9.g.cs index 2485bd4b0fb..b85972339c4 100644 --- a/crates/bindings-csharp/Runtime/Internal/Autogen/RawReducerDefV9.g.cs +++ b/crates/bindings-csharp/Runtime/Internal/Autogen/RawReducerDefV9.g.cs @@ -1,7 +1,7 @@ // THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE // WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. -// This was generated using spacetimedb cli version 1.1.1 (commit 92e49e96f461b4496bdab42facbab2c5d39d20f4). +// This was generated using spacetimedb cli version 1.2.0 (commit 1814483514681baeedb23e1dadd342dac4697ac5). #nullable enable diff --git a/crates/bindings-csharp/Runtime/Internal/Autogen/RawRowLevelSecurityDefV9.g.cs b/crates/bindings-csharp/Runtime/Internal/Autogen/RawRowLevelSecurityDefV9.g.cs index 91202dfdb0f..86022728d3d 100644 --- a/crates/bindings-csharp/Runtime/Internal/Autogen/RawRowLevelSecurityDefV9.g.cs +++ b/crates/bindings-csharp/Runtime/Internal/Autogen/RawRowLevelSecurityDefV9.g.cs @@ -1,7 +1,7 @@ // THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE // WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. -// This was generated using spacetimedb cli version 1.1.1 (commit 92e49e96f461b4496bdab42facbab2c5d39d20f4). +// This was generated using spacetimedb cli version 1.2.0 (commit 1814483514681baeedb23e1dadd342dac4697ac5). #nullable enable diff --git a/crates/bindings-csharp/Runtime/Internal/Autogen/RawScheduleDefV9.g.cs b/crates/bindings-csharp/Runtime/Internal/Autogen/RawScheduleDefV9.g.cs index 8d13f3a51f1..01423322c48 100644 --- a/crates/bindings-csharp/Runtime/Internal/Autogen/RawScheduleDefV9.g.cs +++ b/crates/bindings-csharp/Runtime/Internal/Autogen/RawScheduleDefV9.g.cs @@ -1,7 +1,7 @@ // THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE // WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. -// This was generated using spacetimedb cli version 1.1.1 (commit 92e49e96f461b4496bdab42facbab2c5d39d20f4). +// This was generated using spacetimedb cli version 1.2.0 (commit 1814483514681baeedb23e1dadd342dac4697ac5). #nullable enable diff --git a/crates/bindings-csharp/Runtime/Internal/Autogen/RawScopedTypeNameV9.g.cs b/crates/bindings-csharp/Runtime/Internal/Autogen/RawScopedTypeNameV9.g.cs index c4254031dad..3e414d08a48 100644 --- a/crates/bindings-csharp/Runtime/Internal/Autogen/RawScopedTypeNameV9.g.cs +++ b/crates/bindings-csharp/Runtime/Internal/Autogen/RawScopedTypeNameV9.g.cs @@ -1,7 +1,7 @@ // THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE // WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. -// This was generated using spacetimedb cli version 1.1.1 (commit 92e49e96f461b4496bdab42facbab2c5d39d20f4). +// This was generated using spacetimedb cli version 1.2.0 (commit 1814483514681baeedb23e1dadd342dac4697ac5). #nullable enable diff --git a/crates/bindings-csharp/Runtime/Internal/Autogen/RawSequenceDefV8.g.cs b/crates/bindings-csharp/Runtime/Internal/Autogen/RawSequenceDefV8.g.cs index 9a87f3ef8c4..5d8b78e0eef 100644 --- a/crates/bindings-csharp/Runtime/Internal/Autogen/RawSequenceDefV8.g.cs +++ b/crates/bindings-csharp/Runtime/Internal/Autogen/RawSequenceDefV8.g.cs @@ -1,7 +1,7 @@ // THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE // WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. -// This was generated using spacetimedb cli version 1.1.1 (commit 92e49e96f461b4496bdab42facbab2c5d39d20f4). +// This was generated using spacetimedb cli version 1.2.0 (commit 1814483514681baeedb23e1dadd342dac4697ac5). #nullable enable diff --git a/crates/bindings-csharp/Runtime/Internal/Autogen/RawSequenceDefV9.g.cs b/crates/bindings-csharp/Runtime/Internal/Autogen/RawSequenceDefV9.g.cs index 0793bd28b0b..3d64c3fec6b 100644 --- a/crates/bindings-csharp/Runtime/Internal/Autogen/RawSequenceDefV9.g.cs +++ b/crates/bindings-csharp/Runtime/Internal/Autogen/RawSequenceDefV9.g.cs @@ -1,7 +1,7 @@ // THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE // WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. -// This was generated using spacetimedb cli version 1.1.1 (commit 92e49e96f461b4496bdab42facbab2c5d39d20f4). +// This was generated using spacetimedb cli version 1.2.0 (commit 1814483514681baeedb23e1dadd342dac4697ac5). #nullable enable diff --git a/crates/bindings-csharp/Runtime/Internal/Autogen/RawTableDefV8.g.cs b/crates/bindings-csharp/Runtime/Internal/Autogen/RawTableDefV8.g.cs index 60ff65f2a43..edc06e19675 100644 --- a/crates/bindings-csharp/Runtime/Internal/Autogen/RawTableDefV8.g.cs +++ b/crates/bindings-csharp/Runtime/Internal/Autogen/RawTableDefV8.g.cs @@ -1,7 +1,7 @@ // THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE // WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. -// This was generated using spacetimedb cli version 1.1.1 (commit 92e49e96f461b4496bdab42facbab2c5d39d20f4). +// This was generated using spacetimedb cli version 1.2.0 (commit 1814483514681baeedb23e1dadd342dac4697ac5). #nullable enable diff --git a/crates/bindings-csharp/Runtime/Internal/Autogen/RawTableDefV9.g.cs b/crates/bindings-csharp/Runtime/Internal/Autogen/RawTableDefV9.g.cs index fc7a42e2771..b21da87a882 100644 --- a/crates/bindings-csharp/Runtime/Internal/Autogen/RawTableDefV9.g.cs +++ b/crates/bindings-csharp/Runtime/Internal/Autogen/RawTableDefV9.g.cs @@ -1,7 +1,7 @@ // THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE // WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. -// This was generated using spacetimedb cli version 1.1.1 (commit 92e49e96f461b4496bdab42facbab2c5d39d20f4). +// This was generated using spacetimedb cli version 1.2.0 (commit 1814483514681baeedb23e1dadd342dac4697ac5). #nullable enable diff --git a/crates/bindings-csharp/Runtime/Internal/Autogen/RawTypeDefV9.g.cs b/crates/bindings-csharp/Runtime/Internal/Autogen/RawTypeDefV9.g.cs index d3d5d55728a..8ffa0de2bd9 100644 --- a/crates/bindings-csharp/Runtime/Internal/Autogen/RawTypeDefV9.g.cs +++ b/crates/bindings-csharp/Runtime/Internal/Autogen/RawTypeDefV9.g.cs @@ -1,7 +1,7 @@ // THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE // WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. -// This was generated using spacetimedb cli version 1.1.1 (commit 92e49e96f461b4496bdab42facbab2c5d39d20f4). +// This was generated using spacetimedb cli version 1.2.0 (commit 1814483514681baeedb23e1dadd342dac4697ac5). #nullable enable diff --git a/crates/bindings-csharp/Runtime/Internal/Autogen/RawUniqueConstraintDataV9.g.cs b/crates/bindings-csharp/Runtime/Internal/Autogen/RawUniqueConstraintDataV9.g.cs index 32e8006ab90..8e8ebf357ef 100644 --- a/crates/bindings-csharp/Runtime/Internal/Autogen/RawUniqueConstraintDataV9.g.cs +++ b/crates/bindings-csharp/Runtime/Internal/Autogen/RawUniqueConstraintDataV9.g.cs @@ -1,7 +1,7 @@ // THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE // WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. -// This was generated using spacetimedb cli version 1.1.1 (commit 92e49e96f461b4496bdab42facbab2c5d39d20f4). +// This was generated using spacetimedb cli version 1.2.0 (commit 1814483514681baeedb23e1dadd342dac4697ac5). #nullable enable diff --git a/crates/bindings-csharp/Runtime/Internal/Autogen/ReducerDef.g.cs b/crates/bindings-csharp/Runtime/Internal/Autogen/ReducerDef.g.cs index c77c7591b0f..920bcc27160 100644 --- a/crates/bindings-csharp/Runtime/Internal/Autogen/ReducerDef.g.cs +++ b/crates/bindings-csharp/Runtime/Internal/Autogen/ReducerDef.g.cs @@ -1,7 +1,7 @@ // THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE // WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. -// This was generated using spacetimedb cli version 1.1.1 (commit 92e49e96f461b4496bdab42facbab2c5d39d20f4). +// This was generated using spacetimedb cli version 1.2.0 (commit 1814483514681baeedb23e1dadd342dac4697ac5). #nullable enable diff --git a/crates/bindings-csharp/Runtime/Internal/Autogen/TableAccess.g.cs b/crates/bindings-csharp/Runtime/Internal/Autogen/TableAccess.g.cs index 89b6a30fa68..502b5559126 100644 --- a/crates/bindings-csharp/Runtime/Internal/Autogen/TableAccess.g.cs +++ b/crates/bindings-csharp/Runtime/Internal/Autogen/TableAccess.g.cs @@ -1,7 +1,7 @@ // THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE // WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. -// This was generated using spacetimedb cli version 1.1.1 (commit 92e49e96f461b4496bdab42facbab2c5d39d20f4). +// This was generated using spacetimedb cli version 1.2.0 (commit 1814483514681baeedb23e1dadd342dac4697ac5). #nullable enable diff --git a/crates/bindings-csharp/Runtime/Internal/Autogen/TableDesc.g.cs b/crates/bindings-csharp/Runtime/Internal/Autogen/TableDesc.g.cs index bb47858628a..7e6993fbdda 100644 --- a/crates/bindings-csharp/Runtime/Internal/Autogen/TableDesc.g.cs +++ b/crates/bindings-csharp/Runtime/Internal/Autogen/TableDesc.g.cs @@ -1,7 +1,7 @@ // THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE // WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. -// This was generated using spacetimedb cli version 1.1.1 (commit 92e49e96f461b4496bdab42facbab2c5d39d20f4). +// This was generated using spacetimedb cli version 1.2.0 (commit 1814483514681baeedb23e1dadd342dac4697ac5). #nullable enable diff --git a/crates/bindings-csharp/Runtime/Internal/Autogen/TableType.g.cs b/crates/bindings-csharp/Runtime/Internal/Autogen/TableType.g.cs index aad45215e9d..bc76eb9ef19 100644 --- a/crates/bindings-csharp/Runtime/Internal/Autogen/TableType.g.cs +++ b/crates/bindings-csharp/Runtime/Internal/Autogen/TableType.g.cs @@ -1,7 +1,7 @@ // THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE // WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. -// This was generated using spacetimedb cli version 1.1.1 (commit 92e49e96f461b4496bdab42facbab2c5d39d20f4). +// This was generated using spacetimedb cli version 1.2.0 (commit 1814483514681baeedb23e1dadd342dac4697ac5). #nullable enable diff --git a/crates/bindings-csharp/Runtime/Internal/Autogen/TypeAlias.g.cs b/crates/bindings-csharp/Runtime/Internal/Autogen/TypeAlias.g.cs index 3fe82bfabf9..3f5861933f9 100644 --- a/crates/bindings-csharp/Runtime/Internal/Autogen/TypeAlias.g.cs +++ b/crates/bindings-csharp/Runtime/Internal/Autogen/TypeAlias.g.cs @@ -1,7 +1,7 @@ // THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE // WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. -// This was generated using spacetimedb cli version 1.1.1 (commit 92e49e96f461b4496bdab42facbab2c5d39d20f4). +// This was generated using spacetimedb cli version 1.2.0 (commit 1814483514681baeedb23e1dadd342dac4697ac5). #nullable enable diff --git a/crates/bindings-csharp/Runtime/Internal/Autogen/Typespace.g.cs b/crates/bindings-csharp/Runtime/Internal/Autogen/Typespace.g.cs index 6107b0aed68..536d150a623 100644 --- a/crates/bindings-csharp/Runtime/Internal/Autogen/Typespace.g.cs +++ b/crates/bindings-csharp/Runtime/Internal/Autogen/Typespace.g.cs @@ -1,7 +1,7 @@ // THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE // WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. -// This was generated using spacetimedb cli version 1.1.1 (commit 92e49e96f461b4496bdab42facbab2c5d39d20f4). +// This was generated using spacetimedb cli version 1.2.0 (commit 1814483514681baeedb23e1dadd342dac4697ac5). #nullable enable diff --git a/crates/bindings/tests/ui/tables.stderr b/crates/bindings/tests/ui/tables.stderr index d003ce5faca..7447119b618 100644 --- a/crates/bindings/tests/ui/tables.stderr +++ b/crates/bindings/tests/ui/tables.stderr @@ -129,11 +129,11 @@ error[E0277]: `&'a Alpha` cannot appear as an argument to an index filtering ope &ConnectionId &Identity &Lifecycle - &RawMiscModuleExportV9 &TableAccess &TableType &bool ðnum::int::I256 + ðnum::uint::U256 and $N others note: required by a bound in `UniqueColumn::::ColType, Col>::find` --> src/table.rs @@ -156,11 +156,11 @@ error[E0277]: the trait bound `Alpha: IndexScanRangeBounds<(Alpha,), SingleBound &ConnectionId &Identity &Lifecycle - &RawMiscModuleExportV9 &TableAccess &TableType &bool ðnum::int::I256 + ðnum::uint::U256 and $N others = note: required for `Alpha` to implement `IndexScanRangeBounds<(Alpha,), SingleBound>` note: required by a bound in `RangedIndex::::filter` diff --git a/crates/schema/src/def/validate/v9.rs b/crates/schema/src/def/validate/v9.rs index 73921631436..4dd65d23093 100644 --- a/crates/schema/src/def/validate/v9.rs +++ b/crates/schema/src/def/validate/v9.rs @@ -381,8 +381,7 @@ impl ModuleValidator<'_> { let col = &mut table.columns[cdv.col_id.idx()]; // First time we have a type for it, so decode it. let mut reader = &cdv.value[..]; - println!("{reader:?}"); - let ty = WithTypespace::new(&self.typespace, &col.ty); + let ty = WithTypespace::new(self.typespace, &col.ty); let field_value = match ty.deserialize(Deserializer::new(&mut reader)) { Ok(field_value) => Some(field_value), Err(decode_error) => { From 1b9facb8ce8b53b6d5694c58c148802a4fd6413a Mon Sep 17 00:00:00 2001 From: Shubham Mishra Date: Mon, 11 Aug 2025 22:05:44 +0530 Subject: [PATCH 4/5] Address comments --- crates/core/src/db/update.rs | 2 +- crates/lib/src/db/raw_def/v9.rs | 12 +++---- crates/schema/src/auto_migrate.rs | 16 ++++++--- crates/schema/src/def.rs | 51 ++++++++++++++++++++++++++++ crates/schema/src/def/validate/v9.rs | 49 ++++++++++++++------------ 5 files changed, 95 insertions(+), 35 deletions(-) diff --git a/crates/core/src/db/update.rs b/crates/core/src/db/update.rs index 98aebce0628..d2496b5bdb5 100644 --- a/crates/core/src/db/update.rs +++ b/crates/core/src/db/update.rs @@ -252,7 +252,7 @@ fn auto_migrate_database( log!(logger, "Removing-row level security `{sql_rls}`"); stdb.drop_row_level_security(tx, sql_rls.clone())?; } - _ => unimplemented!(), + _ => anyhow::bail!("migration step not implemented: {step:?}"), } } diff --git a/crates/lib/src/db/raw_def/v9.rs b/crates/lib/src/db/raw_def/v9.rs index 2af81e18e30..07e0137e445 100644 --- a/crates/lib/src/db/raw_def/v9.rs +++ b/crates/lib/src/db/raw_def/v9.rs @@ -366,19 +366,18 @@ pub enum RawMiscModuleExportV9 { ColumnDefaultValue(RawColumnDefaultValueV9), } -/// Marks a field as having a particularly default +/// Marks a field as having a particular default. #[derive(Debug, Clone, SpacetimeType)] #[sats(crate = crate)] #[cfg_attr(feature = "test", derive(PartialEq, Eq, PartialOrd, Ord))] pub struct RawColumnDefaultValueV9 { - /// Must point to a `ProductType` or an error will be thrown during validation. pub table: RawIdentifier, /// Must be the index of a valid column within `ty`. pub col_id: ColId, - /// A BSATN-encoded AlgebraicValue valid at `ty`. - /// (We can't use AlgebraicValue directly because it isn't serializable!) + /// A BSATN-encoded [`AlgebraicValue`] valid at `ty`. + /// (We can't use `AlgebraicValue` directly because it isn't serializable!) pub value: Box<[u8]>, } @@ -813,10 +812,9 @@ impl RawTableDefBuilder<'_> { self } - /// Adds a default value for the field. - /// Note: this sets the value for all other tables defined on the same + /// Adds a default value for the `column`. pub fn with_default_column_value(self, column: impl Into, value: AlgebraicValue) -> Self { - // Added to misc_exports for backwards-compatibility reasons + // Added to `misc_exports` for backwards-compatibility reasons. self.module_def .misc_exports .push(RawMiscModuleExportV9::ColumnDefaultValue(RawColumnDefaultValueV9 { diff --git a/crates/schema/src/auto_migrate.rs b/crates/schema/src/auto_migrate.rs index 4cfb17b6a51..ec30d6fe582 100644 --- a/crates/schema/src/auto_migrate.rs +++ b/crates/schema/src/auto_migrate.rs @@ -113,10 +113,12 @@ pub enum AutoMigrateStep<'def> { /// /// This is a destructive operation that requires first running a `DisconnectAllUsers`. /// - /// The added columns are guaranteed to be contiguous and at the end of the table. They are also - /// guaranteed to have default values set. + /// The added columns are guaranteed to be contiguous + /// and at the end of the table. + /// They are also guaranteed to have default values set. /// - /// This suppresses any `ChangeColumns` steps for the same table. + /// When this step is present, + /// no `ChangeColumns` steps will be, for the same table. AddColumns(::Key<'def>), /// Add a table, including all indexes, constraints, and sequences. @@ -400,7 +402,7 @@ fn auto_migrate_table<'def>(plan: &mut AutoMigratePlan<'def>, old: &'def TableDe match col_diff { Diff::Add { new } => { if new.default_value.is_some() { - // row_type_changed, columns_added + // `row_type_changed`, `columns_added` Ok(ProductMonoid(Any(false), Any(true))) } else { Err(AutoMigrateError::AddColumn { @@ -451,6 +453,8 @@ fn auto_migrate_table<'def>(plan: &mut AutoMigratePlan<'def>, old: &'def TableDe let ((), ProductMonoid(Any(row_type_changed), Any(columns_added))) = (type_ok, columns_ok).combine_errors()?; + // If we're adding a column, we'll rewrite the whole table. + // That makes any `ChangeColumns` moot, so we can skip it. if columns_added { if !plan .steps @@ -875,7 +879,7 @@ mod tests { ) // add column sequence .with_column_sequence(0) - .with_default_column_value(3, AlgebraicValue::U32(5)) // we need a new + .with_default_column_value(3, AlgebraicValue::U32(5)) // change access .with_access(TableAccess::Private) .finish(); @@ -1024,6 +1028,8 @@ mod tests { assert!(steps.contains(&AutoMigrateStep::DisconnectAllUsers), "{steps:?}"); assert!(steps.contains(&AutoMigrateStep::AddColumns(&bananas)), "{steps:?}"); + // Column is changed but it will not reflect in steps due to `AutoMigrateStep::AddColumns` + assert!(!steps.contains(&AutoMigrateStep::ChangeColumns(&bananas)), "{steps:?}"); } #[test] diff --git a/crates/schema/src/def.rs b/crates/schema/src/def.rs index f7105a598d6..6a63ddd69b1 100644 --- a/crates/schema/src/def.rs +++ b/crates/schema/src/def.rs @@ -1059,8 +1059,12 @@ where #[cfg(test)] mod tests { + use crate::{def::validate::tests::expect_identifier, error::ValidationError}; + use super::*; use proptest::prelude::*; + use spacetimedb_data_structures::expect_error_matching; + use spacetimedb_lib::db::raw_def::v9::RawModuleDefV9Builder; proptest! { #[test] @@ -1076,4 +1080,51 @@ mod tests { prop_assert_eq!(raw, raw2); } } + + #[test] + fn validate_new_column_with_multiple_values() { + let mut old_builder = RawModuleDefV9Builder::new(); + old_builder + .build_table_with_new_type( + "Apples", + ProductType::from([("id", AlgebraicType::U64), ("count", AlgebraicType::U16)]), + true, + ) + .with_default_column_value(1, AlgebraicValue::U16(12)) + .with_default_column_value(1, AlgebraicValue::U16(10)) + .finish(); + + let result: Result = old_builder.finish().try_into(); + let apples = expect_identifier("Apples"); + + expect_error_matching!( + result, + ValidationError::MultipleColumnDefaultValues { + table, + .. + } => *table == apples.clone().into() + ); + } + + #[test] + fn validate_new_column_with_malformed_value() { + let mut old_builder = RawModuleDefV9Builder::new(); + old_builder + .build_table_with_new_type( + "Apples", + ProductType::from([("id", AlgebraicType::U64), ("count", AlgebraicType::U16)]), + true, + ) + .with_default_column_value(1, AlgebraicValue::Bool(false)) + .with_default_column_value(1, AlgebraicValue::U16(10)) + .finish(); + + let result: Result = old_builder.finish().try_into(); + let apples = expect_identifier("Apples"); + + expect_error_matching!( + result, + ValidationError::ColumnDefaultValueMalformed { table, col_id, .. } => *table == apples.clone().into() && *col_id == ColId(1) + ); + } } diff --git a/crates/schema/src/def/validate/v9.rs b/crates/schema/src/def/validate/v9.rs index 4dd65d23093..ee32561ee82 100644 --- a/crates/schema/src/def/validate/v9.rs +++ b/crates/schema/src/def/validate/v9.rs @@ -80,16 +80,7 @@ pub fn validate(def: RawModuleDefV9) -> Result { .combine_errors() .and_then(|(mut tables, types, reducers)| { let sched_exists = check_scheduled_reducers_exist(&tables, &reducers); - let default_values_work = misc_exports - .into_iter() - .map(|export| match export { - RawMiscModuleExportV9::ColumnDefaultValue(fdv) => { - validator.validate_column_default_value(&mut tables, fdv) - } - _ => unimplemented!("unknown misc export"), - }) - .collect_all_errors::<()>(); - + let default_values_work = default_values_work(misc_exports, &mut validator, &mut tables); (sched_exists, default_values_work).combine_errors()?; Ok((tables, types, reducers)) @@ -363,36 +354,36 @@ impl ModuleValidator<'_> { ) -> Result<()> { let table_name = identifier(cdv.table.clone())?; + // Extract the table. We cannot make progress otherwise. let table = tables .get_mut(&table_name) .ok_or_else(|| ValidationError::TableNotFound { table: cdv.table.clone(), })?; - if table.columns.len() <= cdv.col_id.idx() { + // Get the column that a default is being added to. + let Some(col) = table.columns.get_mut(cdv.col_id.idx()) else { return Err(ValidationError::ColumnNotFound { table: cdv.table.clone(), def: cdv.table.clone(), column: cdv.col_id, } .into()); - } + }; - let col = &mut table.columns[cdv.col_id.idx()]; - // First time we have a type for it, so decode it. + // First time the type of the default value is known, so decode it. let mut reader = &cdv.value[..]; let ty = WithTypespace::new(self.typespace, &col.ty); - let field_value = match ty.deserialize(Deserializer::new(&mut reader)) { - Ok(field_value) => Some(field_value), - Err(decode_error) => { - return Err(ValidationError::ColumnDefaultValueMalformed { + let field_value: Result = + ty.deserialize(Deserializer::new(&mut reader)).map_err(|decode_error| { + ValidationError::ColumnDefaultValueMalformed { table: cdv.table.clone(), col_id: cdv.col_id, err: decode_error, } - .into()) - } - }; + .into() + }); + // Ensure there's only one default value. if col.default_value.is_some() { return Err(ValidationError::MultipleColumnDefaultValues { table: cdv.table.clone(), @@ -400,7 +391,7 @@ impl ModuleValidator<'_> { } .into()); } - col.default_value = field_value.clone(); + col.default_value = field_value.ok(); Ok(()) } @@ -953,6 +944,20 @@ fn check_scheduled_reducers_exist( .collect_all_errors() } +fn default_values_work( + misc_exports: Vec, + validator: &mut ModuleValidator, + tables: &mut IdentifierMap, +) -> Result<()> { + misc_exports + .into_iter() + .map(|export| match export { + RawMiscModuleExportV9::ColumnDefaultValue(fdv) => validator.validate_column_default_value(tables, fdv), + _ => unimplemented!("unknown misc export"), + }) + .collect_all_errors::<()>() +} + #[cfg(test)] mod tests { use crate::def::validate::tests::{ From 608efaf98c7e22264f3eed44ee2def2daedfbc70 Mon Sep 17 00:00:00 2001 From: Shubham Mishra Date: Wed, 13 Aug 2025 22:38:55 +0530 Subject: [PATCH 5/5] More comments --- crates/lib/src/db/raw_def/v9.rs | 12 ++--- crates/schema/src/def.rs | 7 ++- crates/schema/src/def/validate/v9.rs | 76 +++++++++++++++++++--------- 3 files changed, 64 insertions(+), 31 deletions(-) diff --git a/crates/lib/src/db/raw_def/v9.rs b/crates/lib/src/db/raw_def/v9.rs index 07e0137e445..56518336e5d 100644 --- a/crates/lib/src/db/raw_def/v9.rs +++ b/crates/lib/src/db/raw_def/v9.rs @@ -366,18 +366,18 @@ pub enum RawMiscModuleExportV9 { ColumnDefaultValue(RawColumnDefaultValueV9), } -/// Marks a field as having a particular default. +/// Marks a particular table's column as having a particular default. #[derive(Debug, Clone, SpacetimeType)] #[sats(crate = crate)] #[cfg_attr(feature = "test", derive(PartialEq, Eq, PartialOrd, Ord))] pub struct RawColumnDefaultValueV9 { + /// Identifies which table that has the default value. + /// This corresponds to `name` in `RawTableDefV9`. pub table: RawIdentifier, - - /// Must be the index of a valid column within `ty`. + /// Identifies which column of `table` that has the default value. pub col_id: ColId, - - /// A BSATN-encoded [`AlgebraicValue`] valid at `ty`. - /// (We can't use `AlgebraicValue` directly because it isn't serializable!) + /// A BSATN-encoded [`AlgebraicValue`] valid at the table column's type. + /// (We cannot use `AlgebraicValue` directly as it isn't `Spacetimetype`.) pub value: Box<[u8]>, } diff --git a/crates/schema/src/def.rs b/crates/schema/src/def.rs index 6a63ddd69b1..1461dcca076 100644 --- a/crates/schema/src/def.rs +++ b/crates/schema/src/def.rs @@ -1116,7 +1116,7 @@ mod tests { true, ) .with_default_column_value(1, AlgebraicValue::Bool(false)) - .with_default_column_value(1, AlgebraicValue::U16(10)) + .with_default_column_value(1, AlgebraicValue::unit()) .finish(); let result: Result = old_builder.finish().try_into(); @@ -1126,5 +1126,10 @@ mod tests { result, ValidationError::ColumnDefaultValueMalformed { table, col_id, .. } => *table == apples.clone().into() && *col_id == ColId(1) ); + assert!(result.is_err_and(|e| e + .into_iter() + .filter(|e| matches!(e, ValidationError::ColumnDefaultValueMalformed { .. })) + .count() + == 2)) } } diff --git a/crates/schema/src/def/validate/v9.rs b/crates/schema/src/def/validate/v9.rs index ee32561ee82..6adbbf01b9a 100644 --- a/crates/schema/src/def/validate/v9.rs +++ b/crates/schema/src/def/validate/v9.rs @@ -80,7 +80,7 @@ pub fn validate(def: RawModuleDefV9) -> Result { .combine_errors() .and_then(|(mut tables, types, reducers)| { let sched_exists = check_scheduled_reducers_exist(&tables, &reducers); - let default_values_work = default_values_work(misc_exports, &mut validator, &mut tables); + let default_values_work = proccess_misc_exports(misc_exports, &validator, &mut tables); (sched_exists, default_values_work).combine_errors()?; Ok((tables, types, reducers)) @@ -348,21 +348,19 @@ impl ModuleValidator<'_> { } fn validate_column_default_value( - &mut self, - tables: &mut HashMap, - cdv: RawColumnDefaultValueV9, - ) -> Result<()> { + &self, + tables: &HashMap, + cdv: &RawColumnDefaultValueV9, + ) -> Result { let table_name = identifier(cdv.table.clone())?; // Extract the table. We cannot make progress otherwise. - let table = tables - .get_mut(&table_name) - .ok_or_else(|| ValidationError::TableNotFound { - table: cdv.table.clone(), - })?; + let table = tables.get(&table_name).ok_or_else(|| ValidationError::TableNotFound { + table: cdv.table.clone(), + })?; // Get the column that a default is being added to. - let Some(col) = table.columns.get_mut(cdv.col_id.idx()) else { + let Some(col) = table.columns.get(cdv.col_id.idx()) else { return Err(ValidationError::ColumnNotFound { table: cdv.table.clone(), def: cdv.table.clone(), @@ -383,17 +381,8 @@ impl ModuleValidator<'_> { } .into() }); - // Ensure there's only one default value. - if col.default_value.is_some() { - return Err(ValidationError::MultipleColumnDefaultValues { - table: cdv.table.clone(), - col_id: cdv.col_id, - } - .into()); - } - col.default_value = field_value.ok(); - Ok(()) + field_value } /// Validate a type definition. @@ -944,20 +933,59 @@ fn check_scheduled_reducers_exist( .collect_all_errors() } -fn default_values_work( +fn proccess_misc_exports( misc_exports: Vec, - validator: &mut ModuleValidator, + validator: &ModuleValidator, tables: &mut IdentifierMap, ) -> Result<()> { misc_exports .into_iter() .map(|export| match export { - RawMiscModuleExportV9::ColumnDefaultValue(fdv) => validator.validate_column_default_value(tables, fdv), + RawMiscModuleExportV9::ColumnDefaultValue(cdv) => process_column_default_value(&cdv, validator, tables), _ => unimplemented!("unknown misc export"), }) .collect_all_errors::<()>() } +fn process_column_default_value( + cdv: &RawColumnDefaultValueV9, + validator: &ModuleValidator, + tables: &mut IdentifierMap, +) -> Result<()> { + // Validate the default value + let validated_value = validator.validate_column_default_value(tables, cdv)?; + + let table_name = identifier(cdv.table.clone())?; + let table = tables + .get_mut(&table_name) + .ok_or_else(|| ValidationError::TableNotFound { + table: cdv.table.clone(), + })?; + + let column = table + .columns + .get_mut(cdv.col_id.idx()) + .ok_or_else(|| ValidationError::ColumnNotFound { + table: cdv.table.clone(), + def: cdv.table.clone(), + column: cdv.col_id, + })?; + + // Ensure there's only one default value. + if column.default_value.is_some() { + return Err(ValidationError::MultipleColumnDefaultValues { + table: cdv.table.clone(), + col_id: cdv.col_id, + } + .into()); + } + + // Set the default value + column.default_value = Some(validated_value); + + Ok(()) +} + #[cfg(test)] mod tests { use crate::def::validate::tests::{