Merge remote-tracking branch 'origin/datatable-roles-redesign-part-2' into datatable-roles-redesign-part-4

# Conflicts:
#	backend/windmill-common/src/workspaces.rs
This commit is contained in:
Diego Imbert
2026-09-17 15:22:45 +02:00
6 changed files with 178 additions and 11 deletions
@@ -2205,17 +2205,15 @@ async fn list_datatables(
Extension(db): Extension<DB>,
Path(w_id): Path<String>,
) -> JsonResult<Vec<DataTableListItem>> {
let names = list_datatable_names(&db, &w_id).await?;
// A pointer entry owns no database, so what it resolves to is the only truthful answer here.
// One that resolves to nothing — a pointer whose workspace was deleted — is dropped rather than
// listed with a database it does not have; what happened is named where it is actionable
// instead: by the delete that stranded it, and by any attempt to use it.
let resolved =
windmill_common::workspaces::resolve_workspace_governing_datatables(&db, &w_id).await?;
let mut items = Vec::with_capacity(names.len());
for name in names {
// A pointer entry owns no database, so what it resolves to is the only truthful answer
// here. One that resolves to nothing — a pointer whose workspace was deleted — is dropped
// rather than listed with a database it does not have; what happened is named where it is
// actionable instead: by the delete that stranded it, and by any attempt to use it.
let Ok(governing) = resolve_governing_datatable(&db, &w_id, &name).await else {
continue;
};
let mut items = Vec::with_capacity(resolved.len());
for (name, governing) in resolved {
let database = governing
.datatable
.database
@@ -8662,6 +8660,14 @@ async fn create_workspace_fork(
.execute(&mut *tx)
.await?;
// The pointers this fork writes to the parent's data tables stay invisible until it commits, so
// a rename of one of them cannot carry them. Holding the parent's settings row makes such a
// rename wait for this commit, and makes the copy below read one that committed first.
sqlx::query("SELECT 1 FROM workspace_settings WHERE workspace_id = $1 FOR SHARE")
.bind(&parent_workspace_id)
.execute(&mut *tx)
.await?;
// Clone all data from the parent workspace using Rust implementation
if let Err(e) =
clone_workspace_data(&mut tx, &db, &parent_workspace_id, &forked_id, &authed).await