diff options
-rw-r--r-- | src/plugins/kdb/db2/libdb2/btree/bt_split.c | 4 | ||||
-rw-r--r-- | src/plugins/kdb/db2/libdb2/test/run.test | 54 |
2 files changed, 54 insertions, 4 deletions
diff --git a/src/plugins/kdb/db2/libdb2/btree/bt_split.c b/src/plugins/kdb/db2/libdb2/btree/bt_split.c index 62ec823a1..9b2708e76 100644 --- a/src/plugins/kdb/db2/libdb2/btree/bt_split.c +++ b/src/plugins/kdb/db2/libdb2/btree/bt_split.c @@ -727,7 +727,7 @@ bt_psplit(t, h, l, r, pskip, ilen) * the right page. */ if (skip <= off) { - skip = 0; + skip = (indx_t)-1; rval = l; } else { rval = r; @@ -737,7 +737,7 @@ bt_psplit(t, h, l, r, pskip, ilen) for (off = 0; nxt < top; ++off) { if (skip == nxt) { ++off; - skip = 0; + skip = (indx_t)-1; } switch (h->flags & P_TYPE) { case P_BINTERNAL: diff --git a/src/plugins/kdb/db2/libdb2/test/run.test b/src/plugins/kdb/db2/libdb2/test/run.test index 48c3a63d0..377d6f794 100644 --- a/src/plugins/kdb/db2/libdb2/test/run.test +++ b/src/plugins/kdb/db2/libdb2/test/run.test @@ -34,7 +34,7 @@ main() bindir=/bin/. if [ $# -eq 0 ]; then - for t in 1 2 3 4 5 6 7 8 9 10 11 12 13 20; do + for t in 1 2 3 4 5 6 7 8 9 10 11 12 13 20 40; do test$t done else @@ -45,7 +45,7 @@ main() [0-9]*) test$1;; btree) - for t in 1 2 3 7 8 9 10 12 13; do + for t in 1 2 3 7 8 9 10 12 13 40; do test$t done;; hash) @@ -743,4 +743,54 @@ bsize=$bsize ffactor=$ffactor nelem=25000 cachesize=65536 failed" done } +# Test for a weird page split condition where an insertion into index +# 0 of a page that would cause the new item to be the only item on the +# left page results in index 0 of the right page being erroneously +# skipped; this only happens with one particular key+data length for +# each page size. +test40 () { + echo "Test 40: btree: page split on index 0" + e=: + for psize in 512 1024 2048 4096 8192; do + echo " page size $psize" + kdsizes=`awk 'BEGIN { + psize = '$psize'; hsize = int(psize/2); + for (kdsize = hsize-40; kdsize <= hsize; kdsize++) { + print kdsize; + } + }' /dev/null` + + # Use a series of keylen+datalen values in the right + # neighborhood to find the one that triggers the bug. + # We could compute the exact size that triggers the + # bug but this additional fuzz may be useful. + + # Insert keys in reverse order to maximize the chances + # for a split on index 0. + + for kdsize in $kdsizes; do + awk 'BEGIN { + kdsize = '$kdsize'; + for (i = 8; i-- > 0; ) { + s = sprintf("a%03d:%09d", i, kdsize); + for (j = 0; j < kdsize-20; j++) { + s = s "x"; + } + printf("p\nka%03d\nd%s\n", i, s); + } + print "o"; + }' /dev/null > $TMP2 + sed -n 's/^d//p' $TMP2 | sort > $TMP1 + $PROG -o $TMP3 -i psize=$psize btree $TMP2 + if (cmp -s $TMP1 $TMP3); then : + else + echo "test40: btree: page size $psize, \ +keylen+datalen=$kdsize failed" + e='exit 1' + fi + done + done + $e +} + main $* |