[Zodb-checkins] SVN: ZODB/branches/bug1734/src/ Tentative fix.

Tim Peters tim.one at comcast.net
Tue Mar 22 19:33:04 EST 2005


Log message for revision 29645:
  Tentative fix.
  

Changed:
  U   ZODB/branches/bug1734/src/BTrees/MergeTemplate.c
  U   ZODB/branches/bug1734/src/BTrees/tests/testConflict.py
  U   ZODB/branches/bug1734/src/ZODB/POSException.py

-=-
Modified: ZODB/branches/bug1734/src/BTrees/MergeTemplate.c
===================================================================
--- ZODB/branches/bug1734/src/BTrees/MergeTemplate.c	2005-03-22 23:30:06 UTC (rev 29644)
+++ ZODB/branches/bug1734/src/BTrees/MergeTemplate.c	2005-03-23 00:33:03 UTC (rev 29645)
@@ -70,7 +70,9 @@
  * However, it's not OK for s2 and s3 to, between them, end up deleting all
  * the keys.  This is a higher-level constraint, due to that the caller of
  * bucket_merge() doesn't have enough info to unlink the resulting empty
- * bucket from its BTree correctly.
+ * bucket from its BTree correctly.  It's also not OK if s2 or s3 are empty,
+ * because the transaction that emptied the bucket unlinked the bucket from
+ * the tree, and nothing we do here can get it linked back in again.
  *
  * Key insertion:  s2 or s3 can add a new key, provided the other transaction
  * doesn't insert the same key.  It's not OK even if they insert the same
@@ -115,6 +117,13 @@
   if (i3.next(&i3) < 0)
       goto err;
 
+  /* If either "after" bucket was empty, punt. */
+  if (i2.position < 0 || i3.position < 0)
+    {
+      merge_error(i1.position, i2.position, i3.position, 12);
+      goto err;
+    }
+
   /* Consult zodb/btrees/interfaces.py for the meaning of the last
    * argument passed to merge_error().
    */

Modified: ZODB/branches/bug1734/src/BTrees/tests/testConflict.py
===================================================================
--- ZODB/branches/bug1734/src/BTrees/tests/testConflict.py	2005-03-22 23:30:06 UTC (rev 29644)
+++ ZODB/branches/bug1734/src/BTrees/tests/testConflict.py	2005-03-23 00:33:03 UTC (rev 29645)
@@ -178,7 +178,7 @@
 
         test_merge(base, b1, b2, bm, 'merge insert from empty')
 
-    def testMergeEmptyAndFill(self):
+    def testFailMergeEmptyAndFill(self):
         base, b1, b2, bm, e1, e2, items = self._setupConflict()
 
         b1.clear()
@@ -186,7 +186,7 @@
         b2.update(e2)
         bm.update(e2)
 
-        test_merge(base, b1, b2, bm, 'merge insert from empty')
+        test_merge(base, b1, b2, bm, 'merge insert from empty', should_fail=1)
 
     def testMergeEmpty(self):
         base, b1, b2, bm, e1, e2, items = self._setupConflict()
@@ -275,7 +275,7 @@
 
         test_merge(base, b1, b2, bm, 'merge insert from empty')
 
-    def testMergeEmptyAndFill(self):
+    def testFailMergeEmptyAndFill(self):
         base, b1, b2, bm, e1, e2, items = self._setupConflict()
 
         b1.clear()
@@ -283,7 +283,7 @@
         b2.update(e2)
         bm.update(e2)
 
-        test_merge(base, b1, b2, bm, 'merge insert from empty')
+        test_merge(base, b1, b2, bm, 'merge insert from empty', should_fail=1)
 
     def testMergeEmpty(self):
         base, b1, b2, bm, e1, e2, items = self._setupConflict()
@@ -810,7 +810,6 @@
             self.assert_(str(detail).startswith('database conflict error'))
             transaction.abort()
         else:
-            print list(copy.items())
             self.fail("expected ConflictError")
 
 

Modified: ZODB/branches/bug1734/src/ZODB/POSException.py
===================================================================
--- ZODB/branches/bug1734/src/ZODB/POSException.py	2005-03-22 23:30:06 UTC (rev 29644)
+++ ZODB/branches/bug1734/src/ZODB/POSException.py	2005-03-23 00:33:03 UTC (rev 29645)
@@ -187,6 +187,9 @@
 
             # 11; conflicting changes in an internal BTree node
             'Conflicting changes in an internal BTree node',
+
+            # 12; i2 or i3 was empty
+            'Empty bucket in a transaction',
             ]
 
     def __init__(self, p1, p2, p3, reason):



More information about the Zodb-checkins mailing list