From 9cda61694957f2f0428779319f85f626578d0cf0 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 22 Feb 2010 14:18:55 +0000 Subject: * The database needs a trigger to get rid of self-references to prevent a foreign key constraint violation on the Refs table when deleting a path. --- src/libstore/local-store.cc | 12 ++++++++++-- src/libstore/schema.sql | 10 ++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc index 0823e785bda2..7df67555eeea 100644 --- a/src/libstore/local-store.cc +++ b/src/libstore/local-store.cc @@ -109,7 +109,11 @@ struct SQLiteStmtUse } ~SQLiteStmtUse() { - stmt.reset(); + try { + stmt.reset(); + } catch (...) { + ignoreException(); + } } }; @@ -798,6 +802,8 @@ void LocalStore::registerValidPaths(const ValidPathInfos & infos) void LocalStore::invalidatePath(const Path & path) { debug(format("invalidating path `%1%'") % path); + + SQLiteTxn txn(db); SQLiteStmtUse use(stmtInvalidatePath); @@ -807,7 +813,9 @@ void LocalStore::invalidatePath(const Path & path) throw SQLiteError(db, format("invalidating path `%1%' in database") % path); /* Note that the foreign key constraints on the Refs table take - care of deleting the references entries for `path'. */ + care of deleting the references entries for `path'. */ + + txn.commit(); } diff --git a/src/libstore/schema.sql b/src/libstore/schema.sql index 682ce5ed7b26..4adad34b700e 100644 --- a/src/libstore/schema.sql +++ b/src/libstore/schema.sql @@ -17,6 +17,16 @@ create table if not exists Refs ( create index if not exists IndexReferrer on Refs(referrer); create index if not exists IndexReference on Refs(reference); +-- Paths can refer to themselves, causing a tuple (N, N) in the Refs +-- table. This causes a deletion of the corresponding row in +-- ValidPaths to cause a foreign key constraint violation (due to `on +-- delete restrict' on the `reference' column). Therefore, explicitly +-- get rid of self-references. +create trigger DeleteSelfRefs before delete on ValidPaths + begin + delete from Refs where referrer = old.id and reference = old.id; + end; + create table if not exists DerivationOutputs ( drv integer not null, id text not null, -- symbolic output id, usually "out" -- cgit 1.4.1