summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoringo@mysql.com <>2004-06-24 12:07:00 +0200
committeringo@mysql.com <>2004-06-24 12:07:00 +0200
commitd74558eb36c1cc1affff3054dc77a1d1529b3024 (patch)
tree78d057b4fb392e8686168bbbbef75c29e35bda9b
parentc9b1946c054e3f04a5dc61bd6add323eec95293e (diff)
parente1cd282ea2d43b68468f22319affd152447919bb (diff)
downloadmariadb-git-d74558eb36c1cc1affff3054dc77a1d1529b3024.tar.gz
Merge mysql.com:/home/mydev/mysql-4.0
into mysql.com:/home/mydev/mysql-4.0-bug2688
-rw-r--r--mysql-test/r/bdb.result18
-rw-r--r--mysql-test/t/bdb.test18
-rw-r--r--sql/ha_berkeley.cc31
3 files changed, 67 insertions, 0 deletions
diff --git a/mysql-test/r/bdb.result b/mysql-test/r/bdb.result
index 2ccb5148d58..7d4b42e6a8c 100644
--- a/mysql-test/r/bdb.result
+++ b/mysql-test/r/bdb.result
@@ -1190,3 +1190,21 @@ a
A
a
drop table t1;
+create table t1 (
+pk1 varchar(8) not null default '',
+pk2 varchar(4) not null default '',
+key1 int(11) default null,
+key2 int(11) default null,
+primary key (pk1,pk2),
+key key1 (key1),
+key key2 (key2)) engine=bdb;
+insert into t1 values ('','empt',2,2), ('a','a--a',2,2),
+('bb','b--b',2,2), ('ccc','c--c',2,2), ('dddd','d--d',2,2);
+select * from t1 force index(key1, key2) where key1 < 3 or key2 < 3;
+pk1 pk2 key1 key2
+ empt 2 2
+a a--a 2 2
+bb b--b 2 2
+ccc c--c 2 2
+dddd d--d 2 2
+drop table t1;
diff --git a/mysql-test/t/bdb.test b/mysql-test/t/bdb.test
index 4b490052535..bed0cbe269d 100644
--- a/mysql-test/t/bdb.test
+++ b/mysql-test/t/bdb.test
@@ -829,3 +829,21 @@ alter table t1 modify a char(10) binary;
explain select a from t1;
select a from t1;
drop table t1;
+
+#
+# bug#2688 - Wrong index_merge query results for BDB table with variable length primary key
+#
+
+create table t1 (
+ pk1 varchar(8) not null default '',
+ pk2 varchar(4) not null default '',
+ key1 int(11) default null,
+ key2 int(11) default null,
+ primary key (pk1,pk2),
+ key key1 (key1),
+ key key2 (key2)) engine=bdb;
+insert into t1 values ('','empt',2,2), ('a','a--a',2,2),
+ ('bb','b--b',2,2), ('ccc','c--c',2,2), ('dddd','d--d',2,2);
+select * from t1 force index(key1, key2) where key1 < 3 or key2 < 3;
+drop table t1;
+
diff --git a/sql/ha_berkeley.cc b/sql/ha_berkeley.cc
index 3522aadf349..18af688d07c 100644
--- a/sql/ha_berkeley.cc
+++ b/sql/ha_berkeley.cc
@@ -1611,13 +1611,44 @@ int ha_berkeley::rnd_pos(byte * buf, byte *pos)
(char*) buf, primary_key, &current_row, (DBT*) 0, 0));
}
+/*
+ Set a reference to the current record in (ref,ref_length).
+
+ SYNOPSIS
+ ha_berkeley::position()
+ record The current record buffer
+
+ DESCRIPTION
+ The BDB handler stores the primary key in (ref,ref_length).
+ There is either an explicit primary key, or an implicit (hidden)
+ primary key.
+ During open(), 'ref_length' is calculated as the maximum primary
+ key length. When an actual key is shorter than that, the rest of
+ the buffer must be cleared out. The row cannot be identified, if
+ garbage follows behind the end of the key. There is no length
+ field for the current key, so that the whole ref_length is used
+ for comparison.
+
+ RETURN
+ nothing
+*/
+
void ha_berkeley::position(const byte *record)
{
DBT key;
+ DBUG_ENTER("ha_berkeley::position");
if (hidden_primary_key)
+ {
+ DBUG_ASSERT(ref_length == BDB_HIDDEN_PRIMARY_KEY_LENGTH);
memcpy_fixed(ref, (char*) current_ident, BDB_HIDDEN_PRIMARY_KEY_LENGTH);
+ }
else
+ {
create_key(&key, primary_key, (char*) ref, record);
+ if (key.size < ref_length)
+ bzero(ref + key.size, ref_length - key.size);
+ }
+ DBUG_VOID_RETURN;
}