]> granicus.if.org Git - python/commitdiff
Fixes SF bug # 778421
authorGregory P. Smith <greg@mad-scientist.com>
Thu, 26 Feb 2004 10:07:14 +0000 (10:07 +0000)
committerGregory P. Smith <greg@mad-scientist.com>
Thu, 26 Feb 2004 10:07:14 +0000 (10:07 +0000)
 * Fixed a bug in the compatibility interface set_location() method
   where it would not properly search to the next nearest key when
   used on BTree databases.  [SF bug id 788421]
 * Fixed a bug in the compatibility interface set_location() method
   where it could crash when looking up keys in a hash or recno
   format database due to an incorrect free().

Lib/bsddb/__init__.py
Lib/bsddb/test/test_basics.py
Lib/bsddb/test/test_compat.py
Modules/_bsddb.c

index 9c59b00b2c79c391a0626d1902ee66ad01cecb2c..90bf92bc5e591e1593d093d07d807ae178bf7155 100644 (file)
@@ -244,7 +244,7 @@ class _DBWithCursor(_iter_mixin):
     def set_location(self, key):
         self._checkOpen()
         self._checkCursor()
-        return self.dbc.set(key)
+        return self.dbc.set_range(key)
 
     def next(self):
         self._checkOpen()
index da7e18f8ae03285be721a7dde0b37fe5d2eeb0b0..09571ab26e6b4667ac5013b050817bc0cc5e78ce 100644 (file)
@@ -385,7 +385,12 @@ class BasicTestCase(unittest.TestCase):
             rec = c.set_range('011',dlen=0,doff=0)
             if verbose:
                 print "searched (partial) for '011', found: ", rec
-            if rec[1] != '': set.fail('expected empty data portion')
+            if rec[1] != '': self.fail('expected empty data portion')
+
+            ev = c.set_range('empty value')
+            if verbose:
+                print "search for 'empty value' returned", ev
+            if ev[1] != '': self.fail('empty value lookup failed')
 
         c.set('0499')
         c.delete()
index 12464ca72da25ac684aae93bdd94dfc3e3fa911d..b108db4c6a90225af3c4d7c7752282801092dd7d 100644 (file)
@@ -49,6 +49,10 @@ class CompatibilityTestCase(unittest.TestCase):
 
         assert getTest[1] == 'quick', 'data mismatch!'
 
+        rv = f.set_location(3)
+        if rv != (3, 'brown'):
+            self.fail('recno database set_location failed: '+repr(rv))
+
         f[25] = 'twenty-five'
         f.close()
         del f
@@ -83,7 +87,6 @@ class CompatibilityTestCase(unittest.TestCase):
         f.close()
 
 
-
     def do_bthash_test(self, factory, what):
         if verbose:
             print '\nTesting: ', what
@@ -103,13 +106,16 @@ class CompatibilityTestCase(unittest.TestCase):
         f['b'] = 'van'
         f['c'] = 'Rossum'
         f['d'] = 'invented'
+        # 'e' intentionally left out
         f['f'] = 'Python'
         if verbose:
             print '%s %s %s' % (f['a'], f['b'], f['c'])
 
         if verbose:
             print 'key ordering...'
-        f.set_location(f.first()[0])
+        start = f.set_location(f.first()[0])
+        if start != ('0', ''):
+            self.fail("incorrect first() result: "+repr(start))
         while 1:
             try:
                 rec = f.next()
@@ -122,6 +128,20 @@ class CompatibilityTestCase(unittest.TestCase):
 
         assert f.has_key('f'), 'Error, missing key!'
 
+        # test that set_location() returns the next nearest key, value
+        # on btree databases and raises KeyError on others.
+        if factory == btopen:
+            e = f.set_location('e')
+            if e != ('f', 'Python'):
+                self.fail('wrong key,value returned: '+repr(e))
+        else:
+            try:
+                e = f.set_location('e')
+            except KeyError:
+                pass
+            else:
+                self.fail("set_location on non-existant key did not raise KeyError")
+
         f.sync()
         f.close()
         # truth test
index a503a8030c02c3b7bfc742baed98b5a5a1ed75ef..fcfcbd4c009003eaec68c7a3c8fd718918942e82 100644 (file)
@@ -97,7 +97,7 @@
 #error "eek! DBVER can't handle minor versions > 9"
 #endif
 
-#define PY_BSDDB_VERSION "4.2.4"
+#define PY_BSDDB_VERSION "4.2.5"
 static char *rcs_id = "$Id$";
 
 
@@ -2940,7 +2940,15 @@ DBC_set_range(DBCursorObject* self, PyObject* args, PyObject* kwargs)
                                    data.data, data.size);
             break;
         }
-        FREE_DBT(key);
+        if (_DB_get_type(self->mydb) == DB_BTREE) {
+            /* the only time a malloced key is returned is when we
+             * call this on a BTree database because it performs
+             * partial matching and needs to return the real key.
+             * All others leave key untouched [where calling free()
+             * on it would often segfault].
+             */
+            FREE_DBT(key);
+        }
         FREE_DBT(data);
     }