We can catch some WC DB inconsistencies as soon as they happen by adding SQLite "trigger" functions that fire on adding or modifying rows, and throw an error if some condition is not met. This is especially useful in the NODES table because of its complex rules.
This patch is presented as a concept and not to apply as-is. It adds a couple of very simple checks, with which I caught the bug fixed in r1127069 and the test-bug fixed in r1127072. [[[ Index: subversion/libsvn_wc/wc-metadata.sql =================================================================== --- subversion/libsvn_wc/wc-metadata.sql (revision 1127430) +++ subversion/libsvn_wc/wc-metadata.sql (working copy) @@ -530,6 +530,24 @@ BEGIN WHERE checksum = OLD.checksum; END; +/* VERIFICATION */ + +/* Verify: on every NODES row: parent_relpath is parent of local_relpath */ +CREATE TRIGGER nn00 BEFORE INSERT ON NODES +WHEN NOT ((new.local_relpath = '' AND new.parent_relpath IS NULL) + OR (relpath_depth(new.local_relpath) + = relpath_depth(new.parent_relpath) + 1)) +BEGIN + SELECT RAISE(FAIL, 'WC DB validity check "nn00" failed'); +END; + +/* Verify: on every NODES row: its op-depth <= its own depth */ +CREATE TRIGGER nn01 BEFORE INSERT ON NODES +WHEN NOT new.op_depth <= relpath_depth(new.local_relpath) +BEGIN + SELECT RAISE(FAIL, 'WC DB validity check "nn01" failed'); +END; + -- STMT_CREATE_EXTERNALS CREATE TABLE EXTERNALS ( ]]] The real purpose here is to make it easy to add new and more complex checks and for them to run when we run the test suite. They need not necessarily be enabled in release builds, although that is an option. In this patch the trigger statements are in the main block in wc-metadata.sql, which works for the test suite but does not add them to existing WCs and does not easily allow them to be disabled in release mode. A proper patch would put these in 'wc-checks.sql' instead, and provide upgrade code. I'm still working on that. The patch presented here is for you to review and try out the idea if you want to. (These two triggers, and probably many that we would create later, depend on a custom SQLite function 'int relpath_depth(relpath)' which was implemented in r1127430. We may want to add some other basic relpath functions such as 'basename' and 'dirname' too.) - Julian