summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEtienne Petrel <etienne.petrel@mongodb.com>2022-09-22 01:58:37 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-09-22 02:27:43 +0000
commitc99b24eef4cd1e7e86548f311c06c358ade021c4 (patch)
tree207db9a17a0ff7f0856688642c8856b302dfc801
parent3be23d6a1dcce377607e9ae24309e4dd5c7dd5f4 (diff)
downloadmongo-c99b24eef4cd1e7e86548f311c06c358ade021c4.tar.gz
Import wiredtiger: 132e8a3ba5cc8ab45dfcbc1ae904b2e5dd1be237 from branch mongodb-master
ref: bb5c03d590..132e8a3ba5 for: 6.2.0-rc0 WT-9851 Support bounded cursor next and prev traversal in FLCS (#8273)
-rw-r--r--src/third_party/wiredtiger/import.data2
-rw-r--r--src/third_party/wiredtiger/src/btree/bt_curnext.c17
-rw-r--r--src/third_party/wiredtiger/src/btree/bt_curprev.c20
-rw-r--r--src/third_party/wiredtiger/src/btree/bt_cursor.c48
-rw-r--r--src/third_party/wiredtiger/src/cursor/cur_std.c3
-rw-r--r--src/third_party/wiredtiger/test/suite/test_cursor_bound02.py26
-rw-r--r--src/third_party/wiredtiger/test/suite/test_cursor_bound03.py5
-rw-r--r--src/third_party/wiredtiger/test/suite/test_cursor_bound04.py17
-rw-r--r--src/third_party/wiredtiger/test/suite/wtbound.py35
9 files changed, 121 insertions, 52 deletions
diff --git a/src/third_party/wiredtiger/import.data b/src/third_party/wiredtiger/import.data
index 120590819ed..f7e0e6da729 100644
--- a/src/third_party/wiredtiger/import.data
+++ b/src/third_party/wiredtiger/import.data
@@ -2,5 +2,5 @@
"vendor": "wiredtiger",
"github": "wiredtiger/wiredtiger.git",
"branch": "mongodb-master",
- "commit": "bb5c03d59037747b3c477bb58e4c82eb961e5589"
+ "commit": "132e8a3ba5cc8ab45dfcbc1ae904b2e5dd1be237"
}
diff --git a/src/third_party/wiredtiger/src/btree/bt_curnext.c b/src/third_party/wiredtiger/src/btree/bt_curnext.c
index 2b99c6fbae3..1dc6b86854c 100644
--- a/src/third_party/wiredtiger/src/btree/bt_curnext.c
+++ b/src/third_party/wiredtiger/src/btree/bt_curnext.c
@@ -13,8 +13,9 @@
* Return the next entry on the append list.
*/
static inline int
-__cursor_fix_append_next(WT_CURSOR_BTREE *cbt, bool newpage, bool restart)
+__cursor_fix_append_next(WT_CURSOR_BTREE *cbt, bool newpage, bool restart, bool *key_out_of_boundsp)
{
+ WT_DECL_RET;
WT_SESSION_IMPL *session;
session = CUR2S(cbt);
@@ -38,7 +39,9 @@ __cursor_fix_append_next(WT_CURSOR_BTREE *cbt, bool newpage, bool restart)
* it to 1, which is correct.
*/
__cursor_set_recno(cbt, cbt->recno + 1);
-
+ if ((ret = __wt_btcur_bounds_early_exit(session, cbt, true, key_out_of_boundsp)) == WT_NOTFOUND)
+ WT_STAT_CONN_DATA_INCR(session, cursor_bounds_next_early_exit);
+ WT_RET(ret);
/*
* Fixed-width column store appends are inherently non-transactional. Even a non-visible update
* by a concurrent or aborted transaction changes the effective end of the data. The effect is
@@ -75,8 +78,9 @@ restart_read:
* Move to the next, fixed-length column-store item.
*/
static inline int
-__cursor_fix_next(WT_CURSOR_BTREE *cbt, bool newpage, bool restart)
+__cursor_fix_next(WT_CURSOR_BTREE *cbt, bool newpage, bool restart, bool *key_out_of_boundsp)
{
+ WT_DECL_RET;
WT_PAGE *page;
WT_SESSION_IMPL *session;
@@ -107,6 +111,9 @@ __cursor_fix_next(WT_CURSOR_BTREE *cbt, bool newpage, bool restart)
new_page:
restart_read:
+ if ((ret = __wt_btcur_bounds_early_exit(session, cbt, true, key_out_of_boundsp)) == WT_NOTFOUND)
+ WT_STAT_CONN_DATA_INCR(session, cursor_bounds_next_early_exit);
+ WT_RET(ret);
/* We only have one slot. */
cbt->slot = 0;
@@ -833,7 +840,7 @@ __wt_btcur_next_prefix(WT_CURSOR_BTREE *cbt, WT_ITEM *prefix, bool truncating)
WT_ASSERT(session, page != NULL);
switch (page->type) {
case WT_PAGE_COL_FIX:
- ret = __cursor_fix_append_next(cbt, newpage, restart);
+ ret = __cursor_fix_append_next(cbt, newpage, restart, &key_out_of_bounds);
break;
case WT_PAGE_COL_VAR:
ret = __cursor_var_append_next(cbt, newpage, restart, &skipped, &key_out_of_bounds);
@@ -859,7 +866,7 @@ __wt_btcur_next_prefix(WT_CURSOR_BTREE *cbt, WT_ITEM *prefix, bool truncating)
} else if (page != NULL) {
switch (page->type) {
case WT_PAGE_COL_FIX:
- ret = __cursor_fix_next(cbt, newpage, restart);
+ ret = __cursor_fix_next(cbt, newpage, restart, &key_out_of_bounds);
break;
case WT_PAGE_COL_VAR:
ret = __cursor_var_next(cbt, newpage, restart, &skipped, &key_out_of_bounds);
diff --git a/src/third_party/wiredtiger/src/btree/bt_curprev.c b/src/third_party/wiredtiger/src/btree/bt_curprev.c
index 20a0172ba7e..07d0053db65 100644
--- a/src/third_party/wiredtiger/src/btree/bt_curprev.c
+++ b/src/third_party/wiredtiger/src/btree/bt_curprev.c
@@ -120,8 +120,9 @@ restart:
* Return the previous fixed-length entry on the append list.
*/
static inline int
-__cursor_fix_append_prev(WT_CURSOR_BTREE *cbt, bool newpage, bool restart)
+__cursor_fix_append_prev(WT_CURSOR_BTREE *cbt, bool newpage, bool restart, bool *key_out_of_boundsp)
{
+ WT_DECL_RET;
WT_SESSION_IMPL *session;
session = CUR2S(cbt);
@@ -184,6 +185,11 @@ __cursor_fix_append_prev(WT_CURSOR_BTREE *cbt, bool newpage, bool restart)
else
__cursor_set_recno(cbt, cbt->recno - 1);
+ if ((ret = __wt_btcur_bounds_early_exit(session, cbt, false, key_out_of_boundsp)) ==
+ WT_NOTFOUND)
+ WT_STAT_CONN_DATA_INCR(session, cursor_bounds_prev_early_exit);
+ WT_RET(ret);
+
if (F_ISSET(&cbt->iface, WT_CURSTD_KEY_ONLY))
return (0);
@@ -218,8 +224,9 @@ restart_read:
* Move to the previous, fixed-length column-store item.
*/
static inline int
-__cursor_fix_prev(WT_CURSOR_BTREE *cbt, bool newpage, bool restart)
+__cursor_fix_prev(WT_CURSOR_BTREE *cbt, bool newpage, bool restart, bool *key_out_of_boundsp)
{
+ WT_DECL_RET;
WT_PAGE *page;
WT_SESSION_IMPL *session;
@@ -250,6 +257,11 @@ __cursor_fix_prev(WT_CURSOR_BTREE *cbt, bool newpage, bool restart)
new_page:
restart_read:
+ if ((ret = __wt_btcur_bounds_early_exit(session, cbt, false, key_out_of_boundsp)) ==
+ WT_NOTFOUND)
+ WT_STAT_CONN_DATA_INCR(session, cursor_bounds_prev_early_exit);
+ WT_RET(ret);
+
/* We only have one slot. */
cbt->slot = 0;
@@ -781,7 +793,7 @@ __wt_btcur_prev(WT_CURSOR_BTREE *cbt, bool truncating)
WT_ASSERT(session, page != NULL);
switch (page->type) {
case WT_PAGE_COL_FIX:
- ret = __cursor_fix_append_prev(cbt, newpage, restart);
+ ret = __cursor_fix_append_prev(cbt, newpage, restart, &key_out_of_bounds);
break;
case WT_PAGE_COL_VAR:
ret = __cursor_var_append_prev(cbt, newpage, restart, &skipped, &key_out_of_bounds);
@@ -800,7 +812,7 @@ __wt_btcur_prev(WT_CURSOR_BTREE *cbt, bool truncating)
if (page != NULL) {
switch (page->type) {
case WT_PAGE_COL_FIX:
- ret = __cursor_fix_prev(cbt, newpage, restart);
+ ret = __cursor_fix_prev(cbt, newpage, restart, &key_out_of_bounds);
break;
case WT_PAGE_COL_VAR:
ret = __cursor_var_prev(cbt, newpage, restart, &skipped, &key_out_of_bounds);
diff --git a/src/third_party/wiredtiger/src/btree/bt_cursor.c b/src/third_party/wiredtiger/src/btree/bt_cursor.c
index 40d9337c1d6..9f294f18f2f 100644
--- a/src/third_party/wiredtiger/src/btree/bt_cursor.c
+++ b/src/third_party/wiredtiger/src/btree/bt_cursor.c
@@ -300,21 +300,24 @@ __wt_cursor_valid(WT_CURSOR_BTREE *cbt, WT_ITEM *key, uint64_t recno, bool *vali
* update that's been deleted is not a valid key/value pair).
*/
if (cbt->ins != NULL) {
- if (WT_CURSOR_BOUNDS_SET(&cbt->iface)) {
+ if (btree->type == BTREE_ROW && WT_CURSOR_BOUNDS_SET(&cbt->iface) && key == NULL) {
/* Get the insert list key. */
- if (key == NULL && btree->type == BTREE_ROW) {
- tmp_key.data = WT_INSERT_KEY(cbt->ins);
- tmp_key.size = WT_INSERT_KEY_SIZE(cbt->ins);
- WT_RET(__btcur_bounds_contains_key(
- session, &cbt->iface, &tmp_key, WT_RECNO_OOB, &key_out_of_bounds, NULL));
- } else
- WT_RET(__btcur_bounds_contains_key(
- session, &cbt->iface, key, cbt->recno, &key_out_of_bounds, NULL));
-
- /* The key value pair we were trying to return weren't within the given bounds. */
- if (key_out_of_bounds)
- return (0);
+ tmp_key.data = WT_INSERT_KEY(cbt->ins);
+ tmp_key.size = WT_INSERT_KEY_SIZE(cbt->ins);
}
+ /*
+ * A number of different scenarios are handled here, we can have a key provided to the
+ * function for row-store. If there isn't a key for row-store then we need to get it from
+ * the insert list. The key held on the cursor isn't considered here. Additionally column
+ * store is handled here by passing the recno.
+ */
+ WT_RET(__btcur_bounds_contains_key(session, &cbt->iface, key == NULL ? &tmp_key : key,
+ cbt->recno, &key_out_of_bounds, NULL));
+
+ /* The key value pair we were trying to return weren't within the given bounds. */
+ if (key_out_of_bounds)
+ return (0);
+
WT_RET(__wt_txn_read_upd_list(session, cbt, cbt->ins->upd));
if (cbt->upd_value->type != WT_UPDATE_INVALID) {
if (cbt->upd_value->type == WT_UPDATE_TOMBSTONE)
@@ -325,6 +328,19 @@ __wt_cursor_valid(WT_CURSOR_BTREE *cbt, WT_ITEM *key, uint64_t recno, bool *vali
}
/*
+ * The previous call to the contains key function handles insert list scenarios. If we don't
+ * have an insert list then we should check again against the recno. We can't check for
+ * row-store here as the key is extracted later in the function.
+ */
+ if (btree->type != BTREE_ROW) {
+ WT_RET(__btcur_bounds_contains_key(
+ session, &cbt->iface, NULL, cbt->recno, &key_out_of_bounds, NULL));
+ /* The key value pair we were trying to return weren't within the given bounds. */
+ if (key_out_of_bounds)
+ return (0);
+ }
+
+ /*
* If we don't have an insert object, or in the case of column-store, there's an insert object
* but no update was visible to us and the key on the page is the same as the insert object's
* key, and the slot as set by the search function is valid, we can use the original page
@@ -380,12 +396,6 @@ __wt_cursor_valid(WT_CURSOR_BTREE *cbt, WT_ITEM *key, uint64_t recno, bool *vali
if (__wt_cell_type(cell) == WT_CELL_DEL)
return (0);
- WT_RET(__btcur_bounds_contains_key(
- session, &cbt->iface, NULL, cbt->recno, &key_out_of_bounds, NULL));
- /* The key value pair we were trying to return weren't within the given bounds. */
- if (key_out_of_bounds)
- return (0);
-
/*
* Check for an update. For column store, modifications are handled with insert lists, so an
* insert can have the same key as an on-page or history store object. Setting update here,
diff --git a/src/third_party/wiredtiger/src/cursor/cur_std.c b/src/third_party/wiredtiger/src/cursor/cur_std.c
index b047c06221c..4afd6533cf1 100644
--- a/src/third_party/wiredtiger/src/cursor/cur_std.c
+++ b/src/third_party/wiredtiger/src/cursor/cur_std.c
@@ -1187,9 +1187,6 @@ __wt_cursor_bound(WT_CURSOR *cursor, const char *config)
CURSOR_API_CALL_CONF(cursor, session, bound, config, cfg, NULL);
- if (CUR2BT(cursor)->type == BTREE_COL_FIX)
- WT_ERR_MSG(session, EINVAL, "setting bounds is not compatible with fixed column store.");
-
if (F_ISSET(cursor, WT_CURSTD_PREFIX_SEARCH))
WT_ERR_MSG(session, EINVAL, "setting bounds is not compatible with prefix search.");
diff --git a/src/third_party/wiredtiger/test/suite/test_cursor_bound02.py b/src/third_party/wiredtiger/test/suite/test_cursor_bound02.py
index 459c9aabd85..f6a73acfea7 100644
--- a/src/third_party/wiredtiger/test/suite/test_cursor_bound02.py
+++ b/src/third_party/wiredtiger/test/suite/test_cursor_bound02.py
@@ -46,6 +46,7 @@ class test_cursor_bound02(bound_base):
key_formats = [
('string', dict(key_format='S')),
('var', dict(key_format='r')),
+ ('fix', dict(key_format='r')),
('int', dict(key_format='i')),
('bytes', dict(key_format='u')),
('composite_string', dict(key_format='SSS')),
@@ -55,6 +56,7 @@ class test_cursor_bound02(bound_base):
value_formats = [
('string', dict(value_format='S')),
+ ('fix-byte', dict(value_format='8t')),
('complex-string', dict(value_format='SS')),
]
@@ -67,8 +69,10 @@ class test_cursor_bound02(bound_base):
def test_bound_api(self):
uri = self.uri + self.file_name
create_params = 'value_format={},key_format={}'.format(self.value_format, self.key_format)
- if self.use_colgroup:
+ if self.use_colgroup and self.value_format != '8t':
create_params += self.gen_colgroup_create_param()
+ else:
+ self.use_colgroup = False
self.session.create(uri, create_params)
# Add in column groups.
@@ -138,10 +142,15 @@ class test_cursor_bound02(bound_base):
def test_bound_api_reset(self):
+ # Fixed length bit arrays don't work well with colgroups.
+ if (self.value_format == '8t' and self.use_colgroup):
+ return
uri = self.uri + self.file_name
create_params = 'value_format={},key_format={}'.format(self.value_format, self.key_format)
- if self.use_colgroup:
+ if self.use_colgroup and self.value_format != '8t':
create_params += self.gen_colgroup_create_param()
+ else:
+ self.use_colgroup = False
self.session.create(uri, create_params)
# Add in column groups.
if self.use_colgroup:
@@ -164,7 +173,7 @@ class test_cursor_bound02(bound_base):
cursor.reset()
self.assertEqual(self.set_bounds(cursor, 99, "lower"), 0)
- # Test bound API: Test that cursor reset works the clearing bounds both ways.
+ # Test bound API: Test that cursor reset works the clearing bounds both ways.
self.assertEqual(self.set_bounds(cursor, 50, "lower"), 0)
cursor.reset()
self.assertEqual(self.set_bounds(cursor, 20, "lower"), 0)
@@ -191,10 +200,15 @@ class test_cursor_bound02(bound_base):
cursor.reset()
def test_bound_api_clear(self):
+ # Fixed length bit arrays don't work well with colgroups.
+ if (self.value_format == '8t' and self.use_colgroup):
+ return
uri = self.uri + self.file_name
create_params = 'value_format={},key_format={}'.format(self.value_format, self.key_format)
- if self.use_colgroup:
+ if self.use_colgroup and self.value_format != '8t':
create_params += self.gen_colgroup_create_param()
+ else:
+ self.use_colgroup = False
self.session.create(uri, create_params)
# Add in column groups.
if self.use_colgroup:
@@ -213,12 +227,12 @@ class test_cursor_bound02(bound_base):
self.assertEqual(cursor.bound("action=clear,bound=lower"), 0)
self.assertEqual(self.set_bounds(cursor, 10, "upper"), 0)
- # Test bound API: Test that clearing the upper bound works.
+ # Test bound API: Test that clearing the upper bound works.
self.assertRaisesWithMessage(wiredtiger.WiredTigerError, lambda: self.set_bounds(cursor, 99, "lower"), '/Invalid argument/')
self.assertEqual(cursor.bound("action=clear,bound=upper"), 0)
self.assertEqual(self.set_bounds(cursor, 99, "lower"), 0)
- # Test bound API: Test that clearing both of the bounds works.
+ # Test bound API: Test that clearing both of the bounds works.
cursor.reset()
self.assertEqual(self.set_bounds(cursor, 50, "upper"), 0)
self.assertEqual(cursor.bound("action=clear"), 0)
diff --git a/src/third_party/wiredtiger/test/suite/test_cursor_bound03.py b/src/third_party/wiredtiger/test/suite/test_cursor_bound03.py
index fcbbb7e4b78..3e7daa3e5fb 100644
--- a/src/third_party/wiredtiger/test/suite/test_cursor_bound03.py
+++ b/src/third_party/wiredtiger/test/suite/test_cursor_bound03.py
@@ -43,8 +43,8 @@ class test_cursor_bound03(bound_base):
]
key_formats = [
- ('string', dict(key_format='S')),
('var', dict(key_format='r')),
+ ('string', dict(key_format='S')),
('int', dict(key_format='i')),
('bytes', dict(key_format='u')),
('composite_string', dict(key_format='SSS')),
@@ -54,8 +54,9 @@ class test_cursor_bound03(bound_base):
value_formats = [
('string', dict(value_format='S')),
+ ('fix', dict(value_format='8t'))
# FIX-ME-WT-9589: Fix bug complex colgroups not returning records within bounds.
- # ('complex-string', dict(value_format='SS')),
+ #('complex-string', dict(value_format='SS')),
]
config = [
diff --git a/src/third_party/wiredtiger/test/suite/test_cursor_bound04.py b/src/third_party/wiredtiger/test/suite/test_cursor_bound04.py
index b3e6fe0bc27..e3061435731 100644
--- a/src/third_party/wiredtiger/test/suite/test_cursor_bound04.py
+++ b/src/third_party/wiredtiger/test/suite/test_cursor_bound04.py
@@ -56,6 +56,7 @@ class test_cursor_bound04(bound_base):
value_formats = [
('string', dict(value_format='S')),
+ ('fix', dict(value_format='8t'))
# FIX-ME-WT-9589: Fix bug complex colgroups not returning records within bounds.
# ('complex-string', dict(value_format='SS')),
]
@@ -82,7 +83,7 @@ class test_cursor_bound04(bound_base):
cursor.bound("action=clear,bound=lower")
self.assertEqual(cursor.next(), 0)
key = cursor.get_key()
- self.assertEqual(key, self.check_key(self.start_key))
+ self.assertEqual(key, self.check_key(1 if self.flcs else self.start_key))
cursor.reset()
# Test bound api: Test lower bound setting with positioned cursor.
@@ -114,7 +115,7 @@ class test_cursor_bound04(bound_base):
self.set_bounds(cursor, 55, "upper")
self.assertEqual(cursor.next(), 0)
key = cursor.get_key()
- self.assertEqual(key, self.check_key(self.start_key))
+ self.assertEqual(key, self.check_key(1 if self.flcs else self.start_key))
cursor.set_key(self.gen_key(60))
self.assertRaisesWithMessage(wiredtiger.WiredTigerError, lambda: self.set_bounds(cursor, 50, "upper"), '/Invalid argument/')
cursor.reset()
@@ -122,7 +123,7 @@ class test_cursor_bound04(bound_base):
self.set_bounds(cursor, 55, "upper")
self.assertEqual(cursor.next(), 0)
key = cursor.get_key()
- self.assertEqual(key, self.check_key(self.start_key))
+ self.assertEqual(key, self.check_key(1 if self.flcs else self.start_key))
cursor.set_key(self.gen_key(90))
self.assertRaisesWithMessage(wiredtiger.WiredTigerError, lambda: self.set_bounds(cursor, 50, "upper"),
'/Invalid argument/')
@@ -131,7 +132,7 @@ class test_cursor_bound04(bound_base):
self.set_bounds(cursor, 55, "upper")
self.assertEqual(cursor.next(), 0)
key = cursor.get_key()
- self.assertEqual(key, self.check_key(self.start_key))
+ self.assertEqual(key, self.check_key(1 if self.flcs else self.start_key))
cursor.set_key(self.gen_key(10))
self.assertRaisesWithMessage(wiredtiger.WiredTigerError, lambda: self.set_bounds(cursor, 50, "upper"),
'/Invalid argument/')
@@ -150,7 +151,7 @@ class test_cursor_bound04(bound_base):
self.set_bounds(cursor, 55, "upper")
self.assertEqual(cursor.next(), 0)
key = cursor.get_key()
- self.assertEqual(key, self.check_key(self.start_key))
+ self.assertEqual(key, self.check_key(1 if self.flcs else self.start_key))
self.assertRaisesWithMessage(wiredtiger.WiredTigerError, lambda: cursor.bound("bound=upper,inclusive=false"),
'/Invalid argument/')
cursor.reset()
@@ -167,9 +168,9 @@ class test_cursor_bound04(bound_base):
self.set_bounds(cursor, 55, "upper")
self.assertEqual(cursor.next(), 0)
key = cursor.get_key()
- self.assertEqual(key, self.check_key(self.start_key))
+ self.assertEqual(key, self.check_key(1 if self.flcs else self.start_key))
self.assertEqual(cursor.bound("action=clear"), 0)
- self.cursor_traversal_bound(cursor, None, None, True, self.end_key - self.start_key)
+ self.cursor_traversal_bound(cursor, None, None, True, self.end_key - 1 if self.flcs else self.end_key - self.start_key)
cursor.reset()
cursor.close()
@@ -229,7 +230,7 @@ class test_cursor_bound04(bound_base):
key = cursor.get_key()
self.assertEqual(key, self.check_key(45))
self.assertEqual(cursor.bound("action=clear"), 0)
- self.cursor_traversal_bound(cursor, None, None, False, 45 - self.start_key)
+ self.cursor_traversal_bound(cursor, None, None, False, 45 - self.start_key if not self.flcs else 45 - 1)
cursor.reset()
self.set_bounds(cursor, 45, "upper")
diff --git a/src/third_party/wiredtiger/test/suite/wtbound.py b/src/third_party/wiredtiger/test/suite/wtbound.py
index 8e814327f0e..f5c86b57bbf 100644
--- a/src/third_party/wiredtiger/test/suite/wtbound.py
+++ b/src/third_party/wiredtiger/test/suite/wtbound.py
@@ -108,10 +108,18 @@ class bound_base(wttest.WiredTigerTestCase):
end_key = 79
lower_inclusive = True
upper_inclusive = True
+ flcs = False
def create_session_and_cursor(self, cursor_config=None):
uri = self.uri + self.file_name
create_params = 'value_format={},key_format={}'.format(self.value_format, self.key_format)
+
+ if (self.value_format == '8t'):
+ # Colgroups generation doesn't seem to work with 8t format.
+ self.use_colgroup = False
+ if (self.key_format == 'r'):
+ self.flcs = True
+
if self.use_colgroup:
create_params += self.gen_colgroup_create_param()
self.session.create(uri, create_params)
@@ -127,7 +135,7 @@ class bound_base(wttest.WiredTigerTestCase):
self.session.begin_transaction()
for i in range(self.start_key, self.end_key + 1):
- cursor[self.gen_key(i)] = self.gen_val("value" + str(i))
+ cursor[self.gen_key(i)] = self.gen_val(str(i))
self.session.commit_transaction()
if (self.evict):
@@ -182,7 +190,8 @@ class bound_base(wttest.WiredTigerTestCase):
tuple_val.append(self.recno(i))
elif key == "i":
tuple_val.append(i)
-
+ if (self.value_format == '8t'):
+ return int(int(i) & 0xff)
if (len(self.value_format) == 1):
return tuple_val[0]
else:
@@ -226,10 +235,11 @@ class bound_base(wttest.WiredTigerTestCase):
def cursor_traversal_bound(self, cursor, lower_key, upper_key, next=None, expected_count=None):
if next == None:
- next = self.direction
+ next = self.next
start_range = self.start_key
end_range = self.end_key
+ flcs_start_range = start_range
if (upper_key):
if (upper_key < end_range):
@@ -243,6 +253,15 @@ class bound_base(wttest.WiredTigerTestCase):
if (not self.lower_inclusive):
start_range += 1
+ # Special handling for fixed length column store where implicit records may exist.
+ if (self.flcs):
+ if (lower_key is not None):
+ if (lower_key < start_range):
+ flcs_start_range = lower_key
+ if (not self.lower_inclusive):
+ flcs_start_range += 1
+ else:
+ flcs_start_range = 1
count = ret = 0
while True:
@@ -269,4 +288,12 @@ class bound_base(wttest.WiredTigerTestCase):
if (expected_count != None):
self.assertEqual(expected_count, count)
else:
- self.assertEqual(end_range - start_range + 1, count)
+ # As a result of fix length column store creating implicit records during eviction we
+ # have assert that we either walked the expected range or a range with additional
+ # implicit records.
+ if (self.flcs):
+ range_without_implicit = end_range - start_range + 1
+ range_with_implicit = end_range - flcs_start_range + 1
+ self.assertTrue(count == range_with_implicit or count == range_without_implicit)
+ else:
+ self.assertEqual(end_range - start_range + 1, count)