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
bk@mysql.r18.ru
brian@avenger.(none)
brian@brian-akers-computer.local
brian@private-client-ip-101.oz.net
carsten@tsort.bitbybit.dk
davida@isil.mysql.com
dlenev@brandersnatch.localdomain
......@@ -102,6 +103,7 @@ miguel@light.local
miguel@sartre.local
mikron@c-fb0ae253.1238-1-64736c10.cust.bredbandsbolaget.se
mikron@mikael-ronstr-ms-dator.local
mleich@mysql.com
mmatthew@markslaptop.
monty@bitch.mysql.fi
monty@butch.
......
......@@ -4,7 +4,7 @@ dnl Process this file with autoconf to produce a configure script.
AC_INIT(sql/mysqld.cc)
AC_CANONICAL_SYSTEM
# 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)
PROTOCOL_VERSION=10
......
......@@ -47,6 +47,7 @@ my_bool _hash_init(HASH *hash, CHARSET_INFO *charset,
uint key_length, hash_get_key get_key,
void (*free_element)(void*), uint flags CALLER_INFO_PROTO);
void hash_free(HASH *tree);
void hash_reset(HASH *hash);
byte *hash_element(HASH *hash,uint idx);
gptr hash_search(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);
void hash_replace(HASH *hash, uint idx, byte *new_row);
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)
#ifdef __cplusplus
......
......@@ -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,
const char *filename,const char *group);
void mysql_detach_stmt_list(LIST **stmt_list);
MYSQL * STDCALL
cli_mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
const char *passwd, const char *db,
......
......@@ -662,6 +662,7 @@ my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user,
const char *passwd, const char *db)
{
char buff[512],*end=buff;
int rc;
DBUG_ENTER("mysql_change_user");
if (!user)
......@@ -695,18 +696,26 @@ my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user,
/* Write authentication package */
simple_command(mysql,COM_CHANGE_USER, buff,(ulong) (end-buff),1);
if ((*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));
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(0);
rc= (*mysql->methods->read_change_user_result)(mysql, buff, passwd);
/*
The server will close all statements no matter was the attempt
to change user successful or not.
*/
mysql_detach_stmt_list(&mysql->stmts);
if (rc == 0)
{
/* Free old connect information */
my_free(mysql->user,MYF(MY_ALLOW_ZERO_PTR));
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)
......
......@@ -110,10 +110,10 @@ select a,b from t1 where a=@arg00;
set @arg00=NULL;
set @arg01=2;
execute stmt1 using @arg00, @arg01;
select a,b from t1;
select a,b from t1 order by a;
set @arg00=0;
execute stmt1 using @arg01, @arg00;
select a,b from t1;
select a,b from t1 order by a;
## update with subquery and several parameters
set @arg00=23;
......@@ -134,7 +134,7 @@ prepare stmt1 from 'update t1 set a=? where b=?
and a not in (select ? from t2
where b = ? or a = ?)';
execute stmt1 using @arg04, @arg01, @arg02, @arg03, @arg00 ;
select a,b from t1 ;
select a,b from t1 order by a;
drop table t2 ;
## update with parameters in limit
......@@ -202,7 +202,7 @@ set @arg01=1 ;
prepare stmt1 from 'insert into t1 set a=?, b=''sechs''
on duplicate key update a=a + ?, b=concat(b,''modified'') ';
execute stmt1 using @arg00, @arg01;
select * from t1;
select * from t1 order by a;
set @arg00=81 ;
set @arg01=1 ;
--error 1062
......@@ -221,17 +221,17 @@ set @updated="updated" ;
insert into t1 values(1000,'x1000_1') ;
insert into t1 values(@1000,@x1000_2),(@1000,@x1000_3)
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 ;
insert into t1 values(1000,'x1000_1') ;
prepare stmt1 from ' insert into t1 values(?,?),(?,?)
on duplicate key update a = a + ?, b = concat(b,?) ';
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 ;
insert into t1 values(1000,'x1000_1') ;
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 ;
## replace
......
......@@ -45,19 +45,19 @@
set @duplicate='duplicate ' ;
set @1000=1000 ;
set @5=5 ;
select a,b from t1 where a < 5 ;
select a,b from t1 where a < 5 order by a ;
--enable_info
insert into t1 select a + @1000, concat(@duplicate,b) from t1
where a < @5 ;
--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 ;
prepare stmt1 from ' insert into t1 select a + ?, concat(?,b) from t1
where a < ? ' ;
--enable_info
execute stmt1 using @1000, @duplicate, @5;
--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 ;
set @float=1.00;
......@@ -78,7 +78,7 @@ select b, a + @100 from t1
where (a,b) in ( select sqrt(a+@1)+CAST(@float AS signed),b
from t1);
--disable_info
select a,b from t2;
select a,b from t2 order by a ;
delete from t2 ;
prepare stmt1 from ' insert into t2 (b,a)
select ?, sum(first.a)
......@@ -93,5 +93,5 @@ select b, a + ? from t1
--enable_info
execute stmt1 using @duplicate, @5, @five, @2, @100, @1, @float ;
--disable_info
select a,b from t2;
select a,b from t2 order by a ;
drop table t2;
This diff is collapsed.
......@@ -420,6 +420,9 @@ 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 count(*) from t1;
count(*)
2000
begin;
SELECT COUNT(*) FROM t1;
COUNT(*)
......@@ -429,17 +432,128 @@ INSERT INTO t1 VALUES
SELECT COUNT(*) FROM t1;
COUNT(*)
2005
rollback;
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 COUNT(*) FROM t1;
COUNT(*)
commit;
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
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;
SELECT COUNT(*) FROM t1;
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
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
insert into t1 select * from t1 where b < 10 order by pk1;
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;
......@@ -1016,15 +1016,15 @@ set @arg01=2;
execute stmt1 using @arg00, @arg01;
Warnings:
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
1 one
0 two
1 one
3 three
4 four
set @arg00=0;
execute stmt1 using @arg01, @arg00;
select a,b from t1;
select a,b from t1 order by a;
a b
1 one
2 two
......@@ -1048,7 +1048,7 @@ prepare stmt1 from 'update t1 set a=? where b=?
and a not in (select ? from t2
where b = ? or a = ?)';
execute stmt1 using @arg04, @arg01, @arg02, @arg03, @arg00 ;
select a,b from t1 ;
select a,b from t1 order by a;
a b
1 one
2 two
......@@ -1142,19 +1142,19 @@ set @arg01=1 ;
prepare stmt1 from 'insert into t1 set a=?, b=''sechs''
on duplicate key update a=a + ?, b=concat(b,''modified'') ';
execute stmt1 using @arg00, @arg01;
select * from t1;
select * from t1 order by a;
a b
0 NULL
1 one
2 two
3 three
4 four
5 five
7 sixmodified
0 NULL
8 eight
9 nine
81 8-1
82 8-2
9 nine
set @arg00=81 ;
set @arg01=1 ;
execute stmt1 using @arg00, @arg01;
......@@ -1170,7 +1170,7 @@ set @updated="updated" ;
insert into t1 values(1000,'x1000_1') ;
insert into t1 values(@1000,@x1000_2),(@1000,@x1000_3)
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
1000 x1000_3
1100 x1000_1updated
......@@ -1179,14 +1179,14 @@ insert into t1 values(1000,'x1000_1') ;
prepare stmt1 from ' insert into t1 values(?,?),(?,?)
on duplicate key update a = a + ?, b = concat(b,?) ';
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
1000 x1000_3
1100 x1000_1updated
delete from t1 where a >= 1000 ;
insert into t1 values(1000,'x1000_1') ;
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
1200 x1000_1updatedupdated
delete from t1 where a >= 1000 ;
......@@ -1195,37 +1195,37 @@ ERROR HY000: This command is not supported in the prepared statement protocol ye
set @duplicate='duplicate ' ;
set @1000=1000 ;
set @5=5 ;
select a,b from t1 where a < 5 ;
select a,b from t1 where a < 5 order by a ;
a b
0 NULL
1 one
2 two
3 three
4 four
0 NULL
insert into t1 select a + @1000, concat(@duplicate,b) from t1
where a < @5 ;
affected rows: 5
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
1000 NULL
1001 duplicate one
1002 duplicate two
1003 duplicate three
1004 duplicate four
1000 NULL
delete from t1 where a >= 1000 ;
prepare stmt1 from ' insert into t1 select a + ?, concat(?,b) from t1
where a < ? ' ;
execute stmt1 using @1000, @duplicate, @5;
affected rows: 5
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
1004 duplicate four
1003 duplicate three
1002 duplicate two
1001 duplicate one
1000 NULL
1001 duplicate one
1002 duplicate two
1003 duplicate three
1004 duplicate four
delete from t1 where a >= 1000 ;
set @float=1.00;
set @five='five' ;
......@@ -1243,15 +1243,15 @@ where (a,b) in ( select sqrt(a+@1)+CAST(@float AS signed),b
from t1);
affected rows: 8
info: Records: 8 Duplicates: 0 Warnings: 0
select a,b from t2;
select a,b from t2 order by a ;
a b
81 duplicate
82 duplicate
8 duplicate
3 duplicate
4 duplicate
9 duplicate
7 duplicate
3 duplicate
8 duplicate
9 duplicate
81 duplicate
82 duplicate
103 three
delete from t2 ;
prepare stmt1 from ' insert into t2 (b,a)
......@@ -1267,15 +1267,15 @@ select b, a + ? from t1
execute stmt1 using @duplicate, @5, @five, @2, @100, @1, @float ;
affected rows: 8
info: Records: 8 Duplicates: 0 Warnings: 0
select a,b from t2;
select a,b from t2 order by a ;
a b
81 duplicate
82 duplicate
8 duplicate
3 duplicate
4 duplicate
9 duplicate
7 duplicate
3 duplicate
8 duplicate
9 duplicate
81 duplicate
82 duplicate
103 three
drop table t2;
drop table t1, t_many_col_types;
......@@ -1016,7 +1016,7 @@ set @arg01=2;
execute stmt1 using @arg00, @arg01;
Warnings:
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
0 two
1 one
......@@ -1024,7 +1024,7 @@ a b
4 four
set @arg00=0;
execute stmt1 using @arg01, @arg00;
select a,b from t1;
select a,b from t1 order by a;
a b
1 one
2 two
......@@ -1048,7 +1048,7 @@ prepare stmt1 from 'update t1 set a=? where b=?
and a not in (select ? from t2
where b = ? or a = ?)';
execute stmt1 using @arg04, @arg01, @arg02, @arg03, @arg00 ;
select a,b from t1 ;
select a,b from t1 order by a;
a b
1 one
2 two
......@@ -1142,7 +1142,7 @@ set @arg01=1 ;
prepare stmt1 from 'insert into t1 set a=?, b=''sechs''
on duplicate key update a=a + ?, b=concat(b,''modified'') ';
execute stmt1 using @arg00, @arg01;
select * from t1;
select * from t1 order by a;
a b
0 NULL
1 one
......@@ -1170,7 +1170,7 @@ set @updated="updated" ;
insert into t1 values(1000,'x1000_1') ;
insert into t1 values(@1000,@x1000_2),(@1000,@x1000_3)
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
1000 x1000_3
1100 x1000_1updated
......@@ -1179,14 +1179,14 @@ insert into t1 values(1000,'x1000_1') ;
prepare stmt1 from ' insert into t1 values(?,?),(?,?)
on duplicate key update a = a + ?, b = concat(b,?) ';
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
1000 x1000_3
1100 x1000_1updated
delete from t1 where a >= 1000 ;
insert into t1 values(1000,'x1000_1') ;
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
1200 x1000_1updatedupdated
delete from t1 where a >= 1000 ;
......@@ -1195,7 +1195,7 @@ ERROR HY000: This command is not supported in the prepared statement protocol ye
set @duplicate='duplicate ' ;
set @1000=1000 ;
set @5=5 ;
select a,b from t1 where a < 5 ;
select a,b from t1 where a < 5 order by a ;
a b
0 NULL
1 one
......@@ -1206,7 +1206,7 @@ insert into t1 select a + @1000, concat(@duplicate,b) from t1
where a < @5 ;
affected rows: 5
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
1000 NULL
1001 duplicate one
......@@ -1219,7 +1219,7 @@ where a < ? ' ;
execute stmt1 using @1000, @duplicate, @5;
affected rows: 5
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
1000 NULL
1001 duplicate one
......@@ -1243,7 +1243,7 @@ where (a,b) in ( select sqrt(a+@1)+CAST(@float AS signed),b
from t1);
affected rows: 8
info: Records: 8 Duplicates: 0 Warnings: 0
select a,b from t2;
select a,b from t2 order by a ;
a b
3 duplicate
4 duplicate
......@@ -1267,7 +1267,7 @@ select b, a + ? from t1
execute stmt1 using @duplicate, @5, @five, @2, @100, @1, @float ;
affected rows: 8
info: Records: 8 Duplicates: 0 Warnings: 0
select a,b from t2;
select a,b from t2 order by a ;
a b
3 duplicate
4 duplicate
......
......@@ -1017,15 +1017,15 @@ set @arg01=2;
execute stmt1 using @arg00, @arg01;
Warnings:
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
1 one
0 two
1 one
3 three
4 four
set @arg00=0;
execute stmt1 using @arg01, @arg00;
select a,b from t1;
select a,b from t1 order by a;
a b
1 one
2 two
......@@ -1049,7 +1049,7 @@ prepare stmt1 from 'update t1 set a=? where b=?
and a not in (select ? from t2
where b = ? or a = ?)';
execute stmt1 using @arg04, @arg01, @arg02, @arg03, @arg00 ;
select a,b from t1 ;
select a,b from t1 order by a;
a b
1 one
2 two
......@@ -1143,19 +1143,19 @@ set @arg01=1 ;
prepare stmt1 from 'insert into t1 set a=?, b=''sechs''
on duplicate key update a=a + ?, b=concat(b,''modified'') ';
execute stmt1 using @arg00, @arg01;
select * from t1;
select * from t1 order by a;
a b
0 NULL
1 one
2 two
3 three
4 four
5 five
7 sixmodified
0 NULL
8 eight
9 nine
81 8-1
82 8-2
9 nine
set @arg00=81 ;
set @arg01=1 ;
execute stmt1 using @arg00, @arg01;
......@@ -1171,23 +1171,23 @@ set @updated="updated" ;
insert into t1 values(1000,'x1000_1') ;
insert into t1 values(@1000,@x1000_2),(@1000,@x1000_3)
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
1100 x1000_1updated
1000 x1000_3
1100 x1000_1updated
delete from t1 where a >= 1000 ;
insert into t1 values(1000,'x1000_1') ;
prepare stmt1 from ' insert into t1 values(?,?),(?,?)
on duplicate key update a = a + ?, b = concat(b,?) ';
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
1000 x1000_3
1100 x1000_1updated
delete from t1 where a >= 1000 ;
insert into t1 values(1000,'x1000_1') ;
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
1200 x1000_1updatedupdated
delete from t1 where a >= 1000 ;
......@@ -1196,37 +1196,37 @@ ERROR HY000: This command is not supported in the prepared statement protocol ye
set @duplicate='duplicate ' ;
set @1000=1000 ;
set @5=5 ;
select a,b from t1 where a < 5 ;
select a,b from t1 where a < 5 order by a ;
a b
0 NULL
1 one
2 two
3 three
4 four
0 NULL
insert into t1 select a + @1000, concat(@duplicate,b) from t1
where a < @5 ;
affected rows: 5
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
1002 duplicate two
1000 NULL
1001 duplicate one
1002 duplicate two
1003 duplicate three
1004 duplicate four
1000 NULL
delete from t1 where a >= 1000 ;
prepare stmt1 from ' insert into t1 select a + ?, concat(?,b) from t1
where a < ? ' ;
execute stmt1 using @1000, @duplicate, @5;
affected rows: 5
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
1000 NULL
1004 duplicate four
1003 duplicate three
1002 duplicate two
1001 duplicate one
1002 duplicate two
1003 duplicate three
1004 duplicate four
delete from t1 where a >= 1000 ;
set @float=1.00;
set @five='five' ;
......@@ -1244,15 +1244,15 @@ where (a,b) in ( select sqrt(a+@1)+CAST(@float AS signed),b
from t1);
affected rows: 8
info: Records: 8 Duplicates: 0 Warnings: 0
select a,b from t2;
select a,b from t2 order by a ;
a b
81 duplicate
82 duplicate
8 duplicate
3 duplicate
4 duplicate
9 duplicate
7 duplicate
3 duplicate
8 duplicate
9 duplicate
81 duplicate
82 duplicate
103 three
delete from t2 ;
prepare stmt1 from ' insert into t2 (b,a)
......@@ -1268,15 +1268,15 @@ select b, a + ? from t1
execute stmt1 using @duplicate, @5, @five, @2, @100, @1, @float ;
affected rows: 8
info: Records: 8 Duplicates: 0 Warnings: 0
select a,b from t2;
select a,b from t2 order by a ;
a b
81 duplicate
82 duplicate
8 duplicate
3 duplicate
4 duplicate
9 duplicate
7 duplicate
3 duplicate
8 duplicate
9 duplicate
81 duplicate
82 duplicate
103 three
drop table t2;
drop table t1, t_many_col_types;
......@@ -1059,19 +1059,19 @@ set @arg01=2;
execute stmt1 using @arg00, @arg01;
Warnings:
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
3 three
0 two
1 one
3 three
4 four
set @arg00=0;
execute stmt1 using @arg01, @arg00;
select a,b from t1;
select a,b from t1 order by a;
a b
3 three
2 two
1 one
2 two
3 three
4 four
set @arg00=23;
set @arg01='two';
......@@ -1091,11 +1091,11 @@ prepare stmt1 from 'update t1 set a=? where b=?
and a not in (select ? from t2
where b = ? or a = ?)';
execute stmt1 using @arg04, @arg01, @arg02, @arg03, @arg00 ;
select a,b from t1 ;
select a,b from t1 order by a;
a b
3 three
2 two
1 one
2 two
3 three
4 four
drop table t2 ;
set @arg00=1;
......@@ -1185,19 +1185,19 @@ set @arg01=1 ;
prepare stmt1 from 'insert into t1 set a=?, b=''sechs''
on duplicate key update a=a + ?, b=concat(b,''modified'') ';
execute stmt1 using @arg00, @arg01;
select * from t1;
select * from t1 order by a;
a b
4 four
3 three
2 two
0 NULL
1 one
2 two
3 three
4 four
5 five
7 sixmodified
0 NULL
8 eight
9 nine
81 8-1
82 8-2
9 nine
set @arg00=81 ;
set @arg01=1 ;
execute stmt1 using @arg00, @arg01;
......@@ -1213,7 +1213,7 @@ set @updated="updated" ;
insert into t1 values(1000,'x1000_1') ;
insert into t1 values(@1000,@x1000_2),(@1000,@x1000_3)
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
1000 x1000_3
1100 x1000_1updated
......@@ -1222,14 +1222,14 @@ insert into t1 values(1000,'x1000_1') ;
prepare stmt1 from ' insert into t1 values(?,?),(?,?)
on duplicate key update a = a + ?, b = concat(b,?) ';
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
1000 x1000_3
1100 x1000_1updated
delete from t1 where a >= 1000 ;
insert into t1 values(1000,'x1000_1') ;
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
1200 x1000_1updatedupdated
delete from t1 where a >= 1000 ;
......@@ -2254,19 +2254,19 @@ set @arg01=2;
execute stmt1 using @arg00, @arg01;
Warnings:
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
3 three
0 two
1 one
3 three
4 four
set @arg00=0;
execute stmt1 using @arg01, @arg00;
select a,b from t1;
select a,b from t1 order by a;
a b
3 three
2 two
1 one
2 two
3 three
4 four
set @arg00=23;
set @arg01='two';
......@@ -2286,11 +2286,11 @@ prepare stmt1 from 'update t1 set a=? where b=?
and a not in (select ? from t2
where b = ? or a = ?)';
execute stmt1 using @arg04, @arg01, @arg02, @arg03, @arg00 ;
select a,b from t1 ;
select a,b from t1 order by a;
a b
3 three
2 two
1 one
2 two
3 three
4 four
drop table t2 ;
set @arg00=1;
......@@ -2380,19 +2380,19 @@ set @arg01=1 ;
prepare stmt1 from 'insert into t1 set a=?, b=''sechs''
on duplicate key update a=a + ?, b=concat(b,''modified'') ';
execute stmt1 using @arg00, @arg01;
select * from t1;
select * from t1 order by a;
a b
4 four
3 three
2 two
0 NULL
1 one
2 two
3 three
4 four
5 five
7 sixmodified
0 NULL
8 eight
9 nine
81 8-1
82 8-2
9 nine
set @arg00=81 ;
set @arg01=1 ;
execute stmt1 using @arg00, @arg01;
......@@ -2408,7 +2408,7 @@ set @updated="updated" ;
insert into t1 values(1000,'x1000_1') ;
insert into t1 values(@1000,@x1000_2),(@1000,@x1000_3)
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
1000 x1000_3
1100 x1000_1updated
......@@ -2417,14 +2417,14 @@ insert into t1 values(1000,'x1000_1') ;
prepare stmt1 from ' insert into t1 values(?,?),(?,?)
on duplicate key update a = a + ?, b = concat(b,?) ';
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
1000 x1000_3
1100 x1000_1updated
delete from t1 where a >= 1000 ;
insert into t1 values(1000,'x1000_1') ;
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
1200 x1000_1updatedupdated
delete from t1 where a >= 1000 ;
......
......@@ -1016,7 +1016,7 @@ set @arg01=2;
execute stmt1 using @arg00, @arg01;
Warnings:
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
0 two
1 one
......@@ -1024,7 +1024,7 @@ a b
4 four
set @arg00=0;
execute stmt1 using @arg01, @arg00;
select a,b from t1;
select a,b from t1 order by a;
a b
1 one
2 two
......@@ -1048,7 +1048,7 @@ prepare stmt1 from 'update t1 set a=? where b=?
and a not in (select ? from t2
where b = ? or a = ?)';
execute stmt1 using @arg04, @arg01, @arg02, @arg03, @arg00 ;
select a,b from t1 ;
select a,b from t1 order by a;
a b
1 one
2 two
......@@ -1142,7 +1142,7 @@ set @arg01=1 ;
prepare stmt1 from 'insert into t1 set a=?, b=''sechs''
on duplicate key update a=a + ?, b=concat(b,''modified'') ';
execute stmt1 using @arg00, @arg01;
select * from t1;
select * from t1 order by a;
a b
0 NULL
1 one
......@@ -1170,7 +1170,7 @@ set @updated="updated" ;
insert into t1 values(1000,'x1000_1') ;
insert into t1 values(@1000,@x1000_2),(@1000,@x1000_3)
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
1000 x1000_3
1100 x1000_1updated
......@@ -1179,14 +1179,14 @@ insert into t1 values(1000,'x1000_1') ;
prepare stmt1 from ' insert into t1 values(?,?),(?,?)
on duplicate key update a = a + ?, b = concat(b,?) ';
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
1000 x1000_3
1100 x1000_1updated
delete from t1 where a >= 1000 ;
insert into t1 values(1000,'x1000_1') ;
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
1200 x1000_1updatedupdated
delete from t1 where a >= 1000 ;
......@@ -1195,7 +1195,7 @@ ERROR HY000: This command is not supported in the prepared statement protocol ye
set @duplicate='duplicate ' ;
set @1000=1000 ;
set @5=5 ;
select a,b from t1 where a < 5 ;
select a,b from t1 where a < 5 order by a ;
a b
0 NULL
1 one
......@@ -1206,7 +1206,7 @@ insert into t1 select a + @1000, concat(@duplicate,b) from t1
where a < @5 ;
affected rows: 5
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
1000 NULL
1001 duplicate one
......@@ -1219,7 +1219,7 @@ where a < ? ' ;
execute stmt1 using @1000, @duplicate, @5;
affected rows: 5
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
1000 NULL
1001 duplicate one
......@@ -1243,7 +1243,7 @@ where (a,b) in ( select sqrt(a+@1)+CAST(@float AS signed),b
from t1);
affected rows: 8
info: Records: 8 Duplicates: 0 Warnings: 0
select a,b from t2;
select a,b from t2 order by a ;
a b
3 duplicate
4 duplicate
......@@ -1267,7 +1267,7 @@ select b, a + ? from t1
execute stmt1 using @duplicate, @5, @five, @2, @100, @1, @float ;
affected rows: 8
info: Records: 8 Duplicates: 0 Warnings: 0
select a,b from t2;
select a,b from t2 order by a ;
a b
3 duplicate
4 duplicate
......
......@@ -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 (4,011403,37,'intercepted','audiology','tinily','');
SELECT * FROM t2;
OPTIMIZE TABLE t2;
SELECT * FROM t2;
drop table t1, t2;
......@@ -437,26 +437,125 @@ 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);
select count(*) from t1;
begin;
#
# Insert duplicate rows, inside transaction
# since failing inserts rollbacks whole transaction
# all select count (except second) return same value
# Test that select count(*) can see inserts made in the same transaction
#
begin;
SELECT COUNT(*) FROM t1;
INSERT INTO t1 VALUES
(2001,2001,2001),(2002,2002,2002),(2003,2003,2003),(2004,2004,2004),(2005,2005,2005);
SELECT COUNT(*) FROM t1;
rollback;
#
# Insert duplicate rows, inside transaction
# try to 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);
SELECT COUNT(*) FROM t1;
--error 1296
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"
......@@ -466,4 +565,21 @@ SELECT COUNT(*) FROM t1;
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;
......@@ -88,6 +88,32 @@ void hash_free(HASH *hash)
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 */
/*
......
......@@ -229,10 +229,10 @@ LocalConfig::parseString(const char * connectString, char *line){
bool LocalConfig::readFile(const char * filename, bool &fopenError)
{
char line[150], line2[150];
char line[1024];
fopenError = false;
FILE * file = fopen(filename, "r");
if(file == 0){
snprintf(line, 150, "Unable to open local config file: %s", filename);
......@@ -241,31 +241,33 @@ bool LocalConfig::readFile(const char * filename, bool &fopenError)
return false;
}
unsigned int sz = 1024;
char* theString = (char*)NdbMem_Allocate(sz);
theString[0] = 0;
fgets(theString, sz, file);
while (fgets(line+1, 100, file)) {
line[0] = ';';
while (strlen(theString) + strlen(line) >= sz) {
sz = sz*2;
char *newString = (char*)NdbMem_Allocate(sz);
strcpy(newString, theString);
free(theString);
theString = newString;
BaseString theString;
while(fgets(line, 1024, file)){
BaseString tmp(line);
tmp.trim(" \t\n\r");
if(tmp.length() > 0 && tmp.c_str()[0] != '#'){
theString.append(tmp);
break;
}
strcat(theString, line);
}
bool return_value = parseString(theString, line);
while (fgets(line, 1024, file)) {
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) {
snprintf(line2, 150, "Reading %s: %s", filename, line);
setError(0,line2);
BaseString tmp;
tmp.assfmt("Reading %s: %s", filename, line);
setError(0, tmp.c_str());
}
free(theString);
fclose(file);
return return_value;
}
......
......@@ -159,6 +159,7 @@ Configuration::Configuration()
_initialStart = false;
_daemonMode = false;
m_config_retriever= 0;
m_clusterConfig= 0;
}
Configuration::~Configuration(){
......
......@@ -145,27 +145,29 @@ NdbConnection::init()
}//NdbConnection::init()
/*****************************************************************************
setOperationErrorCode(int anErrorCode);
setOperationErrorCode(int error);
Remark: Sets an error code on the connection object from an
operation object.
*****************************************************************************/
void
NdbConnection::setOperationErrorCode(int anErrorCode)
NdbConnection::setOperationErrorCode(int error)
{
if (theError.code == 0)
theError.code = anErrorCode;
}//NdbConnection::setOperationErrorCode()
DBUG_ENTER("NdbConnection::setOperationErrorCode");
setErrorCode(error);
DBUG_VOID_RETURN;
}
/*****************************************************************************
setOperationErrorCodeAbort(int anErrorCode);
setOperationErrorCodeAbort(int error);
Remark: Sets an error code on the connection object from an
operation object.
*****************************************************************************/
void
NdbConnection::setOperationErrorCodeAbort(int anErrorCode)
NdbConnection::setOperationErrorCodeAbort(int error)
{
DBUG_ENTER("NdbConnection::setOperationErrorCodeAbort");
if (theTransactionIsStarted == false) {
theCommitStatus = Aborted;
} else if ((m_abortOption == AbortOnError) &&
......@@ -173,9 +175,9 @@ NdbConnection::setOperationErrorCodeAbort(int anErrorCode)
(theCommitStatus != Aborted)) {
theCommitStatus = NeedAbort;
}//if
if (theError.code == 0)
theError.code = anErrorCode;
}//NdbConnection::setOperationErrorCodeAbort()
setErrorCode(error);
DBUG_VOID_RETURN;
}
/*****************************************************************************
setErrorCode(int anErrorCode);
......@@ -183,10 +185,15 @@ setErrorCode(int anErrorCode);
Remark: Sets an error indication on the connection object.
*****************************************************************************/
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)
theError.code = anErrorCode;
theError.code = error;
DBUG_VOID_RETURN;
}//NdbConnection::setErrorCode()
int
......@@ -262,8 +269,12 @@ NdbConnection::execute(ExecType aTypeOfExec,
AbortOption abortOption,
int forceSend)
{
DBUG_ENTER("NdbConnection::execute");
DBUG_PRINT("enter", ("aTypeOfExec: %d, abortOption: %d",
aTypeOfExec, abortOption));
if (! theBlobFlag)
return executeNoBlobs(aTypeOfExec, abortOption, forceSend);
DBUG_RETURN(executeNoBlobs(aTypeOfExec, abortOption, forceSend));
/*
* execute prepared ops in batches, as requested by blobs
......@@ -346,7 +357,7 @@ NdbConnection::execute(ExecType aTypeOfExec,
}
} while (theFirstOpInList != NULL || tExecType != aTypeOfExec);
return ret;
DBUG_RETURN(ret);
}
int
......@@ -354,6 +365,10 @@ NdbConnection::executeNoBlobs(ExecType aTypeOfExec,
AbortOption abortOption,
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
// since last execute or since beginning. If this works ok we will continue
......@@ -376,7 +391,7 @@ NdbConnection::executeNoBlobs(ExecType aTypeOfExec,
*/
ndbout << "This timeout should never occur, execute(..)" << endl;
setOperationErrorCodeAbort(4012); // Error code for "Cluster Failure"
return -1;
DBUG_RETURN(-1);
}//if
/*
......@@ -400,13 +415,13 @@ NdbConnection::executeNoBlobs(ExecType aTypeOfExec,
}
#endif
if (theReturnStatus == ReturnFailure) {
return -1;
DBUG_RETURN(-1);
}//if
break;
}
}
thePendingBlobOps = 0;
return 0;
DBUG_RETURN(0);
}//NdbConnection::execute()
/*****************************************************************************
......@@ -430,9 +445,15 @@ NdbConnection::executeAsynchPrepare( ExecType aTypeOfExec,
void* anyObject,
AbortOption abortOption)
{
DBUG_ENTER("NdbConnection::executeAsynchPrepare");
DBUG_PRINT("enter", ("aTypeOfExec: %d, aCallback: %x, anyObject: %x",
aTypeOfExec, aCallback, anyObject));
/**
* Reset error.code on execute
*/
if (theError.code != 0)
DBUG_PRINT("enter", ("Resetting error %d on execute", theError.code));
theError.code = 0;
NdbScanOperation* tcOp = m_theFirstScanOperation;
if (tcOp != 0){
......@@ -441,7 +462,7 @@ NdbConnection::executeAsynchPrepare( ExecType aTypeOfExec,
int tReturnCode;
tReturnCode = tcOp->executeCursor(theDBnode);
if (tReturnCode == -1) {
return;
DBUG_VOID_RETURN;
}//if
tcOp = (NdbScanOperation*)tcOp->next();
} // while
......@@ -463,17 +484,6 @@ NdbConnection::executeAsynchPrepare( ExecType aTypeOfExec,
theCallbackFunction = aCallback;
theCallbackObject = anyObject;
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;
tNdb->thePreparedTransactionsArray[tnoOfPreparedTransactions] = this;
theTransArrayIndex = tnoOfPreparedTransactions;
......@@ -502,7 +512,11 @@ NdbConnection::executeAsynchPrepare( ExecType aTypeOfExec,
} else {
theSendStatus = sendABORTfail;
}//if
return;
if (theCommitStatus == Aborted){
DBUG_PRINT("exit", ("theCommitStatus: Aborted"));
setErrorCode(4350);
}
DBUG_VOID_RETURN;
}//if
if (tTransactionIsStarted == true) {
if (tLastOp != NULL) {
......@@ -520,7 +534,7 @@ NdbConnection::executeAsynchPrepare( ExecType aTypeOfExec,
* We will use the commit method.
*********************************************************************/
theSendStatus = sendCOMMITstate;
return;
DBUG_VOID_RETURN;
} else {
/**********************************************************************
* We need to put it into the array of completed transactions to
......@@ -532,7 +546,7 @@ NdbConnection::executeAsynchPrepare( ExecType aTypeOfExec,
* put it into the completed array.
**********************************************************************/
theSendStatus = sendCompleted;
return; // No Commit with no operations is OK
DBUG_VOID_RETURN; // No Commit with no operations is OK
}//if
}//if
} else if (tTransactionIsStarted == false) {
......@@ -560,7 +574,7 @@ NdbConnection::executeAsynchPrepare( ExecType aTypeOfExec,
* will put it into the completed array.
***********************************************************************/
theSendStatus = sendCompleted;
return;
DBUG_VOID_RETURN;
}//if
}
......@@ -573,7 +587,7 @@ NdbConnection::executeAsynchPrepare( ExecType aTypeOfExec,
tReturnCode = tOp->prepareSend(theTCConPtr, theTransactionId);
if (tReturnCode == -1) {
theSendStatus = sendABORTfail;
return;
DBUG_VOID_RETURN;
}//if
/*************************************************************************
......@@ -596,7 +610,7 @@ NdbConnection::executeAsynchPrepare( ExecType aTypeOfExec,
theNoOfOpSent = 0;
theNoOfOpCompleted = 0;
theSendStatus = sendOperations;
return;
DBUG_VOID_RETURN;
}//NdbConnection::executeAsynchPrepare()
void NdbConnection::close()
......@@ -665,6 +679,8 @@ Remark: Send all operations belonging to this connection.
int
NdbConnection::doSend()
{
DBUG_ENTER("NdbConnection::doSend");
/*
This method assumes that at least one operation have been defined. This
is ensured by the caller of this routine (=execute).
......@@ -687,7 +703,7 @@ NdbConnection::doSend()
theSendStatus = sendTC_OP;
theTransactionIsStarted = true;
tNdb->insert_sent_list(this);
return 0;
DBUG_RETURN(0);
}//case
case sendABORT:
case sendABORTfail:{
......@@ -699,18 +715,18 @@ NdbConnection::doSend()
theReturnStatus = ReturnFailure;
}//if
if (sendROLLBACK() == 0) {
return 0;
DBUG_RETURN(0);
}//if
break;
}//case
case sendCOMMITstate:
if (sendCOMMIT() == 0) {
return 0;
DBUG_RETURN(0);
}//if
break;
case sendCompleted:
theNdb->insert_completed_list(this);
return 0;
DBUG_RETURN(0);
default:
ndbout << "Inconsistent theSendStatus = " << theSendStatus << endl;
abort();
......@@ -720,7 +736,7 @@ NdbConnection::doSend()
theReleaseOnClose = true;
theTransactionIsStarted = false;
theCommitStatus = Aborted;
return -1;
DBUG_RETURN(-1);
}//NdbConnection::doSend()
/**************************************************************************
......
......@@ -29,24 +29,31 @@
void
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];
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){
/**
* Release all connections in idle list (for node)
*/
NdbConnection * tNdbCon = theConnectionArray[node_id];
theConnectionArray[node_id] = NULL;
while (tNdbCon != NULL) {
NdbConnection* tempNdbCon = tNdbCon;
tNdbCon = tNdbCon->next();
releaseNdbCon(tempNdbCon);
}//while
}
the_release_ind[node_id] = 0;
}//if
}//for
}
}
DBUG_VOID_RETURN;
}
#if 0
......
......@@ -228,6 +228,7 @@ ErrorBundle ErrorCodes[] = {
{ 4347, IE, "Bad state at alter index" },
{ 4348, IE, "Inconsistency detected at alter index" },
{ 4349, IE, "Inconsistency detected at index usage" },
{ 4350, IE, "Transaction already aborted" },
/**
* Application error
......
......@@ -30,7 +30,7 @@ testSystemRestart \
testTimeout \
testTransactions \
testDeadlock \
test_event ndbapi_slow_select testReadPerf
test_event ndbapi_slow_select testReadPerf testLcp
#flexTimedAsynch
#testBlobs
......@@ -68,6 +68,7 @@ testDeadlock_SOURCES = testDeadlock.cpp
test_event_SOURCES = test_event.cpp
ndbapi_slow_select_SOURCES = slow_select.cpp
testReadPerf_SOURCES = testReadPerf.cpp
testLcp_SOURCES = testLcp.cpp
INCLUDES_LOC = -I$(top_srcdir)/ndb/include/kernel
......
......@@ -2097,47 +2097,50 @@ int Bank::increaseSystemValue(SystemValueId sysValId, Uint64 &value){
*
*/
DBUG_ENTER("Bank::increaseSystemValue");
int check;
NdbConnection* pTrans = m_ndb.startTransaction();
if (pTrans == NULL){
ERR(m_ndb.getNdbError());
return NDBT_FAILED;
DBUG_RETURN(NDBT_FAILED);
}
NdbOperation* pOp = pTrans->getNdbOperation("SYSTEM_VALUES");
if (pOp == NULL) {
ERR(pTrans->getNdbError());
m_ndb.closeTransaction(pTrans);
return NDBT_FAILED;
DBUG_RETURN(NDBT_FAILED);
}
check = pOp->readTupleExclusive();
// check = pOp->readTuple();
if( check == -1 ) {
ERR(pTrans->getNdbError());
m_ndb.closeTransaction(pTrans);
return NDBT_FAILED;
DBUG_RETURN(NDBT_FAILED);
}
check = pOp->equal("SYSTEM_VALUES_ID", sysValId);
if( check == -1 ) {
ERR(pTrans->getNdbError());
m_ndb.closeTransaction(pTrans);
return NDBT_FAILED;
DBUG_RETURN(NDBT_FAILED);
}
NdbRecAttr* valueRec = pOp->getValue("VALUE");
if( valueRec ==NULL ) {
ERR(pTrans->getNdbError());
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);
return NDBT_FAILED;
DBUG_RETURN(NDBT_FAILED);
}
value = valueRec->u_64_value();
......@@ -2147,49 +2150,56 @@ int Bank::increaseSystemValue(SystemValueId sysValId, Uint64 &value){
if (pOp2 == NULL) {
ERR(pTrans->getNdbError());
m_ndb.closeTransaction(pTrans);
return NDBT_FAILED;
DBUG_RETURN(NDBT_FAILED);
}
check = pOp2->updateTuple();
if( check == -1 ) {
ERR(pTrans->getNdbError());
m_ndb.closeTransaction(pTrans);
return NDBT_FAILED;
DBUG_RETURN(NDBT_FAILED);
}
check = pOp2->equal("SYSTEM_VALUES_ID", sysValId);
if( check == -1 ) {
ERR(pTrans->getNdbError());
m_ndb.closeTransaction(pTrans);
return NDBT_FAILED;
DBUG_RETURN(NDBT_FAILED);
}
check = pOp2->setValue("VALUE", value);
if( check == -1 ) {
ERR(pTrans->getNdbError());
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");
if (pOp3 == NULL) {
ERR(pTrans->getNdbError());
m_ndb.closeTransaction(pTrans);
return NDBT_FAILED;
DBUG_RETURN(NDBT_FAILED);
}
check = pOp3->readTuple();
if( check == -1 ) {
ERR(pTrans->getNdbError());
m_ndb.closeTransaction(pTrans);
return NDBT_FAILED;
DBUG_RETURN(NDBT_FAILED);
}
check = pOp3->equal("SYSTEM_VALUES_ID", sysValId);
if( check == -1 ) {
ERR(pTrans->getNdbError());
m_ndb.closeTransaction(pTrans);
return NDBT_FAILED;
DBUG_RETURN(NDBT_FAILED);
}
// Read new value
......@@ -2197,28 +2207,31 @@ int Bank::increaseSystemValue(SystemValueId sysValId, Uint64 &value){
if( valueNewRec ==NULL ) {
ERR(pTrans->getNdbError());
m_ndb.closeTransaction(pTrans);
return NDBT_FAILED;
DBUG_RETURN(NDBT_FAILED);
}
check = pTrans->execute(Commit);
if( check == -1 ) {
ERR(pTrans->getNdbError());
m_ndb.closeTransaction(pTrans);
return NDBT_FAILED;
DBUG_RETURN(NDBT_FAILED);
}
// Check that value updated equals the value we read after the update
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;
m_ndb.closeTransaction(pTrans);
return NDBT_FAILED;
DBUG_RETURN(NDBT_FAILED);
}
m_ndb.closeTransaction(pTrans);
return 0;
DBUG_RETURN(0);
}
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,
else
numTestsOk++;
numTestsExecuted++;
if (result == NDBT_OK && createTable == true){
pDict->dropTable(pTab->getName());
}
delete ctx;
}
}
......
......@@ -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)
{
DBUG_ENTER("mysql_close");
......@@ -2255,20 +2281,7 @@ void STDCALL mysql_close(MYSQL *mysql)
}
mysql_close_free_options(mysql);
mysql_close_free(mysql);
#ifdef MYSQL_CLIENT
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*/
mysql_detach_stmt_list(&mysql->stmts);
#ifndef TO_BE_DELETED
/* free/close slave list */
if (mysql->rpl_pivot)
......
......@@ -70,7 +70,6 @@
Allow users to set compression level.
Add truncate table command.
Implement versioning, should be easy.
Implement optimize so we can fix broken tables.
Allow for errors, find a way to mark bad rows.
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
......@@ -88,6 +87,7 @@ static int archive_init= 0;
/* The file extension */
#define ARZ ".ARZ"
#define ARN ".ARN"
/*
Used for hash table that tracks open tables.
......@@ -117,7 +117,7 @@ static ARCHIVE_SHARE *get_share(const char *table_name, TABLE *table)
if (!archive_init)
{
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))
{
pthread_mutex_unlock(&LOCK_mysql_create_db);
......@@ -205,7 +205,7 @@ static int free_share(ARCHIVE_SHARE *share)
We just implement one additional file extension.
*/
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,
/*
Look at ha_archive::open() for an explanation of the row format.
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)
{
......@@ -380,17 +385,7 @@ int ha_archive::rnd_init(bool scan)
pthread_mutex_lock(&share->mutex);
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);
#endif
share->dirty= FALSE;
}
pthread_mutex_unlock(&share->mutex);
......@@ -504,6 +499,54 @@ int ha_archive::rnd_pos(byte * buf, byte *pos)
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
......
......@@ -112,7 +112,7 @@ class ha_archive: public handler
int external_lock(THD *thd, int lock_type);
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 optimize(THD* thd, HA_CHECK_OPT* check_opt);
THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to,
enum thr_lock_type lock_type);
};
......@@ -122,6 +122,8 @@ static const err_code_mapping err_map[]=
{ 827, HA_ERR_RECORD_FILE_FULL },
{ 832, HA_ERR_RECORD_FILE_FULL },
{ 0, 1 },
{ -1, -1 }
};
......@@ -173,7 +175,7 @@ void ha_ndbcluster::records_update()
DBUG_PRINT("info", ("id=%d, no_uncommitted_rows_count=%d",
((const NDBTAB *)m_table)->getTableId(),
info->no_uncommitted_rows_count));
if (info->records == ~(ha_rows)0)
// if (info->records == ~(ha_rows)0)
{
Uint64 rows;
if(ndb_get_table_statistics(m_ndb, m_tabname, &rows, 0) == 0){
......@@ -246,8 +248,6 @@ int ha_ndbcluster::ndb_err(NdbConnection *trans)
{
int res;
const NdbError err= trans->getNdbError();
if (!err.code)
return 0; // Don't log things to DBUG log if no error
DBUG_ENTER("ndb_err");
ERR_PRINT(err);
......@@ -283,10 +283,11 @@ bool ha_ndbcluster::get_error_message(int error,
DBUG_ENTER("ha_ndbcluster::get_error_message");
DBUG_PRINT("enter", ("error: %d", error));
if (!m_ndb)
Ndb *ndb= ((Thd_ndb*)current_thd->transaction.thd_ndb)->ndb;
if (!ndb)
DBUG_RETURN(false);
const NdbError err= m_ndb->getNdbError(error);
const NdbError err= ndb->getNdbError(error);
bool temporary= err.status==NdbError::TemporaryError;
buf->set(err.message, strlen(err.message), &my_charset_bin);
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)
*/
int ha_ndbcluster::get_ndb_value(NdbOperation *ndb_op, Field *field,
uint fieldnr)
uint fieldnr, byte* buf)
{
DBUG_ENTER("get_ndb_value");
DBUG_PRINT("enter", ("fieldnr: %d flags: %o", fieldnr,
......@@ -524,12 +525,15 @@ int ha_ndbcluster::get_ndb_value(NdbOperation *ndb_op, Field *field,
if (field != NULL)
{
DBUG_ASSERT(buf);
if (ndb_supported_type(field->type()))
{
DBUG_ASSERT(field->ptr != NULL);
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);
}
......@@ -603,7 +607,7 @@ int ha_ndbcluster::get_metadata(const char *path)
DBUG_ENTER("get_metadata");
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());
DBUG_PRINT("info", ("Table schema version: %d", tab->getObjectVersion()));
......@@ -651,8 +655,8 @@ int ha_ndbcluster::get_metadata(const char *path)
if (error)
DBUG_RETURN(error);
// All checks OK, lets use the table
m_table= (void*)tab;
m_table= NULL;
m_table_info= NULL;
DBUG_RETURN(build_index_list(table, ILBP_OPEN));
}
......@@ -767,6 +771,7 @@ void ha_ndbcluster::release_metadata()
DBUG_PRINT("enter", ("m_tabname: %s", m_tabname));
m_table= NULL;
m_table_info= NULL;
// Release index list
for (i= 0; i < MAX_KEY; i++)
......@@ -947,7 +952,7 @@ int ha_ndbcluster::pk_read(const byte *key, uint key_len, byte *buf)
ERR_RETURN(trans->getNdbError());
// 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());
}
else
......@@ -964,7 +969,7 @@ int ha_ndbcluster::pk_read(const byte *key, uint key_len, byte *buf)
if ((thd->query_id == field->query_id) ||
retrieve_all_fields)
{
if (get_ndb_value(op, field, i))
if (get_ndb_value(op, field, i, buf))
ERR_RETURN(trans->getNdbError());
}
else
......@@ -1018,7 +1023,7 @@ int ha_ndbcluster::complemented_pk_read(const byte *old_data, byte *new_data)
if (!(field->flags & PRI_KEY_FLAG) &&
(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());
}
}
......@@ -1081,7 +1086,7 @@ int ha_ndbcluster::unique_index_read(const byte *key,
if ((thd->query_id == field->query_id) ||
(field->flags & PRI_KEY_FLAG))
{
if (get_ndb_value(op, field, i))
if (get_ndb_value(op, field, i, buf))
ERR_RETURN(op->getNdbError());
}
else
......@@ -1480,7 +1485,7 @@ int ha_ndbcluster::define_read_attrs(byte* buf, NdbOperation* op)
(field->flags & PRI_KEY_FLAG) ||
retrieve_all_fields)
{
if (get_ndb_value(op, field, i))
if (get_ndb_value(op, field, i, buf))
ERR_RETURN(op->getNdbError());
}
else
......@@ -1499,7 +1504,7 @@ int ha_ndbcluster::define_read_attrs(byte* buf, NdbOperation* op)
if (!tab->getColumn(hidden_no))
DBUG_RETURN(1);
#endif
if (get_ndb_value(op, NULL, hidden_no))
if (get_ndb_value(op, NULL, hidden_no, NULL))
ERR_RETURN(op->getNdbError());
}
......@@ -1521,6 +1526,11 @@ int ha_ndbcluster::write_row(byte *record)
NdbOperation *op;
int res;
DBUG_ENTER("write_row");
if(m_ignore_dup_key_not_supported)
{
DBUG_RETURN(HA_ERR_WRONG_COMMAND);
}
statistic_increment(ha_write_count,&LOCK_status);
if (table->timestamp_default_now)
......@@ -2385,7 +2395,17 @@ void ha_ndbcluster::info(uint flag)
if (flag & 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)
{
......@@ -2479,14 +2499,20 @@ int ha_ndbcluster::extra(enum ha_extra_function operation)
break;
case HA_EXTRA_IGNORE_DUP_KEY: /* Dup keys don't rollback everything*/
DBUG_PRINT("info", ("HA_EXTRA_IGNORE_DUP_KEY"));
DBUG_PRINT("info", ("Turning ON use of write instead of insert"));
m_use_write= TRUE;
if (current_thd->lex->sql_command == SQLCOM_REPLACE)
{
DBUG_PRINT("info", ("Turning ON use of write instead of insert"));
m_use_write= TRUE;
} else
{
m_ignore_dup_key_not_supported= TRUE;
}
break;
case 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"));
m_use_write= false;
m_ignore_dup_key_not_supported= false;
break;
case HA_EXTRA_RETRIEVE_ALL_COLS: /* Retrieve all columns, not just those
where field->query_id is the same as
......@@ -2766,6 +2792,16 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type)
// Start of transaction
retrieve_all_fields= FALSE;
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);
}
else
......@@ -2788,6 +2824,8 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type)
thd->transaction.stmt.ndb_tid= 0;
}
}
m_table= NULL;
m_table_info= NULL;
if (m_active_trans)
DBUG_PRINT("warning", ("m_active_trans != NULL"));
if (m_active_cursor)
......@@ -3273,6 +3311,7 @@ int ha_ndbcluster::alter_table_name(const char *from, const char *to)
ERR_RETURN(dict->getNdbError());
m_table= NULL;
m_table_info= NULL;
DBUG_RETURN(0);
}
......@@ -3364,6 +3403,7 @@ ha_ndbcluster::ha_ndbcluster(TABLE *table_arg):
HA_NO_PREFIX_CHAR_KEYS),
m_share(0),
m_use_write(false),
m_ignore_dup_key_not_supported(false),
retrieve_all_fields(FALSE),
rows_to_insert(1),
rows_inserted(0),
......
......@@ -211,7 +211,7 @@ class ha_ndbcluster: public handler
int set_ndb_key(NdbOperation*, Field *field,
uint fieldnr, const byte* field_ptr);
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);
int get_ndb_blobs_value(NdbBlob *last_ndb_blob);
int set_primary_key(NdbOperation *op, const byte *key);
......@@ -245,6 +245,7 @@ class ha_ndbcluster: public handler
typedef union { NdbRecAttr *rec; NdbBlob *blob; void *ptr; } NdbValue;
NdbValue m_value[NDB_MAX_ATTRIBUTES_IN_TABLE];
bool m_use_write;
bool m_ignore_dup_key_not_supported;
bool retrieve_all_fields;
ha_rows rows_to_insert;
ha_rows rows_inserted;
......
......@@ -328,6 +328,7 @@ void THD::change_user(void)
cleanup();
cleanup_done= 0;
init();
stmt_map.reset();
hash_init(&user_vars, &my_charset_bin, USER_VARS_HASH_SIZE, 0, 0,
(hash_get_key) get_var_key,
(hash_free_key) free_user_var, 0);
......
......@@ -566,7 +566,7 @@ class Statement: public Item_arena
assignment in Statement::Statement)
Non-empty statement names are unique too: attempt to insert a new statement
with duplicate name causes older statement to be deleted
Statements are auto-deleted when they are removed from the map and when the
map is deleted.
*/
......@@ -575,7 +575,7 @@ class Statement_map
{
public:
Statement_map();
int insert(Statement *statement);
Statement *find_by_name(LEX_STRING *name)
......@@ -608,11 +608,18 @@ class Statement_map
}
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()
{
hash_free(&st_hash);
hash_free(&names_hash);
hash_free(&st_hash);
}
private:
HASH st_hash;
......
......@@ -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
*/
......@@ -10694,6 +10722,8 @@ int main(int argc, char **argv)
test_bug5399(); /* check that statement id uniquely identifies
statement */
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
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