Merge mysql.com:/home/jonas/src/mysql-5.0

into mysql.com:/home/jonas/src/mysql-5.0-ndb


BitKeeper/etc/logging_ok:
  auto-union
ndb/src/ndbapi/NdbDictionaryImpl.cpp:
  Auto merged
sql/ha_ndbcluster.cc:
  Auto merged
sql/ha_ndbcluster.h:
  Auto merged
sql/mysqld.cc:
  Auto merged
sql/sql_parse.cc:
  Auto merged
sql/sql_select.cc:
  Auto merged
This commit is contained in:
unknown 2005-05-02 15:16:40 +02:00
commit 27ba35b30e
67 changed files with 1583 additions and 569 deletions

View file

@ -19,8 +19,6 @@ if test -r /proc/cpuinfo ; then
if test -z "$model_name" ; then
model_name=`uname -m`
fi
else
exit 0
fi
case "$cpu_family--$model_name" in

View file

@ -50,6 +50,8 @@ dlenev@build.mysql.com
dlenev@jabberwock.localdomain
dlenev@mysql.com
ejonore@mc03.ndb.mysql.com
evgen@moonbone.(none)
evgen@moonbone.local
gbichot@production.mysql.com
gbichot@quadita2.mysql.com
gbichot@quadxeon.mysql.com

View file

@ -102,5 +102,10 @@ tags:
test:
cd mysql-test; ./mysql-test-run && ./mysql-test-run --ps-protocol
test-force:
cd mysql-test; \
mysql-test-run --force ;\
mysql-test-run --ps-protocol --force
# Don't update the files from bitkeeper
%::SCCS/s.%

View file

