summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGregory P. Smith <greg@mad-scientist.com>2004-02-26 10:07:14 (GMT)
committerGregory P. Smith <greg@mad-scientist.com>2004-02-26 10:07:14 (GMT)
commita7befda8d80d759cb88ef6732581860166ecf438 (patch)
tree0d67c57f5b0c9bf097378dd349f1100f2ca6f89b
parent904de5b7343994a7fcb2941ce094ab60da68afed (diff)
downloadcpython-a7befda8d80d759cb88ef6732581860166ecf438.zip
cpython-a7befda8d80d759cb88ef6732581860166ecf438.tar.gz
cpython-a7befda8d80d759cb88ef6732581860166ecf438.tar.bz2
Fixes SF bug # 778421
* 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().
-rw-r--r--Lib/bsddb/__init__.py2
-rw-r--r--Lib/bsddb/test/test_basics.py7
-rw-r--r--Lib/bsddb/test/test_compat.py24
-rw-r--r--Modules/_bsddb.c12
4 files changed, 39 insertions, 6 deletions
diff --git a/Lib/bsddb/__init__.py b/Lib/bsddb/__init__.py
index 9c59b00..90bf92b 100644
--- a/Lib/bsddb/__init__.py
+++ b/Lib/bsddb/__init__.py
@@ -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()
diff --git a/Lib/bsddb/test/test_basics.py b/Lib/bsddb/test/test_basics.py
index da7e18f..09571ab 100644
--- a/Lib/bsddb/test/test_basics.py
+++ b/Lib/bsddb/test/test_basics.py
@@ -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()
diff --git a/Lib/bsddb/test/test_compat.py b/Lib/bsddb/test/test_compat.py
index 12464ca..b108db4 100644
--- a/Lib/bsddb/test/test_compat.py
+++ b/Lib/bsddb/test/test_compat.py
@@ -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
diff --git a/Modules/_bsddb.c b/Modules/_bsddb.c
index a503a80..fcfcbd4 100644
--- a/Modules/_bsddb.c
+++ b/Modules/_bsddb.c
@@ -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);
}