From b6c7176c13bcc115f9d2616cccc7298eba6574c7 Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Fri, 20 Mar 2026 03:48:40 +1300 Subject: [PATCH] fix: prevent metadata table from being dropped during orphan reconciliation When createCollection is called for the _metadata table and the table already exists, the orphan reconciliation code would drop and recreate it, destroying all collection metadata. This breaks upgrades where Database::create() is called on an existing database. The fix adds _metadata to the safe list alongside shared-tables checks, ensuring the metadata table is never treated as an orphan. --- src/Database/Database.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Database/Database.php b/src/Database/Database.php index ffb0ff4da..ac58d72f0 100644 --- a/src/Database/Database.php +++ b/src/Database/Database.php @@ -1796,8 +1796,10 @@ public function createCollection(string $id, array $attributes = [], array $inde $this->adapter->createCollection($id, $attributes, $indexes); $createdPhysicalTable = true; } catch (DuplicateException $e) { - if ($this->adapter->getSharedTables() - && ($id === self::METADATA || $this->adapter->exists($this->adapter->getDatabase(), $id))) { + if ($id === self::METADATA + || ($this->adapter->getSharedTables() + && $this->adapter->exists($this->adapter->getDatabase(), $id))) { + // The metadata table must never be dropped during reconciliation. // In shared-tables mode the physical table is reused across // tenants. A DuplicateException simply means the table already // exists for another tenant — not an orphan.