Commit 3ddb80a7 authored by unknown's avatar unknown

Merge jlindstrom@build.mysql.com:/home/bk/mysql-4.1

into hundin.mysql.fi:/home/jan/mysql-4.1

parents 51eb463f ccf52b4f
...@@ -30,6 +30,7 @@ bk@admin.bk ...@@ -30,6 +30,7 @@ bk@admin.bk
bk@mysql.r18.ru bk@mysql.r18.ru
brian@avenger.(none) brian@avenger.(none)
brian@brian-akers-computer.local brian@brian-akers-computer.local
brian@private-client-ip-101.oz.net
carsten@tsort.bitbybit.dk carsten@tsort.bitbybit.dk
davida@isil.mysql.com davida@isil.mysql.com
dlenev@brandersnatch.localdomain dlenev@brandersnatch.localdomain
...@@ -102,6 +103,7 @@ miguel@light.local ...@@ -102,6 +103,7 @@ miguel@light.local
miguel@sartre.local miguel@sartre.local
mikron@c-fb0ae253.1238-1-64736c10.cust.bredbandsbolaget.se mikron@c-fb0ae253.1238-1-64736c10.cust.bredbandsbolaget.se
mikron@mikael-ronstr-ms-dator.local mikron@mikael-ronstr-ms-dator.local
mleich@mysql.com
mmatthew@markslaptop. mmatthew@markslaptop.
monty@bitch.mysql.fi monty@bitch.mysql.fi
monty@butch. monty@butch.
......
...@@ -4,7 +4,7 @@ dnl Process this file with autoconf to produce a configure script. ...@@ -4,7 +4,7 @@ dnl Process this file with autoconf to produce a configure script.
AC_INIT(sql/mysqld.cc) AC_INIT(sql/mysqld.cc)
AC_CANONICAL_SYSTEM AC_CANONICAL_SYSTEM
# The Docs Makefile.am parses this line! # The Docs Makefile.am parses this line!
AM_INIT_AUTOMAKE(mysql, 4.1.5-gamma) AM_INIT_AUTOMAKE(mysql, 4.1.6-gamma)
AM_CONFIG_HEADER(config.h) AM_CONFIG_HEADER(config.h)
PROTOCOL_VERSION=10 PROTOCOL_VERSION=10
......
...@@ -47,6 +47,7 @@ my_bool _hash_init(HASH *hash, CHARSET_INFO *charset, ...@@ -47,6 +47,7 @@ my_bool _hash_init(HASH *hash, CHARSET_INFO *charset,
uint key_length, hash_get_key get_key, uint key_length, hash_get_key get_key,
void (*free_element)(void*), uint flags CALLER_INFO_PROTO); void (*free_element)(void*), uint flags CALLER_INFO_PROTO);
void hash_free(HASH *tree); void hash_free(HASH *tree);
void hash_reset(HASH *hash);
byte *hash_element(HASH *hash,uint idx); byte *hash_element(HASH *hash,uint idx);
gptr hash_search(HASH *info,const byte *key,uint length); gptr hash_search(HASH *info,const byte *key,uint length);
gptr hash_next(HASH *info,const byte *key,uint length); gptr hash_next(HASH *info,const byte *key,uint length);
...@@ -56,7 +57,6 @@ my_bool hash_update(HASH *hash,byte *record,byte *old_key,uint old_key_length); ...@@ -56,7 +57,6 @@ my_bool hash_update(HASH *hash,byte *record,byte *old_key,uint old_key_length);
void hash_replace(HASH *hash, uint idx, byte *new_row); void hash_replace(HASH *hash, uint idx, byte *new_row);
my_bool hash_check(HASH *hash); /* Only in debug library */ my_bool hash_check(HASH *hash); /* Only in debug library */
#define hash_clear(H) bzero((char*) (H),sizeof(*(H)))
#define hash_inited(H) ((H)->array.buffer != 0) #define hash_inited(H) ((H)->array.buffer != 0)
#ifdef __cplusplus #ifdef __cplusplus
......
...@@ -42,6 +42,7 @@ my_bool handle_local_infile(MYSQL *mysql, const char *net_filename); ...@@ -42,6 +42,7 @@ my_bool handle_local_infile(MYSQL *mysql, const char *net_filename);
void mysql_read_default_options(struct st_mysql_options *options, void mysql_read_default_options(struct st_mysql_options *options,
const char *filename,const char *group); const char *filename,const char *group);
void mysql_detach_stmt_list(LIST **stmt_list);
MYSQL * STDCALL MYSQL * STDCALL
cli_mysql_real_connect(MYSQL *mysql,const char *host, const char *user, cli_mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
const char *passwd, const char *db, const char *passwd, const char *db,
......
...@@ -662,6 +662,7 @@ my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user, ...@@ -662,6 +662,7 @@ my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user,
const char *passwd, const char *db) const char *passwd, const char *db)
{ {
char buff[512],*end=buff; char buff[512],*end=buff;
int rc;
DBUG_ENTER("mysql_change_user"); DBUG_ENTER("mysql_change_user");
if (!user) if (!user)
...@@ -695,18 +696,26 @@ my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user, ...@@ -695,18 +696,26 @@ my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user,
/* Write authentication package */ /* Write authentication package */
simple_command(mysql,COM_CHANGE_USER, buff,(ulong) (end-buff),1); simple_command(mysql,COM_CHANGE_USER, buff,(ulong) (end-buff),1);
if ((*mysql->methods->read_change_user_result)(mysql, buff, passwd)) rc= (*mysql->methods->read_change_user_result)(mysql, buff, passwd);
DBUG_RETURN(1);
/* Free old connect information */ /*
my_free(mysql->user,MYF(MY_ALLOW_ZERO_PTR)); The server will close all statements no matter was the attempt
my_free(mysql->passwd,MYF(MY_ALLOW_ZERO_PTR)); to change user successful or not.
my_free(mysql->db,MYF(MY_ALLOW_ZERO_PTR)); */
mysql_detach_stmt_list(&mysql->stmts);
/* alloc new connect information */ if (rc == 0)
mysql->user= my_strdup(user,MYF(MY_WME)); {
mysql->passwd=my_strdup(passwd,MYF(MY_WME)); /* Free old connect information */
mysql->db= db ? my_strdup(db,MYF(MY_WME)) : 0; my_free(mysql->user,MYF(MY_ALLOW_ZERO_PTR));
DBUG_RETURN(0); my_free(mysql->passwd,MYF(MY_ALLOW_ZERO_PTR));
my_free(mysql->db,MYF(MY_ALLOW_ZERO_PTR));
/* alloc new connect information */
mysql->user= my_strdup(user,MYF(MY_WME));
mysql->passwd=my_strdup(passwd,MYF(MY_WME));
mysql->db= db ? my_strdup(db,MYF(MY_WME)) : 0;
}
DBUG_RETURN(rc);
} }
#if defined(HAVE_GETPWUID) && defined(NO_GETPWUID_DECL) #if defined(HAVE_GETPWUID) && defined(NO_GETPWUID_DECL)
......
...@@ -110,10 +110,10 @@ select a,b from t1 where a=@arg00; ...@@ -110,10 +110,10 @@ select a,b from t1 where a=@arg00;
set @arg00=NULL; set @arg00=NULL;
set @arg01=2; set @arg01=2;
execute stmt1 using @arg00, @arg01; execute stmt1 using @arg00, @arg01;
select a,b from t1; select a,b from t1 order by a;
set @arg00=0; set @arg00=0;
execute stmt1 using @arg01, @arg00; execute stmt1 using @arg01, @arg00;
select a,b from t1; select a,b from t1 order by a;
## update with subquery and several parameters ## update with subquery and several parameters
set @arg00=23; set @arg00=23;
...@@ -134,7 +134,7 @@ prepare stmt1 from 'update t1 set a=? where b=? ...@@ -134,7 +134,7 @@ prepare stmt1 from 'update t1 set a=? where b=?
and a not in (select ? from t2 and a not in (select ? from t2
where b = ? or a = ?)'; where b = ? or a = ?)';
execute stmt1 using @arg04, @arg01, @arg02, @arg03, @arg00 ; execute stmt1 using @arg04, @arg01, @arg02, @arg03, @arg00 ;
select a,b from t1 ; select a,b from t1 order by a;
drop table t2 ; drop table t2 ;
## update with parameters in limit ## update with parameters in limit
...@@ -202,7 +202,7 @@ set @arg01=1 ; ...@@ -202,7 +202,7 @@ set @arg01=1 ;
prepare stmt1 from 'insert into t1 set a=?, b=''sechs'' prepare stmt1 from 'insert into t1 set a=?, b=''sechs''
on duplicate key update a=a + ?, b=concat(b,''modified'') '; on duplicate key update a=a + ?, b=concat(b,''modified'') ';
execute stmt1 using @arg00, @arg01; execute stmt1 using @arg00, @arg01;
select * from t1; select * from t1 order by a;
set @arg00=81 ; set @arg00=81 ;
set @arg01=1 ; set @arg01=1 ;
--error 1062 --error 1062
...@@ -221,17 +221,17 @@ set @updated="updated" ; ...@@ -221,17 +221,17 @@ set @updated="updated" ;
insert into t1 values(1000,'x1000_1') ; insert into t1 values(1000,'x1000_1') ;
insert into t1 values(@1000,@x1000_2),(@1000,@x1000_3) insert into t1 values(@1000,@x1000_2),(@1000,@x1000_3)
on duplicate key update a = a + @100, b = concat(b,@updated) ; on duplicate key update a = a + @100, b = concat(b,@updated) ;
select a,b from t1 where a >= 1000 ; select a,b from t1 where a >= 1000 order by a ;
delete from t1 where a >= 1000 ; delete from t1 where a >= 1000 ;
insert into t1 values(1000,'x1000_1') ; insert into t1 values(1000,'x1000_1') ;
prepare stmt1 from ' insert into t1 values(?,?),(?,?) prepare stmt1 from ' insert into t1 values(?,?),(?,?)
on duplicate key update a = a + ?, b = concat(b,?) '; on duplicate key update a = a + ?, b = concat(b,?) ';
execute stmt1 using @1000, @x1000_2, @1000, @x1000_3, @100, @updated ; execute stmt1 using @1000, @x1000_2, @1000, @x1000_3, @100, @updated ;
select a,b from t1 where a >= 1000 ; select a,b from t1 where a >= 1000 order by a ;
delete from t1 where a >= 1000 ; delete from t1 where a >= 1000 ;
insert into t1 values(1000,'x1000_1') ; insert into t1 values(1000,'x1000_1') ;
execute stmt1 using @1000, @x1000_2, @1100, @x1000_3, @100, @updated ; execute stmt1 using @1000, @x1000_2, @1100, @x1000_3, @100, @updated ;
select a,b from t1 where a >= 1000 ; select a,b from t1 where a >= 1000 order by a ;
delete from t1 where a >= 1000 ; delete from t1 where a >= 1000 ;
## replace ## replace
......
...@@ -45,19 +45,19 @@ ...@@ -45,19 +45,19 @@
set @duplicate='duplicate ' ; set @duplicate='duplicate ' ;
set @1000=1000 ; set @1000=1000 ;
set @5=5 ; set @5=5 ;
select a,b from t1 where a < 5 ; select a,b from t1 where a < 5 order by a ;
--enable_info --enable_info
insert into t1 select a + @1000, concat(@duplicate,b) from t1 insert into t1 select a + @1000, concat(@duplicate,b) from t1
where a < @5 ; where a < @5 ;
--disable_info --disable_info
select a,b from t1 where a >= 1000 ; select a,b from t1 where a >= 1000 order by a ;
delete from t1 where a >= 1000 ; delete from t1 where a >= 1000 ;
prepare stmt1 from ' insert into t1 select a + ?, concat(?,b) from t1 prepare stmt1 from ' insert into t1 select a + ?, concat(?,b) from t1
where a < ? ' ; where a < ? ' ;
--enable_info --enable_info
execute stmt1 using @1000, @duplicate, @5; execute stmt1 using @1000, @duplicate, @5;
--disable_info --disable_info
select a,b from t1 where a >= 1000 ; select a,b from t1 where a >= 1000 order by a ;
delete from t1 where a >= 1000 ; delete from t1 where a >= 1000 ;
set @float=1.00; set @float=1.00;
...@@ -78,7 +78,7 @@ select b, a + @100 from t1 ...@@ -78,7 +78,7 @@ select b, a + @100 from t1
where (a,b) in ( select sqrt(a+@1)+CAST(@float AS signed),b where (a,b) in ( select sqrt(a+@1)+CAST(@float AS signed),b
from t1); from t1);
--disable_info --disable_info
select a,b from t2; select a,b from t2 order by a ;
delete from t2 ; delete from t2 ;
prepare stmt1 from ' insert into t2 (b,a) prepare stmt1 from ' insert into t2 (b,a)
select ?, sum(first.a) select ?, sum(first.a)
...@@ -93,5 +93,5 @@ select b, a + ? from t1 ...@@ -93,5 +93,5 @@ select b, a + ? from t1
--enable_info --enable_info
execute stmt1 using @duplicate, @5, @five, @2, @100, @1, @float ; execute stmt1 using @duplicate, @5, @five, @2, @100, @1, @float ;
--disable_info --disable_info
select a,b from t2; select a,b from t2 order by a ;
drop table t2; drop table t2;
This diff is collapsed.
...@@ -420,6 +420,9 @@ INSERT INTO t1 VALUES ...@@ -420,6 +420,9 @@ INSERT INTO t1 VALUES
(1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5), (1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5),
(6,6,6),(7,7,7),(8,8,8),(9,9,9),(10,10,10); (6,6,6),(7,7,7),(8,8,8),(9,9,9),(10,10,10);
ERROR 23000: Duplicate entry '10' for key 1 ERROR 23000: Duplicate entry '10' for key 1
select count(*) from t1;
count(*)
2000
begin; begin;
SELECT COUNT(*) FROM t1; SELECT COUNT(*) FROM t1;
COUNT(*) COUNT(*)
...@@ -429,17 +432,128 @@ INSERT INTO t1 VALUES ...@@ -429,17 +432,128 @@ INSERT INTO t1 VALUES
SELECT COUNT(*) FROM t1; SELECT COUNT(*) FROM t1;
COUNT(*) COUNT(*)
2005 2005
rollback;
begin;
INSERT INTO t1 VALUES INSERT INTO t1 VALUES
(1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5), (1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5),
(6,6,6),(7,7,7),(8,8,8),(9,9,9),(10,10,10); (6,6,6),(7,7,7),(8,8,8),(9,9,9),(10,10,10);
ERROR 23000: Duplicate entry '10' for key 1 ERROR 23000: Duplicate entry '10' for key 1
SELECT COUNT(*) FROM t1; commit;
COUNT(*) ERROR HY000: Got error 4350 'Transaction already aborted' from ndbcluster
select * from t1 where pk1=1;
pk1 b c
1 1 1
select * from t1 where pk1=10;
pk1 b c
10 10 10
select count(*) from t1 where pk1 <= 10 order by pk1;
count(*)
11
select count(*) from t1;
count(*)
2000
begin;
INSERT INTO t1 VALUES
(1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5),
(6,6,6),(7,7,7),(8,8,8),(9,9,9),(10,10,10);
ERROR 23000: Duplicate entry '10' for key 1
rollback;
select * from t1 where pk1=1;
pk1 b c
1 1 1
select * from t1 where pk1=10;
pk1 b c
10 10 10
select count(*) from t1 where pk1 <= 10 order by pk1;
count(*)
11
select count(*) from t1;
count(*)
2000
begin;
INSERT INTO t1 VALUES
(1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5),
(6,6,6),(7,7,7),(8,8,8),(9,9,9),(10,10,10);
ERROR 23000: Duplicate entry '10' for key 1
SELECT * FROM t1 WHERE pk1=10;
ERROR HY000: Got error 4350 'Transaction already aborted' from ndbcluster
rollback;
select * from t1 where pk1=1;
pk1 b c
1 1 1
select * from t1 where pk1=10;
pk1 b c
10 10 10
select count(*) from t1 where pk1 <= 10 order by pk1;
count(*)
11
select count(*) from t1;
count(*)
2000 2000
begin;
INSERT INTO t1 VALUES
(1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5),
(6,6,6),(7,7,7),(8,8,8),(9,9,9),(10,10,10);
ERROR 23000: Duplicate entry '10' for key 1
SELECT * FROM t1 WHERE pk1=10;
ERROR HY000: Got error 4350 'Transaction already aborted' from ndbcluster
SELECT * FROM t1 WHERE pk1=10;
ERROR HY000: Got error 4350 'Transaction already aborted' from ndbcluster
commit; commit;
SELECT COUNT(*) FROM t1; ERROR HY000: Got error 4350 'Transaction already aborted' from ndbcluster
COUNT(*) select * from t1 where pk1=1;
pk1 b c
1 1 1
select * from t1 where pk1=10;
pk1 b c
10 10 10
select count(*) from t1 where pk1 <= 10 order by pk1;
count(*)
11
select count(*) from t1;
count(*)
2000
begin;
INSERT INTO t1 VALUES
(1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5),
(6,6,6),(7,7,7),(8,8,8),(9,9,9),(10,10,10);
ERROR 23000: Duplicate entry '10' for key 1
INSERT INTO t1 values (4000, 40, 44);
ERROR HY000: Got error 4350 'Transaction already aborted' from ndbcluster
rollback;
select * from t1 where pk1=1;
pk1 b c
1 1 1
select * from t1 where pk1=10;
pk1 b c
10 10 10
select count(*) from t1 where pk1 <= 10 order by pk1;
count(*)
11
select count(*) from t1;
count(*)
2000 2000
insert into t1 select * from t1 where b < 10 order by pk1; insert into t1 select * from t1 where b < 10 order by pk1;
ERROR 23000: Duplicate entry '9' for key 1 ERROR 23000: Duplicate entry '9' for key 1
begin;
INSERT IGNORE INTO t1 VALUES(1,2,3);
ERROR HY000: Table storage engine for 't1' doesn't have this option
commit;
select * from t1 where pk1=1;
pk1 b c
1 1 1
INSERT IGNORE INTO t1 VALUES(1,2,3);
ERROR HY000: Table storage engine for 't1' doesn't have this option
select * from t1 where pk1=1;
pk1 b c
1 1 1
REPLACE INTO t1 values(1, 2, 3);
select * from t1 where pk1=1;
pk1 b c
1 2 3
INSERT INTO t1 VALUES(1,1,1) ON DUPLICATE KEY UPDATE b=79;
ERROR HY000: Table storage engine for 't1' doesn't have this option
select * from t1 where pk1=1;
pk1 b c
1 2 3
DROP TABLE t1; DROP TABLE t1;
...@@ -1016,15 +1016,15 @@ set @arg01=2; ...@@ -1016,15 +1016,15 @@ set @arg01=2;
execute stmt1 using @arg00, @arg01; execute stmt1 using @arg00, @arg01;
Warnings: Warnings:
Warning 1263 Data truncated; NULL supplied to NOT NULL column 'a' at row 1 Warning 1263 Data truncated; NULL supplied to NOT NULL column 'a' at row 1
select a,b from t1; select a,b from t1 order by a;
a b a b
1 one
0 two 0 two
1 one
3 three 3 three
4 four 4 four
set @arg00=0; set @arg00=0;
execute stmt1 using @arg01, @arg00; execute stmt1 using @arg01, @arg00;
select a,b from t1; select a,b from t1 order by a;
a b a b
1 one 1 one
2 two 2 two
...@@ -1048,7 +1048,7 @@ prepare stmt1 from 'update t1 set a=? where b=? ...@@ -1048,7 +1048,7 @@ prepare stmt1 from 'update t1 set a=? where b=?
and a not in (select ? from t2 and a not in (select ? from t2
where b = ? or a = ?)'; where b = ? or a = ?)';
execute stmt1 using @arg04, @arg01, @arg02, @arg03, @arg00 ; execute stmt1 using @arg04, @arg01, @arg02, @arg03, @arg00 ;
select a,b from t1 ; select a,b from t1 order by a;
a b a b
1 one 1 one
2 two 2 two
...@@ -1142,19 +1142,19 @@ set @arg01=1 ; ...@@ -1142,19 +1142,19 @@ set @arg01=1 ;
prepare stmt1 from 'insert into t1 set a=?, b=''sechs'' prepare stmt1 from 'insert into t1 set a=?, b=''sechs''
on duplicate key update a=a + ?, b=concat(b,''modified'') '; on duplicate key update a=a + ?, b=concat(b,''modified'') ';
execute stmt1 using @arg00, @arg01; execute stmt1 using @arg00, @arg01;
select * from t1; select * from t1 order by a;
a b a b
0 NULL
1 one 1 one
2 two 2 two
3 three 3 three
4 four 4 four
5 five 5 five
7 sixmodified 7 sixmodified
0 NULL
8 eight 8 eight
9 nine
81 8-1 81 8-1
82 8-2 82 8-2
9 nine
set @arg00=81 ; set @arg00=81 ;
set @arg01=1 ; set @arg01=1 ;
execute stmt1 using @arg00, @arg01; execute stmt1 using @arg00, @arg01;
...@@ -1170,7 +1170,7 @@ set @updated="updated" ; ...@@ -1170,7 +1170,7 @@ set @updated="updated" ;
insert into t1 values(1000,'x1000_1') ; insert into t1 values(1000,'x1000_1') ;
insert into t1 values(@1000,@x1000_2),(@1000,@x1000_3) insert into t1 values(@1000,@x1000_2),(@1000,@x1000_3)
on duplicate key update a = a + @100, b = concat(b,@updated) ; on duplicate key update a = a + @100, b = concat(b,@updated) ;
select a,b from t1 where a >= 1000 ; select a,b from t1 where a >= 1000 order by a ;
a b a b
1000 x1000_3 1000 x1000_3
1100 x1000_1updated 1100 x1000_1updated
...@@ -1179,14 +1179,14 @@ insert into t1 values(1000,'x1000_1') ; ...@@ -1179,14 +1179,14 @@ insert into t1 values(1000,'x1000_1') ;
prepare stmt1 from ' insert into t1 values(?,?),(?,?) prepare stmt1 from ' insert into t1 values(?,?),(?,?)
on duplicate key update a = a + ?, b = concat(b,?) '; on duplicate key update a = a + ?, b = concat(b,?) ';
execute stmt1 using @1000, @x1000_2, @1000, @x1000_3, @100, @updated ; execute stmt1 using @1000, @x1000_2, @1000, @x1000_3, @100, @updated ;
select a,b from t1 where a >= 1000 ; select a,b from t1 where a >= 1000 order by a ;
a b a b
1000 x1000_3 1000 x1000_3
1100 x1000_1updated 1100 x1000_1updated
delete from t1 where a >= 1000 ; delete from t1 where a >= 1000 ;
insert into t1 values(1000,'x1000_1') ; insert into t1 values(1000,'x1000_1') ;
execute stmt1 using @1000, @x1000_2, @1100, @x1000_3, @100, @updated ; execute stmt1 using @1000, @x1000_2, @1100, @x1000_3, @100, @updated ;
select a,b from t1 where a >= 1000 ; select a,b from t1 where a >= 1000 order by a ;
a b a b
1200 x1000_1updatedupdated 1200 x1000_1updatedupdated
delete from t1 where a >= 1000 ; delete from t1 where a >= 1000 ;
...@@ -1195,37 +1195,37 @@ ERROR HY000: This command is not supported in the prepared statement protocol ye ...@@ -1195,37 +1195,37 @@ ERROR HY000: This command is not supported in the prepared statement protocol ye
set @duplicate='duplicate ' ; set @duplicate='duplicate ' ;
set @1000=1000 ; set @1000=1000 ;
set @5=5 ; set @5=5 ;
select a,b from t1 where a < 5 ; select a,b from t1 where a < 5 order by a ;
a b a b
0 NULL
1 one 1 one
2 two 2 two
3 three 3 three
4 four 4 four
0 NULL
insert into t1 select a + @1000, concat(@duplicate,b) from t1 insert into t1 select a + @1000, concat(@duplicate,b) from t1
where a < @5 ; where a < @5 ;
affected rows: 5 affected rows: 5
info: Records: 5 Duplicates: 0 Warnings: 0 info: Records: 5 Duplicates: 0 Warnings: 0
select a,b from t1 where a >= 1000 ; select a,b from t1 where a >= 1000 order by a ;
a b a b
1000 NULL
1001 duplicate one 1001 duplicate one
1002 duplicate two 1002 duplicate two
1003 duplicate three 1003 duplicate three
1004 duplicate four 1004 duplicate four
1000 NULL
delete from t1 where a >= 1000 ; delete from t1 where a >= 1000 ;
prepare stmt1 from ' insert into t1 select a + ?, concat(?,b) from t1 prepare stmt1 from ' insert into t1 select a + ?, concat(?,b) from t1
where a < ? ' ; where a < ? ' ;
execute stmt1 using @1000, @duplicate, @5; execute stmt1 using @1000, @duplicate, @5;
affected rows: 5 affected rows: 5
info: Records: 5 Duplicates: 0 Warnings: 0 info: Records: 5 Duplicates: 0 Warnings: 0
select a,b from t1 where a >= 1000 ; select a,b from t1 where a >= 1000 order by a ;
a b a b
1004 duplicate four
1003 duplicate three
1002 duplicate two
1001 duplicate one
1000 NULL 1000 NULL
1001 duplicate one
1002 duplicate two
1003 duplicate three
1004 duplicate four
delete from t1 where a >= 1000 ; delete from t1 where a >= 1000 ;
set @float=1.00; set @float=1.00;
set @five='five' ; set @five='five' ;
...@@ -1243,15 +1243,15 @@ where (a,b) in ( select sqrt(a+@1)+CAST(@float AS signed),b ...@@ -1243,15 +1243,15 @@ where (a,b) in ( select sqrt(a+@1)+CAST(@float AS signed),b
from t1); from t1);
affected rows: 8 affected rows: 8
info: Records: 8 Duplicates: 0 Warnings: 0 info: Records: 8 Duplicates: 0 Warnings: 0
select a,b from t2; select a,b from t2 order by a ;
a b a b
81 duplicate 3 duplicate
82 duplicate
8 duplicate
4 duplicate 4 duplicate
9 duplicate
7 duplicate 7 duplicate
3 duplicate 8 duplicate
9 duplicate
81 duplicate
82 duplicate
103 three 103 three
delete from t2 ; delete from t2 ;
prepare stmt1 from ' insert into t2 (b,a) prepare stmt1 from ' insert into t2 (b,a)
...@@ -1267,15 +1267,15 @@ select b, a + ? from t1 ...@@ -1267,15 +1267,15 @@ select b, a + ? from t1
execute stmt1 using @duplicate, @5, @five, @2, @100, @1, @float ; execute stmt1 using @duplicate, @5, @five, @2, @100, @1, @float ;
affected rows: 8 affected rows: 8
info: Records: 8 Duplicates: 0 Warnings: 0 info: Records: 8 Duplicates: 0 Warnings: 0
select a,b from t2; select a,b from t2 order by a ;
a b a b
81 duplicate 3 duplicate
82 duplicate
8 duplicate
4 duplicate 4 duplicate
9 duplicate
7 duplicate 7 duplicate
3 duplicate 8 duplicate
9 duplicate
81 duplicate
82 duplicate
103 three 103 three
drop table t2; drop table t2;
drop table t1, t_many_col_types; drop table t1, t_many_col_types;
...@@ -1016,7 +1016,7 @@ set @arg01=2; ...@@ -1016,7 +1016,7 @@ set @arg01=2;
execute stmt1 using @arg00, @arg01; execute stmt1 using @arg00, @arg01;
Warnings: Warnings:
Warning 1263 Data truncated; NULL supplied to NOT NULL column 'a' at row 1 Warning 1263 Data truncated; NULL supplied to NOT NULL column 'a' at row 1
select a,b from t1; select a,b from t1 order by a;
a b a b
0 two 0 two
1 one 1 one
...@@ -1024,7 +1024,7 @@ a b ...@@ -1024,7 +1024,7 @@ a b
4 four 4 four
set @arg00=0; set @arg00=0;
execute stmt1 using @arg01, @arg00; execute stmt1 using @arg01, @arg00;
select a,b from t1; select a,b from t1 order by a;
a b a b
1 one 1 one
2 two 2 two
...@@ -1048,7 +1048,7 @@ prepare stmt1 from 'update t1 set a=? where b=? ...@@ -1048,7 +1048,7 @@ prepare stmt1 from 'update t1 set a=? where b=?
and a not in (select ? from t2 and a not in (select ? from t2
where b = ? or a = ?)'; where b = ? or a = ?)';
execute stmt1 using @arg04, @arg01, @arg02, @arg03, @arg00 ; execute stmt1 using @arg04, @arg01, @arg02, @arg03, @arg00 ;
select a,b from t1 ; select a,b from t1 order by a;
a b a b
1 one 1 one
2 two 2 two
...@@ -1142,7 +1142,7 @@ set @arg01=1 ; ...@@ -1142,7 +1142,7 @@ set @arg01=1 ;
prepare stmt1 from 'insert into t1 set a=?, b=''sechs'' prepare stmt1 from 'insert into t1 set a=?, b=''sechs''
on duplicate key update a=a + ?, b=concat(b,''modified'') '; on duplicate key update a=a + ?, b=concat(b,''modified'') ';
execute stmt1 using @arg00, @arg01; execute stmt1 using @arg00, @arg01;
select * from t1; select * from t1 order by a;
a b a b
0 NULL 0 NULL
1 one 1 one
...@@ -1170,7 +1170,7 @@ set @updated="updated" ; ...@@ -1170,7 +1170,7 @@ set @updated="updated" ;
insert into t1 values(1000,'x1000_1') ; insert into t1 values(1000,'x1000_1') ;
insert into t1 values(@1000,@x1000_2),(@1000,@x1000_3) insert into t1 values(@1000,@x1000_2),(@1000,@x1000_3)
on duplicate key update a = a + @100, b = concat(b,@updated) ; on duplicate key update a = a + @100, b = concat(b,@updated) ;
select a,b from t1 where a >= 1000 ; select a,b from t1 where a >= 1000 order by a ;
a b a b
1000 x1000_3 1000 x1000_3
1100 x1000_1updated 1100 x1000_1updated
...@@ -1179,14 +1179,14 @@ insert into t1 values(1000,'x1000_1') ; ...@@ -1179,14 +1179,14 @@ insert into t1 values(1000,'x1000_1') ;
prepare stmt1 from ' insert into t1 values(?,?),(?,?) prepare stmt1 from ' insert into t1 values(?,?),(?,?)
on duplicate key update a = a + ?, b = concat(b,?) '; on duplicate key update a = a + ?, b = concat(b,?) ';
execute stmt1 using @1000, @x1000_2, @1000, @x1000_3, @100, @updated ; execute stmt1 using @1000, @x1000_2, @1000, @x1000_3, @100, @updated ;
select a,b from t1 where a >= 1000 ; select a,b from t1 where a >= 1000 order by a ;
a b a b
1000 x1000_3 1000 x1000_3
1100 x1000_1updated 1100 x1000_1updated
delete from t1 where a >= 1000 ; delete from t1 where a >= 1000 ;
insert into t1 values(1000,'x1000_1') ; insert into t1 values(1000,'x1000_1') ;
execute stmt1 using @1000, @x1000_2, @1100, @x1000_3, @100, @updated ; execute stmt1 using @1000, @x1000_2, @1100, @x1000_3, @100, @updated ;
select a,b from t1 where a >= 1000 ; select a,b from t1 where a >= 1000 order by a ;
a b a b
1200 x1000_1updatedupdated 1200 x1000_1updatedupdated
delete from t1 where a >= 1000 ; delete from t1 where a >= 1000 ;
...@@ -1195,7 +1195,7 @@ ERROR HY000: This command is not supported in the prepared statement protocol ye ...@@ -1195,7 +1195,7 @@ ERROR HY000: This command is not supported in the prepared statement protocol ye
set @duplicate='duplicate ' ; set @duplicate='duplicate ' ;
set @1000=1000 ; set @1000=1000 ;
set @5=5 ; set @5=5 ;
select a,b from t1 where a < 5 ; select a,b from t1 where a < 5 order by a ;
a b a b
0 NULL 0 NULL
1 one 1 one
...@@ -1206,7 +1206,7 @@ insert into t1 select a + @1000, concat(@duplicate,b) from t1 ...@@ -1206,7 +1206,7 @@ insert into t1 select a + @1000, concat(@duplicate,b) from t1
where a < @5 ; where a < @5 ;
affected rows: 5 affected rows: 5
info: Records: 5 Duplicates: 0 Warnings: 0 info: Records: 5 Duplicates: 0 Warnings: 0
select a,b from t1 where a >= 1000 ; select a,b from t1 where a >= 1000 order by a ;
a b a b
1000 NULL 1000 NULL
1001 duplicate one 1001 duplicate one
...@@ -1219,7 +1219,7 @@ where a < ? ' ; ...@@ -1219,7 +1219,7 @@ where a < ? ' ;
execute stmt1 using @1000, @duplicate, @5; execute stmt1 using @1000, @duplicate, @5;
affected rows: 5 affected rows: 5
info: Records: 5 Duplicates: 0 Warnings: 0 info: Records: 5 Duplicates: 0 Warnings: 0
select a,b from t1 where a >= 1000 ; select a,b from t1 where a >= 1000 order by a ;
a b a b
1000 NULL 1000 NULL
1001 duplicate one 1001 duplicate one
...@@ -1243,7 +1243,7 @@ where (a,b) in ( select sqrt(a+@1)+CAST(@float AS signed),b ...@@ -1243,7 +1243,7 @@ where (a,b) in ( select sqrt(a+@1)+CAST(@float AS signed),b
from t1); from t1);
affected rows: 8 affected rows: 8
info: Records: 8 Duplicates: 0 Warnings: 0 info: Records: 8 Duplicates: 0 Warnings: 0
select a,b from t2; select a,b from t2 order by a ;
a b a b
3 duplicate 3 duplicate
4 duplicate 4 duplicate
...@@ -1267,7 +1267,7 @@ select b, a + ? from t1 ...@@ -1267,7 +1267,7 @@ select b, a + ? from t1
execute stmt1 using @duplicate, @5, @five, @2, @100, @1, @float ; execute stmt1 using @duplicate, @5, @five, @2, @100, @1, @float ;
affected rows: 8 affected rows: 8
info: Records: 8 Duplicates: 0 Warnings: 0 info: Records: 8 Duplicates: 0 Warnings: 0
select a,b from t2; select a,b from t2 order by a ;
a b a b
3 duplicate 3 duplicate
4 duplicate 4 duplicate
......
...@@ -1017,15 +1017,15 @@ set @arg01=2; ...@@ -1017,15 +1017,15 @@ set @arg01=2;
execute stmt1 using @arg00, @arg01; execute stmt1 using @arg00, @arg01;
Warnings: Warnings:
Warning 1263 Data truncated; NULL supplied to NOT NULL column 'a' at row 1 Warning 1263 Data truncated; NULL supplied to NOT NULL column 'a' at row 1
select a,b from t1; select a,b from t1 order by a;
a b a b
1 one
0 two 0 two
1 one
3 three 3 three
4 four 4 four
set @arg00=0; set @arg00=0;
execute stmt1 using @arg01, @arg00; execute stmt1 using @arg01, @arg00;
select a,b from t1; select a,b from t1 order by a;
a b a b
1 one 1 one
2 two 2 two
...@@ -1049,7 +1049,7 @@ prepare stmt1 from 'update t1 set a=? where b=? ...@@ -1049,7 +1049,7 @@ prepare stmt1 from 'update t1 set a=? where b=?
and a not in (select ? from t2 and a not in (select ? from t2
where b = ? or a = ?)'; where b = ? or a = ?)';
execute stmt1 using @arg04, @arg01, @arg02, @arg03, @arg00 ; execute stmt1 using @arg04, @arg01, @arg02, @arg03, @arg00 ;
select a,b from t1 ; select a,b from t1 order by a;
a b a b
1 one 1 one
2 two 2 two
...@@ -1143,19 +1143,19 @@ set @arg01=1 ; ...@@ -1143,19 +1143,19 @@ set @arg01=1 ;
prepare stmt1 from 'insert into t1 set a=?, b=''sechs'' prepare stmt1 from 'insert into t1 set a=?, b=''sechs''
on duplicate key update a=a + ?, b=concat(b,''modified'') '; on duplicate key update a=a + ?, b=concat(b,''modified'') ';
execute stmt1 using @arg00, @arg01; execute stmt1 using @arg00, @arg01;
select * from t1; select * from t1 order by a;
a b a b
0 NULL
1 one 1 one
2 two 2 two
3 three 3 three
4 four 4 four
5 five 5 five
7 sixmodified 7 sixmodified
0 NULL
8 eight 8 eight
9 nine
81 8-1 81 8-1
82 8-2 82 8-2
9 nine
set @arg00=81 ; set @arg00=81 ;
set @arg01=1 ; set @arg01=1 ;
execute stmt1 using @arg00, @arg01; execute stmt1 using @arg00, @arg01;
...@@ -1171,23 +1171,23 @@ set @updated="updated" ; ...@@ -1171,23 +1171,23 @@ set @updated="updated" ;
insert into t1 values(1000,'x1000_1') ; insert into t1 values(1000,'x1000_1') ;
insert into t1 values(@1000,@x1000_2),(@1000,@x1000_3) insert into t1 values(@1000,@x1000_2),(@1000,@x1000_3)
on duplicate key update a = a + @100, b = concat(b,@updated) ; on duplicate key update a = a + @100, b = concat(b,@updated) ;
select a,b from t1 where a >= 1000 ; select a,b from t1 where a >= 1000 order by a ;
a b a b
1100 x1000_1updated
1000 x1000_3 1000 x1000_3
1100 x1000_1updated
delete from t1 where a >= 1000 ; delete from t1 where a >= 1000 ;
insert into t1 values(1000,'x1000_1') ; insert into t1 values(1000,'x1000_1') ;
prepare stmt1 from ' insert into t1 values(?,?),(?,?) prepare stmt1 from ' insert into t1 values(?,?),(?,?)
on duplicate key update a = a + ?, b = concat(b,?) '; on duplicate key update a = a + ?, b = concat(b,?) ';
execute stmt1 using @1000, @x1000_2, @1000, @x1000_3, @100, @updated ; execute stmt1 using @1000, @x1000_2, @1000, @x1000_3, @100, @updated ;
select a,b from t1 where a >= 1000 ; select a,b from t1 where a >= 1000 order by a ;
a b a b
1000 x1000_3 1000 x1000_3
1100 x1000_1updated 1100 x1000_1updated
delete from t1 where a >= 1000 ; delete from t1 where a >= 1000 ;
insert into t1 values(1000,'x1000_1') ; insert into t1 values(1000,'x1000_1') ;
execute stmt1 using @1000, @x1000_2, @1100, @x1000_3, @100, @updated ; execute stmt1 using @1000, @x1000_2, @1100, @x1000_3, @100, @updated ;
select a,b from t1 where a >= 1000 ; select a,b from t1 where a >= 1000 order by a ;
a b a b
1200 x1000_1updatedupdated 1200 x1000_1updatedupdated
delete from t1 where a >= 1000 ; delete from t1 where a >= 1000 ;
...@@ -1196,37 +1196,37 @@ ERROR HY000: This command is not supported in the prepared statement protocol ye ...@@ -1196,37 +1196,37 @@ ERROR HY000: This command is not supported in the prepared statement protocol ye
set @duplicate='duplicate ' ; set @duplicate='duplicate ' ;
set @1000=1000 ; set @1000=1000 ;
set @5=5 ; set @5=5 ;
select a,b from t1 where a < 5 ; select a,b from t1 where a < 5 order by a ;
a b a b
0 NULL
1 one 1 one
2 two 2 two
3 three 3 three
4 four 4 four
0 NULL
insert into t1 select a + @1000, concat(@duplicate,b) from t1 insert into t1 select a + @1000, concat(@duplicate,b) from t1
where a < @5 ; where a < @5 ;
affected rows: 5 affected rows: 5
info: Records: 5 Duplicates: 0 Warnings: 0 info: Records: 5 Duplicates: 0 Warnings: 0
select a,b from t1 where a >= 1000 ; select a,b from t1 where a >= 1000 order by a ;
a b a b
1002 duplicate two 1000 NULL
1001 duplicate one 1001 duplicate one
1002 duplicate two
1003 duplicate three 1003 duplicate three
1004 duplicate four 1004 duplicate four
1000 NULL
delete from t1 where a >= 1000 ; delete from t1 where a >= 1000 ;
prepare stmt1 from ' insert into t1 select a + ?, concat(?,b) from t1 prepare stmt1 from ' insert into t1 select a + ?, concat(?,b) from t1
where a < ? ' ; where a < ? ' ;
execute stmt1 using @1000, @duplicate, @5; execute stmt1 using @1000, @duplicate, @5;
affected rows: 5 affected rows: 5
info: Records: 5 Duplicates: 0 Warnings: 0 info: Records: 5 Duplicates: 0 Warnings: 0
select a,b from t1 where a >= 1000 ; select a,b from t1 where a >= 1000 order by a ;
a b a b
1000 NULL 1000 NULL
1004 duplicate four
1003 duplicate three
1002 duplicate two
1001 duplicate one 1001 duplicate one
1002 duplicate two
1003 duplicate three
1004 duplicate four
delete from t1 where a >= 1000 ; delete from t1 where a >= 1000 ;
set @float=1.00; set @float=1.00;
set @five='five' ; set @five='five' ;
...@@ -1244,15 +1244,15 @@ where (a,b) in ( select sqrt(a+@1)+CAST(@float AS signed),b ...@@ -1244,15 +1244,15 @@ where (a,b) in ( select sqrt(a+@1)+CAST(@float AS signed),b
from t1); from t1);
affected rows: 8 affected rows: 8
info: Records: 8 Duplicates: 0 Warnings: 0 info: Records: 8 Duplicates: 0 Warnings: 0
select a,b from t2; select a,b from t2 order by a ;
a b a b
81 duplicate 3 duplicate
82 duplicate
8 duplicate
4 duplicate 4 duplicate
9 duplicate
7 duplicate 7 duplicate
3 duplicate 8 duplicate
9 duplicate
81 duplicate
82 duplicate
103 three 103 three
delete from t2 ; delete from t2 ;
prepare stmt1 from ' insert into t2 (b,a) prepare stmt1 from ' insert into t2 (b,a)
...@@ -1268,15 +1268,15 @@ select b, a + ? from t1 ...@@ -1268,15 +1268,15 @@ select b, a + ? from t1
execute stmt1 using @duplicate, @5, @five, @2, @100, @1, @float ; execute stmt1 using @duplicate, @5, @five, @2, @100, @1, @float ;
affected rows: 8 affected rows: 8
info: Records: 8 Duplicates: 0 Warnings: 0 info: Records: 8 Duplicates: 0 Warnings: 0
select a,b from t2; select a,b from t2 order by a ;
a b a b
81 duplicate 3 duplicate
82 duplicate
8 duplicate
4 duplicate 4 duplicate
9 duplicate
7 duplicate 7 duplicate
3 duplicate 8 duplicate
9 duplicate
81 duplicate
82 duplicate
103 three 103 three
drop table t2; drop table t2;
drop table t1, t_many_col_types; drop table t1, t_many_col_types;
...@@ -1059,19 +1059,19 @@ set @arg01=2; ...@@ -1059,19 +1059,19 @@ set @arg01=2;
execute stmt1 using @arg00, @arg01; execute stmt1 using @arg00, @arg01;
Warnings: Warnings:
Warning 1263 Data truncated; NULL supplied to NOT NULL column 'a' at row 1 Warning 1263 Data truncated; NULL supplied to NOT NULL column 'a' at row 1
select a,b from t1; select a,b from t1 order by a;
a b a b
3 three
0 two 0 two
1 one 1 one
3 three
4 four 4 four
set @arg00=0; set @arg00=0;
execute stmt1 using @arg01, @arg00; execute stmt1 using @arg01, @arg00;
select a,b from t1; select a,b from t1 order by a;
a b a b
3 three
2 two
1 one 1 one
2 two
3 three
4 four 4 four
set @arg00=23; set @arg00=23;
set @arg01='two'; set @arg01='two';
...@@ -1091,11 +1091,11 @@ prepare stmt1 from 'update t1 set a=? where b=? ...@@ -1091,11 +1091,11 @@ prepare stmt1 from 'update t1 set a=? where b=?
and a not in (select ? from t2 and a not in (select ? from t2
where b = ? or a = ?)'; where b = ? or a = ?)';
execute stmt1 using @arg04, @arg01, @arg02, @arg03, @arg00 ; execute stmt1 using @arg04, @arg01, @arg02, @arg03, @arg00 ;
select a,b from t1 ; select a,b from t1 order by a;
a b a b
3 three
2 two
1 one 1 one
2 two
3 three
4 four 4 four
drop table t2 ; drop table t2 ;
set @arg00=1; set @arg00=1;
...@@ -1185,19 +1185,19 @@ set @arg01=1 ; ...@@ -1185,19 +1185,19 @@ set @arg01=1 ;
prepare stmt1 from 'insert into t1 set a=?, b=''sechs'' prepare stmt1 from 'insert into t1 set a=?, b=''sechs''
on duplicate key update a=a + ?, b=concat(b,''modified'') '; on duplicate key update a=a + ?, b=concat(b,''modified'') ';
execute stmt1 using @arg00, @arg01; execute stmt1 using @arg00, @arg01;
select * from t1; select * from t1 order by a;
a b a b
4 four 0 NULL
3 three
2 two
1 one 1 one
2 two
3 three
4 four
5 five 5 five
7 sixmodified 7 sixmodified
0 NULL
8 eight 8 eight
9 nine
81 8-1 81 8-1
82 8-2 82 8-2
9 nine
set @arg00=81 ; set @arg00=81 ;
set @arg01=1 ; set @arg01=1 ;
execute stmt1 using @arg00, @arg01; execute stmt1 using @arg00, @arg01;
...@@ -1213,7 +1213,7 @@ set @updated="updated" ; ...@@ -1213,7 +1213,7 @@ set @updated="updated" ;
insert into t1 values(1000,'x1000_1') ; insert into t1 values(1000,'x1000_1') ;
insert into t1 values(@1000,@x1000_2),(@1000,@x1000_3) insert into t1 values(@1000,@x1000_2),(@1000,@x1000_3)
on duplicate key update a = a + @100, b = concat(b,@updated) ; on duplicate key update a = a + @100, b = concat(b,@updated) ;
select a,b from t1 where a >= 1000 ; select a,b from t1 where a >= 1000 order by a ;
a b a b
1000 x1000_3 1000 x1000_3
1100 x1000_1updated 1100 x1000_1updated
...@@ -1222,14 +1222,14 @@ insert into t1 values(1000,'x1000_1') ; ...@@ -1222,14 +1222,14 @@ insert into t1 values(1000,'x1000_1') ;
prepare stmt1 from ' insert into t1 values(?,?),(?,?) prepare stmt1 from ' insert into t1 values(?,?),(?,?)
on duplicate key update a = a + ?, b = concat(b,?) '; on duplicate key update a = a + ?, b = concat(b,?) ';
execute stmt1 using @1000, @x1000_2, @1000, @x1000_3, @100, @updated ; execute stmt1 using @1000, @x1000_2, @1000, @x1000_3, @100, @updated ;
select a,b from t1 where a >= 1000 ; select a,b from t1 where a >= 1000 order by a ;
a b a b
1000 x1000_3 1000 x1000_3
1100 x1000_1updated 1100 x1000_1updated
delete from t1 where a >= 1000 ; delete from t1 where a >= 1000 ;
insert into t1 values(1000,'x1000_1') ; insert into t1 values(1000,'x1000_1') ;
execute stmt1 using @1000, @x1000_2, @1100, @x1000_3, @100, @updated ; execute stmt1 using @1000, @x1000_2, @1100, @x1000_3, @100, @updated ;
select a,b from t1 where a >= 1000 ; select a,b from t1 where a >= 1000 order by a ;
a b a b
1200 x1000_1updatedupdated 1200 x1000_1updatedupdated
delete from t1 where a >= 1000 ; delete from t1 where a >= 1000 ;
...@@ -2254,19 +2254,19 @@ set @arg01=2; ...@@ -2254,19 +2254,19 @@ set @arg01=2;
execute stmt1 using @arg00, @arg01; execute stmt1 using @arg00, @arg01;
Warnings: Warnings:
Warning 1263 Data truncated; NULL supplied to NOT NULL column 'a' at row 1 Warning 1263 Data truncated; NULL supplied to NOT NULL column 'a' at row 1
select a,b from t1; select a,b from t1 order by a;
a b a b
3 three
0 two 0 two
1 one 1 one
3 three
4 four 4 four
set @arg00=0; set @arg00=0;
execute stmt1 using @arg01, @arg00; execute stmt1 using @arg01, @arg00;
select a,b from t1; select a,b from t1 order by a;
a b a b
3 three
2 two
1 one 1 one
2 two
3 three
4 four 4 four
set @arg00=23; set @arg00=23;
set @arg01='two'; set @arg01='two';
...@@ -2286,11 +2286,11 @@ prepare stmt1 from 'update t1 set a=? where b=? ...@@ -2286,11 +2286,11 @@ prepare stmt1 from 'update t1 set a=? where b=?
and a not in (select ? from t2 and a not in (select ? from t2
where b = ? or a = ?)'; where b = ? or a = ?)';
execute stmt1 using @arg04, @arg01, @arg02, @arg03, @arg00 ; execute stmt1 using @arg04, @arg01, @arg02, @arg03, @arg00 ;
select a,b from t1 ; select a,b from t1 order by a;
a b a b
3 three
2 two
1 one 1 one
2 two
3 three
4 four 4 four
drop table t2 ; drop table t2 ;
set @arg00=1; set @arg00=1;
...@@ -2380,19 +2380,19 @@ set @arg01=1 ; ...@@ -2380,19 +2380,19 @@ set @arg01=1 ;
prepare stmt1 from 'insert into t1 set a=?, b=''sechs'' prepare stmt1 from 'insert into t1 set a=?, b=''sechs''
on duplicate key update a=a + ?, b=concat(b,''modified'') '; on duplicate key update a=a + ?, b=concat(b,''modified'') ';
execute stmt1 using @arg00, @arg01; execute stmt1 using @arg00, @arg01;
select * from t1; select * from t1 order by a;
a b a b
4 four 0 NULL
3 three
2 two
1 one 1 one
2 two
3 three
4 four
5 five 5 five
7 sixmodified 7 sixmodified
0 NULL
8 eight 8 eight
9 nine
81 8-1 81 8-1
82 8-2 82 8-2
9 nine
set @arg00=81 ; set @arg00=81 ;
set @arg01=1 ; set @arg01=1 ;
execute stmt1 using @arg00, @arg01; execute stmt1 using @arg00, @arg01;
...@@ -2408,7 +2408,7 @@ set @updated="updated" ; ...@@ -2408,7 +2408,7 @@ set @updated="updated" ;
insert into t1 values(1000,'x1000_1') ; insert into t1 values(1000,'x1000_1') ;
insert into t1 values(@1000,@x1000_2),(@1000,@x1000_3) insert into t1 values(@1000,@x1000_2),(@1000,@x1000_3)
on duplicate key update a = a + @100, b = concat(b,@updated) ; on duplicate key update a = a + @100, b = concat(b,@updated) ;
select a,b from t1 where a >= 1000 ; select a,b from t1 where a >= 1000 order by a ;
a b a b
1000 x1000_3 1000 x1000_3
1100 x1000_1updated 1100 x1000_1updated
...@@ -2417,14 +2417,14 @@ insert into t1 values(1000,'x1000_1') ; ...@@ -2417,14 +2417,14 @@ insert into t1 values(1000,'x1000_1') ;
prepare stmt1 from ' insert into t1 values(?,?),(?,?) prepare stmt1 from ' insert into t1 values(?,?),(?,?)
on duplicate key update a = a + ?, b = concat(b,?) '; on duplicate key update a = a + ?, b = concat(b,?) ';
execute stmt1 using @1000, @x1000_2, @1000, @x1000_3, @100, @updated ; execute stmt1 using @1000, @x1000_2, @1000, @x1000_3, @100, @updated ;
select a,b from t1 where a >= 1000 ; select a,b from t1 where a >= 1000 order by a ;
a b a b
1000 x1000_3 1000 x1000_3
1100 x1000_1updated 1100 x1000_1updated
delete from t1 where a >= 1000 ; delete from t1 where a >= 1000 ;
insert into t1 values(1000,'x1000_1') ; insert into t1 values(1000,'x1000_1') ;
execute stmt1 using @1000, @x1000_2, @1100, @x1000_3, @100, @updated ; execute stmt1 using @1000, @x1000_2, @1100, @x1000_3, @100, @updated ;
select a,b from t1 where a >= 1000 ; select a,b from t1 where a >= 1000 order by a ;
a b a b
1200 x1000_1updatedupdated 1200 x1000_1updatedupdated
delete from t1 where a >= 1000 ; delete from t1 where a >= 1000 ;
......
...@@ -1016,7 +1016,7 @@ set @arg01=2; ...@@ -1016,7 +1016,7 @@ set @arg01=2;
execute stmt1 using @arg00, @arg01; execute stmt1 using @arg00, @arg01;
Warnings: Warnings:
Warning 1263 Data truncated; NULL supplied to NOT NULL column 'a' at row 1 Warning 1263 Data truncated; NULL supplied to NOT NULL column 'a' at row 1
select a,b from t1; select a,b from t1 order by a;
a b a b
0 two 0 two
1 one 1 one
...@@ -1024,7 +1024,7 @@ a b ...@@ -1024,7 +1024,7 @@ a b
4 four 4 four
set @arg00=0; set @arg00=0;
execute stmt1 using @arg01, @arg00; execute stmt1 using @arg01, @arg00;
select a,b from t1; select a,b from t1 order by a;
a b a b
1 one 1 one
2 two 2 two
...@@ -1048,7 +1048,7 @@ prepare stmt1 from 'update t1 set a=? where b=? ...@@ -1048,7 +1048,7 @@ prepare stmt1 from 'update t1 set a=? where b=?
and a not in (select ? from t2 and a not in (select ? from t2
where b = ? or a = ?)'; where b = ? or a = ?)';
execute stmt1 using @arg04, @arg01, @arg02, @arg03, @arg00 ; execute stmt1 using @arg04, @arg01, @arg02, @arg03, @arg00 ;
select a,b from t1 ; select a,b from t1 order by a;
a b a b
1 one 1 one
2 two 2 two
...@@ -1142,7 +1142,7 @@ set @arg01=1 ; ...@@ -1142,7 +1142,7 @@ set @arg01=1 ;
prepare stmt1 from 'insert into t1 set a=?, b=''sechs'' prepare stmt1 from 'insert into t1 set a=?, b=''sechs''
on duplicate key update a=a + ?, b=concat(b,''modified'') '; on duplicate key update a=a + ?, b=concat(b,''modified'') ';
execute stmt1 using @arg00, @arg01; execute stmt1 using @arg00, @arg01;
select * from t1; select * from t1 order by a;
a b a b
0 NULL 0 NULL
1 one 1 one
...@@ -1170,7 +1170,7 @@ set @updated="updated" ; ...@@ -1170,7 +1170,7 @@ set @updated="updated" ;
insert into t1 values(1000,'x1000_1') ; insert into t1 values(1000,'x1000_1') ;
insert into t1 values(@1000,@x1000_2),(@1000,@x1000_3) insert into t1 values(@1000,@x1000_2),(@1000,@x1000_3)
on duplicate key update a = a + @100, b = concat(b,@updated) ; on duplicate key update a = a + @100, b = concat(b,@updated) ;
select a,b from t1 where a >= 1000 ; select a,b from t1 where a >= 1000 order by a ;
a b a b
1000 x1000_3 1000 x1000_3
1100 x1000_1updated 1100 x1000_1updated
...@@ -1179,14 +1179,14 @@ insert into t1 values(1000,'x1000_1') ; ...@@ -1179,14 +1179,14 @@ insert into t1 values(1000,'x1000_1') ;
prepare stmt1 from ' insert into t1 values(?,?),(?,?) prepare stmt1 from ' insert into t1 values(?,?),(?,?)
on duplicate key update a = a + ?, b = concat(b,?) '; on duplicate key update a = a + ?, b = concat(b,?) ';
execute stmt1 using @1000, @x1000_2, @1000, @x1000_3, @100, @updated ; execute stmt1 using @1000, @x1000_2, @1000, @x1000_3, @100, @updated ;
select a,b from t1 where a >= 1000 ; select a,b from t1 where a >= 1000 order by a ;
a b a b
1000 x1000_3 1000 x1000_3
1100 x1000_1updated 1100 x1000_1updated
delete from t1 where a >= 1000 ; delete from t1 where a >= 1000 ;
insert into t1 values(1000,'x1000_1') ; insert into t1 values(1000,'x1000_1') ;
execute stmt1 using @1000, @x1000_2, @1100, @x1000_3, @100, @updated ; execute stmt1 using @1000, @x1000_2, @1100, @x1000_3, @100, @updated ;
select a,b from t1 where a >= 1000 ; select a,b from t1 where a >= 1000 order by a ;
a b a b
1200 x1000_1updatedupdated 1200 x1000_1updatedupdated
delete from t1 where a >= 1000 ; delete from t1 where a >= 1000 ;
...@@ -1195,7 +1195,7 @@ ERROR HY000: This command is not supported in the prepared statement protocol ye ...@@ -1195,7 +1195,7 @@ ERROR HY000: This command is not supported in the prepared statement protocol ye
set @duplicate='duplicate ' ; set @duplicate='duplicate ' ;
set @1000=1000 ; set @1000=1000 ;
set @5=5 ; set @5=5 ;
select a,b from t1 where a < 5 ; select a,b from t1 where a < 5 order by a ;
a b a b
0 NULL 0 NULL
1 one 1 one
...@@ -1206,7 +1206,7 @@ insert into t1 select a + @1000, concat(@duplicate,b) from t1 ...@@ -1206,7 +1206,7 @@ insert into t1 select a + @1000, concat(@duplicate,b) from t1
where a < @5 ; where a < @5 ;
affected rows: 5 affected rows: 5
info: Records: 5 Duplicates: 0 Warnings: 0 info: Records: 5 Duplicates: 0 Warnings: 0
select a,b from t1 where a >= 1000 ; select a,b from t1 where a >= 1000 order by a ;
a b a b
1000 NULL 1000 NULL
1001 duplicate one 1001 duplicate one
...@@ -1219,7 +1219,7 @@ where a < ? ' ; ...@@ -1219,7 +1219,7 @@ where a < ? ' ;
execute stmt1 using @1000, @duplicate, @5; execute stmt1 using @1000, @duplicate, @5;
affected rows: 5 affected rows: 5
info: Records: 5 Duplicates: 0 Warnings: 0 info: Records: 5 Duplicates: 0 Warnings: 0
select a,b from t1 where a >= 1000 ; select a,b from t1 where a >= 1000 order by a ;
a b a b
1000 NULL 1000 NULL
1001 duplicate one 1001 duplicate one
...@@ -1243,7 +1243,7 @@ where (a,b) in ( select sqrt(a+@1)+CAST(@float AS signed),b ...@@ -1243,7 +1243,7 @@ where (a,b) in ( select sqrt(a+@1)+CAST(@float AS signed),b
from t1); from t1);
affected rows: 8 affected rows: 8
info: Records: 8 Duplicates: 0 Warnings: 0 info: Records: 8 Duplicates: 0 Warnings: 0
select a,b from t2; select a,b from t2 order by a ;
a b a b
3 duplicate 3 duplicate
4 duplicate 4 duplicate
...@@ -1267,7 +1267,7 @@ select b, a + ? from t1 ...@@ -1267,7 +1267,7 @@ select b, a + ? from t1
execute stmt1 using @duplicate, @5, @five, @2, @100, @1, @float ; execute stmt1 using @duplicate, @5, @five, @2, @100, @1, @float ;
affected rows: 8 affected rows: 8
info: Records: 8 Duplicates: 0 Warnings: 0 info: Records: 8 Duplicates: 0 Warnings: 0
select a,b from t2; select a,b from t2 order by a ;
a b a b
3 duplicate 3 duplicate
4 duplicate 4 duplicate
......
...@@ -1297,4 +1297,6 @@ INSERT INTO t2 VALUES (2,011401,37,'breaking','dreaded','Steinberg','W'); ...@@ -1297,4 +1297,6 @@ INSERT INTO t2 VALUES (2,011401,37,'breaking','dreaded','Steinberg','W');
INSERT INTO t2 VALUES (3,011402,37,'Romans','scholastics','jarring',''); INSERT INTO t2 VALUES (3,011402,37,'Romans','scholastics','jarring','');
INSERT INTO t2 VALUES (4,011403,37,'intercepted','audiology','tinily',''); INSERT INTO t2 VALUES (4,011403,37,'intercepted','audiology','tinily','');
SELECT * FROM t2; SELECT * FROM t2;
OPTIMIZE TABLE t2;
SELECT * FROM t2;
drop table t1, t2; drop table t1, t2;
...@@ -437,26 +437,125 @@ INSERT INTO t1 VALUES ...@@ -437,26 +437,125 @@ INSERT INTO t1 VALUES
(1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5), (1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5),
(6,6,6),(7,7,7),(8,8,8),(9,9,9),(10,10,10); (6,6,6),(7,7,7),(8,8,8),(9,9,9),(10,10,10);
select count(*) from t1;
begin;
# #
# Insert duplicate rows, inside transaction # Test that select count(*) can see inserts made in the same transaction
# since failing inserts rollbacks whole transaction
# all select count (except second) return same value
# #
begin;
SELECT COUNT(*) FROM t1; SELECT COUNT(*) FROM t1;
INSERT INTO t1 VALUES INSERT INTO t1 VALUES
(2001,2001,2001),(2002,2002,2002),(2003,2003,2003),(2004,2004,2004),(2005,2005,2005); (2001,2001,2001),(2002,2002,2002),(2003,2003,2003),(2004,2004,2004),(2005,2005,2005);
SELECT COUNT(*) FROM t1; SELECT COUNT(*) FROM t1;
rollback;
#
# Insert duplicate rows, inside transaction
# try to commit
#
begin;
--error 1062 --error 1062
INSERT INTO t1 VALUES INSERT INTO t1 VALUES
(1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5), (1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5),
(6,6,6),(7,7,7),(8,8,8),(9,9,9),(10,10,10); (6,6,6),(7,7,7),(8,8,8),(9,9,9),(10,10,10);
SELECT COUNT(*) FROM t1;
--error 1296
commit; commit;
SELECT COUNT(*) FROM t1;
select * from t1 where pk1=1;
select * from t1 where pk1=10;
select count(*) from t1 where pk1 <= 10 order by pk1;
select count(*) from t1;
#
# Insert duplicate rows, inside transaction
# rollback
#
begin;
--error 1062
INSERT INTO t1 VALUES
(1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5),
(6,6,6),(7,7,7),(8,8,8),(9,9,9),(10,10,10);
rollback;
select * from t1 where pk1=1;
select * from t1 where pk1=10;
select count(*) from t1 where pk1 <= 10 order by pk1;
select count(*) from t1;
#
# Insert duplicate rows, inside transaction
# then try to select, finally rollback
#
begin;
--error 1062
INSERT INTO t1 VALUES
(1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5),
(6,6,6),(7,7,7),(8,8,8),(9,9,9),(10,10,10);
--error 1296
SELECT * FROM t1 WHERE pk1=10;
rollback;
select * from t1 where pk1=1;
select * from t1 where pk1=10;
select count(*) from t1 where pk1 <= 10 order by pk1;
select count(*) from t1;
#
# Insert duplicate rows, inside transaction
# then try to select, finally commit
#
begin;
--error 1062
INSERT INTO t1 VALUES
(1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5),
(6,6,6),(7,7,7),(8,8,8),(9,9,9),(10,10,10);
--error 1296
SELECT * FROM t1 WHERE pk1=10;
--error 1296
SELECT * FROM t1 WHERE pk1=10;
--error 1296
commit;
select * from t1 where pk1=1;
select * from t1 where pk1=10;
select count(*) from t1 where pk1 <= 10 order by pk1;
select count(*) from t1;
#
# Insert duplicate rows, inside transaction
# then try to do another insert
#
begin;
--error 1062
INSERT INTO t1 VALUES
(1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5),
(6,6,6),(7,7,7),(8,8,8),(9,9,9),(10,10,10);
--error 1296
INSERT INTO t1 values (4000, 40, 44);
rollback;
select * from t1 where pk1=1;
select * from t1 where pk1=10;
select count(*) from t1 where pk1 <= 10 order by pk1;
select count(*) from t1;
# #
# Insert duplicate rows using "insert .. select" # Insert duplicate rows using "insert .. select"
...@@ -466,4 +565,21 @@ SELECT COUNT(*) FROM t1; ...@@ -466,4 +565,21 @@ SELECT COUNT(*) FROM t1;
insert into t1 select * from t1 where b < 10 order by pk1; insert into t1 select * from t1 where b < 10 order by pk1;
begin;
--error 1031
INSERT IGNORE INTO t1 VALUES(1,2,3);
commit;
select * from t1 where pk1=1;
--error 1031
INSERT IGNORE INTO t1 VALUES(1,2,3);
select * from t1 where pk1=1;
REPLACE INTO t1 values(1, 2, 3);
select * from t1 where pk1=1;
--error 1031
INSERT INTO t1 VALUES(1,1,1) ON DUPLICATE KEY UPDATE b=79;
select * from t1 where pk1=1;
DROP TABLE t1; DROP TABLE t1;
...@@ -88,6 +88,32 @@ void hash_free(HASH *hash) ...@@ -88,6 +88,32 @@ void hash_free(HASH *hash)
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
/*
Delete all elements from the hash (the hash itself is to be reused).
SYNOPSIS
hash_reset()
hash the hash to delete elements of
*/
void hash_reset(HASH *hash)
{
DBUG_ENTER("hash_reset");
if (hash->free)
{
HASH_LINK *link= dynamic_element(&hash->array, 0, HASH_LINK*);
HASH_LINK *end= link + hash->records;
for (; link < end; ++link)
(*hash->free)(link->data);
}
reset_dynamic(&hash->array);
hash->records= 0;
hash->blength= 1;
hash->current_record= NO_RECORD;
DBUG_VOID_RETURN;
}
/* some helper functions */ /* some helper functions */
/* /*
......
...@@ -229,10 +229,10 @@ LocalConfig::parseString(const char * connectString, char *line){ ...@@ -229,10 +229,10 @@ LocalConfig::parseString(const char * connectString, char *line){
bool LocalConfig::readFile(const char * filename, bool &fopenError) bool LocalConfig::readFile(const char * filename, bool &fopenError)
{ {
char line[150], line2[150]; char line[1024];
fopenError = false; fopenError = false;
FILE * file = fopen(filename, "r"); FILE * file = fopen(filename, "r");
if(file == 0){ if(file == 0){
snprintf(line, 150, "Unable to open local config file: %s", filename); snprintf(line, 150, "Unable to open local config file: %s", filename);
...@@ -241,31 +241,33 @@ bool LocalConfig::readFile(const char * filename, bool &fopenError) ...@@ -241,31 +241,33 @@ bool LocalConfig::readFile(const char * filename, bool &fopenError)
return false; return false;
} }
unsigned int sz = 1024; BaseString theString;
char* theString = (char*)NdbMem_Allocate(sz);
theString[0] = 0; while(fgets(line, 1024, file)){
BaseString tmp(line);
fgets(theString, sz, file); tmp.trim(" \t\n\r");
while (fgets(line+1, 100, file)) { if(tmp.length() > 0 && tmp.c_str()[0] != '#'){
line[0] = ';'; theString.append(tmp);
while (strlen(theString) + strlen(line) >= sz) { break;
sz = sz*2;
char *newString = (char*)NdbMem_Allocate(sz);
strcpy(newString, theString);
free(theString);
theString = newString;
} }
strcat(theString, line);
} }
while (fgets(line, 1024, file)) {
bool return_value = parseString(theString, line); BaseString tmp(line);
tmp.trim(" \t\n\r");
if(tmp.length() > 0 && tmp.c_str()[0] != '#'){
theString.append(";");
theString.append(tmp);
}
}
bool return_value = parseString(theString.c_str(), line);
if (!return_value) { if (!return_value) {
snprintf(line2, 150, "Reading %s: %s", filename, line); BaseString tmp;
setError(0,line2); tmp.assfmt("Reading %s: %s", filename, line);
setError(0, tmp.c_str());
} }
free(theString);
fclose(file); fclose(file);
return return_value; return return_value;
} }
......
...@@ -159,6 +159,7 @@ Configuration::Configuration() ...@@ -159,6 +159,7 @@ Configuration::Configuration()
_initialStart = false; _initialStart = false;
_daemonMode = false; _daemonMode = false;
m_config_retriever= 0; m_config_retriever= 0;
m_clusterConfig= 0;
} }
Configuration::~Configuration(){ Configuration::~Configuration(){
......
...@@ -145,27 +145,29 @@ NdbConnection::init() ...@@ -145,27 +145,29 @@ NdbConnection::init()
}//NdbConnection::init() }//NdbConnection::init()
/***************************************************************************** /*****************************************************************************
setOperationErrorCode(int anErrorCode); setOperationErrorCode(int error);
Remark: Sets an error code on the connection object from an Remark: Sets an error code on the connection object from an
operation object. operation object.
*****************************************************************************/ *****************************************************************************/
void void
NdbConnection::setOperationErrorCode(int anErrorCode) NdbConnection::setOperationErrorCode(int error)
{ {
if (theError.code == 0) DBUG_ENTER("NdbConnection::setOperationErrorCode");
theError.code = anErrorCode; setErrorCode(error);
}//NdbConnection::setOperationErrorCode() DBUG_VOID_RETURN;
}
/***************************************************************************** /*****************************************************************************
setOperationErrorCodeAbort(int anErrorCode); setOperationErrorCodeAbort(int error);
Remark: Sets an error code on the connection object from an Remark: Sets an error code on the connection object from an
operation object. operation object.
*****************************************************************************/ *****************************************************************************/
void void
NdbConnection::setOperationErrorCodeAbort(int anErrorCode) NdbConnection::setOperationErrorCodeAbort(int error)
{ {
DBUG_ENTER("NdbConnection::setOperationErrorCodeAbort");
if (theTransactionIsStarted == false) { if (theTransactionIsStarted == false) {
theCommitStatus = Aborted; theCommitStatus = Aborted;
} else if ((m_abortOption == AbortOnError) && } else if ((m_abortOption == AbortOnError) &&
...@@ -173,9 +175,9 @@ NdbConnection::setOperationErrorCodeAbort(int anErrorCode) ...@@ -173,9 +175,9 @@ NdbConnection::setOperationErrorCodeAbort(int anErrorCode)
(theCommitStatus != Aborted)) { (theCommitStatus != Aborted)) {
theCommitStatus = NeedAbort; theCommitStatus = NeedAbort;
}//if }//if
if (theError.code == 0) setErrorCode(error);
theError.code = anErrorCode; DBUG_VOID_RETURN;
}//NdbConnection::setOperationErrorCodeAbort() }
/***************************************************************************** /*****************************************************************************
setErrorCode(int anErrorCode); setErrorCode(int anErrorCode);
...@@ -183,10 +185,15 @@ setErrorCode(int anErrorCode); ...@@ -183,10 +185,15 @@ setErrorCode(int anErrorCode);
Remark: Sets an error indication on the connection object. Remark: Sets an error indication on the connection object.
*****************************************************************************/ *****************************************************************************/
void void
NdbConnection::setErrorCode(int anErrorCode) NdbConnection::setErrorCode(int error)
{ {
DBUG_ENTER("NdbConnection::setErrorCode");
DBUG_PRINT("enter", ("error: %d, theError.code: %d", error, theError.code));
if (theError.code == 0) if (theError.code == 0)
theError.code = anErrorCode; theError.code = error;
DBUG_VOID_RETURN;
}//NdbConnection::setErrorCode() }//NdbConnection::setErrorCode()
int int
...@@ -262,8 +269,12 @@ NdbConnection::execute(ExecType aTypeOfExec, ...@@ -262,8 +269,12 @@ NdbConnection::execute(ExecType aTypeOfExec,
AbortOption abortOption, AbortOption abortOption,
int forceSend) int forceSend)
{ {
DBUG_ENTER("NdbConnection::execute");
DBUG_PRINT("enter", ("aTypeOfExec: %d, abortOption: %d",
aTypeOfExec, abortOption));
if (! theBlobFlag) if (! theBlobFlag)
return executeNoBlobs(aTypeOfExec, abortOption, forceSend); DBUG_RETURN(executeNoBlobs(aTypeOfExec, abortOption, forceSend));
/* /*
* execute prepared ops in batches, as requested by blobs * execute prepared ops in batches, as requested by blobs
...@@ -346,7 +357,7 @@ NdbConnection::execute(ExecType aTypeOfExec, ...@@ -346,7 +357,7 @@ NdbConnection::execute(ExecType aTypeOfExec,
} }
} while (theFirstOpInList != NULL || tExecType != aTypeOfExec); } while (theFirstOpInList != NULL || tExecType != aTypeOfExec);
return ret; DBUG_RETURN(ret);
} }
int int
...@@ -354,6 +365,10 @@ NdbConnection::executeNoBlobs(ExecType aTypeOfExec, ...@@ -354,6 +365,10 @@ NdbConnection::executeNoBlobs(ExecType aTypeOfExec,
AbortOption abortOption, AbortOption abortOption,
int forceSend) int forceSend)
{ {
DBUG_ENTER("NdbConnection::executeNoBlobs");
DBUG_PRINT("enter", ("aTypeOfExec: %d, abortOption: %d",
aTypeOfExec, abortOption));
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// We will start by preparing all operations in the transaction defined // We will start by preparing all operations in the transaction defined
// since last execute or since beginning. If this works ok we will continue // since last execute or since beginning. If this works ok we will continue
...@@ -376,7 +391,7 @@ NdbConnection::executeNoBlobs(ExecType aTypeOfExec, ...@@ -376,7 +391,7 @@ NdbConnection::executeNoBlobs(ExecType aTypeOfExec,
*/ */
ndbout << "This timeout should never occur, execute(..)" << endl; ndbout << "This timeout should never occur, execute(..)" << endl;
setOperationErrorCodeAbort(4012); // Error code for "Cluster Failure" setOperationErrorCodeAbort(4012); // Error code for "Cluster Failure"
return -1; DBUG_RETURN(-1);
}//if }//if
/* /*
...@@ -400,13 +415,13 @@ NdbConnection::executeNoBlobs(ExecType aTypeOfExec, ...@@ -400,13 +415,13 @@ NdbConnection::executeNoBlobs(ExecType aTypeOfExec,
} }
#endif #endif
if (theReturnStatus == ReturnFailure) { if (theReturnStatus == ReturnFailure) {
return -1; DBUG_RETURN(-1);
}//if }//if
break; break;
} }
} }
thePendingBlobOps = 0; thePendingBlobOps = 0;
return 0; DBUG_RETURN(0);
}//NdbConnection::execute() }//NdbConnection::execute()
/***************************************************************************** /*****************************************************************************
...@@ -430,9 +445,15 @@ NdbConnection::executeAsynchPrepare( ExecType aTypeOfExec, ...@@ -430,9 +445,15 @@ NdbConnection::executeAsynchPrepare( ExecType aTypeOfExec,
void* anyObject, void* anyObject,
AbortOption abortOption) AbortOption abortOption)
{ {
DBUG_ENTER("NdbConnection::executeAsynchPrepare");
DBUG_PRINT("enter", ("aTypeOfExec: %d, aCallback: %x, anyObject: %x",
aTypeOfExec, aCallback, anyObject));
/** /**
* Reset error.code on execute * Reset error.code on execute
*/ */
if (theError.code != 0)
DBUG_PRINT("enter", ("Resetting error %d on execute", theError.code));
theError.code = 0; theError.code = 0;
NdbScanOperation* tcOp = m_theFirstScanOperation; NdbScanOperation* tcOp = m_theFirstScanOperation;
if (tcOp != 0){ if (tcOp != 0){
...@@ -441,7 +462,7 @@ NdbConnection::executeAsynchPrepare( ExecType aTypeOfExec, ...@@ -441,7 +462,7 @@ NdbConnection::executeAsynchPrepare( ExecType aTypeOfExec,
int tReturnCode; int tReturnCode;
tReturnCode = tcOp->executeCursor(theDBnode); tReturnCode = tcOp->executeCursor(theDBnode);
if (tReturnCode == -1) { if (tReturnCode == -1) {
return; DBUG_VOID_RETURN;
}//if }//if
tcOp = (NdbScanOperation*)tcOp->next(); tcOp = (NdbScanOperation*)tcOp->next();
} // while } // while
...@@ -463,17 +484,6 @@ NdbConnection::executeAsynchPrepare( ExecType aTypeOfExec, ...@@ -463,17 +484,6 @@ NdbConnection::executeAsynchPrepare( ExecType aTypeOfExec,
theCallbackFunction = aCallback; theCallbackFunction = aCallback;
theCallbackObject = anyObject; theCallbackObject = anyObject;
m_abortOption = abortOption; m_abortOption = abortOption;
// SendStatusType tSendStatus = theSendStatus;
// if (tSendStatus != InitState) {
/****************************************************************************
* The application is obviously doing strange things. We should probably
* report to the application the problem in some manner. Since we don't have
* a good way of handling the problem we avoid discovering the problem.
* Should be handled at some point in time.
****************************************************************************/
// return;
// }
m_waitForReply = true; m_waitForReply = true;
tNdb->thePreparedTransactionsArray[tnoOfPreparedTransactions] = this; tNdb->thePreparedTransactionsArray[tnoOfPreparedTransactions] = this;
theTransArrayIndex = tnoOfPreparedTransactions; theTransArrayIndex = tnoOfPreparedTransactions;
...@@ -502,7 +512,11 @@ NdbConnection::executeAsynchPrepare( ExecType aTypeOfExec, ...@@ -502,7 +512,11 @@ NdbConnection::executeAsynchPrepare( ExecType aTypeOfExec,
} else { } else {
theSendStatus = sendABORTfail; theSendStatus = sendABORTfail;
}//if }//if
return; if (theCommitStatus == Aborted){
DBUG_PRINT("exit", ("theCommitStatus: Aborted"));
setErrorCode(4350);
}
DBUG_VOID_RETURN;
}//if }//if
if (tTransactionIsStarted == true) { if (tTransactionIsStarted == true) {
if (tLastOp != NULL) { if (tLastOp != NULL) {
...@@ -520,7 +534,7 @@ NdbConnection::executeAsynchPrepare( ExecType aTypeOfExec, ...@@ -520,7 +534,7 @@ NdbConnection::executeAsynchPrepare( ExecType aTypeOfExec,
* We will use the commit method. * We will use the commit method.
*********************************************************************/ *********************************************************************/
theSendStatus = sendCOMMITstate; theSendStatus = sendCOMMITstate;
return; DBUG_VOID_RETURN;
} else { } else {
/********************************************************************** /**********************************************************************
* We need to put it into the array of completed transactions to * We need to put it into the array of completed transactions to
...@@ -532,7 +546,7 @@ NdbConnection::executeAsynchPrepare( ExecType aTypeOfExec, ...@@ -532,7 +546,7 @@ NdbConnection::executeAsynchPrepare( ExecType aTypeOfExec,
* put it into the completed array. * put it into the completed array.
**********************************************************************/ **********************************************************************/
theSendStatus = sendCompleted; theSendStatus = sendCompleted;
return; // No Commit with no operations is OK DBUG_VOID_RETURN; // No Commit with no operations is OK
}//if }//if
}//if }//if
} else if (tTransactionIsStarted == false) { } else if (tTransactionIsStarted == false) {
...@@ -560,7 +574,7 @@ NdbConnection::executeAsynchPrepare( ExecType aTypeOfExec, ...@@ -560,7 +574,7 @@ NdbConnection::executeAsynchPrepare( ExecType aTypeOfExec,
* will put it into the completed array. * will put it into the completed array.
***********************************************************************/ ***********************************************************************/
theSendStatus = sendCompleted; theSendStatus = sendCompleted;
return; DBUG_VOID_RETURN;
}//if }//if
} }
...@@ -573,7 +587,7 @@ NdbConnection::executeAsynchPrepare( ExecType aTypeOfExec, ...@@ -573,7 +587,7 @@ NdbConnection::executeAsynchPrepare( ExecType aTypeOfExec,
tReturnCode = tOp->prepareSend(theTCConPtr, theTransactionId); tReturnCode = tOp->prepareSend(theTCConPtr, theTransactionId);
if (tReturnCode == -1) { if (tReturnCode == -1) {
theSendStatus = sendABORTfail; theSendStatus = sendABORTfail;
return; DBUG_VOID_RETURN;
}//if }//if
/************************************************************************* /*************************************************************************
...@@ -596,7 +610,7 @@ NdbConnection::executeAsynchPrepare( ExecType aTypeOfExec, ...@@ -596,7 +610,7 @@ NdbConnection::executeAsynchPrepare( ExecType aTypeOfExec,
theNoOfOpSent = 0; theNoOfOpSent = 0;
theNoOfOpCompleted = 0; theNoOfOpCompleted = 0;
theSendStatus = sendOperations; theSendStatus = sendOperations;
return; DBUG_VOID_RETURN;
}//NdbConnection::executeAsynchPrepare() }//NdbConnection::executeAsynchPrepare()
void NdbConnection::close() void NdbConnection::close()
...@@ -665,6 +679,8 @@ Remark: Send all operations belonging to this connection. ...@@ -665,6 +679,8 @@ Remark: Send all operations belonging to this connection.
int int
NdbConnection::doSend() NdbConnection::doSend()
{ {
DBUG_ENTER("NdbConnection::doSend");
/* /*
This method assumes that at least one operation have been defined. This This method assumes that at least one operation have been defined. This
is ensured by the caller of this routine (=execute). is ensured by the caller of this routine (=execute).
...@@ -687,7 +703,7 @@ NdbConnection::doSend() ...@@ -687,7 +703,7 @@ NdbConnection::doSend()
theSendStatus = sendTC_OP; theSendStatus = sendTC_OP;
theTransactionIsStarted = true; theTransactionIsStarted = true;
tNdb->insert_sent_list(this); tNdb->insert_sent_list(this);
return 0; DBUG_RETURN(0);
}//case }//case
case sendABORT: case sendABORT:
case sendABORTfail:{ case sendABORTfail:{
...@@ -699,18 +715,18 @@ NdbConnection::doSend() ...@@ -699,18 +715,18 @@ NdbConnection::doSend()
theReturnStatus = ReturnFailure; theReturnStatus = ReturnFailure;
}//if }//if
if (sendROLLBACK() == 0) { if (sendROLLBACK() == 0) {
return 0; DBUG_RETURN(0);
}//if }//if
break; break;
}//case }//case
case sendCOMMITstate: case sendCOMMITstate:
if (sendCOMMIT() == 0) { if (sendCOMMIT() == 0) {
return 0; DBUG_RETURN(0);
}//if }//if
break; break;
case sendCompleted: case sendCompleted:
theNdb->insert_completed_list(this); theNdb->insert_completed_list(this);
return 0; DBUG_RETURN(0);
default: default:
ndbout << "Inconsistent theSendStatus = " << theSendStatus << endl; ndbout << "Inconsistent theSendStatus = " << theSendStatus << endl;
abort(); abort();
...@@ -720,7 +736,7 @@ NdbConnection::doSend() ...@@ -720,7 +736,7 @@ NdbConnection::doSend()
theReleaseOnClose = true; theReleaseOnClose = true;
theTransactionIsStarted = false; theTransactionIsStarted = false;
theCommitStatus = Aborted; theCommitStatus = Aborted;
return -1; DBUG_RETURN(-1);
}//NdbConnection::doSend() }//NdbConnection::doSend()
/************************************************************************** /**************************************************************************
......
...@@ -29,24 +29,31 @@ ...@@ -29,24 +29,31 @@
void void
Ndb::checkFailedNode() Ndb::checkFailedNode()
{ {
for (NodeId i = 0; i < theNoOfDBnodes; i ++){ DBUG_ENTER("Ndb::checkFailedNode");
DBUG_PRINT("enter", ("theNoOfDBnodes: %d", theNoOfDBnodes));
DBUG_ASSERT(theNoOfDBnodes < MAX_NDB_NODES);
for (int i = 0; i < theNoOfDBnodes; i++){
const NodeId node_id = theDBnodes[i]; const NodeId node_id = theDBnodes[i];
DBUG_PRINT("info", ("i: %d, node_id: %d", i, node_id));
NdbConnection * tNdbCon = theConnectionArray[node_id]; DBUG_ASSERT(node_id < MAX_NDB_NODES);
if (the_release_ind[node_id] == 1){ if (the_release_ind[node_id] == 1){
/** /**
* Release all connections in idle list (for node) * Release all connections in idle list (for node)
*/ */
NdbConnection * tNdbCon = theConnectionArray[node_id];
theConnectionArray[node_id] = NULL; theConnectionArray[node_id] = NULL;
while (tNdbCon != NULL) { while (tNdbCon != NULL) {
NdbConnection* tempNdbCon = tNdbCon; NdbConnection* tempNdbCon = tNdbCon;
tNdbCon = tNdbCon->next(); tNdbCon = tNdbCon->next();
releaseNdbCon(tempNdbCon); releaseNdbCon(tempNdbCon);
}//while }
the_release_ind[node_id] = 0; the_release_ind[node_id] = 0;
}//if }
}//for }
DBUG_VOID_RETURN;
} }
#if 0 #if 0
......
...@@ -228,6 +228,7 @@ ErrorBundle ErrorCodes[] = { ...@@ -228,6 +228,7 @@ ErrorBundle ErrorCodes[] = {
{ 4347, IE, "Bad state at alter index" }, { 4347, IE, "Bad state at alter index" },
{ 4348, IE, "Inconsistency detected at alter index" }, { 4348, IE, "Inconsistency detected at alter index" },
{ 4349, IE, "Inconsistency detected at index usage" }, { 4349, IE, "Inconsistency detected at index usage" },
{ 4350, IE, "Transaction already aborted" },
/** /**
* Application error * Application error
......
...@@ -30,7 +30,7 @@ testSystemRestart \ ...@@ -30,7 +30,7 @@ testSystemRestart \
testTimeout \ testTimeout \
testTransactions \ testTransactions \
testDeadlock \ testDeadlock \
test_event ndbapi_slow_select testReadPerf test_event ndbapi_slow_select testReadPerf testLcp
#flexTimedAsynch #flexTimedAsynch
#testBlobs #testBlobs
...@@ -68,6 +68,7 @@ testDeadlock_SOURCES = testDeadlock.cpp ...@@ -68,6 +68,7 @@ testDeadlock_SOURCES = testDeadlock.cpp
test_event_SOURCES = test_event.cpp test_event_SOURCES = test_event.cpp
ndbapi_slow_select_SOURCES = slow_select.cpp ndbapi_slow_select_SOURCES = slow_select.cpp
testReadPerf_SOURCES = testReadPerf.cpp testReadPerf_SOURCES = testReadPerf.cpp
testLcp_SOURCES = testLcp.cpp
INCLUDES_LOC = -I$(top_srcdir)/ndb/include/kernel INCLUDES_LOC = -I$(top_srcdir)/ndb/include/kernel
......
...@@ -2097,47 +2097,50 @@ int Bank::increaseSystemValue(SystemValueId sysValId, Uint64 &value){ ...@@ -2097,47 +2097,50 @@ int Bank::increaseSystemValue(SystemValueId sysValId, Uint64 &value){
* *
*/ */
DBUG_ENTER("Bank::increaseSystemValue");
int check; int check;
NdbConnection* pTrans = m_ndb.startTransaction(); NdbConnection* pTrans = m_ndb.startTransaction();
if (pTrans == NULL){ if (pTrans == NULL){
ERR(m_ndb.getNdbError()); ERR(m_ndb.getNdbError());
return NDBT_FAILED; DBUG_RETURN(NDBT_FAILED);
} }
NdbOperation* pOp = pTrans->getNdbOperation("SYSTEM_VALUES"); NdbOperation* pOp = pTrans->getNdbOperation("SYSTEM_VALUES");
if (pOp == NULL) { if (pOp == NULL) {
ERR(pTrans->getNdbError()); ERR(pTrans->getNdbError());
m_ndb.closeTransaction(pTrans); m_ndb.closeTransaction(pTrans);
return NDBT_FAILED; DBUG_RETURN(NDBT_FAILED);
} }
check = pOp->readTupleExclusive(); check = pOp->readTupleExclusive();
// check = pOp->readTuple();
if( check == -1 ) { if( check == -1 ) {
ERR(pTrans->getNdbError()); ERR(pTrans->getNdbError());
m_ndb.closeTransaction(pTrans); m_ndb.closeTransaction(pTrans);
return NDBT_FAILED; DBUG_RETURN(NDBT_FAILED);
} }
check = pOp->equal("SYSTEM_VALUES_ID", sysValId); check = pOp->equal("SYSTEM_VALUES_ID", sysValId);
if( check == -1 ) { if( check == -1 ) {
ERR(pTrans->getNdbError()); ERR(pTrans->getNdbError());
m_ndb.closeTransaction(pTrans); m_ndb.closeTransaction(pTrans);
return NDBT_FAILED; DBUG_RETURN(NDBT_FAILED);
} }
NdbRecAttr* valueRec = pOp->getValue("VALUE"); NdbRecAttr* valueRec = pOp->getValue("VALUE");
if( valueRec ==NULL ) { if( valueRec ==NULL ) {
ERR(pTrans->getNdbError()); ERR(pTrans->getNdbError());
m_ndb.closeTransaction(pTrans); m_ndb.closeTransaction(pTrans);
return NDBT_FAILED; DBUG_RETURN(NDBT_FAILED);
} }
check = pTrans->execute(NoCommit); check = pTrans->execute(NoCommit);
if( check == -1 ) { if( check == -1 ) {
ERR(pTrans->getNdbError()); ERR(pTrans->getNdbError());
m_ndb.closeTransaction(pTrans); m_ndb.closeTransaction(pTrans);
return NDBT_FAILED; DBUG_RETURN(NDBT_FAILED);
} }
value = valueRec->u_64_value(); value = valueRec->u_64_value();
...@@ -2147,49 +2150,56 @@ int Bank::increaseSystemValue(SystemValueId sysValId, Uint64 &value){ ...@@ -2147,49 +2150,56 @@ int Bank::increaseSystemValue(SystemValueId sysValId, Uint64 &value){
if (pOp2 == NULL) { if (pOp2 == NULL) {
ERR(pTrans->getNdbError()); ERR(pTrans->getNdbError());
m_ndb.closeTransaction(pTrans); m_ndb.closeTransaction(pTrans);
return NDBT_FAILED; DBUG_RETURN(NDBT_FAILED);
} }
check = pOp2->updateTuple(); check = pOp2->updateTuple();
if( check == -1 ) { if( check == -1 ) {
ERR(pTrans->getNdbError()); ERR(pTrans->getNdbError());
m_ndb.closeTransaction(pTrans); m_ndb.closeTransaction(pTrans);
return NDBT_FAILED; DBUG_RETURN(NDBT_FAILED);
} }
check = pOp2->equal("SYSTEM_VALUES_ID", sysValId); check = pOp2->equal("SYSTEM_VALUES_ID", sysValId);
if( check == -1 ) { if( check == -1 ) {
ERR(pTrans->getNdbError()); ERR(pTrans->getNdbError());
m_ndb.closeTransaction(pTrans); m_ndb.closeTransaction(pTrans);
return NDBT_FAILED; DBUG_RETURN(NDBT_FAILED);
} }
check = pOp2->setValue("VALUE", value); check = pOp2->setValue("VALUE", value);
if( check == -1 ) { if( check == -1 ) {
ERR(pTrans->getNdbError()); ERR(pTrans->getNdbError());
m_ndb.closeTransaction(pTrans); m_ndb.closeTransaction(pTrans);
return NDBT_FAILED; DBUG_RETURN(NDBT_FAILED);
}
check = pTrans->execute(NoCommit);
if( check == -1 ) {
ERR(pTrans->getNdbError());
m_ndb.closeTransaction(pTrans);
DBUG_RETURN(NDBT_FAILED);
} }
NdbOperation* pOp3 = pTrans->getNdbOperation("SYSTEM_VALUES"); NdbOperation* pOp3 = pTrans->getNdbOperation("SYSTEM_VALUES");
if (pOp3 == NULL) { if (pOp3 == NULL) {
ERR(pTrans->getNdbError()); ERR(pTrans->getNdbError());
m_ndb.closeTransaction(pTrans); m_ndb.closeTransaction(pTrans);
return NDBT_FAILED; DBUG_RETURN(NDBT_FAILED);
} }
check = pOp3->readTuple(); check = pOp3->readTuple();
if( check == -1 ) { if( check == -1 ) {
ERR(pTrans->getNdbError()); ERR(pTrans->getNdbError());
m_ndb.closeTransaction(pTrans); m_ndb.closeTransaction(pTrans);
return NDBT_FAILED; DBUG_RETURN(NDBT_FAILED);
} }
check = pOp3->equal("SYSTEM_VALUES_ID", sysValId); check = pOp3->equal("SYSTEM_VALUES_ID", sysValId);
if( check == -1 ) { if( check == -1 ) {
ERR(pTrans->getNdbError()); ERR(pTrans->getNdbError());
m_ndb.closeTransaction(pTrans); m_ndb.closeTransaction(pTrans);
return NDBT_FAILED; DBUG_RETURN(NDBT_FAILED);
} }
// Read new value // Read new value
...@@ -2197,28 +2207,31 @@ int Bank::increaseSystemValue(SystemValueId sysValId, Uint64 &value){ ...@@ -2197,28 +2207,31 @@ int Bank::increaseSystemValue(SystemValueId sysValId, Uint64 &value){
if( valueNewRec ==NULL ) { if( valueNewRec ==NULL ) {
ERR(pTrans->getNdbError()); ERR(pTrans->getNdbError());
m_ndb.closeTransaction(pTrans); m_ndb.closeTransaction(pTrans);
return NDBT_FAILED; DBUG_RETURN(NDBT_FAILED);
} }
check = pTrans->execute(Commit); check = pTrans->execute(Commit);
if( check == -1 ) { if( check == -1 ) {
ERR(pTrans->getNdbError()); ERR(pTrans->getNdbError());
m_ndb.closeTransaction(pTrans); m_ndb.closeTransaction(pTrans);
return NDBT_FAILED; DBUG_RETURN(NDBT_FAILED);
} }
// Check that value updated equals the value we read after the update // Check that value updated equals the value we read after the update
if (valueNewRec->u_64_value() != value){ if (valueNewRec->u_64_value() != value){
printf("value actual=%lld\n", valueNewRec->u_64_value());
printf("value expected=%lld actual=%lld\n", value, valueNewRec->u_64_value());
DBUG_PRINT("info", ("value expected=%ld actual=%ld", value, valueNewRec->u_64_value()));
g_err << "getNextTransactionId: value was not updated" << endl; g_err << "getNextTransactionId: value was not updated" << endl;
m_ndb.closeTransaction(pTrans); m_ndb.closeTransaction(pTrans);
return NDBT_FAILED; DBUG_RETURN(NDBT_FAILED);
} }
m_ndb.closeTransaction(pTrans); m_ndb.closeTransaction(pTrans);
return 0;
DBUG_RETURN(0);
} }
int Bank::increaseSystemValue2(SystemValueId sysValId, Uint64 &value){ int Bank::increaseSystemValue2(SystemValueId sysValId, Uint64 &value){
......
#include <NDBT.hpp>
#include <NdbApi.hpp>
#include <NdbRestarter.hpp>
#include <HugoOperations.hpp>
#include <UtilTransactions.hpp>
#include <signaldata/DumpStateOrd.hpp>
struct CASE
{
bool start_row;
bool end_row;
bool curr_row;
const char * op1;
const char * op2;
int val;
};
static CASE g_ops[] =
{
{ false, true, false, "INSERT", 0, 0 },
{ false, true, false, "INSERT", "UPDATE", 0 },
{ false, false, false, "INSERT", "DELETE", 0 },
{ true, true, false, "UPDATE", 0, 0 },
{ true, true, false, "UPDATE", "UPDATE", 0 },
{ true, false, false, "UPDATE", "DELETE", 0 },
{ true, false, false, "DELETE", 0, 0 },
{ true, true, false, "DELETE", "INSERT", 0 }
};
const size_t OP_COUNT = (sizeof(g_ops)/sizeof(g_ops[0]));
static Ndb* g_ndb = 0;
static CASE* g_cases;
static HugoOperations* g_hugo_ops;
static int g_rows = 1000;
static int g_setup_tables = 1;
static const char * g_tablename = "T1";
static const NdbDictionary::Table* g_table = 0;
static NdbRestarter g_restarter;
static int init_ndb(int argc, char** argv);
static int parse_args(int argc, char** argv);
static int connect_ndb();
static int drop_all_tables();
static int load_table();
static int pause_lcp();
static int do_op(int row);
static int continue_lcp(int error);
static int commit();
static int restart();
static int validate();
#define require(x) { bool b = x; if(!b){g_err << __LINE__ << endl; abort();}}
int
main(int argc, char ** argv){
require(!init_ndb(argc, argv));
require(!parse_args(argc, argv));
require(!connect_ndb());
if(g_setup_tables){
require(!drop_all_tables());
if(NDBT_Tables::createTable(g_ndb, g_tablename) != 0){
exit(-1);
}
}
g_table = g_ndb->getDictionary()->getTable(g_tablename);
if(g_table == 0){
g_err << "Failed to retreive table: " << g_tablename << endl;
exit(-1);
}
require(g_hugo_ops = new HugoOperations(* g_table));
require(!g_hugo_ops->startTransaction(g_ndb));
g_cases= new CASE[g_rows];
require(!load_table());
g_info << "Performing all ops wo/ inteference of LCP" << endl;
g_info << "Testing pre LCP operations, ZLCP_OP_WRITE_RT_BREAK" << endl;
g_info << " where ZLCP_OP_WRITE_RT_BREAK is finished before SAVE_PAGES"
<< endl;
require(!pause_lcp());
for(size_t j = 0; j<g_rows; j++){
require(!do_op(j));
}
require(!continue_lcp(5900));
require(!commit());
require(!restart());
require(!validate());
g_info << "Testing pre LCP operations, ZLCP_OP_WRITE_RT_BREAK" << endl;
g_info << " where ZLCP_OP_WRITE_RT_BREAK is finished after SAVE_PAGES"
<< endl;
require(!load_table());
require(!pause_lcp());
for(size_t j = 0; j<g_rows; j++){
require(!do_op(j));
}
require(!continue_lcp(5901));
require(!commit());
require(!restart());
require(!validate());
g_info << "Testing pre LCP operations, undo-ed at commit" << endl;
require(!load_table());
require(!pause_lcp());
for(size_t j = 0; j<g_rows; j++){
require(!do_op(j));
}
require(!continue_lcp(5902));
require(!commit());
require(!continue_lcp(5903));
require(!restart());
require(!validate());
}
static int init_ndb(int argc, char** argv)
{
return 0;
}
static int parse_args(int argc, char** argv)
{
return 0;
}
static int connect_ndb()
{
g_ndb = new Ndb("TEST_DB");
g_ndb->init();
if(g_ndb->waitUntilReady(30) == 0){
int args[] = { DumpStateOrd::DihMaxTimeBetweenLCP };
return g_restarter.dumpStateAllNodes(args, 1);
}
return -1;
}
static int disconnect_ndb()
{
delete g_ndb;
g_ndb = 0;
g_table = 0;
return 0;
}
static int drop_all_tables()
{
NdbDictionary::Dictionary * dict = g_ndb->getDictionary();
require(dict);
BaseString db = g_ndb->getDatabaseName();
BaseString schema = g_ndb->getSchemaName();
NdbDictionary::Dictionary::List list;
if (dict->listObjects(list, NdbDictionary::Object::TypeUndefined) == -1){
g_err << "Failed to list tables: " << endl
<< dict->getNdbError() << endl;
return -1;
}
for (unsigned i = 0; i < list.count; i++) {
NdbDictionary::Dictionary::List::Element& elt = list.elements[i];
switch (elt.type) {
case NdbDictionary::Object::SystemTable:
case NdbDictionary::Object::UserTable:
g_ndb->setDatabaseName(elt.database);
g_ndb->setSchemaName(elt.schema);
if(dict->dropTable(elt.name) != 0){
g_err << "Failed to drop table: "
<< elt.database << "/" << elt.schema << "/" << elt.name <<endl;
g_err << dict->getNdbError() << endl;
return -1;
}
break;
case NdbDictionary::Object::UniqueHashIndex:
case NdbDictionary::Object::OrderedIndex:
case NdbDictionary::Object::HashIndexTrigger:
case NdbDictionary::Object::IndexTrigger:
case NdbDictionary::Object::SubscriptionTrigger:
case NdbDictionary::Object::ReadOnlyConstraint:
default:
break;
}
}
g_ndb->setDatabaseName(db.c_str());
g_ndb->setSchemaName(schema.c_str());
return 0;
}
static int load_table()
{
UtilTransactions clear(* g_table);
require(!clear.clearTable(g_ndb));
HugoOperations ops(* g_table);
require(!ops.startTransaction(g_ndb));
for(size_t i = 0; i<g_rows; i++){
g_cases[i] = g_ops[ i % OP_COUNT];
if(g_cases[i].start_row){
g_cases[i].curr_row = true;
g_cases[i].val = rand();
require(!ops.pkInsertRecord(g_ndb, i, 1, g_cases[i].val));
}
if((i+1) % 100 == 0){
require(!ops.execute_Commit(g_ndb));
require(!ops.getTransaction()->restart());
}
}
if((g_rows+1) % 100 != 0)
require(!ops.execute_Commit(g_ndb));
return 0;
}
static int pause_lcp()
{
return 0;
}
static int do_op(int row)
{
HugoOperations & ops = * g_hugo_ops;
if(strcmp(g_cases[row].op1, "INSERT") == 0){
require(!g_cases[row].curr_row);
g_cases[row].curr_row = true;
g_cases[row].val = rand();
require(!ops.pkInsertRecord(g_ndb, row, 1, g_cases[row].val));
} else if(strcmp(g_cases[row].op1, "UPDATE") == 0){
require(g_cases[row].curr_row);
g_cases[row].val = rand();
require(!ops.pkUpdateRecord(g_ndb, row, 1, g_cases[row].val));
} else if(strcmp(g_cases[row].op1, "DELETE") == 0){
require(g_cases[row].curr_row);
g_cases[row].curr_row = false;
require(!ops.pkDeleteRecord(g_ndb, row, 1));
}
require(!ops.execute_NoCommit(g_ndb));
if(g_cases[row].op2 == 0){
} else if(strcmp(g_cases[row].op2, "INSERT") == 0){
require(!g_cases[row].curr_row);
g_cases[row].curr_row = true;
g_cases[row].val = rand();
require(!ops.pkInsertRecord(g_ndb, row, 1, g_cases[row].val));
} else if(strcmp(g_cases[row].op2, "UPDATE") == 0){
require(g_cases[row].curr_row);
g_cases[row].val = rand();
require(!ops.pkUpdateRecord(g_ndb, row, 1, g_cases[row].val));
} else if(strcmp(g_cases[row].op2, "DELETE") == 0){
require(g_cases[row].curr_row);
g_cases[row].curr_row = false;
require(!ops.pkDeleteRecord(g_ndb, row, 1));
}
if(g_cases[row].op2 != 0)
require(!ops.execute_NoCommit(g_ndb));
return 0;
}
static int continue_lcp(int error)
{
error = 0;
if(g_restarter.insertErrorInAllNodes(error) == 0){
int args[] = { DumpStateOrd::DihStartLcpImmediately };
return g_restarter.dumpStateAllNodes(args, 1);
}
return -1;
}
static int commit()
{
HugoOperations & ops = * g_hugo_ops;
int res = ops.execute_Commit(g_ndb);
if(res == 0){
return ops.getTransaction()->restart();
}
return res;
}
static int restart()
{
g_info << "Restarting cluster" << endl;
disconnect_ndb();
delete g_hugo_ops;
require(!g_restarter.restartAll());
require(!g_restarter.waitClusterStarted(30));
require(!connect_ndb());
g_table = g_ndb->getDictionary()->getTable(g_tablename);
require(g_table);
require(g_hugo_ops = new HugoOperations(* g_table));
require(!g_hugo_ops->startTransaction(g_ndb));
return 0;
}
static int validate()
{
HugoOperations ops(* g_table);
for(size_t i = 0; i<g_rows; i++){
require(g_cases[i].curr_row == g_cases[i].end_row);
require(!ops.startTransaction(g_ndb));
ops.pkReadRecord(g_ndb, i, 1);
int res = ops.execute_Commit(g_ndb);
if(g_cases[i].curr_row){
require(res == 0 && ops.verifyUpdatesValue(g_cases[i].val) == 0);
} else {
require(res == 626);
}
ops.closeTransaction(g_ndb);
}
return 0;
}
...@@ -859,6 +859,11 @@ void NDBT_TestSuite::execute(Ndb* ndb, const NdbDictionary::Table* pTab, ...@@ -859,6 +859,11 @@ void NDBT_TestSuite::execute(Ndb* ndb, const NdbDictionary::Table* pTab,
else else
numTestsOk++; numTestsOk++;
numTestsExecuted++; numTestsExecuted++;
if (result == NDBT_OK && createTable == true){
pDict->dropTable(pTab->getName());
}
delete ctx; delete ctx;
} }
} }
......
...@@ -2239,6 +2239,32 @@ static void mysql_close_free(MYSQL *mysql) ...@@ -2239,6 +2239,32 @@ static void mysql_close_free(MYSQL *mysql)
} }
/*
Clear connection pointer of every statement: this is necessary
to give error on attempt to use a prepared statement of closed
connection.
SYNOPSYS
mysql_detach_stmt_list()
stmt_list pointer to mysql->stmts
*/
void mysql_detach_stmt_list(LIST **stmt_list)
{
#ifdef MYSQL_CLIENT
/* Reset connection handle in all prepared statements. */
LIST *element= *stmt_list;
for (; element; element= element->next)
{
MYSQL_STMT *stmt= (MYSQL_STMT *) element->data;
stmt->mysql= 0;
/* No need to call list_delete for statement here */
}
*stmt_list= 0;
#endif /* MYSQL_CLIENT */
}
void STDCALL mysql_close(MYSQL *mysql) void STDCALL mysql_close(MYSQL *mysql)
{ {
DBUG_ENTER("mysql_close"); DBUG_ENTER("mysql_close");
...@@ -2255,20 +2281,7 @@ void STDCALL mysql_close(MYSQL *mysql) ...@@ -2255,20 +2281,7 @@ void STDCALL mysql_close(MYSQL *mysql)
} }
mysql_close_free_options(mysql); mysql_close_free_options(mysql);
mysql_close_free(mysql); mysql_close_free(mysql);
#ifdef MYSQL_CLIENT mysql_detach_stmt_list(&mysql->stmts);
if (mysql->stmts)
{
/* Reset connection handle in all prepared statements. */
LIST *element;
for (element= mysql->stmts; element; element= element->next)
{
MYSQL_STMT *stmt= (MYSQL_STMT *) element->data;
stmt->mysql= 0;
/* No need to call list_delete for statement here */
}
mysql->stmts= 0;
}
#endif /*MYSQL_CLIENT*/
#ifndef TO_BE_DELETED #ifndef TO_BE_DELETED
/* free/close slave list */ /* free/close slave list */
if (mysql->rpl_pivot) if (mysql->rpl_pivot)
......
...@@ -70,7 +70,6 @@ ...@@ -70,7 +70,6 @@
Allow users to set compression level. Allow users to set compression level.
Add truncate table command. Add truncate table command.
Implement versioning, should be easy. Implement versioning, should be easy.
Implement optimize so we can fix broken tables.
Allow for errors, find a way to mark bad rows. Allow for errors, find a way to mark bad rows.
See if during an optimize you can make the table smaller. See if during an optimize you can make the table smaller.
Talk to the gzip guys, come up with a writable format so that updates are doable Talk to the gzip guys, come up with a writable format so that updates are doable
...@@ -88,6 +87,7 @@ static int archive_init= 0; ...@@ -88,6 +87,7 @@ static int archive_init= 0;
/* The file extension */ /* The file extension */
#define ARZ ".ARZ" #define ARZ ".ARZ"
#define ARN ".ARN"
/* /*
Used for hash table that tracks open tables. Used for hash table that tracks open tables.
...@@ -117,7 +117,7 @@ static ARCHIVE_SHARE *get_share(const char *table_name, TABLE *table) ...@@ -117,7 +117,7 @@ static ARCHIVE_SHARE *get_share(const char *table_name, TABLE *table)
if (!archive_init) if (!archive_init)
{ {
VOID(pthread_mutex_init(&archive_mutex,MY_MUTEX_INIT_FAST)); VOID(pthread_mutex_init(&archive_mutex,MY_MUTEX_INIT_FAST));
if (!hash_init(&archive_open_tables,system_charset_info,32,0,0, if (hash_init(&archive_open_tables,system_charset_info,32,0,0,
(hash_get_key) archive_get_key,0,0)) (hash_get_key) archive_get_key,0,0))
{ {
pthread_mutex_unlock(&LOCK_mysql_create_db); pthread_mutex_unlock(&LOCK_mysql_create_db);
...@@ -205,7 +205,7 @@ static int free_share(ARCHIVE_SHARE *share) ...@@ -205,7 +205,7 @@ static int free_share(ARCHIVE_SHARE *share)
We just implement one additional file extension. We just implement one additional file extension.
*/ */
const char **ha_archive::bas_ext() const const char **ha_archive::bas_ext() const
{ static const char *ext[]= { ARZ, NullS }; return ext; } { static const char *ext[]= { ARZ, ARN, NullS }; return ext; }
/* /*
...@@ -322,6 +322,11 @@ int ha_archive::create(const char *name, TABLE *table_arg, ...@@ -322,6 +322,11 @@ int ha_archive::create(const char *name, TABLE *table_arg,
/* /*
Look at ha_archive::open() for an explanation of the row format. Look at ha_archive::open() for an explanation of the row format.
Here we just write out the row. Here we just write out the row.
Wondering about start_bulk_insert()? We don't implement it for
archive since it optimizes for lots of writes. The only save
for implementing start_bulk_insert() is that we could skip
setting dirty to true each time.
*/ */
int ha_archive::write_row(byte * buf) int ha_archive::write_row(byte * buf)
{ {
...@@ -380,17 +385,7 @@ int ha_archive::rnd_init(bool scan) ...@@ -380,17 +385,7 @@ int ha_archive::rnd_init(bool scan)
pthread_mutex_lock(&share->mutex); pthread_mutex_lock(&share->mutex);
if (share->dirty == TRUE) if (share->dirty == TRUE)
{ {
/* I was having problems with OSX, but it worked for 10.3 so I am wrapping this with and ifdef */
#ifdef BROKEN_GZFLUSH
gzclose(share->archive_write);
if ((share->archive_write= gzopen(share->data_file_name, "ab")) == NULL)
{
pthread_mutex_unlock(&share->mutex);
DBUG_RETURN(errno ? errno : -1);
}
#else
gzflush(share->archive_write, Z_SYNC_FLUSH); gzflush(share->archive_write, Z_SYNC_FLUSH);
#endif
share->dirty= FALSE; share->dirty= FALSE;
} }
pthread_mutex_unlock(&share->mutex); pthread_mutex_unlock(&share->mutex);
...@@ -504,6 +499,54 @@ int ha_archive::rnd_pos(byte * buf, byte *pos) ...@@ -504,6 +499,54 @@ int ha_archive::rnd_pos(byte * buf, byte *pos)
DBUG_RETURN(get_row(buf)); DBUG_RETURN(get_row(buf));
} }
/*
The table can become fragmented if data was inserted, read, and then
inserted again. What we do is open up the file and recompress it completely.
*/
int ha_archive::optimize(THD* thd, HA_CHECK_OPT* check_opt)
{
DBUG_ENTER("ha_archive::optimize");
int read; // Bytes read, gzread() returns int
gzFile reader, writer;
char block[IO_SIZE];
char writer_filename[FN_REFLEN];
/* Lets create a file to contain the new data */
fn_format(writer_filename,share->table_name,"",ARN, MY_REPLACE_EXT|MY_UNPACK_FILENAME);
/* Closing will cause all data waiting to be flushed, to be flushed */
gzclose(share->archive_write);
if ((reader= gzopen(share->data_file_name, "rb")) == NULL)
DBUG_RETURN(-1);
if ((writer= gzopen(writer_filename, "wb")) == NULL)
{
gzclose(reader);
DBUG_RETURN(-1);
}
while (read= gzread(reader, block, IO_SIZE))
gzwrite(writer, block, read);
gzclose(reader);
gzclose(writer);
my_rename(writer_filename,share->data_file_name,MYF(0));
/*
We reopen the file in case some IO is waiting to go through.
In theory the table is closed right after this operation,
but it is possible for IO to still happen.
I may be being a bit too paranoid right here.
*/
if ((share->archive_write= gzopen(share->data_file_name, "ab")) == NULL)
DBUG_RETURN(errno ? errno : -1);
share->dirty= FALSE;
DBUG_RETURN(0);
}
/****************************************************************************** /******************************************************************************
Everything below here is default, please look at ha_example.cc for Everything below here is default, please look at ha_example.cc for
......
...@@ -112,7 +112,7 @@ class ha_archive: public handler ...@@ -112,7 +112,7 @@ class ha_archive: public handler
int external_lock(THD *thd, int lock_type); int external_lock(THD *thd, int lock_type);
ha_rows records_in_range(uint inx, key_range *min_key, key_range *max_key); ha_rows records_in_range(uint inx, key_range *min_key, key_range *max_key);
int create(const char *name, TABLE *form, HA_CREATE_INFO *create_info); int create(const char *name, TABLE *form, HA_CREATE_INFO *create_info);
int optimize(THD* thd, HA_CHECK_OPT* check_opt);
THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to, THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to,
enum thr_lock_type lock_type); enum thr_lock_type lock_type);
}; };
...@@ -122,6 +122,8 @@ static const err_code_mapping err_map[]= ...@@ -122,6 +122,8 @@ static const err_code_mapping err_map[]=
{ 827, HA_ERR_RECORD_FILE_FULL }, { 827, HA_ERR_RECORD_FILE_FULL },
{ 832, HA_ERR_RECORD_FILE_FULL }, { 832, HA_ERR_RECORD_FILE_FULL },
{ 0, 1 },
{ -1, -1 } { -1, -1 }
}; };
...@@ -173,7 +175,7 @@ void ha_ndbcluster::records_update() ...@@ -173,7 +175,7 @@ void ha_ndbcluster::records_update()
DBUG_PRINT("info", ("id=%d, no_uncommitted_rows_count=%d", DBUG_PRINT("info", ("id=%d, no_uncommitted_rows_count=%d",
((const NDBTAB *)m_table)->getTableId(), ((const NDBTAB *)m_table)->getTableId(),
info->no_uncommitted_rows_count)); info->no_uncommitted_rows_count));
if (info->records == ~(ha_rows)0) // if (info->records == ~(ha_rows)0)
{ {
Uint64 rows; Uint64 rows;
if(ndb_get_table_statistics(m_ndb, m_tabname, &rows, 0) == 0){ if(ndb_get_table_statistics(m_ndb, m_tabname, &rows, 0) == 0){
...@@ -246,8 +248,6 @@ int ha_ndbcluster::ndb_err(NdbConnection *trans) ...@@ -246,8 +248,6 @@ int ha_ndbcluster::ndb_err(NdbConnection *trans)
{ {
int res; int res;
const NdbError err= trans->getNdbError(); const NdbError err= trans->getNdbError();
if (!err.code)
return 0; // Don't log things to DBUG log if no error
DBUG_ENTER("ndb_err"); DBUG_ENTER("ndb_err");
ERR_PRINT(err); ERR_PRINT(err);
...@@ -283,10 +283,11 @@ bool ha_ndbcluster::get_error_message(int error, ...@@ -283,10 +283,11 @@ bool ha_ndbcluster::get_error_message(int error,
DBUG_ENTER("ha_ndbcluster::get_error_message"); DBUG_ENTER("ha_ndbcluster::get_error_message");
DBUG_PRINT("enter", ("error: %d", error)); DBUG_PRINT("enter", ("error: %d", error));
if (!m_ndb) Ndb *ndb= ((Thd_ndb*)current_thd->transaction.thd_ndb)->ndb;
if (!ndb)
DBUG_RETURN(false); DBUG_RETURN(false);
const NdbError err= m_ndb->getNdbError(error); const NdbError err= ndb->getNdbError(error);
bool temporary= err.status==NdbError::TemporaryError; bool temporary= err.status==NdbError::TemporaryError;
buf->set(err.message, strlen(err.message), &my_charset_bin); buf->set(err.message, strlen(err.message), &my_charset_bin);
DBUG_PRINT("exit", ("message: %s, temporary: %d", buf->ptr(), temporary)); DBUG_PRINT("exit", ("message: %s, temporary: %d", buf->ptr(), temporary));
...@@ -516,7 +517,7 @@ int ha_ndbcluster::get_ndb_blobs_value(NdbBlob *last_ndb_blob) ...@@ -516,7 +517,7 @@ int ha_ndbcluster::get_ndb_blobs_value(NdbBlob *last_ndb_blob)
*/ */
int ha_ndbcluster::get_ndb_value(NdbOperation *ndb_op, Field *field, int ha_ndbcluster::get_ndb_value(NdbOperation *ndb_op, Field *field,
uint fieldnr) uint fieldnr, byte* buf)
{ {
DBUG_ENTER("get_ndb_value"); DBUG_ENTER("get_ndb_value");
DBUG_PRINT("enter", ("fieldnr: %d flags: %o", fieldnr, DBUG_PRINT("enter", ("fieldnr: %d flags: %o", fieldnr,
...@@ -524,12 +525,15 @@ int ha_ndbcluster::get_ndb_value(NdbOperation *ndb_op, Field *field, ...@@ -524,12 +525,15 @@ int ha_ndbcluster::get_ndb_value(NdbOperation *ndb_op, Field *field,
if (field != NULL) if (field != NULL)
{ {
DBUG_ASSERT(buf);
if (ndb_supported_type(field->type())) if (ndb_supported_type(field->type()))
{ {
DBUG_ASSERT(field->ptr != NULL); DBUG_ASSERT(field->ptr != NULL);
if (! (field->flags & BLOB_FLAG)) if (! (field->flags & BLOB_FLAG))
{ {
m_value[fieldnr].rec= ndb_op->getValue(fieldnr, field->ptr); byte *field_buf= buf + (field->ptr - table->record[0]);
m_value[fieldnr].rec= ndb_op->getValue(fieldnr,
field_buf);
DBUG_RETURN(m_value[fieldnr].rec == NULL); DBUG_RETURN(m_value[fieldnr].rec == NULL);
} }
...@@ -603,7 +607,7 @@ int ha_ndbcluster::get_metadata(const char *path) ...@@ -603,7 +607,7 @@ int ha_ndbcluster::get_metadata(const char *path)
DBUG_ENTER("get_metadata"); DBUG_ENTER("get_metadata");
DBUG_PRINT("enter", ("m_tabname: %s, path: %s", m_tabname, path)); DBUG_PRINT("enter", ("m_tabname: %s, path: %s", m_tabname, path));
if (!(tab= dict->getTable(m_tabname, &m_table_info))) if (!(tab= dict->getTable(m_tabname)))
ERR_RETURN(dict->getNdbError()); ERR_RETURN(dict->getNdbError());
DBUG_PRINT("info", ("Table schema version: %d", tab->getObjectVersion())); DBUG_PRINT("info", ("Table schema version: %d", tab->getObjectVersion()));
...@@ -651,8 +655,8 @@ int ha_ndbcluster::get_metadata(const char *path) ...@@ -651,8 +655,8 @@ int ha_ndbcluster::get_metadata(const char *path)
if (error) if (error)
DBUG_RETURN(error); DBUG_RETURN(error);
// All checks OK, lets use the table m_table= NULL;
m_table= (void*)tab; m_table_info= NULL;
DBUG_RETURN(build_index_list(table, ILBP_OPEN)); DBUG_RETURN(build_index_list(table, ILBP_OPEN));
} }
...@@ -767,6 +771,7 @@ void ha_ndbcluster::release_metadata() ...@@ -767,6 +771,7 @@ void ha_ndbcluster::release_metadata()
DBUG_PRINT("enter", ("m_tabname: %s", m_tabname)); DBUG_PRINT("enter", ("m_tabname: %s", m_tabname));
m_table= NULL; m_table= NULL;
m_table_info= NULL;
// Release index list // Release index list
for (i= 0; i < MAX_KEY; i++) for (i= 0; i < MAX_KEY; i++)
...@@ -947,7 +952,7 @@ int ha_ndbcluster::pk_read(const byte *key, uint key_len, byte *buf) ...@@ -947,7 +952,7 @@ int ha_ndbcluster::pk_read(const byte *key, uint key_len, byte *buf)
ERR_RETURN(trans->getNdbError()); ERR_RETURN(trans->getNdbError());
// Read key at the same time, for future reference // Read key at the same time, for future reference
if (get_ndb_value(op, NULL, no_fields)) if (get_ndb_value(op, NULL, no_fields, NULL))
ERR_RETURN(trans->getNdbError()); ERR_RETURN(trans->getNdbError());
} }
else else
...@@ -964,7 +969,7 @@ int ha_ndbcluster::pk_read(const byte *key, uint key_len, byte *buf) ...@@ -964,7 +969,7 @@ int ha_ndbcluster::pk_read(const byte *key, uint key_len, byte *buf)
if ((thd->query_id == field->query_id) || if ((thd->query_id == field->query_id) ||
retrieve_all_fields) retrieve_all_fields)
{ {
if (get_ndb_value(op, field, i)) if (get_ndb_value(op, field, i, buf))
ERR_RETURN(trans->getNdbError()); ERR_RETURN(trans->getNdbError());
} }
else else
...@@ -1018,7 +1023,7 @@ int ha_ndbcluster::complemented_pk_read(const byte *old_data, byte *new_data) ...@@ -1018,7 +1023,7 @@ int ha_ndbcluster::complemented_pk_read(const byte *old_data, byte *new_data)
if (!(field->flags & PRI_KEY_FLAG) && if (!(field->flags & PRI_KEY_FLAG) &&
(thd->query_id != field->query_id)) (thd->query_id != field->query_id))
{ {
if (get_ndb_value(op, field, i)) if (get_ndb_value(op, field, i, new_data))
ERR_RETURN(trans->getNdbError()); ERR_RETURN(trans->getNdbError());
} }
} }
...@@ -1081,7 +1086,7 @@ int ha_ndbcluster::unique_index_read(const byte *key, ...@@ -1081,7 +1086,7 @@ int ha_ndbcluster::unique_index_read(const byte *key,
if ((thd->query_id == field->query_id) || if ((thd->query_id == field->query_id) ||
(field->flags & PRI_KEY_FLAG)) (field->flags & PRI_KEY_FLAG))
{ {
if (get_ndb_value(op, field, i)) if (get_ndb_value(op, field, i, buf))
ERR_RETURN(op->getNdbError()); ERR_RETURN(op->getNdbError());
} }
else else
...@@ -1480,7 +1485,7 @@ int ha_ndbcluster::define_read_attrs(byte* buf, NdbOperation* op) ...@@ -1480,7 +1485,7 @@ int ha_ndbcluster::define_read_attrs(byte* buf, NdbOperation* op)
(field->flags & PRI_KEY_FLAG) || (field->flags & PRI_KEY_FLAG) ||
retrieve_all_fields) retrieve_all_fields)
{ {
if (get_ndb_value(op, field, i)) if (get_ndb_value(op, field, i, buf))
ERR_RETURN(op->getNdbError()); ERR_RETURN(op->getNdbError());
} }
else else
...@@ -1499,7 +1504,7 @@ int ha_ndbcluster::define_read_attrs(byte* buf, NdbOperation* op) ...@@ -1499,7 +1504,7 @@ int ha_ndbcluster::define_read_attrs(byte* buf, NdbOperation* op)
if (!tab->getColumn(hidden_no)) if (!tab->getColumn(hidden_no))
DBUG_RETURN(1); DBUG_RETURN(1);
#endif #endif
if (get_ndb_value(op, NULL, hidden_no)) if (get_ndb_value(op, NULL, hidden_no, NULL))
ERR_RETURN(op->getNdbError()); ERR_RETURN(op->getNdbError());
} }
...@@ -1521,6 +1526,11 @@ int ha_ndbcluster::write_row(byte *record) ...@@ -1521,6 +1526,11 @@ int ha_ndbcluster::write_row(byte *record)
NdbOperation *op; NdbOperation *op;
int res; int res;
DBUG_ENTER("write_row"); DBUG_ENTER("write_row");
if(m_ignore_dup_key_not_supported)
{
DBUG_RETURN(HA_ERR_WRONG_COMMAND);
}
statistic_increment(ha_write_count,&LOCK_status); statistic_increment(ha_write_count,&LOCK_status);
if (table->timestamp_default_now) if (table->timestamp_default_now)
...@@ -2385,7 +2395,17 @@ void ha_ndbcluster::info(uint flag) ...@@ -2385,7 +2395,17 @@ void ha_ndbcluster::info(uint flag)
if (flag & HA_STATUS_VARIABLE) if (flag & HA_STATUS_VARIABLE)
{ {
DBUG_PRINT("info", ("HA_STATUS_VARIABLE")); DBUG_PRINT("info", ("HA_STATUS_VARIABLE"));
records_update(); if (m_table_info)
{
records_update();
}
else
{
Uint64 rows;
if(ndb_get_table_statistics(m_ndb, m_tabname, &rows, 0) == 0){
records= rows;
}
}
} }
if (flag & HA_STATUS_ERRKEY) if (flag & HA_STATUS_ERRKEY)
{ {
...@@ -2479,14 +2499,20 @@ int ha_ndbcluster::extra(enum ha_extra_function operation) ...@@ -2479,14 +2499,20 @@ int ha_ndbcluster::extra(enum ha_extra_function operation)
break; break;
case HA_EXTRA_IGNORE_DUP_KEY: /* Dup keys don't rollback everything*/ case HA_EXTRA_IGNORE_DUP_KEY: /* Dup keys don't rollback everything*/
DBUG_PRINT("info", ("HA_EXTRA_IGNORE_DUP_KEY")); DBUG_PRINT("info", ("HA_EXTRA_IGNORE_DUP_KEY"));
if (current_thd->lex->sql_command == SQLCOM_REPLACE)
DBUG_PRINT("info", ("Turning ON use of write instead of insert")); {
m_use_write= TRUE; DBUG_PRINT("info", ("Turning ON use of write instead of insert"));
m_use_write= TRUE;
} else
{
m_ignore_dup_key_not_supported= TRUE;
}
break; break;
case HA_EXTRA_NO_IGNORE_DUP_KEY: case HA_EXTRA_NO_IGNORE_DUP_KEY:
DBUG_PRINT("info", ("HA_EXTRA_NO_IGNORE_DUP_KEY")); DBUG_PRINT("info", ("HA_EXTRA_NO_IGNORE_DUP_KEY"));
DBUG_PRINT("info", ("Turning OFF use of write instead of insert")); DBUG_PRINT("info", ("Turning OFF use of write instead of insert"));
m_use_write= false; m_use_write= false;
m_ignore_dup_key_not_supported= false;
break; break;
case HA_EXTRA_RETRIEVE_ALL_COLS: /* Retrieve all columns, not just those case HA_EXTRA_RETRIEVE_ALL_COLS: /* Retrieve all columns, not just those
where field->query_id is the same as where field->query_id is the same as
...@@ -2766,6 +2792,16 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type) ...@@ -2766,6 +2792,16 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type)
// Start of transaction // Start of transaction
retrieve_all_fields= FALSE; retrieve_all_fields= FALSE;
ops_pending= 0; ops_pending= 0;
{
NDBDICT *dict= m_ndb->getDictionary();
const NDBTAB *tab;
void *tab_info;
if (!(tab= dict->getTable(m_tabname, &tab_info)))
ERR_RETURN(dict->getNdbError());
DBUG_PRINT("info", ("Table schema version: %d", tab->getObjectVersion()));
m_table= (void *)tab;
m_table_info= tab_info;
}
no_uncommitted_rows_init(thd); no_uncommitted_rows_init(thd);
} }
else else
...@@ -2788,6 +2824,8 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type) ...@@ -2788,6 +2824,8 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type)
thd->transaction.stmt.ndb_tid= 0; thd->transaction.stmt.ndb_tid= 0;
} }
} }
m_table= NULL;
m_table_info= NULL;
if (m_active_trans) if (m_active_trans)
DBUG_PRINT("warning", ("m_active_trans != NULL")); DBUG_PRINT("warning", ("m_active_trans != NULL"));
if (m_active_cursor) if (m_active_cursor)
...@@ -3273,6 +3311,7 @@ int ha_ndbcluster::alter_table_name(const char *from, const char *to) ...@@ -3273,6 +3311,7 @@ int ha_ndbcluster::alter_table_name(const char *from, const char *to)
ERR_RETURN(dict->getNdbError()); ERR_RETURN(dict->getNdbError());
m_table= NULL; m_table= NULL;
m_table_info= NULL;
DBUG_RETURN(0); DBUG_RETURN(0);
} }
...@@ -3364,6 +3403,7 @@ ha_ndbcluster::ha_ndbcluster(TABLE *table_arg): ...@@ -3364,6 +3403,7 @@ ha_ndbcluster::ha_ndbcluster(TABLE *table_arg):
HA_NO_PREFIX_CHAR_KEYS), HA_NO_PREFIX_CHAR_KEYS),
m_share(0), m_share(0),
m_use_write(false), m_use_write(false),
m_ignore_dup_key_not_supported(false),
retrieve_all_fields(FALSE), retrieve_all_fields(FALSE),
rows_to_insert(1), rows_to_insert(1),
rows_inserted(0), rows_inserted(0),
......
...@@ -211,7 +211,7 @@ class ha_ndbcluster: public handler ...@@ -211,7 +211,7 @@ class ha_ndbcluster: public handler
int set_ndb_key(NdbOperation*, Field *field, int set_ndb_key(NdbOperation*, Field *field,
uint fieldnr, const byte* field_ptr); uint fieldnr, const byte* field_ptr);
int set_ndb_value(NdbOperation*, Field *field, uint fieldnr); int set_ndb_value(NdbOperation*, Field *field, uint fieldnr);
int get_ndb_value(NdbOperation*, Field *field, uint fieldnr); int get_ndb_value(NdbOperation*, Field *field, uint fieldnr, byte*);
friend int g_get_ndb_blobs_value(NdbBlob *ndb_blob, void *arg); friend int g_get_ndb_blobs_value(NdbBlob *ndb_blob, void *arg);
int get_ndb_blobs_value(NdbBlob *last_ndb_blob); int get_ndb_blobs_value(NdbBlob *last_ndb_blob);
int set_primary_key(NdbOperation *op, const byte *key); int set_primary_key(NdbOperation *op, const byte *key);
...@@ -245,6 +245,7 @@ class ha_ndbcluster: public handler ...@@ -245,6 +245,7 @@ class ha_ndbcluster: public handler
typedef union { NdbRecAttr *rec; NdbBlob *blob; void *ptr; } NdbValue; typedef union { NdbRecAttr *rec; NdbBlob *blob; void *ptr; } NdbValue;
NdbValue m_value[NDB_MAX_ATTRIBUTES_IN_TABLE]; NdbValue m_value[NDB_MAX_ATTRIBUTES_IN_TABLE];
bool m_use_write; bool m_use_write;
bool m_ignore_dup_key_not_supported;
bool retrieve_all_fields; bool retrieve_all_fields;
ha_rows rows_to_insert; ha_rows rows_to_insert;
ha_rows rows_inserted; ha_rows rows_inserted;
......
...@@ -328,6 +328,7 @@ void THD::change_user(void) ...@@ -328,6 +328,7 @@ void THD::change_user(void)
cleanup(); cleanup();
cleanup_done= 0; cleanup_done= 0;
init(); init();
stmt_map.reset();
hash_init(&user_vars, &my_charset_bin, USER_VARS_HASH_SIZE, 0, 0, hash_init(&user_vars, &my_charset_bin, USER_VARS_HASH_SIZE, 0, 0,
(hash_get_key) get_var_key, (hash_get_key) get_var_key,
(hash_free_key) free_user_var, 0); (hash_free_key) free_user_var, 0);
......
...@@ -566,7 +566,7 @@ class Statement: public Item_arena ...@@ -566,7 +566,7 @@ class Statement: public Item_arena
assignment in Statement::Statement) assignment in Statement::Statement)
Non-empty statement names are unique too: attempt to insert a new statement Non-empty statement names are unique too: attempt to insert a new statement
with duplicate name causes older statement to be deleted with duplicate name causes older statement to be deleted
Statements are auto-deleted when they are removed from the map and when the Statements are auto-deleted when they are removed from the map and when the
map is deleted. map is deleted.
*/ */
...@@ -575,7 +575,7 @@ class Statement_map ...@@ -575,7 +575,7 @@ class Statement_map
{ {
public: public:
Statement_map(); Statement_map();
int insert(Statement *statement); int insert(Statement *statement);
Statement *find_by_name(LEX_STRING *name) Statement *find_by_name(LEX_STRING *name)
...@@ -608,11 +608,18 @@ class Statement_map ...@@ -608,11 +608,18 @@ class Statement_map
} }
hash_delete(&st_hash, (byte *) statement); hash_delete(&st_hash, (byte *) statement);
} }
/* Erase all statements (calls Statement destructor) */
void reset()
{
hash_reset(&names_hash);
hash_reset(&st_hash);
last_found_statement= 0;
}
~Statement_map() ~Statement_map()
{ {
hash_free(&st_hash);
hash_free(&names_hash); hash_free(&names_hash);
hash_free(&st_hash);
} }
private: private:
HASH st_hash; HASH st_hash;
......
...@@ -10391,6 +10391,34 @@ static void test_bug5194() ...@@ -10391,6 +10391,34 @@ static void test_bug5194()
} }
static void test_bug5315()
{
MYSQL_STMT *stmt;
const char *stmt_text;
int rc;
myheader("test_bug5315");
stmt_text= "SELECT 1";
stmt= mysql_stmt_init(mysql);
rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
DBUG_ASSERT(rc == 0);
mysql_change_user(mysql, opt_user, opt_password, current_db);
rc= mysql_stmt_execute(stmt);
DBUG_ASSERT(rc != 0);
if (rc)
printf("Got error (as expected):\n%s", mysql_stmt_error(stmt));
/* check that connection is OK */
mysql_stmt_close(stmt);
stmt= mysql_stmt_init(mysql);
rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
DBUG_ASSERT(rc == 0);
rc= mysql_stmt_execute(stmt);
DBUG_ASSERT(rc == 0);
mysql_stmt_close(stmt);
}
/* /*
Read and parse arguments and MySQL options from my.cnf Read and parse arguments and MySQL options from my.cnf
*/ */
...@@ -10694,6 +10722,8 @@ int main(int argc, char **argv) ...@@ -10694,6 +10722,8 @@ int main(int argc, char **argv)
test_bug5399(); /* check that statement id uniquely identifies test_bug5399(); /* check that statement id uniquely identifies
statement */ statement */
test_bug5194(); /* bulk inserts in prepared mode */ test_bug5194(); /* bulk inserts in prepared mode */
test_bug5315(); /* check that mysql_change_user closes all
prepared statements */
/* /*
XXX: PLEASE RUN THIS PROGRAM UNDER VALGRIND AND VERIFY THAT YOUR TEST XXX: PLEASE RUN THIS PROGRAM UNDER VALGRIND AND VERIFY THAT YOUR TEST
DOESN'T CONTAIN WARNINGS/ERRORS BEFORE YOU PUSH. DOESN'T CONTAIN WARNINGS/ERRORS BEFORE YOU PUSH.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment