diff options
author | unknown <serg@serg.mylan> | 2004-11-23 15:50:29 +0100 |
---|---|---|
committer | unknown <serg@serg.mylan> | 2004-11-23 15:50:29 +0100 |
commit | 555e0e444fbc7cdf9f660019abac34797ba6f033 (patch) | |
tree | 68966b4b0c10161f3a9fef27193c1356b0f68cda | |
parent | 8941ac568573f059233f37e8bef48039b2ecff41 (diff) | |
parent | f30976748cf8d164be6dc29b5c0064b9e0f2b3d9 (diff) | |
download | mariadb-git-555e0e444fbc7cdf9f660019abac34797ba6f033.tar.gz |
Merge serg.mylan:/usr/home/serg/Abk/mysql-4.1
into serg.mylan:/usr/home/serg/Abk/mysql-5.0
sql/mysqld.cc:
Auto merged
-rw-r--r-- | myisam/mi_create.c | 10 | ||||
-rw-r--r-- | mysql-test/mysql_test_run.c | 1728 | ||||
-rw-r--r-- | ndb/include/ndbapi/NdbConnection.hpp | 4 | ||||
-rw-r--r-- | ndb/src/ndbapi/NdbConnection.cpp | 36 | ||||
-rw-r--r-- | ndb/test/ndbapi/testBlobs.cpp | 303 | ||||
-rw-r--r-- | sql/mysqld.cc | 23 |
6 files changed, 365 insertions, 1739 deletions
diff --git a/myisam/mi_create.c b/myisam/mi_create.c index 7fc7cc4edf1..f99a2c655d2 100644 --- a/myisam/mi_create.c +++ b/myisam/mi_create.c @@ -16,7 +16,7 @@ /* Create a MyISAM table */ -#include "fulltext.h" +#include "ftdefs.h" #include "sp_defs.h" #if defined(MSDOS) || defined(__WIN__) @@ -41,7 +41,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, File dfile,file; int errpos,save_errno; myf create_flag; - uint fields,length,max_key_length,packed,pointer, + uint fields,length,max_key_length,packed,pointer,real_length_diff, key_length,info_length,key_segs,options,min_key_length_skip, base_pos,varchar_count,long_varchar_count,varchar_length, max_key_block_length,unique_key_parts,fulltext_keys,offset; @@ -238,7 +238,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, { share.state.key_root[i]= HA_OFFSET_ERROR; - min_key_length_skip=length=0; + min_key_length_skip=length=real_length_diff=0; key_length=pointer; if (keydef->flag & HA_SPATIAL) { @@ -297,6 +297,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, key_length+= HA_FT_MAXBYTELEN+HA_FT_WLEN; length++; /* At least one length byte */ min_key_length_skip+=HA_FT_MAXBYTELEN; + real_length_diff=HA_FT_MAXBYTELEN-FT_MAX_WORD_LEN_FOR_SORT; } else { @@ -397,7 +398,8 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, key_segs) share.state.rec_per_key_part[key_segs-1]=1L; length+=key_length; - keydef->block_length= MI_BLOCK_SIZE(length,pointer,MI_MAX_KEYPTR_SIZE); + keydef->block_length= MI_BLOCK_SIZE(length-real_length_diff, + pointer,MI_MAX_KEYPTR_SIZE); if (keydef->block_length > MI_MAX_KEY_BLOCK_LENGTH || length >= MI_MAX_KEY_BUFF) { diff --git a/mysql-test/mysql_test_run.c b/mysql-test/mysql_test_run.c deleted file mode 100644 index 6f388fc4a45..00000000000 --- a/mysql-test/mysql_test_run.c +++ /dev/null @@ -1,1728 +0,0 @@ -/* - Copyright (c) 2002, 2003 Novell, Inc. All Rights Reserved. - - 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 -*/ - -#include <stdlib.h> -#include <stdio.h> -#include <errno.h> -#ifndef __WIN__ -#include <dirent.h> -#endif -#include <string.h> -#ifdef __NETWARE__ -#include <screen.h> -#include <nks/vm.h> -#endif -#include <ctype.h> -#include <sys/stat.h> -#ifndef __WIN__ -#include <unistd.h> -#endif -#include <fcntl.h> -#ifdef __NETWARE__ -#include <sys/mode.h> -#endif -#ifdef __WIN__ -#include <Shlwapi.h> -#include <direct.h> -#endif - -#include "my_manage.h" - -/****************************************************************************** - - macros - -******************************************************************************/ - -#define HEADER "TEST RESULT \n" -#define DASH "-------------------------------------------------------\n" - -#define NW_TEST_SUFFIX ".nw-test" -#define NW_RESULT_SUFFIX ".nw-result" -#define TEST_SUFFIX ".test" -#define RESULT_SUFFIX ".result" -#define REJECT_SUFFIX ".reject" -#define OUT_SUFFIX ".out" -#define ERR_SUFFIX ".err" - -const char *TEST_PASS = "[ pass ]"; -const char *TEST_SKIP = "[ skip ]"; -const char *TEST_FAIL = "[ fail ]"; -const char *TEST_BAD = "[ bad ]"; -const char *TEST_IGNORE = "[ignore]"; - -/****************************************************************************** - - global variables - -******************************************************************************/ -#ifdef __NETWARE__ -static char base_dir[PATH_MAX] = "sys:/mysql"; -#else -static char base_dir[PATH_MAX] = ".."; -#endif -static char db[PATH_MAX] = "test"; -static char user[PATH_MAX] = "root"; -static char password[PATH_MAX] = ""; - -int master_port = 9306; -int slave_port = 9307; - -#if !defined(__NETWARE__) && !defined(__WIN__) -static char master_socket[PATH_MAX] = "./var/tmp/master.sock"; -static char slave_socket[PATH_MAX] = "./var/tmp/slave.sock"; -#endif - -// comma delimited list of tests to skip or empty string -#ifndef __WIN__ -static char skip_test[PATH_MAX] = " lowercase_table3 , system_mysql_db_fix "; -#else -/* - The most ignore testes contain the calls of system command -*/ -#define MAX_COUNT_TESTES 1024 -/* - lowercase_table3 is disabled by Gerg - system_mysql_db_fix is disabled by Gerg - sp contains a command system - rpl_EE_error contains a command system - rpl_loaddatalocal contains a command system - ndb_autodiscover contains a command system - rpl_rotate_logs contains a command system - repair contains a command system - rpl_trunc_binlog contains a command system - mysqldump contains a command system - rpl000001 makes non-exit loop...temporary skiped -*/ -static char skip_test[PATH_MAX] = " lowercase_table3 , system_mysql_db_fix , sp , rpl_EE_error , rpl_loaddatalocal , ndb_autodiscover , rpl_rotate_logs , repair , rpl_trunc_binlog , mysqldump , rpl000001 "; -#endif -static char ignore_test[PATH_MAX] = ""; - -static char bin_dir[PATH_MAX]; -static char mysql_test_dir[PATH_MAX]; -static char test_dir[PATH_MAX]; -static char mysql_tmp_dir[PATH_MAX]; -static char result_dir[PATH_MAX]; -static char master_dir[PATH_MAX]; -static char slave_dir[PATH_MAX]; -static char lang_dir[PATH_MAX]; -static char char_dir[PATH_MAX]; - -static char mysqladmin_file[PATH_MAX]; -static char mysqld_file[PATH_MAX]; -static char mysqltest_file[PATH_MAX]; -#ifndef __WIN__ -static char master_pid[PATH_MAX]; -static char slave_pid[PATH_MAX]; -static char sh_file[PATH_MAX] = "/bin/sh"; -#else -static HANDLE master_pid; -static HANDLE slave_pid; -#endif - -static char master_opt[PATH_MAX] = ""; -static char slave_opt[PATH_MAX] = ""; - -static char slave_master_info[PATH_MAX] = ""; - -static char master_init_script[PATH_MAX] = ""; -static char slave_init_script[PATH_MAX] = ""; - -// OpenSSL -static char ca_cert[PATH_MAX]; -static char server_cert[PATH_MAX]; -static char server_key[PATH_MAX]; -static char client_cert[PATH_MAX]; -static char client_key[PATH_MAX]; - -int total_skip = 0; -int total_pass = 0; -int total_fail = 0; -int total_test = 0; - -int total_ignore = 0; - -int use_openssl = FALSE; -int master_running = FALSE; -int slave_running = FALSE; -int skip_slave = TRUE; -int single_test = TRUE; - -int restarts = 0; - -FILE *log_fd = NULL; - -/****************************************************************************** - - functions - -******************************************************************************/ - -/****************************************************************************** - - prototypes - -******************************************************************************/ - -void report_stats(); -void install_db(char *); -void mysql_install_db(); -void start_master(); -void start_slave(); -void mysql_start(); -void stop_slave(); -void stop_master(); -void mysql_stop(); -void mysql_restart(); -int read_option(char *, char *); -void run_test(char *); -void setup(char *); -void vlog(const char *, va_list); -void mlog(const char *, ...); -void log_info(const char *, ...); -void log_error(const char *, ...); -void log_errno(const char *, ...); -void die(const char *); -char *str_tok(char *string, const char *delim); -#ifndef __WIN__ -void run_init_script(const char *script_name); -#endif -/****************************************************************************** - - report_stats() - - Report the gathered statistics. - -******************************************************************************/ -void report_stats() -{ - if (total_fail == 0) - { - mlog("\nAll %d test(s) were successful.\n", total_test); - } - else - { - double percent = ((double)total_pass / total_test) * 100; - - mlog("\nFailed %u/%u test(s), %.02f%% successful.\n", - total_fail, total_test, percent); - mlog("\nThe .out and .err files in %s may give you some\n", result_dir); - mlog("hint of what when wrong.\n"); - mlog("\nIf you want to report this error, please first read the documentation\n"); - mlog("at: http://www.mysql.com/doc/M/y/MySQL_test_suite.html\n"); - } -} - -/****************************************************************************** - - install_db() - - Install the a database. - -******************************************************************************/ -void install_db(char *datadir) -{ - arg_list_t al; - int err; - char input[PATH_MAX]; - char output[PATH_MAX]; - char error[PATH_MAX]; - - // input file -#ifdef __NETWARE__ - snprintf(input, PATH_MAX, "%s/bin/init_db.sql", base_dir); -#else - snprintf(input, PATH_MAX, "%s/mysql-test/init_db.sql", base_dir); -#endif - snprintf(output, PATH_MAX, "%s/install.out", datadir); - snprintf(error, PATH_MAX, "%s/install.err", datadir); - - // args - init_args(&al); - add_arg(&al, mysqld_file); - add_arg(&al, "--no-defaults"); - add_arg(&al, "--bootstrap"); - add_arg(&al, "--skip-grant-tables"); - add_arg(&al, "--basedir=%s", base_dir); - add_arg(&al, "--datadir=%s", datadir); - add_arg(&al, "--skip-innodb"); - add_arg(&al, "--skip-bdb"); -#ifndef __NETWARE__ - add_arg(&al, "--character-sets-dir=%s", char_dir); - add_arg(&al, "--language=%s", lang_dir); -#endif - - // spawn - if ((err = spawn(mysqld_file, &al, TRUE, input, output, error, NULL)) != 0) - { - die("Unable to create database."); - } - - // free args - free_args(&al); -} - -/****************************************************************************** - - mysql_install_db() - - Install the test databases. - -******************************************************************************/ -void mysql_install_db() -{ - char temp[PATH_MAX]; - - // var directory - snprintf(temp, PATH_MAX, "%s/var", mysql_test_dir); - - // clean up old direcotry - del_tree(temp); - - // create var directory -#ifndef __WIN__ - mkdir(temp, S_IRWXU); - // create subdirectories - mlog("Creating test-suite folders...\n"); - snprintf(temp, PATH_MAX, "%s/var/run", mysql_test_dir); - mkdir(temp, S_IRWXU); - snprintf(temp, PATH_MAX, "%s/var/tmp", mysql_test_dir); - mkdir(temp, S_IRWXU); - snprintf(temp, PATH_MAX, "%s/var/master-data", mysql_test_dir); - mkdir(temp, S_IRWXU); - snprintf(temp, PATH_MAX, "%s/var/master-data/mysql", mysql_test_dir); - mkdir(temp, S_IRWXU); - snprintf(temp, PATH_MAX, "%s/var/master-data/test", mysql_test_dir); - mkdir(temp, S_IRWXU); - snprintf(temp, PATH_MAX, "%s/var/slave-data", mysql_test_dir); - mkdir(temp, S_IRWXU); - snprintf(temp, PATH_MAX, "%s/var/slave-data/mysql", mysql_test_dir); - mkdir(temp, S_IRWXU); - snprintf(temp, PATH_MAX, "%s/var/slave-data/test", mysql_test_dir); - mkdir(temp, S_IRWXU); -#else - mkdir(temp); - // create subdirectories - mlog("Creating test-suite folders...\n"); - snprintf(temp, PATH_MAX, "%s/var/run", mysql_test_dir); - mkdir(temp); - snprintf(temp, PATH_MAX, "%s/var/tmp", mysql_test_dir); - mkdir(temp); - snprintf(temp, PATH_MAX, "%s/var/master-data", mysql_test_dir); - mkdir(temp); - snprintf(temp, PATH_MAX, "%s/var/master-data/mysql", mysql_test_dir); - mkdir(temp); - snprintf(temp, PATH_MAX, "%s/var/master-data/test", mysql_test_dir); - mkdir(temp); - snprintf(temp, PATH_MAX, "%s/var/slave-data", mysql_test_dir); - mkdir(temp); - snprintf(temp, PATH_MAX, "%s/var/slave-data/mysql", mysql_test_dir); - mkdir(temp); - snprintf(temp, PATH_MAX, "%s/var/slave-data/test", mysql_test_dir); - mkdir(temp); -#endif - - // install databases - mlog("Creating test databases for master... \n"); - install_db(master_dir); - mlog("Creating test databases for slave... \n"); - install_db(slave_dir); -} - -/****************************************************************************** - - start_master() - - Start the master server. - -******************************************************************************/ -void start_master() -{ - arg_list_t al; - int err; - char master_out[PATH_MAX]; - char master_err[PATH_MAX]; -// char temp[PATH_MAX]; - char temp2[PATH_MAX]; - - // remove old berkeley db log files that can confuse the server - removef("%s/log.*", master_dir); - - // remove stale binary logs - removef("%s/var/log/*-bin.*", mysql_test_dir); - - // remove stale binary logs - removef("%s/var/log/*.index", mysql_test_dir); - - // remove master.info file - removef("%s/master.info", master_dir); - - // remove relay files - removef("%s/var/log/*relay*", mysql_test_dir); - - // remove relay-log.info file - removef("%s/relay-log.info", master_dir); - - // init script - if (master_init_script[0] != 0) - { -#ifdef __NETWARE__ - // TODO: use the scripts - if (strinstr(master_init_script, "repair_part2-master.sh") != 0) - { - FILE *fp; - - // create an empty index file - snprintf(temp, PATH_MAX, "%s/test/t1.MYI", master_dir); - fp = fopen(temp, "wb+"); - - fputs("1", fp); - - fclose(fp); - } -#elif !defined(__WIN__) - run_init_script(master_init_script); -#endif - } - - // redirection files - snprintf(master_out, PATH_MAX, "%s/var/run/master%u.out", - mysql_test_dir, restarts); - snprintf(master_err, PATH_MAX, "%s/var/run/master%u.err", - mysql_test_dir, restarts); -#ifndef __WIN__ - snprintf(temp2,PATH_MAX,"%s/var",mysql_test_dir); - mkdir(temp2,S_IRWXU); - snprintf(temp2,PATH_MAX,"%s/var/log",mysql_test_dir); - mkdir(temp2,S_IRWXU); -#else - snprintf(temp2,PATH_MAX,"%s/var",mysql_test_dir); - mkdir(temp2); - snprintf(temp2,PATH_MAX,"%s/var/log",mysql_test_dir); - mkdir(temp2); -#endif - // args - init_args(&al); - add_arg(&al, "%s", mysqld_file); - add_arg(&al, "--no-defaults"); - add_arg(&al, "--log-bin=%s/var/log/master-bin",mysql_test_dir); - add_arg(&al, "--server-id=1"); - add_arg(&al, "--basedir=%s", base_dir); - add_arg(&al, "--port=%u", master_port); -#if !defined(__NETWARE__) && !defined(__WIN__) - add_arg(&al, "--socket=%s",master_socket); -#endif - add_arg(&al, "--local-infile"); - add_arg(&al, "--core"); - add_arg(&al, "--datadir=%s", master_dir); -#ifndef __WIN__ - add_arg(&al, "--pid-file=%s", master_pid); -#endif - add_arg(&al, "--character-sets-dir=%s", char_dir); - add_arg(&al, "--tmpdir=%s", mysql_tmp_dir); - add_arg(&al, "--language=%s", lang_dir); -#ifdef DEBUG //only for debug builds - add_arg(&al, "--debug"); -#endif - - if (use_openssl) - { - add_arg(&al, "--ssl-ca=%s", ca_cert); - add_arg(&al, "--ssl-cert=%s", server_cert); - add_arg(&al, "--ssl-key=%s", server_key); - } - - // $MASTER_40_ARGS - add_arg(&al, "--rpl-recovery-rank=1"); - add_arg(&al, "--init-rpl-role=master"); - - // $SMALL_SERVER - add_arg(&al, "-O"); - add_arg(&al, "key_buffer_size=1M"); - add_arg(&al, "-O"); - add_arg(&al, "sort_buffer=256K"); - add_arg(&al, "-O"); - add_arg(&al, "max_heap_table_size=1M"); - - // $EXTRA_MASTER_OPT - if (master_opt[0] != 0) - { - char *p; - - p = (char *)str_tok(master_opt, " \t"); - if (!strstr(master_opt, "timezone")) - { - while (p) - { - add_arg(&al, "%s", p); - p = (char *)str_tok(NULL, " \t"); - } - } - } - - // remove the pid file if it exists -#ifndef __WIN__ - remove(master_pid); -#endif - - // spawn -#ifdef __WIN__ - if ((err= spawn(mysqld_file, &al, FALSE, NULL, master_out, master_err, &master_pid)) == 0) -#else - if ((err= spawn(mysqld_file, &al, FALSE, NULL, master_out, master_err, master_pid)) == 0) -#endif - { - sleep_until_file_exists(master_pid); - - if ((err = wait_for_server_start(bin_dir, mysqladmin_file, user, password, master_port, - mysql_tmp_dir)) == 0) - { - master_running = TRUE; - } - else - { - log_error("The master server went down early."); - } - } - else - { - log_error("Unable to start master server."); - } - - // free_args - free_args(&al); -} - -/****************************************************************************** - - start_slave() - - Start the slave server. - -******************************************************************************/ -void start_slave() -{ - arg_list_t al; - int err; - char slave_out[PATH_MAX]; - char slave_err[PATH_MAX]; - - // skip? - if (skip_slave) return; - - // remove stale binary logs - removef("%s/*-bin.*", slave_dir); - - // remove stale binary logs - removef("%s/*.index", slave_dir); - - // remove master.info file - removef("%s/master.info", slave_dir); - - // remove relay files - removef("%s/var/log/*relay*", mysql_test_dir); - - // remove relay-log.info file - removef("%s/relay-log.info", slave_dir); - - // init script - if (slave_init_script[0] != 0) - { -#ifdef __NETWARE__ - // TODO: use the scripts - if (strinstr(slave_init_script, "rpl000016-slave.sh") != 0) - { - // create empty master.info file - snprintf(temp, PATH_MAX, "%s/master.info", slave_dir); - close(open(temp, O_WRONLY | O_CREAT,S_IRWXU|S_IRWXG|S_IRWXO)); - } - else if (strinstr(slave_init_script, "rpl000017-slave.sh") != 0) - { - FILE *fp; - - // create a master.info file - snprintf(temp, PATH_MAX, "%s/master.info", slave_dir); - fp = fopen(temp, "wb+"); - - fputs("master-bin.000001\n", fp); - fputs("4\n", fp); - fputs("127.0.0.1\n", fp); - fputs("replicate\n", fp); - fputs("aaaaaaaaaaaaaaab\n", fp); - fputs("9306\n", fp); - fputs("1\n", fp); - fputs("0\n", fp); - - fclose(fp); - } - else if (strinstr(slave_init_script, "rpl_rotate_logs-slave.sh") != 0) - { - // create empty master.info file - snprintf(temp, PATH_MAX, "%s/master.info", slave_dir); - close(open(temp, O_WRONLY | O_CREAT,S_IRWXU|S_IRWXG|S_IRWXO)); - } -#elif !defined(__WIN__) - run_init_script(slave_init_script); -#endif - } - - // redirection files - snprintf(slave_out, PATH_MAX, "%s/var/run/slave%u.out", - mysql_test_dir, restarts); - snprintf(slave_err, PATH_MAX, "%s/var/run/slave%u.err", - mysql_test_dir, restarts); - - // args - init_args(&al); - add_arg(&al, "%s", mysqld_file); - add_arg(&al, "--no-defaults"); - add_arg(&al, "--log-bin=slave-bin"); - add_arg(&al, "--relay_log=slave-relay-bin"); - add_arg(&al, "--basedir=%s", base_dir); - add_arg(&al, "--port=%u", slave_port); -#if !defined(__NETWARE__) && !defined(__WIN__) - add_arg(&al, "--socket=%s",slave_socket); -#endif - add_arg(&al, "--datadir=%s", slave_dir); -#ifndef __WIN__ - add_arg(&al, "--pid-file=%s", slave_pid); -#endif - add_arg(&al, "--character-sets-dir=%s", char_dir); - add_arg(&al, "--core"); - add_arg(&al, "--tmpdir=%s", mysql_tmp_dir); - add_arg(&al, "--language=%s", lang_dir); - - add_arg(&al, "--exit-info=256"); - add_arg(&al, "--log-slave-updates"); - add_arg(&al, "--init-rpl-role=slave"); - add_arg(&al, "--skip-innodb"); - add_arg(&al, "--skip-slave-start"); - add_arg(&al, "--slave-load-tmpdir=../../var/tmp"); - - add_arg(&al, "--report-user=%s", user); - add_arg(&al, "--report-host=127.0.0.1"); - add_arg(&al, "--report-port=%u", slave_port); - - add_arg(&al, "--master-retry-count=10"); - add_arg(&al, "-O"); - add_arg(&al, "slave_net_timeout=10"); -#ifdef DEBUG //only for debug builds - add_arg(&al, "--debug"); -#endif - - if (use_openssl) - { - add_arg(&al, "--ssl-ca=%s", ca_cert); - add_arg(&al, "--ssl-cert=%s", server_cert); - add_arg(&al, "--ssl-key=%s", server_key); - } - - // slave master info - if (slave_master_info[0] != 0) - { - char *p; - - p = (char *)str_tok(slave_master_info, " \t"); - - while(p) - { - add_arg(&al, "%s", p); - - p = (char *)str_tok(NULL, " \t"); - } - } - else - { - add_arg(&al, "--master-user=%s", user); - add_arg(&al, "--master-password=%s", password); - add_arg(&al, "--master-host=127.0.0.1"); - add_arg(&al, "--master-port=%u", master_port); - add_arg(&al, "--master-connect-retry=1"); - add_arg(&al, "--server-id=2"); - add_arg(&al, "--rpl-recovery-rank=2"); - } - - // small server - add_arg(&al, "-O"); - add_arg(&al, "key_buffer_size=1M"); - add_arg(&al, "-O"); - add_arg(&al, "sort_buffer=256K"); - add_arg(&al, "-O"); - add_arg(&al, "max_heap_table_size=1M"); - - - // opt args - if (slave_opt[0] != 0) - { - char *p; - - p = (char *)str_tok(slave_opt, " \t"); - - while(p) - { - add_arg(&al, "%s", p); - - p = (char *)str_tok(NULL, " \t"); - } - } - - // remove the pid file if it exists -#ifndef __WIN__ - remove(slave_pid); -#endif - // spawn -#ifdef __WIN__ - if ((err = spawn(mysqld_file, &al, FALSE, NULL, slave_out, slave_err, &slave_pid)) == 0) -#else - if ((err = spawn(mysqld_file, &al, FALSE, NULL, slave_out, slave_err, slave_pid)) == 0) -#endif - { - sleep_until_file_exists(slave_pid); - - if ((err = wait_for_server_start(bin_dir, mysqladmin_file, user, password, slave_port, - mysql_tmp_dir)) == 0) - { - slave_running = TRUE; - } - else - { - log_error("The slave server went down early."); - } - } - else - { - log_error("Unable to start slave server."); - } - - // free args - free_args(&al); -} - -/****************************************************************************** - - mysql_start() - - Start the mysql servers. - -******************************************************************************/ -void mysql_start() -{ -// log_info("Starting the MySQL server(s): %u", ++restarts); - start_master(); - - start_slave(); - - // activate the test screen -#ifdef __NETWARE__ - ActivateScreen(getscreenhandle()); -#endif -} - -/****************************************************************************** - - stop_slave() - - Stop the slave server. - -******************************************************************************/ -void stop_slave() -{ - int err; - - // running? - if (!slave_running) return; - - // stop - if ((err = stop_server(bin_dir, mysqladmin_file, user, password, slave_port, slave_pid, - mysql_tmp_dir)) == 0) - { - slave_running = FALSE; - } - else - { - log_error("Unable to stop slave server."); - } -} - -/****************************************************************************** - - stop_master() - - Stop the master server. - -******************************************************************************/ -void stop_master() -{ - int err; - - // running? - if (!master_running) return; - - if ((err = stop_server(bin_dir, mysqladmin_file, user, password, master_port, master_pid, - mysql_tmp_dir)) == 0) - { - master_running = FALSE; - } - else - { - log_error("Unable to stop master server."); - } -} - -/****************************************************************************** - - mysql_stop() - - Stop the mysql servers. - -******************************************************************************/ -void mysql_stop() -{ - - stop_master(); - - stop_slave(); - - // activate the test screen -#ifdef __NETWARE__ - ActivateScreen(getscreenhandle()); -#endif -} - -/****************************************************************************** - - mysql_restart() - - Restart the mysql servers. - -******************************************************************************/ -void mysql_restart() -{ -// log_info("Restarting the MySQL server(s): %u", ++restarts); - - mysql_stop(); - - mlog(DASH); - - mysql_start(); -} - -/****************************************************************************** - - read_option() - - Read the option file. - -******************************************************************************/ -int read_option(char *opt_file, char *opt) -{ - int fd, err; - char *p; - char buf[PATH_MAX]; - - // copy current option - strncpy(buf, opt, PATH_MAX); - - // open options file - fd = open(opt_file, O_RDONLY); - - err = read(fd, opt, PATH_MAX); - - close(fd); - - if (err > 0) - { - // terminate string - if ((p = strchr(opt, '\n')) != NULL) - { - *p = 0; - - // check for a '\r' - if ((p = strchr(opt, '\r')) != NULL) - { - *p = 0; - } - } - else - { - opt[err] = 0; - } - - // check for $MYSQL_TEST_DIR - if ((p = strstr(opt, "$MYSQL_TEST_DIR")) != NULL) - { - char temp[PATH_MAX]; - - *p = 0; - - strcpy(temp, p + strlen("$MYSQL_TEST_DIR")); - - strcat(opt, mysql_test_dir); - - strcat(opt, temp); - } - // Check for double backslash and replace it with single bakslash - if ((p = strstr(opt, "\\\\")) != NULL) - { - /* bmove is guranteed to work byte by byte */ - bmove(p, p+1, strlen(p+1)); - } - } - else - { - // clear option - *opt = 0; - } - - // compare current option with previous - return strcmp(opt, buf); -} - -/****************************************************************************** - - run_test() - - Run the given test case. - -******************************************************************************/ -void run_test(char *test) -{ - char temp[PATH_MAX]; - const char *rstr; - int skip = FALSE, ignore=FALSE; - int restart = FALSE; - int flag = FALSE; - struct stat info; - - // skip tests in the skip list - snprintf(temp, PATH_MAX, " %s ", test); - skip = (strinstr(skip_test, temp) != 0); - if (skip == FALSE) - ignore = (strinstr(ignore_test, temp) != 0); - - snprintf(master_init_script, PATH_MAX, "%s/%s-master.sh", test_dir, test); - snprintf(slave_init_script, PATH_MAX, "%s/%s-slave.sh", test_dir, test); -#ifdef __WIN__ - if (! stat(master_init_script, &info)) - skip = TRUE; - if (!stat(slave_init_script, &info)) - skip = TRUE; -#endif - if (ignore) - { - // show test - mlog("%-46s ", test); - - // ignore - rstr = TEST_IGNORE; - ++total_ignore; - } - else if (!skip) // skip test? - { - char test_file[PATH_MAX]; - char master_opt_file[PATH_MAX]; - char slave_opt_file[PATH_MAX]; - char slave_master_info_file[PATH_MAX]; - char result_file[PATH_MAX]; - char reject_file[PATH_MAX]; - char out_file[PATH_MAX]; - char err_file[PATH_MAX]; - int err; - arg_list_t al; -#ifdef __WIN__ - /* - Clean test database - */ - removef("%s/test/*.*", master_dir); - removef("%s/test/*.*", slave_dir); - removef("%s/mysqltest/*.*", master_dir); - removef("%s/mysqltest/*.*", slave_dir); - -#endif - // skip slave? - flag = skip_slave; - skip_slave = (strncmp(test, "rpl", 3) != 0); - if (flag != skip_slave) restart = TRUE; - - // create files - snprintf(master_opt_file, PATH_MAX, "%s/%s-master.opt", test_dir, test); - snprintf(slave_opt_file, PATH_MAX, "%s/%s-slave.opt", test_dir, test); - snprintf(slave_master_info_file, PATH_MAX, "%s/%s.slave-mi", test_dir, test); - snprintf(reject_file, PATH_MAX, "%s/%s%s", result_dir, test, REJECT_SUFFIX); - snprintf(out_file, PATH_MAX, "%s/%s%s", result_dir, test, OUT_SUFFIX); - snprintf(err_file, PATH_MAX, "%s/%s%s", result_dir, test, ERR_SUFFIX); - - // netware specific files - snprintf(test_file, PATH_MAX, "%s/%s%s", test_dir, test, NW_TEST_SUFFIX); - if (stat(test_file, &info)) - { - snprintf(test_file, PATH_MAX, "%s/%s%s", test_dir, test, TEST_SUFFIX); - if (access(test_file,0)) - { - printf("Invalid test name %s, %s file not found\n",test,test_file); - return; - } - } - - snprintf(result_file, PATH_MAX, "%s/%s%s", result_dir, test, NW_RESULT_SUFFIX); - if (stat(result_file, &info)) - { - snprintf(result_file, PATH_MAX, "%s/%s%s", result_dir, test, RESULT_SUFFIX); - } - - // init scripts - if (stat(master_init_script, &info)) - master_init_script[0] = 0; - else - restart = TRUE; - - if (stat(slave_init_script, &info)) - slave_init_script[0] = 0; - else - restart = TRUE; - - // read options - if (read_option(master_opt_file, master_opt)) restart = TRUE; - if (read_option(slave_opt_file, slave_opt)) restart = TRUE; - if (read_option(slave_master_info_file, slave_master_info)) restart = TRUE; - - // cleanup previous run - remove(reject_file); - remove(out_file); - remove(err_file); - - // start or restart? - if (!master_running) mysql_start(); - else if (restart) mysql_restart(); - - // let the system stabalize - sleep(1); - - // show test - mlog("%-46s ", test); - - - // args - init_args(&al); - add_arg(&al, "%s", mysqltest_file); - add_arg(&al, "--no-defaults"); - add_arg(&al, "--port=%u", master_port); -#if !defined(__NETWARE__) && !defined(__WIN__) - add_arg(&al, "--socket=%s", master_socket); - add_arg(&al, "--tmpdir=%s", mysql_tmp_dir); -#endif - add_arg(&al, "--database=%s", db); - add_arg(&al, "--user=%s", user); - add_arg(&al, "--password=%s", password); - add_arg(&al, "--silent"); - add_arg(&al, "--basedir=%s/", mysql_test_dir); - add_arg(&al, "--host=127.0.0.1"); - add_arg(&al, "-v"); - add_arg(&al, "-R"); - add_arg(&al, "%s", result_file); - - if (use_openssl) - { - add_arg(&al, "--ssl-ca=%s", ca_cert); - add_arg(&al, "--ssl-cert=%s", client_cert); - add_arg(&al, "--ssl-key=%s", client_key); - } - - // spawn - err = spawn(mysqltest_file, &al, TRUE, test_file, out_file, err_file, NULL); - - // free args - free_args(&al); - - remove_empty_file(out_file); - remove_empty_file(err_file); - - if (err == 0) - { - // pass - rstr = TEST_PASS; - ++total_pass; - - // increment total - ++total_test; - } - else if (err == 2) - { - // skip - rstr = TEST_SKIP; - ++total_skip; - } - else if (err == 1) - { - // fail - rstr = TEST_FAIL; - ++total_fail; - - // increment total - ++total_test; - } - else - { - rstr = TEST_BAD; - } - } - else // early skips - { - // show test - mlog("%-46s ", test); - - // skip - rstr = TEST_SKIP; - ++total_skip; - } - - // result - mlog("%-14s\n", rstr); -} - -/****************************************************************************** - - vlog() - - Log the message. - -******************************************************************************/ -void vlog(const char *format, va_list ap) -{ - vfprintf(stdout, format, ap); - fflush(stdout); - - if (log_fd) - { - vfprintf(log_fd, format, ap); - fflush(log_fd); - } -} - -/****************************************************************************** - - log() - - Log the message. - -******************************************************************************/ -void mlog(const char *format, ...) -{ - va_list ap; - - va_start(ap, format); - - vlog(format, ap); - - va_end(ap); -} - -/****************************************************************************** - - log_info() - - Log the given information. - -******************************************************************************/ -void log_info(const char *format, ...) -{ - va_list ap; - - va_start(ap, format); - - mlog("-- INFO : "); - vlog(format, ap); - mlog("\n"); - - va_end(ap); -} - -/****************************************************************************** - - log_error() - - Log the given error. - -******************************************************************************/ -void log_error(const char *format, ...) -{ - va_list ap; - - va_start(ap, format); - - mlog("-- ERROR: "); - vlog(format, ap); - mlog("\n"); - - va_end(ap); -} - -/****************************************************************************** - - log_errno() - - Log the given error and errno. - -******************************************************************************/ -void log_errno(const char *format, ...) -{ - va_list ap; - - va_start(ap, format); - - mlog("-- ERROR: (%003u) ", errno); - vlog(format, ap); - mlog("\n"); - - va_end(ap); -} - -/****************************************************************************** - - die() - - Exit the application. - -******************************************************************************/ -void die(const char *msg) -{ - log_error(msg); -#ifdef __NETWARE__ - pressanykey(); -#endif - exit(-1); -} - -/****************************************************************************** - - setup() - - Setup the mysql test enviornment. - -******************************************************************************/ -void setup(char *file) -{ - char temp[PATH_MAX]; - char file_path[PATH_MAX*2]; - char *p; - int position; - - // set the timezone for the timestamp test -#ifdef __WIN__ - _putenv( "TZ=GMT-3" ); -#else - setenv("TZ", "GMT-3", TRUE); -#endif - // find base dir -#ifdef __NETWARE__ - strcpy(temp, strlwr(file)); - while((p = strchr(temp, '\\')) != NULL) *p = '/'; -#else - getcwd(temp, PATH_MAX); - position = strlen(temp); - temp[position] = '/'; - temp[position+1] = 0; -#ifdef __WIN__ - while((p = strchr(temp, '\\')) != NULL) *p = '/'; -#endif -#endif - - if ((position = strinstr(temp, "/mysql-test/")) != 0) - { - p = temp + position - 1; - *p = 0; - strcpy(base_dir, temp); - } - - log_info("Currect directory: %s",base_dir); - -#ifdef __NETWARE__ - // setup paths - snprintf(bin_dir, PATH_MAX, "%s/bin", base_dir); - snprintf(mysql_test_dir, PATH_MAX, "%s/mysql-test", base_dir); - snprintf(test_dir, PATH_MAX, "%s/t", mysql_test_dir); - snprintf(mysql_tmp_dir, PATH_MAX, "%s/var/tmp", mysql_test_dir); - snprintf(result_dir, PATH_MAX, "%s/r", mysql_test_dir); - snprintf(master_dir, PATH_MAX, "%s/var/master-data", mysql_test_dir); - snprintf(slave_dir, PATH_MAX, "%s/var/slave-data", mysql_test_dir); - snprintf(lang_dir, PATH_MAX, "%s/share/english", base_dir); - snprintf(char_dir, PATH_MAX, "%s/share/charsets", base_dir); - -#ifdef HAVE_OPENSSL - use_openssl = TRUE; -#endif // HAVE_OPENSSL - - // OpenSSL paths - snprintf(ca_cert, PATH_MAX, "%s/SSL/cacert.pem", base_dir); - snprintf(server_cert, PATH_MAX, "%s/SSL/server-cert.pem", base_dir); - snprintf(server_key, PATH_MAX, "%s/SSL/server-key.pem", base_dir); - snprintf(client_cert, PATH_MAX, "%s/SSL/client-cert.pem", base_dir); - snprintf(client_key, PATH_MAX, "%s/SSL/client-key.pem", base_dir); - - // setup files - snprintf(mysqld_file, PATH_MAX, "%s/mysqld", bin_dir); - snprintf(mysqltest_file, PATH_MAX, "%s/mysqltest", bin_dir); - snprintf(mysqladmin_file, PATH_MAX, "%s/mysqladmin", bin_dir); - snprintf(master_pid, PATH_MAX, "%s/var/run/master.pid", mysql_test_dir); - snprintf(slave_pid, PATH_MAX, "%s/var/run/slave.pid", mysql_test_dir); -#elif __WIN__ - // setup paths -#ifdef _DEBUG - snprintf(bin_dir, PATH_MAX, "%s/client_debug", base_dir); -#else - snprintf(bin_dir, PATH_MAX, "%s/client_release", base_dir); -#endif - snprintf(mysql_test_dir, PATH_MAX, "%s/mysql-test", base_dir); - snprintf(test_dir, PATH_MAX, "%s/t", mysql_test_dir); - snprintf(mysql_tmp_dir, PATH_MAX, "%s/var/tmp", mysql_test_dir); - snprintf(result_dir, PATH_MAX, "%s/r", mysql_test_dir); - snprintf(master_dir, PATH_MAX, "%s/var/master-data", mysql_test_dir); - snprintf(slave_dir, PATH_MAX, "%s/var/slave-data", mysql_test_dir); - snprintf(lang_dir, PATH_MAX, "%s/share/english", base_dir); - snprintf(char_dir, PATH_MAX, "%s/share/charsets", base_dir); - -#ifdef HAVE_OPENSSL - use_openssl = TRUE; -#endif // HAVE_OPENSSL - - // OpenSSL paths - snprintf(ca_cert, PATH_MAX, "%s/SSL/cacert.pem", base_dir); - snprintf(server_cert, PATH_MAX, "%s/SSL/server-cert.pem", base_dir); - snprintf(server_key, PATH_MAX, "%s/SSL/server-key.pem", base_dir); - snprintf(client_cert, PATH_MAX, "%s/SSL/client-cert.pem", base_dir); - snprintf(client_key, PATH_MAX, "%s/SSL/client-key.pem", base_dir); - - // setup files - snprintf(mysqld_file, PATH_MAX, "%s/mysqld.exe", bin_dir); - snprintf(mysqltest_file, PATH_MAX, "%s/mysqltest.exe", bin_dir); - snprintf(mysqladmin_file, PATH_MAX, "%s/mysqladmin.exe", bin_dir); -#else - // setup paths - snprintf(bin_dir, PATH_MAX, "%s/client", base_dir); - snprintf(mysql_test_dir, PATH_MAX, "%s/mysql-test", base_dir); - snprintf(test_dir, PATH_MAX, "%s/t", mysql_test_dir); - snprintf(mysql_tmp_dir, PATH_MAX, "%s/var/tmp", mysql_test_dir); - snprintf(result_dir, PATH_MAX, "%s/r", mysql_test_dir); - snprintf(master_dir, PATH_MAX, "%s/var/master-data", mysql_test_dir); - snprintf(slave_dir, PATH_MAX, "%s/var/slave-data", mysql_test_dir); - snprintf(lang_dir, PATH_MAX, "%s/sql/share/english", base_dir); - snprintf(char_dir, PATH_MAX, "%s/sql/share/charsets", base_dir); - -#ifdef HAVE_OPENSSL - use_openssl = TRUE; -#endif // HAVE_OPENSSL - - // OpenSSL paths - snprintf(ca_cert, PATH_MAX, "%s/SSL/cacert.pem", base_dir); - snprintf(server_cert, PATH_MAX, "%s/SSL/server-cert.pem", base_dir); - snprintf(server_key, PATH_MAX, "%s/SSL/server-key.pem", base_dir); - snprintf(client_cert, PATH_MAX, "%s/SSL/client-cert.pem", base_dir); - snprintf(client_key, PATH_MAX, "%s/SSL/client-key.pem", base_dir); - - // setup files - snprintf(mysqld_file, PATH_MAX, "%s/sql/mysqld", base_dir); - snprintf(mysqltest_file, PATH_MAX, "%s/mysqltest", bin_dir); - snprintf(mysqladmin_file, PATH_MAX, "%s/mysqladmin", bin_dir); - snprintf(master_pid, PATH_MAX, "%s/var/run/master.pid", mysql_test_dir); - snprintf(slave_pid, PATH_MAX, "%s/var/run/slave.pid", mysql_test_dir); - - snprintf(master_socket,PATH_MAX, "%s/var/tmp/master.sock", mysql_test_dir); - snprintf(slave_socket,PATH_MAX, "%s/var/tmp/slave.sock", mysql_test_dir); - -#endif - // create log file - snprintf(temp, PATH_MAX, "%s/mysql-test-run.log", mysql_test_dir); - if ((log_fd = fopen(temp, "w+")) == NULL) - { - log_errno("Unable to create log file."); - } - - // prepare skip test list - while((p = strchr(skip_test, ',')) != NULL) *p = ' '; - strcpy(temp, strlwr(skip_test)); - snprintf(skip_test, PATH_MAX, " %s ", temp); - - // environment -#ifdef __NETWARE__ - setenv("MYSQL_TEST_DIR", mysql_test_dir, 1); - snprintf(file_path, PATH_MAX*2, "%s/client/mysqldump --no-defaults -u root --port=%u", bin_dir, master_port); - setenv("MYSQL_DUMP", file_path, 1); - snprintf(file_path, PATH_MAX*2, "%s/client/mysqlbinlog --no-defaults --local-load=%s", bin_dir, mysql_tmp_dir); - setenv("MYSQL_BINLOG", file_path, 1); -#elif __WIN__ - snprintf(file_path,MAX_PATH,"MYSQL_TEST_DIR=%s",mysql_test_dir); - _putenv(file_path); - snprintf(file_path, PATH_MAX*2, "MYSQL_DUMP=%s/mysqldump.exe --no-defaults -u root --port=%u", bin_dir, master_port); - _putenv(file_path); - snprintf(file_path, PATH_MAX*2, "MYSQL_BINLOG=%s/mysqlbinlog.exe --no-defaults --local-load=%s", bin_dir, mysql_tmp_dir); - _putenv(file_path); -#else - setenv("MYSQL_TEST_DIR", mysql_test_dir, 1); - snprintf(file_path, PATH_MAX*2, "%s/mysqldump --no-defaults -u root --port=%u --socket=%s", bin_dir, master_port, master_socket); - setenv("MYSQL_DUMP", file_path, 1); - snprintf(file_path, PATH_MAX*2, "%s/mysqlbinlog --no-defaults --local-load=%s", bin_dir, mysql_tmp_dir); - setenv("MYSQL_BINLOG", file_path, 1); -#endif - -#ifndef __WIN__ - setenv("MASTER_MYPORT", "9306", 1); - setenv("SLAVE_MYPORT", "9307", 1); - setenv("MYSQL_TCP_PORT", "3306", 1); -#else - _putenv("MASTER_MYPORT=9306"); - _putenv("SLAVE_MYPORT=9307"); - _putenv("MYSQL_TCP_PORT=3306"); -#endif - -} - -/****************************************************************************** - - main() - -******************************************************************************/ -int main(int argc, char **argv) -{ - int is_ignore_list = 0; - // setup - setup(argv[0]); - - /* The --ignore option is comma saperated list of test cases to skip and - should be very first command line option to the test suite. - - The usage is now: - mysql_test_run --ignore=test1,test2 test3 test4 - where test1 and test2 are test cases to ignore - and test3 and test4 are test cases to run. - */ - if (argc >= 2 && !strnicmp(argv[1], "--ignore=", sizeof("--ignore=")-1)) - { - char *temp, *token; - temp= strdup(strchr(argv[1],'=') + 1); - for (token=str_tok(temp, ","); token != NULL; token=str_tok(NULL, ",")) - { - if (strlen(ignore_test) + strlen(token) + 2 <= PATH_MAX-1) - sprintf(ignore_test+strlen(ignore_test), " %s ", token); - else - { - free(temp); - die("ignore list too long."); - } - } - free(temp); - is_ignore_list = 1; - } - // header -#ifndef __WIN__ - mlog("MySQL Server %s, for %s (%s)\n\n", VERSION, SYSTEM_TYPE, MACHINE_TYPE); -#else - mlog("MySQL Server ---, for %s (%s)\n\n", SYSTEM_TYPE, MACHINE_TYPE); -#endif - - mlog("Initializing Tests...\n"); - - // install test databases - mysql_install_db(); - - mlog("Starting Tests...\n"); - - mlog("\n"); - mlog(HEADER); - mlog(DASH); - - if ( argc > 1 + is_ignore_list ) - { - int i; - - // single test - single_test = TRUE; - - for (i = 1 + is_ignore_list; i < argc; i++) - { - // run given test - run_test(argv[i]); - } - } - else - { - // run all tests -#ifndef __WIN__ - struct dirent **namelist; - int i,n; - char test[NAME_MAX]; - char *p; - int position; - - n = scandir(test_dir, &namelist, 0, alphasort); - if (n < 0) - die("Unable to open tests directory."); - else - { - for (i = 0; i < n; i++) - { - strcpy(test, strlwr(namelist[i]->d_name)); - // find the test suffix - if ((position = strinstr(test, TEST_SUFFIX)) != 0) - { - p = test + position - 1; - // null terminate at the suffix - *p = 0; - // run test - run_test(test); - } - free(namelist[n]); - } - free(namelist); - } -#else - struct _finddata_t dir; - intptr_t handle; - char test[NAME_MAX]; - char mask[PATH_MAX]; - char *p; - int position; - char **names = 0; - char **testes = 0; - int name_index; - int index; - - // single test - single_test = FALSE; - - snprintf(mask,MAX_PATH,"%s/*.test",test_dir); - - if ((handle=_findfirst(mask,&dir)) == -1L) - { - die("Unable to open tests directory."); - } - - names = malloc(MAX_COUNT_TESTES*4); - testes = names; - name_index = 0; - - do - { - if (!(dir.attrib & _A_SUBDIR)) - { - strcpy(test, strlwr(dir.name)); - - // find the test suffix - if ((position = strinstr(test, TEST_SUFFIX)) != 0) - { - p = test + position - 1; - // null terminate at the suffix - *p = 0; - - // insert test - *names = malloc(PATH_MAX); - strcpy(*names,test); - names++; - name_index++; - } - } - }while (_findnext(handle,&dir) == 0); - - _findclose(handle); - - qsort( (void *)testes, name_index, sizeof( char * ), compare ); - - for (index = 0; index <= name_index; index++) - { - run_test(testes[index]); - free(testes[index]); - } - - free(testes); -#endif - } - - // stop server - mysql_stop(); - - mlog(DASH); - mlog("\n"); - - mlog("Ending Tests...\n"); - - // report stats - report_stats(); - - // close log - if (log_fd) fclose(log_fd); - - // keep results up -#ifdef __NETWARE__ - pressanykey(); -#endif - return 0; -} - - -/* - Synopsis: - This function breaks the string into a sequence of tokens. The difference - between this function and strtok is that it respects the quoted string i.e. - it skips any delimiter character within the quoted part of the string. - It return tokens by eliminating quote character. It modifies the input string - passed. It will work with whitespace delimeter but may not work properly with - other delimeter. If the delimeter will contain any quote character, then - function will not tokenize and will return null string. - e.g. if input string is - --init-slave="set global max_connections=500" --skip-external-locking - then the output will two string i.e. - --init-slave=set global max_connections=500 - --skip-external-locking - -Arguments: - string: input string - delim: set of delimiter character -Output: - return the null terminated token of NULL. -*/ - - -char *str_tok(char *string, const char *delim) -{ - char *token; /* current token received from strtok */ - char *qt_token; /* token delimeted by the matching pair of quote */ - /* - if there are any quote chars found in the token then this variable - will hold the concatenated string to return to the caller - */ - char *ptr_token=NULL; - /* pointer to the quote character in the token from strtok */ - char *ptr_quote=NULL; - - /* See if the delimeter contains any quote character */ - if (strchr(delim,'\'') || strchr(delim,'\"')) - return NULL; - - /* repeate till we are getting some token from strtok */ - while ((token = (char*)strtok(string, delim) ) != NULL) - { - /* - make the input string NULL so that next time onward strtok can - be called with NULL input string. - */ - string = NULL; - /* - We don't need to remove any quote character for Windows version - */ -#ifndef __WIN__ - /* check if the current token contain double quote character*/ - if ((ptr_quote = (char*)strchr(token,'\"')) != NULL) - { - /* - get the matching the matching double quote in the remaining - input string - */ - qt_token = (char*)strtok(NULL,"\""); - } - /* check if the current token contain single quote character*/ - else if ((ptr_quote = (char*)strchr(token,'\'')) != NULL) - { - /* - get the matching the matching single quote in the remaining - input string - */ - qt_token = (char*)strtok(NULL,"\'"); - } -#endif - /* - if the current token does not contains any quote character then - return to the caller. - */ - if (ptr_quote == NULL) - { - /* - if there is any earlier token i.e. ptr_token then append the - current token in it and return it else return the current - token directly - */ - return ptr_token ? strcat(ptr_token,token) : token; - } - - /* - remove the quote character i.e. make NULL so that the token will - be devided in two part and later both part can be concatenated - and hence quote will be removed - */ - *ptr_quote= 0; - - /* check if ptr_token has been initialized or not */ - if (ptr_token == NULL) - { - /* initialize the ptr_token with current token */ - ptr_token= token; - /* copy entire string between matching pair of quote*/ - sprintf(ptr_token+strlen(ptr_token),"%s %s", ptr_quote+1, qt_token); - } - else - { - /* - copy the current token and entire string between matching pair - of quote - */ - if (qt_token == NULL) - { - sprintf(ptr_token+strlen(ptr_token),"%s%s", token, ptr_quote+1); - } - else - { - sprintf(ptr_token+strlen(ptr_token),"%s%s %s", token, ptr_quote+1, - qt_token ); - } - } - } - - /* return the concatenated token */ - return ptr_token; -} - -#ifndef __WIN__ - -/* - Synopsis: - This function run scripts files on Linux and Netware - -Arguments: - script_name: name of script file - -Output: - nothing -*/ -void run_init_script(const char *script_name) -{ - arg_list_t al; - int err; - - // args - init_args(&al); - add_arg(&al, sh_file); - add_arg(&al, script_name); - - // spawn - if ((err = spawn(sh_file, &al, TRUE, NULL, NULL, NULL, NULL)) != 0) - { - die("Unable to run script."); - } - - // free args - free_args(&al); -} -#endif diff --git a/ndb/include/ndbapi/NdbConnection.hpp b/ndb/include/ndbapi/NdbConnection.hpp index 7af5d27b922..256199dced7 100644 --- a/ndb/include/ndbapi/NdbConnection.hpp +++ b/ndb/include/ndbapi/NdbConnection.hpp @@ -607,8 +607,8 @@ private: NdbOperation* theLastExecOpInList; // Last executing operation in list. - NdbOperation* theCompletedFirstOp; // First operation in completed - // operation list. + NdbOperation* theCompletedFirstOp; // First & last operation in completed + NdbOperation* theCompletedLastOp; // operation list. Uint32 theNoOfOpSent; // How many operations have been sent Uint32 theNoOfOpCompleted; // How many operations have completed diff --git a/ndb/src/ndbapi/NdbConnection.cpp b/ndb/src/ndbapi/NdbConnection.cpp index 4f6468eb4ae..719c5bef49e 100644 --- a/ndb/src/ndbapi/NdbConnection.cpp +++ b/ndb/src/ndbapi/NdbConnection.cpp @@ -55,6 +55,7 @@ NdbConnection::NdbConnection( Ndb* aNdb ) : theFirstExecOpInList(NULL), theLastExecOpInList(NULL), theCompletedFirstOp(NULL), + theCompletedLastOp(NULL), theNoOfOpSent(0), theNoOfOpCompleted(0), theNoOfOpFetched(0), @@ -124,6 +125,7 @@ NdbConnection::init() theLastExecOpInList = NULL; theCompletedFirstOp = NULL; + theCompletedLastOp = NULL; theGlobalCheckpointId = 0; theCommitStatus = Started; @@ -256,6 +258,8 @@ NdbConnection::handleExecuteCompletion() if (tLastExecOp != NULL) { tLastExecOp->next(theCompletedFirstOp); theCompletedFirstOp = tFirstExecOp; + if (theCompletedLastOp == NULL) + theCompletedLastOp = tLastExecOp; theFirstExecOpInList = NULL; theLastExecOpInList = NULL; }//if @@ -292,6 +296,8 @@ NdbConnection::execute(ExecType aTypeOfExec, ExecType tExecType; NdbOperation* tPrepOp; + NdbOperation* tCompletedFirstOp = NULL; + NdbOperation* tCompletedLastOp = NULL; int ret = 0; do { @@ -314,6 +320,7 @@ NdbConnection::execute(ExecType aTypeOfExec, } tPrepOp = tPrepOp->next(); } + // save rest of prepared ops if batch NdbOperation* tRestOp= 0; NdbOperation* tLastOp= 0; @@ -323,6 +330,7 @@ NdbConnection::execute(ExecType aTypeOfExec, tLastOp = theLastOpInList; theLastOpInList = tPrepOp; } + if (tExecType == Commit) { NdbOperation* tOp = theCompletedFirstOp; while (tOp != NULL) { @@ -338,6 +346,19 @@ NdbConnection::execute(ExecType aTypeOfExec, } } + // completed ops are in unspecified order + if (theCompletedFirstOp != NULL) { + if (tCompletedFirstOp == NULL) { + tCompletedFirstOp = theCompletedFirstOp; + tCompletedLastOp = theCompletedLastOp; + } else { + tCompletedLastOp->next(theCompletedFirstOp); + tCompletedLastOp = theCompletedLastOp; + } + theCompletedFirstOp = NULL; + theCompletedLastOp = NULL; + } + if (executeNoBlobs(tExecType, abortOption, forceSend) == -1) ret = -1; #ifndef VM_TRACE @@ -362,6 +383,7 @@ NdbConnection::execute(ExecType aTypeOfExec, tOp = tOp->next(); } } + // add saved prepared ops if batch if (tPrepOp != NULL && tRestOp != NULL) { if (theFirstOpInList == NULL) @@ -373,6 +395,18 @@ NdbConnection::execute(ExecType aTypeOfExec, assert(theFirstOpInList == NULL || tExecType == NoCommit); } while (theFirstOpInList != NULL || tExecType != aTypeOfExec); + if (tCompletedFirstOp != NULL) { + tCompletedLastOp->next(theCompletedFirstOp); + theCompletedFirstOp = tCompletedFirstOp; + if (theCompletedLastOp == NULL) + theCompletedLastOp = tCompletedLastOp; + } +#if ndb_api_count_completed_ops_after_blob_execute + { NdbOperation* tOp; unsigned n = 0; + for (tOp = theCompletedFirstOp; tOp != NULL; tOp = tOp->next()) n++; + ndbout << "completed ops: " << n << endl; + } +#endif DBUG_RETURN(ret); } @@ -894,6 +928,7 @@ NdbConnection::releaseOperations() releaseOps(theFirstExecOpInList); theCompletedFirstOp = NULL; + theCompletedLastOp = NULL; theFirstOpInList = NULL; theFirstExecOpInList = NULL; theLastOpInList = NULL; @@ -909,6 +944,7 @@ NdbConnection::releaseCompletedOperations() { releaseOps(theCompletedFirstOp); theCompletedFirstOp = NULL; + theCompletedLastOp = NULL; }//NdbConnection::releaseOperations() /****************************************************************************** diff --git a/ndb/test/ndbapi/testBlobs.cpp b/ndb/test/ndbapi/testBlobs.cpp index efa0811aa39..4b532856709 100644 --- a/ndb/test/ndbapi/testBlobs.cpp +++ b/ndb/test/ndbapi/testBlobs.cpp @@ -22,6 +22,7 @@ #include <NdbMain.h> #include <NdbOut.hpp> #include <NdbTest.hpp> +#include <NdbTick.h> struct Bcol { bool m_nullable; @@ -59,6 +60,9 @@ struct Opt { bool m_oneblob; Bcol m_blob1; Bcol m_blob2; + // perf + const char* m_tnameperf; + unsigned m_rowsperf; // bugs int m_bug; int (*m_bugtest)(); @@ -84,6 +88,9 @@ struct Opt { m_oneblob(false), m_blob1(false, 7, 1137, 10), m_blob2(true, 99, 55, 1), + // perf + m_tnameperf("TBLOB2"), + m_rowsperf(10000), // bugs m_bug(0), m_bugtest(0) { @@ -107,6 +114,7 @@ printusage() << " -loop N loop N times 0=forever [" << d.m_loop << "]" << endl << " -parts N max parts in blob value [" << d.m_parts << "]" << endl << " -rows N number of rows [" << d.m_rows << "]" << endl + << " -rowsperf N rows for performace test [" << d.m_rowsperf << "]" << endl << " -seed N random seed 0=loop number [" << d.m_seed << "]" << endl << " -skip xxx skip given tests (see list) [no tests]" << endl << " -test xxx only given tests (see list) [all tests]" << endl @@ -118,6 +126,7 @@ printusage() << " i hash index ops" << endl << " s table scans" << endl << " r ordered index scans" << endl + << " p performance test" << endl << "additional flags for test/skip" << endl << " u update existing blob value" << endl << " n normal insert and update" << endl @@ -1381,6 +1390,292 @@ testmain() return 0; } +// separate performance test + +struct Tmr { // stolen from testOIBasic + Tmr() { + clr(); + } + void clr() { + m_on = m_ms = m_cnt = m_time[0] = m_text[0] = 0; + } + void on() { + assert(m_on == 0); + m_on = NdbTick_CurrentMillisecond(); + } + void off(unsigned cnt = 0) { + NDB_TICKS off = NdbTick_CurrentMillisecond(); + assert(m_on != 0 && off >= m_on); + m_ms += off - m_on; + m_cnt += cnt; + m_on = 0; + } + const char* time() { + if (m_cnt == 0) + sprintf(m_time, "%u ms", m_ms); + else + sprintf(m_time, "%u ms per %u ( %u ms per 1000 )", m_ms, m_cnt, (1000 * m_ms) / m_cnt); + return m_time; + } + const char* pct (const Tmr& t1) { + if (0 < t1.m_ms) + sprintf(m_text, "%u pct", (100 * m_ms) / t1.m_ms); + else + sprintf(m_text, "[cannot measure]"); + return m_text; + } + const char* over(const Tmr& t1) { + if (0 < t1.m_ms) { + if (t1.m_ms <= m_ms) + sprintf(m_text, "%u pct", (100 * (m_ms - t1.m_ms)) / t1.m_ms); + else + sprintf(m_text, "-%u pct", (100 * (t1.m_ms - m_ms)) / t1.m_ms); + } else + sprintf(m_text, "[cannot measure]"); + return m_text; + } + NDB_TICKS m_on; + unsigned m_ms; + unsigned m_cnt; + char m_time[100]; + char m_text[100]; +}; + +static int +testperf() +{ + if (! testcase('p')) + return 0; + DBG("=== perf test ==="); + g_ndb = new Ndb("TEST_DB"); + CHK(g_ndb->init() == 0); + CHK(g_ndb->waitUntilReady() == 0); + g_dic = g_ndb->getDictionary(); + NdbDictionary::Table tab(g_opt.m_tnameperf); + if (g_dic->getTable(tab.getName()) != 0) + CHK(g_dic->dropTable(tab) == 0); + // col A - pk + { NdbDictionary::Column col("A"); + col.setType(NdbDictionary::Column::Unsigned); + col.setPrimaryKey(true); + tab.addColumn(col); + } + // col B - char 20 + { NdbDictionary::Column col("B"); + col.setType(NdbDictionary::Column::Char); + col.setLength(20); + col.setNullable(true); + tab.addColumn(col); + } + // col C - text + { NdbDictionary::Column col("C"); + col.setType(NdbDictionary::Column::Text); + col.setInlineSize(20); + col.setPartSize(512); + col.setStripeSize(1); + col.setNullable(true); + tab.addColumn(col); + } + // create + CHK(g_dic->createTable(tab) == 0); + Uint32 cA = 0, cB = 1, cC = 2; + // timers + Tmr t1; + Tmr t2; + // insert char (one trans) + { + DBG("--- insert char ---"); + t1.on(); + CHK((g_con = g_ndb->startTransaction()) != 0); + for (Uint32 k = 0; k < g_opt.m_rowsperf; k++) { + CHK((g_opr = g_con->getNdbOperation(tab.getName())) != 0); + CHK(g_opr->insertTuple() == 0); + CHK(g_opr->equal(cA, (char*)&k) == 0); + CHK(g_opr->setValue(cB, "b") == 0); + CHK(g_con->execute(NoCommit) == 0); + } + t1.off(g_opt.m_rowsperf); + CHK(g_con->execute(Rollback) == 0); + DBG(t1.time()); + g_opr = 0; + g_con = 0; + } + // insert text (one trans) + { + DBG("--- insert text ---"); + t2.on(); + CHK((g_con = g_ndb->startTransaction()) != 0); + for (Uint32 k = 0; k < g_opt.m_rowsperf; k++) { + CHK((g_opr = g_con->getNdbOperation(tab.getName())) != 0); + CHK(g_opr->insertTuple() == 0); + CHK(g_opr->equal(cA, (char*)&k) == 0); + CHK((g_bh1 = g_opr->getBlobHandle(cC)) != 0); + CHK((g_bh1->setValue("c", 1) == 0)); + CHK(g_con->execute(NoCommit) == 0); + } + t2.off(g_opt.m_rowsperf); + CHK(g_con->execute(Rollback) == 0); + DBG(t2.time()); + g_bh1 = 0; + g_opr = 0; + g_con = 0; + } + // insert overhead + DBG("insert overhead: " << t2.over(t1)); + t1.clr(); + t2.clr(); + // insert + { + DBG("--- insert for read test ---"); + unsigned n = 0; + CHK((g_con = g_ndb->startTransaction()) != 0); + for (Uint32 k = 0; k < g_opt.m_rowsperf; k++) { + CHK((g_opr = g_con->getNdbOperation(tab.getName())) != 0); + CHK(g_opr->insertTuple() == 0); + CHK(g_opr->equal(cA, (char*)&k) == 0); + CHK(g_opr->setValue(cB, "b") == 0); + CHK((g_bh1 = g_opr->getBlobHandle(cC)) != 0); + CHK((g_bh1->setValue("c", 1) == 0)); + if (++n == g_opt.m_batch) { + CHK(g_con->execute(Commit) == 0); + g_ndb->closeTransaction(g_con); + CHK((g_con = g_ndb->startTransaction()) != 0); + n = 0; + } + } + if (n != 0) { + CHK(g_con->execute(Commit) == 0); + n = 0; + } + g_bh1 = 0; + g_opr = 0; + g_con = 0; + } + // pk read char (one trans) + { + DBG("--- pk read char ---"); + CHK((g_con = g_ndb->startTransaction()) != 0); + Uint32 a; + char b[20]; + t1.on(); + for (Uint32 k = 0; k < g_opt.m_rowsperf; k++) { + CHK((g_opr = g_con->getNdbOperation(tab.getName())) != 0); + CHK(g_opr->readTuple() == 0); + CHK(g_opr->equal(cA, (char*)&k) == 0); + CHK(g_opr->getValue(cA, (char*)&a) != 0); + CHK(g_opr->getValue(cB, b) != 0); + a = (Uint32)-1; + b[0] = 0; + CHK(g_con->execute(NoCommit) == 0); + CHK(a == k && strcmp(b, "b") == 0); + } + CHK(g_con->execute(Commit) == 0); + t1.off(g_opt.m_rowsperf); + DBG(t1.time()); + g_opr = 0; + g_con = 0; + } + // pk read text (one trans) + { + DBG("--- pk read text ---"); + CHK((g_con = g_ndb->startTransaction()) != 0); + Uint32 a; + char c[20]; + t2.on(); + for (Uint32 k = 0; k < g_opt.m_rowsperf; k++) { + CHK((g_opr = g_con->getNdbOperation(tab.getName())) != 0); + CHK(g_opr->readTuple() == 0); + CHK(g_opr->equal(cA, (char*)&k) == 0); + CHK(g_opr->getValue(cA, (char*)&a) != 0); + CHK((g_bh1 = g_opr->getBlobHandle(cC)) != 0); + a = (Uint32)-1; + c[0] = 0; + CHK(g_con->execute(NoCommit) == 0); + Uint32 m = 20; + CHK(g_bh1->readData(c, m) == 0); + CHK(a == k && m == 1 && strcmp(c, "c") == 0); + } + CHK(g_con->execute(Commit) == 0); + t2.off(g_opt.m_rowsperf); + DBG(t2.time()); + g_opr = 0; + g_con = 0; + } + // pk read overhead + DBG("pk read overhead: " << t2.over(t1)); + t1.clr(); + t2.clr(); + // scan read char + { + DBG("--- scan read char ---"); + NdbResultSet* rs; + Uint32 a; + char b[20]; + CHK((g_con = g_ndb->startTransaction()) != 0); + CHK((g_ops = g_con->getNdbScanOperation(tab.getName())) != 0); + CHK((rs = g_ops->readTuples(NdbScanOperation::LM_Read)) != 0); + CHK(g_ops->getValue(cA, (char*)&a) != 0); + CHK(g_ops->getValue(cB, b) != 0); + CHK(g_con->execute(NoCommit) == 0); + unsigned n = 0; + t1.on(); + while (1) { + a = (Uint32)-1; + b[0] = 0; + int ret; + CHK((ret = rs->nextResult(true)) == 0 || ret == 1); + if (ret == 1) + break; + CHK(a < g_opt.m_rowsperf && strcmp(b, "b") == 0); + n++; + } + CHK(n == g_opt.m_rowsperf); + t1.off(g_opt.m_rowsperf); + DBG(t1.time()); + g_ops = 0; + g_con = 0; + } + // scan read text + { + DBG("--- read text ---"); + NdbResultSet* rs; + Uint32 a; + char c[20]; + CHK((g_con = g_ndb->startTransaction()) != 0); + CHK((g_ops = g_con->getNdbScanOperation(tab.getName())) != 0); + CHK((rs = g_ops->readTuples(NdbScanOperation::LM_Read)) != 0); + CHK(g_ops->getValue(cA, (char*)&a) != 0); + CHK((g_bh1 = g_ops->getBlobHandle(cC)) != 0); + CHK(g_con->execute(NoCommit) == 0); + unsigned n = 0; + t2.on(); + while (1) { + a = (Uint32)-1; + c[0] = 0; + int ret; + CHK((ret = rs->nextResult(true)) == 0 || ret == 1); + if (ret == 1) + break; + Uint32 m = 20; + CHK(g_bh1->readData(c, m) == 0); + CHK(a < g_opt.m_rowsperf && m == 1 && strcmp(c, "c") == 0); + n++; + } + CHK(n == g_opt.m_rowsperf); + t2.off(g_opt.m_rowsperf); + DBG(t2.time()); + g_bh1 = 0; + g_ops = 0; + g_con = 0; + } + // scan read overhead + DBG("scan read overhead: " << t2.over(t1)); + t1.clr(); + t2.clr(); + delete g_ndb; + return 0; +} + // bug tests static int @@ -1498,6 +1793,12 @@ NDB_COMMAND(testOdbcDriver, "testBlobs", "testBlobs", "testBlobs", 65535) continue; } } + if (strcmp(arg, "-rowsperf") == 0) { + if (++argv, --argc > 0) { + g_opt.m_rowsperf = atoi(argv[0]); + continue; + } + } if (strcmp(arg, "-seed") == 0) { if (++argv, --argc > 0) { g_opt.m_seed = atoi(argv[0]); @@ -1558,7 +1859,7 @@ NDB_COMMAND(testOdbcDriver, "testBlobs", "testBlobs", "testBlobs", 65535) strcat(b, "r"); g_opt.m_skip = strdup(b); } - if (testmain() == -1) { + if (testmain() == -1 || testperf() == -1) { ndbout << "line " << __LINE__ << " FAIL loop=" << g_loop << endl; return NDBT_ProgramExit(NDBT_FAILED); } diff --git a/sql/mysqld.cc b/sql/mysqld.cc index cd158e48b11..3001cda8b2b 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -469,6 +469,7 @@ Query_cache query_cache; #ifdef HAVE_SMEM char *shared_memory_base_name= default_shared_memory_base_name; bool opt_enable_shared_memory; +HANDLE smem_event_connect_request= 0; #endif #include "sslopt-vars.h" @@ -746,6 +747,15 @@ void kill_mysql(void) CloseHandle(hEvent); */ } +#ifdef HAVE_SMEM + /* + Send event to smem_event_connect_request for aborting + */ + if (!SetEvent(smem_event_connect_request)) + { + DBUG_PRINT("error",("Got error: %ld from SetEvent of smem_event_connect_request",GetLastError())); + } +#endif #endif #elif defined(OS2) pthread_cond_signal(&eventShutdown); // post semaphore @@ -3799,7 +3809,6 @@ pthread_handler_decl(handle_connections_shared_memory,arg) /* file-mapping object, use for create shared memory */ HANDLE handle_connect_file_map= 0; char *handle_connect_map= 0; // pointer on shared memory - HANDLE event_connect_request= 0; // for start connection actions HANDLE event_connect_answer= 0; ulong smem_buffer_length= shared_memory_buffer_length + 4; ulong connect_number= 1; @@ -3820,7 +3829,7 @@ pthread_handler_decl(handle_connections_shared_memory,arg) */ suffix_pos= strxmov(tmp,shared_memory_base_name,"_",NullS); strmov(suffix_pos, "CONNECT_REQUEST"); - if ((event_connect_request= CreateEvent(0,FALSE,FALSE,tmp)) == 0) + if ((smem_event_connect_request= CreateEvent(0,FALSE,FALSE,tmp)) == 0) { errmsg= "Could not create request event"; goto error; @@ -3851,7 +3860,13 @@ pthread_handler_decl(handle_connections_shared_memory,arg) while (!abort_loop) { /* Wait a request from client */ - WaitForSingleObject(event_connect_request,INFINITE); + WaitForSingleObject(smem_event_connect_request,INFINITE); + + /* + it can be after shutdown command + */ + if (abort_loop) + goto error; HANDLE handle_client_file_map= 0; char *handle_client_map= 0; @@ -3976,7 +3991,7 @@ error: if (handle_connect_map) UnmapViewOfFile(handle_connect_map); if (handle_connect_file_map) CloseHandle(handle_connect_file_map); if (event_connect_answer) CloseHandle(event_connect_answer); - if (event_connect_request) CloseHandle(event_connect_request); + if (smem_event_connect_request) CloseHandle(smem_event_connect_request); decrement_handler_count(); DBUG_RETURN(0); |