mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
Fixed for bugs that was found when getting full code coverage of BDB
Fixed bug with HEAP tables on windows Fixed bug with HAVING on empty tables Docs/manual.texi: Update of UDF functions mysql-test/mysql-test-run.sh: Added option --user mysql-test/r/bdb.result: Added more test to get better coverage mysql-test/t/bdb.test: Added more test to get better coverage sql/field.cc: Fixes for key packing in BDB sql/field.h: Fixes for key packing in BDB sql/ha_berkeley.cc: Fixed for bugs that was found when getting full code coverage sql/ha_heap.cc: Fixed problem with HEAP tables on windows sql/log.cc: Safety fix sql/sql_select.cc: Fixed bug with HAVING on empty tables sql/table.cc: Fixed problem with HEAP tables on windows
This commit is contained in:
@ -31588,17 +31588,22 @@ message to less than 80 characters so that it fits the width of a standard
|
|||||||
terminal screen.
|
terminal screen.
|
||||||
|
|
||||||
The return value of the main function @code{xxx()} is the function value, for
|
The return value of the main function @code{xxx()} is the function value, for
|
||||||
@code{long long} and @code{double} functions. For string functions, the
|
@code{long long} and @code{double} functions. A string functions should
|
||||||
string is returned in the @code{result} and @code{length} arguments.
|
return a pointer to the result and store the length of the string in the
|
||||||
@code{result} is a buffer at least 255 bytes long. Set these to the contents
|
@code{length} arguments. @code{result} is a buffer at least 255 bytes long.
|
||||||
and length of the return value. For example:
|
Set these to the contents and length of the return value. For example:
|
||||||
|
|
||||||
@example
|
@example
|
||||||
memcpy(result, "result string", 13);
|
memcpy(result, "result string", 13);
|
||||||
*length = 13;
|
*length = 13;
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
The string function return value normally also points to the result.
|
If your string functions that needs to return a string longer than 255
|
||||||
|
bytes, you must allocate the space for it with @code{malloc()} in your
|
||||||
|
@code{xxx_init()} function or your @code{xxx()} function and free it in
|
||||||
|
your @code{xxx_deinit()} function. You can store the allocated memory
|
||||||
|
in the @code{ptr} slot in the @code{UDF_INIT} structure for reuse by
|
||||||
|
future @code{xxx()} calls. @xref{UDF calling sequences}.
|
||||||
|
|
||||||
To indicate a return value of @code{NULL} in the main function, set
|
To indicate a return value of @code{NULL} in the main function, set
|
||||||
@code{is_null} to @code{1}:
|
@code{is_null} to @code{1}:
|
||||||
@ -40403,6 +40408,12 @@ though, so Version 3.23 is not released as a stable version yet.
|
|||||||
@appendixsubsec Changes in release 3.23.31
|
@appendixsubsec Changes in release 3.23.31
|
||||||
@itemize @bullet
|
@itemize @bullet
|
||||||
@item
|
@item
|
||||||
|
Using @code{HAVING} on an empty table could produce one result row.
|
||||||
|
@item
|
||||||
|
Fixed that the @strong{MySQL} RPM is not depending on perl5 anymore.
|
||||||
|
@item
|
||||||
|
Fixed some problems with @code{HEAP} tables on windows.
|
||||||
|
@item
|
||||||
@code{SHOW TABLE STATUS} didn't show correct average row length for tables
|
@code{SHOW TABLE STATUS} didn't show correct average row length for tables
|
||||||
bigger than 4G.
|
bigger than 4G.
|
||||||
@item
|
@item
|
||||||
@ -40412,15 +40423,16 @@ Added option @code{MEDIUM} to @code{CHECK TABLE}.
|
|||||||
@item
|
@item
|
||||||
Fixed problem when using @code{DECIMAL()} keys on negative numbers.
|
Fixed problem when using @code{DECIMAL()} keys on negative numbers.
|
||||||
@item
|
@item
|
||||||
@code{HOUR()} on a @code{CHAR} column always returned @code{NULL}.
|
@code{HOUR()} (and some other @code{TIME} functions) on a @code{CHAR} column
|
||||||
|
always returned @code{NULL}.
|
||||||
@item
|
@item
|
||||||
Fixed security bug in something (please upgrade if you are using a earlier
|
Fixed security bug in something (please upgrade if you are using a earlier
|
||||||
MySQL 3.23 version).
|
MySQL 3.23 version).
|
||||||
@item
|
@item
|
||||||
Fixed buffer overflow bug when writing a certain error message.
|
Fixed buffer overflow bug when writing a certain error message.
|
||||||
@item
|
@item
|
||||||
Added usage of @code{getrlimit()} on Linux to get @code{-O --open-files-limit=#}
|
Added usage of @code{getrlimit()} on Linux to get @code{-O
|
||||||
to work on Linux.
|
--open-files-limit=#} to work on Linux.
|
||||||
@item
|
@item
|
||||||
Added new mysqld variable: bdb_version.
|
Added new mysqld variable: bdb_version.
|
||||||
@item
|
@item
|
||||||
|
@ -100,9 +100,11 @@ DO_GCOV=""
|
|||||||
DO_GDB=""
|
DO_GDB=""
|
||||||
DO_DDD=""
|
DO_DDD=""
|
||||||
SLEEP_TIME=2
|
SLEEP_TIME=2
|
||||||
|
DBUSER=""
|
||||||
|
|
||||||
while test $# -gt 0; do
|
while test $# -gt 0; do
|
||||||
case "$1" in
|
case "$1" in
|
||||||
|
--user=*) DBUSER=`$ECHO "$1" | $SED -e "s;--user=;;"` ;;
|
||||||
--force) FORCE=1 ;;
|
--force) FORCE=1 ;;
|
||||||
--local) USE_RUNNING_SERVER="" ;;
|
--local) USE_RUNNING_SERVER="" ;;
|
||||||
--tmpdir=*) MYSQL_TMP_DIR=`$ECHO "$1" | $SED -e "s;--tmpdir=;;"` ;;
|
--tmpdir=*) MYSQL_TMP_DIR=`$ECHO "$1" | $SED -e "s;--tmpdir=;;"` ;;
|
||||||
@ -209,9 +211,9 @@ fi
|
|||||||
if [ -n "$USE_RUNNING_SERVER" ]
|
if [ -n "$USE_RUNNING_SERVER" ]
|
||||||
then
|
then
|
||||||
MASTER_MYSOCK="/tmp/mysql.sock"
|
MASTER_MYSOCK="/tmp/mysql.sock"
|
||||||
DBUSER=test
|
DBUSER=${DBUSER:-test}
|
||||||
else
|
else
|
||||||
DBUSER=root # We want to do FLUSH xxx commands
|
DBUSER=${DBUSER:-root} # We want to do FLUSH xxx commands
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -w / ]
|
if [ -w / ]
|
||||||
|
@ -147,6 +147,12 @@ Table Op Msg_type Msg_text
|
|||||||
test.t1 check error The handler for the table doesn't support check/repair
|
test.t1 check error The handler for the table doesn't support check/repair
|
||||||
a b
|
a b
|
||||||
2 testing
|
2 testing
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 analyze status OK
|
||||||
|
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment
|
||||||
|
t1 1 skr 1 a A 3 NULL NULL
|
||||||
|
a b
|
||||||
|
1
|
||||||
a b
|
a b
|
||||||
a 1
|
a 1
|
||||||
a 2
|
a 2
|
||||||
@ -429,6 +435,8 @@ count(*)
|
|||||||
count(*)
|
count(*)
|
||||||
1
|
1
|
||||||
count(*)
|
count(*)
|
||||||
|
0
|
||||||
|
count(*)
|
||||||
1
|
1
|
||||||
count(*)
|
count(*)
|
||||||
1
|
1
|
||||||
@ -468,4 +476,4 @@ hello 1
|
|||||||
Table Op Msg_type Msg_text
|
Table Op Msg_type Msg_text
|
||||||
test.t1 optimize status OK
|
test.t1 optimize status OK
|
||||||
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment
|
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment
|
||||||
t1 0 PRIMARY 1 a A 1 NULL NULL
|
t1 0 PRIMARY 1 a A 2 NULL NULL
|
||||||
|
4
mysql-test/r/having.result
Normal file
4
mysql-test/r/having.result
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
b
|
||||||
|
b
|
||||||
|
b
|
||||||
|
0
|
@ -4,7 +4,7 @@
|
|||||||
# Small basic test with ignore
|
# Small basic test with ignore
|
||||||
#
|
#
|
||||||
|
|
||||||
drop table if exists t1;
|
drop table if exists t1,t2;
|
||||||
create table t1 (id int unsigned not null auto_increment, code tinyint unsigned not null, name char(20) not null, primary key (id), key (code), unique (name)) type=bdb;
|
create table t1 (id int unsigned not null auto_increment, code tinyint unsigned not null, name char(20) not null, primary key (id), key (code), unique (name)) type=bdb;
|
||||||
|
|
||||||
insert into t1 (code, name) values (1, 'Tim'), (1, 'Monty'), (2, 'David'), (2, 'Erik'), (3, 'Sasha'), (3, 'Jeremy'), (4, 'Matt');
|
insert into t1 (code, name) values (1, 'Tim'), (1, 'Monty'), (2, 'David'), (2, 'Erik'), (3, 'Sasha'), (3, 'Jeremy'), (4, 'Matt');
|
||||||
@ -81,6 +81,17 @@ create table t1 (a int,b varchar(20)) type=bdb;
|
|||||||
insert into t1 values (1,""), (2,"testing");
|
insert into t1 values (1,""), (2,"testing");
|
||||||
delete from t1 where a = 1;
|
delete from t1 where a = 1;
|
||||||
select * from t1;
|
select * from t1;
|
||||||
|
create index skr on t1 (a);
|
||||||
|
insert into t1 values (3,""), (4,"testing");
|
||||||
|
analyze table t1;
|
||||||
|
show keys from t1;
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
|
# Test of reading on secondary key with may be null
|
||||||
|
|
||||||
|
create table t1 (a int,b varchar(20),key(a)) type=bdb;
|
||||||
|
insert into t1 values (1,""), (2,"testing");
|
||||||
|
select * from t1 where a = 1;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
#
|
#
|
||||||
@ -352,12 +363,15 @@ CREATE TABLE t1 (
|
|||||||
INDEX sca_pic (sca_pic)
|
INDEX sca_pic (sca_pic)
|
||||||
) type = bdb ;
|
) type = bdb ;
|
||||||
|
|
||||||
INSERT INTO t1 ( sca_code, cat_code, sca_desc, lan_code, sca_pic, sca_sdesc, sca_sch_desc) VALUES ( 'PD', 'J', 'PENDANT', 'EN', NULL, NULL, 'PENDANT'),( 'RI', 'J', 'RING', 'EN', NULL, NULL, 'RING'),( 'QQ', 'J', 'RING', 'EN', 'not null', NULL, 'RING');
|
INSERT INTO t1 ( sca_code, cat_code, sca_desc, lan_code, sca_pic, sca_sdesc, sca_sch_desc) VALUES ( 'PD', 'J', 'PENDANT', 'EN', NULL, NULL, 'PENDANT'),( 'RI', 'J', 'RING', 'EN', NULL, NULL, 'RING'),( 'QQ', 'N', 'RING', 'EN', 'not null', NULL, 'RING');
|
||||||
select count(*) from t1 where sca_code = 'PD';
|
select count(*) from t1 where sca_code = 'PD';
|
||||||
select count(*) from t1 where sca_code <= 'PD';
|
select count(*) from t1 where sca_code <= 'PD';
|
||||||
select count(*) from t1 where sca_pic is null;
|
select count(*) from t1 where sca_pic is null;
|
||||||
alter table t1 drop index sca_pic, add index sca_pic (cat_code, sca_pic);
|
alter table t1 drop index sca_pic, add index sca_pic (cat_code, sca_pic);
|
||||||
select count(*) from t1 where sca_code='PD' and sca_pic is null;
|
select count(*) from t1 where sca_code='PD' and sca_pic is null;
|
||||||
|
select count(*) from t1 where cat_code='E';
|
||||||
|
|
||||||
|
|
||||||
alter table t1 drop index sca_pic, add index (sca_pic, cat_code);
|
alter table t1 drop index sca_pic, add index (sca_pic, cat_code);
|
||||||
select count(*) from t1 where sca_code='PD' and sca_pic is null;
|
select count(*) from t1 where sca_code='PD' and sca_pic is null;
|
||||||
select count(*) from t1 where sca_pic >= 'n';
|
select count(*) from t1 where sca_pic >= 'n';
|
||||||
@ -385,7 +399,7 @@ flush logs;
|
|||||||
#
|
#
|
||||||
# Test key on blob with null values
|
# Test key on blob with null values
|
||||||
#
|
#
|
||||||
create table t1 (b blob, i int, key (b(100)), key (i), key (i, b(20)));
|
create table t1 (b blob, i int, key (b(100)), key (i), key (i, b(20))) type=bdb;
|
||||||
insert into t1 values ('this is a blob', 1), (null, -1), (null, null),("",1),("",2),("",3);
|
insert into t1 values ('this is a blob', 1), (null, -1), (null, null),("",1),("",2),("",3);
|
||||||
select b from t1 where b = 'this is a blob';
|
select b from t1 where b = 'this is a blob';
|
||||||
select * from t1 where b like 't%';
|
select * from t1 where b like 't%';
|
||||||
@ -399,7 +413,7 @@ drop table t1;
|
|||||||
#
|
#
|
||||||
# Test with variable length primary key
|
# Test with variable length primary key
|
||||||
#
|
#
|
||||||
create table t1 (a varchar(100) not null, primary key(a), b int not null);
|
create table t1 (a varchar(100) not null, primary key(a), b int not null) type=bdb;
|
||||||
insert into t1 values("hello",1),("world",2);
|
insert into t1 values("hello",1),("world",2);
|
||||||
select * from t1 order by b desc;
|
select * from t1 order by b desc;
|
||||||
optimize table t1;
|
optimize table t1;
|
||||||
|
10
mysql-test/t/having.test
Normal file
10
mysql-test/t/having.test
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# test of problems with having (Reported by Mark Rogers)
|
||||||
|
#
|
||||||
|
|
||||||
|
drop table if exists t1;
|
||||||
|
create table t1 (a int);
|
||||||
|
select count(a) as b from t1 where a=0 having b > 0;
|
||||||
|
insert into t1 values (null);
|
||||||
|
select count(a) as b from t1 where a=0 having b > 0;
|
||||||
|
select count(a) as b from t1 where a=0 having b >=0;
|
||||||
|
drop table t1;
|
65
sql/field.cc
65
sql/field.cc
@ -3599,7 +3599,7 @@ void Field_varstring::sql_type(String &res) const
|
|||||||
|
|
||||||
char *Field_varstring::pack(char *to, const char *from, uint max_length)
|
char *Field_varstring::pack(char *to, const char *from, uint max_length)
|
||||||
{
|
{
|
||||||
uint length=uint2korr(to);
|
uint length=uint2korr(from);
|
||||||
if (length > max_length)
|
if (length > max_length)
|
||||||
length=max_length;
|
length=max_length;
|
||||||
*to++= (length & 255);
|
*to++= (length & 255);
|
||||||
@ -4037,6 +4037,43 @@ void Field_blob::sql_type(String &res) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char *Field_blob::pack(char *to, const char *from, uint max_length)
|
||||||
|
{
|
||||||
|
char *save=ptr;
|
||||||
|
ptr=(char*) from;
|
||||||
|
ulong length=get_length(); // Length of from string
|
||||||
|
if (length > max_length)
|
||||||
|
{
|
||||||
|
ptr=to;
|
||||||
|
length=max_length;
|
||||||
|
store_length(length); // Store max length
|
||||||
|
ptr=(char*) from;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
memcpy(to,from,packlength); // Copy length
|
||||||
|
if (length)
|
||||||
|
{
|
||||||
|
get_ptr((char**) &from);
|
||||||
|
memcpy(to+packlength, from,length);
|
||||||
|
}
|
||||||
|
ptr=save; // Restore org row pointer
|
||||||
|
return to+packlength+length;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char *Field_blob::unpack(char *to, const char *from)
|
||||||
|
{
|
||||||
|
memcpy(to,from,packlength);
|
||||||
|
from+=packlength;
|
||||||
|
ulong length=get_length();
|
||||||
|
if (length)
|
||||||
|
memcpy_fixed(to+packlength, &from, sizeof(from));
|
||||||
|
else
|
||||||
|
bzero(to+packlength,sizeof(from));
|
||||||
|
return from+length;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Keys for blobs are like keys on varchars */
|
/* Keys for blobs are like keys on varchars */
|
||||||
|
|
||||||
int Field_blob::pack_cmp(const char *a, const char *b, uint key_length)
|
int Field_blob::pack_cmp(const char *a, const char *b, uint key_length)
|
||||||
@ -4087,10 +4124,33 @@ int Field_blob::pack_cmp(const char *b, uint key_length)
|
|||||||
return my_sortncmp(a,a_length, b,b_length);
|
return my_sortncmp(a,a_length, b,b_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Create a packed key that will be used for storage from a MySQL row */
|
||||||
|
|
||||||
char *Field_blob::pack_key(char *to, const char *from, uint max_length)
|
char *Field_blob::pack_key(char *to, const char *from, uint max_length)
|
||||||
{
|
{
|
||||||
uint length=uint2korr(to);
|
char *save=ptr;
|
||||||
|
ptr=(char*) from;
|
||||||
|
ulong length=get_length(); // Length of from string
|
||||||
|
if (length > max_length)
|
||||||
|
length=max_length;
|
||||||
|
*to++= (uchar) length;
|
||||||
|
if (max_length > 255) // 2 byte length
|
||||||
|
*to++= (uchar) (length >> 8);
|
||||||
|
if (length)
|
||||||
|
{
|
||||||
|
get_ptr((char**) &from);
|
||||||
|
memcpy(to, from, length);
|
||||||
|
}
|
||||||
|
ptr=save; // Restore org row pointer
|
||||||
|
return to+length;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create a packed key that will be used for storage from a MySQL key */
|
||||||
|
|
||||||
|
char *Field_blob::pack_key_from_key_image(char *to, const char *from,
|
||||||
|
uint max_length)
|
||||||
|
{
|
||||||
|
uint length=uint2korr(from);
|
||||||
if (length > max_length)
|
if (length > max_length)
|
||||||
length=max_length;
|
length=max_length;
|
||||||
*to++= (length & 255);
|
*to++= (length & 255);
|
||||||
@ -4101,6 +4161,7 @@ char *Field_blob::pack_key(char *to, const char *from, uint max_length)
|
|||||||
return to+length;
|
return to+length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
** enum type.
|
** enum type.
|
||||||
** This is a string which only can have a selection of different values.
|
** This is a string which only can have a selection of different values.
|
||||||
|
44
sql/field.h
44
sql/field.h
@ -166,7 +166,12 @@ public:
|
|||||||
memcpy(to,from,length);
|
memcpy(to,from,length);
|
||||||
return from+length;
|
return from+length;
|
||||||
}
|
}
|
||||||
virtual char *keypack(char* to, const char *from, uint max_length=~(uint) 0)
|
virtual char *pack_key(char* to, const char *from, uint max_length)
|
||||||
|
{
|
||||||
|
return pack(to,from,max_length);
|
||||||
|
}
|
||||||
|
virtual char *pack_key_from_key_image(char* to, const char *from,
|
||||||
|
uint max_length)
|
||||||
{
|
{
|
||||||
return pack(to,from,max_length);
|
return pack(to,from,max_length);
|
||||||
}
|
}
|
||||||
@ -861,39 +866,10 @@ public:
|
|||||||
tmp=(char*) value.ptr(); memcpy_fixed(ptr+packlength,&tmp,sizeof(char*));
|
tmp=(char*) value.ptr(); memcpy_fixed(ptr+packlength,&tmp,sizeof(char*));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
char *pack(char *to, const char *from, uint max_length= ~(uint) 0)
|
char *pack(char *to, const char *from, uint max_length= ~(uint) 0);
|
||||||
{
|
const char *unpack(char *to, const char *from);
|
||||||
ulong length=get_length();
|
char *pack_key(char *to, const char *from, uint max_length);
|
||||||
if (length > max_length)
|
char *pack_key_from_key_image(char* to, const char *from, uint max_length);
|
||||||
{
|
|
||||||
length=max_length;
|
|
||||||
char *save=ptr;
|
|
||||||
ptr=to;
|
|
||||||
store_length(length);
|
|
||||||
ptr=save;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
memcpy(to,from,packlength);
|
|
||||||
if (length)
|
|
||||||
{
|
|
||||||
get_ptr((char**) &from);
|
|
||||||
memcpy(to+packlength, from,length);
|
|
||||||
return to+packlength+length;
|
|
||||||
}
|
|
||||||
return to+packlength;
|
|
||||||
}
|
|
||||||
const char *unpack(char *to, const char *from)
|
|
||||||
{
|
|
||||||
memcpy(to,from,packlength);
|
|
||||||
from+=packlength;
|
|
||||||
ulong length=get_length();
|
|
||||||
if (length)
|
|
||||||
memcpy_fixed(to+packlength, &from, sizeof(from));
|
|
||||||
else
|
|
||||||
bzero(to+packlength,sizeof(from));
|
|
||||||
return from+length;
|
|
||||||
}
|
|
||||||
char *pack_key(char *to, const char *from, uint max_length=~(uint) 0);
|
|
||||||
int pack_cmp(const char *a, const char *b, uint key_length);
|
int pack_cmp(const char *a, const char *b, uint key_length);
|
||||||
int pack_cmp(const char *b, uint key_length);
|
int pack_cmp(const char *b, uint key_length);
|
||||||
uint packed_col_length(const char *col_ptr)
|
uint packed_col_length(const char *col_ptr)
|
||||||
|
@ -42,7 +42,6 @@
|
|||||||
|
|
||||||
Testing of:
|
Testing of:
|
||||||
- LOCK TABLES
|
- LOCK TABLES
|
||||||
- BLOBS
|
|
||||||
- Mark tables that participate in a transaction so that they are not
|
- Mark tables that participate in a transaction so that they are not
|
||||||
closed during the transaction. We need to test what happens if
|
closed during the transaction. We need to test what happens if
|
||||||
MySQL closes a table that is updated by a not commit transaction.
|
MySQL closes a table that is updated by a not commit transaction.
|
||||||
@ -290,7 +289,7 @@ static void berkeley_noticecall(DB_ENV *db_env, db_notices notice)
|
|||||||
{
|
{
|
||||||
switch (notice)
|
switch (notice)
|
||||||
{
|
{
|
||||||
case DB_NOTICE_LOGFILE_CHANGED:
|
case DB_NOTICE_LOGFILE_CHANGED: /* purecov: tested */
|
||||||
pthread_mutex_lock(&LOCK_manager);
|
pthread_mutex_lock(&LOCK_manager);
|
||||||
manager_status |= MANAGER_BERKELEY_LOG_CLEANUP;
|
manager_status |= MANAGER_BERKELEY_LOG_CLEANUP;
|
||||||
pthread_mutex_unlock(&LOCK_manager);
|
pthread_mutex_unlock(&LOCK_manager);
|
||||||
@ -418,6 +417,10 @@ berkeley_key_cmp(TABLE *table, KEY *key_info, const char *key, uint key_length)
|
|||||||
if (key_part->null_bit)
|
if (key_part->null_bit)
|
||||||
{
|
{
|
||||||
key_length--;
|
key_length--;
|
||||||
|
/*
|
||||||
|
With the current usage, the following case will always be FALSE,
|
||||||
|
because NULL keys are sorted before any other key
|
||||||
|
*/
|
||||||
if (*key != (table->record[0][key_part->null_offset] &
|
if (*key != (table->record[0][key_part->null_offset] &
|
||||||
key_part->null_bit) ? 0 : 1)
|
key_part->null_bit) ? 0 : 1)
|
||||||
return 1;
|
return 1;
|
||||||
@ -731,7 +734,6 @@ DBT *ha_berkeley::create_key(DBT *key, uint keynr, char *buff,
|
|||||||
DBUG_ENTER("create_key");
|
DBUG_ENTER("create_key");
|
||||||
|
|
||||||
key->data=buff;
|
key->data=buff;
|
||||||
|
|
||||||
for ( ; key_part != end && key_length > 0; key_part++)
|
for ( ; key_part != end && key_length > 0; key_part++)
|
||||||
{
|
{
|
||||||
if (key_part->null_bit)
|
if (key_part->null_bit)
|
||||||
@ -745,7 +747,7 @@ DBT *ha_berkeley::create_key(DBT *key, uint keynr, char *buff,
|
|||||||
}
|
}
|
||||||
*buff++ = 1; // Store NOT NULL marker
|
*buff++ = 1; // Store NOT NULL marker
|
||||||
}
|
}
|
||||||
buff=key_part->field->pack(buff,record + key_part->offset,
|
buff=key_part->field->pack_key(buff,record + key_part->offset,
|
||||||
key_part->length);
|
key_part->length);
|
||||||
key_length-=key_part->length;
|
key_length-=key_part->length;
|
||||||
}
|
}
|
||||||
@ -783,7 +785,8 @@ DBT *ha_berkeley::pack_key(DBT *key, uint keynr, char *buff,
|
|||||||
}
|
}
|
||||||
key_ptr++;
|
key_ptr++;
|
||||||
}
|
}
|
||||||
buff=key_part->field->keypack(buff,key_ptr,key_part->length);
|
buff=key_part->field->pack_key_from_key_image(buff,key_ptr,
|
||||||
|
key_part->length);
|
||||||
key_ptr+=key_part->store_length;
|
key_ptr+=key_part->store_length;
|
||||||
key_length-=key_part->store_length;
|
key_length-=key_part->store_length;
|
||||||
}
|
}
|
||||||
@ -807,7 +810,7 @@ int ha_berkeley::write_row(byte * record)
|
|||||||
if ((error=pack_row(&row, record,1)))
|
if ((error=pack_row(&row, record,1)))
|
||||||
DBUG_RETURN(error); /* purecov: inspected */
|
DBUG_RETURN(error); /* purecov: inspected */
|
||||||
|
|
||||||
if (table->keys == 1)
|
if (table->keys + test(hidden_primary_key) == 1)
|
||||||
{
|
{
|
||||||
error=file->put(file, transaction, create_key(&prim_key, primary_key,
|
error=file->put(file, transaction, create_key(&prim_key, primary_key,
|
||||||
key_buff, record),
|
key_buff, record),
|
||||||
@ -859,8 +862,8 @@ int ha_berkeley::write_row(byte * record)
|
|||||||
int new_error = 0;
|
int new_error = 0;
|
||||||
if (thd_options & OPTION_INTERNAL_SUBTRANSACTIONS)
|
if (thd_options & OPTION_INTERNAL_SUBTRANSACTIONS)
|
||||||
{
|
{
|
||||||
DBUG_PRINT("trans",("aborting subtransaction"));
|
DBUG_PRINT("trans",("aborting subtransaction")); /* purecov: deadcode */
|
||||||
new_error=txn_abort(sub_trans);
|
new_error=txn_abort(sub_trans); /* purecov: deadcode */
|
||||||
}
|
}
|
||||||
else if (changed_keys)
|
else if (changed_keys)
|
||||||
{
|
{
|
||||||
@ -871,14 +874,14 @@ int ha_berkeley::write_row(byte * record)
|
|||||||
{
|
{
|
||||||
if ((new_error = remove_key(sub_trans, keynr, record,
|
if ((new_error = remove_key(sub_trans, keynr, record,
|
||||||
(DBT*) 0, &prim_key)))
|
(DBT*) 0, &prim_key)))
|
||||||
break;
|
break; /* purecov: inspected */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (new_error)
|
if (new_error)
|
||||||
{
|
{
|
||||||
error=new_error; // This shouldn't happen
|
error=new_error; // This shouldn't happen /* purecov: inspected */
|
||||||
break;
|
break; /* purecov: inspected */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1185,7 +1188,8 @@ int ha_berkeley::remove_key(DB_TXN *trans, uint keynr, const byte *record,
|
|||||||
*/
|
*/
|
||||||
dbug_assert(keynr != primary_key && prim_key->data != key_buff2);
|
dbug_assert(keynr != primary_key && prim_key->data != key_buff2);
|
||||||
DBC *tmp_cursor;
|
DBC *tmp_cursor;
|
||||||
if (!(error=file->cursor(key_file[keynr], trans, &tmp_cursor, 0)))
|
if (!(error=key_file[keynr]->cursor(key_file[keynr], trans,
|
||||||
|
&tmp_cursor, 0)))
|
||||||
{
|
{
|
||||||
if (!(error=cursor->c_get(tmp_cursor,
|
if (!(error=cursor->c_get(tmp_cursor,
|
||||||
(keynr == primary_key ?
|
(keynr == primary_key ?
|
||||||
@ -1294,8 +1298,9 @@ int ha_berkeley::index_init(uint keynr)
|
|||||||
DBUG_ENTER("index_init");
|
DBUG_ENTER("index_init");
|
||||||
active_index=keynr;
|
active_index=keynr;
|
||||||
dbug_assert(cursor == 0);
|
dbug_assert(cursor == 0);
|
||||||
if ((error=file->cursor(key_file[keynr], transaction, &cursor,
|
if ((error=key_file[keynr]->cursor(key_file[keynr], transaction, &cursor,
|
||||||
table->reginfo.lock_type > TL_WRITE_ALLOW_READ ?
|
table->reginfo.lock_type >
|
||||||
|
TL_WRITE_ALLOW_READ ?
|
||||||
0 : 0)))
|
0 : 0)))
|
||||||
cursor=0; // Safety /* purecov: inspected */
|
cursor=0; // Safety /* purecov: inspected */
|
||||||
bzero((char*) &last_key,sizeof(last_key));
|
bzero((char*) &last_key,sizeof(last_key));
|
||||||
@ -1353,8 +1358,8 @@ int ha_berkeley::read_row(int error, char *buf, uint keynr, DBT *row,
|
|||||||
current_row.flags=DB_DBT_REALLOC;
|
current_row.flags=DB_DBT_REALLOC;
|
||||||
if ((error=file->get(file, transaction, &key, ¤t_row, 0)))
|
if ((error=file->get(file, transaction, &key, ¤t_row, 0)))
|
||||||
{
|
{
|
||||||
table->status=STATUS_NOT_FOUND;
|
table->status=STATUS_NOT_FOUND; /* purecov: inspected */
|
||||||
DBUG_RETURN(error == DB_NOTFOUND ? HA_ERR_CRASHED : error);
|
DBUG_RETURN(error == DB_NOTFOUND ? HA_ERR_CRASHED : error); /* purecov: inspected */
|
||||||
}
|
}
|
||||||
row= ¤t_row;
|
row= ¤t_row;
|
||||||
}
|
}
|
||||||
@ -1371,7 +1376,7 @@ int ha_berkeley::index_read_idx(byte * buf, uint keynr, const byte * key,
|
|||||||
statistic_increment(ha_read_key_count,&LOCK_status);
|
statistic_increment(ha_read_key_count,&LOCK_status);
|
||||||
DBUG_ENTER("index_read_idx");
|
DBUG_ENTER("index_read_idx");
|
||||||
current_row.flags=DB_DBT_REALLOC;
|
current_row.flags=DB_DBT_REALLOC;
|
||||||
DBUG_RETURN(read_row(file->get(key_file[keynr], transaction,
|
DBUG_RETURN(read_row(key_file[keynr]->get(key_file[keynr], transaction,
|
||||||
pack_key(&last_key, keynr, key_buff, key,
|
pack_key(&last_key, keynr, key_buff, key,
|
||||||
key_len),
|
key_len),
|
||||||
¤t_row,0),
|
¤t_row,0),
|
||||||
@ -1389,13 +1394,15 @@ int ha_berkeley::index_read(byte * buf, const byte * key,
|
|||||||
|
|
||||||
statistic_increment(ha_read_key_count,&LOCK_status);
|
statistic_increment(ha_read_key_count,&LOCK_status);
|
||||||
bzero((char*) &row,sizeof(row));
|
bzero((char*) &row,sizeof(row));
|
||||||
if (key_len == key_info->key_length)
|
if (key_len == key_info->key_length + key_info->extra_length)
|
||||||
{
|
{
|
||||||
error=read_row(cursor->c_get(cursor, pack_key(&last_key,
|
error=read_row(cursor->c_get(cursor, pack_key(&last_key,
|
||||||
active_index,
|
active_index,
|
||||||
key_buff,
|
key_buff,
|
||||||
key, key_len),
|
key, key_len),
|
||||||
&row, DB_SET),
|
&row,
|
||||||
|
(find_flag == HA_READ_KEY_EXACT ?
|
||||||
|
DB_SET : DB_SET_RANGE)),
|
||||||
buf, active_index, &row, (DBT*) 0, 0);
|
buf, active_index, &row, (DBT*) 0, 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1840,13 +1847,15 @@ ha_rows ha_berkeley::records_in_range(int keynr,
|
|||||||
{
|
{
|
||||||
DBT key;
|
DBT key;
|
||||||
DB_KEY_RANGE start_range, end_range;
|
DB_KEY_RANGE start_range, end_range;
|
||||||
|
DB *kfile=key_file[keynr];
|
||||||
double start_pos,end_pos,rows;
|
double start_pos,end_pos,rows;
|
||||||
DBUG_ENTER("records_in_range");
|
DBUG_ENTER("records_in_range");
|
||||||
if ((start_key && file->key_range(key_file[keynr],transaction,
|
|
||||||
|
if ((start_key && kfile->key_range(kfile,transaction,
|
||||||
pack_key(&key, keynr, key_buff, start_key,
|
pack_key(&key, keynr, key_buff, start_key,
|
||||||
start_key_len),
|
start_key_len),
|
||||||
&start_range,0)) ||
|
&start_range,0)) ||
|
||||||
(end_key && file->key_range(key_file[keynr],transaction,
|
(end_key && kfile->key_range(kfile,transaction,
|
||||||
pack_key(&key, keynr, key_buff, end_key,
|
pack_key(&key, keynr, key_buff, end_key,
|
||||||
end_key_len),
|
end_key_len),
|
||||||
&end_range,0)))
|
&end_range,0)))
|
||||||
@ -1969,8 +1978,8 @@ int ha_berkeley::analyze(THD* thd, HA_CHECK_OPT* check_opt)
|
|||||||
free(stat);
|
free(stat);
|
||||||
stat=0;
|
stat=0;
|
||||||
}
|
}
|
||||||
if (file->stat(key_file[i], (void*) &stat, 0, 0))
|
if (key_file[i]->stat(key_file[i], (void*) &stat, 0, 0))
|
||||||
goto err;
|
goto err; /* purecov: inspected */
|
||||||
share->rec_per_key[i]= (stat->bt_ndata /
|
share->rec_per_key[i]= (stat->bt_ndata /
|
||||||
(stat->bt_nkeys ? stat->bt_nkeys : 1));
|
(stat->bt_nkeys ? stat->bt_nkeys : 1));
|
||||||
}
|
}
|
||||||
@ -1983,7 +1992,7 @@ int ha_berkeley::analyze(THD* thd, HA_CHECK_OPT* check_opt)
|
|||||||
stat=0;
|
stat=0;
|
||||||
}
|
}
|
||||||
if (file->stat(file, (void*) &stat, 0, 0))
|
if (file->stat(file, (void*) &stat, 0, 0))
|
||||||
goto err;
|
goto err; /* purecov: inspected */
|
||||||
}
|
}
|
||||||
pthread_mutex_lock(&share->mutex);
|
pthread_mutex_lock(&share->mutex);
|
||||||
share->rows=stat->bt_ndata;
|
share->rows=stat->bt_ndata;
|
||||||
@ -1997,9 +2006,9 @@ int ha_berkeley::analyze(THD* thd, HA_CHECK_OPT* check_opt)
|
|||||||
HA_ADMIN_OK);
|
HA_ADMIN_OK);
|
||||||
|
|
||||||
err:
|
err:
|
||||||
if (stat)
|
if (stat) /* purecov: inspected */
|
||||||
free(stat);
|
free(stat); /* purecov: inspected */
|
||||||
return HA_ADMIN_FAILED;
|
return HA_ADMIN_FAILED; /* purecov: inspected */
|
||||||
}
|
}
|
||||||
|
|
||||||
int ha_berkeley::optimize(THD* thd, HA_CHECK_OPT* check_opt)
|
int ha_berkeley::optimize(THD* thd, HA_CHECK_OPT* check_opt)
|
||||||
@ -2036,7 +2045,7 @@ int ha_berkeley::check(THD* thd, HA_CHECK_OPT* check_opt)
|
|||||||
tmp_file->set_bt_compare(tmp_file,
|
tmp_file->set_bt_compare(tmp_file,
|
||||||
(hidden_primary_key ? berkeley_cmp_hidden_key :
|
(hidden_primary_key ? berkeley_cmp_hidden_key :
|
||||||
berkeley_cmp_packed_key));
|
berkeley_cmp_packed_key));
|
||||||
file->app_private= (void*) (table->key_info+table->primary_key);
|
tmp_file->app_private= (void*) (table->key_info+table->primary_key);
|
||||||
fn_format(name_buff,share->table_name,"", ha_berkeley_ext, 2 | 4);
|
fn_format(name_buff,share->table_name,"", ha_berkeley_ext, 2 | 4);
|
||||||
if ((error=tmp_file->verify(tmp_file, name_buff, NullS, (FILE*) 0,
|
if ((error=tmp_file->verify(tmp_file, name_buff, NullS, (FILE*) 0,
|
||||||
hidden_primary_key ? 0 : DB_NOORDERCHK)))
|
hidden_primary_key ? 0 : DB_NOORDERCHK)))
|
||||||
@ -2196,7 +2205,7 @@ void ha_berkeley::get_status()
|
|||||||
{
|
{
|
||||||
share->org_rows=share->rows=
|
share->org_rows=share->rows=
|
||||||
table->max_rows ? table->max_rows : HA_BERKELEY_MAX_ROWS;
|
table->max_rows ? table->max_rows : HA_BERKELEY_MAX_ROWS;
|
||||||
if (!file->cursor(share->status_block, 0, &cursor, 0))
|
if (!share->status_block->cursor(share->status_block, 0, &cursor, 0))
|
||||||
{
|
{
|
||||||
DBT row;
|
DBT row;
|
||||||
char rec_buff[64];
|
char rec_buff[64];
|
||||||
|
@ -70,7 +70,7 @@ int ha_heap::open(const char *name, int mode, uint test_if_locked)
|
|||||||
}
|
}
|
||||||
mem_per_row += MY_ALIGN(table->reclength+1, sizeof(char*));
|
mem_per_row += MY_ALIGN(table->reclength+1, sizeof(char*));
|
||||||
max_rows = (ulong) (max_heap_table_size / mem_per_row);
|
max_rows = (ulong) (max_heap_table_size / mem_per_row);
|
||||||
file=heap_open(table->path,mode,
|
file=heap_open(name,mode,
|
||||||
table->keys,keydef,
|
table->keys,keydef,
|
||||||
table->reclength,
|
table->reclength,
|
||||||
((table->max_rows < max_rows && table->max_rows) ?
|
((table->max_rows < max_rows && table->max_rows) ?
|
||||||
@ -278,5 +278,5 @@ int ha_heap::create(const char *name, TABLE *form, HA_CREATE_INFO *create_info)
|
|||||||
|
|
||||||
{
|
{
|
||||||
char buff[FN_REFLEN];
|
char buff[FN_REFLEN];
|
||||||
return heap_create(fn_format(buff,name,"","",2));
|
return heap_create(fn_format(buff,name,"","",4+2));
|
||||||
}
|
}
|
||||||
|
@ -952,7 +952,7 @@ void sql_print_error(const char *format,...)
|
|||||||
#ifndef DBUG_OFF
|
#ifndef DBUG_OFF
|
||||||
{
|
{
|
||||||
char buff[1024];
|
char buff[1024];
|
||||||
vsnprintf(buff,sizeof(buff)-1,format,args);
|
my_vsnprintf(buff,sizeof(buff)-1,format,args);
|
||||||
DBUG_PRINT("error",("%s",buff));
|
DBUG_PRINT("error",("%s",buff));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -314,7 +314,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
|
|||||||
{ /* Impossible cond */
|
{ /* Impossible cond */
|
||||||
error=return_zero_rows(result, tables, fields,
|
error=return_zero_rows(result, tables, fields,
|
||||||
join.tmp_table_param.sum_func_count != 0 && !group,
|
join.tmp_table_param.sum_func_count != 0 && !group,
|
||||||
select_options,"Impossible WHERE",join.having,
|
select_options,"Impossible WHERE",having,
|
||||||
procedure);
|
procedure);
|
||||||
delete procedure;
|
delete procedure;
|
||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
@ -330,7 +330,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
|
|||||||
{
|
{
|
||||||
error=return_zero_rows(result, tables, fields, !group,
|
error=return_zero_rows(result, tables, fields, !group,
|
||||||
select_options,"No matching min/max row",
|
select_options,"No matching min/max row",
|
||||||
join.having,procedure);
|
having,procedure);
|
||||||
delete procedure;
|
delete procedure;
|
||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
}
|
}
|
||||||
@ -383,7 +383,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
|
|||||||
{
|
{
|
||||||
error=return_zero_rows(result,tables,fields,
|
error=return_zero_rows(result,tables,fields,
|
||||||
join.tmp_table_param.sum_func_count != 0 &&
|
join.tmp_table_param.sum_func_count != 0 &&
|
||||||
!group,0,"",join.having,procedure);
|
!group,0,"",having,procedure);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
if (!(thd->options & OPTION_BIG_SELECTS) &&
|
if (!(thd->options & OPTION_BIG_SELECTS) &&
|
||||||
@ -414,7 +414,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
|
|||||||
join.tmp_table_param.sum_func_count != 0 && !group,
|
join.tmp_table_param.sum_func_count != 0 && !group,
|
||||||
select_options,
|
select_options,
|
||||||
"Impossible WHERE noticed after reading const tables",
|
"Impossible WHERE noticed after reading const tables",
|
||||||
join.having,procedure);
|
having,procedure);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -531,7 +531,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
|
|||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
if ((err=(outparam->file->
|
if ((err=(outparam->file->
|
||||||
ha_open(index_file,
|
ha_open(unpack_filename(index_file,index_file),
|
||||||
(db_stat & HA_READ_ONLY ? O_RDONLY : O_RDWR),
|
(db_stat & HA_READ_ONLY ? O_RDONLY : O_RDWR),
|
||||||
(db_stat & HA_OPEN_TEMPORARY ? HA_OPEN_TMP_TABLE :
|
(db_stat & HA_OPEN_TEMPORARY ? HA_OPEN_TMP_TABLE :
|
||||||
((db_stat & HA_WAIT_IF_LOCKED) ||
|
((db_stat & HA_WAIT_IF_LOCKED) ||
|
||||||
|
Reference in New Issue
Block a user