Add support for Gemini table handler, Monty has checked and approved
Fix bug when read return error
This commit is contained in:
parent
3c48448042
commit
d145a6b97e
@ -1 +1 @@
|
||||
monty@tik.mysql.fi
|
||||
mikef@nslinux.bedford.progress.com
|
||||
|
@ -117,6 +117,9 @@
|
||||
/* POSIX readdir_r */
|
||||
#undef HAVE_READDIR_R
|
||||
|
||||
/* Have Gemini db installed */
|
||||
#undef HAVE_GEMINI_DB
|
||||
|
||||
/* POSIX sigwait */
|
||||
#undef HAVE_SIGWAIT
|
||||
|
||||
|
86
acinclude.m4
86
acinclude.m4
@ -941,6 +941,92 @@ dnl ---------------------------------------------------------------------------
|
||||
dnl END OF MYSQL_CHECK_INNOBASE SECTION
|
||||
dnl ---------------------------------------------------------------------------
|
||||
|
||||
dnl ---------------------------------------------------------------------------
|
||||
dnl Macro: MYSQL_CHECK_GEMINI
|
||||
dnl Sets HAVE_GEMINI_DB if --with-gemini is used
|
||||
dnl ---------------------------------------------------------------------------
|
||||
|
||||
AC_DEFUN([MYSQL_CHECK_GEMINI], [
|
||||
AC_ARG_WITH([gemini],
|
||||
[\
|
||||
--with-gemini[=DIR] Use Gemini DB located in DIR],
|
||||
[gemini="$withval"],
|
||||
[gemini=no])
|
||||
|
||||
AC_MSG_CHECKING([for Gemini DB])
|
||||
|
||||
dnl SORT OUT THE SUPPLIED ARGUMENTS TO DETERMINE WHAT TO DO
|
||||
dnl echo "DBG_GEM1: gemini='$gemini'"
|
||||
have_gemini_db=no
|
||||
gemini_includes=
|
||||
gemini_libs=
|
||||
case "$gemini" in
|
||||
no )
|
||||
AC_MSG_RESULT([Not using Gemini DB])
|
||||
;;
|
||||
yes | default | *)
|
||||
have_gemini_db="yes"
|
||||
gemini_includes="-I../gemini/incl -I../gemini"
|
||||
gemini_libs="\
|
||||
../gemini/api/libapi.a\
|
||||
../gemini/db/libdb.a\
|
||||
../gemini/dbut/libdbut.a\
|
||||
../gemini/vst/libvst.a"
|
||||
AC_MSG_RESULT([Using Gemini DB])
|
||||
;;
|
||||
esac
|
||||
|
||||
AC_SUBST(gemini_includes)
|
||||
AC_SUBST(gemini_libs)
|
||||
])
|
||||
|
||||
dnl ---------------------------------------------------------------------------
|
||||
dnl END OF MYSQL_CHECK_GEMINI SECTION
|
||||
dnl ---------------------------------------------------------------------------
|
||||
|
||||
dnl ---------------------------------------------------------------------------
|
||||
dnl Macro: MYSQL_CHECK_GEMINI
|
||||
dnl Sets HAVE_GEMINI_DB if --with-gemini is used
|
||||
dnl ---------------------------------------------------------------------------
|
||||
|
||||
AC_DEFUN([MYSQL_CHECK_GEMINI], [
|
||||
AC_ARG_WITH([gemini],
|
||||
[\
|
||||
--with-gemini[=DIR] Use Gemini DB located in DIR],
|
||||
[gemini="$withval"],
|
||||
[gemini=no])
|
||||
|
||||
AC_MSG_CHECKING([for Gemini DB])
|
||||
|
||||
dnl SORT OUT THE SUPPLIED ARGUMENTS TO DETERMINE WHAT TO DO
|
||||
dnl echo "DBG_GEM1: gemini='$gemini'"
|
||||
have_gemini_db=no
|
||||
gemini_includes=
|
||||
gemini_libs=
|
||||
case "$gemini" in
|
||||
no )
|
||||
AC_MSG_RESULT([Not using Gemini DB])
|
||||
;;
|
||||
yes | default | *)
|
||||
have_gemini_db="yes"
|
||||
gemini_includes="-I../gemini/incl -I../gemini"
|
||||
gemini_libs="\
|
||||
../gemini/api/libapi.a\
|
||||
../gemini/db/libdb.a\
|
||||
../gemini/dbut/libdbut.a\
|
||||
../gemini/vst/libvst.a"
|
||||
AC_MSG_RESULT([Using Gemini DB])
|
||||
;;
|
||||
esac
|
||||
|
||||
AC_SUBST(gemini_includes)
|
||||
AC_SUBST(gemini_libs)
|
||||
])
|
||||
|
||||
dnl ---------------------------------------------------------------------------
|
||||
dnl END OF MYSQL_CHECK_GEMINI SECTION
|
||||
dnl ---------------------------------------------------------------------------
|
||||
|
||||
dnl ---------------------------------------------------------------------------
|
||||
dnl Got this from the GNU tar 1.13.11 distribution
|
||||
dnl by Paul Eggert <eggert@twinsun.com>
|
||||
|
@ -211,6 +211,8 @@ enum ha_base_keytype {
|
||||
#define HA_ERR_WRONG_TABLE_DEF 143
|
||||
#define HA_ERR_CRASHED_ON_REPAIR 144 /* Last (automatic?) repair failed */
|
||||
#define HA_ERR_CRASHED_ON_USAGE 145 /* Table must be repaired */
|
||||
#define HA_ERR_LOCK_WAIT_TIMEOUT 146
|
||||
#define HA_ERR_LOCK_TABLE_FULL 147
|
||||
|
||||
/* Other constants */
|
||||
|
||||
|
2
mysql-test/include/have_gemini.inc
Normal file
2
mysql-test/include/have_gemini.inc
Normal file
@ -0,0 +1,2 @@
|
||||
-- require r/have_gemini.require
|
||||
show variables like "have_gemini";
|
364
mysql-test/r/gemini.result
Normal file
364
mysql-test/r/gemini.result
Normal file
@ -0,0 +1,364 @@
|
||||
id code name
|
||||
1 1 Tim
|
||||
2 1 Monty
|
||||
3 2 David
|
||||
4 2 Erik
|
||||
5 3 Sasha
|
||||
6 3 Jeremy
|
||||
7 4 Matt
|
||||
id code name
|
||||
2 1 Monty
|
||||
3 2 David
|
||||
4 2 Erik
|
||||
5 3 Sasha
|
||||
6 3 Jeremy
|
||||
7 4 Matt
|
||||
8 1 Sinisa
|
||||
id code name
|
||||
3 2 David
|
||||
4 2 Erik
|
||||
5 3 Sasha
|
||||
6 3 Jeremy
|
||||
7 4 Matt
|
||||
8 1 Sinisa
|
||||
12 1 Ralph
|
||||
id parent_id level
|
||||
8 102 2
|
||||
9 102 2
|
||||
15 102 2
|
||||
id parent_id level
|
||||
1001 100 0
|
||||
1003 101 1
|
||||
1004 101 1
|
||||
1008 102 2
|
||||
1009 102 2
|
||||
1017 103 2
|
||||
1022 104 2
|
||||
1024 104 2
|
||||
1028 105 2
|
||||
1029 105 2
|
||||
1030 105 2
|
||||
1031 106 2
|
||||
1032 106 2
|
||||
1033 106 2
|
||||
1203 107 2
|
||||
1202 107 2
|
||||
1020 103 2
|
||||
1157 100 0
|
||||
1193 105 2
|
||||
1040 107 2
|
||||
1002 101 1
|
||||
1015 102 2
|
||||
1006 101 1
|
||||
1034 106 2
|
||||
1035 106 2
|
||||
1016 103 2
|
||||
1007 101 1
|
||||
1036 107 2
|
||||
1018 103 2
|
||||
1026 105 2
|
||||
1027 105 2
|
||||
1183 104 2
|
||||
1038 107 2
|
||||
1025 105 2
|
||||
1037 107 2
|
||||
1021 104 2
|
||||
1019 103 2
|
||||
1005 101 1
|
||||
1179 105 2
|
||||
id parent_id level
|
||||
1001 100 0
|
||||
1003 101 1
|
||||
1004 101 1
|
||||
1008 102 2
|
||||
1010 102 2
|
||||
1017 103 2
|
||||
1023 104 2
|
||||
1024 104 2
|
||||
1028 105 2
|
||||
1029 105 2
|
||||
1030 105 2
|
||||
1031 106 2
|
||||
1032 106 2
|
||||
1033 106 2
|
||||
1204 107 2
|
||||
1203 107 2
|
||||
1020 103 2
|
||||
1158 100 0
|
||||
1194 105 2
|
||||
1041 107 2
|
||||
1002 101 1
|
||||
1015 102 2
|
||||
1006 101 1
|
||||
1034 106 2
|
||||
1035 106 2
|
||||
1016 103 2
|
||||
1007 101 1
|
||||
1036 107 2
|
||||
1018 103 2
|
||||
1026 105 2
|
||||
1027 105 2
|
||||
1184 104 2
|
||||
1039 107 2
|
||||
1025 105 2
|
||||
1038 107 2
|
||||
1022 104 2
|
||||
1019 103 2
|
||||
1005 101 1
|
||||
1180 105 2
|
||||
id parent_id level
|
||||
1008 102 2
|
||||
1010 102 2
|
||||
1015 102 2
|
||||
table type possible_keys key key_len ref rows Extra
|
||||
t1 ref level level 1 const 6 where used; Using index
|
||||
table type possible_keys key key_len ref rows Extra
|
||||
t1 ref level level 1 const 6 where used
|
||||
table type possible_keys key key_len ref rows Extra
|
||||
t1 ref level level 1 const 6 where used
|
||||
level id
|
||||
1 1003
|
||||
1 1004
|
||||
1 1002
|
||||
1 1006
|
||||
1 1007
|
||||
1 1005
|
||||
level id parent_id
|
||||
1 1003 101
|
||||
1 1004 101
|
||||
1 1002 101
|
||||
1 1006 101
|
||||
1 1007 101
|
||||
1 1005 101
|
||||
gesuchnr benutzer_id
|
||||
1 1
|
||||
2 1
|
||||
a
|
||||
2
|
||||
user_id name phone ref_email detail
|
||||
10292 sanjeev 29153373 sansh777@hotmail.com xxx
|
||||
10292 shirish 2333604 shirish@yahoo.com ddsds
|
||||
10292 sonali 323232 sonali@bolly.com filmstar
|
||||
user_id name phone ref_email detail
|
||||
10292 sanjeev 29153373 sansh777@hotmail.com xxx
|
||||
10292 shirish 2333604 shirish@yahoo.com ddsds
|
||||
10292 sonali 323232 sonali@bolly.com filmstar
|
||||
user_id name phone ref_email detail
|
||||
10292 sanjeev 29153373 sansh777@hotmail.com xxx
|
||||
10292 shirish 2333604 shirish@yahoo.com ddsds
|
||||
10292 sonali 323232 sonali@bolly.com filmstar
|
||||
10293 shirish 2333604 shirish@yahoo.com ddsds
|
||||
user_id name phone ref_email detail
|
||||
10293 shirish 2333604 shirish@yahoo.com ddsds
|
||||
user_id name phone ref_email detail
|
||||
10291 sanjeev 29153373 sansh777@hotmail.com xxx
|
||||
a b
|
||||
1 3
|
||||
2 3
|
||||
3 3
|
||||
a b
|
||||
1 3
|
||||
2 3
|
||||
3 3
|
||||
a b
|
||||
a b
|
||||
1 3
|
||||
2 3
|
||||
3 3
|
||||
a b
|
||||
1 3
|
||||
2 3
|
||||
3 3
|
||||
id ggid email passwd
|
||||
1 test1 xxx
|
||||
id ggid email passwd
|
||||
1 test1 xxx
|
||||
id ggid email passwd
|
||||
2 test2 yyy
|
||||
id parent_id level
|
||||
8 102 2
|
||||
9 102 2
|
||||
15 102 2
|
||||
id parent_id level
|
||||
1001 100 0
|
||||
1003 101 1
|
||||
1004 101 1
|
||||
1008 102 2
|
||||
1024 102 2
|
||||
1017 103 2
|
||||
1022 104 2
|
||||
1024 104 2
|
||||
1028 105 2
|
||||
1029 105 2
|
||||
1030 105 2
|
||||
1031 106 2
|
||||
1032 106 2
|
||||
1033 106 2
|
||||
1203 107 2
|
||||
1202 107 2
|
||||
1020 103 2
|
||||
1157 100 0
|
||||
1193 105 2
|
||||
1040 107 2
|
||||
1002 101 1
|
||||
1015 102 2
|
||||
1006 101 1
|
||||
1034 106 2
|
||||
1035 106 2
|
||||
1016 103 2
|
||||
1007 101 1
|
||||
1036 107 2
|
||||
1018 103 2
|
||||
1026 105 2
|
||||
1027 105 2
|
||||
1183 104 2
|
||||
1038 107 2
|
||||
1025 105 2
|
||||
1037 107 2
|
||||
1021 104 2
|
||||
1019 103 2
|
||||
1005 101 1
|
||||
1179 105 2
|
||||
id parent_id level
|
||||
1002 100 0
|
||||
1004 101 1
|
||||
1005 101 1
|
||||
1009 102 2
|
||||
1025 102 2
|
||||
1018 103 2
|
||||
1023 104 2
|
||||
1025 104 2
|
||||
1029 105 2
|
||||
1030 105 2
|
||||
1031 105 2
|
||||
1032 106 2
|
||||
1033 106 2
|
||||
1034 106 2
|
||||
1204 107 2
|
||||
1203 107 2
|
||||
1021 103 2
|
||||
1158 100 0
|
||||
1194 105 2
|
||||
1041 107 2
|
||||
1003 101 1
|
||||
1016 102 2
|
||||
1007 101 1
|
||||
1035 106 2
|
||||
1036 106 2
|
||||
1017 103 2
|
||||
1008 101 1
|
||||
1037 107 2
|
||||
1019 103 2
|
||||
1027 105 2
|
||||
1028 105 2
|
||||
1184 104 2
|
||||
1039 107 2
|
||||
1026 105 2
|
||||
1038 107 2
|
||||
1022 104 2
|
||||
1020 103 2
|
||||
1006 101 1
|
||||
1180 105 2
|
||||
id parent_id level
|
||||
1009 102 2
|
||||
1025 102 2
|
||||
1016 102 2
|
||||
table type possible_keys key key_len ref rows Extra
|
||||
t1 ref level level 1 const 6 where used; Using index
|
||||
level id
|
||||
1 1004
|
||||
1 1005
|
||||
1 1003
|
||||
1 1007
|
||||
1 1008
|
||||
1 1006
|
||||
level id parent_id
|
||||
1 1004 101
|
||||
1 1005 101
|
||||
1 1003 101
|
||||
1 1007 101
|
||||
1 1008 101
|
||||
1 1006 101
|
||||
level id
|
||||
1 1003
|
||||
1 1004
|
||||
1 1005
|
||||
1 1006
|
||||
1 1007
|
||||
1 1008
|
||||
id parent_id level
|
||||
1002 100 0
|
||||
1009 102 2
|
||||
1025 102 2
|
||||
1018 103 2
|
||||
1023 104 2
|
||||
1025 104 2
|
||||
1029 105 2
|
||||
1030 105 2
|
||||
1031 105 2
|
||||
1032 106 2
|
||||
1033 106 2
|
||||
1034 106 2
|
||||
1204 107 2
|
||||
1203 107 2
|
||||
1021 103 2
|
||||
1158 100 0
|
||||
1194 105 2
|
||||
1041 107 2
|
||||
1016 102 2
|
||||
1035 106 2
|
||||
1036 106 2
|
||||
1017 103 2
|
||||
1037 107 2
|
||||
1019 103 2
|
||||
1027 105 2
|
||||
1028 105 2
|
||||
1184 104 2
|
||||
1039 107 2
|
||||
1026 105 2
|
||||
1038 107 2
|
||||
1022 104 2
|
||||
1020 103 2
|
||||
1180 105 2
|
||||
count(*)
|
||||
1
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
test for rollback
|
||||
test for rollback
|
||||
n after rollback
|
||||
4 after rollback
|
||||
n after commit
|
||||
4 after commit
|
||||
5 after commit
|
||||
n after commit
|
||||
4 after commit
|
||||
5 after commit
|
||||
6 after commit
|
||||
n
|
||||
4
|
||||
5
|
||||
6
|
||||
7
|
||||
afterbegin_id afterbegin_nom
|
||||
1 first
|
||||
2 hamdouni
|
||||
afterrollback_id afterrollback_nom
|
||||
1 first
|
||||
afterautocommit0_id afterautocommit0_nom
|
||||
1 first
|
||||
3 mysql
|
||||
afterrollback_id afterrollback_nom
|
||||
1 first
|
||||
id val
|
||||
id val
|
||||
pippo 12
|
||||
id val
|
||||
ID NAME
|
||||
1 Jochen
|
||||
_userid
|
||||
marc@anyware.co.uk
|
||||
_userid
|
||||
marc@anyware.co.uk
|
2
mysql-test/r/have_gemini.require
Normal file
2
mysql-test/r/have_gemini.require
Normal file
@ -0,0 +1,2 @@
|
||||
Variable_name Value
|
||||
have_gemini YES
|
340
mysql-test/t/gemini.test
Normal file
340
mysql-test/t/gemini.test
Normal file
@ -0,0 +1,340 @@
|
||||
-- source include/have_gemini.inc
|
||||
|
||||
#
|
||||
# Small basic test with ignore
|
||||
#
|
||||
|
||||
drop table if exists t1;
|
||||
create table t1 (id int unsigned not null auto_increment, code tinyint unsigned not null, name char(20) not null, primary key (id), key (code), unique (name)) type=gemini;
|
||||
|
||||
insert into t1 (code, name) values (1, 'Tim'), (1, 'Monty'), (2, 'David'), (2, 'Erik'), (3, 'Sasha'), (3, 'Jeremy'), (4, 'Matt');
|
||||
select id, code, name from t1 order by id;
|
||||
|
||||
update ignore t1 set id = 8, name = 'Sinisa' where id < 3;
|
||||
select id, code, name from t1 order by id;
|
||||
update ignore t1 set id = id + 10, name = 'Ralph' where id < 4;
|
||||
select id, code, name from t1 order by id;
|
||||
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# A bit bigger test
|
||||
#
|
||||
|
||||
CREATE TABLE t1 (
|
||||
id int(11) NOT NULL auto_increment,
|
||||
parent_id int(11) DEFAULT '0' NOT NULL,
|
||||
level tinyint(4) DEFAULT '0' NOT NULL,
|
||||
PRIMARY KEY (id),
|
||||
KEY parent_id (parent_id),
|
||||
KEY level (level)
|
||||
) type=gemini;
|
||||
INSERT INTO t1 VALUES (1,0,0),(3,1,1),(4,1,1),(8,2,2),(9,2,2),(17,3,2),(22,4,2),(24,4,2),(28,5,2),(29,5,2),(30,5,2),(31,6,2),(32,6,2),(33,6,2),(203,7,2),(202,7,2),(20,3,2),(157,0,0),(193,5,2),(40,7,2),(2,1,1),(15,2,2),(6,1,1),(34,6,2),(35,6,2),(16,3,2),(7,1,1),(36,7,2),(18,3,2),(26,5,2),(27,5,2),(183,4,2),(38,7,2),(25,5,2),(37,7,2),(21,4,2),(19,3,2),(5,1,1),(179,5,2);
|
||||
update t1 set parent_id=parent_id+100;
|
||||
select * from t1 where parent_id=102;
|
||||
update t1 set id=id+1000;
|
||||
!$1062 update t1 set id=1024 where id=1009;
|
||||
select * from t1;
|
||||
update ignore t1 set id=id+1; # This will change all rows
|
||||
select * from t1;
|
||||
update ignore t1 set id=1023 where id=1010;
|
||||
select * from t1 where parent_id=102;
|
||||
explain select level from t1 where level=1;
|
||||
explain select level,id from t1 where level=1;
|
||||
explain select level,id,parent_id from t1 where level=1;
|
||||
select level,id from t1 where level=1;
|
||||
select level,id,parent_id from t1 where level=1;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Test replace
|
||||
#
|
||||
|
||||
CREATE TABLE t1 (
|
||||
gesuchnr int(11) DEFAULT '0' NOT NULL,
|
||||
benutzer_id int(11) DEFAULT '0' NOT NULL,
|
||||
PRIMARY KEY (gesuchnr,benutzer_id)
|
||||
) type=gemini;
|
||||
|
||||
replace into t1 (gesuchnr,benutzer_id) values (2,1);
|
||||
replace into t1 (gesuchnr,benutzer_id) values (1,1);
|
||||
replace into t1 (gesuchnr,benutzer_id) values (1,1);
|
||||
select * from t1;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# test delete using hidden_primary_key
|
||||
#
|
||||
|
||||
create table t1 (a int) type=gemini;
|
||||
insert into t1 values (1), (2);
|
||||
delete from t1 where a = 1;
|
||||
select * from t1;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Test auto_increment on sub key
|
||||
#
|
||||
|
||||
#create table t1 (a char(10) not null, b int not null auto_increment, primary key(a,b)) type=gemini;
|
||||
#insert into t1 values ("a",1),("b",2),("a",2),("c",1);
|
||||
#insert into t1 values ("a",NULL),("b",NULL),("c",NULL),("e",NULL);
|
||||
#insert into t1 (a) values ("a"),("b"),("c"),("d");
|
||||
#insert into t1 (a) values ('k'),('d');
|
||||
#insert into t1 (a) values ("a");
|
||||
#insert into t1 values ("d",last_insert_id());
|
||||
#select * from t1;
|
||||
#drop table t1;
|
||||
|
||||
#
|
||||
# Test when reading on part of unique key
|
||||
#
|
||||
CREATE TABLE t1 (
|
||||
user_id int(10) DEFAULT '0' NOT NULL,
|
||||
name varchar(100),
|
||||
phone varchar(100),
|
||||
ref_email varchar(100) DEFAULT '' NOT NULL,
|
||||
detail varchar(200),
|
||||
PRIMARY KEY (user_id,ref_email)
|
||||
)type=gemini;
|
||||
|
||||
INSERT INTO t1 VALUES (10292,'sanjeev','29153373','sansh777@hotmail.com','xxx'),(10292,'shirish','2333604','shirish@yahoo.com','ddsds'),(10292,'sonali','323232','sonali@bolly.com','filmstar');
|
||||
select * from t1 where user_id=10292;
|
||||
INSERT INTO t1 VALUES (10291,'sanjeev','29153373','sansh777@hotmail.com','xxx'),(10293,'shirish','2333604','shirish@yahoo.com','ddsds');
|
||||
select * from t1 where user_id=10292;
|
||||
select * from t1 where user_id>=10292;
|
||||
select * from t1 where user_id>10292;
|
||||
select * from t1 where user_id<10292;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Test that keys are created in right order
|
||||
# - Needs ANALYZE TABLE to work - MikeF 2/12/01
|
||||
#
|
||||
#CREATE TABLE t1 (a int not null, b int not null,c int not null,
|
||||
#key(a),primary key(a,b), unique(c),key(a),unique(b)) type = gemini;
|
||||
#show index from t1;
|
||||
#drop table t1;
|
||||
|
||||
#
|
||||
# Test of ALTER TABLE and gemini tables
|
||||
#
|
||||
|
||||
#create table t1 (col1 int not null, col2 char(4) not null, primary key(col1));
|
||||
#alter table t1 type=gemini;
|
||||
#insert into t1 values ('1','1'),('5','2'),('2','3'),('3','4'),('4','4');
|
||||
#select * from t1;
|
||||
#update t1 set col2='7' where col1='4';
|
||||
#select * from t1;
|
||||
#alter table t1 add co3 int not null;
|
||||
#select * from t1;
|
||||
#update t1 set col2='9' where col1='2';
|
||||
#select * from t1;
|
||||
#drop table t1;
|
||||
|
||||
#
|
||||
# INSERT INTO gemini tables
|
||||
#
|
||||
|
||||
create table t1 (a int not null , b int, primary key (a)) type = gemini;
|
||||
create table t2 (a int not null , b int, primary key (a)) type = myisam;
|
||||
insert into t1 VALUES (1,3) , (2,3), (3,3);
|
||||
select * from t1;
|
||||
insert into t2 select * from t1;
|
||||
select * from t2;
|
||||
delete from t1 where b = 3;
|
||||
select * from t1;
|
||||
insert into t1 select * from t2;
|
||||
select * from t1;
|
||||
select * from t2;
|
||||
drop table t1,t2;
|
||||
|
||||
#
|
||||
# Search on unique key
|
||||
#
|
||||
|
||||
CREATE TABLE t1 (
|
||||
id int(11) NOT NULL auto_increment,
|
||||
ggid varchar(32) binary DEFAULT '' NOT NULL,
|
||||
email varchar(64) DEFAULT '' NOT NULL,
|
||||
passwd varchar(32) binary DEFAULT '' NOT NULL,
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE ggid (ggid)
|
||||
) TYPE=gemini;
|
||||
|
||||
insert into t1 (ggid,passwd) values ('test1','xxx');
|
||||
insert into t1 (ggid,passwd) values ('test2','yyy');
|
||||
|
||||
select * from t1 where ggid='test1';
|
||||
select * from t1 where passwd='xxx';
|
||||
select * from t1 where id=2;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# ORDER BY on not primary key
|
||||
#
|
||||
|
||||
#CREATE TABLE t1 (
|
||||
# user_name varchar(12),
|
||||
#password text,
|
||||
#subscribed char(1),
|
||||
#user_id int(11) DEFAULT '0' NOT NULL,
|
||||
#quota bigint(20),
|
||||
#weight double,
|
||||
#access_date date,
|
||||
#access_time time,
|
||||
#approved datetime,
|
||||
#dummy_primary_key int(11) NOT NULL auto_increment,
|
||||
#PRIMARY KEY (dummy_primary_key)
|
||||
#) TYPE=gemini;
|
||||
#INSERT INTO t1 VALUES ('user_0','somepassword','N',0,0,0,'2000-09-07','23:06:59','2000-09-07 23:06:59',1);
|
||||
#INSERT INTO t1 VALUES ('user_1','somepassword','Y',1,1,1,'2000-09-07','23:06:59','2000-09-07 23:06:59',2);
|
||||
#INSERT INTO t1 VALUES ('user_2','somepassword','N',2,2,1.4142135623731,'2000-09-07','23:06:59','2000-09-07 23:06:59',3);
|
||||
#INSERT INTO t1 VALUES ('user_3','somepassword','Y',3,3,1.7320508075689,'2000-09-07','23:06:59','2000-09-07 23:06:59',4);
|
||||
#INSERT INTO t1 VALUES ('user_4','somepassword','N',4,4,2,'2000-09-07','23:06:59','2000-09-07 23:06:59',5);
|
||||
#select user_name, password , subscribed, user_id, quota, weight, access_date, access_time, approved, dummy_primary_key from t1 order by user_name;
|
||||
#drop table t1;
|
||||
|
||||
#
|
||||
# Testing of tables without primary keys
|
||||
#
|
||||
|
||||
CREATE TABLE t1 (
|
||||
id int(11) NOT NULL auto_increment,
|
||||
parent_id int(11) DEFAULT '0' NOT NULL,
|
||||
level tinyint(4) DEFAULT '0' NOT NULL,
|
||||
KEY (id),
|
||||
KEY parent_id (parent_id),
|
||||
KEY level (level)
|
||||
) type=gemini;
|
||||
INSERT INTO t1 VALUES (1,0,0),(3,1,1),(4,1,1),(8,2,2),(9,2,2),(17,3,2),(22,4,2),(24,4,2),(28,5,2),(29,5,2),(30,5,2),(31,6,2),(32,6,2),(33,6,2),(203,7,2),(202,7,2),(20,3,2),(157,0,0),(193,5,2),(40,7,2),(2,1,1),(15,2,2),(6,1,1),(34,6,2),(35,6,2),(16,3,2),(7,1,1),(36,7,2),(18,3,2),(26,5,2),(27,5,2),(183,4,2),(38,7,2),(25,5,2),(37,7,2),(21,4,2),(19,3,2),(5,1,1);
|
||||
INSERT INTO t1 values (179,5,2);
|
||||
update t1 set parent_id=parent_id+100;
|
||||
select * from t1 where parent_id=102;
|
||||
update t1 set id=id+1000;
|
||||
update t1 set id=1024 where id=1009;
|
||||
select * from t1;
|
||||
update ignore t1 set id=id+1; # This will change all rows
|
||||
select * from t1;
|
||||
update ignore t1 set id=1023 where id=1010;
|
||||
select * from t1 where parent_id=102;
|
||||
explain select level from t1 where level=1;
|
||||
select level,id from t1 where level=1;
|
||||
select level,id,parent_id from t1 where level=1;
|
||||
select level,id from t1 where level=1 order by id;
|
||||
delete from t1 where level=1;
|
||||
select * from t1;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Test of index only reads
|
||||
#
|
||||
CREATE TABLE t1 (
|
||||
sca_code char(6) NOT NULL,
|
||||
cat_code char(6) NOT NULL,
|
||||
sca_desc varchar(50),
|
||||
lan_code char(2) NOT NULL,
|
||||
sca_pic varchar(100),
|
||||
sca_sdesc varchar(50),
|
||||
sca_sch_desc varchar(16),
|
||||
PRIMARY KEY (sca_code, cat_code, lan_code)
|
||||
) type = gemini ;
|
||||
|
||||
INSERT INTO t1 ( sca_code, cat_code, sca_desc, lan_code, sca_pic, sca_sdesc, sca_sch_desc) VALUES ( 'PD', 'J', 'PENDANT', 'EN', NULL, NULL, 'PENDANT'),( 'RI', 'J', 'RING', 'EN', NULL, NULL, 'RING');
|
||||
select count(*) from t1 where sca_code = 'PD';
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Test of opening table twice
|
||||
#
|
||||
CREATE TABLE t1 (a int not null, primary key (a)) type=gemini;
|
||||
insert into t1 values(1),(2),(3);
|
||||
select t1.a from t1 natural join t1 as t2 order by t1.a;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Test rollback
|
||||
#
|
||||
|
||||
select "test for rollback";
|
||||
create table t1 (n int not null primary key) type=gemini;
|
||||
set autocommit=0;
|
||||
insert into t1 values (4);
|
||||
commit;
|
||||
insert into t1 values (5);
|
||||
rollback;
|
||||
select n, "after rollback" from t1;
|
||||
insert into t1 values (5);
|
||||
commit;
|
||||
select n, "after commit" from t1;
|
||||
commit;
|
||||
insert into t1 values (6);
|
||||
!$1062 insert into t1 values (4);
|
||||
commit;
|
||||
select n, "after commit" from t1;
|
||||
set autocommit=1;
|
||||
insert into t1 values (7);
|
||||
!$1062 insert into t1 values (4);
|
||||
select n from t1;
|
||||
# nop
|
||||
rollback;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Testing transactions
|
||||
#
|
||||
|
||||
create table t1 ( id int NOT NULL PRIMARY KEY, nom varchar(64)) type=gemini;
|
||||
insert into t1 values(1,'first');
|
||||
begin;
|
||||
insert into t1 values(2,'hamdouni');
|
||||
select id as afterbegin_id,nom as afterbegin_nom from t1;
|
||||
rollback;
|
||||
select id as afterrollback_id,nom as afterrollback_nom from t1;
|
||||
set autocommit=0;
|
||||
insert into t1 values(3,'mysql');
|
||||
select id as afterautocommit0_id,nom as afterautocommit0_nom from t1;
|
||||
rollback;
|
||||
select id as afterrollback_id,nom as afterrollback_nom from t1;
|
||||
set autocommit=1;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Simple not autocommit test
|
||||
#
|
||||
|
||||
CREATE TABLE t1 (id char(8) not null primary key, val int not null) type=gemini;
|
||||
insert into t1 values ('pippo', 12);
|
||||
!$1062 insert into t1 values ('pippo', 12); # Gives error
|
||||
delete from t1;
|
||||
delete from t1 where id = 'pippo';
|
||||
select * from t1;
|
||||
|
||||
insert into t1 values ('pippo', 12);
|
||||
set autocommit=0;
|
||||
delete from t1;
|
||||
rollback;
|
||||
select * from t1;
|
||||
delete from t1;
|
||||
commit;
|
||||
select * from t1;
|
||||
drop table t1;
|
||||
set autocommit=1;
|
||||
|
||||
#
|
||||
# The following simple tests failed at some point
|
||||
#
|
||||
|
||||
CREATE TABLE t1 (ID INTEGER NOT NULL PRIMARY KEY, NAME VARCHAR(64)) TYPE=gemini;
|
||||
INSERT INTO t1 VALUES (1, 'Jochen');
|
||||
select * from t1;
|
||||
drop table t1;
|
||||
|
||||
CREATE TABLE t1 ( _userid VARCHAR(60) NOT NULL PRIMARY KEY) TYPE=gemini;
|
||||
set autocommit=0;
|
||||
INSERT INTO t1 SET _userid='marc@anyware.co.uk';
|
||||
COMMIT;
|
||||
SELECT * FROM t1;
|
||||
SELECT _userid FROM t1 WHERE _userid='marc@anyware.co.uk';
|
||||
drop table t1;
|
||||
set autocommit=1;
|
@ -1377,7 +1377,7 @@ INSERT INTO t3 (period,name,companynr,price,price2) VALUES (1008,"tucked",311,23
|
||||
INSERT INTO t3 (period,name,companynr,price,price2) VALUES (1009,"gems",447,2374834,9872392);
|
||||
INSERT INTO t3 (period,name,companynr,price,price2) VALUES (1010,"clinker",512,786542,76234234);
|
||||
|
||||
create temporary table tmp select * from t3;
|
||||
create temporary table tmp type = myisam select * from t3;
|
||||
|
||||
insert into t3 select * from tmp;
|
||||
insert into tmp select * from t3;
|
||||
|
@ -199,6 +199,11 @@ sub new
|
||||
{
|
||||
$limits{'max_text_size'} = 8000; # Limit in Innobase
|
||||
}
|
||||
if (defined($main::opt_create_options) &&
|
||||
$main::opt_create_options =~ /type=gemini/i)
|
||||
{
|
||||
$limits{'working_blobs'} = 0; # Blobs not implemented yet
|
||||
}
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ MYSQLDATAdir = $(localstatedir)
|
||||
MYSQLSHAREdir = $(pkgdatadir)
|
||||
MYSQLBASEdir= $(prefix)
|
||||
INCLUDES = @MT_INCLUDES@ \
|
||||
@bdb_includes@ @innobase_includes@ \
|
||||
@bdb_includes@ @innobase_includes@ @gemini_includes@ \
|
||||
-I$(srcdir)/../include \
|
||||
-I$(srcdir)/../regex \
|
||||
-I$(srcdir) -I../include -I.. -I.
|
||||
@ -40,7 +40,7 @@ LDADD = ../isam/libnisam.a \
|
||||
../regex/libregex.a \
|
||||
../strings/libmystrings.a
|
||||
mysqld_LDADD = @MYSQLD_EXTRA_LDFLAGS@ \
|
||||
@bdb_libs@ @innobase_libs@ \
|
||||
@bdb_libs@ @innobase_libs@ @gemini_libs@ \
|
||||
$(LDADD) $(CXXLDFLAGS) $(WRAPLIBS)
|
||||
noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \
|
||||
item_strfunc.h item_timefunc.h item_uniq.h \
|
||||
@ -50,7 +50,7 @@ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \
|
||||
field.h handler.h \
|
||||
ha_isammrg.h ha_isam.h ha_myisammrg.h\
|
||||
ha_heap.h ha_myisam.h ha_berkeley.h ha_innobase.h \
|
||||
opt_range.h opt_ft.h \
|
||||
ha_gemini.h opt_range.h opt_ft.h \
|
||||
sql_select.h structs.h table.h sql_udf.h hash_filo.h\
|
||||
lex.h lex_symbol.h sql_acl.h sql_crypt.h md5.h \
|
||||
log_event.h mini_client.h sql_repl.h slave.h
|
||||
@ -71,7 +71,7 @@ mysqld_SOURCES = sql_lex.cc \
|
||||
records.cc filesort.cc handler.cc \
|
||||
ha_isam.cc ha_isammrg.cc ha_heap.cc \
|
||||
ha_myisam.cc ha_myisammrg.cc ha_berkeley.cc \
|
||||
ha_innobase.cc \
|
||||
ha_innobase.cc ha_gemini.cc \
|
||||
sql_db.cc sql_table.cc sql_rename.cc sql_crypt.cc \
|
||||
sql_load.cc mf_iocache.cc field_conv.cc sql_show.cc \
|
||||
sql_udf.cc sql_analyse.cc sql_analyse.h sql_cache.cc \
|
||||
|
2685
sql/ha_gemini.cc
Normal file
2685
sql/ha_gemini.cc
Normal file
File diff suppressed because it is too large
Load Diff
185
sql/ha_gemini.h
Normal file
185
sql/ha_gemini.h
Normal file
@ -0,0 +1,185 @@
|
||||
/* Copyright (C) 2000 NuSphere Corporation
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma interface /* gcc class implementation */
|
||||
#endif
|
||||
|
||||
#include "dstd.h"
|
||||
#include "dsmpub.h"
|
||||
|
||||
/* class for the the gemini handler */
|
||||
|
||||
enum enum_key_string_options{KEY_CREATE,KEY_DELETE,KEY_CHECK};
|
||||
|
||||
#define READ_UNCOMMITED 0
|
||||
#define READ_COMMITED 1
|
||||
#define REPEATABLE_READ 2
|
||||
#define SERIALIZEABLE 3
|
||||
|
||||
class ha_gemini: public handler
|
||||
{
|
||||
/* define file as an int for now until we have a real file struct */
|
||||
int file;
|
||||
uint int_option_flag;
|
||||
int tableNumber;
|
||||
dsmIndex_t *pindexNumbers; // dsm object numbers for the indexes on this table
|
||||
unsigned long lastRowid;
|
||||
uint last_dup_key;
|
||||
bool fixed_length_row, key_read, using_ignore;
|
||||
byte *rec_buff;
|
||||
dsmKey_t *pbracketBase;
|
||||
dsmKey_t *pbracketLimit;
|
||||
dsmKey_t *pfoundKey;
|
||||
dsmMask_t tableStatus; // Crashed/repair status
|
||||
|
||||
int index_open(char *tableName);
|
||||
int pack_row(byte **prow, int *ppackedLength, const byte *record);
|
||||
void unpack_row(char *record, char *prow);
|
||||
int findRow(THD *thd, dsmMask_t findMode, byte *buf);
|
||||
int fetch_row(void *gemini_context, const byte *buf);
|
||||
int handleIndexEntries(const byte * record, dsmRecid_t recid,
|
||||
enum_key_string_options option);
|
||||
|
||||
int handleIndexEntry(const byte * record, dsmRecid_t recid,
|
||||
enum_key_string_options option,uint keynr);
|
||||
|
||||
int createKeyString(const byte * record, KEY *pkeyinfo,
|
||||
unsigned char *pkeyBuf, int bufSize,
|
||||
int *pkeyStringLen, short geminiIndexNumber,
|
||||
bool *thereIsAnull);
|
||||
int fullCheck(THD *thd,byte *buf);
|
||||
|
||||
int pack_key( uint keynr, dsmKey_t *pkey,
|
||||
const byte *key_ptr, uint key_length);
|
||||
|
||||
void unpack_key(char *record, dsmKey_t *key, uint index);
|
||||
|
||||
int key_cmp(uint keynr, const byte * old_row,
|
||||
const byte * new_row);
|
||||
|
||||
|
||||
short cursorId; /* cursorId of active index cursor if any */
|
||||
dsmMask_t lockMode; /* Shared or exclusive */
|
||||
|
||||
/* FIXFIX Don't know why we need this because I don't know what
|
||||
store_lock method does but we core dump without this */
|
||||
THR_LOCK alock;
|
||||
THR_LOCK_DATA lock;
|
||||
public:
|
||||
ha_gemini(TABLE *table): handler(table), file(0),
|
||||
int_option_flag(HA_READ_NEXT | HA_READ_PREV |
|
||||
HA_REC_NOT_IN_SEQ |
|
||||
HA_KEYPOS_TO_RNDPOS | HA_READ_ORDER | HA_LASTKEY_ORDER |
|
||||
HA_LONGLONG_KEYS | HA_NULL_KEY | HA_HAVE_KEY_READ_ONLY |
|
||||
HA_NO_BLOBS | HA_NO_TEMP_TABLES |
|
||||
/* HA_BLOB_KEY | */ /*HA_NOT_EXACT_COUNT | */
|
||||
/*HA_KEY_READ_WRONG_STR |*/ HA_DROP_BEFORE_CREATE),
|
||||
pbracketBase(0),pbracketLimit(0),pfoundKey(0),
|
||||
cursorId(0)
|
||||
{
|
||||
}
|
||||
~ha_gemini() {}
|
||||
const char *table_type() const { return "Gemini"; }
|
||||
const char **bas_ext() const;
|
||||
ulong option_flag() const { return int_option_flag; }
|
||||
uint max_record_length() const { return MAXRECSZ; }
|
||||
uint max_keys() const { return MAX_KEY-1; }
|
||||
uint max_key_parts() const { return MAX_REF_PARTS; }
|
||||
uint max_key_length() const { return MAXKEYSZ; }
|
||||
bool fast_key_read() { return 1;}
|
||||
bool has_transactions() { return 1;}
|
||||
|
||||
int open(const char *name, int mode, uint test_if_locked);
|
||||
int close(void);
|
||||
double scan_time();
|
||||
int write_row(byte * buf);
|
||||
int update_row(const byte * old_data, byte * new_data);
|
||||
int delete_row(const byte * buf);
|
||||
int index_init(uint index);
|
||||
int index_end();
|
||||
int index_read(byte * buf, const byte * key,
|
||||
uint key_len, enum ha_rkey_function find_flag);
|
||||
int index_read_idx(byte * buf, uint index, const byte * key,
|
||||
uint key_len, enum ha_rkey_function find_flag);
|
||||
int index_next(byte * buf);
|
||||
int index_next_same(byte * buf, const byte *key, uint keylen);
|
||||
int index_prev(byte * buf);
|
||||
int index_first(byte * buf);
|
||||
int index_last(byte * buf);
|
||||
int rnd_init(bool scan=1);
|
||||
int rnd_end();
|
||||
int rnd_next(byte *buf);
|
||||
int rnd_pos(byte * buf, byte *pos);
|
||||
void position(const byte *record);
|
||||
void info(uint);
|
||||
int extra(enum ha_extra_function operation);
|
||||
int reset(void);
|
||||
int check(THD* thd, HA_CHECK_OPT* check_opt);
|
||||
int repair(THD* thd, HA_CHECK_OPT* check_opt);
|
||||
int external_lock(THD *thd, int lock_type);
|
||||
virtual longlong get_auto_increment();
|
||||
void position(byte *record);
|
||||
ha_rows records_in_range(int inx,
|
||||
const byte *start_key,uint start_key_len,
|
||||
enum ha_rkey_function start_search_flag,
|
||||
const byte *end_key,uint end_key_len,
|
||||
enum ha_rkey_function end_search_flag);
|
||||
|
||||
int create(const char *name, register TABLE *form,
|
||||
HA_CREATE_INFO *create_info);
|
||||
int delete_table(const char *name);
|
||||
int rename_table(const char* from, const char* to);
|
||||
THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to,
|
||||
enum thr_lock_type lock_type);
|
||||
};
|
||||
|
||||
#define GEMOPT_FLUSH_LOG 0x00000001
|
||||
#define GEMOPT_UNBUFFERED_IO 0x00000002
|
||||
|
||||
#define GEMINI_RECOVERY_FULL 0x00000001
|
||||
#define GEMINI_RECOVERY_NONE 0x00000002
|
||||
#define GEMINI_RECOVERY_FORCE 0x00000004
|
||||
|
||||
#define GEM_OPTID_SPIN_RETRIES 1
|
||||
|
||||
extern bool gemini_skip;
|
||||
extern long gemini_options;
|
||||
extern long gemini_buffer_cache;
|
||||
extern long gemini_io_threads;
|
||||
extern long gemini_log_cluster_size;
|
||||
extern long gemini_locktablesize;
|
||||
extern long gemini_lock_wait_timeout;
|
||||
extern long gemini_spin_retries;
|
||||
extern long gemini_connection_limit;
|
||||
extern TYPELIB gemini_recovery_typelib;
|
||||
extern ulong gemini_recovery_options;
|
||||
|
||||
bool gemini_init(void);
|
||||
bool gemini_end(void);
|
||||
bool gemini_flush_logs(void);
|
||||
int gemini_commit(THD *thd);
|
||||
int gemini_rollback(THD *thd);
|
||||
void gemini_disconnect(THD *thd);
|
||||
int gemini_rollback_to_savepoint(THD *thd);
|
||||
int gemini_parse_table_name(const char *fullname, char *dbname, char *tabname);
|
||||
int gemini_is_vst(const char *pname);
|
||||
int gemini_set_option_long(int optid, long optval);
|
||||
|
||||
const int gemini_blocksize = 8192;
|
||||
const int gemini_recbits = 7;
|
||||
|
@ -35,6 +35,9 @@
|
||||
#ifdef HAVE_INNOBASE_DB
|
||||
#include "ha_innobase.h"
|
||||
#endif
|
||||
#ifdef HAVE_GEMINI_DB
|
||||
#include "ha_gemini.h"
|
||||
#endif
|
||||
#include <myisampack.h>
|
||||
#include <errno.h>
|
||||
|
||||
@ -49,7 +52,7 @@ ulong ha_read_count, ha_write_count, ha_delete_count, ha_update_count,
|
||||
|
||||
const char *ha_table_type[] = {
|
||||
"", "DIAB_ISAM","HASH","MISAM","PISAM","RMS_ISAM","HEAP", "ISAM",
|
||||
"MRG_ISAM","MYISAM", "MRG_MYISAM", "BDB", "INNOBASE", "?", "?",NullS
|
||||
"MRG_ISAM","MYISAM", "MRG_MYISAM", "BDB", "INNOBASE", "GEMINI", "?", "?",NullS
|
||||
};
|
||||
|
||||
const char *ha_row_type[] = {
|
||||
@ -77,6 +80,10 @@ enum db_type ha_checktype(enum db_type database_type)
|
||||
case DB_TYPE_INNOBASE:
|
||||
return(innobase_skip ? DB_TYPE_MYISAM : database_type);
|
||||
#endif
|
||||
#ifdef HAVE_GEMINI_DB
|
||||
case DB_TYPE_GEMINI:
|
||||
return(gemini_skip ? DB_TYPE_MYISAM : database_type);
|
||||
#endif
|
||||
#ifndef NO_HASH
|
||||
case DB_TYPE_HASH:
|
||||
#endif
|
||||
@ -118,6 +125,10 @@ handler *get_new_handler(TABLE *table, enum db_type db_type)
|
||||
#ifdef HAVE_INNOBASE_DB
|
||||
case DB_TYPE_INNOBASE:
|
||||
return new ha_innobase(table);
|
||||
#endif
|
||||
#ifdef HAVE_GEMINI_DB
|
||||
case DB_TYPE_GEMINI:
|
||||
return new ha_gemini(table);
|
||||
#endif
|
||||
case DB_TYPE_HEAP:
|
||||
return new ha_heap(table);
|
||||
@ -149,6 +160,15 @@ int ha_init()
|
||||
if (!innobase_skip) // If we couldn't use handler
|
||||
opt_using_transactions=1;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_GEMINI_DB
|
||||
if (!gemini_skip)
|
||||
{
|
||||
if (gemini_init())
|
||||
return -1;
|
||||
if (!gemini_skip) // If we couldn't use handler
|
||||
opt_using_transactions=1;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
@ -176,6 +196,10 @@ int ha_panic(enum ha_panic_function flag)
|
||||
#ifdef HAVE_INNOBASE_DB
|
||||
if (!innobase_skip)
|
||||
error|=innobase_end();
|
||||
#endif
|
||||
#ifdef HAVE_GEMINI_DB
|
||||
if (!gemini_skip)
|
||||
error|=gemini_end();
|
||||
#endif
|
||||
return error;
|
||||
} /* ha_panic */
|
||||
@ -187,6 +211,12 @@ void ha_close_connection(THD* thd)
|
||||
if (!innobase_skip)
|
||||
innobase_close_connection(thd);
|
||||
#endif
|
||||
#ifdef HAVE_GEMINI_DB
|
||||
if (!gemini_skip && thd->gemini.context)
|
||||
{
|
||||
gemini_disconnect(thd);
|
||||
}
|
||||
#endif /* HAVE_GEMINI_DB */
|
||||
}
|
||||
|
||||
/*
|
||||
@ -250,6 +280,20 @@ int ha_commit_trans(THD *thd, THD_TRANS* trans)
|
||||
error=1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_GEMINI_DB
|
||||
/* Commit the transaction in behalf of the commit statement
|
||||
or if we're in auto-commit mode */
|
||||
if((trans == &thd->transaction.all) ||
|
||||
(!(thd->options & (OPTION_NOT_AUTO_COMMIT | OPTION_BEGIN))))
|
||||
{
|
||||
error=gemini_commit(thd);
|
||||
if (error)
|
||||
{
|
||||
my_error(ER_ERROR_DURING_COMMIT, MYF(0), error);
|
||||
error=1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (error && trans == &thd->transaction.all && mysql_bin_log.is_open())
|
||||
sql_print_error("Error: Got error during commit; Binlog is not up to date!");
|
||||
@ -287,6 +331,18 @@ int ha_rollback_trans(THD *thd, THD_TRANS *trans)
|
||||
error=1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_GEMINI_DB
|
||||
if((trans == &thd->transaction.stmt) &&
|
||||
(thd->options & (OPTION_NOT_AUTO_COMMIT | OPTION_BEGIN)))
|
||||
error = gemini_rollback_to_savepoint(thd);
|
||||
else
|
||||
error=gemini_rollback(thd);
|
||||
if (error)
|
||||
{
|
||||
my_error(ER_ERROR_DURING_ROLLBACK, MYF(0), error);
|
||||
error=1;
|
||||
}
|
||||
#endif
|
||||
if (trans == &thd->transaction.all)
|
||||
reinit_io_cache(&thd->transaction.trans_log,
|
||||
@ -678,6 +734,21 @@ int handler::rename_table(const char * from, const char * to)
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
int ha_commit_rename(THD *thd)
|
||||
{
|
||||
int error=0;
|
||||
#ifdef HAVE_GEMINI_DB
|
||||
/* Gemini needs to commit the rename; otherwise a rollback will change
|
||||
** the table names back internally but the physical files will still
|
||||
** have the new names.
|
||||
*/
|
||||
if (ha_commit_stmt(thd))
|
||||
error= -1;
|
||||
if (ha_commit(thd))
|
||||
error= -1;
|
||||
#endif
|
||||
return error;
|
||||
}
|
||||
|
||||
int handler::index_next_same(byte *buf, const byte *key, uint keylen)
|
||||
{
|
||||
|
@ -72,6 +72,7 @@
|
||||
#define HA_DROP_BEFORE_CREATE (HA_PRIMARY_KEY_IN_READ_INDEX*2)
|
||||
#define HA_NOT_READ_AFTER_KEY (HA_DROP_BEFORE_CREATE*2)
|
||||
#define HA_NOT_DELETE_WITH_CACHE (HA_NOT_READ_AFTER_KEY*2)
|
||||
#define HA_NO_TEMP_TABLES (HA_NOT_DELETE_WITH_CACHE*2)
|
||||
|
||||
/* Parameters for open() (in register form->filestat) */
|
||||
/* HA_GET_INFO does a implicit HA_ABORT_IF_LOCKED */
|
||||
@ -310,6 +311,17 @@ public:
|
||||
enum thr_lock_type lock_type)=0;
|
||||
};
|
||||
|
||||
#ifdef HAVE_GEMINI_DB
|
||||
struct st_gemini
|
||||
{
|
||||
void *context;
|
||||
unsigned long savepoint;
|
||||
bool needSavepoint;
|
||||
uint tx_isolation;
|
||||
uint lock_count;
|
||||
};
|
||||
#endif
|
||||
|
||||
/* Some extern variables used with handlers */
|
||||
|
||||
extern const char *ha_row_type[];
|
||||
@ -337,4 +349,4 @@ int ha_rollback_trans(THD *thd, THD_TRANS *trans);
|
||||
int ha_autocommit_or_rollback(THD *thd, int error);
|
||||
void ha_set_spin_retries(uint retries);
|
||||
bool ha_flush_logs(void);
|
||||
|
||||
int ha_commit_rename(THD *thd);
|
||||
|
@ -146,6 +146,7 @@ static SYMBOL symbols[] = {
|
||||
{ "FULLTEXT", SYM(FULLTEXT_SYM),0,0},
|
||||
{ "FUNCTION", SYM(UDF_SYM),0,0},
|
||||
{ "GEMINI", SYM(GEMINI_SYM),0,0},
|
||||
{ "GEMINI_SPIN_RETRIES", SYM(GEMINI_SPIN_RETRIES),0,0},
|
||||
{ "GLOBAL", SYM(GLOBAL_SYM),0,0},
|
||||
{ "GRANT", SYM(GRANT),0,0},
|
||||
{ "GRANTS", SYM(GRANTS),0,0},
|
||||
|
128
sql/mysqld.cc
128
sql/mysqld.cc
@ -25,6 +25,9 @@
|
||||
#ifdef HAVE_INNOBASE_DB
|
||||
#include "ha_innobase.h"
|
||||
#endif
|
||||
#ifdef HAVE_GEMINI_DB
|
||||
#include "ha_gemini.h"
|
||||
#endif
|
||||
#include "ha_myisam.h"
|
||||
#include <nisam.h>
|
||||
#include <thr_alarm.h>
|
||||
@ -279,6 +282,9 @@ const char *first_keyword="first";
|
||||
const char **errmesg; /* Error messages */
|
||||
const char *myisam_recover_options_str="OFF";
|
||||
enum_tx_isolation default_tx_isolation=ISO_READ_COMMITTED;
|
||||
#ifdef HAVE_GEMINI_DB
|
||||
const char *gemini_recovery_options_str="FULL";
|
||||
#endif
|
||||
my_string mysql_unix_port=NULL,mysql_tmpdir=NULL;
|
||||
ulong my_bind_addr; /* the address we bind to */
|
||||
DATE_FORMAT dayord;
|
||||
@ -2427,7 +2433,9 @@ enum options {
|
||||
OPT_INNOBASE_FLUSH_LOG_AT_TRX_COMMIT,
|
||||
OPT_SAFE_SHOW_DB,
|
||||
OPT_GEMINI_SKIP, OPT_INNOBASE_SKIP,
|
||||
OPT_TEMP_POOL, OPT_TX_ISOLATION
|
||||
OPT_TEMP_POOL, OPT_TX_ISOLATION,
|
||||
OPT_GEMINI_FLUSH_LOG, OPT_GEMINI_RECOVER,
|
||||
OPT_GEMINI_UNBUFFERED_IO
|
||||
};
|
||||
|
||||
static struct option long_options[] = {
|
||||
@ -2464,6 +2472,11 @@ static struct option long_options[] = {
|
||||
{"enable-locking", no_argument, 0, (int) OPT_ENABLE_LOCK},
|
||||
{"exit-info", optional_argument, 0, 'T'},
|
||||
{"flush", no_argument, 0, (int) OPT_FLUSH},
|
||||
#ifdef HAVE_GEMINI_DB
|
||||
{"gemini-flush-log-at-commit",no_argument, 0, (int) OPT_GEMINI_FLUSH_LOG},
|
||||
{"gemini-recovery", required_argument, 0, (int) OPT_GEMINI_RECOVER},
|
||||
{"gemini-unbuffered-io", no_argument, 0, (int) OPT_GEMINI_UNBUFFERED_IO},
|
||||
#endif
|
||||
/* We must always support this option to make scripts like mysqltest easier
|
||||
to do */
|
||||
{"innobase_data_file_path", required_argument, 0,
|
||||
@ -2592,6 +2605,22 @@ CHANGEABLE_VAR changeable_vars[] = {
|
||||
DELAYED_QUEUE_SIZE, 1, ~0L, 0, 1 },
|
||||
{ "flush_time", (long*) &flush_time,
|
||||
FLUSH_TIME, 0, ~0L, 0, 1 },
|
||||
#ifdef HAVE_GEMINI_DB
|
||||
{ "gemini_buffer_cache", (long*) &gemini_buffer_cache,
|
||||
128 * 8192, 16, LONG_MAX, 0, 1 },
|
||||
{ "gemini_connection_limit", (long*) &gemini_connection_limit,
|
||||
100, 10, LONG_MAX, 0, 1 },
|
||||
{ "gemini_io_threads", (long*) &gemini_io_threads,
|
||||
2, 0, 256, 0, 1 },
|
||||
{ "gemini_log_cluster_size", (long*) &gemini_log_cluster_size,
|
||||
256 * 1024, 16 * 1024, LONG_MAX, 0, 1 },
|
||||
{ "gemini_lock_table_size", (long*) &gemini_locktablesize,
|
||||
4096, 1024, LONG_MAX, 0, 1 },
|
||||
{ "gemini_lock_wait_timeout",(long*) &gemini_lock_wait_timeout,
|
||||
10, 1, LONG_MAX, 0, 1 },
|
||||
{ "gemini_spin_retries", (long*) &gemini_spin_retries,
|
||||
1, 0, LONG_MAX, 0, 1 },
|
||||
#endif
|
||||
#ifdef HAVE_INNOBASE_DB
|
||||
{"innobase_mirrored_log_groups",
|
||||
(long*) &innobase_mirrored_log_groups, 1, 1, 10, 0, 1},
|
||||
@ -2711,6 +2740,16 @@ struct show_var_st init_vars[]= {
|
||||
{"delayed_queue_size", (char*) &delayed_queue_size, SHOW_LONG},
|
||||
{"flush", (char*) &myisam_flush, SHOW_MY_BOOL},
|
||||
{"flush_time", (char*) &flush_time, SHOW_LONG},
|
||||
#ifdef HAVE_GEMINI_DB
|
||||
{"gemini_buffer_cache", (char*) &gemini_buffer_cache, SHOW_LONG},
|
||||
{"gemini_connection_limit", (char*) &gemini_connection_limit, SHOW_LONG},
|
||||
{"gemini_io_threads", (char*) &gemini_io_threads, SHOW_LONG},
|
||||
{"gemini_log_cluster_size", (char*) &gemini_log_cluster_size, SHOW_LONG},
|
||||
{"gemini_lock_table_size", (char*) &gemini_locktablesize, SHOW_LONG},
|
||||
{"gemini_lock_wait_timeout",(char*) &gemini_lock_wait_timeout, SHOW_LONG},
|
||||
{"gemini_recovery_options", (char*) &gemini_recovery_options_str, SHOW_CHAR_PTR},
|
||||
{"gemini_spin_retries", (char*) &gemini_spin_retries, SHOW_LONG},
|
||||
#endif
|
||||
{"have_bdb", (char*) &have_berkeley_db, SHOW_HAVE},
|
||||
{"have_gemini", (char*) &have_gemini, SHOW_HAVE},
|
||||
{"have_innobase", (char*) &have_innobase, SHOW_HAVE},
|
||||
@ -2974,6 +3013,16 @@ static void usage(void)
|
||||
--skip-bdb Don't use berkeley db (will save memory)\n\
|
||||
");
|
||||
#endif /* HAVE_BERKELEY_DB */
|
||||
#ifdef HAVE_GEMINI_DB
|
||||
puts("\
|
||||
--gemini-recovery=mode Set Crash Recovery operating mode\n\
|
||||
(FULL, NONE, FORCE - default FULL)
|
||||
--gemini-flush-log-at-commit\n\
|
||||
Every commit forces a write to the reovery log\n\
|
||||
--gemini-unbuffered-io Use unbuffered i/o\n\
|
||||
--skip-gemini Don't use gemini (will save memory)\n\
|
||||
");
|
||||
#endif
|
||||
#ifdef HAVE_INNOBASE_DB
|
||||
puts("\
|
||||
--innobase_data_home_dir=dir The common part for innobase table spaces\n
|
||||
@ -3519,6 +3568,21 @@ static void get_options(int argc,char **argv)
|
||||
#ifdef HAVE_GEMINI_DB
|
||||
gemini_skip=1;
|
||||
have_gemini=SHOW_OPTION_DISABLED;
|
||||
break;
|
||||
case OPT_GEMINI_RECOVER:
|
||||
gemini_recovery_options_str=optarg;
|
||||
if ((gemini_recovery_options=
|
||||
find_bit_type(optarg, &gemini_recovery_typelib)) == ~(ulong) 0)
|
||||
{
|
||||
fprintf(stderr, "Unknown option to gemini-recovery: %s\n",optarg);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case OPT_GEMINI_FLUSH_LOG:
|
||||
gemini_options |= GEMOPT_FLUSH_LOG;
|
||||
break;
|
||||
case OPT_GEMINI_UNBUFFERED_IO:
|
||||
gemini_options |= GEMOPT_UNBUFFERED_IO;
|
||||
#endif
|
||||
break;
|
||||
case OPT_INNOBASE_SKIP:
|
||||
@ -4002,6 +4066,68 @@ static int get_service_parameters()
|
||||
{
|
||||
SET_CHANGEABLE_VARVAL( "thread_concurrency" );
|
||||
}
|
||||
#ifdef HAVE_GEMINI_DB
|
||||
else if ( lstrcmp(szKeyValueName, TEXT("GeminiLazyCommit")) == 0 )
|
||||
{
|
||||
CHECK_KEY_TYPE( REG_DWORD, szKeyValueName );
|
||||
if ( *lpdwValue )
|
||||
gemini_options |= GEMOPT_FLUSH_LOG;
|
||||
else
|
||||
gemini_options &= ~GEMOPT_FLUSH_LOG;
|
||||
}
|
||||
else if ( lstrcmp(szKeyValueName, TEXT("GeminiFullRecovery")) == 0 )
|
||||
{
|
||||
CHECK_KEY_TYPE( REG_DWORD, szKeyValueName );
|
||||
if ( *lpdwValue )
|
||||
gemini_options &= ~GEMOPT_NO_CRASH_PROTECTION;
|
||||
else
|
||||
gemini_options |= GEMOPT_NO_CRASH_PROTECTION;
|
||||
}
|
||||
else if ( lstrcmp(szKeyValueName, TEXT("GeminiNoRecovery")) == 0 )
|
||||
{
|
||||
CHECK_KEY_TYPE( REG_DWORD, szKeyValueName );
|
||||
if ( *lpdwValue )
|
||||
gemini_options |= GEMOPT_NO_CRASH_PROTECTION;
|
||||
else
|
||||
gemini_options &= ~GEMOPT_NO_CRASH_PROTECTION;
|
||||
}
|
||||
else if ( lstrcmp(szKeyValueName, TEXT("GeminiUnbufferedIO")) == 0 )
|
||||
{
|
||||
CHECK_KEY_TYPE( REG_DWORD, szKeyValueName );
|
||||
if ( *lpdwValue )
|
||||
gemini_options |= GEMOPT_UNBUFFERED_IO;
|
||||
else
|
||||
gemini_options &= ~GEMOPT_UNBUFFERED_IO;
|
||||
}
|
||||
else if ( lstrcmp(szKeyValueName, TEXT("GeminiLockTableSize")) == 0 )
|
||||
{
|
||||
SET_CHANGEABLE_VARVAL( "gemini_lock_table_size" );
|
||||
}
|
||||
else if ( lstrcmp(szKeyValueName, TEXT("GeminiBufferCache")) == 0 )
|
||||
{
|
||||
SET_CHANGEABLE_VARVAL( "gemini_buffer_cache" );
|
||||
}
|
||||
else if ( lstrcmp(szKeyValueName, TEXT("GeminiSpinRetries")) == 0 )
|
||||
{
|
||||
SET_CHANGEABLE_VARVAL( "gemini_spin_retries" );
|
||||
}
|
||||
else if ( lstrcmp(szKeyValueName, TEXT("GeminiIoThreads")) == 0 )
|
||||
{
|
||||
SET_CHANGEABLE_VARVAL( "gemini_io_threads" );
|
||||
}
|
||||
else if ( lstrcmp(szKeyValueName, TEXT("GeminiConnectionLimit")) == 0 )
|
||||
{
|
||||
SET_CHANGEABLE_VARVAL( "gemini_connection_limit" );
|
||||
}
|
||||
else if ( lstrcmp(szKeyValueName, TEXT("GeminiLogClusterSize")) == 0 )
|
||||
{
|
||||
SET_CHANGEABLE_VARVAL( "gemini_log_cluster_size" );
|
||||
}
|
||||
else if ( lstrcmp(szKeyValueName, TEXT("GeminiLockWaitTimeout")) == 0 )
|
||||
{
|
||||
SET_CHANGEABLE_VARVAL( "gemini_lock_wait_timeout" );
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
TCHAR szErrorMsg [ 512 ];
|
||||
|
@ -2400,15 +2400,22 @@ int QUICK_SELECT::get_next()
|
||||
|
||||
for (;;)
|
||||
{
|
||||
int result;
|
||||
if (range)
|
||||
{ // Already read through key
|
||||
int result=((range->flag & EQ_RANGE) ?
|
||||
file->index_next_same(record, (byte*) range->min_key,
|
||||
range->min_length) :
|
||||
file->index_next(record));
|
||||
if (!result && !cmp_next(*it.ref()))
|
||||
DBUG_RETURN(0);
|
||||
result=((range->flag & EQ_RANGE) ?
|
||||
file->index_next_same(record, (byte*) range->min_key,
|
||||
range->min_length) :
|
||||
file->index_next(record));
|
||||
if (!result)
|
||||
{
|
||||
if (!cmp_next(*it.ref()))
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
else if (result != HA_ERR_END_OF_FILE)
|
||||
DBUG_RETURN(result);
|
||||
}
|
||||
|
||||
if (!(range=it++))
|
||||
DBUG_RETURN(HA_ERR_END_OF_FILE); // All ranges used
|
||||
if (range->flag & NO_MIN_RANGE) // Read first record
|
||||
@ -2421,15 +2428,17 @@ int QUICK_SELECT::get_next()
|
||||
range=0; // To next range
|
||||
continue;
|
||||
}
|
||||
if (file->index_read(record,(byte*) range->min_key,
|
||||
if ((result = file->index_read(record,(byte*) range->min_key,
|
||||
range->min_length,
|
||||
((range->flag & NEAR_MIN) ?
|
||||
HA_READ_AFTER_KEY:
|
||||
(range->flag & EQ_RANGE) ?
|
||||
HA_READ_KEY_EXACT :
|
||||
HA_READ_KEY_OR_NEXT)))
|
||||
HA_READ_KEY_OR_NEXT))))
|
||||
|
||||
{
|
||||
if (result != HA_ERR_KEY_NOT_FOUND)
|
||||
DBUG_RETURN(result);
|
||||
range=0; // Not found, to next range
|
||||
continue;
|
||||
}
|
||||
|
@ -164,25 +164,30 @@ static int rr_sequential(READ_RECORD *info)
|
||||
|
||||
static int rr_from_tempfile(READ_RECORD *info)
|
||||
{
|
||||
int tmp;
|
||||
tryNext:
|
||||
if (my_b_read(info->io_cache,info->ref_pos,info->ref_length))
|
||||
return -1; /* End of file */
|
||||
int tmp=info->file->rnd_pos(info->record,info->ref_pos);
|
||||
tmp=info->file->rnd_pos(info->record,info->ref_pos);
|
||||
if (tmp)
|
||||
{
|
||||
if (tmp == HA_ERR_END_OF_FILE)
|
||||
tmp= -1;
|
||||
else if (tmp == HA_ERR_RECORD_DELETED)
|
||||
goto tryNext;
|
||||
else if (info->print_error)
|
||||
info->file->print_error(tmp,MYF(0));
|
||||
}
|
||||
return tmp;
|
||||
} /* rr_from_tempfile */
|
||||
|
||||
|
||||
static int rr_from_pointers(READ_RECORD *info)
|
||||
{
|
||||
byte *cache_pos;
|
||||
tryNext:
|
||||
if (info->cache_pos == info->cache_end)
|
||||
return -1; /* End of file */
|
||||
byte *cache_pos=info->cache_pos;
|
||||
cache_pos=info->cache_pos;
|
||||
info->cache_pos+=info->ref_length;
|
||||
|
||||
int tmp=info->file->rnd_pos(info->record,cache_pos);
|
||||
@ -190,6 +195,8 @@ static int rr_from_pointers(READ_RECORD *info)
|
||||
{
|
||||
if (tmp == HA_ERR_END_OF_FILE)
|
||||
tmp= -1;
|
||||
else if (tmp == HA_ERR_RECORD_DELETED)
|
||||
goto tryNext;
|
||||
else if (info->print_error)
|
||||
info->file->print_error(tmp,MYF(0));
|
||||
}
|
||||
|
@ -105,6 +105,9 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0),
|
||||
#ifdef __WIN__
|
||||
real_id = 0;
|
||||
#endif
|
||||
#ifdef HAVE_GEMINI_DB
|
||||
bzero((char *)&gemini, sizeof(gemini));
|
||||
#endif
|
||||
#ifdef SIGNAL_WITH_VIO_CLOSE
|
||||
active_vio = 0;
|
||||
pthread_mutex_init(&active_vio_lock, NULL);
|
||||
|
@ -250,6 +250,9 @@ public:
|
||||
THD_TRANS stmt; /* Trans for current statement */
|
||||
uint bdb_lock_count;
|
||||
} transaction;
|
||||
#ifdef HAVE_GEMINI_DB
|
||||
struct st_gemini gemini;
|
||||
#endif
|
||||
Item *free_list;
|
||||
CONVERT *convert_set;
|
||||
Field *dupp_field;
|
||||
@ -265,10 +268,11 @@ public:
|
||||
max_join_size,sent_row_count;
|
||||
table_map used_tables;
|
||||
ulong query_id,version, inactive_timeout,options,thread_id;
|
||||
ulong gemini_spin_retries;
|
||||
long dbug_thread_id;
|
||||
pthread_t real_id;
|
||||
uint current_tablenr,tmp_table,cond_count,col_access,query_length;
|
||||
uint server_status,open_options, gemini_spin_retries;
|
||||
uint server_status,open_options;
|
||||
enum_tx_isolation tx_isolation, session_tx_isolation;
|
||||
char scramble[9];
|
||||
bool slave_thread;
|
||||
|
@ -136,12 +136,12 @@ typedef struct st_lex {
|
||||
LEX_MASTER_INFO mi; // used by CHANGE MASTER
|
||||
ulong thread_id,type;
|
||||
ulong options;
|
||||
ulong gemini_spin_retries;
|
||||
enum_sql_command sql_command;
|
||||
enum lex_states next_state;
|
||||
enum enum_duplicates duplicates;
|
||||
enum enum_tx_isolation tx_isolation;
|
||||
uint in_sum_expr,grant,grant_tot_col,which_columns, sort_default;
|
||||
uint gemini_spin_retries;
|
||||
thr_lock_type lock_option;
|
||||
bool create_refs,drop_primary,drop_if_exists,local_file;
|
||||
bool in_comment,ignore_space,verbose;
|
||||
|
@ -31,7 +31,7 @@ static TABLE_LIST *rename_tables(THD *thd, TABLE_LIST *table_list,
|
||||
|
||||
bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list)
|
||||
{
|
||||
bool error=1,got_all_locks=1;
|
||||
bool error=1,cerror,got_all_locks=1;
|
||||
TABLE_LIST *lock_table,*ren_table=0;
|
||||
DBUG_ENTER("mysql_rename_tables");
|
||||
|
||||
@ -85,7 +85,14 @@ end:
|
||||
rename_tables(thd, table, 1);
|
||||
/* Note that lock_table == 0 here, so the unlock loop will work */
|
||||
}
|
||||
if (!error)
|
||||
|
||||
/* Lets hope this doesn't fail as the result will be messy */
|
||||
if ((cerror=ha_commit_rename(thd)))
|
||||
{
|
||||
my_error(ER_GET_ERRNO,MYF(0),cerror);
|
||||
error= 1;
|
||||
}
|
||||
else if (!error)
|
||||
{
|
||||
mysql_update_log.write(thd,thd->query,thd->query_length);
|
||||
if (mysql_bin_log.is_open())
|
||||
@ -95,6 +102,7 @@ end:
|
||||
}
|
||||
send_ok(&thd->net);
|
||||
}
|
||||
|
||||
for (TABLE_LIST *table=table_list ; table != lock_table ; table=table->next)
|
||||
unlock_table_name(thd,table);
|
||||
pthread_cond_broadcast(&COND_refresh);
|
||||
|
@ -1170,6 +1170,12 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
||||
if (mysql_rename_table(old_db_type,db,table_name,new_db,new_name))
|
||||
error= -1;
|
||||
}
|
||||
if (!error && (error=ha_commit_rename(thd)))
|
||||
{
|
||||
my_error(ER_GET_ERRNO,MYF(0),error);
|
||||
error=1;
|
||||
}
|
||||
|
||||
VOID(pthread_cond_broadcast(&COND_refresh));
|
||||
VOID(pthread_mutex_unlock(&LOCK_open));
|
||||
if (!error)
|
||||
@ -1603,6 +1609,7 @@ end_temporary:
|
||||
DBUG_RETURN(0);
|
||||
|
||||
err:
|
||||
(void) ha_commit_rename(thd); // Just for safety
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user