Skip to content

Commit 59d4f96

Browse files
ldanilekConvex, Inc.
authored andcommitted
allow table number reuse across components (#27509)
effectively revert #26245 now that we've aligned on the direction. GitOrigin-RevId: e3f2953cc11d29793ca6e8ddf71ab8269a3a10b1
1 parent c192aaa commit 59d4f96

File tree

4 files changed

+50
-32
lines changed

4 files changed

+50
-32
lines changed

crates/database/src/bootstrap_model/table.rs

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -247,23 +247,35 @@ impl<'a, RT: Runtime> TableModel<'a, RT> {
247247

248248
// Checks both _tables and _virtual_tables to find a non-conflicting table
249249
// number
250-
pub async fn next_user_table_number(&mut self) -> anyhow::Result<TableNumber> {
251-
self.next_table_number(false).await
250+
pub async fn next_user_table_number(
251+
&mut self,
252+
namespace: TableNamespace,
253+
) -> anyhow::Result<TableNumber> {
254+
self.next_table_number(false, namespace).await
252255
}
253256

254-
pub async fn next_system_table_number(&mut self) -> anyhow::Result<TableNumber> {
255-
self.next_table_number(true).await
257+
pub async fn next_system_table_number(
258+
&mut self,
259+
namespace: TableNamespace,
260+
) -> anyhow::Result<TableNumber> {
261+
self.next_table_number(true, namespace).await
256262
}
257263

258-
async fn next_table_number(&mut self, is_system: bool) -> anyhow::Result<TableNumber> {
264+
async fn next_table_number(
265+
&mut self,
266+
is_system: bool,
267+
namespace: TableNamespace,
268+
) -> anyhow::Result<TableNumber> {
259269
let occupied_table_numbers = {
260270
let mut occupied_table_numbers = BTreeSet::new();
261271
let tables_query = Query::full_table_scan(TABLES_TABLE.clone(), Order::Asc);
262272
let mut query_stream =
263273
ResolvedQuery::new(self.tx, TableNamespace::Global, tables_query)?;
264274
while let Some(table_metadata) = query_stream.next(self.tx, None).await? {
265275
let parsed_metadata: ParsedDocument<TableMetadata> = table_metadata.try_into()?;
266-
occupied_table_numbers.insert(parsed_metadata.number);
276+
if parsed_metadata.namespace == namespace {
277+
occupied_table_numbers.insert(parsed_metadata.number);
278+
}
267279
}
268280
let virtual_tables_query =
269281
Query::full_table_scan(VIRTUAL_TABLES_TABLE.clone(), Order::Asc);
@@ -481,7 +493,7 @@ impl<'a, RT: Runtime> TableModel<'a, RT> {
481493
);
482494
table_number
483495
} else {
484-
self.next_user_table_number().await?
496+
self.next_user_table_number(namespace).await?
485497
};
486498
let table_metadata =
487499
TableMetadata::new_with_state(namespace, table.clone(), table_number, state);
@@ -733,18 +745,17 @@ mod tests {
733745
async fn test_next_table_number(rt: TestRuntime) -> anyhow::Result<()> {
734746
let mut tx = new_tx(rt).await?;
735747
let mut model = TableModel::new(&mut tx);
748+
let namespace = TableNamespace::test_user();
736749

737-
let next_table_number: u32 = model.next_user_table_number().await?.into();
750+
let next_table_number: u32 = model.next_user_table_number(namespace).await?.into();
738751
assert_eq!(
739752
(NUM_RESERVED_SYSTEM_TABLE_NUMBERS + 1) as usize,
740753
next_table_number as usize
741754
);
742755

743756
let table_name = TableName::from_str("my_table")?;
744-
model
745-
.insert_table_metadata(TableNamespace::test_user(), &table_name)
746-
.await?;
747-
let new_next_table_number: u32 = model.next_user_table_number().await?.into();
757+
model.insert_table_metadata(namespace, &table_name).await?;
758+
let new_next_table_number: u32 = model.next_user_table_number(namespace).await?.into();
748759
assert_eq!(next_table_number + 1, new_next_table_number);
749760
Ok(())
750761
}

crates/database/src/table_registry.rs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ impl TableRegistry {
107107
if self.table_exists(metadata.namespace, &metadata.name) {
108108
anyhow::bail!("Tried to create duplicate table {new_value}");
109109
}
110-
self.validate_table_number(metadata.number)?;
110+
self.validate_table_number(metadata.namespace, metadata.number)?;
111111
}
112112
Some(TableUpdate {
113113
namespace: metadata.namespace,
@@ -195,7 +195,7 @@ impl TableRegistry {
195195
{
196196
anyhow::bail!("Tried to create duplicate virtual table {new_value}");
197197
}
198-
self.validate_table_number(metadata.number)?;
198+
self.validate_table_number(metadata.namespace, metadata.number)?;
199199
virtual_table_creation =
200200
Some((metadata.namespace, metadata.number, metadata.name));
201201
},
@@ -211,19 +211,23 @@ impl TableRegistry {
211211
Ok(update)
212212
}
213213

214-
fn validate_table_number(&self, table_number: TableNumber) -> anyhow::Result<()> {
214+
fn validate_table_number(
215+
&self,
216+
namespace: TableNamespace,
217+
table_number: TableNumber,
218+
) -> anyhow::Result<()> {
215219
anyhow::ensure!(
216220
!self
217221
.table_mapping
218-
.iter()
219-
.any(|(_, _, number, _)| number == table_number),
222+
.namespace(namespace)
223+
.table_number_exists()(table_number),
220224
"Cannot add a table with table number {table_number} since it already exists in the \
221225
table mapping"
222226
);
223227
anyhow::ensure!(
224228
!self
225229
.virtual_table_mapping
226-
.namespace(TableNamespace::TODO())
230+
.namespace(namespace)
227231
.number_exists(table_number),
228232
"Cannot add a table with table number {table_number} since it already exists in the \
229233
virtual table mapping"

crates/database/src/transaction.rs

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ use common::{
2424
TABLES_TABLE,
2525
},
2626
},
27-
components::COMPONENTS_ENABLED,
2827
document::{
2928
CreationTime,
3029
DocumentUpdate,
@@ -642,21 +641,19 @@ impl<RT: Runtime> Transaction<RT> {
642641

643642
async fn table_number_for_system_table(
644643
&mut self,
644+
namespace: TableNamespace,
645645
table_name: &TableName,
646646
default_table_number: Option<TableNumber>,
647647
) -> anyhow::Result<TableNumber> {
648648
Ok(if let Some(default_table_number) = default_table_number {
649-
let existing_name = self
650-
.table_mapping()
651-
.iter()
652-
.find(|(_, _, table_number, _)| *table_number == default_table_number);
653-
let table_number = if let Some((_, _, _, existing_name)) = existing_name {
649+
let existing_name =
650+
self.table_mapping().namespace(namespace).number_to_name()(default_table_number)
651+
.ok();
652+
let table_number = if let Some(existing_name) = existing_name {
654653
// In tests, have a hard failure on conflicting default table numbers. In
655654
// real system, have a looser fallback where we pick
656655
// another table number.
657-
// Also allow this when components are enabled, because system tables in
658-
// different namespaces have different table numbers.
659-
if !*COMPONENTS_ENABLED && cfg!(any(test, feature = "testing")) {
656+
if cfg!(any(test, feature = "testing")) {
660657
anyhow::bail!(
661658
"{default_table_number} is used by both {table_name} and {existing_name}"
662659
);
@@ -665,7 +662,9 @@ impl<RT: Runtime> Transaction<RT> {
665662
// If the table_number requested is taken, just pick a higher table number.
666663
// This might be true for older backends that have lower-numbered system
667664
// tables.
668-
TableModel::new(self).next_system_table_number().await?
665+
TableModel::new(self)
666+
.next_system_table_number(namespace)
667+
.await?
669668
} else {
670669
default_table_number
671670
};
@@ -680,7 +679,9 @@ impl<RT: Runtime> Transaction<RT> {
680679
);
681680
table_number
682681
} else {
683-
TableModel::new(self).next_system_table_number().await?
682+
TableModel::new(self)
683+
.next_system_table_number(namespace)
684+
.await?
684685
})
685686
}
686687

@@ -701,7 +702,7 @@ impl<RT: Runtime> Transaction<RT> {
701702
let is_new = !TableModel::new(self).table_exists(namespace, table_name);
702703
if is_new {
703704
let table_number = self
704-
.table_number_for_system_table(table_name, default_table_number)
705+
.table_number_for_system_table(namespace, table_name, default_table_number)
705706
.await?;
706707
let metadata = TableMetadata::new(namespace, table_name.clone(), table_number);
707708
let table_doc_id = SystemMetadataModel::new_global(self)
@@ -750,7 +751,7 @@ impl<RT: Runtime> Transaction<RT> {
750751
.name_exists(table_name);
751752
if is_new {
752753
let table_number = self
753-
.table_number_for_system_table(table_name, default_table_number)
754+
.table_number_for_system_table(namespace, table_name, default_table_number)
754755
.await?;
755756
let metadata = VirtualTableMetadata::new(namespace, table_name.clone(), table_number);
756757
let table_doc_id = SystemMetadataModel::new_global(self)

crates/isolate/src/tests/user_error.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,9 @@ async fn test_nonexistent_table(rt: TestRuntime) -> anyhow::Result<()> {
149149
t.create_index("boatVotes.by_boat", "boat").await?;
150150
t.backfill_indexes().await?;
151151
let mut tx = t.database.begin(Identity::system()).await?;
152-
let table_number = TableModel::new(&mut tx).next_user_table_number().await?;
152+
let table_number = TableModel::new(&mut tx)
153+
.next_user_table_number(TableNamespace::test_user())
154+
.await?;
153155
let nonexistent_id = DeveloperDocumentId::new(table_number, InternalId::MIN);
154156
t.mutation(
155157
"userError:nonexistentTable",

0 commit comments

Comments
 (0)