diff options
author | unknown <monty@hundin.mysql.fi> | 2001-10-10 02:50:28 +0300 |
---|---|---|
committer | unknown <monty@hundin.mysql.fi> | 2001-10-10 02:50:28 +0300 |
commit | 8cbba4051fa166f296b49bcfdc1ea9d071d42112 (patch) | |
tree | 088cf9579071d756c85870f15378382121877072 | |
parent | 126e9b5577bf6ab9694745bc6085572d7ddeca88 (diff) | |
download | mariadb-git-8cbba4051fa166f296b49bcfdc1ea9d071d42112.tar.gz |
Remved Gemini code.
BitKeeper/deleted/.del-ha_gemini.cc~5d72172d33b00c6:
Delete: sql/ha_gemini.cc
BitKeeper/deleted/.del-ha_gemini.h~4dfccf1929195747:
Delete: sql/ha_gemini.h
BitKeeper/deleted/.del-gemini.result~89b4f9cced8dfc2f:
Delete: mysql-test/r/gemini.result
BitKeeper/deleted/.del-gemini.test~51d0362310e55e17:
Delete: mysql-test/t/gemini.test
BitKeeper/deleted/.del-have_gemini.inc~42f94f0dfd0f7b18:
Delete: mysql-test/include/have_gemini.inc
BitKeeper/deleted/.del-have_gemini.require~206702c48b2e206b:
Delete: mysql-test/r/have_gemini.require
BitKeeper/deleted/.del-gemini.dat~a73393a88b124b9f:
Delete: mysql-test/std_data/gemini.dat
BitKeeper/deleted/.del-isolation.test~6a39e4138dd4a456:
Delete: mysql-test/t/isolation.test
BitKeeper/deleted/.del-isolation.result~4da11e109a3d93a9:
Delete: mysql-test/r/isolation.result
acinclude.m4:
Remved gemini code.
configure.in:
Remved gemini code.
libmysql/libmysql.c:
Remved gemini code.
mysql-test/install_test_db.sh:
Remved gemini code.
scripts/mysql_install_db.sh:
Remved gemini code.
sql/Makefile.am:
Remved gemini code.
sql/field.cc:
Remved gemini code.
sql/field.h:
Remved gemini code.
sql/handler.cc:
Remved gemini code.
sql/handler.h:
Remved gemini code.
sql/lex.h:
Remved gemini code.
sql/mysqld.cc:
Remved gemini code.
sql/sql_base.cc:
Remved gemini code.
sql/sql_class.cc:
Remved gemini code.
sql/sql_class.h:
Remved gemini code.
sql/sql_lex.h:
Remved gemini code.
sql/sql_parse.cc:
Remved gemini code.
sql/sql_rename.cc:
Remved gemini code.
sql/sql_table.cc:
Remved gemini code.
sql/sql_yacc.yy:
Remved gemini code.
-rw-r--r-- | acinclude.m4 | 42 | ||||
-rw-r--r-- | configure.in | 12 | ||||
-rw-r--r-- | libmysql/libmysql.c | 2 | ||||
-rw-r--r-- | mysql-test/include/have_gemini.inc | 4 | ||||
-rw-r--r-- | mysql-test/install_test_db.sh | 2 | ||||
-rw-r--r-- | mysql-test/r/gemini.result | 370 | ||||
-rw-r--r-- | mysql-test/r/have_gemini.require | 2 | ||||
-rw-r--r-- | mysql-test/r/isolation.result | 61 | ||||
-rw-r--r-- | mysql-test/std_data/gemini.dat | 5 | ||||
-rw-r--r-- | mysql-test/t/gemini.test | 355 | ||||
-rw-r--r-- | mysql-test/t/isolation.test | 209 | ||||
-rw-r--r-- | scripts/mysql_install_db.sh | 2 | ||||
-rw-r--r-- | sql/Makefile.am | 8 | ||||
-rw-r--r-- | sql/field.cc | 54 | ||||
-rw-r--r-- | sql/field.h | 15 | ||||
-rw-r--r-- | sql/ha_gemini.cc | 3630 | ||||
-rw-r--r-- | sql/ha_gemini.h | 208 | ||||
-rw-r--r-- | sql/handler.cc | 93 | ||||
-rw-r--r-- | sql/handler.h | 15 | ||||
-rw-r--r-- | sql/lex.h | 2 | ||||
-rw-r--r-- | sql/mysqld.cc | 144 | ||||
-rw-r--r-- | sql/sql_base.cc | 6 | ||||
-rw-r--r-- | sql/sql_class.cc | 4 | ||||
-rw-r--r-- | sql/sql_class.h | 8 | ||||
-rw-r--r-- | sql/sql_lex.h | 1 | ||||
-rw-r--r-- | sql/sql_parse.cc | 5 | ||||
-rw-r--r-- | sql/sql_rename.cc | 9 | ||||
-rw-r--r-- | sql/sql_table.cc | 7 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 13 |
29 files changed, 13 insertions, 5275 deletions
diff --git a/acinclude.m4 b/acinclude.m4 index 79caa4338ac..1cfd80ea5ed 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -1159,48 +1159,6 @@ dnl END OF MYSQL_CHECK_INNODB 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" - 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> dnl --------------------------------------------------------------------------- diff --git a/configure.in b/configure.in index ab2cc87d46f..35a3b54339c 100644 --- a/configure.in +++ b/configure.in @@ -2077,7 +2077,6 @@ AC_MSG_RESULT([default: $default_charset; compiled in: $CHARSETS]) MYSQL_CHECK_BDB MYSQL_CHECK_INNODB -MYSQL_CHECK_GEMINI # If we have threads generate some library functions and test programs sql_server_dirs= @@ -2197,17 +2196,6 @@ EOF echo "END OF INNODB CONFIGURATION" fi - if test "X$have_gemini_db" = "Xyes"; then - sql_server_dirs="gemini $sql_server_dirs" - echo "CONFIGURING FOR GEMINI DB" - (cd gemini && sh ./configure) \ - || AC_MSG_ERROR([could not configure Gemini DB]) - - echo "END OF GEMINI DB CONFIGURATION" - - AC_DEFINE(HAVE_GEMINI_DB) - fi - if test "$with_posix_threads" = "no" -o "$with_mit_threads" = "yes" then # MIT user level threads diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 2a7aeead1b4..c08c93e2439 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -148,7 +148,7 @@ static MYSQL* spawn_init(MYSQL* parent, const char* host, *****************************************************************************/ int my_connect(my_socket s, const struct sockaddr *name, uint namelen, - uint timeout) + uint timeout) { #if defined(__WIN__) || defined(OS2) return connect(s, (struct sockaddr*) name, namelen); diff --git a/mysql-test/include/have_gemini.inc b/mysql-test/include/have_gemini.inc deleted file mode 100644 index d98c9750714..00000000000 --- a/mysql-test/include/have_gemini.inc +++ /dev/null @@ -1,4 +0,0 @@ --- require r/have_gemini.require -disable_query_log; -show variables like "have_gemini"; -enable_query_log; diff --git a/mysql-test/install_test_db.sh b/mysql-test/install_test_db.sh index f810d2d9ad4..acf8cebc723 100644 --- a/mysql-test/install_test_db.sh +++ b/mysql-test/install_test_db.sh @@ -195,7 +195,7 @@ then fi mysqld_boot=" $execdir/mysqld --no-defaults --bootstrap --skip-grant-tables \ - --basedir=$basedir --datadir=$ldata --skip-innodb --skip-bdb --skip-gemini $EXTRA_ARG" + --basedir=$basedir --datadir=$ldata --skip-innodb --skip-bdb $EXTRA_ARG" echo "running $mysqld_boot" if $mysqld_boot << END_OF_DATA diff --git a/mysql-test/r/gemini.result b/mysql-test/r/gemini.result deleted file mode 100644 index 0b43b4f5192..00000000000 --- a/mysql-test/r/gemini.result +++ /dev/null @@ -1,370 +0,0 @@ -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 -f1 -65 -379 -468 -469 -508 diff --git a/mysql-test/r/have_gemini.require b/mysql-test/r/have_gemini.require deleted file mode 100644 index 0ffe0e40d3b..00000000000 --- a/mysql-test/r/have_gemini.require +++ /dev/null @@ -1,2 +0,0 @@ -Variable_name Value -have_gemini YES diff --git a/mysql-test/r/isolation.result b/mysql-test/r/isolation.result deleted file mode 100644 index 60b71e217bb..00000000000 --- a/mysql-test/r/isolation.result +++ /dev/null @@ -1,61 +0,0 @@ -f1 -test1 -bar -f1 -test2 -bar -f1 -test3 -bar -f1 -f1 -test4 -bar -f1 -test5 -bar -f1 -test6 -bar -f1 -test7 -bar -f1 -test8 -bar -f1 -test9 -bar -f1 -test10 -bar -f1 -test11 -bar -f1 -test12 -bar -f1 -test13 -bar -f1 -test14 -bar -f1 -test15 -bar -f1 -test16 -bar -f1 -test17 -bar -f1 -test18 -bar -f1 -test19 -bar -f1 -test20 -bar diff --git a/mysql-test/std_data/gemini.dat b/mysql-test/std_data/gemini.dat deleted file mode 100644 index c2e1045f5ac..00000000000 --- a/mysql-test/std_data/gemini.dat +++ /dev/null @@ -1,5 +0,0 @@ -65,-1,1 -379,-1,1 -468,-1,1 -469,-1,1 -508,-1,1 diff --git a/mysql-test/t/gemini.test b/mysql-test/t/gemini.test deleted file mode 100644 index 9d4451c3551..00000000000 --- a/mysql-test/t/gemini.test +++ /dev/null @@ -1,355 +0,0 @@ --- 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; - -# -# Test of load data infile -# - -CREATE TABLE if not exists `t1` ( - `f1` int(11) unsigned NOT NULL default '0', - `f2` tinyint(3) unsigned NOT NULL default '0', - `f3` tinyint(3) unsigned NOT NULL default '0', - PRIMARY KEY (`f1`) -) TYPE=Gemini; -lock table t1 write; -load data infile ''../../std_data/gemini.dat' ignore into table t1 fields terminated by ','; -select f1 from t1; -drop table t1; diff --git a/mysql-test/t/isolation.test b/mysql-test/t/isolation.test deleted file mode 100644 index 2a1a0ee79be..00000000000 --- a/mysql-test/t/isolation.test +++ /dev/null @@ -1,209 +0,0 @@ -source include/have_gemini.inc -source include/master-slave.inc; -connection master; -drop table if exists t1; -create table t1 (f1 char(20) not null) type = gemini; -set autocommit=0; - -insert into t1 (f1) values ("test1"), ("bar"); -connection master1; -!$1030 select * from t1; -connection master; -commit; - -drop table if exists t1; -create table t1 (f1 char(20) not null) type = gemini; -insert into t1 (f1) values ("test2"), ("bar"); -connection master1; -set transaction isolation level serializable; ---error 1218 -select * from t1; -connection master; -commit; - -drop table if exists t1; -create table t1 (f1 char(20) not null) type = gemini; -insert into t1 (f1) values ("test3"), ("bar"); -connection master1; -set transaction isolation level read uncommitted; -select * from t1; -connection master; -commit; - -drop table if exists t1; -create table t1 (f1 char(20) not null) type = gemini; -connection master1; -set transaction isolation level read committed; -select * from t1; -connection master; -commit; - -drop table if exists t1; -create table t1 (f1 char(20) not null) type = gemini; -insert into t1 (f1) values ("test4"), ("bar"); -connection master1; -set transaction isolation level repeatable read; -select * from t1; -connection master; -commit; - -drop table if exists t1; -create table t1 (f1 char(20) not null) type = gemini; -set transaction isolation level serializable; -insert into t1 (f1) values ("test5"), ("bar"); -connection master1; -set transaction isolation level serializable; -select * from t1; -connection master; -commit; - -drop table if exists t1; -create table t1 (f1 char(20) not null) type = gemini; -set transaction isolation level serializable; -insert into t1 (f1) values ("test6"), ("bar"); -connection master1; -set transaction isolation level read uncommitted; -select * from t1; -connection master; -commit; - -drop table if exists t1; -create table t1 (f1 char(20) not null) type = gemini; -set transaction isolation level serializable; -insert into t1 (f1) values ("test7"), ("bar"); -connection master1; -set transaction isolation level read committed; -select * from t1; -connection master; -commit; - -drop table if exists t1; -create table t1 (f1 char(20) not null) type = gemini; -set transaction isolation level serializable; -insert into t1 (f1) values ("test8"), ("bar"); -connection master1; -set transaction isolation level repeatable read; -select * from t1; -connection master; -commit; - -drop table if exists t1; -create table t1 (f1 char(20) not null) type = gemini; -set transaction isolation level read uncommitted; -insert into t1 (f1) values ("test9"), ("bar"); -connection master1; -set transaction isolation level serializable; -select * from t1; -connection master; -commit; - -drop table if exists t1; -create table t1 (f1 char(20) not null) type = gemini; -set transaction isolation level read uncommitted; -insert into t1 (f1) values ("test10"), ("bar"); -connection master1; -set transaction isolation level read uncommitted; -select * from t1; -connection master; -commit; - -drop table if exists t1; -create table t1 (f1 char(20) not null) type = gemini; -set transaction isolation level read uncommitted; -insert into t1 (f1) values ("test11"), ("bar"); -connection master1; -set transaction isolation level read committed; -select * from t1; -connection master; -commit; - -drop table if exists t1; -create table t1 (f1 char(20) not null) type = gemini; -set transaction isolation level read uncommitted; -insert into t1 (f1) values ("test12"), ("bar"); -connection master1; -set transaction isolation level repeatable read; -select * from t1; -connection master; -commit; - -drop table if exists t1; -create table t1 (f1 char(20) not null) type = gemini; -set transaction isolation level read committed; -insert into t1 (f1) values ("test13"), ("bar"); -connection master1; -set transaction isolation level serializable; -select * from t1; -connection master; -commit; - -drop table if exists t1; -create table t1 (f1 char(20) not null) type = gemini; -set transaction isolation level read committed; -insert into t1 (f1) values ("test14"), ("bar"); -connection master1; -set transaction isolation level read uncommitted; -select * from t1; -connection master; -commit; - -drop table if exists t1; -create table t1 (f1 char(20) not null) type = gemini; -set transaction isolation level read committed; -insert into t1 (f1) values ("test15"), ("bar"); -connection master1; -set transaction isolation level read committed; -select * from t1; -connection master; -commit; - -drop table if exists t1; -create table t1 (f1 char(20) not null) type = gemini; -set transaction isolation level read committed; -insert into t1 (f1) values ("test16"), ("bar"); -connection master1; -set transaction isolation level repeatable read; -select * from t1; -connection master; -commit; - -drop table if exists t1; -create table t1 (f1 char(20) not null) type = gemini; -set transaction isolation level repeatable read; -insert into t1 (f1) values ("test17"), ("bar"); -connection master1; -set transaction isolation level serializable; -select * from t1; -connection master; -commit; - -drop table if exists t1; -create table t1 (f1 char(20) not null) type = gemini; -set transaction isolation level repeatable read; -insert into t1 (f1) values ("test18"), ("bar"); -connection master1; -set transaction isolation level read uncommitted; -select * from t1; -connection master; -commit; - -drop table if exists t1; -create table t1 (f1 char(20) not null) type = gemini; -set transaction isolation level repeatable read; -insert into t1 (f1) values ("test19"), ("bar"); -connection master1; -set transaction isolation level read committed; -select * from t1; -connection master; -commit; - -drop table if exists t1; -create table t1 (f1 char(20) not null) type = gemini; -set transaction isolation level repeatable read; -insert into t1 (f1) values ("test20"), ("bar"); -connection master1; -set transaction isolation level repeatable read; -select * from t1; -connection master; -commit; -drop table t1; diff --git a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh index c99126cdf53..0da457582f1 100644 --- a/scripts/mysql_install_db.sh +++ b/scripts/mysql_install_db.sh @@ -294,7 +294,7 @@ fi echo "Installing all prepared tables" if eval "$execdir/mysqld $defaults --bootstrap --skip-grant-tables \ - --basedir=$basedir --datadir=$ldata --skip-innodb --skip-gemini --skip-bdb $args" << END_OF_DATA + --basedir=$basedir --datadir=$ldata --skip-innodb --skip-bdb $args" << END_OF_DATA use mysql; $c_d $i_d diff --git a/sql/Makefile.am b/sql/Makefile.am index a11b1d0c252..a1e82b2844a 100644 --- a/sql/Makefile.am +++ b/sql/Makefile.am @@ -21,7 +21,7 @@ MYSQLDATAdir = $(localstatedir) MYSQLSHAREdir = $(pkgdatadir) MYSQLBASEdir= $(prefix) INCLUDES = @MT_INCLUDES@ \ - @bdb_includes@ @innodb_includes@ @gemini_includes@ \ + @bdb_includes@ @innodb_includes@ \ -I$(srcdir)/../include \ -I$(srcdir)/../regex \ -I$(srcdir) -I../include -I. $(openssl_includes) @@ -43,7 +43,7 @@ LDADD = ../isam/libnisam.a \ mysqld_LDADD = @MYSQLD_EXTRA_LDFLAGS@ \ @bdb_libs@ @innodb_libs@ @pstack_libs@ \ - @gemini_libs@ @innodb_system_libs@ \ + @innodb_system_libs@ \ $(LDADD) $(CXXLDFLAGS) $(WRAPLIBS) @LIBDL@ @openssl_libs@ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \ item_strfunc.h item_timefunc.h item_uniq.h \ @@ -53,7 +53,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 \ - ha_gemini.h opt_range.h opt_ft.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 \ log_event.h mini_client.h sql_repl.h slave.h \ @@ -75,7 +75,7 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc \ time.cc opt_range.cc opt_sum.cc opt_ft.cc \ records.cc filesort.cc handler.cc \ ha_heap.cc ha_myisam.cc ha_myisammrg.cc \ - ha_berkeley.cc ha_innobase.cc ha_gemini.cc \ + ha_berkeley.cc ha_innobase.cc \ ha_isam.cc ha_isammrg.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 \ diff --git a/sql/field.cc b/sql/field.cc index b34f58439db..85a5076e09a 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -4086,60 +4086,6 @@ const char *Field_blob::unpack(char *to, const char *from) return from+length; } - -#ifdef HAVE_GEMINI_DB -/* Blobs in Gemini tables are stored separately from the rows which contain -** them (except for tiny blobs, which are stored in the row). For all other -** blob types (blob, mediumblob, longblob), the row contains the length of -** the blob data and a blob id. These methods (pack_id, get_id, and -** unpack_id) handle packing and unpacking blob fields in Gemini rows. -*/ -char *Field_blob::pack_id(char *to, const char *from, ulonglong id, uint max_length) -{ - char *save=ptr; - ptr=(char*) from; - ulong length=get_length(); // Length of from string - if (length > max_length) - { - ptr=to; - length=max_length; - store_length(length); // Store max length - ptr=(char*) from; - } - else - memcpy(to,from,packlength); // Copy length - if (length) - { - int8store(to+packlength, id); - } - ptr=save; // Restore org row pointer - return to+packlength+sizeof(id); -} - - -ulonglong Field_blob::get_id(const char *from) -{ - ulonglong id = 0; - ulong length=get_length(from); - if (length) - id=uint8korr(from+packlength); - return id; -} - - -const char *Field_blob::unpack_id(char *to, const char *from, const char *bdata) -{ - memcpy(to,from,packlength); - ulong length=get_length(from); - from+=packlength; - if (length) - memcpy_fixed(to+packlength, &bdata, sizeof(bdata)); - else - bzero(to+packlength,sizeof(bdata)); - return from+sizeof(ulonglong); -} -#endif /* HAVE_GEMINI_DB */ - /* Keys for blobs are like keys on varchars */ int Field_blob::pack_cmp(const char *a, const char *b, uint key_length) diff --git a/sql/field.h b/sql/field.h index 8f60b7e008b..47bf5cc02ef 100644 --- a/sql/field.h +++ b/sql/field.h @@ -883,21 +883,6 @@ public: } char *pack(char *to, const char *from, uint max_length= ~(uint) 0); const char *unpack(char *to, const char *from); -#ifdef HAVE_GEMINI_DB - char *pack_id(char *to, const char *from, ulonglong id, - uint max_length= ~(uint) 0); - ulonglong get_id(const char *from); - const char *unpack_id(char *to, const char *from, const char *bdata); - inline void get_ptr_from_key_image(char **str,char *key_str) - { - *str = key_str + sizeof(uint16); - } - inline uint get_length_from_key_image(char *key_str) - { - return uint2korr(key_str); - } - enum_field_types blobtype() { return (packlength == 1 ? FIELD_TYPE_TINY_BLOB : FIELD_TYPE_BLOB);} -#endif char *pack_key(char *to, const char *from, uint max_length); char *pack_key_from_key_image(char* to, const char *from, uint max_length); int pack_cmp(const char *a, const char *b, uint key_length); diff --git a/sql/ha_gemini.cc b/sql/ha_gemini.cc deleted file mode 100644 index a60841c3fe6..00000000000 --- a/sql/ha_gemini.cc +++ /dev/null @@ -1,3630 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & 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 */ - -/* This file is based on ha_berkeley.cc */ - -#ifdef __GNUC__ -#pragma implementation // gcc: Class implementation -#endif - -#include "mysql_priv.h" -#ifdef HAVE_GEMINI_DB -#include "ha_gemini.h" -#include "dbconfig.h" -#include "dsmpub.h" -#include "recpub.h" -#include "vststat.h" - -#include <m_ctype.h> -#include <myisampack.h> -#include <m_string.h> -#include <assert.h> -#include <hash.h> -#include <stdarg.h> -#include "geminikey.h" - -#define gemini_msg MSGD_CALLBACK - -pthread_mutex_t gem_mutex; - -static HASH gem_open_tables; -static GEM_SHARE *get_share(const char *table_name, TABLE *table); -static int free_share(GEM_SHARE *share, bool mutex_is_locked); -static byte* gem_get_key(GEM_SHARE *share,uint *length, - my_bool not_used __attribute__((unused))); -static void gemini_lock_table_overflow_error(dsmContext_t *pcontext); - -const char *ha_gemini_ext=".gmd"; -const char *ha_gemini_idx_ext=".gmi"; - -bool gemini_skip=0; -long gemini_options = 0; -long gemini_buffer_cache; -long gemini_io_threads; -long gemini_log_cluster_size; -long gemini_locktablesize; -long gemini_lock_wait_timeout; -long gemini_spin_retries; -long gemini_connection_limit; -char *gemini_basedir; - -const char gemini_dbname[] = "gemini"; -dsmContext_t *pfirstContext = NULL; - -ulong gemini_recovery_options = GEMINI_RECOVERY_FULL; -/* bits in gemini_recovery_options */ -const char *gemini_recovery_names[] = -{ "FULL", "NONE", "FORCE" }; -TYPELIB gemini_recovery_typelib= {array_elements(gemini_recovery_names)-1,"", - gemini_recovery_names}; - -const int start_of_name = 2; /* Name passed as ./<db>/<table-name> - and we're not interested in the ./ */ -static const int keyBufSize = MAXKEYSZ + FULLKEYHDRSZ + MAX_REF_PARTS + 16; - -static int gemini_tx_begin(THD *thd); -static void print_msg(THD *thd, const char *table_name, const char *op_name, - const char *msg_type, const char *fmt, ...); - -static int gemini_helper_threads(dsmContext_t *pContext); -pthread_handler_decl(gemini_watchdog,arg ); -pthread_handler_decl(gemini_rl_writer,arg ); -pthread_handler_decl(gemini_apw,arg); - -/* General functions */ - -bool gemini_init(void) -{ - dsmStatus_t rc = 0; - char pmsgsfile[MAXPATHN]; - - DBUG_ENTER("gemini_init"); - - gemini_basedir=mysql_home; - /* If datadir isn't set, bail out */ - if (*mysql_real_data_home == '\0') - { - goto badret; - } - - /* dsmContextCreate and dsmContextSetString(DSM_TAGDB_DBNAME) must - ** be the first DSM calls we make so that we can log any errors which - ** occur in subsequent DSM calls. DO NOT INSERT ANY DSM CALLS IN - ** BETWEEN THIS COMMENT AND THE COMMENT THAT SAYS "END OF CODE..." - */ - /* Gotta connect to the database regardless of the operation */ - rc = dsmContextCreate(&pfirstContext); - if( rc != 0 ) - { - gemini_msg(pfirstContext, "dsmContextCreate failed %l",rc); - goto badret; - } - /* This call will also open the log file */ - rc = dsmContextSetString(pfirstContext, DSM_TAGDB_DBNAME, - strlen(gemini_dbname), (TEXT *)gemini_dbname); - if( rc != 0 ) - { - gemini_msg(pfirstContext, "Dbname tag failed %l", rc); - goto badret; - } - /* END OF CODE NOT TO MESS WITH */ - - fn_format(pmsgsfile, GEM_MSGS_FILE, language, ".db", 2 | 4); - rc = dsmContextSetString(pfirstContext, DSM_TAGDB_MSGS_FILE, - strlen(pmsgsfile), (TEXT *)pmsgsfile); - if( rc != 0 ) - { - gemini_msg(pfirstContext, "MSGS_DIR tag failed %l", rc); - goto badret; - } - - strxmov(pmsgsfile, gemini_basedir, GEM_SYM_FILE, NullS); - rc = dsmContextSetString(pfirstContext, DSM_TAGDB_SYMFILE, - strlen(pmsgsfile), (TEXT *)pmsgsfile); - if( rc != 0 ) - { - gemini_msg(pfirstContext, "SYMFILE tag failed %l", rc); - goto badret; - } - - rc = dsmContextSetLong(pfirstContext,DSM_TAGDB_ACCESS_TYPE,DSM_ACCESS_STARTUP); - if ( rc != 0 ) - { - gemini_msg(pfirstContext, "ACCESS TAG set failed %l",rc); - goto badret; - } - rc = dsmContextSetLong(pfirstContext,DSM_TAGDB_ACCESS_ENV, DSM_SQL_ENGINE); - if( rc != 0 ) - { - gemini_msg(pfirstContext, "ACCESS_ENV set failed %l",rc); - goto badret; - } - - rc = dsmContextSetString(pfirstContext, DSM_TAGDB_DATADIR, - strlen(mysql_real_data_home), - (TEXT *)mysql_real_data_home); - if( rc != 0 ) - { - gemini_msg(pfirstContext, "Datadir tag failed %l", rc); - goto badret; - } - - rc = dsmContextSetLong(pfirstContext, DSM_TAGDB_MAX_USERS, - gemini_connection_limit); - if(rc != 0) - { - gemini_msg(pfirstContext, "MAX_USERS tag set failed %l",rc); - goto badret; - } - - rc = dsmContextSetLong(pfirstContext, DSM_TAGDB_DEFAULT_LOCK_TIMEOUT, - gemini_lock_wait_timeout); - if(rc != 0) - { - gemini_msg(pfirstContext, "MAX_LOCK_ENTRIES tag set failed %l",rc); - goto badret; - } - - rc = dsmContextSetLong(pfirstContext, DSM_TAGDB_MAX_LOCK_ENTRIES, - gemini_locktablesize); - if(rc != 0) - { - gemini_msg(pfirstContext, "MAX_LOCK_ENTRIES tag set failed %l",rc); - goto badret; - } - - rc = dsmContextSetLong(pfirstContext, DSM_TAGDB_SPIN_AMOUNT, - gemini_spin_retries); - if(rc != 0) - { - gemini_msg(pfirstContext, "SPIN_AMOUNT tag set failed %l",rc); - goto badret; - } - - /* blocksize is hardcoded to 8K. Buffer cache is in bytes - need to convert this to 8K blocks */ - gemini_buffer_cache = gemini_buffer_cache / 8192; - rc = dsmContextSetLong(pfirstContext, DSM_TAGDB_DB_BUFFERS, - gemini_buffer_cache); - if(rc != 0) - { - gemini_msg(pfirstContext, "DB_BUFFERS tag set failed %l",rc); - goto badret; - } - - rc = dsmContextSetLong(pfirstContext, DSM_TAGDB_FLUSH_AT_COMMIT, - ((gemini_options & GEMOPT_FLUSH_LOG) ? 0 : 1)); - if(rc != 0) - { - gemini_msg(pfirstContext, "FLush_Log_At_Commit tag set failed %l",rc); - goto badret; - } - rc = dsmContextSetLong(pfirstContext, DSM_TAGDB_DIRECT_IO, - ((gemini_options & GEMOPT_UNBUFFERED_IO) ? 1 : 0)); - if(rc != 0) - { - gemini_msg(pfirstContext, "DIRECT_IO tag set failed %l",rc); - goto badret; - } - - rc = dsmContextSetLong(pfirstContext, DSM_TAGDB_CRASH_PROTECTION, - ((gemini_recovery_options & GEMINI_RECOVERY_FULL) ? 1 : 0)); - if(rc != 0) - { - gemini_msg(pfirstContext, "CRASH_PROTECTION tag set failed %l",rc); - goto badret; - } - - if (gemini_recovery_options & GEMINI_RECOVERY_FORCE) - { - rc = dsmContextSetLong(pfirstContext, DSM_TAGDB_FORCE_ACCESS, 1); - if(rc != 0) - { - printf("CRASH_PROTECTION tag set failed %ld",rc); - goto badret; - } - } - - /* cluster size will come in bytes, need to convert it to - 16 K units. */ - gemini_log_cluster_size = (gemini_log_cluster_size + 16383) / 16384; - rc = dsmContextSetLong(pfirstContext, DSM_TAGDB_BI_CLUSTER_SIZE, - gemini_log_cluster_size); - - if(rc != 0) - { - gemini_msg(pfirstContext, "CRASH_PROTECTION tag set failed %l",rc); - goto badret; - } - - rc = dsmUserConnect(pfirstContext,(TEXT *)"Multi-user", - DSM_DB_OPENDB | DSM_DB_OPENFILE); - if( rc != 0 ) - { - /* Message is output in dbenv() */ - goto badret; - } - /* Set access to shared for subsequent user connects */ - rc = dsmContextSetLong(pfirstContext,DSM_TAGDB_ACCESS_TYPE,DSM_ACCESS_SHARED); - - rc = gemini_helper_threads(pfirstContext); - - - (void) hash_init(&gem_open_tables,32,0,0, - (hash_get_key) gem_get_key,0,0); - pthread_mutex_init(&gem_mutex,NULL); - - - DBUG_RETURN(0); - -badret: - gemini_skip = 1; - DBUG_RETURN(0); -} - -static int gemini_helper_threads(dsmContext_t *pContext) -{ - int rc = 0; - int i; - pthread_attr_t thr_attr; - - pthread_t hThread; - DBUG_ENTER("gemini_helper_threads"); - - (void) pthread_attr_init(&thr_attr); -#if !defined(HAVE_DEC_3_2_THREADS) - pthread_attr_setscope(&thr_attr,PTHREAD_SCOPE_SYSTEM); - (void) pthread_attr_setdetachstate(&thr_attr,PTHREAD_CREATE_DETACHED); - pthread_attr_setstacksize(&thr_attr,32768); -#endif - rc = pthread_create (&hThread, &thr_attr, gemini_watchdog, (void *)pContext); - if (rc) - { - gemini_msg(pContext, "Can't Create gemini watchdog thread"); - goto done; - } - if(!gemini_io_threads) - goto done; - - rc = pthread_create(&hThread, &thr_attr, gemini_rl_writer, (void *)pContext); - if(rc) - { - gemini_msg(pContext, "Can't create Gemini recovery log writer thread"); - goto done; - } - - for(i = gemini_io_threads - 1;i;i--) - { - rc = pthread_create(&hThread, &thr_attr, gemini_apw, (void *)pContext); - if(rc) - { - gemini_msg(pContext, "Can't create Gemini database page writer thread"); - goto done; - } - } -done: - - DBUG_RETURN(rc); -} - -pthread_handler_decl(gemini_watchdog,arg ) -{ - int rc = 0; - dsmContext_t *pcontext = (dsmContext_t *)arg; - dsmContext_t *pmyContext = NULL; - - - rc = dsmContextCopy(pcontext,&pmyContext, DSMCONTEXTDB); - if( rc != 0 ) - { - gemini_msg(pcontext, "dsmContextCopy failed for Gemini watchdog %d",rc); - - return 0; - } - rc = dsmUserConnect(pmyContext,NULL,0); - - if( rc != 0 ) - { - gemini_msg(pcontext, "dsmUserConnect failed for Gemini watchdog %d",rc); - - return 0; - } - - my_thread_init(); - pthread_detach_this_thread(); - - while(rc == 0) - { - rc = dsmDatabaseProcessEvents(pmyContext); - if(!rc) - rc = dsmWatchdog(pmyContext); - sleep(1); - } - rc = dsmUserDisconnect(pmyContext,0); - my_thread_end(); - return 0; -} - -pthread_handler_decl(gemini_rl_writer,arg ) -{ - int rc = 0; - dsmContext_t *pcontext = (dsmContext_t *)arg; - dsmContext_t *pmyContext = NULL; - - - rc = dsmContextCopy(pcontext,&pmyContext, DSMCONTEXTDB); - if( rc != 0 ) - { - gemini_msg(pcontext, "dsmContextCopy failed for Gemini recovery log writer %d",rc); - - return 0; - } - rc = dsmUserConnect(pmyContext,NULL,0); - - if( rc != 0 ) - { - gemini_msg(pcontext, "dsmUserConnect failed for Gemini recovery log writer %d",rc); - - return 0; - } - - my_thread_init(); - pthread_detach_this_thread(); - - while(rc == 0) - { - rc = dsmRLwriter(pmyContext); - } - rc = dsmUserDisconnect(pmyContext,0); - my_thread_end(); - return 0; -} - -pthread_handler_decl(gemini_apw,arg ) -{ - int rc = 0; - dsmContext_t *pcontext = (dsmContext_t *)arg; - dsmContext_t *pmyContext = NULL; - - my_thread_init(); - pthread_detach_this_thread(); - - rc = dsmContextCopy(pcontext,&pmyContext, DSMCONTEXTDB); - if( rc != 0 ) - { - gemini_msg(pcontext, "dsmContextCopy failed for Gemini page writer %d",rc); - my_thread_end(); - return 0; - } - rc = dsmUserConnect(pmyContext,NULL,0); - - if( rc != 0 ) - { - gemini_msg(pcontext, "dsmUserConnect failed for Gemini page writer %d",rc); - my_thread_end(); - return 0; - } - - while(rc == 0) - { - rc = dsmAPW(pmyContext); - } - rc = dsmUserDisconnect(pmyContext,0); - my_thread_end(); - return 0; -} - -int gemini_set_option_long(int optid, long optval) -{ - dsmStatus_t rc = 0; - - switch (optid) - { - case GEM_OPTID_SPIN_RETRIES: - /* If we don't have a context yet, skip the set and just save the - ** value in gemini_spin_retries for a later gemini_init(). This - ** may not ever happen, but we're covered if it does. - */ - if (pfirstContext) - { - rc = dsmContextSetLong(pfirstContext, DSM_TAGDB_SPIN_AMOUNT, - optval); - } - if (rc) - { - gemini_msg(pfirstContext, "SPIN_AMOUNT tag set failed %l",rc); - } - else - { - gemini_spin_retries = optval; - } - break; - } - - return rc; -} - -static int gemini_connect(THD *thd) -{ - DBUG_ENTER("gemini_connect"); - - dsmStatus_t rc; - - rc = dsmContextCopy(pfirstContext,(dsmContext_t **)&thd->gemini.context, - DSMCONTEXTDB); - if( rc != 0 ) - { - gemini_msg(pfirstContext, "dsmContextCopy failed %l",rc); - - return(rc); - } - rc = dsmUserConnect((dsmContext_t *)thd->gemini.context,NULL,0); - - if( rc != 0 ) - { - gemini_msg(pfirstContext, "dsmUserConnect failed %l",rc); - - return(rc); - } - rc = (dsmStatus_t)gemini_tx_begin(thd); - - DBUG_RETURN(rc); -} - -void gemini_disconnect(THD *thd) -{ - dsmStatus_t rc; - - if(thd->gemini.context) - { - rc = dsmUserDisconnect((dsmContext_t *)thd->gemini.context,0); - } - return; -} - -bool gemini_end(void) -{ - dsmStatus_t rc; - THD *thd; - - DBUG_ENTER("gemini_end"); - - hash_free(&gem_open_tables); - pthread_mutex_destroy(&gem_mutex); - if(pfirstContext) - { - rc = dsmShutdownSet(pfirstContext, DSM_SHUTDOWN_NORMAL); - sleep(2); - rc = dsmContextSetLong(pfirstContext,DSM_TAGDB_ACCESS_TYPE,DSM_ACCESS_STARTUP); - rc = dsmShutdown(pfirstContext, DSMNICEBIT,DSMNICEBIT); - } - DBUG_RETURN(0); -} - -bool gemini_flush_logs() -{ - DBUG_ENTER("gemini_flush_logs"); - - DBUG_RETURN(0); -} - -static int gemini_tx_begin(THD *thd) -{ - dsmStatus_t rc; - DBUG_ENTER("gemini_tx_begin"); - - thd->gemini.savepoint = 1; - - rc = dsmTransaction((dsmContext_t *)thd->gemini.context, - &thd->gemini.savepoint,DSMTXN_START,0,NULL); - if(!rc) - thd->gemini.needSavepoint = 1; - - thd->gemini.tx_isolation = thd->tx_isolation; - - DBUG_PRINT("trans",("beginning transaction")); - DBUG_RETURN(rc); -} - -int gemini_commit(THD *thd) -{ - dsmStatus_t rc; - LONG txNumber = 0; - - DBUG_ENTER("gemini_commit"); - - if(!thd->gemini.context) - DBUG_RETURN(0); - - rc = dsmTransaction((dsmContext_t *)thd->gemini.context, - 0,DSMTXN_COMMIT,0,NULL); - if(!rc) - rc = gemini_tx_begin(thd); - - thd->gemini.lock_count = 0; - - DBUG_PRINT("trans",("ending transaction")); - DBUG_RETURN(rc); -} - -int gemini_rollback(THD *thd) -{ - dsmStatus_t rc; - LONG txNumber; - - DBUG_ENTER("gemini_rollback"); - DBUG_PRINT("trans",("aborting transaction")); - - if(!thd->gemini.context) - DBUG_RETURN(0); - - thd->gemini.savepoint = 0; - rc = dsmTransaction((dsmContext_t *)thd->gemini.context, - &thd->gemini.savepoint,DSMTXN_ABORT,0,NULL); - if(!rc) - rc = gemini_tx_begin(thd); - - thd->gemini.lock_count = 0; - - DBUG_RETURN(rc); -} - -int gemini_rollback_to_savepoint(THD *thd) -{ - dsmStatus_t rc = 0; - DBUG_ENTER("gemini_rollback_to_savepoint"); - if(thd->gemini.savepoint > 1) - { - rc = dsmTransaction((dsmContext_t *)thd->gemini.context, - &thd->gemini.savepoint,DSMTXN_UNSAVE,0,NULL); - } - DBUG_RETURN(rc); -} - -int gemini_recovery_logging(THD *thd, bool on) -{ - int error; - int noLogging; - - if(!thd->gemini.context) - return 0; - - if(on) - noLogging = 0; - else - noLogging = 1; - - error = dsmContextSetLong((dsmContext_t *)thd->gemini.context, - DSM_TAGCONTEXT_NO_LOGGING,noLogging); - return error; -} - -/* gemDataType - translates from mysql data type constant to gemini - key services data type contstant */ -int gemDataType ( int mysqlType ) -{ - switch (mysqlType) - { - case FIELD_TYPE_LONG: - case FIELD_TYPE_TINY: - case FIELD_TYPE_SHORT: - case FIELD_TYPE_TIMESTAMP: - case FIELD_TYPE_LONGLONG: - case FIELD_TYPE_INT24: - case FIELD_TYPE_DATE: - case FIELD_TYPE_TIME: - case FIELD_TYPE_DATETIME: - case FIELD_TYPE_YEAR: - case FIELD_TYPE_NEWDATE: - case FIELD_TYPE_ENUM: - case FIELD_TYPE_SET: - return GEM_INT; - case FIELD_TYPE_DECIMAL: - return GEM_DECIMAL; - case FIELD_TYPE_FLOAT: - return GEM_FLOAT; - case FIELD_TYPE_DOUBLE: - return GEM_DOUBLE; - case FIELD_TYPE_TINY_BLOB: - return GEM_TINYBLOB; - case FIELD_TYPE_MEDIUM_BLOB: - return GEM_MEDIUMBLOB; - case FIELD_TYPE_LONG_BLOB: - return GEM_LONGBLOB; - case FIELD_TYPE_BLOB: - return GEM_BLOB; - case FIELD_TYPE_VAR_STRING: - case FIELD_TYPE_STRING: - return GEM_CHAR; - } - return -1; -} - -/***************************************************************************** -** Gemini tables -*****************************************************************************/ - -const char **ha_gemini::bas_ext() const -{ static const char *ext[]= { ha_gemini_ext, ha_gemini_idx_ext, NullS }; - return ext; -} - - -int ha_gemini::open(const char *name, int mode, uint test_if_locked) -{ - dsmObject_t tableId = 0; - THD *thd; - char name_buff[FN_REFLEN]; - char tabname_buff[FN_REFLEN]; - char dbname_buff[FN_REFLEN]; - unsigned i,nameLen; - LONG txNumber; - dsmStatus_t rc; - - DBUG_ENTER("ha_gemini::open"); - - thd = current_thd; - /* Init shared structure */ - if (!(share=get_share(name,table))) - { - DBUG_RETURN(1); /* purecov: inspected */ - } - thr_lock_data_init(&share->lock,&lock,(void*) 0); - - ref_length = sizeof(dsmRecid_t); - - if(thd->gemini.context == NULL) - { - /* Need to get this thread a connection into the database */ - rc = gemini_connect(thd); - if(rc) - return rc; - } - if (!(rec_buff=(byte*)my_malloc(table->rec_buff_length, - MYF(MY_WME)))) - { - DBUG_RETURN(1); - } - - /* separate out the name of the table and the database (a VST must be - ** created in the mysql database) - */ - rc = gemini_parse_table_name(name, dbname_buff, tabname_buff); - if (rc == 0) - { - if (strcmp(dbname_buff, "mysql") == 0) - { - tableId = gemini_is_vst(tabname_buff); - } - } - sprintf(name_buff, "%s.%s", dbname_buff, tabname_buff); - - /* if it's not a VST, get the table number the regular way */ - if (!tableId) - { - rc = dsmObjectNameToNum((dsmContext_t *)thd->gemini.context, - (dsmText_t *)name_buff, - &tableId); - if (rc) - { - gemini_msg((dsmContext_t *)thd->gemini.context, - "Unable to find table number for %s", name_buff); - DBUG_RETURN(rc); - } - } - tableNumber = tableId; - - if(!rc) - rc = index_open(name_buff); - - fixed_length_row=!(table->db_create_options & HA_OPTION_PACK_RECORD); - key_read = 0; - using_ignore = 0; - - /* Get the gemini table status -- we want to know if the table - crashed while being in the midst of a repair operation */ - rc = dsmTableStatus((dsmContext_t *)thd->gemini.context, - tableNumber,&tableStatus); - if(tableStatus == DSM_OBJECT_IN_REPAIR) - tableStatus = HA_ERR_CRASHED; - - pthread_mutex_lock(&share->mutex); - share->use_count++; - pthread_mutex_unlock(&share->mutex); - - if (table->blob_fields) - { - /* Allocate room for the blob ids from an unpacked row. Note that - ** we may not actually need all of this space because tiny blobs - ** are stored in the packed row, not in a separate storage object - ** like larger blobs. But we allocate an entry for all blobs to - ** keep the code simpler. - */ - pBlobDescs = (gemBlobDesc_t *)my_malloc( - table->blob_fields * sizeof(gemBlobDesc_t), - MYF(MY_WME | MY_ZEROFILL)); - } - else - { - pBlobDescs = 0; - } - - get_index_stats(thd); - info(HA_STATUS_CONST); - - DBUG_RETURN (rc); -} - -/* Look up and store the object numbers for the indexes on this table */ -int ha_gemini::index_open(char *tableName) -{ - dsmStatus_t rc = 0; - int nameLen; - - DBUG_ENTER("ha_gemini::index_open"); - if(table->keys) - { - THD *thd = current_thd; - dsmObject_t objectNumber; - if (!(pindexNumbers=(dsmIndex_t *)my_malloc(table->keys*sizeof(dsmIndex_t), - MYF(MY_WME)))) - { - DBUG_RETURN(1); - } - nameLen = strlen(tableName); - tableName[nameLen] = '.'; - nameLen++; - - for( uint i = 0; i < table->keys && !rc; i++) - { - strcpy(&tableName[nameLen],table->key_info[i].name); - rc = dsmObjectNameToNum((dsmContext_t *)thd->gemini.context, - (dsmText_t *)tableName, - &objectNumber); - if (rc) - { - gemini_msg((dsmContext_t *)thd->gemini.context, - "Unable to file Index number for %s", tableName); - DBUG_RETURN(rc); - } - pindexNumbers[i] = objectNumber; - } - } - else - pindexNumbers = 0; - - DBUG_RETURN(rc); -} - -int ha_gemini::close(void) -{ - DBUG_ENTER("ha_gemini::close"); - my_free((char*)rec_buff,MYF(MY_ALLOW_ZERO_PTR)); - rec_buff = 0; - my_free((char *)pindexNumbers,MYF(MY_ALLOW_ZERO_PTR)); - pindexNumbers = 0; - - if (pBlobDescs) - { - for (uint i = 0; i < table->blob_fields; i++) - { - my_free((char*)pBlobDescs[i].pBlob, MYF(MY_ALLOW_ZERO_PTR)); - } - my_free((char *)pBlobDescs, MYF(0)); - pBlobDescs = 0; - } - - DBUG_RETURN(free_share(share, 0)); -} - - -int ha_gemini::write_row(byte * record) -{ - int error = 0; - dsmRecord_t dsmRecord; - THD *thd; - - DBUG_ENTER("write_row"); - - if(tableStatus == HA_ERR_CRASHED) - DBUG_RETURN(tableStatus); - - thd = current_thd; - - statistic_increment(ha_write_count,&LOCK_status); - if (table->time_stamp) - update_timestamp(record+table->time_stamp-1); - - if(thd->gemini.needSavepoint || using_ignore) - { - thd->gemini.savepoint++; - error = dsmTransaction((dsmContext_t *)thd->gemini.context, - &thd->gemini.savepoint, - DSMTXN_SAVE, 0, 0); - if (error) - DBUG_RETURN(error); - thd->gemini.needSavepoint = 0; - } - - if (table->next_number_field && record == table->record[0]) - { - if(thd->next_insert_id) - { - ULONG64 nr; - /* A set insert-id statement so set the auto-increment value if this - value is higher than it's current value */ - error = dsmTableAutoIncrement((dsmContext_t *)thd->gemini.context, - tableNumber, (ULONG64 *)&nr,1); - if(thd->next_insert_id > nr) - { - error = dsmTableAutoIncrementSet((dsmContext_t *)thd->gemini.context, - tableNumber, - (ULONG64)thd->next_insert_id); - } - } - - update_auto_increment(); - } - - dsmRecord.table = tableNumber; - dsmRecord.maxLength = table->rec_buff_length; - - if ((error=pack_row((byte **)&dsmRecord.pbuffer, (int *)&dsmRecord.recLength, - record, FALSE))) - { - DBUG_RETURN(error); - } - - error = dsmRecordCreate((dsmContext_t *)thd->gemini.context, - &dsmRecord,0); - - if(!error) - { - error = handleIndexEntries(record, dsmRecord.recid,KEY_CREATE); - if(error == HA_ERR_FOUND_DUPP_KEY && using_ignore) - { - dsmStatus_t rc; - rc = dsmTransaction((dsmContext_t *)thd->gemini.context, - &thd->gemini.savepoint,DSMTXN_UNSAVE,0,NULL); - thd->gemini.needSavepoint = 1; - } - } - if(error == DSM_S_RQSTREJ) - error = HA_ERR_LOCK_WAIT_TIMEOUT; - - DBUG_RETURN(error); -} - -longlong ha_gemini::get_auto_increment() -{ - longlong nr; - int error; - int update; - THD *thd=current_thd; - - if(thd->lex.sql_command == SQLCOM_SHOW_TABLES) - update = 0; - else - update = 1; - - error = dsmTableAutoIncrement((dsmContext_t *)thd->gemini.context, - tableNumber, (ULONG64 *)&nr, - update); - return nr; -} - -/* Put or delete index entries for a row */ -int ha_gemini::handleIndexEntries(const byte * record, dsmRecid_t recid, - enum_key_string_options option) -{ - dsmStatus_t rc = 0; - - DBUG_ENTER("handleIndexEntries"); - - for (uint i = 0; i < table->keys && rc == 0; i++) - { - rc = handleIndexEntry(record, recid,option, i); - } - DBUG_RETURN(rc); -} - -int ha_gemini::handleIndexEntry(const byte * record, dsmRecid_t recid, - enum_key_string_options option,uint keynr) -{ - dsmStatus_t rc = 0; - KEY *key_info; - int keyStringLen; - bool thereIsAnull; - THD *thd; - - AUTOKEY(theKey,keyBufSize); - - DBUG_ENTER("handleIndexEntry"); - - thd = current_thd; - key_info=table->key_info+keynr; - thereIsAnull = FALSE; - rc = createKeyString(record, key_info, theKey.akey.keystr, - sizeof(theKey.apad),&keyStringLen, - (short)pindexNumbers[keynr], - &thereIsAnull); - if(!rc) - { - theKey.akey.index = pindexNumbers[keynr]; - theKey.akey.keycomps = (COUNT)key_info->key_parts; - - /* We have to subtract three here since cxKeyPrepare - expects that the three lead bytes of the header are - not counted in this length -- But cxKeyPrepare also - expects that these three bytes are present in the keystr */ - theKey.akey.keyLen = (COUNT)keyStringLen - FULLKEYHDRSZ; - theKey.akey.unknown_comp = (dsmBoolean_t)thereIsAnull; - theKey.akey.word_index = 0; - theKey.akey.descending_key =0; - if(option == KEY_CREATE) - { - rc = dsmKeyCreate((dsmContext_t *)thd->gemini.context, &theKey.akey, - (dsmTable_t)tableNumber, recid, NULL); - if(rc == DSM_S_IXDUPKEY) - { - last_dup_key=keynr; - rc = HA_ERR_FOUND_DUPP_KEY; - } - } - else if(option == KEY_DELETE) - { - rc = dsmKeyDelete((dsmContext_t *)thd->gemini.context, &theKey.akey, - (dsmTable_t)tableNumber, recid, 0, NULL); - } - else - { - /* KEY_CHECK */ - dsmCursid_t aCursorId; - int error; - - rc = dsmCursorCreate((dsmContext_t *)thd->gemini.context, - (dsmTable_t)tableNumber, - (dsmIndex_t)pindexNumbers[keynr], - &aCursorId,NULL); - - rc = dsmCursorFind((dsmContext_t *)thd->gemini.context, - &aCursorId,&theKey.akey,NULL,DSMDBKEY, - DSMFINDFIRST,DSM_LK_SHARE,0, - &lastRowid,0); - error = dsmCursorDelete((dsmContext_t *)thd->gemini.context, - &aCursorId, 0); - - } - } - DBUG_RETURN(rc); -} - -int ha_gemini::createKeyString(const byte * record, KEY *pkeyinfo, - unsigned char *pkeyBuf, int bufSize, - int *pkeyStringLen, - short geminiIndexNumber, - bool *thereIsAnull) -{ - dsmStatus_t rc = 0; - int componentLen; - int fieldType; - int isNull; - uint key_part_length; - - KEY_PART_INFO *key_part; - - DBUG_ENTER("createKeyString"); - - rc = gemKeyInit(pkeyBuf,pkeyStringLen, geminiIndexNumber); - - for(uint i = 0; i < pkeyinfo->key_parts && rc == 0; i++) - { - unsigned char *pos; - - key_part = pkeyinfo->key_part + i; - key_part_length = key_part->length; - fieldType = gemDataType(key_part->field->type()); - switch (fieldType) - { - case GEM_CHAR: - { - /* Save the current ptr to the field in case we're building a key - to remove an old key value when an indexed character column - gets updated. */ - char *ptr = key_part->field->ptr; - key_part->field->ptr = (char *)record + key_part->offset; - key_part->field->sort_string((char*)rec_buff, key_part->length); - key_part->field->ptr = ptr; - pos = (unsigned char *)rec_buff; - } - break; - - case GEM_TINYBLOB: - case GEM_BLOB: - case GEM_MEDIUMBLOB: - case GEM_LONGBLOB: - ((Field_blob*)key_part->field)->get_ptr((char**)&pos); - key_part_length = ((Field_blob*)key_part->field)->get_length( - (char*)record + key_part->offset); - break; - - default: - pos = (unsigned char *)record + key_part->offset; - break; - } - - isNull = record[key_part->null_offset] & key_part->null_bit; - if(isNull) - *thereIsAnull = TRUE; - - rc = gemFieldToIdxComponent(pos, - (unsigned long) key_part_length, - fieldType, - isNull , - key_part->field->flags & UNSIGNED_FLAG, - pkeyBuf + *pkeyStringLen, - bufSize, - &componentLen); - *pkeyStringLen += componentLen; - } - DBUG_RETURN(rc); -} - - -int ha_gemini::update_row(const byte * old_record, byte * new_record) -{ - int error = 0; - dsmRecord_t dsmRecord; - unsigned long savepoint; - THD *thd = current_thd; - DBUG_ENTER("update_row"); - - statistic_increment(ha_update_count,&LOCK_status); - if (table->time_stamp) - update_timestamp(new_record+table->time_stamp-1); - - if(thd->gemini.needSavepoint || using_ignore) - { - thd->gemini.savepoint++; - error = dsmTransaction((dsmContext_t *)thd->gemini.context, - &thd->gemini.savepoint, - DSMTXN_SAVE, 0, 0); - if (error) - DBUG_RETURN(error); - thd->gemini.needSavepoint = 0; - } - for (uint keynr=0 ; keynr < table->keys ; keynr++) - { - if(key_cmp(keynr,old_record, new_record,FALSE)) - { - error = handleIndexEntry(old_record,lastRowid,KEY_DELETE,keynr); - if(error) - DBUG_RETURN(error); - error = handleIndexEntry(new_record, lastRowid, KEY_CREATE, keynr); - if(error) - { - if (using_ignore && error == HA_ERR_FOUND_DUPP_KEY) - { - dsmStatus_t rc; - rc = dsmTransaction((dsmContext_t *)thd->gemini.context, - &thd->gemini.savepoint,DSMTXN_UNSAVE,0,NULL); - thd->gemini.needSavepoint = 1; - } - DBUG_RETURN(error); - } - } - } - - dsmRecord.table = tableNumber; - dsmRecord.recid = lastRowid; - dsmRecord.maxLength = table->rec_buff_length; - - if ((error=pack_row((byte **)&dsmRecord.pbuffer, (int *)&dsmRecord.recLength, - new_record, TRUE))) - { - DBUG_RETURN(error); - } - error = dsmRecordUpdate((dsmContext_t *)thd->gemini.context, - &dsmRecord, 0, NULL); - - DBUG_RETURN(error); -} - - -int ha_gemini::delete_row(const byte * record) -{ - int error = 0; - dsmRecord_t dsmRecord; - THD *thd = current_thd; - dsmContext_t *pcontext = (dsmContext_t *)thd->gemini.context; - DBUG_ENTER("delete_row"); - - statistic_increment(ha_delete_count,&LOCK_status); - - if(thd->gemini.needSavepoint) - { - thd->gemini.savepoint++; - error = dsmTransaction(pcontext, &thd->gemini.savepoint, DSMTXN_SAVE, 0, 0); - if (error) - DBUG_RETURN(error); - thd->gemini.needSavepoint = 0; - } - - dsmRecord.table = tableNumber; - dsmRecord.recid = lastRowid; - - error = handleIndexEntries(record, dsmRecord.recid,KEY_DELETE); - if(!error) - { - error = dsmRecordDelete(pcontext, &dsmRecord, 0, NULL); - } - - /* Delete any blobs associated with this row */ - if (table->blob_fields) - { - dsmBlob_t gemBlob; - - gemBlob.areaType = DSMOBJECT_BLOB; - gemBlob.blobObjNo = tableNumber; - for (uint i = 0; i < table->blob_fields; i++) - { - if (pBlobDescs[i].blobId) - { - gemBlob.blobId = pBlobDescs[i].blobId; - my_free((char *)pBlobDescs[i].pBlob, MYF(MY_ALLOW_ZERO_PTR)); - dsmBlobStart(pcontext, &gemBlob); - dsmBlobDelete(pcontext, &gemBlob, NULL); - /* according to DSM doc, no need to call dsmBlobEnd() */ - } - } - } - - DBUG_RETURN(error); -} - -int ha_gemini::index_init(uint keynr) -{ - int error = 0; - THD *thd; - DBUG_ENTER("index_init"); - thd = current_thd; - - lastRowid = 0; - active_index=keynr; - error = dsmCursorCreate((dsmContext_t *)thd->gemini.context, - (dsmTable_t)tableNumber, - (dsmIndex_t)pindexNumbers[keynr], - &cursorId,NULL); - pbracketBase = (dsmKey_t *)my_malloc(sizeof(dsmKey_t) + keyBufSize, - MYF(MY_WME)); - if(!pbracketBase) - DBUG_RETURN(1); - pbracketLimit = (dsmKey_t *)my_malloc(sizeof(dsmKey_t) + keyBufSize,MYF(MY_WME)); - if(!pbracketLimit) - { - my_free((char *)pbracketLimit,MYF(0)); - DBUG_RETURN(1); - } - pbracketBase->index = 0; - pbracketLimit->index = (dsmIndex_t)pindexNumbers[keynr]; - pbracketBase->descending_key = pbracketLimit->descending_key = 0; - pbracketBase->ksubstr = pbracketLimit->ksubstr = 0; - pbracketLimit->keycomps = pbracketBase->keycomps = 1; - - pfoundKey = (dsmKey_t *)my_malloc(sizeof(dsmKey_t) + keyBufSize,MYF(MY_WME)); - if(!pfoundKey) - { - my_free((char *)pbracketLimit,MYF(0)); - my_free((char *)pbracketBase,MYF(0)); - DBUG_RETURN(1); - } - - DBUG_RETURN(error); -} - -int ha_gemini::index_end() -{ - int error = 0; - THD *thd; - DBUG_ENTER("index_end"); - thd = current_thd; - error = dsmCursorDelete((dsmContext_t *)thd->gemini.context, - &cursorId, 0); - if(pbracketLimit) - my_free((char *)pbracketLimit,MYF(0)); - if(pbracketBase) - my_free((char *)pbracketBase,MYF(0)); - if(pfoundKey) - my_free((char *)pfoundKey,MYF(0)); - - pbracketLimit = 0; - pbracketBase = 0; - pfoundKey = 0; - DBUG_RETURN(error); -} - -/* This is only used to read whole keys */ - -int ha_gemini::index_read_idx(byte * buf, uint keynr, const byte * key, - uint key_len, enum ha_rkey_function find_flag) -{ - int error = 0; - DBUG_ENTER("index_read_idx"); - statistic_increment(ha_read_key_count,&LOCK_status); - - error = index_init(keynr); - if (!error) - error = index_read(buf,key,key_len,find_flag); - - if(error == HA_ERR_END_OF_FILE) - error = HA_ERR_KEY_NOT_FOUND; - - table->status = error ? STATUS_NOT_FOUND : 0; - DBUG_RETURN(error); -} - -int ha_gemini::pack_key( uint keynr, dsmKey_t *pkey, - const byte *key_ptr, uint key_length) -{ - KEY *key_info=table->key_info+keynr; - KEY_PART_INFO *key_part=key_info->key_part; - KEY_PART_INFO *end=key_part+key_info->key_parts; - int rc; - int componentLen; - DBUG_ENTER("pack_key"); - - rc = gemKeyInit(pkey->keystr,&componentLen, - (short)pindexNumbers[active_index]); - pkey->keyLen = componentLen; - - for (; key_part != end && (int) key_length > 0 && !rc; key_part++) - { - uint offset=0; - unsigned char *pos; - uint key_part_length = key_part->length; - - int fieldType; - if (key_part->null_bit) - { - offset=1; - if (*key_ptr != 0) // Store 0 if NULL - { - key_length-= key_part->store_length; - key_ptr+= key_part->store_length; - rc = gemFieldToIdxComponent( - (unsigned char *)key_ptr + offset, - (unsigned long) key_part_length, - 0, - 1 , /* Tells it to build a null component */ - key_part->field->flags & UNSIGNED_FLAG, - pkey->keystr + pkey->keyLen, - keyBufSize, - &componentLen); - pkey->keyLen += componentLen; - continue; - } - } - fieldType = gemDataType(key_part->field->type()); - switch (fieldType) - { - case GEM_CHAR: - key_part->field->store((char*)key_ptr + offset, key_part->length); - key_part->field->sort_string((char*)rec_buff, key_part->length); - pos = (unsigned char *)rec_buff; - break; - - case GEM_TINYBLOB: - case GEM_BLOB: - case GEM_MEDIUMBLOB: - case GEM_LONGBLOB: - ((Field_blob*)key_part->field)->get_ptr((char**)&pos); - key_part_length = ((Field_blob*)key_part->field)->get_length( - (char*)key_ptr + offset); - break; - - default: - pos = (unsigned char *)key_ptr + offset; - break; - } - - rc = gemFieldToIdxComponent( - pos, - (unsigned long) key_part_length, - fieldType, - 0 , - key_part->field->flags & UNSIGNED_FLAG, - pkey->keystr + pkey->keyLen, - keyBufSize, - &componentLen); - - key_ptr+=key_part->store_length; - key_length-=key_part->store_length; - pkey->keyLen += componentLen; - } - DBUG_RETURN(rc); -} - -void ha_gemini::unpack_key(char *record, dsmKey_t *key, uint index) -{ - KEY *key_info=table->key_info+index; - KEY_PART_INFO *key_part= key_info->key_part, - *end=key_part+key_info->key_parts; - int fieldIsNull, fieldType; - int rc = 0; - - char unsigned *pos= &key->keystr[FULLKEYHDRSZ+4/* 4 for the index number*/]; - - for ( ; key_part != end; key_part++) - { - fieldType = gemDataType(key_part->field->type()); - if(fieldType == GEM_CHAR) - { - /* Can't get data from character indexes since the sort weights - are in the index and not the characters. */ - key_read = 0; - } - rc = gemIdxComponentToField(pos, fieldType, - (unsigned char *)record + key_part->field->offset(), - //key_part->field->field_length, - key_part->length, - key_part->field->decimals(), - &fieldIsNull); - if(fieldIsNull) - { - record[key_part->null_offset] |= key_part->null_bit; - } - else if (key_part->null_bit) - { - record[key_part->null_offset]&= ~key_part->null_bit; - } - while(*pos++); /* Advance to next field in key by finding */ - /* a null byte */ - } -} - -int ha_gemini::index_read(byte * buf, const byte * key, - uint key_len, enum ha_rkey_function find_flag) -{ - int error = 0; - THD *thd; - int componentLen; - - DBUG_ENTER("index_read"); - statistic_increment(ha_read_key_count,&LOCK_status); - - - pbracketBase->index = (short)pindexNumbers[active_index]; - pbracketBase->keycomps = 1; - - - /* Its a greater than operation so create a base bracket - from the input key data. */ - error = pack_key(active_index, pbracketBase, key, key_len); - if(error) - goto errorReturn; - - if(find_flag == HA_READ_AFTER_KEY) - { - /* A greater than operation */ - error = gemKeyAddLow(pbracketBase->keystr + pbracketBase->keyLen, - &componentLen); - pbracketBase->keyLen += componentLen; - } - if(find_flag == HA_READ_KEY_EXACT) - { - /* Need to set up a high bracket for an equality operator - Which is a copy of the base bracket plus a hi lim term */ - bmove(pbracketLimit,pbracketBase,(size_t)pbracketBase->keyLen + sizeof(dsmKey_t)); - error = gemKeyAddHigh(pbracketLimit->keystr + pbracketLimit->keyLen, - &componentLen); - if(error) - goto errorReturn; - pbracketLimit->keyLen += componentLen; - } - else - { - /* Always add a high range -- except for HA_READ_KEY_EXACT this - is all we need for the upper index bracket */ - error = gemKeyHigh(pbracketLimit->keystr, &componentLen, - pbracketLimit->index); - - pbracketLimit->keyLen = componentLen; - } - /* We have to subtract the header size here since cxKeyPrepare - expects that the three lead bytes of the header are - not counted in this length -- But cxKeyPrepare also - expects that these three bytes are present in the keystr */ - pbracketBase->keyLen -= FULLKEYHDRSZ; - pbracketLimit->keyLen -= FULLKEYHDRSZ; - - thd = current_thd; - - error = findRow(thd, DSMFINDFIRST, buf); - -errorReturn: - if (error == DSM_S_ENDLOOP) - error = HA_ERR_KEY_NOT_FOUND; - - table->status = error ? STATUS_NOT_FOUND : 0; - DBUG_RETURN(error); -} - - -int ha_gemini::index_next(byte * buf) -{ - THD *thd; - int error = 1; - int keyStringLen=0; - dsmMask_t findMode; - DBUG_ENTER("index_next"); - - if(tableStatus == HA_ERR_CRASHED) - DBUG_RETURN(tableStatus); - - thd = current_thd; - - if(pbracketBase->index == 0) - { - error = gemKeyLow(pbracketBase->keystr, &keyStringLen, - pbracketLimit->index); - - pbracketBase->keyLen = (COUNT)keyStringLen - FULLKEYHDRSZ; - pbracketBase->index = pbracketLimit->index; - error = gemKeyHigh(pbracketLimit->keystr, &keyStringLen, - pbracketLimit->index); - pbracketLimit->keyLen = (COUNT)keyStringLen - FULLKEYHDRSZ; - - findMode = DSMFINDFIRST; - } - else - findMode = DSMFINDNEXT; - - error = findRow(thd,findMode,buf); - - if (error == DSM_S_ENDLOOP) - error = HA_ERR_END_OF_FILE; - - table->status = error ? STATUS_NOT_FOUND : 0; - DBUG_RETURN(error); -} - -int ha_gemini::index_next_same(byte * buf, const byte *key, uint keylen) -{ - int error = 0; - DBUG_ENTER("index_next_same"); - statistic_increment(ha_read_next_count,&LOCK_status); - DBUG_RETURN(index_next(buf)); -} - - -int ha_gemini::index_prev(byte * buf) -{ - int error = 0; - THD *thd = current_thd; - - DBUG_ENTER("index_prev"); - statistic_increment(ha_read_prev_count,&LOCK_status); - - error = findRow(thd, DSMFINDPREV, buf); - - if (error == DSM_S_ENDLOOP) - error = HA_ERR_END_OF_FILE; - - - table->status = error ? STATUS_NOT_FOUND : 0; - DBUG_RETURN(error); -} - - -int ha_gemini::index_first(byte * buf) -{ - DBUG_ENTER("index_first"); - statistic_increment(ha_read_first_count,&LOCK_status); - DBUG_RETURN(index_next(buf)); -} - -int ha_gemini::index_last(byte * buf) -{ - int error = 0; - THD *thd; - int keyStringLen; - dsmMask_t findMode; - thd = current_thd; - - DBUG_ENTER("index_last"); - statistic_increment(ha_read_last_count,&LOCK_status); - - error = gemKeyLow(pbracketBase->keystr, &keyStringLen, - pbracketLimit->index); - - pbracketBase->keyLen = (COUNT)keyStringLen - FULLKEYHDRSZ; - pbracketBase->index = pbracketLimit->index; - error = gemKeyHigh(pbracketLimit->keystr, &keyStringLen, - pbracketLimit->index); - pbracketLimit->keyLen = (COUNT)keyStringLen - FULLKEYHDRSZ; - - error = findRow(thd,DSMFINDLAST,buf); - - if (error == DSM_S_ENDLOOP) - error = HA_ERR_END_OF_FILE; - - table->status = error ? STATUS_NOT_FOUND : 0; - DBUG_RETURN(error); -} - -int ha_gemini::rnd_init(bool scan) -{ - THD *thd = current_thd; - - lastRowid = 0; - - return 0; -} - -int ha_gemini::rnd_end() -{ -/* - return gem_scan_end(); -*/ - return 0; -} - -int ha_gemini::rnd_next(byte *buf) -{ - int error = 0; - dsmRecord_t dsmRecord; - THD *thd; - - DBUG_ENTER("rnd_next"); - - if(tableStatus == HA_ERR_CRASHED) - DBUG_RETURN(tableStatus); - - thd = current_thd; - if(thd->gemini.tx_isolation == ISO_READ_COMMITTED && !(lockMode & DSM_LK_EXCL) - && lastRowid) - error = dsmObjectUnlock((dsmContext_t *)thd->gemini.context, - tableNumber, DSMOBJECT_RECORD, lastRowid, - lockMode | DSM_UNLK_FREE, 0); - - statistic_increment(ha_read_rnd_next_count,&LOCK_status); - dsmRecord.table = tableNumber; - dsmRecord.recid = lastRowid; - dsmRecord.pbuffer = (dsmBuffer_t *)rec_buff; - dsmRecord.recLength = table->reclength; - dsmRecord.maxLength = table->rec_buff_length; - - error = dsmTableScan((dsmContext_t *)thd->gemini.context, - &dsmRecord, DSMFINDNEXT, lockMode, 0); - - if(!error) - { - lastRowid = dsmRecord.recid; - error = unpack_row((char *)buf,(char *)dsmRecord.pbuffer); - } - if(!error) - ; - else - { - lastRowid = 0; - if (error == DSM_S_ENDLOOP) - error = HA_ERR_END_OF_FILE; - else if (error == DSM_S_RQSTREJ) - error = HA_ERR_LOCK_WAIT_TIMEOUT; - else if (error == DSM_S_LKTBFULL) - { - error = HA_ERR_LOCK_TABLE_FULL; - gemini_lock_table_overflow_error((dsmContext_t *)thd->gemini.context); - } - } - table->status = error ? STATUS_NOT_FOUND : 0; - DBUG_RETURN(error); -} - - -int ha_gemini::rnd_pos(byte * buf, byte *pos) -{ - int error; - int rc; - - THD *thd; - - statistic_increment(ha_read_rnd_count,&LOCK_status); - thd = current_thd; - memcpy((void *)&lastRowid,pos,ref_length); - if(thd->gemini.tx_isolation == ISO_READ_COMMITTED && !(lockMode & DSM_LK_EXCL)) - { - /* Lock the row */ - - error = dsmObjectLock((dsmContext_t *)thd->gemini.context, - (dsmObject_t)tableNumber,DSMOBJECT_RECORD,lastRowid, - lockMode, 1, 0); - if ( error ) - goto errorReturn; - } - error = fetch_row(thd->gemini.context, buf); - if(thd->gemini.tx_isolation == ISO_READ_COMMITTED && !(lockMode & DSM_LK_EXCL)) - { - /* Unlock the row */ - - rc = dsmObjectUnlock((dsmContext_t *)thd->gemini.context, - (dsmObject_t)tableNumber,DSMOBJECT_RECORD,lastRowid, - lockMode | DSM_UNLK_FREE , 0); - } - if(error == DSM_S_RMNOTFND) - error = HA_ERR_RECORD_DELETED; - - errorReturn: - table->status = error ? STATUS_NOT_FOUND : 0; - return error; -} - -int ha_gemini::fetch_row(void *gemini_context,const byte *buf) -{ - dsmStatus_t rc = 0; - dsmRecord_t dsmRecord; - - DBUG_ENTER("fetch_row"); - dsmRecord.table = tableNumber; - dsmRecord.recid = lastRowid; - dsmRecord.pbuffer = (dsmBuffer_t *)rec_buff; - dsmRecord.recLength = table->reclength; - dsmRecord.maxLength = table->rec_buff_length; - - rc = dsmRecordGet((dsmContext_t *)gemini_context, - &dsmRecord, 0); - - if(!rc) - { - rc = unpack_row((char *)buf,(char *)dsmRecord.pbuffer); - } - - DBUG_RETURN(rc); -} -int ha_gemini::findRow(THD *thd, dsmMask_t findMode, byte *buf) -{ - dsmStatus_t rc; - dsmKey_t *pkey; - - DBUG_ENTER("findRow"); - - if(thd->gemini.tx_isolation == ISO_READ_COMMITTED && !(lockMode & DSM_LK_EXCL) - && lastRowid) - rc = dsmObjectUnlock((dsmContext_t *)thd->gemini.context, - tableNumber, DSMOBJECT_RECORD, lastRowid, - lockMode | DSM_UNLK_FREE, 0); - if( key_read ) - pkey = pfoundKey; - else - pkey = 0; - - rc = dsmCursorFind((dsmContext_t *)thd->gemini.context, - &cursorId, - pbracketBase, - pbracketLimit, - DSMPARTIAL, - findMode, - lockMode, - NULL, - &lastRowid, - pkey); - if( rc ) - goto errorReturn; - - if(key_read) - { - unpack_key((char*)buf, pkey, active_index); - } - if(!key_read) /* unpack_key may have turned off key_read */ - { - rc = fetch_row((dsmContext_t *)thd->gemini.context,buf); - } - -errorReturn: - if(!rc) - ; - else - { - lastRowid = 0; - if(rc == DSM_S_RQSTREJ) - rc = HA_ERR_LOCK_WAIT_TIMEOUT; - else if (rc == DSM_S_LKTBFULL) - { - rc = HA_ERR_LOCK_TABLE_FULL; - gemini_lock_table_overflow_error((dsmContext_t *)thd->gemini.context); - } - } - - DBUG_RETURN(rc); -} - -void ha_gemini::position(const byte *record) -{ - memcpy(ref,&lastRowid,ref_length); -} - - -void ha_gemini::info(uint flag) -{ - DBUG_ENTER("info"); - - if ((flag & HA_STATUS_VARIABLE)) - { - THD *thd = current_thd; - dsmStatus_t error; - ULONG64 rows; - - if(thd->gemini.context == NULL) - { - /* Need to get this thread a connection into the database */ - error = gemini_connect(thd); - if(error) - DBUG_VOID_RETURN; - } - - error = dsmRowCount((dsmContext_t *)thd->gemini.context,tableNumber,&rows); - records = (ha_rows)rows; - deleted = 0; - } - if ((flag & HA_STATUS_CONST)) - { - ha_rows *rec_per_key = share->rec_per_key; - for (uint i = 0; i < table->keys; i++) - for(uint k=0; - k < table->key_info[i].key_parts; k++,rec_per_key++) - table->key_info[i].rec_per_key[k] = *rec_per_key; - } - if ((flag & HA_STATUS_ERRKEY)) - { - errkey=last_dup_key; - } - if ((flag & HA_STATUS_TIME)) - { - ; - } - if ((flag & HA_STATUS_AUTO)) - { - THD *thd = current_thd; - dsmStatus_t error; - - error = dsmTableAutoIncrement((dsmContext_t *)thd->gemini.context, - tableNumber, - (ULONG64 *)&auto_increment_value, - 0); - /* Should return the next auto-increment value that - will be given -- so we need to increment the one dsm - currently reports. */ - auto_increment_value++; - } - - DBUG_VOID_RETURN; -} - - -int ha_gemini::extra(enum ha_extra_function operation) -{ - switch (operation) - { - case HA_EXTRA_RESET: - case HA_EXTRA_RESET_STATE: - key_read=0; - using_ignore=0; - break; - case HA_EXTRA_KEYREAD: - key_read=1; // Query satisfied with key - break; - case HA_EXTRA_NO_KEYREAD: - key_read=0; - break; - case HA_EXTRA_IGNORE_DUP_KEY: - using_ignore=1; - break; - case HA_EXTRA_NO_IGNORE_DUP_KEY: - using_ignore=0; - break; - - default: - break; - } - return 0; -} - - -int ha_gemini::reset(void) -{ - key_read=0; // Reset to state after open - return 0; -} - - -/* - As MySQL will execute an external lock for every new table it uses - we can use this to start the transactions. -*/ - -int ha_gemini::external_lock(THD *thd, int lock_type) -{ - dsmStatus_t rc = 0; - LONG txNumber; - - DBUG_ENTER("ha_gemini::external_lock"); - - if (lock_type != F_UNLCK) - { - if (!thd->gemini.lock_count) - { - thd->gemini.lock_count = 1; - thd->gemini.tx_isolation = thd->tx_isolation; - } - // lockMode has already been set in store_lock - // If the statement about to be executed calls for - // exclusive locks and we're running at read uncommitted - // isolation level then raise an error. - if(thd->gemini.tx_isolation == ISO_READ_UNCOMMITTED) - { - if(lockMode == DSM_LK_EXCL) - { - DBUG_RETURN(HA_ERR_READ_ONLY_TRANSACTION); - } - else - { - lockMode = DSM_LK_NOLOCK; - } - } - - if(thd->gemini.context == NULL) - { - /* Need to get this thread a connection into the database */ - rc = gemini_connect(thd); - if(rc) - return rc; - } - /* Set need savepoint flag */ - thd->gemini.needSavepoint = 1; - - if(rc) - DBUG_RETURN(rc); - - - if( thd->in_lock_tables || thd->gemini.tx_isolation == ISO_SERIALIZABLE ) - { - rc = dsmObjectLock((dsmContext_t *)thd->gemini.context, - (dsmObject_t)tableNumber,DSMOBJECT_TABLE,0, - lockMode, 1, 0); - if(rc == DSM_S_RQSTREJ) - rc = HA_ERR_LOCK_WAIT_TIMEOUT; - } - } - else /* lock_type == F_UNLK */ - { - /* Commit the tx if we're in auto-commit mode */ - if (!(thd->options & OPTION_NOT_AUTO_COMMIT)&& - !(thd->options & OPTION_BEGIN)) - gemini_commit(thd); - } - - DBUG_RETURN(rc); -} - - -THR_LOCK_DATA **ha_gemini::store_lock(THD *thd, THR_LOCK_DATA **to, - enum thr_lock_type lock_type) -{ - if (lock_type != TL_IGNORE && lock.type == TL_UNLOCK) - { - /* If we are not doing a LOCK TABLE, then allow multiple writers */ - if ((lock_type >= TL_WRITE_CONCURRENT_INSERT && - lock_type <= TL_WRITE) && - !thd->in_lock_tables) - lock_type = TL_WRITE_ALLOW_WRITE; - lock.type=lock_type; - } - if(table->reginfo.lock_type > TL_WRITE_ALLOW_READ) - lockMode = DSM_LK_EXCL; - else - lockMode = DSM_LK_SHARE; - - *to++= &lock; - return to; -} - -void ha_gemini::update_create_info(HA_CREATE_INFO *create_info) -{ - table->file->info(HA_STATUS_AUTO | HA_STATUS_CONST); - if (!(create_info->used_fields & HA_CREATE_USED_AUTO)) - { - create_info->auto_increment_value=auto_increment_value; - } -} - -int ha_gemini::create(const char *name, register TABLE *form, - HA_CREATE_INFO *create_info) -{ - THD *thd; - char name_buff[FN_REFLEN]; - char dbname_buff[FN_REFLEN]; - DBUG_ENTER("ha_gemini::create"); - dsmContext_t *pcontext; - dsmStatus_t rc; - dsmArea_t areaNumber; - dsmObject_t tableNumber = 0; - dsmDbkey_t dummy = 0; - unsigned i; - int baseNameLen; - dsmObject_t indexNumber; - - /* separate out the name of the table and the database (a VST must be - ** created in the mysql database) - */ - rc = gemini_parse_table_name(name, dbname_buff, name_buff); - if (rc == 0) - { - /* If the table is a VST, don't create areas or extents */ - if (strcmp(dbname_buff, "mysql") == 0) - { - tableNumber = gemini_is_vst(name_buff); - if (tableNumber) - { - return 0; - } - } - } - - thd = current_thd; - if(thd->gemini.context == NULL) - { - /* Need to get this thread a connection into the database */ - rc = gemini_connect(thd); - if(rc) - return rc; - } - pcontext = (dsmContext_t *)thd->gemini.context; - - if(thd->gemini.needSavepoint || using_ignore) - { - thd->gemini.savepoint++; - rc = dsmTransaction((dsmContext_t *)thd->gemini.context, - &thd->gemini.savepoint, - DSMTXN_SAVE, 0, 0); - if (rc) - DBUG_RETURN(rc); - thd->gemini.needSavepoint = 0; - } - - fn_format(name_buff, name, "", ha_gemini_ext, 2 | 4); - /* Create a storage area */ - rc = dsmAreaNew(pcontext,gemini_blocksize,DSMAREA_TYPE_DATA, - &areaNumber, gemini_recbits, - (dsmText_t *)"gemini_data_area"); - if( rc != 0 ) - { - gemini_msg(pcontext, "dsmAreaNew failed %l",rc); - return(rc); - } - - /* Create an extent */ - /* Don't pass in leading ./ in name_buff */ - rc = dsmExtentCreate(pcontext,areaNumber,1,15,5, - (dsmText_t *)&name_buff[start_of_name]); - if( rc != 0 ) - { - gemini_msg(pcontext, "dsmExtentCreate failed %l",rc); - return(rc); - } - - /* Create the table storage object */ - /* Change slashes in the name to periods */ - for( i = 0; i < strlen(name_buff); i++) - if(name_buff[i] == '/' || name_buff[i] == '\\') - name_buff[i] = '.'; - - /* Get rid of .gmd suffix */ - name_buff[strlen(name_buff) - 4] = '\0'; - - rc = dsmObjectCreate(pcontext, areaNumber, &tableNumber, - DSMOBJECT_MIXTABLE,0,0,0, - (dsmText_t *)&name_buff[start_of_name], - &dummy,&dummy); - - if (rc == 0 && table->blob_fields) - { - /* create a storage object record for blob fields */ - rc = dsmObjectCreate(pcontext, areaNumber, &tableNumber, - DSMOBJECT_BLOB,0,0,0, - (dsmText_t *)&name_buff[start_of_name], - &dummy,&dummy); - if( rc != 0 ) - { - gemini_msg(pcontext, "dsmObjectCreate for blob object failed %l",rc); - return(rc); - } - } - - if(rc == 0 && form->keys) - { - fn_format(name_buff, name, "", ha_gemini_idx_ext, 2 | 4); - /* Create a storage area */ - rc = dsmAreaNew(pcontext,gemini_blocksize,DSMAREA_TYPE_DATA, - &areaNumber, gemini_recbits, - (dsmText_t *)"gemini_index_area"); - if( rc != 0 ) - { - gemini_msg(pcontext, "dsmAreaNew failed %l",rc); - return(rc); - } - /* Create an extent */ - /* Don't pass in leading ./ in name_buff */ - rc = dsmExtentCreate(pcontext,areaNumber,1,15,5, - (dsmText_t *)&name_buff[start_of_name]); - if( rc != 0 ) - { - gemini_msg(pcontext, "dsmExtentCreate failed %l",rc); - return(rc); - } - - /* Change slashes in the name to periods */ - for( i = 0; i < strlen(name_buff); i++) - if(name_buff[i] == '/' || name_buff[i] == '\\') - name_buff[i] = '.'; - - /* Get rid of .gmi suffix */ - name_buff[strlen(name_buff) - 4] = '\0'; - - baseNameLen = strlen(name_buff); - name_buff[baseNameLen] = '.'; - baseNameLen++; - for( i = 0; i < form->keys; i++) - { - dsmObjectAttr_t indexUnique; - - indexNumber = DSMINDEX_INVALID; - /* Create a storage object record for each index */ - /* Add the index name so the object name is in the form - <db>.<table>.<index_name> */ - strcpy(&name_buff[baseNameLen],table->key_info[i].name); - if(table->key_info[i].flags & HA_NOSAME) - indexUnique = 1; - else - indexUnique = 0; - rc = dsmObjectCreate(pcontext, areaNumber, &indexNumber, - DSMOBJECT_MIXINDEX,indexUnique,tableNumber, - DSMOBJECT_MIXTABLE, - (dsmText_t *)&name_buff[start_of_name], - &dummy,&dummy); - - } - } - /* The auto_increment value is the next one to be given - out so give dsm one less than this value */ - if(create_info->auto_increment_value) - rc = dsmTableAutoIncrementSet(pcontext,tableNumber, - create_info->auto_increment_value-1); - - /* Get a table lock on this table in case this table is being - created as part of an alter table statement. We don't want - the alter table statement to abort because of a lock table overflow - */ - if (thd->lex.sql_command == SQLCOM_CREATE_INDEX || - thd->lex.sql_command == SQLCOM_ALTER_TABLE || - thd->lex.sql_command == SQLCOM_DROP_INDEX) - { - rc = dsmObjectLock(pcontext, - (dsmObject_t)tableNumber,DSMOBJECT_TABLE,0, - DSM_LK_EXCL, 1, 0); - /* and don't commit so we won't release the table on the table number - of the table being altered */ - } - else - { - if(!rc) - rc = gemini_commit(thd); - } - - DBUG_RETURN(rc); -} - -int ha_gemini::delete_table(const char *pname) -{ - THD *thd; - dsmStatus_t rc; - dsmContext_t *pcontext; - unsigned i,nameLen; - dsmArea_t indexArea = 0; - dsmArea_t tableArea = 0; - dsmObjectAttr_t objectAttr; - dsmObject_t associate; - dsmObjectType_t associateType; - dsmDbkey_t block, root; - int need_txn = 0; - dsmObject_t tableNum = 0; - char name_buff[FN_REFLEN]; - char dbname_buff[FN_REFLEN]; - DBUG_ENTER("ha_gemini::delete_table"); - - /* separate out the name of the table and the database (a VST must be - ** located in the mysql database) - */ - rc = gemini_parse_table_name(pname, dbname_buff, name_buff); - if (rc == 0) - { - /* If the table is a VST, there are no areas or extents to delete */ - if (strcmp(dbname_buff, "mysql") == 0) - { - tableNum = gemini_is_vst(name_buff); - if (tableNum) - { - return 0; - } - } - } - - thd = current_thd; - if(thd->gemini.context == NULL) - { - /* Need to get this thread a connection into the database */ - rc = gemini_connect(thd); - if(rc) - { - DBUG_RETURN(rc); - } - } - pcontext = (dsmContext_t *)thd->gemini.context; - - - bzero(name_buff, FN_REFLEN); - - nameLen = strlen(pname); - for( i = start_of_name; i < nameLen; i++) - { - if(pname[i] == '/' || pname[i] == '\\') - name_buff[i-start_of_name] = '.'; - else - name_buff[i-start_of_name] = pname[i]; - } - - rc = dsmObjectNameToNum(pcontext, (dsmText_t *)name_buff, - (dsmObject_t *)&tableNum); - if (rc) - { - gemini_msg(pcontext, "Unable to find table number for %s", name_buff); - rc = gemini_rollback(thd); - if (rc) - { - gemini_msg(pcontext, "Error in rollback %l",rc); - } - DBUG_RETURN(rc); - } - - rc = dsmObjectInfo(pcontext, tableNum, DSMOBJECT_MIXTABLE, tableNum, - &tableArea, &objectAttr, &associateType, &block, &root); - if (rc) - { - gemini_msg(pcontext, "Failed to get area number for table %d, %s, return %l", - tableNum, pname, rc); - rc = gemini_rollback(thd); - if (rc) - { - gemini_msg(pcontext, "Error in rollback %l",rc); - } - } - - indexArea = DSMAREA_INVALID; - - /* Delete the indexes and tables storage objects for with the table */ - rc = dsmObjectDeleteAssociate(pcontext, tableNum, &indexArea); - if (rc) - { - gemini_msg(pcontext, "Error deleting storage objects for table number %d, return %l", - (int)tableNum, rc); - - /* roll back txn and return */ - rc = gemini_rollback(thd); - if (rc) - { - gemini_msg(pcontext, "Error in rollback %l",rc); - } - DBUG_RETURN(rc); - } - - if (indexArea != DSMAREA_INVALID) - { - /* Delete the extents for both Index and Table */ - rc = dsmExtentDelete(pcontext, indexArea); - rc = dsmAreaDelete(pcontext, indexArea); - if (rc) - { - gemini_msg(pcontext, "Error deleting Index Area %l, return %l", indexArea, rc); - - /* roll back txn and return */ - rc = gemini_rollback(thd); - if (rc) - { - gemini_msg(pcontext, "Error in rollback %l",rc); - } - DBUG_RETURN(rc); - } - } - - rc = dsmExtentDelete(pcontext, tableArea); - rc = dsmAreaDelete(pcontext, tableArea); - if (rc) - { - gemini_msg(pcontext, "Error deleting table Area %l, name %s, return %l", - tableArea, pname, rc); - /* roll back txn and return */ - rc = gemini_rollback(thd); - if (rc) - { - gemini_msg(pcontext, "Error in rollback %l",rc); - } - DBUG_RETURN(rc); - } - - - /* Commit the transaction */ - rc = gemini_commit(thd); - if (rc) - { - gemini_msg(pcontext, "Failed to commit transaction %l",rc); - } - - - /* now remove all the files that need to be removed and - cause a checkpoint so recovery will work */ - rc = dsmExtentUnlink(pcontext); - - DBUG_RETURN(0); -} - - -int ha_gemini::rename_table(const char *pfrom, const char *pto) -{ - THD *thd; - dsmContext_t *pcontext; - dsmStatus_t rc; - char dbname_buff[FN_REFLEN]; - char name_buff[FN_REFLEN]; - char newname_buff[FN_REFLEN]; - char newextname_buff[FN_REFLEN]; - char newidxextname_buff[FN_REFLEN]; - unsigned i, nameLen; - dsmObject_t tableNum; - dsmArea_t indexArea = 0; - dsmArea_t tableArea = 0; - - DBUG_ENTER("ha_gemini::rename_table"); - - /* don't allow rename of VSTs */ - rc = gemini_parse_table_name(pfrom, dbname_buff, name_buff); - if (rc == 0) - { - /* If the table is a VST, don't create areas or extents */ - if (strcmp(dbname_buff, "mysql") == 0) - { - if (gemini_is_vst(name_buff)) - { - return DSM_S_CANT_RENAME_VST; - } - } - } - - thd = current_thd; - if (thd->gemini.context == NULL) - { - /* Need to get this thread a connection into the database */ - rc = gemini_connect(thd); - if (rc) - { - DBUG_RETURN(rc); - } - } - - pcontext = (dsmContext_t *)thd->gemini.context; - - /* change the slashes to dots in the old and new names */ - nameLen = strlen(pfrom); - for( i = start_of_name; i < nameLen; i++) - { - if(pfrom[i] == '/' || pfrom[i] == '\\') - name_buff[i-start_of_name] = '.'; - else - name_buff[i-start_of_name] = pfrom[i]; - } - name_buff[i-start_of_name] = '\0'; - - nameLen = strlen(pto); - for( i = start_of_name; i < nameLen; i++) - { - if(pto[i] == '/' || pto[i] == '\\') - newname_buff[i-start_of_name] = '.'; - else - newname_buff[i-start_of_name] = pto[i]; - } - newname_buff[i-start_of_name] = '\0'; - - /* generate new extent names (for table and index extents) */ - fn_format(newextname_buff, pto, "", ha_gemini_ext, 2 | 4); - fn_format(newidxextname_buff, pto, "", ha_gemini_idx_ext, 2 | 4); - - rc = dsmObjectNameToNum(pcontext, (dsmText_t *)name_buff, &tableNum); - if (rc) - { - gemini_msg(pcontext, "Unable to file Table number for %s", name_buff); - goto errorReturn; - } - - rc = dsmObjectRename(pcontext, tableNum, - (dsmText_t *)newname_buff, - (dsmText_t *)&newidxextname_buff[start_of_name], - (dsmText_t *)&newextname_buff[start_of_name], - &indexArea, &tableArea); - if (rc) - { - gemini_msg(pcontext, "Failed to rename %s to %s",name_buff,newname_buff); - goto errorReturn; - } - - /* Rename the physical table and index files (if necessary). - ** Close the file, rename it, and reopen it (have to do it this - ** way so rename works on Windows). - */ - if (!(rc = dsmAreaClose(pcontext, tableArea))) - { - if (!(rc = rename_file_ext(pfrom, pto, ha_gemini_ext))) - { - rc = dsmAreaOpen(pcontext, tableArea, 0); - if (rc) - { - gemini_msg(pcontext, "Failed to reopen area %d",tableArea); - } - } - } - - if (!rc && indexArea) - { - if (!(rc = dsmAreaClose(pcontext, indexArea))) - { - if (!(rc = rename_file_ext(pfrom, pto, ha_gemini_idx_ext))) - { - rc = dsmAreaOpen(pcontext, indexArea, 0); - if (rc) - { - gemini_msg(pcontext, "Failed to reopen area %d",tableArea); - } - } - } - } - -errorReturn: - DBUG_RETURN(rc); -} - - -/* - How many seeks it will take to read through the table - This is to be comparable to the number returned by records_in_range so - that we can decide if we should scan the table or use keys. -*/ - -double ha_gemini::scan_time() -{ - return (double)records / - (double)((gemini_blocksize / (double)table->reclength)); -} - -int ha_gemini::analyze(THD* thd, HA_CHECK_OPT* check_opt) -{ - int error; - uint saveIsolation; - dsmMask_t saveLockMode; - - check_opt->quick = TRUE; - check_opt->optimize = TRUE; // Tells check not to get table lock - saveLockMode = lockMode; - saveIsolation = thd->gemini.tx_isolation; - thd->gemini.tx_isolation = ISO_READ_UNCOMMITTED; - lockMode = DSM_LK_NOLOCK; - error = check(thd,check_opt); - lockMode = saveLockMode; - thd->gemini.tx_isolation = saveIsolation; - return (error); -} - -int ha_gemini::check(THD* thd, HA_CHECK_OPT* check_opt) -{ - int error = 0; - int checkStatus = HA_ADMIN_OK; - ha_rows indexCount; - byte *buf = 0, *indexBuf = 0, *prevBuf = 0; - int errorCount = 0; - - info(HA_STATUS_VARIABLE); // Makes sure row count is up to date - - /* Get a shared table lock */ - if(thd->gemini.needSavepoint) - { - /* We don't really need a savepoint here but do it anyway - just to keep the savepoint number correct. */ - thd->gemini.savepoint++; - error = dsmTransaction((dsmContext_t *)thd->gemini.context, - &thd->gemini.savepoint, - DSMTXN_SAVE, 0, 0); - if (error) - return(error); - thd->gemini.needSavepoint = 0; - } - buf = (byte*)my_malloc(table->rec_buff_length,MYF(MY_WME)); - indexBuf = (byte*)my_malloc(table->rec_buff_length,MYF(MY_WME)); - prevBuf = (byte*)my_malloc(table->rec_buff_length,MYF(MY_WME |MY_ZEROFILL )); - - /* Lock the table */ - if (!check_opt->optimize) - error = dsmObjectLock((dsmContext_t *)thd->gemini.context, - (dsmObject_t)tableNumber, - DSMOBJECT_TABLE,0, - DSM_LK_SHARE, 1, 0); - if(error) - { - gemini_msg((dsmContext_t *)thd->gemini.context, - "Failed to lock table %d, error %d",tableNumber, error); - return error; - } - - ha_rows *rec_per_key = share->rec_per_key; - /* If quick option just scan along index converting and counting entries */ - for (uint i = 0; i < table->keys; i++) - { - key_read = 1; // Causes data to be extracted from the keys - indexCount = 0; - // Clear the cardinality stats for this index - memset(table->key_info[i].rec_per_key,0, - sizeof(table->key_info[0].rec_per_key[0]) * - table->key_info[i].key_parts); - error = index_init(i); - error = index_first(indexBuf); - while(!error) - { - indexCount++; - if(!check_opt->quick) - { - /* Fetch row and compare to data produced from key */ - error = fetch_row(thd->gemini.context,buf); - if(!error) - { - if(key_cmp(i,buf,indexBuf,FALSE)) - { - - gemini_msg((dsmContext_t *)thd->gemini.context, - "Check Error! Key does not match row for rowid %d for index %s", - lastRowid,table->key_info[i].name); - print_msg(thd,table->real_name,"check","error", - "Key does not match row for rowid %d for index %s", - lastRowid,table->key_info[i].name); - checkStatus = HA_ADMIN_CORRUPT; - errorCount++; - if(errorCount > 1000) - goto error_return; - } - else if(error == DSM_S_RMNOTFND) - { - errorCount++; - checkStatus = HA_ADMIN_CORRUPT; - gemini_msg((dsmContext_t *)thd->gemini.context, - "Check Error! Key does not have a valid row pointer %d for index %s", - lastRowid,table->key_info[i].name); - print_msg(thd,table->real_name,"check","error", - "Key does not have a valid row pointer %d for index %s", - lastRowid,table->key_info[i].name); - if(errorCount > 1000) - goto error_return; - error = 0; - } - } - } - - key_cmp(i,indexBuf,prevBuf,TRUE); - bcopy((void *)indexBuf,(void *)prevBuf,table->rec_buff_length); - - if(!error) - error = index_next(indexBuf); - } - - for(uint j=1; j < table->key_info[i].key_parts; j++) - { - table->key_info[i].rec_per_key[j] += table->key_info[i].rec_per_key[j-1]; - } - for(uint k=0; k < table->key_info[i].key_parts; k++) - { - if (table->key_info[i].rec_per_key[k]) - table->key_info[i].rec_per_key[k] = - records / table->key_info[i].rec_per_key[k]; - *rec_per_key = table->key_info[i].rec_per_key[k]; - rec_per_key++; - } - - if(error == HA_ERR_END_OF_FILE) - { - /* Check count of rows */ - - if(records != indexCount) - { - /* Number of index entries does not agree with the number of - rows in the index. */ - checkStatus = HA_ADMIN_CORRUPT; - gemini_msg((dsmContext_t *)thd->gemini.context, - "Check Error! Total rows %d does not match total index entries %d for %s", - records, indexCount, - table->key_info[i].name); - print_msg(thd,table->real_name,"check","error", - "Total rows %d does not match total index entries %d for %s", - records, indexCount, - table->key_info[i].name); - } - } - else - { - checkStatus = HA_ADMIN_FAILED; - goto error_return; - } - index_end(); - } - if(!check_opt->quick) - { - /* Now scan the table and for each row generate the keys - and find them in the index */ - error = fullCheck(thd, buf); - if(error) - checkStatus = error; - } - // Store the key distribution information - error = saveKeyStats(thd); - -error_return: - my_free((char*)buf,MYF(MY_ALLOW_ZERO_PTR)); - my_free((char*)indexBuf,MYF(MY_ALLOW_ZERO_PTR)); - my_free((char*)prevBuf,MYF(MY_ALLOW_ZERO_PTR)); - - index_end(); - key_read = 0; - if(!check_opt->optimize) - { - error = dsmObjectUnlock((dsmContext_t *)thd->gemini.context, - (dsmObject_t)tableNumber, - DSMOBJECT_TABLE,0, - DSM_LK_SHARE,0); - if (error) - { - gemini_msg((dsmContext_t *)thd->gemini.context, - "Unable to unlock table %d", tableNumber); - } - } - - return checkStatus; -} - -int ha_gemini::saveKeyStats(THD *thd) -{ - dsmStatus_t rc = 0; - - /* Insert a row in the indexStats table for each column of - each index of the table */ - - for(uint i = 0; i < table->keys; i++) - { - for (uint j = 0; j < table->key_info[i].key_parts && !rc ;j++) - { - rc = dsmIndexStatsPut((dsmContext_t *)thd->gemini.context, - tableNumber, pindexNumbers[i], - j, (LONG64)table->key_info[i].rec_per_key[j]); - if (rc) - { - gemini_msg((dsmContext_t *)thd->gemini.context, - "Failed to update index stats for table %d, index %d", - tableNumber, pindexNumbers[i]); - } - } - } - return rc; -} - -int ha_gemini::fullCheck(THD *thd,byte *buf) -{ - int error; - int errorCount = 0; - int checkStatus = 0; - - lastRowid = 0; - - while(((error = rnd_next( buf)) != HA_ERR_END_OF_FILE) && errorCount <= 1000) - { - if(!error) - { - error = handleIndexEntries(buf,lastRowid,KEY_CHECK); - if(error) - { - /* Error finding an index entry for a row. */ - print_msg(thd,table->real_name,"check","error", - "Unable to find all index entries for row %d", - lastRowid); - errorCount++; - checkStatus = HA_ADMIN_CORRUPT; - error = 0; - } - } - else - { - /* Error reading a row */ - print_msg(thd,table->real_name,"check","error", - "Error reading row %d status = %d", - lastRowid,error); - errorCount++; - checkStatus = HA_ADMIN_CORRUPT; - error = 0; - } - } - - return checkStatus; -} - -int ha_gemini::repair(THD* thd, HA_CHECK_OPT* check_opt) -{ - int error; - dsmRecord_t dsmRecord; - byte *buf; - - if(thd->gemini.needSavepoint) - { - /* We don't really need a savepoint here but do it anyway - just to keep the savepoint number correct. */ - thd->gemini.savepoint++; - error = dsmTransaction((dsmContext_t *)thd->gemini.context, - &thd->gemini.savepoint, - DSMTXN_SAVE, 0, 0); - if (error) - { - gemini_msg((dsmContext_t *)thd->gemini.context, - "Error setting savepoint number %d, error %d", - thd->gemini.savepoint++, error); - return(error); - } - thd->gemini.needSavepoint = 0; - } - - - /* Lock the table */ - error = dsmObjectLock((dsmContext_t *)thd->gemini.context, - (dsmObject_t)tableNumber, - DSMOBJECT_TABLE,0, - DSM_LK_EXCL, 1, 0); - if(error) - { - gemini_msg((dsmContext_t *)thd->gemini.context, - "Failed to lock table %d, error %d",tableNumber, error); - return error; - } - - error = dsmContextSetLong((dsmContext_t *)thd->gemini.context, - DSM_TAGCONTEXT_NO_LOGGING,1); - - error = dsmTableReset((dsmContext_t *)thd->gemini.context, - (dsmTable_t)tableNumber, table->keys, - pindexNumbers); - if (error) - { - gemini_msg((dsmContext_t *)thd->gemini.context, - "dsmTableReset failed for table %d, error %d",tableNumber, error); - } - - buf = (byte*)my_malloc(table->rec_buff_length,MYF(MY_WME)); - dsmRecord.table = tableNumber; - dsmRecord.recid = 0; - dsmRecord.pbuffer = (dsmBuffer_t *)rec_buff; - dsmRecord.recLength = table->reclength; - dsmRecord.maxLength = table->rec_buff_length; - while(!error) - { - error = dsmTableScan((dsmContext_t *)thd->gemini.context, - &dsmRecord, DSMFINDNEXT, DSM_LK_NOLOCK, - 1); - if(!error) - { - if (!(error = unpack_row((char *)buf,(char *)dsmRecord.pbuffer))) - { - error = handleIndexEntries(buf,dsmRecord.recid,KEY_CREATE); - if(error == HA_ERR_FOUND_DUPP_KEY) - { - /* We don't want to stop on duplicate keys -- we're repairing - here so let's get as much repaired as possible. */ - error = 0; - } - } - } - } - error = dsmObjectUnlock((dsmContext_t *)thd->gemini.context, - (dsmObject_t)tableNumber, - DSMOBJECT_TABLE,0, - DSM_LK_EXCL,0); - if (error) - { - gemini_msg((dsmContext_t *)thd->gemini.context, - "Unable to unlock table %d", tableNumber); - } - - my_free((char*)buf,MYF(MY_ALLOW_ZERO_PTR)); - - error = dsmContextSetLong((dsmContext_t *)thd->gemini.context, - DSM_TAGCONTEXT_NO_LOGGING,0); - - return error; -} - - -int ha_gemini::restore(THD* thd, HA_CHECK_OPT *check_opt) -{ - dsmContext_t *pcontext = (dsmContext_t *)thd->gemini.context; - char* backup_dir = thd->lex.backup_dir; - char src_path[FN_REFLEN], dst_path[FN_REFLEN]; - char* table_name = table->real_name; - int error = 0; - int errornum; - const char* errmsg = ""; - dsmArea_t tableArea = 0; - dsmObjectAttr_t objectAttr; - dsmObject_t associate; - dsmObjectType_t associateType; - dsmDbkey_t block, root; - dsmStatus_t rc; - - rc = dsmObjectInfo(pcontext, tableNumber, DSMOBJECT_MIXTABLE, tableNumber, - &tableArea, &objectAttr, &associateType, &block, &root); - if (rc) - { - error = HA_ADMIN_FAILED; - errmsg = "Failed in dsmObjectInfo (.gmd) (Error %d)"; - errornum = rc; - gemini_msg(pcontext, errmsg ,errornum); - goto err; - } - - rc = dsmAreaFlush(pcontext, tableArea, FLUSH_BUFFERS | FLUSH_SYNC); - if (rc) - { - error = HA_ADMIN_FAILED; - errmsg = "Failed in dsmAreaFlush (.gmd) (Error %d)"; - errornum = rc; - gemini_msg(pcontext, errmsg ,errornum); - goto err; - } - - rc = dsmAreaClose(pcontext, tableArea); - if (rc) - { - error = HA_ADMIN_FAILED; - errmsg = "Failed in dsmAreaClose (.gmd) (Error %d)"; - errornum = rc; - gemini_msg(pcontext, errmsg ,errornum); - goto err; - } - - /* Restore the data file */ - if (!fn_format(src_path, table_name, backup_dir, ha_gemini_ext, 4 + 64)) - { - return HA_ADMIN_INVALID; - } - - if (my_copy(src_path, fn_format(dst_path, table->path, "", - ha_gemini_ext, 4), MYF(MY_WME))) - { - error = HA_ADMIN_FAILED; - errmsg = "Failed in my_copy (.gmd) (Error %d)"; - errornum = errno; - gemini_msg(pcontext, errmsg ,errornum); - goto err; - } - - rc = dsmAreaFlush(pcontext, tableArea, FREE_BUFFERS); - if (rc) - { - error = HA_ADMIN_FAILED; - errmsg = "Failed in dsmAreaFlush (.gmd) (Error %d)"; - errornum = rc; - gemini_msg(pcontext, errmsg ,errornum); - goto err; - } - - rc = dsmAreaOpen(pcontext, tableArea, 1); - if (rc) - { - error = HA_ADMIN_FAILED; - errmsg = "Failed in dsmAreaOpen (.gmd) (Error %d)"; - errornum = rc; - gemini_msg(pcontext, errmsg ,errornum); - goto err; - } - -#ifdef GEMINI_BACKUP_IDX - dsmArea_t indexArea = 0; - - rc = dsmObjectInfo(pcontext, tableNumber, DSMOBJECT_MIXINDEX, &indexArea, - &objectAttr, &associate, &associateType, &block, &root); - if (rc) - { - error = HA_ADMIN_FAILED; - errmsg = "Failed in dsmObjectInfo (.gmi) (Error %d)"; - errornum = rc; - gemini_msg(pcontext, errmsg ,errornum); - goto err; - } - - rc = dsmAreaClose(pcontext, indexArea); - if (rc) - { - error = HA_ADMIN_FAILED; - errmsg = "Failed in dsmAreaClose (.gmi) (Error %d)"; - errornum = rc; - gemini_msg(pcontext, errmsg ,errornum); - goto err; - } - - /* Restore the index file */ - if (!fn_format(src_path, table_name, backup_dir, ha_gemini_idx_ext, 4 + 64)) - { - return HA_ADMIN_INVALID; - } - - if (my_copy(src_path, fn_format(dst_path, table->path, "", - ha_gemini_idx_ext, 4), MYF(MY_WME))) - { - error = HA_ADMIN_FAILED; - errmsg = "Failed in my_copy (.gmi) (Error %d)"; - errornum = errno; - gemini_msg(pcontext, errmsg ,errornum); - goto err; - } - - rc = dsmAreaOpen(pcontext, indexArea, 1); - if (rc) - { - error = HA_ADMIN_FAILED; - errmsg = "Failed in dsmAreaOpen (.gmi) (Error %d)"; - errornum = rc; - gemini_msg(pcontext, errmsg ,errornum); - goto err; - } - - return HA_ADMIN_OK; -#else /* #ifdef GEMINI_BACKUP_IDX */ - HA_CHECK_OPT tmp_check_opt; - tmp_check_opt.init(); - /* The following aren't currently implemented in ha_gemini::repair - ** tmp_check_opt.quick = 1; - ** tmp_check_opt.flags |= T_VERY_SILENT; - */ - return (repair(thd, &tmp_check_opt)); -#endif /* #ifdef GEMINI_BACKUP_IDX */ - - err: - { -#if 0 - /* mi_check_print_error is in ha_myisam.cc, so none of the informative - ** error messages above is currently being printed - */ - MI_CHECK param; - myisamchk_init(¶m); - param.thd = thd; - param.op_name = (char*)"restore"; - param.table_name = table->table_name; - param.testflag = 0; - mi_check_print_error(¶m,errmsg, errornum); -#endif - return error; - } -} - - -int ha_gemini::backup(THD* thd, HA_CHECK_OPT *check_opt) -{ - dsmContext_t *pcontext = (dsmContext_t *)thd->gemini.context; - char* backup_dir = thd->lex.backup_dir; - char src_path[FN_REFLEN], dst_path[FN_REFLEN]; - char* table_name = table->real_name; - int error = 0; - int errornum; - const char* errmsg = ""; - dsmArea_t tableArea = 0; - dsmObjectAttr_t objectAttr; - dsmObject_t associate; - dsmObjectType_t associateType; - dsmDbkey_t block, root; - dsmStatus_t rc; - - rc = dsmObjectInfo(pcontext, tableNumber, DSMOBJECT_MIXTABLE, tableNumber, - &tableArea, &objectAttr, &associateType, &block, &root); - if (rc) - { - error = HA_ADMIN_FAILED; - errmsg = "Failed in dsmObjectInfo (.gmd) (Error %d)"; - errornum = rc; - goto err; - } - - /* Flush the buffers before backing up the table */ - dsmAreaFlush((dsmContext_t *)thd->gemini.context, tableArea, - FLUSH_BUFFERS | FLUSH_SYNC); - if (rc) - { - error = HA_ADMIN_FAILED; - errmsg = "Failed in dsmAreaFlush (.gmd) (Error %d)"; - errornum = rc; - gemini_msg(pcontext, errmsg ,errornum); - goto err; - } - - /* Backup the .FRM file */ - if (!fn_format(dst_path, table_name, backup_dir, reg_ext, 4 + 64)) - { - errmsg = "Failed in fn_format() for .frm file: errno = %d"; - error = HA_ADMIN_INVALID; - errornum = errno; - gemini_msg(pcontext, errmsg ,errornum); - goto err; - } - - if (my_copy(fn_format(src_path, table->path,"", reg_ext, 4), - dst_path, - MYF(MY_WME | MY_HOLD_ORIGINAL_MODES ))) - { - error = HA_ADMIN_FAILED; - errmsg = "Failed copying .frm file: errno = %d"; - errornum = errno; - gemini_msg(pcontext, errmsg ,errornum); - goto err; - } - - /* Backup the data file */ - if (!fn_format(dst_path, table_name, backup_dir, ha_gemini_ext, 4 + 64)) - { - errmsg = "Failed in fn_format() for .GMD file: errno = %d"; - error = HA_ADMIN_INVALID; - errornum = errno; - gemini_msg(pcontext, errmsg ,errornum); - goto err; - } - - if (my_copy(fn_format(src_path, table->path,"", ha_gemini_ext, 4), - dst_path, - MYF(MY_WME | MY_HOLD_ORIGINAL_MODES )) ) - { - errmsg = "Failed copying .GMD file: errno = %d"; - error= HA_ADMIN_FAILED; - errornum = errno; - gemini_msg(pcontext, errmsg ,errornum); - goto err; - } - -#ifdef GEMINI_BACKUP_IDX - dsmArea_t indexArea = 0; - - rc = dsmObjectInfo(pcontext, tableNumber, DSMOBJECT_MIXINDEX, &indexArea, - &objectAttr, &associate, &associateType, &block, &root); - if (rc) - { - error = HA_ADMIN_FAILED; - errmsg = "Failed in dsmObjectInfo (.gmi) (Error %d)"; - errornum = rc; - gemini_msg(pcontext, errmsg ,errornum); - goto err; - } - - /* Backup the index file */ - if (!fn_format(dst_path, table_name, backup_dir, ha_gemini_idx_ext, 4 + 64)) - { - errmsg = "Failed in fn_format() for .GMI file: errno = %d"; - error = HA_ADMIN_INVALID; - errornum = errno; - gemini_msg(pcontext, errmsg ,errornum); - goto err; - } - - if (my_copy(fn_format(src_path, table->path,"", ha_gemini_idx_ext, 4), - dst_path, - MYF(MY_WME | MY_HOLD_ORIGINAL_MODES )) ) - { - errmsg = "Failed copying .GMI file: errno = %d"; - error= HA_ADMIN_FAILED; - errornum = errno; - gemini_msg(pcontext, errmsg ,errornum); - goto err; - } -#endif /* #ifdef GEMINI_BACKUP_IDX */ - - return HA_ADMIN_OK; - - err: - { -#if 0 - /* mi_check_print_error is in ha_myisam.cc, so none of the informative - ** error messages above is currently being printed - */ - MI_CHECK param; - myisamchk_init(¶m); - param.thd = thd; - param.op_name = (char*)"backup"; - param.table_name = table->table_name; - param.testflag = 0; - mi_check_print_error(¶m,errmsg, errornum); -#endif - return error; - } -} - - -int ha_gemini::optimize(THD* thd, HA_CHECK_OPT *check_opt) -{ - return HA_ADMIN_ALREADY_DONE; -} - - -ha_rows ha_gemini::records_in_range(int keynr, - 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 error; - int componentLen; - float pctInrange; - ha_rows rows = 5; - - DBUG_ENTER("records_in_range"); - - error = index_init(keynr); - if(error) - DBUG_RETURN(rows); - - pbracketBase->index = (short)pindexNumbers[keynr]; - pbracketBase->keycomps = 1; - - if(start_key) - { - error = pack_key(keynr, pbracketBase, start_key, start_key_len); - if(start_search_flag == HA_READ_AFTER_KEY) - { - /* A greater than operation */ - error = gemKeyAddLow(pbracketBase->keystr + pbracketBase->keyLen, - &componentLen); - pbracketBase->keyLen += componentLen; - } - } - else - { - error = gemKeyLow(pbracketBase->keystr, &componentLen, - pbracketBase->index); - pbracketBase->keyLen = componentLen; - - } - pbracketBase->keyLen -= FULLKEYHDRSZ; - - if(end_key) - { - error = pack_key(keynr, pbracketLimit, end_key, end_key_len); - if(!error && end_search_flag == HA_READ_AFTER_KEY) - { - error = gemKeyAddHigh(pbracketLimit->keystr + pbracketLimit->keyLen, - &componentLen); - pbracketLimit->keyLen += componentLen; - } - } - else - { - error = gemKeyHigh(pbracketLimit->keystr,&componentLen, - pbracketLimit->index); - pbracketLimit->keyLen = componentLen; - } - - pbracketLimit->keyLen -= FULLKEYHDRSZ; - error = dsmIndexRowsInRange((dsmContext_t *)current_thd->gemini.context, - pbracketBase,pbracketLimit, - tableNumber, - &pctInrange); - if(pctInrange >= 1) - rows = (ha_rows)pctInrange; - else - { - rows = (ha_rows)(records * pctInrange); - if(!rows && pctInrange > 0) - rows = 1; - } - index_end(); - - DBUG_RETURN(rows); -} - - -/* - Pack a row for storage. If the row is of fixed length, just store the - row 'as is'. - If not, we will generate a packed row suitable for storage. - This will only fail if we don't have enough memory to pack the row, which; - may only happen in rows with blobs, as the default row length is - pre-allocated. -*/ -int ha_gemini::pack_row(byte **pprow, int *ppackedLength, const byte *record, - bool update) -{ - THD *thd = current_thd; - dsmContext_t *pcontext = (dsmContext_t *)thd->gemini.context; - gemBlobDesc_t *pBlobDesc = pBlobDescs; - - if (fixed_length_row) - { - *pprow = (byte *)record; - *ppackedLength=(int)table->reclength; - return 0; - } - /* Copy null bits */ - memcpy(rec_buff, record, table->null_bytes); - byte *ptr=rec_buff + table->null_bytes; - - for (Field **field=table->field ; *field ; field++) - { -#ifdef GEMINI_TINYBLOB_IN_ROW - /* Tiny blobs (255 bytes or less) are stored in the row; larger - ** blobs are stored in a separate storage object (see ha_gemini::create). - */ - if ((*field)->type() == FIELD_TYPE_BLOB && - ((Field_blob*)*field)->blobtype() != FIELD_TYPE_TINY_BLOB) -#else - if ((*field)->type() == FIELD_TYPE_BLOB) -#endif - { - dsmBlob_t gemBlob; - char *blobptr; - - gemBlob.areaType = DSMOBJECT_BLOB; - gemBlob.blobObjNo = tableNumber; - gemBlob.blobId = 0; - gemBlob.totLength = gemBlob.segLength = - ((Field_blob*)*field)->get_length((char*)record + (*field)->offset()); - ((Field_blob*)*field)->get_ptr((char**) &blobptr); - gemBlob.pBuffer = (dsmBuffer_t *)blobptr; - gemBlob.blobContext.blobOffset = 0; - if (gemBlob.totLength) - { - dsmBlobStart(pcontext, &gemBlob); - if (update && pBlobDesc->blobId) - { - gemBlob.blobId = pBlobDesc->blobId; - dsmBlobUpdate(pcontext, &gemBlob, NULL); - } - else - { - dsmBlobPut(pcontext, &gemBlob, NULL); - } - dsmBlobEnd(pcontext, &gemBlob); - } - ptr = (byte*)((Field_blob*)*field)->pack_id((char*) ptr, - (char*)record + (*field)->offset(), (longlong)gemBlob.blobId); - - pBlobDesc++; - } - else - { - ptr=(byte*) (*field)->pack((char*) ptr, (char*)record + (*field)->offset()); - } - } - - *pprow=rec_buff; - *ppackedLength= (ptr - rec_buff); - return 0; -} - -int ha_gemini::unpack_row(char *record, char *prow) -{ - THD *thd = current_thd; - dsmContext_t *pcontext = (dsmContext_t *)thd->gemini.context; - gemBlobDesc_t *pBlobDesc = pBlobDescs; - - if (fixed_length_row) - { - /* If the table is a VST, the row is in Gemini internal format. - ** Convert the fields to MySQL format. - */ - if (RM_IS_VST(tableNumber)) - { - int i = 2; /* VST fields are numbered sequentially starting at 2 */ - long longValue; - char *fld; - unsigned long unknown; - - for (Field **field = table->field; *field; field++, i++) - { - switch ((*field)->type()) - { - case FIELD_TYPE_LONG: - case FIELD_TYPE_TINY: - case FIELD_TYPE_SHORT: - case FIELD_TYPE_TIMESTAMP: - case FIELD_TYPE_LONGLONG: - case FIELD_TYPE_INT24: - case FIELD_TYPE_DATE: - case FIELD_TYPE_TIME: - case FIELD_TYPE_DATETIME: - case FIELD_TYPE_YEAR: - case FIELD_TYPE_NEWDATE: - case FIELD_TYPE_ENUM: - case FIELD_TYPE_SET: - recGetLONG((dsmText_t *)prow, i, 0, &longValue, &unknown); - if (unknown) - { - (*field)->set_null(); - } - else - { - (*field)->set_notnull(); - (*field)->store((longlong)longValue); - } - break; - - case FIELD_TYPE_DECIMAL: - case FIELD_TYPE_DOUBLE: - case FIELD_TYPE_TINY_BLOB: - case FIELD_TYPE_MEDIUM_BLOB: - case FIELD_TYPE_LONG_BLOB: - case FIELD_TYPE_BLOB: - case FIELD_TYPE_VAR_STRING: - break; - - case FIELD_TYPE_STRING: - svcByteString_t stringFld; - - fld = (char *)my_malloc((*field)->field_length, MYF(MY_WME)); - stringFld.pbyte = (TEXT *)fld; - stringFld.size = (*field)->field_length; - recGetBYTES((dsmText_t *)prow, i, 0, &stringFld, &unknown); - if (unknown) - { - (*field)->set_null(); - } - else - { - (*field)->set_notnull(); - (*field)->store(fld, (*field)->field_length); - } - my_free(fld, MYF(MY_ALLOW_ZERO_PTR)); - break; - - default: - break; - } - } - } - else - { - memcpy(record,(char*) prow,table->reclength); - } - } - else - { - /* Copy null bits */ - const char *ptr= (const char*) prow; - memcpy(record, ptr, table->null_bytes); - ptr+=table->null_bytes; - - for (Field **field=table->field ; *field ; field++) - { -#ifdef GEMINI_TINYBLOB_IN_ROW - /* Tiny blobs (255 bytes or less) are stored in the row; larger - ** blobs are stored in a separate storage object (see ha_gemini::create). - */ - if ((*field)->type() == FIELD_TYPE_BLOB && - ((Field_blob*)*field)->blobtype() != FIELD_TYPE_TINY_BLOB) -#else - if ((*field)->type() == FIELD_TYPE_BLOB) -#endif - { - dsmBlob_t gemBlob; - - gemBlob.areaType = DSMOBJECT_BLOB; - gemBlob.blobObjNo = tableNumber; - gemBlob.blobId = (dsmBlobId_t)(((Field_blob*)*field)->get_id(ptr)); - if (gemBlob.blobId) - { - gemBlob.totLength = - gemBlob.segLength = ((Field_blob*)*field)->get_length(ptr); - /* Allocate memory to store the blob. This memory is freed - ** the next time unpack_row is called for this table. - */ - gemBlob.pBuffer = (dsmBuffer_t *)my_malloc(gemBlob.totLength, - MYF(0)); - if (!gemBlob.pBuffer) - { - return HA_ERR_OUT_OF_MEM; - } - gemBlob.blobContext.blobOffset = 0; - dsmBlobStart(pcontext, &gemBlob); - dsmBlobGet(pcontext, &gemBlob, NULL); - dsmBlobEnd(pcontext, &gemBlob); - } - else - { - gemBlob.pBuffer = 0; - } - ptr = ((Field_blob*)*field)->unpack_id(record + (*field)->offset(), - ptr, (char *)gemBlob.pBuffer); - pBlobDesc->blobId = gemBlob.blobId; - my_free((char*)pBlobDesc->pBlob, MYF(MY_ALLOW_ZERO_PTR)); - pBlobDesc->pBlob = gemBlob.pBuffer; - pBlobDesc++; - } - else - { - ptr= (*field)->unpack(record + (*field)->offset(), ptr); - } - } - } - - return 0; -} - -int ha_gemini::key_cmp(uint keynr, const byte * old_row, - const byte * new_row, bool updateStats) -{ - KEY_PART_INFO *key_part=table->key_info[keynr].key_part; - KEY_PART_INFO *end=key_part+table->key_info[keynr].key_parts; - - for ( uint i = 0 ; key_part != end ; key_part++, i++) - { - if (key_part->null_bit) - { - if ((old_row[key_part->null_offset] & key_part->null_bit) != - (new_row[key_part->null_offset] & key_part->null_bit)) - { - if(updateStats) - table->key_info[keynr].rec_per_key[i]++; - return 1; - } - else if((old_row[key_part->null_offset] & key_part->null_bit) && - (new_row[key_part->null_offset] & key_part->null_bit)) - /* Both are null */ - continue; - } - if (key_part->key_part_flag & (HA_BLOB_PART | HA_VAR_LENGTH)) - { - if (key_part->field->cmp_binary((char*)(old_row + key_part->offset), - (char*)(new_row + key_part->offset), - (ulong) key_part->length)) - { - if(updateStats) - table->key_info[keynr].rec_per_key[i]++; - return 1; - } - } - else - { - if (memcmp(old_row+key_part->offset, new_row+key_part->offset, - key_part->length)) - { - /* Check for special case of -0 which causes table check - to find an invalid key when comparing the the index - value of 0 to the -0 stored in the row */ - if(key_part->field->type() == FIELD_TYPE_DECIMAL) - { - double fieldValue; - char *ptr = key_part->field->ptr; - - key_part->field->ptr = (char *)old_row + key_part->offset; - fieldValue = key_part->field->val_real(); - if(fieldValue == 0) - { - key_part->field->ptr = (char *)new_row + key_part->offset; - fieldValue = key_part->field->val_real(); - if(fieldValue == 0) - { - key_part->field->ptr = ptr; - continue; - } - } - key_part->field->ptr = ptr; - } - if(updateStats) - { - table->key_info[keynr].rec_per_key[i]++; - } - return 1; - } - } - } - return 0; -} - -int gemini_parse_table_name(const char *fullname, char *dbname, char *tabname) -{ - char *namestart; - char *nameend; - - /* separate out the name of the table and the database - */ - namestart = (char *)strchr(fullname + start_of_name, '/'); - if (!namestart) - { - /* if on Windows, slashes go the other way */ - namestart = (char *)strchr(fullname + start_of_name, '\\'); - } - nameend = (char *)strchr(fullname + start_of_name, '.'); - /* sometimes fullname has an extension, sometimes it doesn't */ - if (!nameend) - { - nameend = (char *)fullname + strlen(fullname); - } - strncpy(dbname, fullname + start_of_name, - (namestart - fullname) - start_of_name); - dbname[(namestart - fullname) - start_of_name] = '\0'; - strncpy(tabname, namestart + 1, (nameend - namestart) - 1); - tabname[nameend - namestart - 1] = '\0'; - - return 0; -} - -/* PROGRAM: gemini_is_vst - if the name is the name of a VST, return - * its number - * - * RETURNS: Table number if a match is found - * 0 if not a VST - */ -int -gemini_is_vst(const char *pname) /* IN the name */ -{ - int tablenum = 0; - - for (int i = 0; i < vstnumfils; i++) - { - if (strcmp(pname, vstfil[i].filename) == 0) - { - tablenum = vstfil[i].filnum; - break; - } - } - - return tablenum; -} - -static void print_msg(THD *thd, const char *table_name, const char *op_name, - const char *msg_type, const char *fmt, ...) -{ - String* packet = &thd->packet; - packet->length(0); - char msgbuf[256]; - msgbuf[0] = 0; - va_list args; - va_start(args,fmt); - - my_vsnprintf(msgbuf, sizeof(msgbuf), fmt, args); - msgbuf[sizeof(msgbuf) - 1] = 0; // healthy paranoia - - DBUG_PRINT(msg_type,("message: %s",msgbuf)); - - net_store_data(packet, table_name); - net_store_data(packet, op_name); - net_store_data(packet, msg_type); - net_store_data(packet, msgbuf); - if (my_net_write(&thd->net, (char*)thd->packet.ptr(), - thd->packet.length())) - thd->killed=1; -} - -/* Load shared area with rows per key statistics */ -void -ha_gemini::get_index_stats(THD *thd) -{ - dsmStatus_t rc = 0; - ha_rows *rec_per_key = share->rec_per_key; - - for(uint i = 0; i < table->keys && !rc; i++) - { - for (uint j = 0; j < table->key_info[i].key_parts && !rc;j++) - { - LONG64 rows_per_key; - rc = dsmIndexStatsGet((dsmContext_t *)thd->gemini.context, - tableNumber, pindexNumbers[i],(int)j, - &rows_per_key); - if (rc) - { - gemini_msg((dsmContext_t *)thd->gemini.context, - "Index Statistics faild for table %d index %d, error %d", - tableNumber, pindexNumbers[i], rc); - } - *rec_per_key = (ha_rows)rows_per_key; - rec_per_key++; - } - } - return; -} - -/**************************************************************************** - Handling the shared GEM_SHARE structure that is needed to provide - a global in memory storage location of the rec_per_key stats used - by the optimizer. -****************************************************************************/ - -static byte* gem_get_key(GEM_SHARE *share,uint *length, - my_bool not_used __attribute__((unused))) -{ - *length=share->table_name_length; - return (byte*) share->table_name; -} - -static GEM_SHARE *get_share(const char *table_name, TABLE *table) -{ - GEM_SHARE *share; - - pthread_mutex_lock(&gem_mutex); - uint length=(uint) strlen(table_name); - if (!(share=(GEM_SHARE*) hash_search(&gem_open_tables, (byte*) table_name, - length))) - { - ha_rows *rec_per_key; - char *tmp_name; - - if ((share=(GEM_SHARE *) - my_multi_malloc(MYF(MY_WME | MY_ZEROFILL), - &share, sizeof(*share), - &rec_per_key, table->key_parts * sizeof(ha_rows), - &tmp_name, length+1, - NullS))) - { - share->rec_per_key = rec_per_key; - share->table_name = tmp_name; - share->table_name_length=length; - strcpy(share->table_name,table_name); - if (hash_insert(&gem_open_tables, (byte*) share)) - { - pthread_mutex_unlock(&gem_mutex); - my_free((gptr) share,0); - return 0; - } - thr_lock_init(&share->lock); - pthread_mutex_init(&share->mutex,NULL); - } - } - pthread_mutex_unlock(&gem_mutex); - return share; -} - -static int free_share(GEM_SHARE *share, bool mutex_is_locked) -{ - pthread_mutex_lock(&gem_mutex); - if (mutex_is_locked) - pthread_mutex_unlock(&share->mutex); - if (!--share->use_count) - { - hash_delete(&gem_open_tables, (byte*) share); - thr_lock_delete(&share->lock); - pthread_mutex_destroy(&share->mutex); - my_free((gptr) share, MYF(0)); - } - pthread_mutex_unlock(&gem_mutex); - return 0; -} - -static void gemini_lock_table_overflow_error(dsmContext_t *pcontext) -{ - gemini_msg(pcontext, "The total number of locks exceeds the lock table size"); - gemini_msg(pcontext, "Either increase gemini_lock_table_size or use a"); - gemini_msg(pcontext, "different transaction isolation level"); -} - -#endif /* HAVE_GEMINI_DB */ diff --git a/sql/ha_gemini.h b/sql/ha_gemini.h deleted file mode 100644 index 006401271c6..00000000000 --- a/sql/ha_gemini.h +++ /dev/null @@ -1,208 +0,0 @@ -/* Copyright (C) 2000 MySQL AB & 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 "gem_my_global.h" -#include "dstd.h" -#include "dsmpub.h" - -/* class for the the gemini handler */ - -enum enum_key_string_options{KEY_CREATE,KEY_DELETE,KEY_CHECK}; -typedef struct st_gemini_share { - ha_rows *rec_per_key; - THR_LOCK lock; - pthread_mutex_t mutex; - char *table_name; - uint table_name_length,use_count; -} GEM_SHARE; - -typedef struct gemBlobDesc -{ - dsmBlobId_t blobId; - dsmBuffer_t *pBlob; -} gemBlobDesc_t; - -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 - dsmRecid_t 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 - gemBlobDesc_t *pBlobDescs; - - int index_open(char *tableName); - int pack_row(byte **prow, int *ppackedLength, const byte *record, - bool update); - int 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, bool updateStats); - - int saveKeyStats(THD *thd); - void get_index_stats(THD *thd); - - 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_DATA lock; - GEM_SHARE *share; - - 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_BLOB_KEY | - HA_NO_TEMP_TABLES | HA_NO_FULLTEXT_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 / 2; } - 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 analyze(THD* thd, HA_CHECK_OPT* check_opt); - int check(THD* thd, HA_CHECK_OPT* check_opt); - int repair(THD* thd, HA_CHECK_OPT* check_opt); - int restore(THD* thd, HA_CHECK_OPT* check_opt); - int backup(THD* thd, HA_CHECK_OPT* check_opt); - int optimize(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); - void update_create_info(HA_CREATE_INFO *create_info); - 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 SHOW_COMP_OPTION have_gemini; -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 char *gemini_basedir; -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); -int gemini_recovery_logging(THD *thd, bool on); -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 = BLKSIZE; -const int gemini_recbits = DEFAULT_RECBITS; - -extern "C" void uttrace(void); diff --git a/sql/handler.cc b/sql/handler.cc index 5a41498aff1..4876a73d2a9 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -35,9 +35,6 @@ #ifdef HAVE_INNOBASE_DB #include "ha_innobase.h" #endif -#ifdef HAVE_GEMINI_DB -#include "ha_gemini.h" -#endif #include <myisampack.h> #include <errno.h> @@ -81,10 +78,6 @@ enum db_type ha_checktype(enum db_type database_type) case DB_TYPE_INNODB: return(innodb_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 @@ -123,10 +116,6 @@ handler *get_new_handler(TABLE *table, enum db_type db_type) case DB_TYPE_INNODB: 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); case DB_TYPE_MYISAM: @@ -162,17 +151,6 @@ int ha_init() have_innodb=SHOW_OPTION_DISABLED; } #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; - else - have_gemini=SHOW_OPTION_DISABLED; - } -#endif return 0; } @@ -200,10 +178,6 @@ int ha_panic(enum ha_panic_function flag) if (!innodb_skip) error|=innobase_end(); #endif -#ifdef HAVE_GEMINI_DB - if (!gemini_skip) - error|=gemini_end(); -#endif return error; } /* ha_panic */ @@ -214,12 +188,6 @@ void ha_close_connection(THD* thd) if (!innodb_skip) innobase_close_connection(thd); #endif -#ifdef HAVE_GEMINI_DB - if (!gemini_skip && thd->gemini.context) - { - gemini_disconnect(thd); - } -#endif /* HAVE_GEMINI_DB */ } /* @@ -285,20 +253,6 @@ int ha_commit_trans(THD *thd, THD_TRANS* trans) trans->innodb_active_trans=0; } #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!"); thd->tx_isolation=thd->session_tx_isolation; @@ -337,18 +291,6 @@ int ha_rollback_trans(THD *thd, THD_TRANS *trans) trans->innodb_active_trans=0; } #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, WRITE_CACHE, (my_off_t) 0, 0, 1); @@ -359,17 +301,6 @@ int ha_rollback_trans(THD *thd, THD_TRANS *trans) DBUG_RETURN(error); } -void ha_set_spin_retries(uint retries) -{ -#ifdef HAVE_GEMINI_DB - if (!gemini_skip) - { - gemini_set_option_long(GEM_OPTID_SPIN_RETRIES, retries); - } -#endif /* HAVE_GEMINI_DB */ -} - - bool ha_flush_logs() { bool result=0; @@ -751,22 +682,6 @@ 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; -} - /* Tell the handler to turn on or off logging to the handler's recovery log */ @@ -775,14 +690,6 @@ int ha_recovery_logging(THD *thd, bool on) int error=0; DBUG_ENTER("ha_recovery_logging"); -#ifdef USING_TRANSACTIONS - if (opt_using_transactions) - { -#ifdef HAVE_GEMINI_DB - error = gemini_recovery_logging(thd, on); -#endif - } -#endif DBUG_RETURN(error); } diff --git a/sql/handler.h b/sql/handler.h index f0806ea3bea..dc26ff1d303 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -25,7 +25,7 @@ #define NO_HASH /* Not yet implemented */ #endif -#if defined(HAVE_BERKELEY_DB) || defined(HAVE_INNOBASE_DB) || defined(HAVE_GEMINI_DB) +#if defined(HAVE_BERKELEY_DB) || defined(HAVE_INNOBASE_DB) #define USING_TRANSACTIONS #endif @@ -132,7 +132,6 @@ enum row_type { ROW_TYPE_NOT_USED=-1, ROW_TYPE_DEFAULT, ROW_TYPE_FIXED, typedef struct st_thd_trans { void *bdb_tid; void *innobase_tid; - void *gemini_tid; bool innodb_active_trans; } THD_TRANS; @@ -323,17 +322,6 @@ 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[]; @@ -364,5 +352,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); int ha_recovery_logging(THD *thd, bool on); diff --git a/sql/lex.h b/sql/lex.h index 72d77e18910..8976826fe1e 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -153,8 +153,6 @@ static SYMBOL symbols[] = { { "FULL", SYM(FULL),0,0}, { "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}, diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 7b0c97c4b79..1a84877df05 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -28,9 +28,6 @@ #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> @@ -183,11 +180,6 @@ SHOW_COMP_OPTION have_berkeley_db=SHOW_OPTION_YES; #else SHOW_COMP_OPTION have_berkeley_db=SHOW_OPTION_NO; #endif -#ifdef HAVE_GEMINI_DB -SHOW_COMP_OPTION have_gemini=SHOW_OPTION_YES; -#else -SHOW_COMP_OPTION have_gemini=SHOW_OPTION_NO; -#endif #ifdef HAVE_INNOBASE_DB SHOW_COMP_OPTION have_innodb=SHOW_OPTION_YES; #else @@ -334,9 +326,6 @@ enum_tx_isolation default_tx_isolation=ISO_READ_COMMITTED; uint rpl_recovery_rank=0; -#ifdef HAVE_GEMINI_DB -const char *gemini_recovery_options_str="FULL"; -#endif my_string mysql_unix_port=NULL, mysql_tmpdir=NULL, allocated_mysql_tmpdir=NULL; ulong my_bind_addr; /* the address we bind to */ DATE_FORMAT dayord; @@ -1240,9 +1229,6 @@ the thread stack. Please read http://www.mysql.com/doc/L/i/Linux.html\n\n", #ifdef HAVE_STACKTRACE if(!(test_flags & TEST_NO_STACKTRACE)) { -#ifdef HAVE_GEMINI_DB - utrace(); -#endif print_stacktrace(thd ? (gptr) thd->thread_stack : (gptr) 0, thread_stack); } @@ -2600,10 +2586,8 @@ enum options { OPT_INNODB_FLUSH_LOG_AT_TRX_COMMIT, OPT_INNODB_FLUSH_METHOD, OPT_SAFE_SHOW_DB, - OPT_GEMINI_SKIP, OPT_INNODB_SKIP, + OPT_INNODB_SKIP, OPT_SKIP_SAFEMALLOC, OPT_TEMP_POOL, OPT_TX_ISOLATION, - OPT_GEMINI_FLUSH_LOG, OPT_GEMINI_RECOVER, - OPT_GEMINI_UNBUFFERED_IO, OPT_SKIP_SAFEMALLOC, OPT_SKIP_STACK_TRACE, OPT_SKIP_SYMLINKS, OPT_MAX_BINLOG_DUMP_EVENTS, OPT_SPORADIC_BINLOG_DUMP_FAIL, OPT_SAFE_USER_CREATE, OPT_SQL_MODE, @@ -2647,11 +2631,6 @@ static struct option long_options[] = { {"enable-pstack", no_argument, 0, (int) OPT_DO_PSTACK}, {"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 */ {"innodb_data_file_path", required_argument, 0, @@ -2746,7 +2725,6 @@ static struct option long_options[] = { (int) OPT_SHOW_SLAVE_AUTH_INFO}, {"skip-bdb", no_argument, 0, (int) OPT_BDB_SKIP}, {"skip-innodb", no_argument, 0, (int) OPT_INNODB_SKIP}, - {"skip-gemini", no_argument, 0, (int) OPT_GEMINI_SKIP}, {"skip-concurrent-insert", no_argument, 0, (int) OPT_SKIP_CONCURRENT_INSERT}, {"skip-delay-key-write", no_argument, 0, (int) OPT_SKIP_DELAY_KEY_WRITE}, {"skip-grant-tables", no_argument, 0, (int) OPT_SKIP_GRANT}, @@ -2814,22 +2792,6 @@ CHANGEABLE_VAR changeable_vars[] = { HA_FT_MAXLEN, 10, HA_FT_MAXLEN, 0, 1 }, { "ft_max_word_len_for_sort",(long*) &ft_max_word_len_for_sort, 20, 4, HA_FT_MAXLEN, 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 {"innodb_mirrored_log_groups", (long*) &innobase_mirrored_log_groups, 1, 1, 10, 0, 1}, @@ -2965,18 +2927,7 @@ struct show_var_st init_vars[]= { {"ft_min_word_len", (char*) &ft_min_word_len, SHOW_LONG}, {"ft_max_word_len", (char*) &ft_max_word_len, SHOW_LONG}, {"ft_max_word_len_for_sort",(char*) &ft_max_word_len_for_sort, 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_innodb", (char*) &have_innodb, SHOW_HAVE}, {"have_isam", (char*) &have_isam, SHOW_HAVE}, {"have_raid", (char*) &have_raid, SHOW_HAVE}, @@ -3293,16 +3244,6 @@ 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)\n\ - --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("\ --innodb_data_home_dir=dir The common part for Innodb table spaces\n\ @@ -3879,27 +3820,6 @@ static void get_options(int argc,char **argv) have_berkeley_db=SHOW_OPTION_DISABLED; #endif break; - case OPT_GEMINI_SKIP: -#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_INNODB_SKIP: #ifdef HAVE_INNOBASE_DB innodb_skip=1; @@ -4446,68 +4366,6 @@ 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 ]; diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 595bee99908..d16998e1581 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1390,11 +1390,7 @@ TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type lock_type) #if defined( __WIN__) || defined(OS2) /* Win32 can't drop a file that is open */ - if (lock_type == TL_WRITE_ALLOW_READ -#ifdef HAVE_GEMINI_DB - && table->db_type != DB_TYPE_GEMINI -#endif /* HAVE_GEMINI_DB */ - ) + if (lock_type == TL_WRITE_ALLOW_READ) { lock_type= TL_WRITE; } diff --git a/sql/sql_class.cc b/sql/sql_class.cc index b77166d0bc0..006e7364b3b 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -93,7 +93,6 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0), tmp_table=0; lock=locked_tables=0; used_tables=0; - gemini_spin_retries=0; cuted_fields=sent_row_count=0L; start_time=(time_t) 0; current_linfo = 0; @@ -110,9 +109,6 @@ 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, MY_MUTEX_INIT_FAST); diff --git a/sql/sql_class.h b/sql/sql_class.h index b34b97b29a0..f2e174d85c1 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -262,9 +262,6 @@ 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, *handler_items; CONVERT *convert_set; Field *dupp_field; @@ -280,7 +277,6 @@ public: max_join_size, sent_row_count, examined_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; @@ -374,12 +370,10 @@ public: { #ifdef USING_TRANSACTIONS return (transaction.all.bdb_tid != 0 || - transaction.all.innodb_active_trans != 0 || - transaction.all.gemini_tid != 0); + transaction.all.innodb_active_trans != 0); #else return 0; #endif - } inline gptr alloc(unsigned int size) { return alloc_root(&mem_root,size); } inline gptr calloc(unsigned int size) diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 6ccb0a6b059..83652d1f818 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -174,7 +174,6 @@ typedef struct st_lex { HA_CREATE_INFO create_info; LEX_MASTER_INFO mi; // used by CHANGE MASTER ulong thread_id,type; - ulong gemini_spin_retries; enum_sql_command sql_command; enum lex_states next_state; enum enum_duplicates duplicates; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index cdf6cb8e7f1..7104e41fc46 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1897,11 +1897,6 @@ mysql_execute_command(void) TL_WRITE_LOW_PRIORITY : TL_WRITE); thd->default_select_limit=select_lex->select_limit; thd->tx_isolation=lex->tx_isolation; - if (thd->gemini_spin_retries != lex->gemini_spin_retries) - { - thd->gemini_spin_retries= lex->gemini_spin_retries; - ha_set_spin_retries(thd->gemini_spin_retries); - } DBUG_PRINT("info",("options: %ld limit: %ld", thd->options,(long) thd->default_select_limit)); diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc index 0f6e2f9fbf3..7a6652953cc 100644 --- a/sql/sql_rename.cc +++ b/sql/sql_rename.cc @@ -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,cerror,got_all_locks=1; + bool error=1,got_all_locks=1; TABLE_LIST *lock_table,*ren_table=0; DBUG_ENTER("mysql_rename_tables"); @@ -87,12 +87,7 @@ end: } /* 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) + if (!error) { mysql_update_log.write(thd,thd->query,thd->query_length); if (mysql_bin_log.is_open()) diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 99c2b837480..9306a6d4d9a 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1192,12 +1192,6 @@ 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)); } @@ -1704,7 +1698,6 @@ end_temporary: DBUG_RETURN(0); err: - (void) ha_commit_rename(thd); // Just for safety DBUG_RETURN(-1); } diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 7d084f5878e..7f35886f52d 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -185,8 +185,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token FROM %token FULL %token FULLTEXT_SYM -%token GEMINI_SYM -%token GEMINI_SPIN_RETRIES %token GLOBAL_SYM %token GRANT %token GRANTS @@ -812,7 +810,6 @@ table_types: | HEAP_SYM { $$= DB_TYPE_HEAP; } | BERKELEY_DB_SYM { $$= DB_TYPE_BERKELEY_DB; } | INNOBASE_SYM { $$= DB_TYPE_INNODB; } - | GEMINI_SYM { $$= DB_TYPE_GEMINI; } row_types: DEFAULT { $$= ROW_TYPE_DEFAULT; } @@ -2862,7 +2859,6 @@ keyword: | FIXED_SYM {} | FLUSH_SYM {} | GRANTS {} - | GEMINI_SYM {} | GLOBAL_SYM {} | HEAP_SYM {} | HANDLER_SYM {} @@ -2957,7 +2953,6 @@ set: lex->sql_command= SQLCOM_SET_OPTION; lex->select->options=lex->thd->options; lex->select->select_limit=lex->thd->default_select_limit; - lex->gemini_spin_retries=lex->thd->gemini_spin_retries; lex->tx_isolation=lex->thd->tx_isolation; lex->option_type=0; lex->option_list.empty() @@ -3026,14 +3021,6 @@ option_value: { current_thd->next_insert_id=$3; } - | GEMINI_SPIN_RETRIES equal ULONG_NUM - { - Lex->gemini_spin_retries= $3; - } - | GEMINI_SPIN_RETRIES equal DEFAULT - { - Lex->gemini_spin_retries= 1; - } | CHAR_SYM SET IDENT { CONVERT *tmp; |