@ -727,7 +727,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
void (*func) (MYSQL_RES*, MYSQL_ROW, uint);
new_line = 1;
if (mysql_query(mysql, "show status") ||
if (mysql_query(mysql, "show /*!50002 GLOBAL */ status") ||
!(res = mysql_store_result(mysql)))
{
my_printf_error(0, "unable to show status; error: '%s'", MYF(ME_BELL),

View file

@ -646,8 +646,8 @@ m4_define([_AC_PROG_CXX_EXIT_DECLARATION],
'void exit (int);' \
'#include <stdlib.h>'
do
_AC_COMPILE_IFELSE([AC_LANG_PROGRAM([@%:@include <stdlib.h>
$ac_declaration],
_AC_COMPILE_IFELSE([AC_LANG_PROGRAM([$ac_declaration
@%:@include <stdlib.h>],
[exit (42);])],
[],
[continue])

View file

@ -116,8 +116,6 @@ AC_SUBST(SAVE_LDFLAGS)
AC_SUBST(SAVE_CXXLDFLAGS)
AC_SUBST(CXXLDFLAGS)
AC_PREREQ(2.58)dnl Minimum Autoconf version required.
#AC_ARG_PROGRAM # Automaticly invoked by AM_INIT_AUTOMAKE
AM_SANITY_CHECK
@ -1800,6 +1798,9 @@ If you are using gcc 2.8.# you should upgrade to egcs 1.0.3 or newer and try
again]);
fi
fi
AC_CHECK_TYPES([sigset_t, off_t], [], [], [#include <sys/types.h>])
AC_CHECK_TYPES([size_t], [], [], [#include <stdio.h>])
MYSQL_PTHREAD_YIELD
######################################################################

View file

@ -106,20 +106,33 @@ functions */
/* Type information */
#if defined(__EMX__) || !defined(HAVE_UINT)
#undef HAVE_UINT
#define HAVE_UINT
typedef unsigned short ushort;
typedef unsigned int uint;
#endif /* defined(__EMX__) || !defined(HAVE_UINT) */
typedef unsigned __int64 ulonglong; /* Microsofts 64 bit types */
typedef __int64 longlong;
#ifndef HAVE_SIGSET_T
typedef int sigset_t;
#endif
#define longlong_defined
/* off_t should not be __int64 because of conflicts in header files;
Use my_off_t or os_off_t instead */
/*
off_t should not be __int64 because of conflicts in header files;
Use my_off_t or os_off_t instead
*/
#ifndef HAVE_OFF_T
typedef long off_t;
#endif
typedef __int64 os_off_t;
#ifdef _WIN64
typedef UINT_PTR rf_SetTimer;
#else
#ifndef HAVE_SIZE_T
typedef unsigned int size_t;
#endif
typedef uint rf_SetTimer;
#endif

View file

@ -425,6 +425,8 @@ int __void__;
#endif
#if defined(__EMX__) || !defined(HAVE_UINT)
#undef HAVE_UINT
#define HAVE_UINT
typedef unsigned int uint;
typedef unsigned short ushort;
#endif

View file

@ -638,6 +638,7 @@ extern uint dirname_part(my_string to,const char *name);
extern uint dirname_length(const char *name);
#define base_name(A) (A+dirname_length(A))
extern int test_if_hard_path(const char *dir_name);
extern my_bool has_path(const char *name);
extern char *convert_dirname(char *to, const char *from, const char *from_end);
extern void to_unix_path(my_string name);
extern my_string fn_ext(const char *name);

View file

@ -31,6 +31,7 @@
#define __GNU_LIBRARY__ /* Skip warnings in getopt.h */
#endif
#include <my_getopt.h>
#include <assert.h>
#if INT_MAX > 32767
#define BITS_SAVED 32
@ -1996,7 +1997,9 @@ static void write_bits (register ulong value, register uint bits)
{
reg3 uint byte_buff;
bits= (uint) -file_buffer.bits;
byte_buff=file_buffer.current_byte | (uint) (value >> bits);
DBUG_ASSERT(bits <= 8 * sizeof(value));
byte_buff= (file_buffer.current_byte |
((bits != 8 * sizeof(value)) ? (uint) (value >> bits) : 0));
#if BITS_SAVED == 32
*file_buffer.pos++= (byte) (byte_buff >> 24) ;
*file_buffer.pos++= (byte) (byte_buff >> 16) ;
@ -2004,7 +2007,9 @@ static void write_bits (register ulong value, register uint bits)
*file_buffer.pos++= (byte) (byte_buff >> 8) ;
*file_buffer.pos++= (byte) byte_buff;
value&=(1 << bits)-1;
DBUG_ASSERT(bits <= 8 * sizeof(ulong));
if (bits != 8 * sizeof(value))
value&= (((ulong) 1) << bits) - 1;
#if BITS_SAVED == 16
if (bits >= sizeof(uint))
{

View file

@ -80,7 +80,7 @@ MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking)
continue; /* Skip comments */
}
if (!test_if_hard_path(buff))
if (!has_path(buff))
{
VOID(strmake(name_buff+dir_length,buff,
sizeof(name_buff)-1-dir_length));

View file

@ -192,6 +192,8 @@ select count(*) from t3;
count(*)
1199
rename table t3 to t4;
Warnings:
Error 7 Error on rename of './test/t3.ARN' to './test/t4.ARN' (Errcode: 2)
select * from t4 where fld3='bonfire';
auto fld1 companynr fld3 fld4 fld5 fld6
1191 068504 00 bonfire corresponds positively

View file

@ -128,3 +128,20 @@ t2.value64=t1.value64;
value64 value32 value64 value32
9223372036854775807 2 9223372036854775807 4
drop table t1, t2;
create table t1 select 1 as 'a';
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` bigint(1) NOT NULL default '0'
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
create table t1 select 9223372036854775809 as 'a';
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` bigint(19) unsigned NOT NULL default '0'
) ENGINE=MyISAM DEFAULT CHARSET=latin1
select * from t1;
a
9223372036854775809
drop table t1;

View file

@ -4,12 +4,11 @@ CAST(1-2 AS UNSIGNED)
select CAST(CAST(1-2 AS UNSIGNED) AS SIGNED INTEGER);
CAST(CAST(1-2 AS UNSIGNED) AS SIGNED INTEGER)
-1
select CONVERT('-1',UNSIGNED);
CONVERT('-1',UNSIGNED)
18446744073709551615
select CAST('10 ' as unsigned integer);
CAST('10 ' as unsigned integer)
10
Warnings:
Warning 1292 Truncated incorrect INTEGER value: '10 '
select cast(-5 as unsigned) | 1, cast(-5 as unsigned) & -1;
cast(-5 as unsigned) | 1 cast(-5 as unsigned) & -1
18446744073709551611 18446744073709551611
@ -100,6 +99,41 @@ select 10E+0+'a';
10
Warnings:
Warning 1292 Truncated incorrect DOUBLE value: 'a'
select cast('18446744073709551616' as unsigned);
cast('18446744073709551616' as unsigned)
18446744073709551615
Warnings:
Warning 1292 Truncated incorrect INTEGER value: '18446744073709551616'
select cast('18446744073709551616' as signed);
cast('18446744073709551616' as signed)
-1
Warnings:
Warning 1292 Truncated incorrect INTEGER value: '18446744073709551616'
select cast('9223372036854775809' as signed);
cast('9223372036854775809' as signed)
-9223372036854775807
Warnings:
Warning 1105 Cast to signed converted positive out-of-range integer to it's negative complement
select cast('-1' as unsigned);
cast('-1' as unsigned)
18446744073709551615
Warnings:
Warning 1105 Cast to unsigned converted negative integer to it's positive complement
select cast('abc' as signed);
cast('abc' as signed)
0
Warnings:
Warning 1292 Truncated incorrect INTEGER value: 'abc'
select cast('1a' as signed);
cast('1a' as signed)
1
Warnings:
Warning 1292 Truncated incorrect INTEGER value: '1a'
select cast('' as signed);
cast('' as signed)
0
Warnings:
Warning 1292 Truncated incorrect INTEGER value: ''
set names binary;
select cast(_latin1'test' as char character set latin2);
cast(_latin1'test' as char character set latin2)
@ -255,6 +289,39 @@ timediff(cast('2004-12-30 12:00:00' as time), '12:00:00')
select timediff(cast('1 12:00:00' as time), '12:00:00');
timediff(cast('1 12:00:00' as time), '12:00:00')
24:00:00
select cast(18446744073709551615 as unsigned);
cast(18446744073709551615 as unsigned)
18446744073709551615
select cast(18446744073709551615 as signed);
cast(18446744073709551615 as signed)
-1
select cast('18446744073709551615' as unsigned);
cast('18446744073709551615' as unsigned)
18446744073709551615
select cast('18446744073709551615' as signed);
cast('18446744073709551615' as signed)
-1
Warnings:
Warning 1105 Cast to signed converted positive out-of-range integer to it's negative complement
select cast('9223372036854775807' as signed);
cast('9223372036854775807' as signed)
9223372036854775807
select cast(concat('184467440','73709551615') as unsigned);
cast(concat('184467440','73709551615') as unsigned)
18446744073709551615
select cast(concat('184467440','73709551615') as signed);
cast(concat('184467440','73709551615') as signed)
-1
Warnings:
Warning 1105 Cast to signed converted positive out-of-range integer to it's negative complement
select cast(repeat('1',20) as unsigned);
cast(repeat('1',20) as unsigned)
11111111111111111111
select cast(repeat('1',20) as signed);
cast(repeat('1',20) as signed)
-7335632962598440505
Warnings:
Warning 1105 Cast to signed converted positive out-of-range integer to it's negative complement
select cast('1.2' as decimal(3,2));
cast('1.2' as decimal(3,2))
1.20

View file

@ -801,5 +801,5 @@ CREATE TABLE t1 (st varchar(100));
INSERT INTO t1 VALUES ("Fake string");
CREATE TABLE t2 (geom GEOMETRY NOT NULL, SPATIAL KEY gk(geom));
INSERT INTO t2 SELECT GeomFromText(st) FROM t1;
ERROR HY000: Unknown error
ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
drop table t1, t2;

View file

@ -461,9 +461,9 @@ Note 1003 select issimple(multipoint(point(3,6),point(4,10))) AS `issimple(Multi
create table t1 (a geometry not null);
insert into t1 values (GeomFromText('Point(1 2)'));
insert into t1 values ('Garbage');
ERROR HY000: Unknown error
ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
insert IGNORE into t1 values ('Garbage');
ERROR HY000: Unknown error
ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
alter table t1 add spatial index(a);
drop table t1;
create table t1(a geometry not null, spatial index(a));
@ -655,3 +655,13 @@ t1 where object_id=85984;
object_id geometrytype(geo) ISSIMPLE(GEO) ASTEXT(centroid(geo))
85984 MULTIPOLYGON 0 POINT(-114.87787186923 36.33101763469)
drop table t1;
create table t1 (fl geometry);
insert into t1 values (1);
ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
insert into t1 values (1.11);
ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
insert into t1 values ("qwerty");
ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
insert into t1 values (pointfromtext('point(1,1)'));
ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
drop table t1;

View file

@ -702,3 +702,12 @@ c
val-74
val-98
drop table t1,t2;
create table t1 (b int4 unsigned not null);
insert into t1 values(3000000000);
select * from t1;
b
3000000000
select min(b) from t1;
min(b)
3000000000
drop table t1;

View file

@ -1,3 +1,4 @@
drop table if exists t1;
create table t1 (c1 char(5) unique not null, c2 int, stamp timestamp) engine=innodb;
select * from t1;
c1 c2 stamp

View file

@ -13,6 +13,26 @@ a
show status like 'handler_discover%';
Variable_name Value
Handler_discover 0
select * from t1;
a
2
drop table t1;
create table t1 (a int) engine=ndbcluster;
insert into t1 value (2);
select * from t1;
a
2
show status like 'handler_discover%';
Variable_name Value
Handler_discover 0
drop table t1;
create table t1 (a int) engine=ndbcluster;
insert into t1 value (2);
select * from t1;
ERROR HY000: Got error 241 'Invalid schema object version' from ndbcluster
select * from t1;
a
2
flush status;
select * from t1;
a
@ -20,7 +40,7 @@ a
update t1 set a=3 where a=2;
show status like 'handler_discover%';
Variable_name Value
Handler_discover 1
Handler_discover 0
create table t3 (a int not null primary key, b varchar(22),
c int, last_col text) engine=ndb;
insert into t3 values(1, 'Hi!', 89, 'Longtext column');

View file

@ -97,3 +97,29 @@ Variable_name Value
Created_tmp_disk_tables 0
Created_tmp_tables 2
drop table t1;
create temporary table t1 as select 'This is temp. table' A;
create view t1 as select 'This is view' A;
select * from t1;
A
This is temp. table
show create table t1;
Table Create Table
t1 CREATE TEMPORARY TABLE `t1` (
`A` varchar(19) NOT NULL default ''
) ENGINE=MyISAM DEFAULT CHARSET=latin1
show create view t1;
View Create View
t1 CREATE ALGORITHM=UNDEFINED VIEW `test`.`t1` AS select _latin1'This is view' AS `A`
drop view t1;
select * from t1;
A
This is temp. table
create view t1 as select 'This is view again' A;
select * from t1;
A
This is temp. table
drop table t1;
select * from t1;
A
This is view again
drop view t1;

View file

@ -764,3 +764,23 @@ non PS, 1.0 in parameter 1.0
PS, 1.0 in parameter 1.0
deallocate prepare stmt;
drop table t1;
create table t1 (
strippedproductid char(15) not null default '',
zlevelprice decimal(10,2) default null,
primary key (strippedproductid)
);
create table t2 (
productid char(15) not null default '',
zlevelprice char(21) default null,
primary key (productid)
);
insert into t1 values ('002trans','49.99');
insert into t1 values ('003trans','39.98');
insert into t1 values ('004trans','31.18');
insert INTO t2 SELECT * FROM t1;
select * from t2;
productid zlevelprice
002trans 49.99
003trans 39.98
004trans 31.18
drop table t1, t2;

View file

@ -182,3 +182,44 @@ coercibility(@v1) coercibility(@v2) coercibility(@v3) coercibility(@v4)
set session @honk=99;
set one_shot @honk=99;
ERROR HY000: The 'SET ONE_SHOT' syntax is reserved for purposes internal to the MySQL server
set @first_var= NULL;
create table t1 select @first_var;
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`@first_var` longblob
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
set @first_var= cast(NULL as signed integer);
create table t1 select @first_var;
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`@first_var` bigint(20) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
set @first_var= NULL;
create table t1 select @first_var;
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`@first_var` bigint(20) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
set @first_var= concat(NULL);
create table t1 select @first_var;
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`@first_var` longblob
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
set @first_var=1;
set @first_var= cast(NULL as CHAR);
create table t1 select @first_var;
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`@first_var` longtext
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;

View file

@ -104,3 +104,13 @@ t2.value64=t1.value64;
drop table t1, t2;
#
# Test of CREATE ... SELECT and unsigned integers
#
create table t1 select 1 as 'a';
show create table t1;
drop table t1;
create table t1 select 9223372036854775809 as 'a';
show create table t1;
select * from t1;
drop table t1;

View file

@ -4,7 +4,6 @@
select CAST(1-2 AS UNSIGNED);
select CAST(CAST(1-2 AS UNSIGNED) AS SIGNED INTEGER);
select CONVERT('-1',UNSIGNED);
select CAST('10 ' as unsigned integer);
select cast(-5 as unsigned) | 1, cast(-5 as unsigned) & -1;
select cast(-5 as unsigned) -1, cast(-5 as unsigned) + 1;
@ -34,6 +33,15 @@ select 10+'a';
select 10.0+cast('a' as decimal);
select 10E+0+'a';
# out-of-range cases
select cast('18446744073709551616' as unsigned);
select cast('18446744073709551616' as signed);
select cast('9223372036854775809' as signed);
select cast('-1' as unsigned);
select cast('abc' as signed);
select cast('1a' as signed);
select cast('' as signed);
#
# Character set convertion
#
@ -132,6 +140,22 @@ select timediff(cast('2004-12-30 12:00:00' as time), '12:00:00');
# Still we should not throw away "days" part of time value
select timediff(cast('1 12:00:00' as time), '12:00:00');
#
# Bug #7036: Casting from string to unsigned would cap value of result at
# maximum signed value instead of maximum unsigned value
#
select cast(18446744073709551615 as unsigned);
select cast(18446744073709551615 as signed);
select cast('18446744073709551615' as unsigned);
select cast('18446744073709551615' as signed);
select cast('9223372036854775807' as signed);
select cast(concat('184467440','73709551615') as unsigned);
select cast(concat('184467440','73709551615') as signed);
select cast(repeat('1',20) as unsigned);
select cast(repeat('1',20) as signed);
#decimal-related additions
select cast('1.2' as decimal(3,2));
select 1e18 * cast('1.2' as decimal(3,2));

View file

@ -168,6 +168,6 @@ drop table t1;
CREATE TABLE t1 (st varchar(100));
INSERT INTO t1 VALUES ("Fake string");
CREATE TABLE t2 (geom GEOMETRY NOT NULL, SPATIAL KEY gk(geom));
--error 1105
--error 1416
INSERT INTO t2 SELECT GeomFromText(st) FROM t1;
drop table t1, t2;

View file

@ -165,9 +165,9 @@ explain extended select issimple(MultiPoint(Point(3, 6), Point(4, 10))), issimpl
create table t1 (a geometry not null);
insert into t1 values (GeomFromText('Point(1 2)'));
-- error 1105
-- error 1416
insert into t1 values ('Garbage');
-- error 1105
-- error 1416
insert IGNORE into t1 values ('Garbage');
alter table t1 add spatial index(a);
@ -359,3 +359,15 @@ select object_id, geometrytype(geo), ISSIMPLE(GEO), ASTEXT(centroid(geo)) from
t1 where object_id=85984;
drop table t1;
create table t1 (fl geometry);
--error 1416
insert into t1 values (1);
--error 1416
insert into t1 values (1.11);
--error 1416
insert into t1 values ("qwerty");
--error 1416
insert into t1 values (pointfromtext('point(1,1)'));
drop table t1;

View file

@ -515,3 +515,10 @@ explain select c from t2 where a = 2 and b = 'val-2' group by c;
select c from t2 where a = 2 and b = 'val-2' group by c;
drop table t1,t2;
# Test for BUG#9298 "Wrong handling of int4 unsigned columns in GROUP functions"
# (the actual problem was with protocol code, not GROUP BY)
create table t1 (b int4 unsigned not null);
insert into t1 values(3000000000);
select * from t1;
select min(b) from t1;
drop table t1;

View file

@ -2,6 +2,10 @@
# embedded server ignores 'delayed', so skip this
-- source include/not_embedded.inc
--disable_warnings
drop table if exists t1;
--enable_warnings
#
# Bug #1078
#

View file

@ -18,6 +18,30 @@ select * from t1;
select * from t2;
show status like 'handler_discover%';
# Check dropping and recreating table on same server
connect (con1,localhost,,,test);
connect (con2,localhost,,,test);
connection con1;
select * from t1;
connection con2;
drop table t1;
create table t1 (a int) engine=ndbcluster;
insert into t1 value (2);
connection con1;
select * from t1;
# Check dropping and recreating table on different server
connection server2;
show status like 'handler_discover%';
drop table t1;
create table t1 (a int) engine=ndbcluster;
insert into t1 value (2);
connection server1;
# Currently a retry is required remotely
--error 1296
select * from t1;
select * from t1;
# Connect to server2 and use the tables from there
connection server2;
flush status;

View file

@ -89,3 +89,18 @@ flush status;
select * from t1 group by d;
show status like "created_tmp%tables";
drop table t1;
# Fix for BUG#8921: Check that temporary table is ingored by view commands.
create temporary table t1 as select 'This is temp. table' A;
create view t1 as select 'This is view' A;
select * from t1;
show create table t1;
show create view t1;
drop view t1;
select * from t1;
create view t1 as select 'This is view again' A;
select * from t1;
drop table t1;
select * from t1;
drop view t1;

View file

@ -343,3 +343,31 @@ execute stmt using @a;
select * from t1;
deallocate prepare stmt;
drop table t1;
#
# A test case for Bug#5673 "Rounding problem in 4.0.21 inserting decimal
# value into a char field": this is a regression bug in 4.0 tree caused by
# a fix for some other decimal conversion issue. The patch never was
# approved to get into 4.0 (maybe because it was considered too intrusive)
#
create table t1 (
strippedproductid char(15) not null default '',
zlevelprice decimal(10,2) default null,
primary key (strippedproductid)
);
create table t2 (
productid char(15) not null default '',
zlevelprice char(21) default null,
primary key (productid)
);
insert into t1 values ('002trans','49.99');
insert into t1 values ('003trans','39.98');
insert into t1 values ('004trans','31.18');
insert INTO t2 SELECT * FROM t1;
select * from t2;
drop table t1, t2;

View file

@ -119,3 +119,29 @@ select coercibility(@v1),coercibility(@v2),coercibility(@v3),coercibility(@v4);
set session @honk=99;
--error 1382
set one_shot @honk=99;
#
# Bug #6598: problem with cast(NULL as signed integer);
#
set @first_var= NULL;
create table t1 select @first_var;
show create table t1;
drop table t1;
set @first_var= cast(NULL as signed integer);
create table t1 select @first_var;
show create table t1;
drop table t1;
set @first_var= NULL;
create table t1 select @first_var;
show create table t1;
drop table t1;
set @first_var= concat(NULL);
create table t1 select @first_var;
show create table t1;
drop table t1;
set @first_var=1;
set @first_var= cast(NULL as CHAR);
create table t1 select @first_var;
show create table t1;
drop table t1;

View file

@ -409,6 +409,56 @@ static int search_default_file(Process_option_func opt_handler,
}
/*
Skip over keyword and get argument after keyword
SYNOPSIS
get_argument()
keyword Include directive keyword
kwlen Length of keyword
ptr Pointer to the keword in the line under process
line line number
RETURN
0 error
# Returns pointer to the argument after the keyword.
*/
static char *get_argument(const char *keyword, uint kwlen,
char *ptr, char *name, uint line)
{
char *end;
/* Skip over "include / includedir keyword" and following whitespace */
for (ptr+= kwlen - 1;
my_isspace(&my_charset_latin1, ptr[0]);
ptr++)
{}
/*
Trim trailing whitespace from directory name
The -1 below is for the newline added by fgets()
Note that my_isspace() is true for \r and \n
*/
for (end= ptr + strlen(ptr) - 1;
my_isspace(&my_charset_latin1, *(end - 1));
end--)
{}
end[0]= 0; /* Cut off end space */
/* Print error msg if there is nothing after !include* directive */
if (end <= ptr)
{
fprintf(stderr,
"error: Wrong '!%s' directive in config file: %s at line %d\n",
keyword, name, line);
return 0;
}
return ptr;
}
/*
Open a configuration file (if exists) and read given options from it
@ -497,40 +547,34 @@ static int search_default_file_with_ext(Process_option_func opt_handler,
continue;
/* Configuration File Directives */
if ((*ptr == '!') && (recursion_level < max_recursion_level))
if ((*ptr == '!'))
{
if (recursion_level >= max_recursion_level)
{
for (end= ptr + strlen(ptr) - 1;
my_isspace(&my_charset_latin1, *(end - 1));
end--)
{}
end[0]= 0;
fprintf(stderr,
"Warning: skipping '%s' directive as maximum include"
"recursion level was reached in file %s at line %d\n",
ptr, name, line);
continue;
}
/* skip over `!' and following whitespace */
for (++ptr; my_isspace(&my_charset_latin1, ptr[0]); ptr++)
{}
if ((!strncmp(ptr, includedir_keyword, sizeof(includedir_keyword) - 1))
&& my_isspace(&my_charset_latin1, ptr[sizeof(includedir_keyword) - 1]))
if ((!strncmp(ptr, includedir_keyword,
sizeof(includedir_keyword) - 1)) &&
my_isspace(&my_charset_latin1, ptr[sizeof(includedir_keyword) - 1]))
{
/* skip over "includedir" and following whitespace */
for (ptr+= sizeof(includedir_keyword) - 1;
my_isspace(&my_charset_latin1, ptr[0]); ptr++)
{}
/* trim trailing whitespace from directory name */
end= ptr + strlen(ptr) - 1;
/* fgets() stores the newline character in the buffer */
if ((end[0] == '\n') || (end[0] == '\r') ||
my_isspace(&my_charset_latin1, end[0]))
{
for (; my_isspace(&my_charset_latin1, *(end - 1)); end--)
{}
end[0]= 0;
}
/* print error msg if there is nothing after !includedir directive */
if (end == ptr)
{
fprintf(stderr,
"error: Wrong !includedir directive in config "
"file: %s at line %d\n",
name,line);
goto err;
}
if (!(ptr= get_argument(includedir_keyword,
sizeof(includedir_keyword),
ptr, name, line)))
goto err;
if (!(search_dir= my_dir(ptr, MYF(MY_WME))))
goto err;
@ -559,28 +603,13 @@ static int search_default_file_with_ext(Process_option_func opt_handler,
my_dirend(search_dir);
}
else if ((!strncmp(ptr, include_keyword, sizeof(include_keyword) - 1))
&& my_isspace(&my_charset_latin1, ptr[sizeof(include_keyword) - 1]))
else if ((!strncmp(ptr, include_keyword, sizeof(include_keyword) - 1)) &&
my_isspace(&my_charset_latin1, ptr[sizeof(include_keyword)-1]))
{
/* skip over `include' and following whitespace */
for (ptr+= sizeof(include_keyword) - 1;
my_isspace(&my_charset_latin1, ptr[0]); ptr++)
{}
/* trim trailing whitespace from filename */
end= ptr + strlen(ptr) - 1;
for (; my_isspace(&my_charset_latin1, *(end - 1)) ; end--)
{}
end[0]= 0;
if (end == ptr)
{
fprintf(stderr,
"error: Wrong !include directive in config "
"file: %s at line %d\n",
name,line);
goto err;
}
if (!(ptr= get_argument(include_keyword,
sizeof(include_keyword), ptr,
name, line)))
goto err;
search_default_file_with_ext(opt_handler, handler_ctx, "", "", ptr,
recursion_level + 1);
@ -588,14 +617,6 @@ static int search_default_file_with_ext(Process_option_func opt_handler,
continue;
}
else
if (recursion_level >= max_recursion_level)
{
fprintf(stderr,
"warning: skipping !include directive as maximum include"
"recursion level was reached in file %s at line %d\n",
name, line);
}
if (*ptr == '[') /* Group name */
{

View file

@ -1025,8 +1025,8 @@ static void reg_requests(KEY_CACHE *keycache, BLOCK_LINK *block, int count)
for a too long time (this time is determined by parameter age_threshold).
*/
static inline void unreg_request(KEY_CACHE *keycache,
BLOCK_LINK *block, int at_end)
static void unreg_request(KEY_CACHE *keycache,
BLOCK_LINK *block, int at_end)
{
if (! --block->requests)
{
@ -1045,10 +1045,13 @@ static inline void unreg_request(KEY_CACHE *keycache,
}
link_block(keycache, block, hot, (my_bool)at_end);
block->last_hit_time= keycache->keycache_time;
if (++keycache->keycache_time - keycache->used_ins->last_hit_time >
keycache->keycache_time++;
block= keycache->used_ins;
/* Check if we should link a hot block to the warm block */
if (block && keycache->keycache_time - block->last_hit_time >
keycache->age_threshold)
{
block= keycache->used_ins;
unlink_block(keycache, block);
link_block(keycache, block, 0, 0);
if (block->temperature != BLOCK_WARM)

View file

@ -192,3 +192,25 @@ int test_if_hard_path(register const char *dir_name)
return FALSE;
#endif
} /* test_if_hard_path */
/*
Test if a name contains an (absolute or relative) path.
SYNOPSIS
has_path()
name The name to test.
RETURN
TRUE name contains a path.
FALSE name does not contain a path.
*/
my_bool has_path(const char *name)
{
return test(strchr(name, FN_LIBCHAR))
#ifdef FN_DEVCHAR
|| test(strchr(name, FN_DEVCHAR))
#endif
;
}

View file

@ -76,8 +76,11 @@ public:
Changed, ///< The object has been modified in memory
///< and has to be commited in NDB Kernel for
///< changes to take effect
Retrieved ///< The object exist and has been read
Retrieved, ///< The object exist and has been read
///< into main memory from NDB Kernel
Invalid ///< The object has been invalidated
///< and should not be used
};
/**

View file

@ -1528,6 +1528,7 @@ int NdbDictionaryImpl::alterTable(NdbTableImpl &impl)
// If in local cache it must be in global
if (!cachedImpl)
abort();
cachedImpl->m_status = NdbDictionary::Object::Invalid;
m_globalHash->drop(cachedImpl);
m_globalHash->unlock();
}
@ -1832,8 +1833,8 @@ NdbDictionaryImpl::dropTable(const char * name)
DBUG_PRINT("info",("INCOMPATIBLE_VERSION internal_name: %s", internalTableName));
m_localHash.drop(internalTableName);
m_globalHash->lock();
tab->m_status = NdbDictionary::Object::Invalid;
m_globalHash->drop(tab);
m_globalHash->unlock();
DBUG_RETURN(dropTable(name));
@ -1877,10 +1878,11 @@ NdbDictionaryImpl::dropTable(NdbTableImpl & impl)
int ret = m_receiver.dropTable(impl);
if(ret == 0 || m_error.code == 709){
const char * internalTableName = impl.m_internalName.c_str();
m_localHash.drop(internalTableName);
m_globalHash->lock();
impl.m_status = NdbDictionary::Object::Invalid;
m_globalHash->drop(&impl);
m_globalHash->unlock();
@ -1978,6 +1980,7 @@ NdbDictionaryImpl::invalidateObject(NdbTableImpl & impl)
m_localHash.drop(internalTableName);
m_globalHash->lock();
impl.m_status = NdbDictionary::Object::Invalid;
m_globalHash->drop(&impl);
m_globalHash->unlock();
return 0;
@ -2244,8 +2247,8 @@ NdbDictionaryImpl::dropIndex(const char * indexName,
m_ndb.internalizeTableName(indexName); // Index is also a table
m_localHash.drop(internalIndexName);
m_globalHash->lock();
idx->m_table->m_status = NdbDictionary::Object::Invalid;
m_globalHash->drop(idx->m_table);
m_globalHash->unlock();
return dropIndex(indexName, tableName);
@ -2279,8 +2282,8 @@ NdbDictionaryImpl::dropIndex(NdbIndexImpl & impl, const char * tableName)
int ret = m_receiver.dropIndex(impl, *timpl);
if(ret == 0){
m_localHash.drop(internalIndexName);
m_globalHash->lock();
impl.m_table->m_status = NdbDictionary::Object::Invalid;
m_globalHash->drop(impl.m_table);
m_globalHash->unlock();
}

View file

@ -447,35 +447,6 @@ const char **ha_archive::bas_ext() const
}
/*
Rename all files that this handler defines in bas_ext list
NOTE Don't care if the .arn file is missing
*/
int ha_archive::rename_table(const char * from, const char * to)
{
DBUG_ENTER("ha_archive::rename_table");
DBUG_PRINT("enter", ("from: %s, to: %s", from, to));
for (const char **ext=bas_ext(); *ext ; ext++)
{
// Check if the .arn file exists before rename
if (!my_strcasecmp(system_charset_info, *ext, ARN))
{
char name[FN_REFLEN];
(void)strxnmov(name, FN_REFLEN, from, ARN, NullS);
if (access(name, F_OK))
{
DBUG_PRINT("info", ("%s does not exist on disk, skipping it", name));
continue;
}
}
if (rename_file_ext(from,to,*ext))
DBUG_RETURN(my_errno);
}
DBUG_RETURN(0);
}
/*
When opening a file we:
Create/get our shared structure.

View file

@ -104,7 +104,6 @@ public:
int end_bulk_insert();
THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to,
enum thr_lock_type lock_type);
int rename_table(const char * from, const char * to);
};
handlerton *archive_db_init(void);

View file

@ -7267,12 +7267,38 @@ void Field_geom::sql_type(String &res) const
}
int Field_geom::store(double nr)
{
my_message(ER_CANT_CREATE_GEOMETRY_OBJECT,
ER(ER_CANT_CREATE_GEOMETRY_OBJECT), MYF(0));
return -1;
}
int Field_geom::store(longlong nr)
{
my_message(ER_CANT_CREATE_GEOMETRY_OBJECT,
ER(ER_CANT_CREATE_GEOMETRY_OBJECT), MYF(0));
return -1;
}
int Field_geom::store_decimal(const my_decimal *)
{
my_message(ER_CANT_CREATE_GEOMETRY_OBJECT,
ER(ER_CANT_CREATE_GEOMETRY_OBJECT), MYF(0));
return -1;
}
int Field_geom::store(const char *from, uint length, CHARSET_INFO *cs)
{
if (!length)
bzero(ptr, Field_blob::pack_length());
else
{
if (from == Geometry::bad_geometry_data.ptr())
goto err;
// Check given WKB
uint32 wkb_type;
if (length < SRID_SIZE + WKB_HEADER_SIZE + SIZEOF_STORED_DOUBLE*2)
@ -7280,7 +7306,7 @@ int Field_geom::store(const char *from, uint length, CHARSET_INFO *cs)
wkb_type= uint4korr(from + WKB_HEADER_SIZE);
if (wkb_type < (uint32) Geometry::wkb_point ||
wkb_type > (uint32) Geometry::wkb_end)
return -1;
goto err;
Field_blob::store_length(length);
if (table->copy_blobs || length <= MAX_FIELD_WIDTH)
{ // Must make a copy
@ -7293,6 +7319,8 @@ int Field_geom::store(const char *from, uint length, CHARSET_INFO *cs)
err:
bzero(ptr, Field_blob::pack_length());
my_message(ER_CANT_CREATE_GEOMETRY_OBJECT,
ER(ER_CANT_CREATE_GEOMETRY_OBJECT), MYF(0));
return -1;
}

View file

@ -118,6 +118,7 @@ public:
String *val_int_as_str(String *val_buffer, my_bool unsigned_flag);
virtual Item_result result_type () const=0;
virtual Item_result cmp_type () const { return result_type(); }
virtual Item_result cast_to_int_type () const { return result_type(); }
static enum_field_types field_type_merge(enum_field_types, enum_field_types);
static Item_result result_merge_type(enum_field_types);
bool eq(Field *field)
@ -1189,9 +1190,9 @@ public:
enum_field_types type() const { return FIELD_TYPE_GEOMETRY; }
void sql_type(String &str) const;
int store(const char *to, uint length, CHARSET_INFO *charset);
int store(double nr) { return 1; }
int store(longlong nr) { return 1; }
int store_decimal(const my_decimal *) { return 1; }
int store(double nr);
int store(longlong nr);
int store_decimal(const my_decimal *);
void get_key_image(char *buff,uint length,imagetype type);
};
#endif /*HAVE_SPATIAL*/
@ -1216,6 +1217,7 @@ public:
}
enum_field_types type() const { return FIELD_TYPE_STRING; }
enum Item_result cmp_type () const { return INT_RESULT; }
enum Item_result cast_to_int_type () const { return INT_RESULT; }
enum ha_base_keytype key_type() const;
int store(const char *to,uint length,CHARSET_INFO *charset);
int store(double nr);

View file

@ -25,7 +25,7 @@
#include "ha_blackhole.h"
static const char *ha_black_hole_exts[] = {
static const char *ha_blackhole_exts[] = {
NullS
};

View file

@ -1632,7 +1632,7 @@ innobase_report_binlog_offset_and_commit(
#endif /* HAVE_REPLICATION */
trx->flush_log_later = TRUE;
innobase_commit(thd, trx_handle);
innobase_commit(thd, TRUE);
trx->flush_log_later = FALSE;

View file

@ -400,6 +400,7 @@ int ha_myisammrg::create(const char *name, register TABLE *form,
const char **table_names, **pos;
TABLE_LIST *tables= (TABLE_LIST*) create_info->merge_list.first;
THD *thd= current_thd;
uint dirlgt= dirname_length(name);
DBUG_ENTER("ha_myisammrg::create");
if (!(table_names= (const char**)
@ -413,11 +414,30 @@ int ha_myisammrg::create(const char *name, register TABLE *form,
tbl= find_temporary_table(thd, tables->db, tables->table_name);
if (!tbl)
{
uint length= my_snprintf(buff,FN_REFLEN,"%s%s/%s",
mysql_real_data_home,
/*
Construct the path to the MyISAM table. Try to meet two conditions:
1.) Allow to include MyISAM tables from different databases, and
2.) allow for moving DATADIR around in the file system.
The first means that we need paths in the .MRG file. The second
means that we should not have absolute paths in the .MRG file.
The best, we can do, is to use 'mysql_data_home', which is '.'
in mysqld and may be an absolute path in an embedded server.
This means that it might not be possible to move the DATADIR of
an embedded server without changing the paths in the .MRG file.
*/
uint length= my_snprintf(buff, FN_REFLEN, "%s/%s/%s", mysql_data_home,
tables->db, tables->table_name);
if (!(table_name= thd->strmake(buff, length)))
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
/*
If a MyISAM table is in the same directory as the MERGE table,
we use the table name without a path. This means that the
DATADIR can easily be moved even for an embedded server as long
as the MyISAM tables are from the same database as the MERGE table.
*/
if ((dirname_length(buff) == dirlgt) && ! memcmp(buff, name, dirlgt))
table_name= tables->table_name;
else
if (! (table_name= thd->strmake(buff, length)))
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
}
else
table_name= (*tbl)->s->path;

View file

@ -418,11 +418,28 @@ void ha_ndbcluster::no_uncommitted_rows_reset(THD *thd)
# The mapped error code
*/
void ha_ndbcluster::invalidateDictionaryCache()
void ha_ndbcluster::invalidate_dictionary_cache(bool global)
{
NDBDICT *dict= get_ndb()->getDictionary();
DBUG_ENTER("invalidate_dictionary_cache");
DBUG_PRINT("info", ("invalidating %s", m_tabname));
dict->invalidateTable(m_tabname);
if (global)
{
const NDBTAB *tab= dict->getTable(m_tabname);
if (!tab)
DBUG_VOID_RETURN;
if (tab->getObjectStatus() == NdbDictionary::Object::Invalid)
{
// Global cache has already been invalidated
dict->removeCachedTable(m_tabname);
global= FALSE;
}
else
dict->invalidateTable(m_tabname);
}
else
dict->removeCachedTable(m_tabname);
table->s->version=0L; /* Free when thread is ready */
/* Invalidate indexes */
for (uint i= 0; i < table->s->keys; i++)
@ -434,18 +451,28 @@ void ha_ndbcluster::invalidateDictionaryCache()
switch(idx_type) {
case(PRIMARY_KEY_ORDERED_INDEX):
case(ORDERED_INDEX):
dict->invalidateIndex(index->getName(), m_tabname);
if (global)
dict->invalidateIndex(index->getName(), m_tabname);
else
dict->removeCachedIndex(index->getName(), m_tabname);
break;
case(UNIQUE_ORDERED_INDEX):
dict->invalidateIndex(index->getName(), m_tabname);
if (global)
dict->invalidateIndex(index->getName(), m_tabname);
else
dict->removeCachedIndex(index->getName(), m_tabname);
case(UNIQUE_INDEX):
dict->invalidateIndex(unique_index->getName(), m_tabname);
if (global)
dict->invalidateIndex(unique_index->getName(), m_tabname);
else
dict->removeCachedIndex(unique_index->getName(), m_tabname);
break;
case(PRIMARY_KEY_INDEX):
case(UNDEFINED_INDEX):
break;
}
}
DBUG_VOID_RETURN;
}
int ha_ndbcluster::ndb_err(NdbTransaction *trans)
@ -457,7 +484,7 @@ int ha_ndbcluster::ndb_err(NdbTransaction *trans)
ERR_PRINT(err);
switch (err.classification) {
case NdbError::SchemaError:
invalidateDictionaryCache();
invalidate_dictionary_cache(TRUE);
if (err.code==284)
{
@ -882,7 +909,14 @@ int ha_ndbcluster::get_metadata(const char *path)
if (!(tab= dict->getTable(m_tabname)))
ERR_RETURN(dict->getNdbError());
DBUG_PRINT("info", ("Table schema version: %d", tab->getObjectVersion()));
// Check if thread has stale local cache
if (tab->getObjectStatus() == NdbDictionary::Object::Invalid)
{
invalidate_dictionary_cache(FALSE);
if (!(tab= dict->getTable(m_tabname)))
ERR_RETURN(dict->getNdbError());
DBUG_PRINT("info", ("Table schema version: %d", tab->getObjectVersion()));
}
/*
Compare FrmData in NDB with frm file from disk.
*/
@ -901,7 +935,7 @@ int ha_ndbcluster::get_metadata(const char *path)
if (!invalidating_ndb_table)
{
DBUG_PRINT("info", ("Invalidating table"));
invalidateDictionaryCache();
invalidate_dictionary_cache(TRUE);
invalidating_ndb_table= TRUE;
}
else
@ -927,7 +961,7 @@ int ha_ndbcluster::get_metadata(const char *path)
if (error)
DBUG_RETURN(error);
m_tableVersion= tab->getObjectVersion();
m_table_version= tab->getObjectVersion();
m_table= (void *)tab;
m_table_info= NULL; // Set in external lock
@ -3269,15 +3303,25 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type)
void *tab_info;
if (!(tab= dict->getTable(m_tabname, &tab_info)))
ERR_RETURN(dict->getNdbError());
DBUG_PRINT("info", ("Table schema version: %d", tab->getObjectVersion()));
if (m_table != (void *)tab || m_tableVersion != tab->getObjectVersion())
DBUG_PRINT("info", ("Table schema version: %d",
tab->getObjectVersion()));
// Check if thread has stale local cache
if (tab->getObjectStatus() == NdbDictionary::Object::Invalid)
{
invalidate_dictionary_cache(FALSE);
if (!(tab= dict->getTable(m_tabname, &tab_info)))
ERR_RETURN(dict->getNdbError());
DBUG_PRINT("info", ("Table schema version: %d",
tab->getObjectVersion()));
}
if (m_table != (void *)tab || m_table_version < tab->getObjectVersion())
{
/*
The table has been altered, refresh the index list
*/
build_index_list(ndb, table, ILBP_OPEN);
m_table= (void *)tab;
m_tableVersion = tab->getObjectVersion();
m_table_version = tab->getObjectVersion();
}
m_table_info= tab_info;
}
@ -3321,7 +3365,6 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type)
thd_ndb->stmt= NULL;
}
}
m_table= NULL;
m_table_info= NULL;
/*
@ -4036,7 +4079,13 @@ int ha_ndbcluster::rename_table(const char *from, const char *to)
dict= ndb->getDictionary();
if (!(orig_tab= dict->getTable(m_tabname)))
ERR_RETURN(dict->getNdbError());
// Check if thread has stale local cache
if (orig_tab->getObjectStatus() == NdbDictionary::Object::Invalid)
{
dict->removeCachedTable(m_tabname);
if (!(orig_tab= dict->getTable(m_tabname)))
ERR_RETURN(dict->getNdbError());
}
m_table= (void *)orig_tab;
// Change current database to that of target table
set_dbname(to);
@ -4159,7 +4208,7 @@ ha_ndbcluster::ha_ndbcluster(TABLE *table_arg):
m_active_trans(NULL),
m_active_cursor(NULL),
m_table(NULL),
m_tableVersion(-1),
m_table_version(-1),
m_table_info(NULL),
m_table_flags(HA_REC_NOT_IN_SEQ |
HA_NULL_IN_KEY |
@ -4409,7 +4458,6 @@ int ndbcluster_discover(THD* thd, const char *db, const char *name,
DBUG_RETURN(1);
ERR_RETURN(err);
}
DBUG_PRINT("info", ("Found table %s", tab->getName()));
len= tab->getFrmLength();

View file

@ -558,7 +558,7 @@ private:
void print_results();
ulonglong get_auto_increment();
void invalidateDictionaryCache();
void invalidate_dictionary_cache(bool global);
int ndb_err(NdbTransaction*);
bool uses_blob_value(bool all_fields);
@ -596,7 +596,7 @@ private:
NdbTransaction *m_active_trans;
NdbScanOperation *m_active_cursor;
void *m_table;
int m_tableVersion;
int m_table_version;
void *m_table_info;
char m_dbname[FN_HEADLEN];
//char m_schemaname[FN_HEADLEN];

View file

@ -185,9 +185,10 @@ enum db_type ha_checktype(enum db_type database_type)
thd= current_thd;
return ((enum db_type) thd->variables.table_type != DB_TYPE_UNKNOWN ?
(enum db_type) thd->variables.table_type :
(enum db_type) global_system_variables.table_type !=
DB_TYPE_UNKNOWN ?
(enum db_type) global_system_variables.table_type : DB_TYPE_MYISAM);
((enum db_type) global_system_variables.table_type !=
DB_TYPE_UNKNOWN ?
(enum db_type) global_system_variables.table_type : DB_TYPE_MYISAM)
);
} /* ha_checktype */
@ -1772,13 +1773,17 @@ int handler::delete_table(const char *name)
int handler::rename_table(const char * from, const char * to)
{
DBUG_ENTER("handler::rename_table");
for (const char **ext=bas_ext(); *ext ; ext++)
int error= 0;
for (const char **ext= bas_ext(); *ext ; ext++)
{
if (rename_file_ext(from,to,*ext))
DBUG_RETURN(my_errno);
if (rename_file_ext(from, to, *ext))
{
if ((error=my_errno) != ENOENT)
break;
error= 0;
}
}
DBUG_RETURN(0);
return error;
}
/*

View file

@ -177,7 +177,14 @@ my_string ip_to_hostname(struct in_addr *in, uint *errors)
&tmp_errno)))
{
DBUG_PRINT("error",("gethostbyname_r returned %d",tmp_errno));
add_wrong_ip(in);
/*
Don't cache responses when the DSN server is down, as otherwise
transient DNS failure may leave any number of clients (those
that attempted to connect during the outage) unable to connect
indefinitely.
*/
if (tmp_errno == HOST_NOT_FOUND || tmp_error == NO_DATA)
add_wrong_ip(in);
my_gethostbyname_r_free();
DBUG_RETURN(0);
}

View file

@ -302,7 +302,8 @@ public:
{ return save_in_field(field, 1); }
virtual bool send(Protocol *protocol, String *str);
virtual bool eq(const Item *, bool binary_cmp) const;
virtual Item_result result_type () const { return REAL_RESULT; }
virtual Item_result result_type() const { return REAL_RESULT; }
virtual Item_result cast_to_int_type() const { return result_type(); }
virtual enum_field_types field_type() const;
virtual enum Type type() const =0;
/* valXXX methods must return NULL or 0 or 0.0 if null_value is set. */
@ -738,6 +739,10 @@ public:
{
return field->result_type();
}
Item_result cast_to_int_type() const
{
return field->cast_to_int_type();
}
enum_field_types field_type() const
{
return field->type();

View file

@ -904,6 +904,58 @@ void Item_func_signed::print(String *str)
}
longlong Item_func_signed::val_int_from_str(int *error)
{
char buff[MAX_FIELD_WIDTH], *end;
String tmp(buff,sizeof(buff), &my_charset_bin), *res;
longlong value;
/*
For a string result, we must first get the string and then convert it
to a longlong
*/
if (!(res= args[0]->val_str(&tmp)))
{
null_value= 1;
*error= 0;
return 0;
}
null_value= 0;
end= (char*) res->ptr()+ res->length();
value= my_strtoll10(res->ptr(), &end, error);
if (*error > 0 || end != res->ptr()+ res->length())
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_TRUNCATED_WRONG_VALUE,
ER(ER_TRUNCATED_WRONG_VALUE), "INTEGER",
res->c_ptr());
return value;
}
longlong Item_func_signed::val_int()
{
longlong value;
int error;
if (args[0]->cast_to_int_type() != STRING_RESULT)
{
value= args[0]->val_int();
null_value= args[0]->null_value;
return value;
}
value= val_int_from_str(&error);
if (value < 0 && error == 0)
{
push_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
"Cast to signed converted positive out-of-range integer to "
"it's negative complement");
}
return value;
}
void Item_func_unsigned::print(String *str)
{
str->append("cast(", 5);
@ -913,6 +965,27 @@ void Item_func_unsigned::print(String *str)
}
longlong Item_func_unsigned::val_int()
{
longlong value;
int error;
if (args[0]->cast_to_int_type() != STRING_RESULT)
{
value= args[0]->val_int();
null_value= args[0]->null_value;
return value;
}
value= val_int_from_str(&error);
if (error < 0)
push_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
"Cast to unsigned converted negative integer to it's "
"positive complement");
return value;
}
String *Item_decimal_typecast::val_str(String *str)
{
my_decimal tmp_buf, *tmp= val_decimal(&tmp_buf);
@ -3271,7 +3344,8 @@ bool Item_func_set_user_var::fix_fields(THD *thd, TABLE_LIST *tables,
from the argument if the argument is NULL
and the variable has previously been initialized.
*/
if (!entry->collation.collation || !args[0]->null_value)
null_item= (args[0]->type() == NULL_ITEM);
if (!entry->collation.collation || !null_item)
entry->collation.set(args[0]->collation.collation, DERIVATION_IMPLICIT);
collation.set(entry->collation.collation, DERIVATION_IMPLICIT);
cached_result_type= args[0]->result_type();
@ -3315,8 +3389,8 @@ update_hash(user_var_entry *entry, bool set_null, void *ptr, uint length,
char *pos= (char*) entry+ ALIGN_SIZE(sizeof(user_var_entry));
if (entry->value && entry->value != pos)
my_free(entry->value,MYF(0));
entry->value=0;
entry->length=0;
entry->value= 0;
entry->length= 0;
}
else
{
@ -3355,9 +3429,9 @@ update_hash(user_var_entry *entry, bool set_null, void *ptr, uint length,
if (type == DECIMAL_RESULT)
((my_decimal*)entry->value)->fix_buffer_pointer();
entry->length= length;
entry->type=type;
entry->collation.set(cs, dv);
}
entry->type=type;
return 0;
}
@ -3366,6 +3440,12 @@ bool
Item_func_set_user_var::update_hash(void *ptr, uint length, Item_result type,
CHARSET_INFO *cs, Derivation dv)
{
/*
If we set a variable explicitely to NULL then keep the old
result type of the variable
*/
if ((null_value= args[0]->null_value) && null_item)
type= entry->type; // Don't change type of item
if (::update_hash(entry, (null_value= args[0]->null_value),
ptr, length, type, cs, dv))
{

View file

@ -262,12 +262,8 @@ public:
null_value= args[0]->null_value;
return tmp;
}
longlong val_int()
{
longlong tmp= args[0]->val_int();
null_value= args[0]->null_value;
return tmp;
}
longlong val_int();
longlong val_int_from_str(int *error);
void fix_length_and_dec()
{ max_length=args[0]->max_length; unsigned_flag=0; }
void print(String *str);
@ -281,6 +277,7 @@ public:
const char *func_name() const { return "cast_as_unsigned"; }
void fix_length_and_dec()
{ max_length=args[0]->max_length; unsigned_flag=1; }
longlong val_int();
void print(String *str);
};
@ -1071,6 +1068,7 @@ class Item_func_set_user_var :public Item_func
char buffer[MAX_FIELD_WIDTH];
String value;
my_decimal decimal_buff;
bool null_item;
union
{
longlong vint;

View file

@ -55,8 +55,11 @@ String *Item_func_geometry_from_text::val_str(String *str)
return 0;
str->length(0);
str->q_append(srid);
if ((null_value= !Geometry::create_from_wkt(&buffer, &trs, str, 0)))
return 0;
if (!Geometry::create_from_wkt(&buffer, &trs, str, 0))
/* We shouldn't return NULL here as NULL is a legal spatial object */
/* Geometry::bad_spatial_data will produce error message beeing stored*/
/* in GEOMETRY field */
return &Geometry::bad_geometry_data;
return str;
}

View file

@ -82,7 +82,8 @@ static int unlock_external(THD *thd, TABLE **table,uint count);
static void print_lock_error(int error, const char *);
MYSQL_LOCK *mysql_lock_tables(THD *thd,TABLE **tables,uint count)
MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count,
bool ignore_global_read_lock)
{
MYSQL_LOCK *sql_lock;
TABLE *write_lock_used;
@ -93,7 +94,7 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd,TABLE **tables,uint count)
if (!(sql_lock = get_lock_data(thd,tables,count, 0,&write_lock_used)))
break;
if (global_read_lock && write_lock_used)
if (global_read_lock && write_lock_used && ! ignore_global_read_lock)
{
/*
Someone has issued LOCK ALL TABLES FOR READ and we want a write lock
@ -949,3 +950,49 @@ bool make_global_read_lock_block_commit(THD *thd)
DBUG_RETURN(error);
}
/*
Set protection against global read lock.
SYNOPSIS
set_protect_against_global_read_lock()
void
RETURN
FALSE OK, no global read lock exists.
TRUE Error, global read lock exists already.
*/
bool set_protect_against_global_read_lock(void)
{
bool global_read_lock_exists;
pthread_mutex_lock(&LOCK_open);
if (! (global_read_lock_exists= test(global_read_lock)))
protect_against_global_read_lock++;
pthread_mutex_unlock(&LOCK_open);
return global_read_lock_exists;
}
/*
Unset protection against global read lock.
SYNOPSIS
unset_protect_against_global_read_lock()
void
RETURN
void
*/
void unset_protect_against_global_read_lock(void)
{
pthread_mutex_lock(&LOCK_open);
protect_against_global_read_lock--;
pthread_mutex_unlock(&LOCK_open);
pthread_cond_broadcast(&COND_refresh);
}

View file

@ -1151,7 +1151,8 @@ extern pthread_t signal_thread;
extern struct st_VioSSLAcceptorFd * ssl_acceptor_fd;
#endif /* HAVE_OPENSSL */
MYSQL_LOCK *mysql_lock_tables(THD *thd,TABLE **table,uint count);
MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **table, uint count,
bool ignore_global_read_lock= FALSE);
void mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock);
void mysql_unlock_read_tables(THD *thd, MYSQL_LOCK *sql_lock);
void mysql_unlock_some_tables(THD *thd, TABLE **table,uint count);
@ -1165,6 +1166,8 @@ bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh,
bool is_not_commit);
void start_waiting_global_read_lock(THD *thd);
bool make_global_read_lock_block_commit(THD *thd);
bool set_protect_against_global_read_lock(void);
void unset_protect_against_global_read_lock(void);
/* Lock based on name */
int lock_and_wait_for_table_name(THD *thd, TABLE_LIST *table_list);

View file

@ -820,7 +820,7 @@ bool Protocol_simple::store_long(longlong from)
#endif
char buff[20];
return net_store_data((char*) buff,
(uint) (int10_to_str((int) from,buff, -10)-buff));
(uint) (int10_to_str((long int)from,buff, (from <0)?-10:10)-buff));
}

View file

@ -5344,3 +5344,5 @@ ER_SP_NOT_VAR_ARG 42000
eng "OUT or INOUT argument %d for routine %s is not a variable"
ER_SP_NO_RETSET_IN_FUNC 0A000
eng "Not allowed to return a result set from a function"
ER_CANT_CREATE_GEOMETRY_OBJECT 22003
eng "Cannot get geometry object from data you send to the GEOMETRY field"

View file

@ -22,6 +22,8 @@
/***************************** Gis_class_info *******************************/
String Geometry::bad_geometry_data("Bad object", &my_charset_bin);
Geometry::Class_info *Geometry::ci_collection[Geometry::wkb_end+1]=
{
NULL, NULL, NULL, NULL, NULL, NULL, NULL

View file

@ -173,6 +173,8 @@ public:
static void operator delete(void *ptr, void *buffer)
{}
static String bad_geometry_data;
enum wkbType
{
wkb_point= 1,

View file

@ -3858,11 +3858,8 @@ fill_record(THD *thd, Field **ptr, List<Item> &values, bool ignore_errors)
TABLE *table= field->table;
if (field == table->next_number_field)
table->auto_increment_field_not_null= TRUE;
if ((value->save_in_field(field, 0) < 0) && !ignore_errors)
{
my_message(ER_UNKNOWN_ERROR, ER(ER_UNKNOWN_ERROR), MYF(0));
if (value->save_in_field(field, 0) == -1)
DBUG_RETURN(TRUE);
}
}
DBUG_RETURN(thd->net.report_error);
}

View file

@ -89,7 +89,7 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list,
}
if (values.elements != table->s->fields)
{
my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), 1);
my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), 1L);
return -1;
}
#ifndef NO_EMBEDDED_ACCESS_CHECKS
@ -112,7 +112,7 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list,
int res;
if (fields.elements != values.elements)
{
my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), 1);
my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), 1L);
return -1;
}
@ -1117,27 +1117,42 @@ static TABLE *delayed_get_table(THD *thd,TABLE_LIST *table_list)
{
int error;
delayed_insert *tmp;
TABLE *table;
DBUG_ENTER("delayed_get_table");
if (!table_list->db)
table_list->db=thd->db;
/* no match; create a new thread to handle the table */
/* Find the thread which handles this table. */
if (!(tmp=find_handler(thd,table_list)))
{
/* Don't create more than max_insert_delayed_threads */
/*
No match. Create a new thread to handle the table, but
no more than max_insert_delayed_threads.
*/
if (delayed_insert_threads >= thd->variables.max_insert_delayed_threads)
DBUG_RETURN(0);
thd->proc_info="Creating delayed handler";
pthread_mutex_lock(&LOCK_delayed_create);
if (!(tmp=find_handler(thd,table_list))) // Was just created
/*
The first search above was done without LOCK_delayed_create.
Another thread might have created the handler in between. Search again.
*/
if (! (tmp= find_handler(thd, table_list)))
{
/*
Avoid that a global read lock steps in while we are creating the
new thread. It would block trying to open the table. Hence, the
DI thread and this thread would wait until after the global
readlock is gone. If the read lock exists already, we leave with
no table and then switch to non-delayed insert.
*/
if (set_protect_against_global_read_lock())
goto err;
if (!(tmp=new delayed_insert()))
{
thd->fatal_error();
my_error(ER_OUTOFMEMORY,MYF(0),sizeof(delayed_insert));
pthread_mutex_unlock(&LOCK_delayed_create);
DBUG_RETURN(0);
goto err1;
}
pthread_mutex_lock(&LOCK_thread_count);
thread_count++;
@ -1146,10 +1161,8 @@ static TABLE *delayed_get_table(THD *thd,TABLE_LIST *table_list)
!(tmp->thd.query=my_strdup(table_list->table_name,MYF(MY_WME))))
{
delete tmp;
thd->fatal_error();
my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
pthread_mutex_unlock(&LOCK_delayed_create);
DBUG_RETURN(0);
goto err1;
}
tmp->table_list= *table_list; // Needed to open table
tmp->table_list.db= tmp->thd.db;
@ -1165,10 +1178,8 @@ static TABLE *delayed_get_table(THD *thd,TABLE_LIST *table_list)
pthread_mutex_unlock(&tmp->mutex);
tmp->unlock();
delete tmp;
thd->fatal_error();
pthread_mutex_unlock(&LOCK_delayed_create);
my_error(ER_CANT_CREATE_THREAD, MYF(0), error);
DBUG_RETURN(0);
goto err1;
}
/* Wait until table is open */
@ -1178,6 +1189,7 @@ static TABLE *delayed_get_table(THD *thd,TABLE_LIST *table_list)
pthread_cond_wait(&tmp->cond_client,&tmp->mutex);
}
pthread_mutex_unlock(&tmp->mutex);
unset_protect_against_global_read_lock();
thd->proc_info="got old table";
if (tmp->thd.killed)
{
@ -1189,28 +1201,34 @@ static TABLE *delayed_get_table(THD *thd,TABLE_LIST *table_list)
thd->net.last_errno=tmp->thd.net.last_errno;
}
tmp->unlock();
pthread_mutex_unlock(&LOCK_delayed_create);
DBUG_RETURN(0); // Continue with normal insert
goto err;
}
if (thd->killed)
{
tmp->unlock();
pthread_mutex_unlock(&LOCK_delayed_create);
DBUG_RETURN(0);
goto err;
}
}
pthread_mutex_unlock(&LOCK_delayed_create);
}
pthread_mutex_lock(&tmp->mutex);
TABLE *table=tmp->get_local_table(thd);
table= tmp->get_local_table(thd);
pthread_mutex_unlock(&tmp->mutex);
tmp->unlock();
if (table)
thd->di=tmp;
else if (tmp->thd.is_fatal_error)
thd->fatal_error();
/* Unlock the delayed insert object after its last access. */
tmp->unlock();
DBUG_RETURN((table_list->table=table));
err1:
thd->fatal_error();
unset_protect_against_global_read_lock();
err:
pthread_mutex_unlock(&LOCK_delayed_create);
DBUG_RETURN(0); // Continue with normal insert
}
@ -1433,6 +1451,14 @@ extern "C" pthread_handler_decl(handle_delayed_insert,arg)
thd->killed=abort_loop ? THD::KILL_CONNECTION : THD::NOT_KILLED;
pthread_mutex_unlock(&LOCK_thread_count);
/*
Wait until the client runs into pthread_cond_wait(),
where we free it after the table is opened and di linked in the list.
If we did not wait here, the client might detect the opened table
before it is linked to the list. It would release LOCK_delayed_create
and allow another thread to create another handler for the same table,
since it does not find one in the list.
*/
pthread_mutex_lock(&di->mutex);
#if !defined( __WIN__) && !defined(OS2) /* Win32 calls this in pthread_create */
if (my_thread_init())
@ -1547,8 +1573,17 @@ extern "C" pthread_handler_decl(handle_delayed_insert,arg)
if (di->tables_in_use && ! thd->lock)
{
/* request for new delayed insert */
if (!(thd->lock=mysql_lock_tables(thd,&di->table,1)))
/*
Request for new delayed insert.
Lock the table, but avoid to be blocked by a global read lock.
If we got here while a global read lock exists, then one or more
inserts started before the lock was requested. These are allowed
to complete their work before the server returns control to the
client which requested the global read lock. The delayed insert
handler will close the table and finish when the outstanding
inserts are done.
*/
if (! (thd->lock= mysql_lock_tables(thd, &di->table, 1, TRUE)))
{
/* Fatal error */
di->dead= 1;

View file

@ -3010,6 +3010,10 @@ unsent_create_error:
goto error;
#else
{
/* Ignore temporary tables if this is "SHOW CREATE VIEW" */
if (lex->only_view)
first_table->skip_temporary= 1;
if (check_db_used(thd, all_tables) ||
check_access(thd, SELECT_ACL | EXTRA_ACL, first_table->db,
&first_table->grant.privilege, 0, 0))

View file

@ -2223,7 +2223,7 @@ void mysql_stmt_fetch(THD *thd, char *packet, uint packet_length)
my_pthread_setprio(pthread_self(), QUERY_PRIOR);
thd->protocol= &thd->protocol_prep; // Switch to binary protocol
(void) stmt->cursor->fetch(num_rows);
stmt->cursor->fetch(num_rows);
thd->protocol= &thd->protocol_simple; // Use normal protocol
if (!(specialflag & SPECIAL_NO_PRIOR))

File diff suppressed because it is too large Load diff

View file

@ -91,7 +91,15 @@ enum join_type { JT_UNKNOWN,JT_SYSTEM,JT_CONST,JT_EQ_REF,JT_REF,JT_MAYBE_REF,
class JOIN;
typedef int (*Next_select_func)(JOIN *,struct st_join_table *,bool);
enum enum_nested_loop_state
{
NESTED_LOOP_KILLED= -2, NESTED_LOOP_ERROR= -1,
NESTED_LOOP_OK= 0, NESTED_LOOP_NO_MORE_ROWS= 1,
NESTED_LOOP_QUERY_LIMIT= 3, NESTED_LOOP_CURSOR_LIMIT= 4
};
typedef enum_nested_loop_state
(*Next_select_func)(JOIN *, struct st_join_table *, bool);
typedef int (*Read_record_func)(struct st_join_table *tab);
@ -162,6 +170,11 @@ class JOIN :public Sql_alloc
uint send_group_parts;
bool sort_and_group,first_record,full_join,group, no_field_update;
bool do_send_rows;
/*
TRUE when we want to resume nested loop iterations when
fetching data from a cursor
*/
bool resume_nested_loop;
table_map const_table_map,found_const_table_map,outer_join;
ha_rows send_records,found_records,examined_rows,row_limit, select_limit;
/*
@ -263,6 +276,7 @@ class JOIN :public Sql_alloc
sort_and_group= 0;
first_record= 0;
do_send_rows= 1;
resume_nested_loop= FALSE;
send_records= 0;
found_records= 0;
fetch_limit= HA_POS_ERROR;
@ -374,7 +388,7 @@ public:
void reset_thd(THD *thd);
int open(JOIN *join);
int fetch(ulong num_rows);
void fetch(ulong num_rows);
void reset() { join= 0; }
bool is_open() const { return join != 0; }
void close();

View file

@ -685,6 +685,9 @@ static bool make_empty_rec(THD *thd, File file,enum db_type table_type,
thd->count_cuted_fields= CHECK_FIELD_WARN; // To find wrong default values
while ((field=it++))
{
/*
regfield don't have to be deleted as it's allocated with sql_alloc()
*/
Field *regfield=make_field((char*) buff+field->offset,field->length,
null_pos,
null_count & 7,
@ -696,7 +699,8 @@ static bool make_empty_rec(THD *thd, File file,enum db_type table_type,
field->interval,
field->field_name,
&table);
DBUG_ASSERT(regfield);
if (!regfield)
goto err; // End of memory
if (!(field->flags & NOT_NULL_FLAG))
null_count++;
@ -730,7 +734,6 @@ static bool make_empty_rec(THD *thd, File file,enum db_type table_type,
regfield->store(ER(ER_NO), (uint) strlen(ER(ER_NO)),system_charset_info);
else
regfield->reset();
delete regfield;
}
/* Fill not used startpos */

212
tests/index_corrupt.pl Executable file
View file

@ -0,0 +1,212 @@
#!/usr/bin/perl -w
#
# This is a test for a key cache bug (bug #10167)
# To expose the bug mysqld should be started with --key-buffer-size=64K
#
$opt_loop_count=100000; # Change this to make test harder/easier
##################### Standard benchmark inits ##############################
use DBI;
use Getopt::Long;
use Benchmark;
package main;
$opt_skip_create=$opt_skip_in=$opt_verbose=$opt_fast_insert=
$opt_lock_tables=$opt_debug=$opt_skip_delete=$opt_fast=$opt_force=0;
$opt_host=$opt_user=$opt_password=""; $opt_db="test";
GetOptions("host=s","db=s","loop-count=i","skip-create","skip-in",
"skip-delete","verbose","fast-insert","lock-tables","debug","fast",
"force","user=s","password=s") || die "Aborted";
$opt_verbose=$opt_debug=$opt_lock_tables=$opt_fast_insert=$opt_fast=$opt_skip_in=$opt_force=undef; # Ignore warnings from these
$firsttable = "bench_f1";
$secondtable = "bench_f2";
$kill_file= "/tmp/mysqltest_index_corrupt.$$";
####
#### Start timeing and start test
####
$start_time=new Benchmark;
if (!$opt_skip_create)
{
$dbh = DBI->connect("DBI:mysql:$opt_db:$opt_host",
$opt_user, $opt_password,
{ PrintError => 0}) || die $DBI::errstr;
$dbh->do("drop table if exists $firsttable, $secondtable");
print "Creating tables in $opt_db\n";
$dbh->do("create table $firsttable (
c_pollid INTEGER NOT NULL,
c_time BIGINT NOT NULL,
c_data DOUBLE NOT NULL,
c_error INTEGER NOT NULL,
c_warning INTEGER NOT NULL,
c_okay INTEGER NOT NULL,
c_unknown INTEGER NOT NULL,
c_rolled_up BIT NOT NULL,
INDEX t_mgmt_hist_r_i1 (c_pollid),
INDEX t_mgmt_hist_r_i2 (c_time),
INDEX t_mgmt_hist_r_i3 (c_rolled_up))") or die $DBI::errstr;
$dbh->do("create table $secondtable (
c_pollid INTEGER NOT NULL,
c_min_time BIGINT NOT NULL,
c_max_time BIGINT NOT NULL,
c_min_data DOUBLE NOT NULL,
c_max_data DOUBLE NOT NULL,
c_avg_data DOUBLE NOT NULL,
c_error INTEGER NOT NULL,
c_warning INTEGER NOT NULL,
c_okay INTEGER NOT NULL,
c_unknown INTEGER NOT NULL,
c_rolled_up BIT NOT NULL,
INDEX t_mgmt_hist_d_i1 (c_pollid),
INDEX t_mgmt_hist_d_i2 (c_min_time),
INDEX t_mgmt_hist_d_i3 (c_max_time),
INDEX t_mgmt_hist_d_i4 (c_rolled_up))") or die $DBI::errstr;
$dbh->disconnect; $dbh=0; # Close handler
}
$|= 1; # Autoflush
####
#### Start the tests
####
print "Running tests\n";
insert_in_bench() if (($pid=fork()) == 0); $work{$pid}="insert";
select_from_bench() if (($pid=fork()) == 0); $work{$pid}="insert-select;
delete_from_bench() if (($pid=fork()) == 0); $work{$pid}="delete";
$errors=0;
while (($pid=wait()) != -1)
{
$ret=$?/256;
print "thread '" . $work{$pid} . "' finished with exit code $ret\n";
$errors++ if ($ret != 0);
}
if (!$opt_skip_delete && !$errors)
{
$dbh = DBI->connect("DBI:mysql:$opt_db:$opt_host",
$opt_user, $opt_password,
{ PrintError => 0}) || die $DBI::errstr;
$dbh->do("drop table $firsttable, $secondtable");
}
print ($errors ? "Test failed\n" :"Test ok\n");
$end_time=new Benchmark;
print "Total time: " .
timestr(timediff($end_time, $start_time),"noc") . "\n";
unlink $kill_file;
exit(0);
#
# Insert records in the two tables
#
sub insert_in_bench
{
my ($dbh,$rows,$found,$i);
$dbh = DBI->connect("DBI:mysql:$opt_db:$opt_host",
$opt_user, $opt_password,
{ PrintError => 0}) || die $DBI::errstr;
for ($rows= 1; $rows <= $opt_loop_count ; $rows++)
{
$c_pollid = sprintf("%d",rand 1000);
$c_time = sprintf("%d",rand 100000);
$c_data = rand 1000000;
$test = rand 1;
$c_error=0;
$c_warning=0;
$c_okay=0;
$c_unknown=0;
if ($test < .8) {
$c_okay=1;
} elsif ($test <.9) {
$c_error=1;
} elsif ($test <.95) {
$c_warning=1;
} else {
$c_unknown=1;
}
$statement = "INSERT INTO $firsttable (c_pollid, c_time, c_data, c_error
, c_warning, c_okay, c_unknown, c_rolled_up) ".
"VALUES ($c_pollid,$c_time,$c_data,$c_error,$c_warning,$c_okay,$c_unknown,0)";
$cursor = $dbh->prepare($statement);
$cursor->execute();
$cursor->finish();
}
$dbh->disconnect; $dbh=0;
print "insert_in_bench: Inserted $rows rows\n";
# Kill other threads
open(KILLFILE, "> $kill_file");
close(KILLFILE);
exit(0);
}
sub select_from_bench
{
my ($dbh,$rows,$cursor);
$dbh = DBI->connect("DBI:mysql:$opt_db:$opt_host",
$opt_user, $opt_password,
{ PrintError => 0}) || die $DBI::errstr;
for ($rows= 1; $rows < $opt_loop_count ; $rows++)
{
$t_value = rand 100000;
$t_value2 = $t_value+10000;
$statement = "INSERT INTO $secondtable (c_pollid, c_min_time, c_max_time
, c_min_data, c_max_data, c_avg_data, c_error, c_warning, c_okay, c_unknown, c_rolled_up) SELECT c_pollid, MIN(c_time), MAX(c_time), MIN(c_data), MAX(c_data), AVG(c_data), SUM(c_error), SUM(c_warning), SUM(c_okay), SUM(c_unknown), 0 FROM $firsttable WHERE (c_time>=$t_value) AND (c_time<$t_value2) AND (c_rolled_up=0) GROUP BY c_pollid";
$cursor = $dbh->prepare($statement);
$cursor->execute();
$cursor->finish();
sleep 1;
if (-e $kill_file)
{
last;
}
}
print "select_from_bench: insert-select executed $rows times\n";
exit(0);
}
sub delete_from_bench
{
my ($dbh,$row, $t_value, $t2_value, $statement, $cursor);
$dbh = DBI->connect("DBI:mysql:$opt_db:$opt_host",
$opt_user, $opt_password,
{ PrintError => 0}) || die $DBI::errstr;
for ($rows= 1; $rows < $opt_loop_count ; $rows++)
{
$t_value = rand 50000;
$t2_value = $t_value + 50001;
$statement = "DELETE FROM $firsttable WHERE (c_time>$t_value) AND (c_time<$t2_value)";
$cursor = $dbh->prepare($statement);
$cursor->execute();
$cursor->finish();
sleep 10;
if (-e $kill_file)
{
last;
}
}
print "delete: delete executed $rows times\n";
exit(0);
}

View file

@ -7046,6 +7046,7 @@ static void test_set_option()
bug #89 (reported by mark@mysql.com)
*/
#ifndef EMBEDDED_LIBRARY
static void test_prepare_grant()
{
int rc;
@ -7138,7 +7139,7 @@ static void test_prepare_grant()
}
}
#endif
/*
Test a crash when invalid/corrupted .frm is used in the
@ -12597,7 +12598,7 @@ static void test_bug8330()
const char *stmt_text;
MYSQL_STMT *stmt[2];
int i, rc;
char *query= "select a,b from t1 where a=?";
const char *query= "select a,b from t1 where a=?";
MYSQL_BIND bind[2];
long lval[2];
@ -12788,7 +12789,7 @@ static void test_bug8722()
}
MYSQL_STMT *open_cursor(char *query)
MYSQL_STMT *open_cursor(const char *query)
{
int rc;
const ulong type= (ulong)CURSOR_TYPE_READ_ONLY;
@ -12854,6 +12855,59 @@ static void test_bug9159()
myquery(rc);
}
/* Crash when opening a cursor to a query with DISTICNT and no key */
static void test_bug9520()
{
MYSQL_STMT *stmt;
MYSQL_BIND bind[1];
char a[6];
ulong a_len;
int rc, row_count= 0;
myheader("test_bug9520");
mysql_query(mysql, "drop table if exists t1");
mysql_query(mysql, "create table t1 (a char(5), b char(5), c char(5),"
" primary key (a, b, c))");
rc= mysql_query(mysql, "insert into t1 values ('x', 'y', 'z'), "
" ('a', 'b', 'c'), ('k', 'l', 'm')");
myquery(rc);
stmt= open_cursor("select distinct b from t1");
/*
Not crashes with:
stmt= open_cursor("select distinct a from t1");
*/
rc= mysql_stmt_execute(stmt);
check_execute(stmt, rc);
bzero(bind, sizeof(bind));
bind[0].buffer_type= MYSQL_TYPE_STRING;
bind[0].buffer= (char*) a;
bind[0].buffer_length= sizeof(a);
bind[0].length= &a_len;
mysql_stmt_bind_result(stmt, bind);
while (!(rc= mysql_stmt_fetch(stmt)))
row_count++;
DIE_UNLESS(rc == MYSQL_NO_DATA);
printf("Fetched %d rows\n", row_count);
DBUG_ASSERT(row_count == 3);
mysql_stmt_close(stmt);
rc= mysql_query(mysql, "drop table t1");
myquery(rc);
}
/*
Read and parse arguments and MySQL options from my.cnf
*/
@ -13079,6 +13133,7 @@ static struct my_tests_st my_tests[]= {
{ "test_bug8722", test_bug8722 },
{ "test_bug8880", test_bug8880 },
{ "test_bug9159", test_bug9159 },
{ "test_bug9520", test_bug9520 },
{ 0, 0 }
};