diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index da85ed6391f..77c82618446 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -102,6 +102,7 @@ miguel@hegel.txg.br miguel@light. miguel@light.local miguel@sartre.local +mikael@mc04.(none) mikron@c-fb0ae253.1238-1-64736c10.cust.bredbandsbolaget.se mikron@mikael-ronstr-ms-dator.local mleich@mysql.com @@ -132,6 +133,7 @@ mwagner@here.mwagner.org mwagner@work.mysql.com mydev@mysql.com mysql@home.(none) +mysql@mc04.(none) mysqldev@build.mysql2.com mysqldev@melody.local mysqldev@mysql.com @@ -161,6 +163,7 @@ ram@ram.(none) ranger@regul.home.lan rburnett@build.mysql.com root@home.(none) +root@mc04.(none) root@x3.internalnet salle@banica.(none) salle@geopard.(none) diff --git a/acinclude.m4 b/acinclude.m4 index 28344919dae..c7d7ba0e9c9 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -1548,16 +1548,43 @@ dnl Sets HAVE_NDBCLUSTER_DB if --with-ndbcluster is used dnl --------------------------------------------------------------------------- AC_DEFUN([MYSQL_CHECK_NDB_OPTIONS], [ + AC_ARG_WITH([ndb-sci], + AC_HELP_STRING([--with-ndb-sci=DIR], + [Provide MySQL with a custom location of + sci library. Given DIR, sci library is + assumed to be in $DIR/lib and header files + in $DIR/include.]), + [mysql_sci_dir=${withval}], + [mysql_sci_dir=""]) + + case "$mysql_sci_dir" in + "no" ) + have_ndb_sci=no + AC_MSG_RESULT([-- not including sci transporter]) + ;; + * ) + if test -f "$mysql_sci_dir/lib/libsisci.a" -a \ + -f "$mysql_sci_dir/include/sisci_api.h"; then + NDB_SCI_INCLUDES="-I$mysql_sci_dir/include" + NDB_SCI_LIBS="-L$mysql_sci_dir/lib -lsisci" + AC_MSG_RESULT([-- including sci transporter]) + AC_DEFINE([NDB_SCI_TRANSPORTER], [1], + [Including Ndb Cluster DB sci transporter]) + AC_SUBST(NDB_SCI_INCLUDES) + AC_SUBST(NDB_SCI_LIBS) + have_ndb_sci="yes" + AC_MSG_RESULT([found sci transporter in $mysql_sci_dir/{include, lib}]) + else + AC_MSG_RESULT([could not find sci transporter in $mysql_sci_dir/{include, lib}]) + fi + ;; + esac + AC_ARG_WITH([ndb-shm], [ --with-ndb-shm Include the NDB Cluster shared memory transporter], [ndb_shm="$withval"], [ndb_shm=no]) - AC_ARG_WITH([ndb-sci], - [ - --with-ndb-sci Include the NDB Cluster sci transporter], - [ndb_sci="$withval"], - [ndb_sci=no]) AC_ARG_WITH([ndb-test], [ --with-ndb-test Include the NDB Cluster ndbapi test programs], @@ -1590,19 +1617,6 @@ AC_DEFUN([MYSQL_CHECK_NDB_OPTIONS], [ ;; esac - have_ndb_sci=no - case "$ndb_sci" in - yes ) - AC_MSG_RESULT([-- including sci transporter]) - AC_DEFINE([NDB_SCI_TRANSPORTER], [1], - [Including Ndb Cluster DB sci transporter]) - have_ndb_sci="yes" - ;; - * ) - AC_MSG_RESULT([-- not including sci transporter]) - ;; - esac - have_ndb_test=no case "$ndb_test" in yes ) diff --git a/client/Makefile.am b/client/Makefile.am index 2db1e49850d..24a4bece825 100644 --- a/client/Makefile.am +++ b/client/Makefile.am @@ -34,7 +34,7 @@ mysqlcheck_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES) $(DEPLIB) mysqlshow_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES) $(DEPLIB) mysqldump_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES) $(DEPLIB) mysqlimport_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES) $(DEPLIB) -mysqltest_SOURCES= mysqltest.c +mysqltest_SOURCES= mysqltest.c ../mysys/my_getsystime.c mysqltest_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES) $(DEPLIB) mysqlbinlog_SOURCES = mysqlbinlog.cc ../mysys/mf_tempdir.c mysqlbinlog_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES) $(DEPLIB) diff --git a/client/mysqltest.c b/client/mysqltest.c index 3287c9738d3..7f2b6e16947 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -58,6 +58,13 @@ #include #include #include +#ifdef HAVE_SYS_PARAM_H +#include +#endif + +#ifndef MAXPATHLEN +#define MAXPATHLEN 256 +#endif #define MAX_QUERY 131072 #define MAX_VAR_NAME 256 @@ -75,7 +82,7 @@ #ifndef MYSQL_MANAGER_PORT #define MYSQL_MANAGER_PORT 23546 #endif -#define MAX_SERVER_ARGS 20 +#define MAX_SERVER_ARGS 64 /* Sometimes in a test the client starts before @@ -132,6 +139,13 @@ static char *embedded_server_args[MAX_SERVER_ARGS]; static my_bool display_result_vertically= FALSE, display_metadata= FALSE; +/* See the timer_output() definition for details */ +static char *timer_file = NULL; +static ulonglong timer_start; +static int got_end_timer= FALSE; +static void timer_output(void); +static ulonglong timer_now(void); + static const char *embedded_server_groups[] = { "server", "embedded", @@ -230,6 +244,7 @@ Q_ENABLE_METADATA, Q_DISABLE_METADATA, Q_EXEC, Q_DELIMITER, Q_DISPLAY_VERTICAL_RESULTS, Q_DISPLAY_HORIZONTAL_RESULTS, Q_QUERY_VERTICAL, Q_QUERY_HORIZONTAL, +Q_START_TIMER, Q_END_TIMER, Q_UNKNOWN, /* Unknown command. */ Q_COMMENT, /* Comments, ignored. */ @@ -308,6 +323,8 @@ const char *command_names[]= "horizontal_results", "query_vertical", "query_horizontal", + "start_timer", + "end_timer", 0 }; @@ -844,10 +861,10 @@ int do_source(struct st_query* q) 1 error */ -int do_exec(struct st_query* q) +static void do_exec(struct st_query* q) { - int error= 0; - DYNAMIC_STRING *ds; + int error; + DYNAMIC_STRING *ds= NULL; /* Assign just to avoid warning */ DYNAMIC_STRING ds_tmp; char buf[1024]; FILE *res_file; @@ -884,7 +901,15 @@ int do_exec(struct st_query* q) while (fgets(buf, sizeof(buf), res_file)) replace_dynstr_append_mem(ds, buf, strlen(buf)); + } + error= pclose(res_file); + + if (error != 0) + die("command \"%s\" failed", cmd); + + if (!disable_result_log) + { if (glob_replace) free_replace(); @@ -902,9 +927,6 @@ int do_exec(struct st_query* q) if (ds == &ds_tmp) dynstr_free(&ds_tmp); } - pclose(res_file); - - DBUG_RETURN(error); } @@ -1986,6 +2008,8 @@ static struct my_option my_long_options[] = #include "sslopt-longopts.h" {"test-file", 'x', "Read test from/in this file (default stdin).", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"timer-file", 'm', "File where the timing in micro seconds is stored.", + 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"tmpdir", 't', "Temporary directory where sockets are put.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"user", 'u', "User for login.", (gptr*) &user, (gptr*) &user, 0, GET_STR, @@ -2047,6 +2071,19 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), die("Could not open %s: errno = %d", argument, errno); break; } + case 'm': + { + static char buff[FN_REFLEN]; + if (!test_if_hard_path(argument)) + { + strxmov(buff, opt_basedir, argument, NullS); + argument= buff; + } + fn_format(buff, argument, "", "", 4); + timer_file= buff; + unlink(timer_file); /* Ignore error, may not exist */ + break; + } case 'p': if (argument) { @@ -2128,7 +2165,7 @@ char* safe_str_append(char* buf, const char* str, int size) void str_to_file(const char* fname, char* str, int size) { int fd; - char buff[FN_REFLEN]; + char buff[MAXPATHLEN]; if (!test_if_hard_path(fname)) { strxmov(buff, opt_basedir, fname, NullS); @@ -2599,6 +2636,9 @@ int main(int argc, char **argv) DBUG_ENTER("main"); DBUG_PROCESS(argv[0]); + /* Use all time until exit if no explicit 'start_timer' */ + timer_start= timer_now(); + save_file[0]=0; TMPDIR[0]=0; memset(cons, 0, sizeof(cons)); @@ -2811,7 +2851,16 @@ int main(int argc, char **argv) (void) mysql_ping(&cur_con->mysql); break; case Q_EXEC: - (void) do_exec(q); + do_exec(q); + break; + case Q_START_TIMER: + /* Overwrite possible earlier start of timer */ + timer_start= timer_now(); + break; + case Q_END_TIMER: + /* End timer before ending mysqltest */ + timer_output(); + got_end_timer= TRUE; break; default: processed = 0; break; } @@ -2847,6 +2896,8 @@ int main(int argc, char **argv) printf("ok\n"); } + if (!got_end_timer) + timer_output(); /* No end_timer cmd, end it */ free_used_memory(); exit(error ? 1 : 0); return error ? 1 : 0; /* Keep compiler happy */ @@ -2900,6 +2951,45 @@ static int read_server_arguments(const char *name) return 0; } +/****************************************************************************\ + * + * A primitive timer that give results in milliseconds if the + * --timer-file= is given. The timer result is written + * to that file when the result is available. To not confuse + * mysql-test-run with an old obsolete result, we remove the file + * before executing any commands. The time we measure is + * + * - If no explicit 'start_timer' or 'end_timer' is given in the + * test case, the timer measure how long we execute in mysqltest. + * + * - If only 'start_timer' is given we measure how long we execute + * from that point until we terminate mysqltest. + * + * - If only 'end_timer' is given we measure how long we execute + * from that we enter mysqltest to the 'end_timer' is command is + * executed. + * + * - If both 'start_timer' and 'end_timer' are given we measure + * the time between executing the two commands. + * +\****************************************************************************/ + +static void timer_output(void) +{ + if (timer_file) + { + char buf[1024]; + ulonglong timer= timer_now() - timer_start; + sprintf(buf,"%llu",timer); + str_to_file(timer_file,buf,strlen(buf)); + } +} + +static ulonglong timer_now(void) +{ + return my_getsystime() / 10000; +} + /**************************************************************************** * Handle replacement of strings ****************************************************************************/ diff --git a/configure.in b/configure.in index be365ec8584..39151205533 100644 --- a/configure.in +++ b/configure.in @@ -3024,11 +3024,11 @@ AC_SUBST([ndb_port_base]) ndb_transporter_opt_objs="" if test X"$have_ndb_shm" = Xyes then - ndb_transporter_opt_objs="$(ndb_transporter_opt_objs) SHM_Transporter.lo SHM_Transporter.unix.lo" + ndb_transporter_opt_objs="$ndb_transporter_opt_objs SHM_Transporter.lo SHM_Transporter.unix.lo" fi if test X"$have_ndb_sci" = Xyes then - ndb_transporter_opt_objs="$(ndb_transporter_opt_objs) SCI_Transporter.lo" + ndb_transporter_opt_objs="$ndb_transporter_opt_objs SCI_Transporter.lo" fi AC_SUBST([ndb_transporter_opt_objs]) diff --git a/mysql-test/include/ps_conv.inc b/mysql-test/include/ps_conv.inc index f61fb7db1c9..03d93b6190d 100644 --- a/mysql-test/include/ps_conv.inc +++ b/mysql-test/include/ps_conv.inc @@ -1190,13 +1190,13 @@ execute stmt1 using @arg00 ; ######## SELECT .. WHERE column(year)=value(DOUBLE(m,n)/DOUBLE) ######## set @arg00= 1.991e+3 ; select 'true' as found from t9 -where c1= 20 and c17= 1.991e+3 ; +where c1= 20 and abs(c17 - 1.991e+3) < 0.01 ; select 'true' as found from t9 -where c1= 20 and c17= @arg00 ; +where c1= 20 and abs(c17 - @arg00) < 0.01 ; prepare stmt1 from "select 'true' as found from t9 -where c1= 20 and c17= 1.991e+3" ; +where c1= 20 and abs(c17 - 1.991e+3) < 0.01" ; execute stmt1 ; prepare stmt1 from "select 'true' as found from t9 -where c1= 20 and c17= ?" ; +where c1= 20 and abs(c17 - ?) < 0.01" ; execute stmt1 using @arg00 ; diff --git a/mysql-test/include/ps_query.inc b/mysql-test/include/ps_query.inc index 3ebe3c7b5a1..e02d0d5bf96 100644 --- a/mysql-test/include/ps_query.inc +++ b/mysql-test/include/ps_query.inc @@ -540,6 +540,10 @@ FROM t9, (select c25 x, c32 y from t2) tt WHERE x = c25 ' ; --enable_metadata prepare stmt1 from @stmt ; +# +# Result log was disabled upon test case failure in the optimized build. +# +--disable_result_log execute stmt1 ; --disable_metadata execute stmt1 ; @@ -588,6 +592,7 @@ execute stmt1 using @arg00, @arg01, @arg02, @arg03, @arg04, @arg05, @arg06, --disable_metadata execute stmt1 using @arg00, @arg01, @arg02, @arg03, @arg04, @arg05, @arg06, @arg07, @arg08, @arg09 ; +--enable_result_log drop table t2 ; diff --git a/mysql-test/mysql-test-run.sh b/mysql-test/mysql-test-run.sh index 41dc3c419f0..5cb491b43c4 100644 --- a/mysql-test/mysql-test-run.sh +++ b/mysql-test/mysql-test-run.sh @@ -208,6 +208,7 @@ MYSQL_MANAGER_LOG=$MYSQL_TEST_DIR/var/log/manager.log MYSQL_MANAGER_USER=root NO_SLAVE=0 USER_TEST= +FAILED_CASES= EXTRA_MASTER_OPT="" EXTRA_MYSQL_TEST_OPT="" @@ -232,11 +233,17 @@ DBUSER="" START_WAIT_TIMEOUT=10 STOP_WAIT_TIMEOUT=10 MYSQL_TEST_SSL_OPTS="" +USE_TIMER="" +USE_EMBEDDED_SERVER="" +RESULT_EXT="" while test $# -gt 0; do case "$1" in + --embedded-server) USE_EMBEDDED_SERVER=1 ; USE_MANAGER=0 ; NO_SLAVE=1 ; \ + USE_RUNNING_SERVER="" RESULT_EXT=".es" ;; --user=*) DBUSER=`$ECHO "$1" | $SED -e "s;--user=;;"` ;; --force) FORCE=1 ;; + --timer) USE_TIMER=1 ;; --verbose-manager) MANAGER_QUIET_OPT="" ;; --old-master) MASTER_40_ARGS="";; --master-binary=*) @@ -295,6 +302,11 @@ while test $# -gt 0; do --record) RECORD=1; EXTRA_MYSQL_TEST_OPT="$EXTRA_MYSQL_TEST_OPT $1" ;; + --small-bench) + DO_SMALL_BENCH=1 + DO_BENCH=1 + NO_SLAVE=1 + ;; --bench) DO_BENCH=1 NO_SLAVE=1 @@ -458,18 +470,27 @@ fi if test ${COLUMNS:-0} -lt 80 ; then COLUMNS=80 ; fi E=`$EXPR $COLUMNS - 8` -DASH72=`$ECHO '------------------------------------------'|$CUT -c 1-$E` +DASH72=`$ECHO '-------------------------------------------------------'|$CUT -c 1-$E` # on source dist, we pick up freshly build executables # on binary, use what is installed if [ x$SOURCE_DIST = x1 ] ; then - MYSQLD="$VALGRIND $BASEDIR/sql/mysqld" - if [ -f "$BASEDIR/client/.libs/lt-mysqltest" ] ; then - MYSQL_TEST="$BASEDIR/client/.libs/lt-mysqltest" - elif [ -f "$BASEDIR/client/.libs/mysqltest" ] ; then - MYSQL_TEST="$BASEDIR/client/.libs/mysqltest" + if [ "x$USE_EMBEDDED_SERVER" = "x1" ] ; then + if [ -f "$BASEDIR/libmysqld/examples/mysqltest" ] ; then + MYSQL_TEST="$VALGRIND $BASEDIR/libmysqld/examples/mysqltest" + else + echo "Fatal error: Cannot find embedded server 'mysqltest'" 1>&2 + exit 1 + fi else - MYSQL_TEST="$BASEDIR/client/mysqltest" + MYSQLD="$VALGRIND $BASEDIR/sql/mysqld" + if [ -f "$BASEDIR/client/.libs/lt-mysqltest" ] ; then + MYSQL_TEST="$BASEDIR/client/.libs/lt-mysqltest" + elif [ -f "$BASEDIR/client/.libs/mysqltest" ] ; then + MYSQL_TEST="$BASEDIR/client/.libs/mysqltest" + else + MYSQL_TEST="$BASEDIR/client/mysqltest" + fi fi if [ -f "$BASEDIR/client/.libs/mysqldump" ] ; then MYSQL_DUMP="$BASEDIR/client/.libs/mysqldump" @@ -566,6 +587,9 @@ export MYSQL MYSQL_DUMP MYSQL_BINLOG MYSQL_FIX_SYSTEM_TABLES CLIENT_BINDIR MYSQL_TEST_ARGS="--no-defaults --socket=$MASTER_MYSOCK --database=$DB \ --user=$DBUSER --password=$DBPASSWD --silent -v --skip-safemalloc \ --tmpdir=$MYSQL_TMP_DIR --port=$MASTER_MYPORT $MYSQL_TEST_SSL_OPTS" +if [ x$USE_TIMER = x1 ] ; then + MYSQL_TEST_ARGS="$MYSQL_TEST_ARGS --timer-file=$MY_LOG_DIR/timer" +fi MYSQL_TEST_BIN=$MYSQL_TEST MYSQL_TEST="$MYSQL_TEST $MYSQL_TEST_ARGS" GDB_CLIENT_INIT=$MYSQL_TMP_DIR/gdbinit.client @@ -599,6 +623,13 @@ show_failed_diff () result_file=r/$1.result eval_file=r/$1.eval + # If we have an special externsion for result files we use it if we are recording + # or a result file with that extension exists. + if [ -n "$RESULT_EXT" -a \( x$RECORD = x1 -o -f "$result_file$RESULT_EXT" \) ] + then + result_file="$result_file$RESULT_EXT" + fi + if [ -f $eval_file ] then result_file=$eval_file @@ -880,6 +911,8 @@ EOF abort_if_failed "Could not execute manager command" } +# The embedded server needs the cleanup so we do some of the start work +# but stop before actually running mysqld or anything. start_master() { @@ -949,6 +982,18 @@ start_master() CUR_MYERR=$MASTER_MYERR CUR_MYSOCK=$MASTER_MYSOCK + # For embedded server we collect the server flags and return + if [ "x$USE_EMBEDDED_SERVER" = "x1" ] ; then + # Add a -A to each argument to pass it to embedded server + EMBEDDED_SERVER_OPTS="" + for opt in $master_args + do + EMBEDDED_SERVER_OPTS="$EMBEDDED_SERVER_OPTS -A $opt" + done + EXTRA_MYSQL_TEST_OPT="$EMBEDDED_SERVER_OPTS" + return + fi + if [ x$DO_DDD = x1 ] then $ECHO "set args $master_args" > $GDB_MASTER_INIT @@ -1159,22 +1204,26 @@ stop_master () { if [ x$MASTER_RUNNING = x1 ] then - pid=`$CAT $MASTER_MYPID` - manager_term $pid master - if [ $? != 0 ] && [ -f $MASTER_MYPID ] - then # try harder! - $ECHO "master not cooperating with mysqladmin, will try manual kill" - kill $pid - sleep_until_file_deleted $pid $MASTER_MYPID - if [ -f $MASTER_MYPID ] ; then - $ECHO "master refused to die. Sending SIGKILL" - kill -9 `$CAT $MASTER_MYPID` - $RM -f $MASTER_MYPID + # For embedded server we don't stop anyting but mark that + # MASTER_RUNNING=0 to get cleanup when calling start_master(). + if [ x$USE_EMBEDDED_SERVER != x1 ] ; then + pid=`$CAT $MASTER_MYPID` + manager_term $pid master + if [ $? != 0 ] && [ -f $MASTER_MYPID ] + then # try harder! + $ECHO "master not cooperating with mysqladmin, will try manual kill" + kill $pid + sleep_until_file_deleted $pid $MASTER_MYPID + if [ -f $MASTER_MYPID ] ; then + $ECHO "master refused to die. Sending SIGKILL" + kill -9 `$CAT $MASTER_MYPID` + $RM -f $MASTER_MYPID + else + $ECHO "master responded to SIGTERM " + fi else - $ECHO "master responded to SIGTERM " + sleep $SLEEP_TIME_AFTER_RESTART fi - else - sleep $SLEEP_TIME_AFTER_RESTART fi MASTER_RUNNING=0 fi @@ -1217,9 +1266,13 @@ run_testcase () master_init_script=$TESTDIR/$tname-master.sh slave_init_script=$TESTDIR/$tname-slave.sh slave_master_info_file=$TESTDIR/$tname.slave-mi - result_file=$tname + tsrcdir=$TESTDIR/$tname-src + result_file="r/$tname.result" echo $tname > $CURRENT_TEST SKIP_SLAVE=`$EXPR \( $tname : rpl \) = 0` + if [ -n "$RESULT_EXT" -a \( x$RECORD = x1 -o -f "$result_file$RESULT_EXT" \) ] ; then + result_file="$result_file$RESULT_EXT" + fi if [ "$USE_MANAGER" = 1 ] ; then many_slaves=`$EXPR \( \( $tname : rpl_failsafe \) != 0 \) \| \( \( $tname : rpl_chain_temp_table \) != 0 \)` fi @@ -1249,11 +1302,45 @@ run_testcase () return fi - # Stop all slave threads, so that we don't have useless reconnection attempts - # and error messages in case the slave and master servers restart. - stop_slave_threads - stop_slave_threads 1 - stop_slave_threads 2 + if [ "x$USE_EMBEDDED_SERVER" != "x1" ] ; then + # Stop all slave threads, so that we don't have useless reconnection + # attempts and error messages in case the slave and master servers restart. + stop_slave_threads + stop_slave_threads 1 + stop_slave_threads 2 + fi + + # FIXME temporary solution, we will get a new C version of this + # script soon anyway so it is not worth it spending the time + if [ "x$USE_EMBEDDED_SERVER" = "x1" -a -z "$DO_TEST" ] ; then + for t in \ + "bdb-deadlock" \ + "connect" \ + "flush_block_commit" \ + "grant2" \ + "grant_cache" \ + "grant" \ + "init_connect" \ + "innodb-deadlock" \ + "innodb-lock" \ + "mix_innodb_myisam_binlog" \ + "mysqlbinlog2" \ + "mysqlbinlog" \ + "mysqldump" \ + "mysql_protocols" \ + "ps_1general" \ + "rename" \ + "show_check" \ + "system_mysql_db_fix" \ + "user_var" \ + "variables" + do + if [ "$tname" = "$t" ] ; then + skip_test $tname + return + fi + done + fi if [ -z "$USE_RUNNING_SERVER" ] ; then @@ -1269,6 +1356,10 @@ run_testcase () ;; --result-file=*) result_file=`$ECHO "$EXTRA_MASTER_OPT" | $SED -e "s;--result-file=;;"` + result_file="r/$result_file.result" + if [ -n "$RESULT_EXT" -a \( x$RECORD = x1 -o -f "$result_file$RESULT_EXT" \) ] ; then + result_file="$result_file$RESULT_EXT" + fi # Note that this must be set to space, not "" for test-reset to work EXTRA_MASTER_OPT=" " ;; @@ -1278,7 +1369,11 @@ run_testcase () start_master TZ=$MY_TZ; export TZ else - if [ ! -z "$EXTRA_MASTER_OPT" ] || [ x$MASTER_RUNNING != x1 ] || [ -f $master_init_script ] + # If we had extra master opts to the previous run + # or there is no master running (FIXME strange.....) + # or there is a master init script + if [ ! -z "$EXTRA_MASTER_OPT" ] || [ x$MASTER_RUNNING != x1 ] || \ + [ -f $master_init_script ] then EXTRA_MASTER_OPT="" stop_master @@ -1289,47 +1384,50 @@ run_testcase () fi fi - do_slave_restart=0 - if [ -f $slave_opt_file ] ; - then - EXTRA_SLAVE_OPT=`$CAT $slave_opt_file | $SED -e "s;\\$MYSQL_TEST_DIR;$MYSQL_TEST_DIR;"` - do_slave_restart=1 - else - if [ ! -z "$EXTRA_SLAVE_OPT" ] || [ x$SLAVE_RUNNING != x1 ] ; - then - EXTRA_SLAVE_OPT="" - do_slave_restart=1 - fi - fi - - if [ -f $slave_master_info_file ] ; then - SLAVE_MASTER_INFO=`$CAT $slave_master_info_file` - do_slave_restart=1 - else - if [ ! -z "$SLAVE_MASTER_INFO" ] || [ x$SLAVE_RUNNING != x1 ] ; + # We never start a slave if embedded server is used + if [ "x$USE_EMBEDDED_SERVER" != "x1" ] ; then + do_slave_restart=0 + if [ -f $slave_opt_file ] ; then - SLAVE_MASTER_INFO="" + EXTRA_SLAVE_OPT=`$CAT $slave_opt_file | $SED -e "s;\\$MYSQL_TEST_DIR;$MYSQL_TEST_DIR;"` do_slave_restart=1 + else + if [ ! -z "$EXTRA_SLAVE_OPT" ] || [ x$SLAVE_RUNNING != x1 ] ; + then + EXTRA_SLAVE_OPT="" + do_slave_restart=1 + fi fi - fi - if [ x$do_slave_restart = x1 ] ; then - stop_slave - echo "CURRENT_TEST: $tname" >> $SLAVE_MYERR - start_slave - else - echo "CURRENT_TEST: $tname" >> $SLAVE_MYERR - fi - if [ x$many_slaves = x1 ]; then - start_slave 1 - start_slave 2 + if [ -f $slave_master_info_file ] ; then + SLAVE_MASTER_INFO=`$CAT $slave_master_info_file` + do_slave_restart=1 + else + if [ ! -z "$SLAVE_MASTER_INFO" ] || [ x$SLAVE_RUNNING != x1 ] ; + then + SLAVE_MASTER_INFO="" + do_slave_restart=1 + fi + fi + + if [ x$do_slave_restart = x1 ] ; then + stop_slave + echo "CURRENT_TEST: $tname" >> $SLAVE_MYERR + start_slave + else + echo "CURRENT_TEST: $tname" >> $SLAVE_MYERR + fi + if [ x$many_slaves = x1 ]; then + start_slave 1 + start_slave 2 + fi fi fi cd $MYSQL_TEST_DIR if [ -f $tf ] ; then $RM -f r/$tname.*reject - mysql_test_args="-R r/$result_file.result $EXTRA_MYSQL_TEST_OPT" + mysql_test_args="-R $result_file $EXTRA_MYSQL_TEST_OPT" if [ -z "$DO_CLIENT_GDB" ] ; then `$MYSQL_TEST $mysql_test_args < $tf 2> $TIMEFILE`; else @@ -1349,7 +1447,12 @@ run_testcase () if [ $res = 0 ]; then total_inc pass_inc - $ECHO "$RES$RES_SPACE [ pass ]" + TIMER="" + if [ x$USE_TIMER = x1 -a -f "$MY_LOG_DIR/timer" ]; then + TIMER=`cat $MY_LOG_DIR/timer` + TIMER=`$PRINTF "%13s" $TIMER` + fi + $ECHO "$RES$RES_SPACE [ pass ] $TIMER" else # why the following ``if'' ? That is why res==1 is special ? if [ $res = 2 ]; then @@ -1364,20 +1467,22 @@ run_testcase () $ECHO "$RES$RES_SPACE [ fail ]" $ECHO error_is - show_failed_diff $result_file + show_failed_diff $tname $ECHO if [ x$FORCE != x1 ] ; then $ECHO "Aborting: $tname failed. To continue, re-run with '--force'." $ECHO - if [ -z "$DO_GDB" ] && [ -z "$USE_RUNNING_SERVER" ] && [ -z "$DO_DDD" ] + if [ -z "$DO_GDB" ] && [ -z "$USE_RUNNING_SERVER" ] && \ + [ -z "$DO_DDD" ] && [ -z "$USE_EMBEDDED_SERVER" ] then mysql_stop stop_manager fi exit 1 fi - - if [ -z "$DO_GDB" ] && [ -z "$USE_RUNNING_SERVER" ] && [ -z "$DO_DDD" ] + FAILED_CASES="$FAILED_CASES $tname" + if [ -z "$DO_GDB" ] && [ -z "$USE_RUNNING_SERVER" ] && \ + [ -z "$DO_DDD" ] && [ -z "$USE_EMBEDDED_SERVER" ] then mysql_restart fi @@ -1451,7 +1556,13 @@ then if [ -z "$USE_RUNNING_NDBCLUSTER" ] then echo "Starting ndbcluster" - ./ndb/ndbcluster --port-base=$NDBCLUSTER_PORT --small --diskless --initial --data-dir=$MYSQL_TEST_DIR/var || exit 1 + if [ "$DO_BENCH" = 1 ] + then + NDBCLUSTER_OPTS="" + else + NDBCLUSTER_OPTS="--small" + fi + ./ndb/ndbcluster --port-base=$NDBCLUSTER_PORT $NDBCLUSTER_OPTS --diskless --initial --data-dir=$MYSQL_TEST_DIR/var || exit 1 USE_NDBCLUSTER="$USE_NDBCLUSTER --ndb-connectstring=\"host=localhost:$NDBCLUSTER_PORT\"" else USE_NDBCLUSTER="$USE_NDBCLUSTER --ndb-connectstring=\"$USE_RUNNING_NDBCLUSTER\"" @@ -1485,9 +1596,14 @@ if [ "$DO_BENCH" = 1 ] then start_master + if [ "$DO_SMALL_BENCH" = 1 ] + then + EXTRA_BENCH_ARGS="--small-test --small-tables" + fi + if [ ! -z "$USE_NDBCLUSTER" ] then - EXTRA_BENCH_ARGS="--create-options=TYPE=ndb" + EXTRA_BENCH_ARGS="--create-options=TYPE=ndb $EXTRA_BENCH_ARGS" fi BENCHDIR=$BASEDIR/sql-bench/ @@ -1495,7 +1611,7 @@ then cd $BENCHDIR if [ -z "$1" ] then - ./run-all-tests --socket=$MASTER_MYSOCK --user=root $EXTRA_BENCH_ARGS + ./run-all-tests --socket=$MASTER_MYSOCK --user=root $EXTRA_BENCH_ARGS --log else if [ -x "./$1" ] then @@ -1511,7 +1627,11 @@ then fi $ECHO -$ECHO " TEST RESULT" +if [ x$USE_TIMER = x1 ] ; then +$ECHO "TEST RESULT TIME (ms)" +else +$ECHO "TEST RESULT" +fi $ECHO $DASH72 if [ -z "$1" ] ; @@ -1562,4 +1682,10 @@ $ECHO [ "$DO_GCOV" ] && gcov_collect # collect coverage information [ "$DO_GPROF" ] && gprof_collect # collect coverage information -exit 0 +if [ $TOT_FAIL -ne 0 ]; then + $ECHO "mysql-test-run: *** Failing the test(s):$FAILED_CASES" + $ECHO + exit 1 +else + exit 0 +fi diff --git a/mysql-test/ndb/ndb_config_2_node.ini b/mysql-test/ndb/ndb_config_2_node.ini index cc0f940efe3..8c89d2aa2cc 100644 --- a/mysql-test/ndb/ndb_config_2_node.ini +++ b/mysql-test/ndb/ndb_config_2_node.ini @@ -6,6 +6,7 @@ IndexMemory= CHOOSE_IndexMemory Diskless= CHOOSE_Diskless TimeBetweenWatchDogCheck= 30000 DataDir= CHOOSE_FILESYSTEM +MaxNoOfOrderedIndexes= CHOOSE_MaxNoOfOrderedIndexes [ndbd] HostName= CHOOSE_HOSTNAME_1 diff --git a/mysql-test/ndb/ndbcluster.sh b/mysql-test/ndb/ndbcluster.sh index f143242371f..7485e42923e 100644 --- a/mysql-test/ndb/ndbcluster.sh +++ b/mysql-test/ndb/ndbcluster.sh @@ -44,7 +44,8 @@ initial_ndb= status_ndb= ndb_diskless=0 -ndb_con_op=100000 +ndb_no_ord=512 +ndb_con_op=105000 ndb_dmem=80M ndb_imem=24M @@ -65,6 +66,7 @@ while test $# -gt 0; do status_ndb=1 ;; --small) + ndb_no_ord=128 ndb_con_op=10000 ndb_dmem=40M ndb_imem=12M @@ -128,6 +130,7 @@ port_transporter=`expr $ndb_mgmd_port + 2` if [ $initial_ndb ] ; then sed \ + -e s,"CHOOSE_MaxNoOfOrderedIndexes","$ndb_no_ord",g \ -e s,"CHOOSE_MaxNoOfConcurrentOperations","$ndb_con_op",g \ -e s,"CHOOSE_DataMemory","$ndb_dmem",g \ -e s,"CHOOSE_IndexMemory","$ndb_imem",g \ diff --git a/mysql-test/r/alter_table.result.es b/mysql-test/r/alter_table.result.es new file mode 100644 index 00000000000..4f93b40a573 --- /dev/null +++ b/mysql-test/r/alter_table.result.es @@ -0,0 +1,483 @@ +drop table if exists t1,t2; +drop database if exists mysqltest; +create table t1 ( +col1 int not null auto_increment primary key, +col2 varchar(30) not null, +col3 varchar (20) not null, +col4 varchar(4) not null, +col5 enum('PENDING', 'ACTIVE', 'DISABLED') not null, +col6 int not null, to_be_deleted int); +insert into t1 values (2,4,3,5,"PENDING",1,7); +alter table t1 +add column col4_5 varchar(20) not null after col4, +add column col7 varchar(30) not null after col5, +add column col8 datetime not null, drop column to_be_deleted, +change column col2 fourth varchar(30) not null after col3, +modify column col6 int not null first; +select * from t1; +col6 col1 col3 fourth col4 col4_5 col5 col7 col8 +1 2 3 4 5 PENDING 0000-00-00 00:00:00 +drop table t1; +create table t1 (bandID MEDIUMINT UNSIGNED NOT NULL PRIMARY KEY, payoutID SMALLINT UNSIGNED NOT NULL); +insert into t1 (bandID,payoutID) VALUES (1,6),(2,6),(3,4),(4,9),(5,10),(6,1),(7,12),(8,12); +alter table t1 add column new_col int, order by payoutid,bandid; +select * from t1; +bandID payoutID new_col +6 1 NULL +3 4 NULL +1 6 NULL +2 6 NULL +4 9 NULL +5 10 NULL +7 12 NULL +8 12 NULL +alter table t1 order by bandid,payoutid; +select * from t1; +bandID payoutID new_col +1 6 NULL +2 6 NULL +3 4 NULL +4 9 NULL +5 10 NULL +6 1 NULL +7 12 NULL +8 12 NULL +drop table t1; +CREATE TABLE t1 ( +GROUP_ID int(10) unsigned DEFAULT '0' NOT NULL, +LANG_ID smallint(5) unsigned DEFAULT '0' NOT NULL, +NAME varchar(80) DEFAULT '' NOT NULL, +PRIMARY KEY (GROUP_ID,LANG_ID), +KEY NAME (NAME)); +ALTER TABLE t1 CHANGE NAME NAME CHAR(80) not null; +SHOW FULL COLUMNS FROM t1; +Field Type Collation Null Key Default Extra Privileges Comment +GROUP_ID int(10) unsigned NULL PRI 0 +LANG_ID smallint(5) unsigned NULL PRI 0 +NAME char(80) latin1_swedish_ci MUL +DROP TABLE t1; +create table t1 (n int); +insert into t1 values(9),(3),(12),(10); +alter table t1 order by n; +select * from t1; +n +3 +9 +10 +12 +drop table t1; +CREATE TABLE t1 ( +id int(11) unsigned NOT NULL default '0', +category_id tinyint(4) unsigned NOT NULL default '0', +type_id tinyint(4) unsigned NOT NULL default '0', +body text NOT NULL, +user_id int(11) unsigned NOT NULL default '0', +status enum('new','old') NOT NULL default 'new', +PRIMARY KEY (id) +) ENGINE=MyISAM; +ALTER TABLE t1 ORDER BY t1.id, t1.status, t1.type_id, t1.user_id, t1.body; +DROP TABLE t1; +CREATE TABLE t1 (AnamneseId int(10) unsigned NOT NULL auto_increment,B BLOB,PRIMARY KEY (AnamneseId)) engine=myisam; +insert into t1 values (null,"hello"); +LOCK TABLES t1 WRITE; +ALTER TABLE t1 ADD Column new_col int not null; +UNLOCK TABLES; +OPTIMIZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 optimize status OK +DROP TABLE t1; +create table t1 (i int unsigned not null auto_increment primary key); +insert into t1 values (null),(null),(null),(null); +alter table t1 drop i,add i int unsigned not null auto_increment, drop primary key, add primary key (i); +select * from t1; +i +1 +2 +3 +4 +drop table t1; +create table t1 (name char(15)); +insert into t1 (name) values ("current"); +create database mysqltest; +create table mysqltest.t1 (name char(15)); +insert into mysqltest.t1 (name) values ("mysqltest"); +select * from t1; +name +current +select * from mysqltest.t1; +name +mysqltest +alter table t1 rename mysqltest.t1; +ERROR 42S01: Table 't1' already exists +select * from t1; +name +current +select * from mysqltest.t1; +name +mysqltest +drop table t1; +drop database mysqltest; +create database mysqltest; +create table mysqltest.t1 (a int,b int,c int); +grant all on mysqltest.t1 to mysqltest_1@localhost; +alter table t1 rename t2; +revoke all privileges on mysqltest.t1 from mysqltest_1@localhost; +delete from mysql.user where user=_binary'mysqltest_1'; +drop database mysqltest; +create table t1 (n1 int not null, n2 int, n3 int, n4 float, +unique(n1), +key (n1, n2, n3, n4), +key (n2, n3, n4, n1), +key (n3, n4, n1, n2), +key (n4, n1, n2, n3) ); +alter table t1 disable keys; +show keys from t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 0 n1 1 n1 A 0 NULL NULL BTREE +t1 1 n1_2 1 n1 A NULL NULL NULL BTREE disabled +t1 1 n1_2 2 n2 A NULL NULL NULL YES BTREE disabled +t1 1 n1_2 3 n3 A NULL NULL NULL YES BTREE disabled +t1 1 n1_2 4 n4 A NULL NULL NULL YES BTREE disabled +t1 1 n2 1 n2 A NULL NULL NULL YES BTREE disabled +t1 1 n2 2 n3 A NULL NULL NULL YES BTREE disabled +t1 1 n2 3 n4 A NULL NULL NULL YES BTREE disabled +t1 1 n2 4 n1 A NULL NULL NULL BTREE disabled +t1 1 n3 1 n3 A NULL NULL NULL YES BTREE disabled +t1 1 n3 2 n4 A NULL NULL NULL YES BTREE disabled +t1 1 n3 3 n1 A NULL NULL NULL BTREE disabled +t1 1 n3 4 n2 A NULL NULL NULL YES BTREE disabled +t1 1 n4 1 n4 A NULL NULL NULL YES BTREE disabled +t1 1 n4 2 n1 A NULL NULL NULL BTREE disabled +t1 1 n4 3 n2 A NULL NULL NULL YES BTREE disabled +t1 1 n4 4 n3 A NULL NULL NULL YES BTREE disabled +insert into t1 values(10,RAND()*1000,RAND()*1000,RAND()); +insert into t1 values(9,RAND()*1000,RAND()*1000,RAND()); +insert into t1 values(8,RAND()*1000,RAND()*1000,RAND()); +insert into t1 values(7,RAND()*1000,RAND()*1000,RAND()); +insert into t1 values(6,RAND()*1000,RAND()*1000,RAND()); +insert into t1 values(5,RAND()*1000,RAND()*1000,RAND()); +insert into t1 values(4,RAND()*1000,RAND()*1000,RAND()); +insert into t1 values(3,RAND()*1000,RAND()*1000,RAND()); +insert into t1 values(2,RAND()*1000,RAND()*1000,RAND()); +insert into t1 values(1,RAND()*1000,RAND()*1000,RAND()); +alter table t1 enable keys; +show keys from t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 0 n1 1 n1 A 10 NULL NULL BTREE +t1 1 n1_2 1 n1 A 10 NULL NULL BTREE +t1 1 n1_2 2 n2 A 10 NULL NULL YES BTREE +t1 1 n1_2 3 n3 A 10 NULL NULL YES BTREE +t1 1 n1_2 4 n4 A 10 NULL NULL YES BTREE +t1 1 n2 1 n2 A 10 NULL NULL YES BTREE +t1 1 n2 2 n3 A 10 NULL NULL YES BTREE +t1 1 n2 3 n4 A 10 NULL NULL YES BTREE +t1 1 n2 4 n1 A 10 NULL NULL BTREE +t1 1 n3 1 n3 A 10 NULL NULL YES BTREE +t1 1 n3 2 n4 A 10 NULL NULL YES BTREE +t1 1 n3 3 n1 A 10 NULL NULL BTREE +t1 1 n3 4 n2 A 10 NULL NULL YES BTREE +t1 1 n4 1 n4 A 10 NULL NULL YES BTREE +t1 1 n4 2 n1 A 10 NULL NULL BTREE +t1 1 n4 3 n2 A 10 NULL NULL YES BTREE +t1 1 n4 4 n3 A 10 NULL NULL YES BTREE +drop table t1; +create table t1 (i int unsigned not null auto_increment primary key); +alter table t1 rename t2; +alter table t2 rename t1, add c char(10) comment "no comment"; +show columns from t1; +Field Type Null Key Default Extra +i int(10) unsigned PRI NULL auto_increment +c char(10) YES NULL +drop table t1; +create table t1 (a int, b int); +insert into t1 values(1,100), (2,100), (3, 100); +insert into t1 values(1,99), (2,99), (3, 99); +insert into t1 values(1,98), (2,98), (3, 98); +insert into t1 values(1,97), (2,97), (3, 97); +insert into t1 values(1,96), (2,96), (3, 96); +insert into t1 values(1,95), (2,95), (3, 95); +insert into t1 values(1,94), (2,94), (3, 94); +insert into t1 values(1,93), (2,93), (3, 93); +insert into t1 values(1,92), (2,92), (3, 92); +insert into t1 values(1,91), (2,91), (3, 91); +insert into t1 values(1,90), (2,90), (3, 90); +insert into t1 values(1,89), (2,89), (3, 89); +insert into t1 values(1,88), (2,88), (3, 88); +insert into t1 values(1,87), (2,87), (3, 87); +insert into t1 values(1,86), (2,86), (3, 86); +insert into t1 values(1,85), (2,85), (3, 85); +insert into t1 values(1,84), (2,84), (3, 84); +insert into t1 values(1,83), (2,83), (3, 83); +insert into t1 values(1,82), (2,82), (3, 82); +insert into t1 values(1,81), (2,81), (3, 81); +insert into t1 values(1,80), (2,80), (3, 80); +insert into t1 values(1,79), (2,79), (3, 79); +insert into t1 values(1,78), (2,78), (3, 78); +insert into t1 values(1,77), (2,77), (3, 77); +insert into t1 values(1,76), (2,76), (3, 76); +insert into t1 values(1,75), (2,75), (3, 75); +insert into t1 values(1,74), (2,74), (3, 74); +insert into t1 values(1,73), (2,73), (3, 73); +insert into t1 values(1,72), (2,72), (3, 72); +insert into t1 values(1,71), (2,71), (3, 71); +insert into t1 values(1,70), (2,70), (3, 70); +insert into t1 values(1,69), (2,69), (3, 69); +insert into t1 values(1,68), (2,68), (3, 68); +insert into t1 values(1,67), (2,67), (3, 67); +insert into t1 values(1,66), (2,66), (3, 66); +insert into t1 values(1,65), (2,65), (3, 65); +insert into t1 values(1,64), (2,64), (3, 64); +insert into t1 values(1,63), (2,63), (3, 63); +insert into t1 values(1,62), (2,62), (3, 62); +insert into t1 values(1,61), (2,61), (3, 61); +insert into t1 values(1,60), (2,60), (3, 60); +insert into t1 values(1,59), (2,59), (3, 59); +insert into t1 values(1,58), (2,58), (3, 58); +insert into t1 values(1,57), (2,57), (3, 57); +insert into t1 values(1,56), (2,56), (3, 56); +insert into t1 values(1,55), (2,55), (3, 55); +insert into t1 values(1,54), (2,54), (3, 54); +insert into t1 values(1,53), (2,53), (3, 53); +insert into t1 values(1,52), (2,52), (3, 52); +insert into t1 values(1,51), (2,51), (3, 51); +insert into t1 values(1,50), (2,50), (3, 50); +insert into t1 values(1,49), (2,49), (3, 49); +insert into t1 values(1,48), (2,48), (3, 48); +insert into t1 values(1,47), (2,47), (3, 47); +insert into t1 values(1,46), (2,46), (3, 46); +insert into t1 values(1,45), (2,45), (3, 45); +insert into t1 values(1,44), (2,44), (3, 44); +insert into t1 values(1,43), (2,43), (3, 43); +insert into t1 values(1,42), (2,42), (3, 42); +insert into t1 values(1,41), (2,41), (3, 41); +insert into t1 values(1,40), (2,40), (3, 40); +insert into t1 values(1,39), (2,39), (3, 39); +insert into t1 values(1,38), (2,38), (3, 38); +insert into t1 values(1,37), (2,37), (3, 37); +insert into t1 values(1,36), (2,36), (3, 36); +insert into t1 values(1,35), (2,35), (3, 35); +insert into t1 values(1,34), (2,34), (3, 34); +insert into t1 values(1,33), (2,33), (3, 33); +insert into t1 values(1,32), (2,32), (3, 32); +insert into t1 values(1,31), (2,31), (3, 31); +insert into t1 values(1,30), (2,30), (3, 30); +insert into t1 values(1,29), (2,29), (3, 29); +insert into t1 values(1,28), (2,28), (3, 28); +insert into t1 values(1,27), (2,27), (3, 27); +insert into t1 values(1,26), (2,26), (3, 26); +insert into t1 values(1,25), (2,25), (3, 25); +insert into t1 values(1,24), (2,24), (3, 24); +insert into t1 values(1,23), (2,23), (3, 23); +insert into t1 values(1,22), (2,22), (3, 22); +insert into t1 values(1,21), (2,21), (3, 21); +insert into t1 values(1,20), (2,20), (3, 20); +insert into t1 values(1,19), (2,19), (3, 19); +insert into t1 values(1,18), (2,18), (3, 18); +insert into t1 values(1,17), (2,17), (3, 17); +insert into t1 values(1,16), (2,16), (3, 16); +insert into t1 values(1,15), (2,15), (3, 15); +insert into t1 values(1,14), (2,14), (3, 14); +insert into t1 values(1,13), (2,13), (3, 13); +insert into t1 values(1,12), (2,12), (3, 12); +insert into t1 values(1,11), (2,11), (3, 11); +insert into t1 values(1,10), (2,10), (3, 10); +insert into t1 values(1,9), (2,9), (3, 9); +insert into t1 values(1,8), (2,8), (3, 8); +insert into t1 values(1,7), (2,7), (3, 7); +insert into t1 values(1,6), (2,6), (3, 6); +insert into t1 values(1,5), (2,5), (3, 5); +insert into t1 values(1,4), (2,4), (3, 4); +insert into t1 values(1,3), (2,3), (3, 3); +insert into t1 values(1,2), (2,2), (3, 2); +insert into t1 values(1,1), (2,1), (3, 1); +alter table t1 add unique (a,b), add key (b); +show keys from t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 0 a 1 a A NULL NULL NULL YES BTREE +t1 0 a 2 b A NULL NULL NULL YES BTREE +t1 1 b 1 b A 100 NULL NULL YES BTREE +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK +show keys from t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 0 a 1 a A 3 NULL NULL YES BTREE +t1 0 a 2 b A 300 NULL NULL YES BTREE +t1 1 b 1 b A 100 NULL NULL YES BTREE +drop table t1; +CREATE TABLE t1 (i int(10), index(i) ); +ALTER TABLE t1 DISABLE KEYS; +INSERT DELAYED INTO t1 VALUES(1),(2),(3); +ALTER TABLE t1 ENABLE KEYS; +drop table t1; +set names koi8r; +create table t1 (a char(10) character set koi8r); +insert into t1 values ('ΤΕΣΤ'); +select a,hex(a) from t1; +a hex(a) +ΤΕΣΤ D4C5D3D4 +alter table t1 change a a char(10) character set cp1251; +select a,hex(a) from t1; +a hex(a) +ΤΕΣΤ F2E5F1F2 +alter table t1 change a a binary(10); +select a,hex(a) from t1; +a hex(a) +ςερς F2E5F1F2 +alter table t1 change a a char(10) character set cp1251; +select a,hex(a) from t1; +a hex(a) +ΤΕΣΤ F2E5F1F2 +alter table t1 change a a char(10) character set koi8r; +select a,hex(a) from t1; +a hex(a) +ΤΕΣΤ D4C5D3D4 +alter table t1 change a a varchar(10) character set cp1251; +select a,hex(a) from t1; +a hex(a) +ΤΕΣΤ F2E5F1F2 +alter table t1 change a a char(10) character set koi8r; +select a,hex(a) from t1; +a hex(a) +ΤΕΣΤ D4C5D3D4 +alter table t1 change a a text character set cp1251; +select a,hex(a) from t1; +a hex(a) +ΤΕΣΤ F2E5F1F2 +alter table t1 change a a char(10) character set koi8r; +select a,hex(a) from t1; +a hex(a) +ΤΕΣΤ D4C5D3D4 +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` char(10) character set koi8r default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +alter table t1 DEFAULT CHARACTER SET latin1; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` char(10) character set koi8r default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +alter table t1 CONVERT TO CHARACTER SET latin1; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` char(10) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +alter table t1 DEFAULT CHARACTER SET cp1251; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` char(10) character set latin1 default NULL +) ENGINE=MyISAM DEFAULT CHARSET=cp1251 +drop table t1; +create table t1 (myblob longblob,mytext longtext) +default charset latin1 collate latin1_general_cs; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `myblob` longblob, + `mytext` longtext collate latin1_general_cs +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_cs +alter table t1 character set latin2; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `myblob` longblob, + `mytext` longtext character set latin1 collate latin1_general_cs +) ENGINE=MyISAM DEFAULT CHARSET=latin2 +drop table t1; +CREATE TABLE t1 ( +Host varchar(16) binary NOT NULL default '', +User varchar(16) binary NOT NULL default '', +PRIMARY KEY (Host,User) +) ENGINE=MyISAM; +ALTER TABLE t1 DISABLE KEYS; +LOCK TABLES t1 WRITE; +INSERT INTO t1 VALUES ('localhost','root'),('localhost',''),('games','monty'); +SHOW INDEX FROM t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 0 PRIMARY 1 Host A NULL NULL NULL BTREE +t1 0 PRIMARY 2 User A 3 NULL NULL BTREE +ALTER TABLE t1 ENABLE KEYS; +UNLOCK TABLES; +CHECK TABLES t1; +Table Op Msg_type Msg_text +test.t1 check status OK +DROP TABLE t1; +CREATE TABLE t1 ( +Host varchar(16) binary NOT NULL default '', +User varchar(16) binary NOT NULL default '', +PRIMARY KEY (Host,User), +KEY (Host) +) ENGINE=MyISAM; +ALTER TABLE t1 DISABLE KEYS; +SHOW INDEX FROM t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 0 PRIMARY 1 Host A NULL NULL NULL BTREE +t1 0 PRIMARY 2 User A 0 NULL NULL BTREE +t1 1 Host 1 Host A NULL NULL NULL BTREE disabled +LOCK TABLES t1 WRITE; +INSERT INTO t1 VALUES ('localhost','root'),('localhost',''); +SHOW INDEX FROM t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 0 PRIMARY 1 Host A NULL NULL NULL BTREE +t1 0 PRIMARY 2 User A 2 NULL NULL BTREE +t1 1 Host 1 Host A NULL NULL NULL BTREE disabled +ALTER TABLE t1 ENABLE KEYS; +SHOW INDEX FROM t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 0 PRIMARY 1 Host A NULL NULL NULL BTREE +t1 0 PRIMARY 2 User A 2 NULL NULL BTREE +t1 1 Host 1 Host A 1 NULL NULL BTREE +UNLOCK TABLES; +CHECK TABLES t1; +Table Op Msg_type Msg_text +test.t1 check status OK +LOCK TABLES t1 WRITE; +ALTER TABLE t1 RENAME t2; +UNLOCK TABLES; +select * from t2; +Host User +localhost +localhost root +DROP TABLE t2; +CREATE TABLE t1 ( +Host varchar(16) binary NOT NULL default '', +User varchar(16) binary NOT NULL default '', +PRIMARY KEY (Host,User), +KEY (Host) +) ENGINE=MyISAM; +LOCK TABLES t1 WRITE; +ALTER TABLE t1 DISABLE KEYS; +SHOW INDEX FROM t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 0 PRIMARY 1 Host A NULL NULL NULL BTREE +t1 0 PRIMARY 2 User A 0 NULL NULL BTREE +t1 1 Host 1 Host A NULL NULL NULL BTREE disabled +DROP TABLE t1; +CREATE TABLE t1 (a int PRIMARY KEY, b INT UNIQUE); +ALTER TABLE t1 DROP PRIMARY KEY; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) NOT NULL default '0', + `b` int(11) default NULL, + UNIQUE KEY `b` (`b`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +ALTER TABLE t1 DROP PRIMARY KEY; +ERROR 42000: Can't DROP 'PRIMARY'; check that column/key exists +DROP TABLE t1; +create table t1 (a int, b int, key(a)); +insert into t1 values (1,1), (2,2); +alter table t1 drop key no_such_key; +ERROR 42000: Can't DROP 'no_such_key'; check that column/key exists +alter table t1 drop key a; +drop table t1; +create table t1 (a int); +alter table t1 rename to `t1\\`; +ERROR 42000: Incorrect table name 't1\\' +rename table t1 to `t1\\`; +ERROR 42000: Incorrect table name 't1\\' +drop table t1; diff --git a/mysql-test/r/drop_temp_table.result.es b/mysql-test/r/drop_temp_table.result.es new file mode 100644 index 00000000000..4497022520e --- /dev/null +++ b/mysql-test/r/drop_temp_table.result.es @@ -0,0 +1,12 @@ +reset master; +create database `drop-temp+table-test`; +use `drop-temp+table-test`; +create temporary table `table:name` (a int); +select get_lock("a",10); +get_lock("a",10) +1 +select get_lock("a",10); +get_lock("a",10) +1 +show binlog events; +drop database `drop-temp+table-test`; diff --git a/mysql-test/r/insert_select.result.es b/mysql-test/r/insert_select.result.es new file mode 100644 index 00000000000..3955c0534f2 --- /dev/null +++ b/mysql-test/r/insert_select.result.es @@ -0,0 +1,628 @@ +drop table if exists t1,t2; +create table t1 (bandID MEDIUMINT UNSIGNED NOT NULL PRIMARY KEY, payoutID SMALLINT UNSIGNED NOT NULL); +insert into t1 (bandID,payoutID) VALUES (1,6),(2,6),(3,4),(4,9),(5,10),(6,1),(7,12),(8,12); +create table t2 (payoutID SMALLINT UNSIGNED NOT NULL PRIMARY KEY); +insert into t2 (payoutID) SELECT DISTINCT payoutID FROM t1; +insert into t2 (payoutID) SELECT payoutID+10 FROM t1; +ERROR 23000: Duplicate entry '16' for key 1 +insert ignore into t2 (payoutID) SELECT payoutID+10 FROM t1; +select * from t2; +payoutID +1 +4 +6 +9 +10 +11 +12 +14 +16 +19 +20 +22 +drop table t1,t2; +CREATE TABLE `t1` ( +`numeropost` bigint(20) unsigned NOT NULL default '0', +`icone` tinyint(4) unsigned NOT NULL default '0', +`numreponse` bigint(20) unsigned NOT NULL auto_increment, +`contenu` text NOT NULL, +`pseudo` varchar(50) NOT NULL default '', +`date` datetime NOT NULL default '0000-00-00 00:00:00', +`ip` bigint(11) NOT NULL default '0', +`signature` tinyint(1) unsigned NOT NULL default '0', +PRIMARY KEY (`numeropost`,`numreponse`) +,KEY `ip` (`ip`), +KEY `date` (`date`), +KEY `pseudo` (`pseudo`), +KEY `numreponse` (`numreponse`) +) ENGINE=MyISAM; +CREATE TABLE `t2` ( +`numeropost` bigint(20) unsigned NOT NULL default '0', +`icone` tinyint(4) unsigned NOT NULL default '0', +`numreponse` bigint(20) unsigned NOT NULL auto_increment, +`contenu` text NOT NULL, +`pseudo` varchar(50) NOT NULL default '', +`date` datetime NOT NULL default '0000-00-00 00:00:00', +`ip` bigint(11) NOT NULL default '0', +`signature` tinyint(1) unsigned NOT NULL default '0', +PRIMARY KEY (`numeropost`,`numreponse`), +KEY `ip` (`ip`), +KEY `date` (`date`), +KEY `pseudo` (`pseudo`), +KEY `numreponse` (`numreponse`) +) ENGINE=MyISAM; +INSERT INTO t2 +(numeropost,icone,numreponse,contenu,pseudo,date,ip,signature) VALUES +(9,1,56,'test','joce','2001-07-25 13:50:53' +,3649052399,0); +INSERT INTO t1 (numeropost,icone,contenu,pseudo,date,signature,ip) +SELECT 1618,icone,contenu,pseudo,date,signature,ip FROM t2 +WHERE numeropost=9 ORDER BY numreponse ASC; +show variables like '%bulk%'; +Variable_name Value +bulk_insert_buffer_size 8388608 +INSERT INTO t1 (numeropost,icone,contenu,pseudo,date,signature,ip) +SELECT 1718,icone,contenu,pseudo,date,signature,ip FROM t2 +WHERE numeropost=9 ORDER BY numreponse ASC; +DROP TABLE t1,t2; +create table t1(a int, unique(a)); +insert into t1 values(2); +create table t2(a int); +insert into t2 values(1),(2); +reset master; +insert into t1 select * from t2; +ERROR 23000: Duplicate entry '2' for key 1 +show binlog events; +select * from t1; +a +1 +2 +drop table t1, t2; +create table t1 (a int not null); +create table t2 (a int not null); +insert into t1 values (1); +insert into t1 values (a+2); +insert into t1 values (a+3); +insert into t1 values (4),(a+5); +insert into t1 select * from t1; +select * from t1; +a +1 +2 +3 +4 +5 +1 +2 +3 +4 +5 +insert into t1 select * from t1 as t2; +select * from t1; +a +1 +2 +3 +4 +5 +1 +2 +3 +4 +5 +1 +2 +3 +4 +5 +1 +2 +3 +4 +5 +insert into t2 select * from t1 as t2; +select * from t1; +a +1 +2 +3 +4 +5 +1 +2 +3 +4 +5 +1 +2 +3 +4 +5 +1 +2 +3 +4 +5 +insert into t1 select t2.a from t1,t2; +select * from t1; +a +1 +2 +3 +4 +5 +1 +2 +3 +4 +5 +1 +2 +3 +4 +5 +1 +2 +3 +4 +5 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +insert into t1 select * from t1,t1; +ERROR 42000: Not unique table/alias: 't1' +drop table t1,t2; +create table t1 (a int not null primary key, b char(10)); +create table t2 (a int not null, b char(10)); +insert into t1 values (1,"t1:1"),(3,"t1:3"); +insert into t2 values (2,"t2:2"), (3,"t2:3"); +insert into t1 select * from t2; +ERROR 23000: Duplicate entry '3' for key 1 +select * from t1; +a b +1 t1:1 +3 t1:3 +2 t2:2 +replace into t1 select * from t2; +select * from t1; +a b +1 t1:1 +3 t2:3 +2 t2:2 +drop table t1,t2; +CREATE TABLE t1 ( USID INTEGER UNSIGNED, ServerID TINYINT UNSIGNED, State ENUM ('unknown', 'Access-Granted', 'Session-Active', 'Session-Closed' ) NOT NULL DEFAULT 'unknown', SessionID CHAR(32), User CHAR(32) NOT NULL DEFAULT '', NASAddr INTEGER UNSIGNED, NASPort INTEGER UNSIGNED, NASPortType INTEGER UNSIGNED, ConnectSpeed INTEGER UNSIGNED, CarrierType CHAR(32), CallingStationID CHAR(32), CalledStationID CHAR(32), AssignedAddr INTEGER UNSIGNED, SessionTime INTEGER UNSIGNED, PacketsIn INTEGER UNSIGNED, OctetsIn INTEGER UNSIGNED, PacketsOut INTEGER UNSIGNED, OctetsOut INTEGER UNSIGNED, TerminateCause INTEGER UNSIGNED, UnauthTime TINYINT UNSIGNED, AccessRequestTime DATETIME, AcctStartTime DATETIME, AcctLastTime DATETIME, LastModification TIMESTAMP NOT NULL); +CREATE TABLE t2 ( USID INTEGER UNSIGNED AUTO_INCREMENT, ServerID TINYINT UNSIGNED, State ENUM ('unknown', 'Access-Granted', 'Session-Active', 'Session-Closed' ) NOT NULL DEFAULT 'unknown', SessionID CHAR(32), User TEXT NOT NULL, NASAddr INTEGER UNSIGNED, NASPort INTEGER UNSIGNED, NASPortType INTEGER UNSIGNED, ConnectSpeed INTEGER UNSIGNED, CarrierType CHAR(32), CallingStationID CHAR(32), CalledStationID CHAR(32), AssignedAddr INTEGER UNSIGNED, SessionTime INTEGER UNSIGNED, PacketsIn INTEGER UNSIGNED, OctetsIn INTEGER UNSIGNED, PacketsOut INTEGER UNSIGNED, OctetsOut INTEGER UNSIGNED, TerminateCause INTEGER UNSIGNED, UnauthTime TINYINT UNSIGNED, AccessRequestTime DATETIME, AcctStartTime DATETIME, AcctLastTime DATETIME, LastModification TIMESTAMP NOT NULL, INDEX(USID,ServerID,NASAddr,SessionID), INDEX(AssignedAddr)); +INSERT INTO t1 VALUES (39,42,'Access-Granted','46','491721000045',2130706433,17690,NULL,NULL,'Localnet','491721000045','49172200000',754974766,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'2003-07-18 00:11:21',NULL,NULL,20030718001121); +INSERT INTO t2 SELECT USID, ServerID, State, SessionID, User, NASAddr, NASPort, NASPortType, ConnectSpeed, CarrierType, CallingStationID, CalledStationID, AssignedAddr, SessionTime, PacketsIn, OctetsIn, PacketsOut, OctetsOut, TerminateCause, UnauthTime, AccessRequestTime, AcctStartTime, AcctLastTime, LastModification from t1 LIMIT 1; +drop table t1,t2; +CREATE TABLE t1( +Month date NOT NULL, +Type tinyint(3) unsigned NOT NULL auto_increment, +Field int(10) unsigned NOT NULL, +Count int(10) unsigned NOT NULL, +UNIQUE KEY Month (Month,Type,Field) +); +insert into t1 Values +(20030901, 1, 1, 100), +(20030901, 1, 2, 100), +(20030901, 2, 1, 100), +(20030901, 2, 2, 100), +(20030901, 3, 1, 100); +select * from t1; +Month Type Field Count +2003-09-01 1 1 100 +2003-09-01 1 2 100 +2003-09-01 2 1 100 +2003-09-01 2 2 100 +2003-09-01 3 1 100 +Select null, Field, Count From t1 Where Month=20030901 and Type=2; +NULL Field Count +NULL 1 100 +NULL 2 100 +create table t2(No int not null, Field int not null, Count int not null); +insert into t2 Select null, Field, Count From t1 Where Month=20030901 and Type=2; +Warnings: +Warning 1263 Data truncated; NULL supplied to NOT NULL column 'No' at row 1 +Warning 1263 Data truncated; NULL supplied to NOT NULL column 'No' at row 2 +select * from t2; +No Field Count +0 1 100 +0 2 100 +drop table t1, t2; diff --git a/mysql-test/r/ndb_alter_table.result b/mysql-test/r/ndb_alter_table.result index 8143e34ecc2..2ee1bf4497b 100644 --- a/mysql-test/r/ndb_alter_table.result +++ b/mysql-test/r/ndb_alter_table.result @@ -72,4 +72,82 @@ col6 col1 col3 fourth col4 col4_5 col5 col7 col8 1 100 3 4 5 PENDING 0000-00-00 00:00:00 1 101 3 4 5 PENDING 0000-00-00 00:00:00 2 102 4 3 5 99 PENDING EXTRA 2004-01-01 00:00:00 +delete from t1; +insert into t1 values (0,0,4,3,5,99,"PENDING","EXTRA",'2004-01-01 00:00:00'); +SET SQL_MODE=''; +insert into t1 values (1,0,4,3,5,99,"PENDING","EXTRA",'2004-01-01 00:00:00'); +select * from t1 order by col1; +col6 col1 col3 fourth col4 col4_5 col5 col7 col8 +0 0 4 3 5 99 PENDING EXTRA 2004-01-01 00:00:00 +1 103 4 3 5 99 PENDING EXTRA 2004-01-01 00:00:00 +alter table t1 drop column col4_5; +insert into t1 values (2,0,4,3,5,"PENDING","EXTRA",'2004-01-01 00:00:00'); +select * from t1 order by col1; +col6 col1 col3 fourth col4 col5 col7 col8 +0 0 4 3 5 PENDING EXTRA 2004-01-01 00:00:00 +1 103 4 3 5 PENDING EXTRA 2004-01-01 00:00:00 +2 104 4 3 5 PENDING EXTRA 2004-01-01 00:00:00 +drop table t1; +CREATE TABLE t1 ( +a INT NOT NULL, +b INT NOT NULL +) ENGINE=ndbcluster; +INSERT INTO t1 VALUES (9410,9412); +ALTER TABLE t1 ADD COLUMN c int not null; +select * from t1 order by a; +a b c +9410 9412 0 +select * from t1 order by a; +a b c +9410 9412 0 +alter table t1 drop c; +select * from t1 order by a; +a b +9410 9412 +drop table t1; +select * from t1 order by a; +ERROR 42S02: Table 'test.t1' doesn't exist +CREATE TABLE t1 ( +a INT NOT NULL PRIMARY KEY, +b INT NOT NULL +) ENGINE=ndbcluster; +INSERT INTO t1 VALUES (0,1),(17,18); +select * from t1 order by a; +a b +0 1 +17 18 +alter table t1 modify column a int not null auto_increment; +select * from t1 order by a; +a b +0 1 +17 18 +INSERT INTO t1 VALUES (0,19),(20,21); +select * from t1 order by a; +a b +0 1 +17 18 +18 19 +20 21 +drop table t1; +CREATE TABLE t1 ( +a INT NOT NULL PRIMARY KEY, +b INT NOT NULL +) ENGINE=ndbcluster; +INSERT INTO t1 VALUES (0,1),(17,18); +select * from t1; +a b +17 18 +0 1 +alter table t1 add c int not null unique auto_increment; +select * from t1 order by a; +a b c +0 1 2 +17 18 1 +INSERT INTO t1 VALUES (18,19,3),(20,21,0); +select * from t1 order by a; +a b c +0 1 2 +17 18 1 +18 19 3 +20 21 4 drop table t1; diff --git a/mysql-test/r/ndb_charset.result b/mysql-test/r/ndb_charset.result new file mode 100644 index 00000000000..93429a1fcb0 --- /dev/null +++ b/mysql-test/r/ndb_charset.result @@ -0,0 +1,191 @@ +drop table if exists t1; +create table t1 ( +a char(3) character set latin1 collate latin1_bin primary key +) engine=ndb; +insert into t1 values('aAa'); +insert into t1 values('aaa'); +insert into t1 values('AAA'); +select * from t1 order by a; +a +AAA +aAa +aaa +select * from t1 where a = 'aAa'; +a +aAa +select * from t1 where a = 'aaa'; +a +aaa +select * from t1 where a = 'AaA'; +a +select * from t1 where a = 'AAA'; +a +AAA +drop table t1; +create table t1 ( +a char(3) character set latin1 collate latin1_swedish_ci primary key +) engine=ndb; +insert into t1 values('aAa'); +insert into t1 values('aaa'); +ERROR 23000: Duplicate entry 'aaa' for key 1 +insert into t1 values('AAA'); +ERROR 23000: Duplicate entry 'AAA' for key 1 +select * from t1 order by a; +a +aAa +select * from t1 where a = 'aAa'; +a +aAa +select * from t1 where a = 'aaa'; +a +aAa +select * from t1 where a = 'AaA'; +a +aAa +select * from t1 where a = 'AAA'; +a +aAa +drop table t1; +create table t1 ( +p int primary key, +a char(3) character set latin1 collate latin1_bin not null, +unique key(a) +) engine=ndb; +insert into t1 values(1, 'aAa'); +insert into t1 values(2, 'aaa'); +insert into t1 values(3, 'AAA'); +select * from t1 order by p; +p a +1 aAa +2 aaa +3 AAA +select * from t1 where a = 'aAa'; +p a +1 aAa +select * from t1 where a = 'aaa'; +p a +2 aaa +select * from t1 where a = 'AaA'; +p a +select * from t1 where a = 'AAA'; +p a +3 AAA +drop table t1; +create table t1 ( +p int primary key, +a char(3) character set latin1 collate latin1_swedish_ci not null, +unique key(a) +) engine=ndb; +insert into t1 values(1, 'aAa'); +insert into t1 values(2, 'aaa'); +ERROR 23000: Can't write, because of unique constraint, to table 't1' +insert into t1 values(3, 'AAA'); +ERROR 23000: Can't write, because of unique constraint, to table 't1' +select * from t1 order by p; +p a +1 aAa +select * from t1 where a = 'aAa'; +p a +1 aAa +select * from t1 where a = 'aaa'; +p a +1 aAa +select * from t1 where a = 'AaA'; +p a +1 aAa +select * from t1 where a = 'AAA'; +p a +1 aAa +drop table t1; +create table t1 ( +p int primary key, +a char(3) character set latin1 collate latin1_bin not null, +index(a) +) engine=ndb; +insert into t1 values(1, 'aAa'); +insert into t1 values(2, 'aaa'); +insert into t1 values(3, 'AAA'); +insert into t1 values(4, 'aAa'); +insert into t1 values(5, 'aaa'); +insert into t1 values(6, 'AAA'); +select * from t1 order by p; +p a +1 aAa +2 aaa +3 AAA +4 aAa +5 aaa +6 AAA +explain select * from t1 where a = 'zZz' order by p; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref a a 3 const 10 Using where; Using filesort +select * from t1 where a = 'aAa' order by p; +p a +1 aAa +4 aAa +select * from t1 where a = 'aaa' order by p; +p a +2 aaa +5 aaa +select * from t1 where a = 'AaA' order by p; +p a +select * from t1 where a = 'AAA' order by p; +p a +3 AAA +6 AAA +drop table t1; +create table t1 ( +p int primary key, +a char(3) character set latin1 collate latin1_swedish_ci not null, +index(a) +) engine=ndb; +insert into t1 values(1, 'aAa'); +insert into t1 values(2, 'aaa'); +insert into t1 values(3, 'AAA'); +insert into t1 values(4, 'aAa'); +insert into t1 values(5, 'aaa'); +insert into t1 values(6, 'AAA'); +select * from t1 order by p; +p a +1 aAa +2 aaa +3 AAA +4 aAa +5 aaa +6 AAA +explain select * from t1 where a = 'zZz' order by p; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref a a 3 const 10 Using where; Using filesort +select * from t1 where a = 'aAa' order by p; +p a +1 aAa +2 aaa +3 AAA +4 aAa +5 aaa +6 AAA +select * from t1 where a = 'aaa' order by p; +p a +1 aAa +2 aaa +3 AAA +4 aAa +5 aaa +6 AAA +select * from t1 where a = 'AaA' order by p; +p a +1 aAa +2 aaa +3 AAA +4 aAa +5 aaa +6 AAA +select * from t1 where a = 'AAA' order by p; +p a +1 aAa +2 aaa +3 AAA +4 aAa +5 aaa +6 AAA +drop table t1; diff --git a/mysql-test/r/ndb_index.result b/mysql-test/r/ndb_index.result index dd92c237ace..5702552b0b5 100644 --- a/mysql-test/r/ndb_index.result +++ b/mysql-test/r/ndb_index.result @@ -4,7 +4,7 @@ PORT varchar(16) NOT NULL, ACCESSNODE varchar(16) NOT NULL, POP varchar(48) NOT NULL, ACCESSTYPE int unsigned NOT NULL, -CUSTOMER_ID varchar(20) NOT NULL, +CUSTOMER_ID varchar(20) collate latin1_bin NOT NULL, PROVIDER varchar(16), TEXPIRE int unsigned, NUM_IP int unsigned, diff --git a/mysql-test/r/packet.result.es b/mysql-test/r/packet.result.es new file mode 100644 index 00000000000..0ff587b3957 --- /dev/null +++ b/mysql-test/r/packet.result.es @@ -0,0 +1,26 @@ +set global max_allowed_packet=100; +set max_allowed_packet=100; +set global net_buffer_length=100; +set net_buffer_length=100; +SELECT length("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") as len; +len +1024 +select repeat('a',2000); +repeat('a',2000) +NULL +Warnings: +Warning 1301 Result of repeat() was larger than max_allowed_packet (1024) - truncated +select @@net_buffer_length, @@max_allowed_packet; +@@net_buffer_length @@max_allowed_packet +1024 1024 +SELECT length("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") as len; +set global max_allowed_packet=default; +set max_allowed_packet=default; +set global net_buffer_length=default; +set net_buffer_length=default; +SELECT length("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") as len; +len +100 +select length(repeat('a',2000)); +length(repeat('a',2000)) +2000 diff --git a/mysql-test/r/ps_2myisam.result b/mysql-test/r/ps_2myisam.result index ee861b257ea..68e0a53fdba 100644 --- a/mysql-test/r/ps_2myisam.result +++ b/mysql-test/r/ps_2myisam.result @@ -908,53 +908,11 @@ FROM t9, (select c25 x, c32 y from t2) tt WHERE x = c25 ' ; prepare stmt1 from @stmt ; execute stmt1 ; -Catalog Database Table Table_alias Column Column_alias Name Type Length Max length Is_null Flags Decimals Charsetnr -def scalar_s 5 21 7 Y 32768 4 8 -def exists_s 8 1 1 N 32769 0 8 -def in_s 8 21 1 Y 32768 0 8 -def in_row_s 8 21 1 Y 32768 0 8 -scalar_s exists_s in_s in_row_s -2.0000 0 1 0 -18.0000 1 0 1 -2.0000 0 1 0 -18.0000 1 0 1 execute stmt1 ; -scalar_s exists_s in_s in_row_s -2.0000 0 1 0 -18.0000 1 0 1 -2.0000 0 1 0 -18.0000 1 0 1 set @stmt= concat('explain ',@stmt); prepare stmt1 from @stmt ; execute stmt1 ; -Catalog Database Table Table_alias Column Column_alias Name Type Length Max length Is_null Flags Decimals Charsetnr -def id 8 3 1 N 32801 0 8 -def select_type 253 19 18 N 1 31 8 -def table 253 64 10 N 1 31 8 -def type 253 10 3 N 1 31 8 -def possible_keys 253 4096 0 Y 0 31 8 -def key 253 64 0 Y 0 31 8 -def key_len 8 3 0 Y 32800 0 8 -def ref 253 1024 0 Y 0 31 8 -def rows 8 10 1 N 32801 0 8 -def Extra 253 255 44 N 1 31 8 -id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t9 ALL NULL NULL NULL NULL 2 -1 PRIMARY ALL NULL NULL NULL NULL 2 Using where -6 DERIVED t2 ALL NULL NULL NULL NULL 2 -5 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -4 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -3 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where; Using temporary; Using filesort execute stmt1 ; -id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t9 ALL NULL NULL NULL NULL 2 -1 PRIMARY ALL NULL NULL NULL NULL 2 Using where -6 DERIVED t2 ALL NULL NULL NULL NULL 2 -5 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -4 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -3 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where; Using temporary; Using filesort set @stmt= ' SELECT (SELECT SUM(c1+c12+?) FROM t2 where (t9.c2-?)=t2.c2 GROUP BY t9.c15 LIMIT 1) as scalar_s, @@ -977,56 +935,14 @@ set @arg09= 40e-1 ; prepare stmt1 from @stmt ; execute stmt1 using @arg00, @arg01, @arg02, @arg03, @arg04, @arg05, @arg06, @arg07, @arg08, @arg09 ; -Catalog Database Table Table_alias Column Column_alias Name Type Length Max length Is_null Flags Decimals Charsetnr -def scalar_s 5 23 2 Y 32768 31 8 -def exists_s 8 1 1 N 32769 0 8 -def in_s 8 21 1 Y 32768 0 8 -def in_row_s 8 21 1 Y 32768 0 8 -scalar_s exists_s in_s in_row_s -2 0 1 0 -18 1 0 1 -2 0 1 0 -18 1 0 1 execute stmt1 using @arg00, @arg01, @arg02, @arg03, @arg04, @arg05, @arg06, @arg07, @arg08, @arg09 ; -scalar_s exists_s in_s in_row_s -2 0 1 0 -18 1 0 1 -2 0 1 0 -18 1 0 1 set @stmt= concat('explain ',@stmt); prepare stmt1 from @stmt ; execute stmt1 using @arg00, @arg01, @arg02, @arg03, @arg04, @arg05, @arg06, @arg07, @arg08, @arg09 ; -Catalog Database Table Table_alias Column Column_alias Name Type Length Max length Is_null Flags Decimals Charsetnr -def id 8 3 1 N 32801 0 8 -def select_type 253 19 18 N 1 31 8 -def table 253 64 10 N 1 31 8 -def type 253 10 3 N 1 31 8 -def possible_keys 253 4096 0 Y 0 31 8 -def key 253 64 0 Y 0 31 8 -def key_len 8 3 0 Y 32800 0 8 -def ref 253 1024 0 Y 0 31 8 -def rows 8 10 1 N 32801 0 8 -def Extra 253 255 44 N 1 31 8 -id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t9 ALL NULL NULL NULL NULL 2 -1 PRIMARY ALL NULL NULL NULL NULL 2 Using where -6 DERIVED t2 ALL NULL NULL NULL NULL 2 -5 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -4 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -3 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where; Using temporary; Using filesort execute stmt1 using @arg00, @arg01, @arg02, @arg03, @arg04, @arg05, @arg06, @arg07, @arg08, @arg09 ; -id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t9 ALL NULL NULL NULL NULL 2 -1 PRIMARY ALL NULL NULL NULL NULL 2 Using where -6 DERIVED t2 ALL NULL NULL NULL NULL 2 -5 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -4 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -3 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where; Using temporary; Using filesort drop table t2 ; select 1 < (select a from t1) ; ERROR 21000: Subquery returns more than 1 row @@ -3192,17 +3108,21 @@ found true set @arg00= 1.991e+3 ; select 'true' as found from t9 -where c1= 20 and c17= 1.991e+3 ; +where c1= 20 and abs(c17 - 1.991e+3) < 0.01 ; found +true select 'true' as found from t9 -where c1= 20 and c17= @arg00 ; +where c1= 20 and abs(c17 - @arg00) < 0.01 ; found +true prepare stmt1 from "select 'true' as found from t9 -where c1= 20 and c17= 1.991e+3" ; +where c1= 20 and abs(c17 - 1.991e+3) < 0.01" ; execute stmt1 ; found +true prepare stmt1 from "select 'true' as found from t9 -where c1= 20 and c17= ?" ; +where c1= 20 and abs(c17 - ?) < 0.01" ; execute stmt1 using @arg00 ; found +true drop table t1, t9; diff --git a/mysql-test/r/ps_3innodb.result b/mysql-test/r/ps_3innodb.result index 33b793d91e6..90cd5e39f9c 100644 --- a/mysql-test/r/ps_3innodb.result +++ b/mysql-test/r/ps_3innodb.result @@ -908,53 +908,11 @@ FROM t9, (select c25 x, c32 y from t2) tt WHERE x = c25 ' ; prepare stmt1 from @stmt ; execute stmt1 ; -Catalog Database Table Table_alias Column Column_alias Name Type Length Max length Is_null Flags Decimals Charsetnr -def scalar_s 5 21 7 Y 32768 4 8 -def exists_s 8 1 1 N 32769 0 8 -def in_s 8 21 1 Y 32768 0 8 -def in_row_s 8 21 1 Y 32768 0 8 -scalar_s exists_s in_s in_row_s -2.0000 0 1 0 -18.0000 1 0 1 -2.0000 0 1 0 -18.0000 1 0 1 execute stmt1 ; -scalar_s exists_s in_s in_row_s -2.0000 0 1 0 -18.0000 1 0 1 -2.0000 0 1 0 -18.0000 1 0 1 set @stmt= concat('explain ',@stmt); prepare stmt1 from @stmt ; execute stmt1 ; -Catalog Database Table Table_alias Column Column_alias Name Type Length Max length Is_null Flags Decimals Charsetnr -def id 8 3 1 N 32801 0 8 -def select_type 253 19 18 N 1 31 8 -def table 253 64 10 N 1 31 8 -def type 253 10 3 N 1 31 8 -def possible_keys 253 4096 0 Y 0 31 8 -def key 253 64 0 Y 0 31 8 -def key_len 8 3 0 Y 32800 0 8 -def ref 253 1024 0 Y 0 31 8 -def rows 8 10 1 N 32801 0 8 -def Extra 253 255 44 N 1 31 8 -id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t9 ALL NULL NULL NULL NULL 2 -1 PRIMARY ALL NULL NULL NULL NULL 2 Using where -6 DERIVED t2 ALL NULL NULL NULL NULL 2 -5 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -4 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -3 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where; Using temporary; Using filesort execute stmt1 ; -id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t9 ALL NULL NULL NULL NULL 2 -1 PRIMARY ALL NULL NULL NULL NULL 2 Using where -6 DERIVED t2 ALL NULL NULL NULL NULL 2 -5 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -4 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -3 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where; Using temporary; Using filesort set @stmt= ' SELECT (SELECT SUM(c1+c12+?) FROM t2 where (t9.c2-?)=t2.c2 GROUP BY t9.c15 LIMIT 1) as scalar_s, @@ -977,56 +935,14 @@ set @arg09= 40e-1 ; prepare stmt1 from @stmt ; execute stmt1 using @arg00, @arg01, @arg02, @arg03, @arg04, @arg05, @arg06, @arg07, @arg08, @arg09 ; -Catalog Database Table Table_alias Column Column_alias Name Type Length Max length Is_null Flags Decimals Charsetnr -def scalar_s 5 23 2 Y 32768 31 8 -def exists_s 8 1 1 N 32769 0 8 -def in_s 8 21 1 Y 32768 0 8 -def in_row_s 8 21 1 Y 32768 0 8 -scalar_s exists_s in_s in_row_s -2 0 1 0 -18 1 0 1 -2 0 1 0 -18 1 0 1 execute stmt1 using @arg00, @arg01, @arg02, @arg03, @arg04, @arg05, @arg06, @arg07, @arg08, @arg09 ; -scalar_s exists_s in_s in_row_s -2 0 1 0 -18 1 0 1 -2 0 1 0 -18 1 0 1 set @stmt= concat('explain ',@stmt); prepare stmt1 from @stmt ; execute stmt1 using @arg00, @arg01, @arg02, @arg03, @arg04, @arg05, @arg06, @arg07, @arg08, @arg09 ; -Catalog Database Table Table_alias Column Column_alias Name Type Length Max length Is_null Flags Decimals Charsetnr -def id 8 3 1 N 32801 0 8 -def select_type 253 19 18 N 1 31 8 -def table 253 64 10 N 1 31 8 -def type 253 10 3 N 1 31 8 -def possible_keys 253 4096 0 Y 0 31 8 -def key 253 64 0 Y 0 31 8 -def key_len 8 3 0 Y 32800 0 8 -def ref 253 1024 0 Y 0 31 8 -def rows 8 10 1 N 32801 0 8 -def Extra 253 255 44 N 1 31 8 -id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t9 ALL NULL NULL NULL NULL 2 -1 PRIMARY ALL NULL NULL NULL NULL 2 Using where -6 DERIVED t2 ALL NULL NULL NULL NULL 2 -5 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -4 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -3 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where; Using temporary; Using filesort execute stmt1 using @arg00, @arg01, @arg02, @arg03, @arg04, @arg05, @arg06, @arg07, @arg08, @arg09 ; -id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t9 ALL NULL NULL NULL NULL 2 -1 PRIMARY ALL NULL NULL NULL NULL 2 Using where -6 DERIVED t2 ALL NULL NULL NULL NULL 2 -5 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -4 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -3 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where; Using temporary; Using filesort drop table t2 ; select 1 < (select a from t1) ; ERROR 21000: Subquery returns more than 1 row @@ -3175,17 +3091,21 @@ found true set @arg00= 1.991e+3 ; select 'true' as found from t9 -where c1= 20 and c17= 1.991e+3 ; +where c1= 20 and abs(c17 - 1.991e+3) < 0.01 ; found +true select 'true' as found from t9 -where c1= 20 and c17= @arg00 ; +where c1= 20 and abs(c17 - @arg00) < 0.01 ; found +true prepare stmt1 from "select 'true' as found from t9 -where c1= 20 and c17= 1.991e+3" ; +where c1= 20 and abs(c17 - 1.991e+3) < 0.01" ; execute stmt1 ; found +true prepare stmt1 from "select 'true' as found from t9 -where c1= 20 and c17= ?" ; +where c1= 20 and abs(c17 - ?) < 0.01" ; execute stmt1 using @arg00 ; found +true drop table t1, t9; diff --git a/mysql-test/r/ps_4heap.result b/mysql-test/r/ps_4heap.result index b2d01af019f..feef6bcf83e 100644 --- a/mysql-test/r/ps_4heap.result +++ b/mysql-test/r/ps_4heap.result @@ -909,53 +909,11 @@ FROM t9, (select c25 x, c32 y from t2) tt WHERE x = c25 ' ; prepare stmt1 from @stmt ; execute stmt1 ; -Catalog Database Table Table_alias Column Column_alias Name Type Length Max length Is_null Flags Decimals Charsetnr -def scalar_s 5 21 7 Y 32768 4 8 -def exists_s 8 1 1 N 32769 0 8 -def in_s 8 21 1 Y 32768 0 8 -def in_row_s 8 21 1 Y 32768 0 8 -scalar_s exists_s in_s in_row_s -2.0000 0 1 0 -18.0000 1 0 1 -2.0000 0 1 0 -18.0000 1 0 1 execute stmt1 ; -scalar_s exists_s in_s in_row_s -2.0000 0 1 0 -18.0000 1 0 1 -2.0000 0 1 0 -18.0000 1 0 1 set @stmt= concat('explain ',@stmt); prepare stmt1 from @stmt ; execute stmt1 ; -Catalog Database Table Table_alias Column Column_alias Name Type Length Max length Is_null Flags Decimals Charsetnr -def id 8 3 1 N 32801 0 8 -def select_type 253 19 18 N 1 31 8 -def table 253 64 10 N 1 31 8 -def type 253 10 3 N 1 31 8 -def possible_keys 253 4096 0 Y 0 31 8 -def key 253 64 0 Y 0 31 8 -def key_len 8 3 0 Y 32800 0 8 -def ref 253 1024 0 Y 0 31 8 -def rows 8 10 1 N 32801 0 8 -def Extra 253 255 44 N 1 31 8 -id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t9 ALL NULL NULL NULL NULL 2 -1 PRIMARY ALL NULL NULL NULL NULL 2 Using where -6 DERIVED t2 ALL NULL NULL NULL NULL 2 -5 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -4 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -3 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where; Using temporary; Using filesort execute stmt1 ; -id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t9 ALL NULL NULL NULL NULL 2 -1 PRIMARY ALL NULL NULL NULL NULL 2 Using where -6 DERIVED t2 ALL NULL NULL NULL NULL 2 -5 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -4 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -3 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where; Using temporary; Using filesort set @stmt= ' SELECT (SELECT SUM(c1+c12+?) FROM t2 where (t9.c2-?)=t2.c2 GROUP BY t9.c15 LIMIT 1) as scalar_s, @@ -978,56 +936,14 @@ set @arg09= 40e-1 ; prepare stmt1 from @stmt ; execute stmt1 using @arg00, @arg01, @arg02, @arg03, @arg04, @arg05, @arg06, @arg07, @arg08, @arg09 ; -Catalog Database Table Table_alias Column Column_alias Name Type Length Max length Is_null Flags Decimals Charsetnr -def scalar_s 5 23 2 Y 32768 31 8 -def exists_s 8 1 1 N 32769 0 8 -def in_s 8 21 1 Y 32768 0 8 -def in_row_s 8 21 1 Y 32768 0 8 -scalar_s exists_s in_s in_row_s -2 0 1 0 -18 1 0 1 -2 0 1 0 -18 1 0 1 execute stmt1 using @arg00, @arg01, @arg02, @arg03, @arg04, @arg05, @arg06, @arg07, @arg08, @arg09 ; -scalar_s exists_s in_s in_row_s -2 0 1 0 -18 1 0 1 -2 0 1 0 -18 1 0 1 set @stmt= concat('explain ',@stmt); prepare stmt1 from @stmt ; execute stmt1 using @arg00, @arg01, @arg02, @arg03, @arg04, @arg05, @arg06, @arg07, @arg08, @arg09 ; -Catalog Database Table Table_alias Column Column_alias Name Type Length Max length Is_null Flags Decimals Charsetnr -def id 8 3 1 N 32801 0 8 -def select_type 253 19 18 N 1 31 8 -def table 253 64 10 N 1 31 8 -def type 253 10 3 N 1 31 8 -def possible_keys 253 4096 0 Y 0 31 8 -def key 253 64 0 Y 0 31 8 -def key_len 8 3 0 Y 32800 0 8 -def ref 253 1024 0 Y 0 31 8 -def rows 8 10 1 N 32801 0 8 -def Extra 253 255 44 N 1 31 8 -id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t9 ALL NULL NULL NULL NULL 2 -1 PRIMARY ALL NULL NULL NULL NULL 2 Using where -6 DERIVED t2 ALL NULL NULL NULL NULL 2 -5 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -4 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -3 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where; Using temporary; Using filesort execute stmt1 using @arg00, @arg01, @arg02, @arg03, @arg04, @arg05, @arg06, @arg07, @arg08, @arg09 ; -id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t9 ALL NULL NULL NULL NULL 2 -1 PRIMARY ALL NULL NULL NULL NULL 2 Using where -6 DERIVED t2 ALL NULL NULL NULL NULL 2 -5 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -4 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -3 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where; Using temporary; Using filesort drop table t2 ; select 1 < (select a from t1) ; ERROR 21000: Subquery returns more than 1 row @@ -3176,17 +3092,21 @@ found true set @arg00= 1.991e+3 ; select 'true' as found from t9 -where c1= 20 and c17= 1.991e+3 ; +where c1= 20 and abs(c17 - 1.991e+3) < 0.01 ; found +true select 'true' as found from t9 -where c1= 20 and c17= @arg00 ; +where c1= 20 and abs(c17 - @arg00) < 0.01 ; found +true prepare stmt1 from "select 'true' as found from t9 -where c1= 20 and c17= 1.991e+3" ; +where c1= 20 and abs(c17 - 1.991e+3) < 0.01" ; execute stmt1 ; found +true prepare stmt1 from "select 'true' as found from t9 -where c1= 20 and c17= ?" ; +where c1= 20 and abs(c17 - ?) < 0.01" ; execute stmt1 using @arg00 ; found +true drop table t1, t9; diff --git a/mysql-test/r/ps_5merge.result b/mysql-test/r/ps_5merge.result index 125fa84e671..8f87343c894 100644 --- a/mysql-test/r/ps_5merge.result +++ b/mysql-test/r/ps_5merge.result @@ -951,53 +951,11 @@ FROM t9, (select c25 x, c32 y from t2) tt WHERE x = c25 ' ; prepare stmt1 from @stmt ; execute stmt1 ; -Catalog Database Table Table_alias Column Column_alias Name Type Length Max length Is_null Flags Decimals Charsetnr -def scalar_s 5 21 7 Y 32768 4 8 -def exists_s 8 1 1 N 32769 0 8 -def in_s 8 21 1 Y 32768 0 8 -def in_row_s 8 21 1 Y 32768 0 8 -scalar_s exists_s in_s in_row_s -2.0000 0 1 0 -18.0000 1 0 1 -2.0000 0 1 0 -18.0000 1 0 1 execute stmt1 ; -scalar_s exists_s in_s in_row_s -2.0000 0 1 0 -18.0000 1 0 1 -2.0000 0 1 0 -18.0000 1 0 1 set @stmt= concat('explain ',@stmt); prepare stmt1 from @stmt ; execute stmt1 ; -Catalog Database Table Table_alias Column Column_alias Name Type Length Max length Is_null Flags Decimals Charsetnr -def id 8 3 1 N 32801 0 8 -def select_type 253 19 18 N 1 31 8 -def table 253 64 10 N 1 31 8 -def type 253 10 3 N 1 31 8 -def possible_keys 253 4096 0 Y 0 31 8 -def key 253 64 0 Y 0 31 8 -def key_len 8 3 0 Y 32800 0 8 -def ref 253 1024 0 Y 0 31 8 -def rows 8 10 1 N 32801 0 8 -def Extra 253 255 44 N 1 31 8 -id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t9 ALL NULL NULL NULL NULL 2 -1 PRIMARY ALL NULL NULL NULL NULL 2 Using where -6 DERIVED t2 ALL NULL NULL NULL NULL 2 -5 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -4 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -3 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where; Using temporary; Using filesort execute stmt1 ; -id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t9 ALL NULL NULL NULL NULL 2 -1 PRIMARY ALL NULL NULL NULL NULL 2 Using where -6 DERIVED t2 ALL NULL NULL NULL NULL 2 -5 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -4 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -3 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where; Using temporary; Using filesort set @stmt= ' SELECT (SELECT SUM(c1+c12+?) FROM t2 where (t9.c2-?)=t2.c2 GROUP BY t9.c15 LIMIT 1) as scalar_s, @@ -1020,56 +978,14 @@ set @arg09= 40e-1 ; prepare stmt1 from @stmt ; execute stmt1 using @arg00, @arg01, @arg02, @arg03, @arg04, @arg05, @arg06, @arg07, @arg08, @arg09 ; -Catalog Database Table Table_alias Column Column_alias Name Type Length Max length Is_null Flags Decimals Charsetnr -def scalar_s 5 23 2 Y 32768 31 8 -def exists_s 8 1 1 N 32769 0 8 -def in_s 8 21 1 Y 32768 0 8 -def in_row_s 8 21 1 Y 32768 0 8 -scalar_s exists_s in_s in_row_s -2 0 1 0 -18 1 0 1 -2 0 1 0 -18 1 0 1 execute stmt1 using @arg00, @arg01, @arg02, @arg03, @arg04, @arg05, @arg06, @arg07, @arg08, @arg09 ; -scalar_s exists_s in_s in_row_s -2 0 1 0 -18 1 0 1 -2 0 1 0 -18 1 0 1 set @stmt= concat('explain ',@stmt); prepare stmt1 from @stmt ; execute stmt1 using @arg00, @arg01, @arg02, @arg03, @arg04, @arg05, @arg06, @arg07, @arg08, @arg09 ; -Catalog Database Table Table_alias Column Column_alias Name Type Length Max length Is_null Flags Decimals Charsetnr -def id 8 3 1 N 32801 0 8 -def select_type 253 19 18 N 1 31 8 -def table 253 64 10 N 1 31 8 -def type 253 10 3 N 1 31 8 -def possible_keys 253 4096 0 Y 0 31 8 -def key 253 64 0 Y 0 31 8 -def key_len 8 3 0 Y 32800 0 8 -def ref 253 1024 0 Y 0 31 8 -def rows 8 10 1 N 32801 0 8 -def Extra 253 255 44 N 1 31 8 -id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t9 ALL NULL NULL NULL NULL 2 -1 PRIMARY ALL NULL NULL NULL NULL 2 Using where -6 DERIVED t2 ALL NULL NULL NULL NULL 2 -5 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -4 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -3 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where; Using temporary; Using filesort execute stmt1 using @arg00, @arg01, @arg02, @arg03, @arg04, @arg05, @arg06, @arg07, @arg08, @arg09 ; -id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t9 ALL NULL NULL NULL NULL 2 -1 PRIMARY ALL NULL NULL NULL NULL 2 Using where -6 DERIVED t2 ALL NULL NULL NULL NULL 2 -5 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -4 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -3 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where; Using temporary; Using filesort drop table t2 ; select 1 < (select a from t1) ; ERROR 21000: Subquery returns more than 1 row @@ -3115,19 +3031,23 @@ found true set @arg00= 1.991e+3 ; select 'true' as found from t9 -where c1= 20 and c17= 1.991e+3 ; +where c1= 20 and abs(c17 - 1.991e+3) < 0.01 ; found +true select 'true' as found from t9 -where c1= 20 and c17= @arg00 ; +where c1= 20 and abs(c17 - @arg00) < 0.01 ; found +true prepare stmt1 from "select 'true' as found from t9 -where c1= 20 and c17= 1.991e+3" ; +where c1= 20 and abs(c17 - 1.991e+3) < 0.01" ; execute stmt1 ; found +true prepare stmt1 from "select 'true' as found from t9 -where c1= 20 and c17= ?" ; +where c1= 20 and abs(c17 - ?) < 0.01" ; execute stmt1 using @arg00 ; found +true drop table t1, t9 ; create table t1 ( @@ -4039,53 +3959,11 @@ FROM t9, (select c25 x, c32 y from t2) tt WHERE x = c25 ' ; prepare stmt1 from @stmt ; execute stmt1 ; -Catalog Database Table Table_alias Column Column_alias Name Type Length Max length Is_null Flags Decimals Charsetnr -def scalar_s 5 21 7 Y 32768 4 8 -def exists_s 8 1 1 N 32769 0 8 -def in_s 8 21 1 Y 32768 0 8 -def in_row_s 8 21 1 Y 32768 0 8 -scalar_s exists_s in_s in_row_s -2.0000 0 1 0 -18.0000 1 0 1 -2.0000 0 1 0 -18.0000 1 0 1 execute stmt1 ; -scalar_s exists_s in_s in_row_s -2.0000 0 1 0 -18.0000 1 0 1 -2.0000 0 1 0 -18.0000 1 0 1 set @stmt= concat('explain ',@stmt); prepare stmt1 from @stmt ; execute stmt1 ; -Catalog Database Table Table_alias Column Column_alias Name Type Length Max length Is_null Flags Decimals Charsetnr -def id 8 3 1 N 32801 0 8 -def select_type 253 19 18 N 1 31 8 -def table 253 64 10 N 1 31 8 -def type 253 10 3 N 1 31 8 -def possible_keys 253 4096 0 Y 0 31 8 -def key 253 64 0 Y 0 31 8 -def key_len 8 3 0 Y 32800 0 8 -def ref 253 1024 0 Y 0 31 8 -def rows 8 10 1 N 32801 0 8 -def Extra 253 255 44 N 1 31 8 -id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t9 ALL NULL NULL NULL NULL 2 -1 PRIMARY ALL NULL NULL NULL NULL 2 Using where -6 DERIVED t2 ALL NULL NULL NULL NULL 2 -5 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -4 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -3 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where; Using temporary; Using filesort execute stmt1 ; -id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t9 ALL NULL NULL NULL NULL 2 -1 PRIMARY ALL NULL NULL NULL NULL 2 Using where -6 DERIVED t2 ALL NULL NULL NULL NULL 2 -5 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -4 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -3 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where; Using temporary; Using filesort set @stmt= ' SELECT (SELECT SUM(c1+c12+?) FROM t2 where (t9.c2-?)=t2.c2 GROUP BY t9.c15 LIMIT 1) as scalar_s, @@ -4108,56 +3986,14 @@ set @arg09= 40e-1 ; prepare stmt1 from @stmt ; execute stmt1 using @arg00, @arg01, @arg02, @arg03, @arg04, @arg05, @arg06, @arg07, @arg08, @arg09 ; -Catalog Database Table Table_alias Column Column_alias Name Type Length Max length Is_null Flags Decimals Charsetnr -def scalar_s 5 23 2 Y 32768 31 8 -def exists_s 8 1 1 N 32769 0 8 -def in_s 8 21 1 Y 32768 0 8 -def in_row_s 8 21 1 Y 32768 0 8 -scalar_s exists_s in_s in_row_s -2 0 1 0 -18 1 0 1 -2 0 1 0 -18 1 0 1 execute stmt1 using @arg00, @arg01, @arg02, @arg03, @arg04, @arg05, @arg06, @arg07, @arg08, @arg09 ; -scalar_s exists_s in_s in_row_s -2 0 1 0 -18 1 0 1 -2 0 1 0 -18 1 0 1 set @stmt= concat('explain ',@stmt); prepare stmt1 from @stmt ; execute stmt1 using @arg00, @arg01, @arg02, @arg03, @arg04, @arg05, @arg06, @arg07, @arg08, @arg09 ; -Catalog Database Table Table_alias Column Column_alias Name Type Length Max length Is_null Flags Decimals Charsetnr -def id 8 3 1 N 32801 0 8 -def select_type 253 19 18 N 1 31 8 -def table 253 64 10 N 1 31 8 -def type 253 10 3 N 1 31 8 -def possible_keys 253 4096 0 Y 0 31 8 -def key 253 64 0 Y 0 31 8 -def key_len 8 3 0 Y 32800 0 8 -def ref 253 1024 0 Y 0 31 8 -def rows 8 10 1 N 32801 0 8 -def Extra 253 255 44 N 1 31 8 -id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t9 ALL NULL NULL NULL NULL 2 -1 PRIMARY ALL NULL NULL NULL NULL 2 Using where -6 DERIVED t2 ALL NULL NULL NULL NULL 2 -5 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -4 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -3 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where; Using temporary; Using filesort execute stmt1 using @arg00, @arg01, @arg02, @arg03, @arg04, @arg05, @arg06, @arg07, @arg08, @arg09 ; -id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t9 ALL NULL NULL NULL NULL 2 -1 PRIMARY ALL NULL NULL NULL NULL 2 Using where -6 DERIVED t2 ALL NULL NULL NULL NULL 2 -5 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -4 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -3 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where; Using temporary; Using filesort drop table t2 ; select 1 < (select a from t1) ; ERROR 21000: Subquery returns more than 1 row @@ -6203,18 +6039,22 @@ found true set @arg00= 1.991e+3 ; select 'true' as found from t9 -where c1= 20 and c17= 1.991e+3 ; +where c1= 20 and abs(c17 - 1.991e+3) < 0.01 ; found +true select 'true' as found from t9 -where c1= 20 and c17= @arg00 ; +where c1= 20 and abs(c17 - @arg00) < 0.01 ; found +true prepare stmt1 from "select 'true' as found from t9 -where c1= 20 and c17= 1.991e+3" ; +where c1= 20 and abs(c17 - 1.991e+3) < 0.01" ; execute stmt1 ; found +true prepare stmt1 from "select 'true' as found from t9 -where c1= 20 and c17= ?" ; +where c1= 20 and abs(c17 - ?) < 0.01" ; execute stmt1 using @arg00 ; found +true drop table t1, t1_1, t1_2, t9_1, t9_2, t9; diff --git a/mysql-test/r/ps_6bdb.result b/mysql-test/r/ps_6bdb.result index 88e4d701acf..52009dcf82a 100644 --- a/mysql-test/r/ps_6bdb.result +++ b/mysql-test/r/ps_6bdb.result @@ -908,53 +908,11 @@ FROM t9, (select c25 x, c32 y from t2) tt WHERE x = c25 ' ; prepare stmt1 from @stmt ; execute stmt1 ; -Catalog Database Table Table_alias Column Column_alias Name Type Length Max length Is_null Flags Decimals Charsetnr -def scalar_s 5 21 7 Y 32768 4 8 -def exists_s 8 1 1 N 32769 0 8 -def in_s 8 21 1 Y 32768 0 8 -def in_row_s 8 21 1 Y 32768 0 8 -scalar_s exists_s in_s in_row_s -2.0000 0 1 0 -2.0000 0 1 0 -18.0000 1 0 1 -18.0000 1 0 1 execute stmt1 ; -scalar_s exists_s in_s in_row_s -2.0000 0 1 0 -2.0000 0 1 0 -18.0000 1 0 1 -18.0000 1 0 1 set @stmt= concat('explain ',@stmt); prepare stmt1 from @stmt ; execute stmt1 ; -Catalog Database Table Table_alias Column Column_alias Name Type Length Max length Is_null Flags Decimals Charsetnr -def id 8 3 1 N 32801 0 8 -def select_type 253 19 18 N 1 31 8 -def table 253 64 10 N 1 31 8 -def type 253 10 3 N 1 31 8 -def possible_keys 253 4096 0 Y 0 31 8 -def key 253 64 0 Y 0 31 8 -def key_len 8 3 0 Y 32800 0 8 -def ref 253 1024 0 Y 0 31 8 -def rows 8 10 1 N 32801 0 8 -def Extra 253 255 44 N 1 31 8 -id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY ALL NULL NULL NULL NULL 2 -1 PRIMARY t9 ALL NULL NULL NULL NULL 3 Using where -6 DERIVED t2 ALL NULL NULL NULL NULL 2 -5 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -4 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -3 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where; Using temporary; Using filesort execute stmt1 ; -id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY ALL NULL NULL NULL NULL 2 -1 PRIMARY t9 ALL NULL NULL NULL NULL 3 Using where -6 DERIVED t2 ALL NULL NULL NULL NULL 2 -5 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -4 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -3 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where; Using temporary; Using filesort set @stmt= ' SELECT (SELECT SUM(c1+c12+?) FROM t2 where (t9.c2-?)=t2.c2 GROUP BY t9.c15 LIMIT 1) as scalar_s, @@ -977,56 +935,14 @@ set @arg09= 40e-1 ; prepare stmt1 from @stmt ; execute stmt1 using @arg00, @arg01, @arg02, @arg03, @arg04, @arg05, @arg06, @arg07, @arg08, @arg09 ; -Catalog Database Table Table_alias Column Column_alias Name Type Length Max length Is_null Flags Decimals Charsetnr -def scalar_s 5 23 2 Y 32768 31 8 -def exists_s 8 1 1 N 32769 0 8 -def in_s 8 21 1 Y 32768 0 8 -def in_row_s 8 21 1 Y 32768 0 8 -scalar_s exists_s in_s in_row_s -2 0 1 0 -2 0 1 0 -18 1 0 1 -18 1 0 1 execute stmt1 using @arg00, @arg01, @arg02, @arg03, @arg04, @arg05, @arg06, @arg07, @arg08, @arg09 ; -scalar_s exists_s in_s in_row_s -2 0 1 0 -2 0 1 0 -18 1 0 1 -18 1 0 1 set @stmt= concat('explain ',@stmt); prepare stmt1 from @stmt ; execute stmt1 using @arg00, @arg01, @arg02, @arg03, @arg04, @arg05, @arg06, @arg07, @arg08, @arg09 ; -Catalog Database Table Table_alias Column Column_alias Name Type Length Max length Is_null Flags Decimals Charsetnr -def id 8 3 1 N 32801 0 8 -def select_type 253 19 18 N 1 31 8 -def table 253 64 10 N 1 31 8 -def type 253 10 3 N 1 31 8 -def possible_keys 253 4096 0 Y 0 31 8 -def key 253 64 0 Y 0 31 8 -def key_len 8 3 0 Y 32800 0 8 -def ref 253 1024 0 Y 0 31 8 -def rows 8 10 1 N 32801 0 8 -def Extra 253 255 44 N 1 31 8 -id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY ALL NULL NULL NULL NULL 2 -1 PRIMARY t9 ALL NULL NULL NULL NULL 3 Using where -6 DERIVED t2 ALL NULL NULL NULL NULL 2 -5 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -4 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -3 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where; Using temporary; Using filesort execute stmt1 using @arg00, @arg01, @arg02, @arg03, @arg04, @arg05, @arg06, @arg07, @arg08, @arg09 ; -id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY ALL NULL NULL NULL NULL 2 -1 PRIMARY t9 ALL NULL NULL NULL NULL 3 Using where -6 DERIVED t2 ALL NULL NULL NULL NULL 2 -5 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -4 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -3 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where; Using temporary; Using filesort drop table t2 ; select 1 < (select a from t1) ; ERROR 21000: Subquery returns more than 1 row @@ -3175,17 +3091,21 @@ found true set @arg00= 1.991e+3 ; select 'true' as found from t9 -where c1= 20 and c17= 1.991e+3 ; +where c1= 20 and abs(c17 - 1.991e+3) < 0.01 ; found +true select 'true' as found from t9 -where c1= 20 and c17= @arg00 ; +where c1= 20 and abs(c17 - @arg00) < 0.01 ; found +true prepare stmt1 from "select 'true' as found from t9 -where c1= 20 and c17= 1.991e+3" ; +where c1= 20 and abs(c17 - 1.991e+3) < 0.01" ; execute stmt1 ; found +true prepare stmt1 from "select 'true' as found from t9 -where c1= 20 and c17= ?" ; +where c1= 20 and abs(c17 - ?) < 0.01" ; execute stmt1 using @arg00 ; found +true drop table t1, t9; diff --git a/mysql-test/r/ps_7ndb.result b/mysql-test/r/ps_7ndb.result index eaadafdf339..decfc08b555 100644 --- a/mysql-test/r/ps_7ndb.result +++ b/mysql-test/r/ps_7ndb.result @@ -909,53 +909,11 @@ FROM t9, (select c25 x, c32 y from t2) tt WHERE x = c25 ' ; prepare stmt1 from @stmt ; execute stmt1 ; -Catalog Database Table Table_alias Column Column_alias Name Type Length Max length Is_null Flags Decimals Charsetnr -def scalar_s 5 21 7 Y 32768 4 8 -def exists_s 8 1 1 N 32769 0 8 -def in_s 8 21 1 Y 32768 0 8 -def in_row_s 8 21 1 Y 32768 0 8 -scalar_s exists_s in_s in_row_s -18.0000 1 0 1 -2.0000 0 1 0 -18.0000 1 0 1 -2.0000 0 1 0 execute stmt1 ; -scalar_s exists_s in_s in_row_s -18.0000 1 0 1 -2.0000 0 1 0 -18.0000 1 0 1 -2.0000 0 1 0 set @stmt= concat('explain ',@stmt); prepare stmt1 from @stmt ; execute stmt1 ; -Catalog Database Table Table_alias Column Column_alias Name Type Length Max length Is_null Flags Decimals Charsetnr -def id 8 3 1 N 32801 0 8 -def select_type 253 19 18 N 1 31 8 -def table 253 64 10 N 1 31 8 -def type 253 10 3 N 1 31 8 -def possible_keys 253 4096 0 Y 0 31 8 -def key 253 64 0 Y 0 31 8 -def key_len 8 3 0 Y 32800 0 8 -def ref 253 1024 0 Y 0 31 8 -def rows 8 10 1 N 32801 0 8 -def Extra 253 255 44 N 1 31 8 -id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t9 ALL NULL NULL NULL NULL 2 -1 PRIMARY ALL NULL NULL NULL NULL 2 Using where -6 DERIVED t2 ALL NULL NULL NULL NULL 2 -5 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -4 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -3 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where; Using temporary; Using filesort execute stmt1 ; -id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t9 ALL NULL NULL NULL NULL 2 -1 PRIMARY ALL NULL NULL NULL NULL 2 Using where -6 DERIVED t2 ALL NULL NULL NULL NULL 2 -5 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -4 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -3 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where; Using temporary; Using filesort set @stmt= ' SELECT (SELECT SUM(c1+c12+?) FROM t2 where (t9.c2-?)=t2.c2 GROUP BY t9.c15 LIMIT 1) as scalar_s, @@ -978,56 +936,14 @@ set @arg09= 40e-1 ; prepare stmt1 from @stmt ; execute stmt1 using @arg00, @arg01, @arg02, @arg03, @arg04, @arg05, @arg06, @arg07, @arg08, @arg09 ; -Catalog Database Table Table_alias Column Column_alias Name Type Length Max length Is_null Flags Decimals Charsetnr -def scalar_s 5 23 2 Y 32768 31 8 -def exists_s 8 1 1 N 32769 0 8 -def in_s 8 21 1 Y 32768 0 8 -def in_row_s 8 21 1 Y 32768 0 8 -scalar_s exists_s in_s in_row_s -18 1 0 1 -2 0 1 0 -18 1 0 1 -2 0 1 0 execute stmt1 using @arg00, @arg01, @arg02, @arg03, @arg04, @arg05, @arg06, @arg07, @arg08, @arg09 ; -scalar_s exists_s in_s in_row_s -18 1 0 1 -2 0 1 0 -18 1 0 1 -2 0 1 0 set @stmt= concat('explain ',@stmt); prepare stmt1 from @stmt ; execute stmt1 using @arg00, @arg01, @arg02, @arg03, @arg04, @arg05, @arg06, @arg07, @arg08, @arg09 ; -Catalog Database Table Table_alias Column Column_alias Name Type Length Max length Is_null Flags Decimals Charsetnr -def id 8 3 1 N 32801 0 8 -def select_type 253 19 18 N 1 31 8 -def table 253 64 10 N 1 31 8 -def type 253 10 3 N 1 31 8 -def possible_keys 253 4096 0 Y 0 31 8 -def key 253 64 0 Y 0 31 8 -def key_len 8 3 0 Y 32800 0 8 -def ref 253 1024 0 Y 0 31 8 -def rows 8 10 1 N 32801 0 8 -def Extra 253 255 44 N 1 31 8 -id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t9 ALL NULL NULL NULL NULL 2 -1 PRIMARY ALL NULL NULL NULL NULL 2 Using where -6 DERIVED t2 ALL NULL NULL NULL NULL 2 -5 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -4 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -3 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where; Using temporary; Using filesort execute stmt1 using @arg00, @arg01, @arg02, @arg03, @arg04, @arg05, @arg06, @arg07, @arg08, @arg09 ; -id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t9 ALL NULL NULL NULL NULL 2 -1 PRIMARY ALL NULL NULL NULL NULL 2 Using where -6 DERIVED t2 ALL NULL NULL NULL NULL 2 -5 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -4 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -3 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where -2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where; Using temporary; Using filesort drop table t2 ; select 1 < (select a from t1) ; ERROR 21000: Subquery returns more than 1 row @@ -3154,17 +3070,21 @@ found true set @arg00= 1.991e+3 ; select 'true' as found from t9 -where c1= 20 and c17= 1.991e+3 ; +where c1= 20 and abs(c17 - 1.991e+3) < 0.01 ; found +true select 'true' as found from t9 -where c1= 20 and c17= @arg00 ; +where c1= 20 and abs(c17 - @arg00) < 0.01 ; found +true prepare stmt1 from "select 'true' as found from t9 -where c1= 20 and c17= 1.991e+3" ; +where c1= 20 and abs(c17 - 1.991e+3) < 0.01" ; execute stmt1 ; found +true prepare stmt1 from "select 'true' as found from t9 -where c1= 20 and c17= ?" ; +where c1= 20 and abs(c17 - ?) < 0.01" ; execute stmt1 using @arg00 ; found +true drop table t1, t9; diff --git a/mysql-test/r/query_cache.result.es b/mysql-test/r/query_cache.result.es new file mode 100644 index 00000000000..218e4e1ae2a --- /dev/null +++ b/mysql-test/r/query_cache.result.es @@ -0,0 +1,910 @@ +set GLOBAL query_cache_size=1355776; +flush query cache; +flush query cache; +reset query cache; +flush status; +drop table if exists t1,t2,t3,t4,t11,t21; +drop database if exists mysqltest; +create table t1 (a int not null); +insert into t1 values (1),(2),(3); +select * from t1; +a +1 +2 +3 +select * from t1; +a +1 +2 +3 +select sql_no_cache * from t1; +a +1 +2 +3 +select length(now()) from t1; +length(now()) +19 +19 +19 +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 1 +show status like "Qcache_inserts"; +Variable_name Value +Qcache_inserts 1 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 1 +drop table t1; +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 0 +create table t1 (a int not null); +insert into t1 values (1),(2),(3); +create table t2 (a int not null); +insert into t2 values (4),(5),(6); +create table t3 (a int not null) engine=MERGE UNION=(t1,t2) INSERT_METHOD=FIRST; +select * from t3; +a +1 +2 +3 +4 +5 +6 +select * from t3; +a +1 +2 +3 +4 +5 +6 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 2 +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 1 +insert into t2 values (7); +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 0 +select * from t1; +a +1 +2 +3 +select * from t1; +a +1 +2 +3 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 3 +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 1 +insert into t3 values (8); +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 0 +select * from t3; +a +1 +2 +3 +8 +4 +5 +6 +7 +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 1 +update t2 set a=9 where a=7; +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 0 +select * from t1; +a +1 +2 +3 +8 +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 1 +update t3 set a=10 where a=1; +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 0 +select * from t3; +a +10 +2 +3 +8 +4 +5 +6 +9 +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 1 +delete from t2 where a=9; +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 0 +select * from t1; +a +10 +2 +3 +8 +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 1 +delete from t3 where a=10; +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 0 +drop table t1, t2, t3; +create table t1 (a int not null); +insert into t1 values (1),(2),(3); +create table t2 (a int not null); +insert into t2 values (1),(2),(3); +select * from t1; +a +1 +2 +3 +select * from t2; +a +1 +2 +3 +insert into t1 values (4); +show status like "Qcache_free_blocks"; +Variable_name Value +Qcache_free_blocks 2 +flush query cache; +show status like "Qcache_free_blocks"; +Variable_name Value +Qcache_free_blocks 1 +drop table t1, t2; +create table t1 (a text not null); +create table t11 (a text not null); +create table t2 (a text not null); +create table t21 (a text not null); +create table t3 (a text not null); +insert into t1 values("1111111111111111111111111111111111111111111111111111"); +insert into t2 select * from t1; +insert into t1 select * from t2; +insert into t2 select * from t1; +insert into t1 select * from t2; +insert into t2 select * from t1; +insert into t1 select * from t2; +insert into t2 select * from t1; +insert into t1 select * from t2; +insert into t2 select * from t1; +insert into t1 select * from t2; +insert into t2 select * from t1; +insert into t1 select * from t2; +insert into t2 select * from t1; +insert into t1 select * from t2; +insert into t2 select * from t1; +insert into t11 select * from t1; +insert into t21 select * from t1; +insert into t1 select * from t2; +insert into t2 select * from t1; +insert into t1 select * from t2; +insert into t3 select * from t1; +insert into t3 select * from t2; +insert into t3 select * from t1; +select * from t11; +select * from t21; +show status like "Qcache_total_blocks"; +Variable_name Value +Qcache_total_blocks 7 +show status like "Qcache_free_blocks"; +Variable_name Value +Qcache_free_blocks 1 +insert into t11 values(""); +select * from t3; +show status like "Qcache_total_blocks"; +Variable_name Value +Qcache_total_blocks 8 +show status like "Qcache_free_blocks"; +Variable_name Value +Qcache_free_blocks 2 +flush query cache; +show status like "Qcache_total_blocks"; +Variable_name Value +Qcache_total_blocks 7 +show status like "Qcache_free_blocks"; +Variable_name Value +Qcache_free_blocks 1 +drop table t1, t2, t3, t11, t21; +set query_cache_type=demand; +create table t1 (a int not null); +insert into t1 values (1),(2),(3); +select * from t1; +a +1 +2 +3 +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 0 +select sql_cache * from t1 union select * from t1; +a +1 +2 +3 +set query_cache_type=2; +select sql_cache * from t1 union select * from t1; +a +1 +2 +3 +select * from t1 union select sql_cache * from t1; +a +1 +2 +3 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 4 +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 2 +set query_cache_type=on; +reset query cache; +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 0 +select sql_no_cache * from t1; +a +1 +2 +3 +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 0 +drop table t1; +create table t1 (a text not null); +select CONNECTION_ID() from t1; +CONNECTION_ID() +select FOUND_ROWS(); +FOUND_ROWS() +0 +select NOW() from t1; +NOW() +select CURDATE() from t1; +CURDATE() +select CURTIME() from t1; +CURTIME() +select DATABASE() from t1; +DATABASE() +select ENCRYPT("test") from t1; +ENCRYPT("test") +select LAST_INSERT_ID() from t1; +LAST_INSERT_ID() +select RAND() from t1; +RAND() +select UNIX_TIMESTAMP() from t1; +UNIX_TIMESTAMP() +select USER() from t1; +USER() +select benchmark(1,1) from t1; +benchmark(1,1) +explain extended select benchmark(1,1) from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 system NULL NULL NULL NULL 0 const row not found +Warnings: +Note 1003 select sql_no_cache benchmark(1,1) AS `benchmark(1,1)` from test.t1 +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 0 +create table t2 (a text not null); +insert into t1 values("1111111111111111111111111111111111111111111111111111"); +insert into t2 select * from t1; +insert into t1 select * from t2; +insert into t2 select * from t1; +insert into t1 select * from t2; +insert into t2 select * from t1; +insert into t1 select * from t2; +insert into t2 select * from t1; +insert into t1 select * from t2; +insert into t2 select * from t1; +insert into t1 select * from t2; +insert into t2 select * from t1; +insert into t1 select * from t2; +insert into t2 select * from t1; +insert into t1 select * from t2; +insert into t2 select * from t1; +insert into t1 select * from t2; +insert into t2 select * from t1; +insert into t1 select * from t2; +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 4 +show status like "Qcache_lowmem_prunes"; +Variable_name Value +Qcache_lowmem_prunes 0 +select a as a1, a as a2 from t1; +select a as a2, a as a3 from t1; +select a as a3, a as a4 from t1; +select a as a1, a as a2 from t1; +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 4 +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 2 +show status like "Qcache_lowmem_prunes"; +Variable_name Value +Qcache_lowmem_prunes 2 +reset query cache; +insert into t2 select * from t1; +insert into t1 select * from t2; +insert into t2 select * from t1; +insert into t1 select * from t2; +insert into t2 select * from t1; +insert into t1 select * from t2; +insert into t2 select * from t1; +insert into t1 select * from t2; +insert into t2 select * from t1; +insert into t1 select * from t2; +select * from t1; +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 0 +drop table t1,t2; +create database mysqltest; +create table mysqltest.t1 (i int not null auto_increment, a int, primary key (i)); +insert into mysqltest.t1 (a) values (1); +select * from mysqltest.t1 where i is null; +i a +1 1 +create table t1(a int); +select * from t1; +a +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 2 +select * from mysqltest.t1; +i a +1 1 +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 3 +drop database mysqltest; +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 1 +drop table t1; +create table t1 (a char(1) not null collate koi8r_general_ci); +insert into t1 values(_koi8r"α"); +set CHARACTER SET koi8r; +select * from t1; +a +α +set CHARACTER SET cp1251_koi8; +select * from t1; +a +ΐ +set CHARACTER SET DEFAULT; +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 2 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 4 +drop table t1; +create database if not exists mysqltest; +create table mysqltest.t1 (i int not null); +create table t1 (i int not null); +insert into mysqltest.t1 (i) values (1); +insert into t1 (i) values (2); +select * from t1; +i +2 +use mysqltest; +select * from t1; +i +1 +select * from t1; +i +1 +use test; +select * from t1; +i +2 +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 2 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 6 +drop database mysqltest; +drop table t1; +create table t1 (i int not null); +insert into t1 (i) values (1),(2),(3),(4); +select SQL_CALC_FOUND_ROWS * from t1 limit 2; +i +1 +2 +select FOUND_ROWS(); +FOUND_ROWS() +4 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 6 +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 1 +select * from t1 where i=1; +i +1 +select FOUND_ROWS(); +FOUND_ROWS() +1 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 6 +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 2 +select SQL_CALC_FOUND_ROWS * from t1 limit 2; +i +1 +2 +select FOUND_ROWS(); +FOUND_ROWS() +4 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 7 +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 2 +select * from t1 where i=1; +i +1 +select FOUND_ROWS(); +FOUND_ROWS() +1 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 8 +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 2 +drop table t1; +flush query cache; +reset query cache; +create table t1 (a int not null); +insert into t1 values (1),(2),(3); +select * from t1; +a +1 +2 +3 +select * from t1; +a +1 +2 +3 +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 1 +insert delayed into t1 values (4); +select a from t1; +a +1 +2 +3 +4 +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 1 +drop table t1; +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 0 +show global variables like "query_cache_min_res_unit"; +Variable_name Value +query_cache_min_res_unit 4096 +set GLOBAL query_cache_min_res_unit=1001; +show global variables like "query_cache_min_res_unit"; +Variable_name Value +query_cache_min_res_unit 1008 +create table t1 (a int not null); +insert into t1 values (1),(2),(3); +create table t2 (a int not null); +insert into t2 values (1),(2),(3); +select * from t1; +a +1 +2 +3 +select * from t1; +a +1 +2 +3 +select * from t2; +a +1 +2 +3 +select * from t2; +a +1 +2 +3 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 11 +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 2 +drop table t1; +select a from t2; +a +1 +2 +3 +select a from t2; +a +1 +2 +3 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 12 +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 2 +drop table t2; +set GLOBAL query_cache_min_res_unit=default; +show global variables like "query_cache_min_res_unit"; +Variable_name Value +query_cache_min_res_unit 4096 +create table t1 (a int not null); +insert into t1 values (1); +select "aaa" from t1; +aaa +aaa +select "AAA" from t1; +AAA +AAA +drop table t1; +create table t1 (a int); +set GLOBAL query_cache_size=1000; +show global variables like "query_cache_size"; +Variable_name Value +query_cache_size 0 +select * from t1; +a +set GLOBAL query_cache_size=1024; +Warnings: +Warning 1282 Query cache failed to set size 1024; new query cache size is 0 +show global variables like "query_cache_size"; +Variable_name Value +query_cache_size 0 +select * from t1; +a +set GLOBAL query_cache_size=10240; +Warnings: +Warning 1282 Query cache failed to set size 10240; new query cache size is 0 +show global variables like "query_cache_size"; +Variable_name Value +query_cache_size 0 +select * from t1; +a +set GLOBAL query_cache_size=20480; +Warnings: +Warning 1282 Query cache failed to set size 20480; new query cache size is 0 +show global variables like "query_cache_size"; +Variable_name Value +query_cache_size 0 +select * from t1; +a +set GLOBAL query_cache_size=40960; +Warnings: +Warning 1282 Query cache failed to set size 40960; new query cache size is 0 +show global variables like "query_cache_size"; +Variable_name Value +query_cache_size 0 +select * from t1; +a +set GLOBAL query_cache_size=51200; +show global variables like "query_cache_size"; +Variable_name Value +query_cache_size 51200 +select * from t1; +a +set GLOBAL query_cache_size=61440; +show global variables like "query_cache_size"; +Variable_name Value +query_cache_size 61440 +select * from t1; +a +set GLOBAL query_cache_size=81920; +show global variables like "query_cache_size"; +Variable_name Value +query_cache_size 81920 +select * from t1; +a +set GLOBAL query_cache_size=102400; +show global variables like "query_cache_size"; +Variable_name Value +query_cache_size 102400 +select * from t1; +a +drop table t1; +set GLOBAL query_cache_size=1048576; +create table t1 (i int not null); +create table t2 (i int not null); +select * from t1; +i +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 1 +create temporary table t3 (i int not null); +select * from t2; +i +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 2 +select * from t3; +i +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 2 +update t1 set i=(select distinct 1 from (select * from t2) a); +drop table t1, t2, t3; +use mysql; +select * from db; +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 0 +use test; +select * from mysql.db; +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 0 +create table t1(id int auto_increment primary key); +insert into t1 values (NULL), (NULL), (NULL); +select * from t1 where id=2; +id +2 +alter table t1 rename to t2; +select * from t1 where id=2; +ERROR 42S02: Table 'test.t1' doesn't exist +drop table t2; +select * from t1 where id=2; +ERROR 42S02: Table 'test.t1' doesn't exist +create table t1 (word char(20) not null); +select * from t1; +word +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 1 +load data infile 'TEST_DIR/std_data/words.dat' into table t1; +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 0 +select count(*) from t1; +count(*) +70 +drop table t1; +create table t1 (a int); +insert into t1 values (1),(2),(3); +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 0 +select * from t1 into outfile "query_cache.out.file"; +select * from t1 into outfile "query_cache.out.file"; +ERROR HY000: File 'query_cache.out.file' already exists +select * from t1 limit 1 into dumpfile "query_cache.dump.file"; +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 0 +drop table t1; +create table t1 (a int); +insert into t1 values (1),(2); +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 0 +select * from t1; +a +1 +2 +SET OPTION SQL_SELECT_LIMIT=1; +select * from t1; +a +1 +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 2 +SET OPTION SQL_SELECT_LIMIT=DEFAULT; +drop table t1; +flush query cache; +reset query cache; +flush status; +set GLOBAL query_cache_size=1048576; +create table t1 (a int not null); +insert into t1 values (1),(2),(3); +create table t2 (a text not null); +create table t3 (a text not null); +insert into t3 values("1111111111111111111111111111111111111111111111111111"); +insert into t2 select * from t3; +insert into t3 select * from t2; +insert into t2 select * from t3; +insert into t3 select * from t2; +insert into t2 select * from t3; +insert into t3 select * from t2; +insert into t2 select * from t3; +insert into t3 select * from t2; +insert into t2 select * from t3; +insert into t3 select * from t2; +drop table t2; +create table t2 (a int not null); +insert into t2 values (1),(2),(3); +create table t4 (a int not null); +insert into t4 values (1),(2),(3); +select * from t4; +select * from t2; +select * from t1 as tt, t1 as ttt where tt.a=1 and ttt.a=2; +select * from t2; +select * from t4; +select * from t1 as tt, t1 as ttt where tt.a=1 and ttt.a=2; +select * from t2; +select * from t4; +select * from t1 as tt, t1 as ttt where tt.a=1 and ttt.a=2; +delete from t2 where a=1; +flush query cache; +select * from t3; +delete from t4 where a=1; +flush query cache; +drop table t1,t2,t3,t4; +set query_cache_wlock_invalidate=1; +create table t1 (a int not null); +create table t2 (a int not null); +select * from t1; +a +select * from t2; +a +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 2 +lock table t1 write, t2 read; +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 1 +unlock table; +drop table t1,t2; +set query_cache_wlock_invalidate=default; +SET NAMES koi8r; +CREATE TABLE t1 (a char(1) character set koi8r); +INSERT INTO t1 VALUES (_koi8r'α'),(_koi8r'Α'); +SELECT a,'Β','β'='Β' FROM t1; +a Π± 'Π‘'='Π±' +α Β 1 +Α Β 1 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 6 +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 1 +set collation_connection=koi8r_bin; +SELECT a,'Β','β'='Β' FROM t1; +a Π± 'Π‘'='Π±' +α Β 0 +Α Β 0 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 6 +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 2 +set character_set_client=cp1251; +SELECT a,'Β','β'='Β' FROM t1; +a Π’ 'Π²'='Π’' +α χ 0 +Α χ 0 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 6 +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 3 +set character_set_results=cp1251; +SELECT a,'Β','β'='Β' FROM t1; +a Π’ 'Π²'='Π’' +ΐ Β 0 +ΰ Β 0 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 6 +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 4 +DROP TABLE t1; +CREATE TABLE t1 (a int(1)); +CREATE DATABASE mysqltest; +USE mysqltest; +DROP DATABASE mysqltest; +SELECT * FROM test.t1; +a +USE test; +DROP TABLE t1; +set character_set_results=null; +select @@character_set_results; +@@character_set_results +NULL +set character_set_results=default; +set GLOBAL query_cache_size=1355776; +create table t1 (id int auto_increment primary key, c char(25)); +insert into t1 set c = repeat('x',24); +insert into t1 set c = concat(repeat('x',24),'x'); +insert into t1 set c = concat(repeat('x',24),'w'); +insert into t1 set c = concat(repeat('x',24),'y'); +set max_sort_length=200; +select c from t1 order by c, id; +c +xxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxw +xxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxy +reset query cache; +set max_sort_length=20; +select c from t1 order by c, id; +c +xxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxw +xxxxxxxxxxxxxxxxxxxxxxxxy +set max_sort_length=200; +select c from t1 order by c, id; +c +xxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxw +xxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxy +set max_sort_length=default; +select '1' || '3' from t1; +'1' || '3' +1 +1 +1 +1 +set SQL_MODE=oracle; +select '1' || '3' from t1; +'1' || '3' +13 +13 +13 +13 +set SQL_MODE=default; +drop table t1; +create table t1 (a varchar(20), b int); +insert into t1 values ('12345678901234567890', 1); +set group_concat_max_len=10; +select group_concat(a) FROM t1 group by b; +group_concat(a) +1234567890 +set group_concat_max_len=1024; +select group_concat(a) FROM t1 group by b; +group_concat(a) +12345678901234567890 +set group_concat_max_len=default; +drop table t1; +SET GLOBAL query_cache_size=0; diff --git a/mysql-test/r/select.result.es b/mysql-test/r/select.result.es new file mode 100644 index 00000000000..2ff58372d6d --- /dev/null +++ b/mysql-test/r/select.result.es @@ -0,0 +1,2366 @@ +drop table if exists t1,t2,t3,t4; +CREATE TABLE t1 ( +Period smallint(4) unsigned zerofill DEFAULT '0000' NOT NULL, +Varor_period smallint(4) unsigned DEFAULT '0' NOT NULL +); +INSERT INTO t1 VALUES (9410,9412); +select period from t1; +period +9410 +select * from t1; +Period Varor_period +9410 9412 +select t1.* from t1; +Period Varor_period +9410 9412 +CREATE TABLE t2 ( +auto int not null auto_increment, +fld1 int(6) unsigned zerofill DEFAULT '000000' NOT NULL, +companynr tinyint(2) unsigned zerofill DEFAULT '00' NOT NULL, +fld3 char(30) DEFAULT '' NOT NULL, +fld4 char(35) DEFAULT '' NOT NULL, +fld5 char(35) DEFAULT '' NOT NULL, +fld6 char(4) DEFAULT '' NOT NULL, +UNIQUE fld1 (fld1), +KEY fld3 (fld3), +PRIMARY KEY (auto) +); +select t2.fld3 from t2 where companynr = 58 and fld3 like "%imaginable%"; +fld3 +imaginable +select fld3 from t2 where fld3 like "%cultivation" ; +fld3 +cultivation +select t2.fld3,companynr from t2 where companynr = 57+1 order by fld3; +fld3 companynr +concoct 58 +druggists 58 +engrossing 58 +Eurydice 58 +exclaimers 58 +ferociousness 58 +hopelessness 58 +Huey 58 +imaginable 58 +judges 58 +merging 58 +ostrich 58 +peering 58 +Phelps 58 +presumes 58 +Ruth 58 +sentences 58 +Shylock 58 +straggled 58 +synergy 58 +thanking 58 +tying 58 +unlocks 58 +select fld3,companynr from t2 where companynr = 58 order by fld3; +fld3 companynr +concoct 58 +druggists 58 +engrossing 58 +Eurydice 58 +exclaimers 58 +ferociousness 58 +hopelessness 58 +Huey 58 +imaginable 58 +judges 58 +merging 58 +ostrich 58 +peering 58 +Phelps 58 +presumes 58 +Ruth 58 +sentences 58 +Shylock 58 +straggled 58 +synergy 58 +thanking 58 +tying 58 +unlocks 58 +select fld3 from t2 order by fld3 desc limit 10; +fld3 +youthfulness +yelped +Wotan +workers +Witt +witchcraft +Winsett +Willy +willed +wildcats +select fld3 from t2 order by fld3 desc limit 5; +fld3 +youthfulness +yelped +Wotan +workers +Witt +select fld3 from t2 order by fld3 desc limit 5,5; +fld3 +witchcraft +Winsett +Willy +willed +wildcats +select t2.fld3 from t2 where fld3 = 'honeysuckle'; +fld3 +honeysuckle +select t2.fld3 from t2 where fld3 LIKE 'honeysuckl_'; +fld3 +honeysuckle +select t2.fld3 from t2 where fld3 LIKE 'hon_ysuckl_'; +fld3 +honeysuckle +select t2.fld3 from t2 where fld3 LIKE 'honeysuckle%'; +fld3 +honeysuckle +select t2.fld3 from t2 where fld3 LIKE 'h%le'; +fld3 +honeysuckle +select t2.fld3 from t2 where fld3 LIKE 'honeysuckle_'; +fld3 +select t2.fld3 from t2 where fld3 LIKE 'don_t_find_me_please%'; +fld3 +explain select t2.fld3 from t2 where fld3 = 'honeysuckle'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ref fld3 fld3 30 const 1 Using where; Using index +explain select fld3 from t2 ignore index (fld3) where fld3 = 'honeysuckle'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where +explain select fld3 from t2 use index (fld1) where fld3 = 'honeysuckle'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where +explain select fld3 from t2 use index (fld3) where fld3 = 'honeysuckle'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ref fld3 fld3 30 const 1 Using where; Using index +explain select fld3 from t2 use index (fld1,fld3) where fld3 = 'honeysuckle'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ref fld3 fld3 30 const 1 Using where; Using index +explain select fld3 from t2 ignore index (fld3,not_used); +ERROR 42000: Key column 'not_used' doesn't exist in table +explain select fld3 from t2 use index (not_used); +ERROR 42000: Key column 'not_used' doesn't exist in table +select t2.fld3 from t2 where fld3 >= 'honeysuckle' and fld3 <= 'honoring' order by fld3; +fld3 +honeysuckle +honoring +explain select t2.fld3 from t2 where fld3 >= 'honeysuckle' and fld3 <= 'honoring' order by fld3; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 range fld3 fld3 30 NULL 2 Using where; Using index +select fld1,fld3 from t2 where fld3="Colombo" or fld3 = "nondecreasing" order by fld3; +fld1 fld3 +148504 Colombo +068305 Colombo +000000 nondecreasing +select fld1,fld3 from t2 where companynr = 37 and fld3 = 'appendixes'; +fld1 fld3 +232605 appendixes +1232605 appendixes +1232606 appendixes +1232607 appendixes +1232608 appendixes +1232609 appendixes +select fld1 from t2 where fld1=250501 or fld1="250502"; +fld1 +250501 +250502 +explain select fld1 from t2 where fld1=250501 or fld1="250502"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 range fld1 fld1 4 NULL 2 Using where; Using index +select fld1 from t2 where fld1=250501 or fld1=250502 or fld1 >= 250505 and fld1 <= 250601 or fld1 between 250501 and 250502; +fld1 +250501 +250502 +250505 +250601 +explain select fld1 from t2 where fld1=250501 or fld1=250502 or fld1 >= 250505 and fld1 <= 250601 or fld1 between 250501 and 250502; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 range fld1 fld1 4 NULL 4 Using where; Using index +select fld1,fld3 from t2 where companynr = 37 and fld3 like 'f%'; +fld1 fld3 +218401 faithful +018007 fanatic +228311 fated +018017 featherweight +218022 feed +088303 feminine +058004 Fenton +038017 fetched +018054 fetters +208101 fiftieth +238007 filial +013606 fingerings +218008 finishers +038205 firearm +188505 fitting +202301 Fitzpatrick +238008 fixedly +012001 flanking +018103 flint +018104 flopping +188007 flurried +013602 foldout +226205 foothill +232102 forgivably +228306 forthcoming +186002 freakish +208113 freest +231315 freezes +036002 funereal +226209 furnishings +198006 furthermore +select fld3 from t2 where fld3 like "L%" and fld3 = "ok"; +fld3 +select fld3 from t2 where (fld3 like "C%" and fld3 = "Chantilly"); +fld3 +Chantilly +select fld1,fld3 from t2 where fld1 like "25050%"; +fld1 fld3 +250501 poisoning +250502 Iraqis +250503 heaving +250504 population +250505 bomb +select fld1,fld3 from t2 where fld1 like "25050_"; +fld1 fld3 +250501 poisoning +250502 Iraqis +250503 heaving +250504 population +250505 bomb +select distinct companynr from t2; +companynr +00 +37 +36 +50 +58 +29 +40 +53 +65 +41 +34 +68 +select distinct companynr from t2 order by companynr; +companynr +00 +29 +34 +36 +37 +40 +41 +50 +53 +58 +65 +68 +select distinct companynr from t2 order by companynr desc; +companynr +68 +65 +58 +53 +50 +41 +40 +37 +36 +34 +29 +00 +select distinct t2.fld3,period from t2,t1 where companynr=37 and fld3 like "O%"; +fld3 period +obliterates 9410 +offload 9410 +opaquely 9410 +organizer 9410 +overestimating 9410 +overlay 9410 +select distinct fld3 from t2 where companynr = 34 order by fld3; +fld3 +absentee +accessed +ahead +alphabetic +Asiaticizations +attitude +aye +bankruptcies +belays +Blythe +bomb +boulevard +bulldozes +cannot +caressing +charcoal +checksumming +chess +clubroom +colorful +cosy +creator +crying +Darius +diffusing +duality +Eiffel +Epiphany +Ernestine +explorers +exterminated +famine +forked +Gershwins +heaving +Hodges +Iraqis +Italianization +Lagos +landslide +libretto +Majorca +mastering +narrowed +occurred +offerers +Palestine +Peruvianizes +pharmaceutic +poisoning +population +Pygmalion +rats +realest +recording +regimented +retransmitting +reviver +rouses +scars +sicker +sleepwalk +stopped +sugars +translatable +uncles +unexpected +uprisings +versatility +vest +select distinct fld3 from t2 limit 10; +fld3 +abates +abiding +Abraham +abrogating +absentee +abut +accessed +accruing +accumulating +accuracies +select distinct fld3 from t2 having fld3 like "A%" limit 10; +fld3 +abates +abiding +Abraham +abrogating +absentee +abut +accessed +accruing +accumulating +accuracies +select distinct substring(fld3,1,3) from t2 where fld3 like "A%"; +substring(fld3,1,3) +aba +abi +Abr +abs +abu +acc +acq +acu +Ade +adj +Adl +adm +Ado +ads +adv +aer +aff +afi +afl +afo +agi +ahe +aim +air +Ald +alg +ali +all +alp +alr +ama +ame +amm +ana +and +ane +Ang +ani +Ann +Ant +api +app +aqu +Ara +arc +Arm +arr +Art +Asi +ask +asp +ass +ast +att +aud +Aug +aut +ave +avo +awe +aye +Azt +select distinct substring(fld3,1,3) as a from t2 having a like "A%" order by a limit 10; +a +aba +abi +Abr +abs +abu +acc +acq +acu +Ade +adj +select distinct substring(fld3,1,3) from t2 where fld3 like "A%" limit 10; +substring(fld3,1,3) +aba +abi +Abr +abs +abu +acc +acq +acu +Ade +adj +select distinct substring(fld3,1,3) as a from t2 having a like "A%" limit 10; +a +aba +abi +Abr +abs +abu +acc +acq +acu +Ade +adj +create table t3 ( +period int not null, +name char(32) not null, +companynr int not null, +price double(11,0), +price2 double(11,0), +key (period), +key (name) +); +create temporary table tmp engine = myisam select * from t3; +insert into t3 select * from tmp; +insert into tmp select * from t3; +insert into t3 select * from tmp; +insert into tmp select * from t3; +insert into t3 select * from tmp; +insert into tmp select * from t3; +insert into t3 select * from tmp; +insert into tmp select * from t3; +insert into t3 select * from tmp; +insert into tmp select * from t3; +insert into t3 select * from tmp; +insert into tmp select * from t3; +insert into t3 select * from tmp; +insert into tmp select * from t3; +insert into t3 select * from tmp; +insert into tmp select * from t3; +insert into t3 select * from tmp; +alter table t3 add t2nr int not null auto_increment primary key first; +drop table tmp; +SET SQL_BIG_TABLES=1; +select distinct concat(fld3," ",fld3) as namn from t2,t3 where t2.fld1=t3.t2nr order by namn limit 10; +namn +Abraham Abraham +abrogating abrogating +admonishing admonishing +Adolph Adolph +afield afield +aging aging +ammonium ammonium +analyzable analyzable +animals animals +animized animized +SET SQL_BIG_TABLES=0; +select distinct concat(fld3," ",fld3) from t2,t3 where t2.fld1=t3.t2nr order by fld3 limit 10; +concat(fld3," ",fld3) +Abraham Abraham +abrogating abrogating +admonishing admonishing +Adolph Adolph +afield afield +aging aging +ammonium ammonium +analyzable analyzable +animals animals +animized animized +select distinct fld5 from t2 limit 10; +fld5 +neat +Steinberg +jarring +tinily +balled +persist +attainments +fanatic +measures +rightfulness +select distinct fld3,count(*) from t2 group by companynr,fld3 limit 10; +fld3 count(*) +affixed 1 +and 1 +annoyers 1 +Anthony 1 +assayed 1 +assurers 1 +attendants 1 +bedlam 1 +bedpost 1 +boasted 1 +SET SQL_BIG_TABLES=1; +select distinct fld3,count(*) from t2 group by companynr,fld3 limit 10; +fld3 count(*) +affixed 1 +and 1 +annoyers 1 +Anthony 1 +assayed 1 +assurers 1 +attendants 1 +bedlam 1 +bedpost 1 +boasted 1 +SET SQL_BIG_TABLES=0; +select distinct fld3,repeat("a",length(fld3)),count(*) from t2 group by companynr,fld3 limit 100,10; +fld3 repeat("a",length(fld3)) count(*) +circus aaaaaa 1 +cited aaaaa 1 +Colombo aaaaaaa 1 +congresswoman aaaaaaaaaaaaa 1 +contrition aaaaaaaaaa 1 +corny aaaaa 1 +cultivation aaaaaaaaaaa 1 +definiteness aaaaaaaaaaaa 1 +demultiplex aaaaaaaaaaa 1 +disappointing aaaaaaaaaaaaa 1 +select distinct companynr,rtrim(space(512+companynr)) from t3 order by 1,2; +companynr rtrim(space(512+companynr)) +37 +78 +101 +154 +311 +447 +512 +select distinct fld3 from t2,t3 where t2.companynr = 34 and t2.fld1=t3.t2nr order by fld3; +fld3 +explain select t3.t2nr,fld3 from t2,t3 where t2.companynr = 34 and t2.fld1=t3.t2nr order by t3.t2nr,fld3; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL fld1 NULL NULL NULL 1199 Using where; Using temporary; Using filesort +1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.fld1 1 Using where; Using index +explain select * from t3 as t1,t3 where t1.period=t3.period order by t3.period; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL period NULL NULL NULL 41810 Using temporary; Using filesort +1 SIMPLE t3 ref period period 4 test.t1.period 4181 +explain select * from t3 as t1,t3 where t1.period=t3.period order by t3.period limit 10; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t3 index period period 4 NULL 41810 +1 SIMPLE t1 ref period period 4 test.t3.period 4181 +explain select * from t3 as t1,t3 where t1.period=t3.period order by t1.period limit 10; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index period period 4 NULL 41810 +1 SIMPLE t3 ref period period 4 test.t1.period 4181 +select period from t1; +period +9410 +select period from t1 where period=1900; +period +select fld3,period from t1,t2 where fld1 = 011401 order by period; +fld3 period +breaking 9410 +select fld3,period from t2,t3 where t2.fld1 = 011401 and t2.fld1=t3.t2nr and t3.period=1001; +fld3 period +breaking 1001 +explain select fld3,period from t2,t3 where t2.fld1 = 011401 and t3.t2nr=t2.fld1 and 1001 = t3.period; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 const fld1 fld1 4 const 1 +1 SIMPLE t3 const PRIMARY,period PRIMARY 4 const 1 +select fld3,period from t2,t1 where companynr*10 = 37*10; +fld3 period +breaking 9410 +Romans 9410 +intercepted 9410 +bewilderingly 9410 +astound 9410 +admonishing 9410 +sumac 9410 +flanking 9410 +combed 9410 +subjective 9410 +scatterbrain 9410 +Eulerian 9410 +Kane 9410 +overlay 9410 +perturb 9410 +goblins 9410 +annihilates 9410 +Wotan 9410 +snatching 9410 +concludes 9410 +laterally 9410 +yelped 9410 +grazing 9410 +Baird 9410 +celery 9410 +misunderstander 9410 +handgun 9410 +foldout 9410 +mystic 9410 +succumbed 9410 +Nabisco 9410 +fingerings 9410 +aging 9410 +afield 9410 +ammonium 9410 +boat 9410 +intelligibility 9410 +Augustine 9410 +teethe 9410 +dreaded 9410 +scholastics 9410 +audiology 9410 +wallet 9410 +parters 9410 +eschew 9410 +quitter 9410 +neat 9410 +Steinberg 9410 +jarring 9410 +tinily 9410 +balled 9410 +persist 9410 +attainments 9410 +fanatic 9410 +measures 9410 +rightfulness 9410 +capably 9410 +impulsive 9410 +starlet 9410 +terminators 9410 +untying 9410 +announces 9410 +featherweight 9410 +pessimist 9410 +daughter 9410 +decliner 9410 +lawgiver 9410 +stated 9410 +readable 9410 +attrition 9410 +cascade 9410 +motors 9410 +interrogate 9410 +pests 9410 +stairway 9410 +dopers 9410 +testicle 9410 +Parsifal 9410 +leavings 9410 +postulation 9410 +squeaking 9410 +contrasted 9410 +leftover 9410 +whiteners 9410 +erases 9410 +Punjab 9410 +Merritt 9410 +Quixotism 9410 +sweetish 9410 +dogging 9410 +scornfully 9410 +bellow 9410 +bills 9410 +cupboard 9410 +sureties 9410 +puddings 9410 +fetters 9410 +bivalves 9410 +incurring 9410 +Adolph 9410 +pithed 9410 +Miles 9410 +trimmings 9410 +tragedies 9410 +skulking 9410 +flint 9410 +flopping 9410 +relaxing 9410 +offload 9410 +suites 9410 +lists 9410 +animized 9410 +multilayer 9410 +standardizes 9410 +Judas 9410 +vacuuming 9410 +dentally 9410 +humanness 9410 +inch 9410 +Weissmuller 9410 +irresponsibly 9410 +luckily 9410 +culled 9410 +medical 9410 +bloodbath 9410 +subschema 9410 +animals 9410 +Micronesia 9410 +repetitions 9410 +Antares 9410 +ventilate 9410 +pityingly 9410 +interdependent 9410 +Graves 9410 +neonatal 9410 +chafe 9410 +honoring 9410 +realtor 9410 +elite 9410 +funereal 9410 +abrogating 9410 +sorters 9410 +Conley 9410 +lectured 9410 +Abraham 9410 +Hawaii 9410 +cage 9410 +hushes 9410 +Simla 9410 +reporters 9410 +Dutchman 9410 +descendants 9410 +groupings 9410 +dissociate 9410 +coexist 9410 +Beebe 9410 +Taoism 9410 +Connally 9410 +fetched 9410 +checkpoints 9410 +rusting 9410 +galling 9410 +obliterates 9410 +traitor 9410 +resumes 9410 +analyzable 9410 +terminator 9410 +gritty 9410 +firearm 9410 +minima 9410 +Selfridge 9410 +disable 9410 +witchcraft 9410 +betroth 9410 +Manhattanize 9410 +imprint 9410 +peeked 9410 +swelling 9410 +interrelationships 9410 +riser 9410 +Gandhian 9410 +peacock 9410 +bee 9410 +kanji 9410 +dental 9410 +scarf 9410 +chasm 9410 +insolence 9410 +syndicate 9410 +alike 9410 +imperial 9410 +convulsion 9410 +railway 9410 +validate 9410 +normalizes 9410 +comprehensive 9410 +chewing 9410 +denizen 9410 +schemer 9410 +chronicle 9410 +Kline 9410 +Anatole 9410 +partridges 9410 +brunch 9410 +recruited 9410 +dimensions 9410 +Chicana 9410 +announced 9410 +praised 9410 +employing 9410 +linear 9410 +quagmire 9410 +western 9410 +relishing 9410 +serving 9410 +scheduling 9410 +lore 9410 +eventful 9410 +arteriole 9410 +disentangle 9410 +cured 9410 +Fenton 9410 +avoidable 9410 +drains 9410 +detectably 9410 +husky 9410 +impelling 9410 +undoes 9410 +evened 9410 +squeezes 9410 +destroyer 9410 +rudeness 9410 +beaner 9410 +boorish 9410 +Everhart 9410 +encompass 9410 +mushrooms 9410 +Alison 9410 +externally 9410 +pellagra 9410 +cult 9410 +creek 9410 +Huffman 9410 +Majorca 9410 +governing 9410 +gadfly 9410 +reassigned 9410 +intentness 9410 +craziness 9410 +psychic 9410 +squabbled 9410 +burlesque 9410 +capped 9410 +extracted 9410 +DiMaggio 9410 +exclamation 9410 +subdirectory 9410 +Gothicism 9410 +feminine 9410 +metaphysically 9410 +sanding 9410 +Miltonism 9410 +freakish 9410 +index 9410 +straight 9410 +flurried 9410 +denotative 9410 +coming 9410 +commencements 9410 +gentleman 9410 +gifted 9410 +Shanghais 9410 +sportswriting 9410 +sloping 9410 +navies 9410 +leaflet 9410 +shooter 9410 +Joplin 9410 +babies 9410 +assails 9410 +admiring 9410 +swaying 9410 +Goldstine 9410 +fitting 9410 +Norwalk 9410 +analogy 9410 +deludes 9410 +cokes 9410 +Clayton 9410 +exhausts 9410 +causality 9410 +sating 9410 +icon 9410 +throttles 9410 +communicants 9410 +dehydrate 9410 +priceless 9410 +publicly 9410 +incidentals 9410 +commonplace 9410 +mumbles 9410 +furthermore 9410 +cautioned 9410 +parametrized 9410 +registration 9410 +sadly 9410 +positioning 9410 +babysitting 9410 +eternal 9410 +hoarder 9410 +congregates 9410 +rains 9410 +workers 9410 +sags 9410 +unplug 9410 +garage 9410 +boulder 9410 +specifics 9410 +Teresa 9410 +Winsett 9410 +convenient 9410 +buckboards 9410 +amenities 9410 +resplendent 9410 +sews 9410 +participated 9410 +Simon 9410 +certificates 9410 +Fitzpatrick 9410 +Evanston 9410 +misted 9410 +textures 9410 +save 9410 +count 9410 +rightful 9410 +chaperone 9410 +Lizzy 9410 +clenched 9410 +effortlessly 9410 +accessed 9410 +beaters 9410 +Hornblower 9410 +vests 9410 +indulgences 9410 +infallibly 9410 +unwilling 9410 +excrete 9410 +spools 9410 +crunches 9410 +overestimating 9410 +ineffective 9410 +humiliation 9410 +sophomore 9410 +star 9410 +rifles 9410 +dialysis 9410 +arriving 9410 +indulge 9410 +clockers 9410 +languages 9410 +Antarctica 9410 +percentage 9410 +ceiling 9410 +specification 9410 +regimented 9410 +ciphers 9410 +pictures 9410 +serpents 9410 +allot 9410 +realized 9410 +mayoral 9410 +opaquely 9410 +hostess 9410 +fiftieth 9410 +incorrectly 9410 +decomposition 9410 +stranglings 9410 +mixture 9410 +electroencephalography 9410 +similarities 9410 +charges 9410 +freest 9410 +Greenberg 9410 +tinting 9410 +expelled 9410 +warm 9410 +smoothed 9410 +deductions 9410 +Romano 9410 +bitterroot 9410 +corset 9410 +securing 9410 +environing 9410 +cute 9410 +Crays 9410 +heiress 9410 +inform 9410 +avenge 9410 +universals 9410 +Kinsey 9410 +ravines 9410 +bestseller 9410 +equilibrium 9410 +extents 9410 +relatively 9410 +pressure 9410 +critiques 9410 +befouled 9410 +rightfully 9410 +mechanizing 9410 +Latinizes 9410 +timesharing 9410 +Aden 9410 +embassies 9410 +males 9410 +shapelessly 9410 +mastering 9410 +Newtonian 9410 +finishers 9410 +abates 9410 +teem 9410 +kiting 9410 +stodgy 9410 +feed 9410 +guitars 9410 +airships 9410 +store 9410 +denounces 9410 +Pyle 9410 +Saxony 9410 +serializations 9410 +Peruvian 9410 +taxonomically 9410 +kingdom 9410 +stint 9410 +Sault 9410 +faithful 9410 +Ganymede 9410 +tidiness 9410 +gainful 9410 +contrary 9410 +Tipperary 9410 +tropics 9410 +theorizers 9410 +renew 9410 +already 9410 +terminal 9410 +Hegelian 9410 +hypothesizer 9410 +warningly 9410 +journalizing 9410 +nested 9410 +Lars 9410 +saplings 9410 +foothill 9410 +labeled 9410 +imperiously 9410 +reporters 9410 +furnishings 9410 +precipitable 9410 +discounts 9410 +excises 9410 +Stalin 9410 +despot 9410 +ripeness 9410 +Arabia 9410 +unruly 9410 +mournfulness 9410 +boom 9410 +slaughter 9410 +Sabine 9410 +handy 9410 +rural 9410 +organizer 9410 +shipyard 9410 +civics 9410 +inaccuracy 9410 +rules 9410 +juveniles 9410 +comprised 9410 +investigations 9410 +stabilizes 9410 +seminaries 9410 +Hunter 9410 +sporty 9410 +test 9410 +weasels 9410 +CERN 9410 +tempering 9410 +afore 9410 +Galatean 9410 +techniques 9410 +error 9410 +veranda 9410 +severely 9410 +Cassites 9410 +forthcoming 9410 +guides 9410 +vanish 9410 +lied 9410 +sawtooth 9410 +fated 9410 +gradually 9410 +widens 9410 +preclude 9410 +evenhandedly 9410 +percentage 9410 +disobedience 9410 +humility 9410 +gleaning 9410 +petted 9410 +bloater 9410 +minion 9410 +marginal 9410 +apiary 9410 +measures 9410 +precaution 9410 +repelled 9410 +primary 9410 +coverings 9410 +Artemia 9410 +navigate 9410 +spatial 9410 +Gurkha 9410 +meanwhile 9410 +Melinda 9410 +Butterfield 9410 +Aldrich 9410 +previewing 9410 +glut 9410 +unaffected 9410 +inmate 9410 +mineral 9410 +impending 9410 +meditation 9410 +ideas 9410 +miniaturizes 9410 +lewdly 9410 +title 9410 +youthfulness 9410 +creak 9410 +Chippewa 9410 +clamored 9410 +freezes 9410 +forgivably 9410 +reduce 9410 +McGovern 9410 +Nazis 9410 +epistle 9410 +socializes 9410 +conceptions 9410 +Kevin 9410 +uncovering 9410 +chews 9410 +appendixes 9410 +appendixes 9410 +appendixes 9410 +appendixes 9410 +appendixes 9410 +appendixes 9410 +raining 9410 +infest 9410 +compartment 9410 +minting 9410 +ducks 9410 +roped 9410 +waltz 9410 +Lillian 9410 +repressions 9410 +chillingly 9410 +noncritical 9410 +lithograph 9410 +spongers 9410 +parenthood 9410 +posed 9410 +instruments 9410 +filial 9410 +fixedly 9410 +relives 9410 +Pandora 9410 +watering 9410 +ungrateful 9410 +secures 9410 +poison 9410 +dusted 9410 +encompasses 9410 +presentation 9410 +Kantian 9410 +select fld3,period,price,price2 from t2,t3 where t2.fld1=t3.t2nr and period >= 1001 and period <= 1002 and t2.companynr = 37 order by fld3,period, price; +fld3 period price price2 +admonishing 1002 28357832 8723648 +analyzable 1002 28357832 8723648 +annihilates 1001 5987435 234724 +Antares 1002 28357832 8723648 +astound 1001 5987435 234724 +audiology 1001 5987435 234724 +Augustine 1002 28357832 8723648 +Baird 1002 28357832 8723648 +bewilderingly 1001 5987435 234724 +breaking 1001 5987435 234724 +Conley 1001 5987435 234724 +dentally 1002 28357832 8723648 +dissociate 1002 28357832 8723648 +elite 1001 5987435 234724 +eschew 1001 5987435 234724 +Eulerian 1001 5987435 234724 +flanking 1001 5987435 234724 +foldout 1002 28357832 8723648 +funereal 1002 28357832 8723648 +galling 1002 28357832 8723648 +Graves 1001 5987435 234724 +grazing 1001 5987435 234724 +groupings 1001 5987435 234724 +handgun 1001 5987435 234724 +humility 1002 28357832 8723648 +impulsive 1002 28357832 8723648 +inch 1001 5987435 234724 +intelligibility 1001 5987435 234724 +jarring 1001 5987435 234724 +lawgiver 1001 5987435 234724 +lectured 1002 28357832 8723648 +Merritt 1002 28357832 8723648 +neonatal 1001 5987435 234724 +offload 1002 28357832 8723648 +parters 1002 28357832 8723648 +pityingly 1002 28357832 8723648 +puddings 1002 28357832 8723648 +Punjab 1001 5987435 234724 +quitter 1002 28357832 8723648 +realtor 1001 5987435 234724 +relaxing 1001 5987435 234724 +repetitions 1001 5987435 234724 +resumes 1001 5987435 234724 +Romans 1002 28357832 8723648 +rusting 1001 5987435 234724 +scholastics 1001 5987435 234724 +skulking 1002 28357832 8723648 +stated 1002 28357832 8723648 +suites 1002 28357832 8723648 +sureties 1001 5987435 234724 +testicle 1002 28357832 8723648 +tinily 1002 28357832 8723648 +tragedies 1001 5987435 234724 +trimmings 1001 5987435 234724 +vacuuming 1001 5987435 234724 +ventilate 1001 5987435 234724 +wallet 1001 5987435 234724 +Weissmuller 1002 28357832 8723648 +Wotan 1002 28357832 8723648 +select t2.fld1,fld3,period,price,price2 from t2,t3 where t2.fld1>= 18201 and t2.fld1 <= 18811 and t2.fld1=t3.t2nr and period = 1001 and t2.companynr = 37; +fld1 fld3 period price price2 +018201 relaxing 1001 5987435 234724 +018601 vacuuming 1001 5987435 234724 +018801 inch 1001 5987435 234724 +018811 repetitions 1001 5987435 234724 +create table t4 ( +companynr tinyint(2) unsigned zerofill NOT NULL default '00', +companyname char(30) NOT NULL default '', +PRIMARY KEY (companynr), +UNIQUE KEY companyname(companyname) +) ENGINE=MyISAM MAX_ROWS=50 PACK_KEYS=1 COMMENT='companynames'; +select STRAIGHT_JOIN t2.companynr,companyname from t4,t2 where t2.companynr=t4.companynr group by t2.companynr; +companynr companyname +00 Unknown +29 company 1 +34 company 2 +36 company 3 +37 company 4 +40 company 5 +41 company 6 +50 company 11 +53 company 7 +58 company 8 +65 company 9 +68 company 10 +select SQL_SMALL_RESULT t2.companynr,companyname from t4,t2 where t2.companynr=t4.companynr group by t2.companynr; +companynr companyname +00 Unknown +29 company 1 +34 company 2 +36 company 3 +37 company 4 +40 company 5 +41 company 6 +50 company 11 +53 company 7 +58 company 8 +65 company 9 +68 company 10 +select * from t1,t1 t12; +Period Varor_period Period Varor_period +9410 9412 9410 9412 +select t2.fld1,t22.fld1 from t2,t2 t22 where t2.fld1 >= 250501 and t2.fld1 <= 250505 and t22.fld1 >= 250501 and t22.fld1 <= 250505; +fld1 fld1 +250501 250501 +250502 250501 +250503 250501 +250504 250501 +250505 250501 +250501 250502 +250502 250502 +250503 250502 +250504 250502 +250505 250502 +250501 250503 +250502 250503 +250503 250503 +250504 250503 +250505 250503 +250501 250504 +250502 250504 +250503 250504 +250504 250504 +250505 250504 +250501 250505 +250502 250505 +250503 250505 +250504 250505 +250505 250505 +insert into t2 (fld1, companynr) values (999999,99); +select t2.companynr,companyname from t2 left join t4 using (companynr) where t4.companynr is null; +companynr companyname +99 NULL +select count(*) from t2 left join t4 using (companynr) where t4.companynr is not null; +count(*) +1199 +explain select t2.companynr,companyname from t2 left join t4 using (companynr) where t4.companynr is null; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 1200 +1 SIMPLE t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1 Using where; Not exists +explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr is null; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 +1 SIMPLE t2 ALL NULL NULL NULL NULL 1200 Using where; Not exists +delete from t2 where fld1=999999; +explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where +1 SIMPLE t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1 +explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr < 0; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where +1 SIMPLE t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1 +explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 and t4.companynr > 0; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where +1 SIMPLE t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1 Using where +explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr is null; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where +explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr < 0 or t4.companynr > 0; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where +explain select t2.companynr,companyname from t4 left join t2 using (companynr) where ifnull(t2.companynr,1)>0; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where +select distinct t2.companynr,t4.companynr from t2,t4 where t2.companynr=t4.companynr+1; +companynr companynr +37 36 +41 40 +explain select distinct t2.companynr,t4.companynr from t2,t4 where t2.companynr=t4.companynr+1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using temporary +1 SIMPLE t4 index NULL PRIMARY 1 NULL 12 Using where; Using index +select t2.fld1,t2.companynr,fld3,period from t3,t2 where t2.fld1 = 38208 and t2.fld1=t3.t2nr and period = 1008 or t2.fld1 = 38008 and t2.fld1 =t3.t2nr and period = 1008; +fld1 companynr fld3 period +038008 37 reporters 1008 +038208 37 Selfridge 1008 +select t2.fld1,t2.companynr,fld3,period from t3,t2 where (t2.fld1 = 38208 or t2.fld1 = 38008) and t2.fld1=t3.t2nr and period>=1008 and period<=1009; +fld1 companynr fld3 period +038008 37 reporters 1008 +038208 37 Selfridge 1008 +select t2.fld1,t2.companynr,fld3,period from t3,t2 where (t3.t2nr = 38208 or t3.t2nr = 38008) and t2.fld1=t3.t2nr and period>=1008 and period<=1009; +fld1 companynr fld3 period +038008 37 reporters 1008 +038208 37 Selfridge 1008 +select period from t1 where (((period > 0) or period < 10000 or (period = 1900)) and (period=1900 and period <= 1901) or (period=1903 and (period=1903)) and period>=1902) or ((period=1904 or period=1905) or (period=1906 or period>1907)) or (period=1908 and period = 1909); +period +9410 +select period from t1 where ((period > 0 and period < 1) or (((period > 0 and period < 100) and (period > 10)) or (period > 10)) or (period > 0 and (period > 5 or period > 6))); +period +9410 +select a.fld1 from t2 as a,t2 b where ((a.fld1 = 250501 and a.fld1=b.fld1) or a.fld1=250502 or a.fld1=250503 or (a.fld1=250505 and a.fld1<=b.fld1 and b.fld1>=a.fld1)) and a.fld1=b.fld1; +fld1 +250501 +250502 +250503 +250505 +select fld1 from t2 where fld1 in (250502,98005,98006,250503,250605,250606) and fld1 >=250502 and fld1 not in (250605,250606); +fld1 +250502 +250503 +select fld1 from t2 where fld1 between 250502 and 250504; +fld1 +250502 +250503 +250504 +select fld3 from t2 where (((fld3 like "_%L%" ) or (fld3 like "%ok%")) and ( fld3 like "L%" or fld3 like "G%")) and fld3 like "L%" ; +fld3 +label +labeled +labeled +landslide +laterally +leaflet +lewdly +Lillian +luckily +select count(*) from t1; +count(*) +1 +select companynr,count(*),sum(fld1) from t2 group by companynr; +companynr count(*) sum(fld1) +00 82 10355753 +29 95 14473298 +34 70 17788966 +36 215 22786296 +37 588 83602098 +40 37 6618386 +41 52 12816335 +50 11 1595438 +53 4 793210 +58 23 2254293 +65 10 2284055 +68 12 3097288 +select companynr,count(*) from t2 group by companynr order by companynr desc limit 5; +companynr count(*) +68 12 +65 10 +58 23 +53 4 +50 11 +select count(*),min(fld4),max(fld4),sum(fld1),avg(fld1),std(fld1),variance(fld1) from t2 where companynr = 34 and fld4<>""; +count(*) min(fld4) max(fld4) sum(fld1) avg(fld1) std(fld1) variance(fld1) +70 absentee vest 17788966 254128.0857 3272.5940 10709871.3069 +explain extended select count(*),min(fld4),max(fld4),sum(fld1),avg(fld1),std(fld1),variance(fld1) from t2 where companynr = 34 and fld4<>""; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where +Warnings: +Note 1003 select count(0) AS `count(*)`,min(test.t2.fld4) AS `min(fld4)`,max(test.t2.fld4) AS `max(fld4)`,sum(test.t2.fld1) AS `sum(fld1)`,avg(test.t2.fld1) AS `avg(fld1)`,std(test.t2.fld1) AS `std(fld1)`,variance(test.t2.fld1) AS `variance(fld1)` from test.t2 where ((test.t2.companynr = 34) and (test.t2.fld4 <> _latin1'')) +select companynr,count(*),min(fld4),max(fld4),sum(fld1),avg(fld1),std(fld1),variance(fld1) from t2 group by companynr limit 3; +companynr count(*) min(fld4) max(fld4) sum(fld1) avg(fld1) std(fld1) variance(fld1) +00 82 Anthony windmills 10355753 126289.6707 115550.9757 13352027981.7087 +29 95 abut wetness 14473298 152350.5053 8368.5480 70032594.9026 +34 70 absentee vest 17788966 254128.0857 3272.5940 10709871.3069 +select companynr,t2nr,count(price),sum(price),min(price),max(price),avg(price) from t3 where companynr = 37 group by companynr,t2nr limit 10; +companynr t2nr count(price) sum(price) min(price) max(price) avg(price) +37 1 1 5987435 5987435 5987435 5987435.0000 +37 2 1 28357832 28357832 28357832 28357832.0000 +37 3 1 39654943 39654943 39654943 39654943.0000 +37 11 1 5987435 5987435 5987435 5987435.0000 +37 12 1 28357832 28357832 28357832 28357832.0000 +37 13 1 39654943 39654943 39654943 39654943.0000 +37 21 1 5987435 5987435 5987435 5987435.0000 +37 22 1 28357832 28357832 28357832 28357832.0000 +37 23 1 39654943 39654943 39654943 39654943.0000 +37 31 1 5987435 5987435 5987435 5987435.0000 +select /*! SQL_SMALL_RESULT */ companynr,t2nr,count(price),sum(price),min(price),max(price),avg(price) from t3 where companynr = 37 group by companynr,t2nr limit 10; +companynr t2nr count(price) sum(price) min(price) max(price) avg(price) +37 1 1 5987435 5987435 5987435 5987435.0000 +37 2 1 28357832 28357832 28357832 28357832.0000 +37 3 1 39654943 39654943 39654943 39654943.0000 +37 11 1 5987435 5987435 5987435 5987435.0000 +37 12 1 28357832 28357832 28357832 28357832.0000 +37 13 1 39654943 39654943 39654943 39654943.0000 +37 21 1 5987435 5987435 5987435 5987435.0000 +37 22 1 28357832 28357832 28357832 28357832.0000 +37 23 1 39654943 39654943 39654943 39654943.0000 +37 31 1 5987435 5987435 5987435 5987435.0000 +select companynr,count(price),sum(price),min(price),max(price),avg(price) from t3 group by companynr ; +companynr count(price) sum(price) min(price) max(price) avg(price) +37 12543 309394878010 5987435 39654943 24666736.6667 +78 8362 414611089292 726498 98439034 49582766.0000 +101 4181 3489454238 834598 834598 834598.0000 +154 4181 4112197254950 983543950 983543950 983543950.0000 +311 4181 979599938 234298 234298 234298.0000 +447 4181 9929180954 2374834 2374834 2374834.0000 +512 4181 3288532102 786542 786542 786542.0000 +select distinct mod(companynr,10) from t4 group by companynr; +mod(companynr,10) +0 +9 +4 +6 +7 +1 +3 +8 +5 +select distinct 1 from t4 group by companynr; +1 +1 +select count(distinct fld1) from t2; +count(distinct fld1) +1199 +select companynr,count(distinct fld1) from t2 group by companynr; +companynr count(distinct fld1) +00 82 +29 95 +34 70 +36 215 +37 588 +40 37 +41 52 +50 11 +53 4 +58 23 +65 10 +68 12 +select companynr,count(*) from t2 group by companynr; +companynr count(*) +00 82 +29 95 +34 70 +36 215 +37 588 +40 37 +41 52 +50 11 +53 4 +58 23 +65 10 +68 12 +select companynr,count(distinct concat(fld1,repeat(65,1000))) from t2 group by companynr; +companynr count(distinct concat(fld1,repeat(65,1000))) +00 82 +29 95 +34 70 +36 215 +37 588 +40 37 +41 52 +50 11 +53 4 +58 23 +65 10 +68 12 +select companynr,count(distinct concat(fld1,repeat(65,200))) from t2 group by companynr; +companynr count(distinct concat(fld1,repeat(65,200))) +00 82 +29 95 +34 70 +36 215 +37 588 +40 37 +41 52 +50 11 +53 4 +58 23 +65 10 +68 12 +select companynr,count(distinct floor(fld1/100)) from t2 group by companynr; +companynr count(distinct floor(fld1/100)) +00 47 +29 35 +34 14 +36 69 +37 108 +40 16 +41 11 +50 9 +53 1 +58 1 +65 1 +68 1 +select companynr,count(distinct concat(repeat(65,1000),floor(fld1/100))) from t2 group by companynr; +companynr count(distinct concat(repeat(65,1000),floor(fld1/100))) +00 47 +29 35 +34 14 +36 69 +37 108 +40 16 +41 11 +50 9 +53 1 +58 1 +65 1 +68 1 +select sum(fld1),fld3 from t2 where fld3="Romans" group by fld1 limit 10; +sum(fld1) fld3 +11402 Romans +select name,count(*) from t3 where name='cloakroom' group by name; +name count(*) +cloakroom 4181 +select name,count(*) from t3 where name='cloakroom' and price>10 group by name; +name count(*) +cloakroom 4181 +select count(*) from t3 where name='cloakroom' and price2=823742; +count(*) +4181 +select name,count(*) from t3 where name='cloakroom' and price2=823742 group by name; +name count(*) +cloakroom 4181 +select name,count(*) from t3 where name >= "extramarital" and price <= 39654943 group by name; +name count(*) +extramarital 4181 +gazer 4181 +gems 4181 +Iranizes 4181 +spates 4181 +tucked 4181 +violinist 4181 +select t2.fld3,count(*) from t2,t3 where t2.fld1=158402 and t3.name=t2.fld3 group by t3.name; +fld3 count(*) +spates 4181 +select companynr|0,companyname from t4 group by 1; +companynr|0 companyname +0 Unknown +29 company 1 +34 company 2 +36 company 3 +37 company 4 +40 company 5 +41 company 6 +50 company 11 +53 company 7 +58 company 8 +65 company 9 +68 company 10 +select t2.companynr,companyname,count(*) from t2,t4 where t2.companynr=t4.companynr group by t2.companynr order by companyname; +companynr companyname count(*) +29 company 1 95 +68 company 10 12 +50 company 11 11 +34 company 2 70 +36 company 3 215 +37 company 4 588 +40 company 5 37 +41 company 6 52 +53 company 7 4 +58 company 8 23 +65 company 9 10 +00 Unknown 82 +select t2.fld1,count(*) from t2,t3 where t2.fld1=158402 and t3.name=t2.fld3 group by t3.name; +fld1 count(*) +158402 4181 +select sum(Period)/count(*) from t1; +sum(Period)/count(*) +9410.00 +select companynr,count(price) as "count",sum(price) as "sum" ,abs(sum(price)/count(price)-avg(price)) as "diff",(0+count(price))*companynr as func from t3 group by companynr; +companynr count sum diff func +37 12543 309394878010 0.0000 464091 +78 8362 414611089292 0.0000 652236 +101 4181 3489454238 0.0000 422281 +154 4181 4112197254950 0.0000 643874 +311 4181 979599938 0.0000 1300291 +447 4181 9929180954 0.0000 1868907 +512 4181 3288532102 0.0000 2140672 +select companynr,sum(price)/count(price) as avg from t3 group by companynr having avg > 70000000 order by avg; +companynr avg +154 983543950.00 +select companynr,count(*) from t2 group by companynr order by 2 desc; +companynr count(*) +37 588 +36 215 +29 95 +00 82 +34 70 +41 52 +40 37 +58 23 +68 12 +50 11 +65 10 +53 4 +select companynr,count(*) from t2 where companynr > 40 group by companynr order by 2 desc; +companynr count(*) +41 52 +58 23 +68 12 +50 11 +65 10 +53 4 +select t2.fld4,t2.fld1,count(price),sum(price),min(price),max(price),avg(price) from t3,t2 where t3.companynr = 37 and t2.fld1 = t3.t2nr group by fld1,t2.fld4; +fld4 fld1 count(price) sum(price) min(price) max(price) avg(price) +teethe 000001 1 5987435 5987435 5987435 5987435.0000 +dreaded 011401 1 5987435 5987435 5987435 5987435.0000 +scholastics 011402 1 28357832 28357832 28357832 28357832.0000 +audiology 011403 1 39654943 39654943 39654943 39654943.0000 +wallet 011501 1 5987435 5987435 5987435 5987435.0000 +parters 011701 1 5987435 5987435 5987435 5987435.0000 +eschew 011702 1 28357832 28357832 28357832 28357832.0000 +quitter 011703 1 39654943 39654943 39654943 39654943.0000 +neat 012001 1 5987435 5987435 5987435 5987435.0000 +Steinberg 012003 1 39654943 39654943 39654943 39654943.0000 +balled 012301 1 5987435 5987435 5987435 5987435.0000 +persist 012302 1 28357832 28357832 28357832 28357832.0000 +attainments 012303 1 39654943 39654943 39654943 39654943.0000 +capably 012501 1 5987435 5987435 5987435 5987435.0000 +impulsive 012602 1 28357832 28357832 28357832 28357832.0000 +starlet 012603 1 39654943 39654943 39654943 39654943.0000 +featherweight 012701 1 5987435 5987435 5987435 5987435.0000 +pessimist 012702 1 28357832 28357832 28357832 28357832.0000 +daughter 012703 1 39654943 39654943 39654943 39654943.0000 +lawgiver 013601 1 5987435 5987435 5987435 5987435.0000 +stated 013602 1 28357832 28357832 28357832 28357832.0000 +readable 013603 1 39654943 39654943 39654943 39654943.0000 +testicle 013801 1 5987435 5987435 5987435 5987435.0000 +Parsifal 013802 1 28357832 28357832 28357832 28357832.0000 +leavings 013803 1 39654943 39654943 39654943 39654943.0000 +squeaking 013901 1 5987435 5987435 5987435 5987435.0000 +contrasted 016001 1 5987435 5987435 5987435 5987435.0000 +leftover 016201 1 5987435 5987435 5987435 5987435.0000 +whiteners 016202 1 28357832 28357832 28357832 28357832.0000 +erases 016301 1 5987435 5987435 5987435 5987435.0000 +Punjab 016302 1 28357832 28357832 28357832 28357832.0000 +Merritt 016303 1 39654943 39654943 39654943 39654943.0000 +sweetish 018001 1 5987435 5987435 5987435 5987435.0000 +dogging 018002 1 28357832 28357832 28357832 28357832.0000 +scornfully 018003 1 39654943 39654943 39654943 39654943.0000 +fetters 018012 1 28357832 28357832 28357832 28357832.0000 +bivalves 018013 1 39654943 39654943 39654943 39654943.0000 +skulking 018021 1 5987435 5987435 5987435 5987435.0000 +flint 018022 1 28357832 28357832 28357832 28357832.0000 +flopping 018023 1 39654943 39654943 39654943 39654943.0000 +Judas 018032 1 28357832 28357832 28357832 28357832.0000 +vacuuming 018033 1 39654943 39654943 39654943 39654943.0000 +medical 018041 1 5987435 5987435 5987435 5987435.0000 +bloodbath 018042 1 28357832 28357832 28357832 28357832.0000 +subschema 018043 1 39654943 39654943 39654943 39654943.0000 +interdependent 018051 1 5987435 5987435 5987435 5987435.0000 +Graves 018052 1 28357832 28357832 28357832 28357832.0000 +neonatal 018053 1 39654943 39654943 39654943 39654943.0000 +sorters 018061 1 5987435 5987435 5987435 5987435.0000 +epistle 018062 1 28357832 28357832 28357832 28357832.0000 +Conley 018101 1 5987435 5987435 5987435 5987435.0000 +lectured 018102 1 28357832 28357832 28357832 28357832.0000 +Abraham 018103 1 39654943 39654943 39654943 39654943.0000 +cage 018201 1 5987435 5987435 5987435 5987435.0000 +hushes 018202 1 28357832 28357832 28357832 28357832.0000 +Simla 018402 1 28357832 28357832 28357832 28357832.0000 +reporters 018403 1 39654943 39654943 39654943 39654943.0000 +coexist 018601 1 5987435 5987435 5987435 5987435.0000 +Beebe 018602 1 28357832 28357832 28357832 28357832.0000 +Taoism 018603 1 39654943 39654943 39654943 39654943.0000 +Connally 018801 1 5987435 5987435 5987435 5987435.0000 +fetched 018802 1 28357832 28357832 28357832 28357832.0000 +checkpoints 018803 1 39654943 39654943 39654943 39654943.0000 +gritty 018811 1 5987435 5987435 5987435 5987435.0000 +firearm 018812 1 28357832 28357832 28357832 28357832.0000 +minima 019101 1 5987435 5987435 5987435 5987435.0000 +Selfridge 019102 1 28357832 28357832 28357832 28357832.0000 +disable 019103 1 39654943 39654943 39654943 39654943.0000 +witchcraft 019201 1 5987435 5987435 5987435 5987435.0000 +betroth 030501 1 5987435 5987435 5987435 5987435.0000 +Manhattanize 030502 1 28357832 28357832 28357832 28357832.0000 +imprint 030503 1 39654943 39654943 39654943 39654943.0000 +swelling 031901 1 5987435 5987435 5987435 5987435.0000 +interrelationships 036001 1 5987435 5987435 5987435 5987435.0000 +riser 036002 1 28357832 28357832 28357832 28357832.0000 +bee 038001 1 5987435 5987435 5987435 5987435.0000 +kanji 038002 1 28357832 28357832 28357832 28357832.0000 +dental 038003 1 39654943 39654943 39654943 39654943.0000 +railway 038011 1 5987435 5987435 5987435 5987435.0000 +validate 038012 1 28357832 28357832 28357832 28357832.0000 +normalizes 038013 1 39654943 39654943 39654943 39654943.0000 +Kline 038101 1 5987435 5987435 5987435 5987435.0000 +Anatole 038102 1 28357832 28357832 28357832 28357832.0000 +partridges 038103 1 39654943 39654943 39654943 39654943.0000 +recruited 038201 1 5987435 5987435 5987435 5987435.0000 +dimensions 038202 1 28357832 28357832 28357832 28357832.0000 +Chicana 038203 1 39654943 39654943 39654943 39654943.0000 +select t3.companynr,fld3,sum(price) from t3,t2 where t2.fld1 = t3.t2nr and t3.companynr = 512 group by companynr,fld3; +companynr fld3 sum(price) +512 boat 786542 +512 capably 786542 +512 cupboard 786542 +512 decliner 786542 +512 descendants 786542 +512 dopers 786542 +512 erases 786542 +512 Micronesia 786542 +512 Miles 786542 +512 skies 786542 +select t2.companynr,count(*),min(fld3),max(fld3),sum(price),avg(price) from t2,t3 where t3.companynr >= 30 and t3.companynr <= 58 and t3.t2nr = t2.fld1 and 1+1=2 group by t2.companynr; +companynr count(*) min(fld3) max(fld3) sum(price) avg(price) +00 1 Omaha Omaha 5987435 5987435.0000 +36 1 dubbed dubbed 28357832 28357832.0000 +37 83 Abraham Wotan 1908978016 22999735.1325 +50 2 scribbled tapestry 68012775 34006387.5000 +select t3.companynr+0,t3.t2nr,fld3,sum(price) from t3,t2 where t2.fld1 = t3.t2nr and t3.companynr = 37 group by 1,t3.t2nr,fld3,fld3,fld3,fld3,fld3 order by fld1; +t3.companynr+0 t2nr fld3 sum(price) +37 1 Omaha 5987435 +37 11401 breaking 5987435 +37 11402 Romans 28357832 +37 11403 intercepted 39654943 +37 11501 bewilderingly 5987435 +37 11701 astound 5987435 +37 11702 admonishing 28357832 +37 11703 sumac 39654943 +37 12001 flanking 5987435 +37 12003 combed 39654943 +37 12301 Eulerian 5987435 +37 12302 dubbed 28357832 +37 12303 Kane 39654943 +37 12501 annihilates 5987435 +37 12602 Wotan 28357832 +37 12603 snatching 39654943 +37 12701 grazing 5987435 +37 12702 Baird 28357832 +37 12703 celery 39654943 +37 13601 handgun 5987435 +37 13602 foldout 28357832 +37 13603 mystic 39654943 +37 13801 intelligibility 5987435 +37 13802 Augustine 28357832 +37 13803 teethe 39654943 +37 13901 scholastics 5987435 +37 16001 audiology 5987435 +37 16201 wallet 5987435 +37 16202 parters 28357832 +37 16301 eschew 5987435 +37 16302 quitter 28357832 +37 16303 neat 39654943 +37 18001 jarring 5987435 +37 18002 tinily 28357832 +37 18003 balled 39654943 +37 18012 impulsive 28357832 +37 18013 starlet 39654943 +37 18021 lawgiver 5987435 +37 18022 stated 28357832 +37 18023 readable 39654943 +37 18032 testicle 28357832 +37 18033 Parsifal 39654943 +37 18041 Punjab 5987435 +37 18042 Merritt 28357832 +37 18043 Quixotism 39654943 +37 18051 sureties 5987435 +37 18052 puddings 28357832 +37 18053 tapestry 39654943 +37 18061 trimmings 5987435 +37 18062 humility 28357832 +37 18101 tragedies 5987435 +37 18102 skulking 28357832 +37 18103 flint 39654943 +37 18201 relaxing 5987435 +37 18202 offload 28357832 +37 18402 suites 28357832 +37 18403 lists 39654943 +37 18601 vacuuming 5987435 +37 18602 dentally 28357832 +37 18603 humanness 39654943 +37 18801 inch 5987435 +37 18802 Weissmuller 28357832 +37 18803 irresponsibly 39654943 +37 18811 repetitions 5987435 +37 18812 Antares 28357832 +37 19101 ventilate 5987435 +37 19102 pityingly 28357832 +37 19103 interdependent 39654943 +37 19201 Graves 5987435 +37 30501 neonatal 5987435 +37 30502 scribbled 28357832 +37 30503 chafe 39654943 +37 31901 realtor 5987435 +37 36001 elite 5987435 +37 36002 funereal 28357832 +37 38001 Conley 5987435 +37 38002 lectured 28357832 +37 38003 Abraham 39654943 +37 38011 groupings 5987435 +37 38012 dissociate 28357832 +37 38013 coexist 39654943 +37 38101 rusting 5987435 +37 38102 galling 28357832 +37 38103 obliterates 39654943 +37 38201 resumes 5987435 +37 38202 analyzable 28357832 +37 38203 terminator 39654943 +select sum(price) from t3,t2 where t2.fld1 = t3.t2nr and t3.companynr = 512 and t3.t2nr = 38008 and t2.fld1 = 38008 or t2.fld1= t3.t2nr and t3.t2nr = 38008 and t2.fld1 = 38008; +sum(price) +234298 +select t2.fld1,sum(price) from t3,t2 where t2.fld1 = t3.t2nr and t3.companynr = 512 and t3.t2nr = 38008 and t2.fld1 = 38008 or t2.fld1 = t3.t2nr and t3.t2nr = 38008 and t2.fld1 = 38008 or t3.t2nr = t2.fld1 and t2.fld1 = 38008 group by t2.fld1; +fld1 sum(price) +038008 234298 +explain select fld3 from t2 where 1>2 or 2>3; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +explain select fld3 from t2 where fld1=fld1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 +select companynr,fld1 from t2 HAVING fld1=250501 or fld1=250502; +companynr fld1 +34 250501 +34 250502 +select companynr,fld1 from t2 WHERE fld1>=250501 HAVING fld1<=250502; +companynr fld1 +34 250501 +34 250502 +select companynr,count(*) as count,sum(fld1) as sum from t2 group by companynr having count > 40 and sum/count >= 120000; +companynr count sum +00 82 10355753 +29 95 14473298 +34 70 17788966 +37 588 83602098 +41 52 12816335 +select companynr from t2 group by companynr having count(*) > 40 and sum(fld1)/count(*) >= 120000 ; +companynr +00 +29 +34 +37 +41 +select t2.companynr,companyname,count(*) from t2,t4 where t2.companynr=t4.companynr group by companyname having t2.companynr >= 40; +companynr companyname count(*) +68 company 10 12 +50 company 11 11 +40 company 5 37 +41 company 6 52 +53 company 7 4 +58 company 8 23 +65 company 9 10 +select count(*) from t2; +count(*) +1199 +select count(*) from t2 where fld1 < 098024; +count(*) +387 +select min(fld1) from t2 where fld1>= 098024; +min(fld1) +98024 +select max(fld1) from t2 where fld1>= 098024; +max(fld1) +1232609 +select count(*) from t3 where price2=76234234; +count(*) +4181 +select count(*) from t3 where companynr=512 and price2=76234234; +count(*) +4181 +explain select min(fld1),max(fld1),count(*) from t2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +select min(fld1),max(fld1),count(*) from t2; +min(fld1) max(fld1) count(*) +0 1232609 1199 +select min(t2nr),max(t2nr) from t3 where t2nr=2115 and price2=823742; +min(t2nr) max(t2nr) +2115 2115 +select count(*),min(t2nr),max(t2nr) from t3 where name='spates' and companynr=78; +count(*) min(t2nr) max(t2nr) +4181 4 41804 +select t2nr,count(*) from t3 where name='gems' group by t2nr limit 20; +t2nr count(*) +9 1 +19 1 +29 1 +39 1 +49 1 +59 1 +69 1 +79 1 +89 1 +99 1 +109 1 +119 1 +129 1 +139 1 +149 1 +159 1 +169 1 +179 1 +189 1 +199 1 +select max(t2nr) from t3 where price=983543950; +max(t2nr) +41807 +select t1.period from t3 = t1 limit 1; +period +1001 +select t1.period from t1 as t1 limit 1; +period +9410 +select t1.period as "Nuvarande period" from t1 as t1 limit 1; +Nuvarande period +9410 +select period as ok_period from t1 limit 1; +ok_period +9410 +select period as ok_period from t1 group by ok_period limit 1; +ok_period +9410 +select 1+1 as summa from t1 group by summa limit 1; +summa +2 +select period as "Nuvarande period" from t1 group by "Nuvarande period" limit 1; +Nuvarande period +9410 +show tables; +Tables_in_test +t1 +t2 +t3 +t4 +show tables from test like "s%"; +Tables_in_test (s%) +show tables from test like "t?"; +Tables_in_test (t?) +show full columns from t2; +Field Type Collation Null Key Default Extra Privileges Comment +auto int(11) NULL PRI NULL auto_increment +fld1 int(6) unsigned zerofill NULL UNI 000000 +companynr tinyint(2) unsigned zerofill NULL 00 +fld3 char(30) latin1_swedish_ci MUL +fld4 char(35) latin1_swedish_ci +fld5 char(35) latin1_swedish_ci +fld6 char(4) latin1_swedish_ci +show full columns from t2 from test like 'f%'; +Field Type Collation Null Key Default Extra Privileges Comment +fld1 int(6) unsigned zerofill NULL UNI 000000 +fld3 char(30) latin1_swedish_ci MUL +fld4 char(35) latin1_swedish_ci +fld5 char(35) latin1_swedish_ci +fld6 char(4) latin1_swedish_ci +show full columns from t2 from test like 's%'; +Field Type Collation Null Key Default Extra Privileges Comment +show keys from t2; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t2 0 PRIMARY 1 auto A 1199 NULL NULL BTREE +t2 0 fld1 1 fld1 A 1199 NULL NULL BTREE +t2 1 fld3 1 fld3 A NULL NULL NULL BTREE +drop table t4, t3, t2, t1; +DO 1; +DO benchmark(100,1+1),1,1; +CREATE TABLE t1 ( +id mediumint(8) unsigned NOT NULL auto_increment, +pseudo varchar(35) NOT NULL default '', +PRIMARY KEY (id), +UNIQUE KEY pseudo (pseudo) +); +INSERT INTO t1 (pseudo) VALUES ('test'); +INSERT INTO t1 (pseudo) VALUES ('test1'); +SELECT 1 as rnd1 from t1 where rand() > 2; +rnd1 +DROP TABLE t1; +CREATE TABLE t1 (gvid int(10) unsigned default NULL, hmid int(10) unsigned default NULL, volid int(10) unsigned default NULL, mmid int(10) unsigned default NULL, hdid int(10) unsigned default NULL, fsid int(10) unsigned default NULL, ctid int(10) unsigned default NULL, dtid int(10) unsigned default NULL, cost int(10) unsigned default NULL, performance int(10) unsigned default NULL, serialnumber bigint(20) unsigned default NULL, monitored tinyint(3) unsigned default '1', removed tinyint(3) unsigned default '0', target tinyint(3) unsigned default '0', dt_modified timestamp(14) NOT NULL, name varchar(255) binary default NULL, description varchar(255) default NULL, UNIQUE KEY hmid (hmid,volid)) ENGINE=MyISAM; +INSERT INTO t1 VALUES (200001,2,1,1,100,1,1,1,0,0,0,1,0,1,20020425060057,'\\\\ARKIVIO-TESTPDC\\E$',''),(200002,2,2,1,101,1,1,1,0,0,0,1,0,1,20020425060057,'\\\\ARKIVIO-TESTPDC\\C$',''),(200003,1,3,2,NULL,NULL,NULL,NULL,NULL,NULL,NULL,1,0,1,20020425060427,'c:',NULL); +CREATE TABLE t2 ( hmid int(10) unsigned default NULL, volid int(10) unsigned default NULL, sampletid smallint(5) unsigned default NULL, sampletime datetime default NULL, samplevalue bigint(20) unsigned default NULL, KEY idx1 (hmid,volid,sampletid,sampletime)) ENGINE=MyISAM; +INSERT INTO t2 VALUES (1,3,10,'2002-06-01 08:00:00',35),(1,3,1010,'2002-06-01 12:00:01',35); +SELECT a.gvid, (SUM(CASE b.sampletid WHEN 140 THEN b.samplevalue ELSE 0 END)) as the_success,(SUM(CASE b.sampletid WHEN 141 THEN b.samplevalue ELSE 0 END)) as the_fail,(SUM(CASE b.sampletid WHEN 142 THEN b.samplevalue ELSE 0 END)) as the_size,(SUM(CASE b.sampletid WHEN 143 THEN b.samplevalue ELSE 0 END)) as the_time FROM t1 a, t2 b WHERE a.hmid = b.hmid AND a.volid = b.volid AND b.sampletime >= 'wrong-date-value' AND b.sampletime < 'wrong-date-value' AND b.sampletid IN (140, 141, 142, 143) GROUP BY a.gvid; +gvid the_success the_fail the_size the_time +Warnings: +Warning 1292 Truncated incorrect datetime value: 'wrong-date-value' +Warning 1292 Truncated incorrect datetime value: 'wrong-date-value' +Warning 1292 Truncated incorrect datetime value: 'wrong-date-value' +Warning 1292 Truncated incorrect datetime value: 'wrong-date-value' +SELECT a.gvid, (SUM(CASE b.sampletid WHEN 140 THEN b.samplevalue ELSE 0 END)) as the_success,(SUM(CASE b.sampletid WHEN 141 THEN b.samplevalue ELSE 0 END)) as the_fail,(SUM(CASE b.sampletid WHEN 142 THEN b.samplevalue ELSE 0 END)) as the_size,(SUM(CASE b.sampletid WHEN 143 THEN b.samplevalue ELSE 0 END)) as the_time FROM t1 a, t2 b WHERE a.hmid = b.hmid AND a.volid = b.volid AND b.sampletime >= NULL AND b.sampletime < NULL AND b.sampletid IN (140, 141, 142, 143) GROUP BY a.gvid; +gvid the_success the_fail the_size the_time +DROP TABLE t1,t2; +create table t1 ( A_Id bigint(20) NOT NULL default '0', A_UpdateBy char(10) NOT NULL default '', A_UpdateDate bigint(20) NOT NULL default '0', A_UpdateSerial int(11) NOT NULL default '0', other_types bigint(20) NOT NULL default '0', wss_type bigint(20) NOT NULL default '0'); +INSERT INTO t1 VALUES (102935998719055004,'brade',1029359987,2,102935229116544068,102935229216544093); +select wss_type from t1 where wss_type ='102935229216544106'; +wss_type +select wss_type from t1 where wss_type ='102935229216544105'; +wss_type +select wss_type from t1 where wss_type ='102935229216544104'; +wss_type +select wss_type from t1 where wss_type ='102935229216544093'; +wss_type +102935229216544093 +select wss_type from t1 where wss_type =102935229216544093; +wss_type +102935229216544093 +drop table t1; +select 1+2,"aaaa",3.13*2.0 into @a,@b,@c; +select @a; +@a +3 +select @b; +@b +aaaa +select @c; +@c +6.26 +create table t1 (a int not null auto_increment primary key); +insert into t1 values (); +insert into t1 values (); +insert into t1 values (); +select * from (t1 as t2 left join t1 as t3 using (a)), t1; +a a a +1 1 1 +2 2 1 +3 3 1 +1 1 2 +2 2 2 +3 3 2 +1 1 3 +2 2 3 +3 3 3 +select * from t1, (t1 as t2 left join t1 as t3 using (a)); +a a a +1 1 1 +2 1 1 +3 1 1 +1 2 2 +2 2 2 +3 2 2 +1 3 3 +2 3 3 +3 3 3 +select * from (t1 as t2 left join t1 as t3 using (a)) straight_join t1; +a a a +1 1 1 +2 2 1 +3 3 1 +1 1 2 +2 2 2 +3 3 2 +1 1 3 +2 2 3 +3 3 3 +select * from t1 straight_join (t1 as t2 left join t1 as t3 using (a)); +a a a +1 1 1 +2 1 1 +3 1 1 +1 2 2 +2 2 2 +3 2 2 +1 3 3 +2 3 3 +3 3 3 +select * from (t1 as t2 left join t1 as t3 using (a)) inner join t1 on t1.a>1; +a a a +1 1 2 +1 1 3 +2 2 2 +2 2 3 +3 3 2 +3 3 3 +select * from t1 inner join (t1 as t2 left join t1 as t3 using (a)) on t1.a>1; +a a a +1 1 NULL +2 1 1 +3 1 1 +1 2 NULL +2 2 2 +3 2 2 +1 3 NULL +2 3 3 +3 3 3 +select * from (t1 as t2 left join t1 as t3 using (a)) inner join t1 using ( a ); +a a a +1 1 1 +2 2 2 +3 3 3 +select * from t1 inner join (t1 as t2 left join t1 as t3 using (a)) using ( a ); +a a a +1 1 1 +2 1 NULL +3 1 NULL +1 2 NULL +2 2 2 +3 2 NULL +1 3 NULL +2 3 NULL +3 3 3 +select * from (t1 as t2 left join t1 as t3 using (a)) left outer join t1 on t1.a>1; +a a a +1 1 2 +1 1 3 +2 2 2 +2 2 3 +3 3 2 +3 3 3 +select * from t1 left outer join (t1 as t2 left join t1 as t3 using (a)) on t1.a>1; +a a a +1 1 NULL +2 1 1 +3 1 1 +1 2 NULL +2 2 2 +3 2 2 +1 3 NULL +2 3 3 +3 3 3 +select * from (t1 as t2 left join t1 as t3 using (a)) left join t1 using ( a ); +a a a +1 1 1 +2 2 2 +3 3 3 +select * from t1 left join (t1 as t2 left join t1 as t3 using (a)) using ( a ); +a a a +1 1 1 +2 1 NULL +3 1 NULL +1 2 NULL +2 2 2 +3 2 NULL +1 3 NULL +2 3 NULL +3 3 3 +select * from (t1 as t2 left join t1 as t3 using (a)) natural left join t1; +a a a +1 1 1 +2 2 2 +3 3 3 +select * from t1 natural left join (t1 as t2 left join t1 as t3 using (a)); +a a a +1 1 1 +2 2 2 +3 3 3 +select * from (t1 as t2 left join t1 as t3 using (a)) right join t1 on t1.a>1; +a a a +1 NULL 1 +2 NULL 1 +3 NULL 1 +1 1 2 +2 2 2 +3 3 2 +1 1 3 +2 2 3 +3 3 3 +select * from t1 right join (t1 as t2 left join t1 as t3 using (a)) on t1.a>1; +a a a +2 1 1 +3 1 1 +2 2 2 +3 2 2 +2 3 3 +3 3 3 +select * from (t1 as t2 left join t1 as t3 using (a)) right outer join t1 using ( a ); +a a a +1 1 1 +2 NULL 1 +3 NULL 1 +1 NULL 2 +2 2 2 +3 NULL 2 +1 NULL 3 +2 NULL 3 +3 3 3 +select * from t1 right outer join (t1 as t2 left join t1 as t3 using (a)) using ( a ); +a a a +1 1 1 +2 2 2 +3 3 3 +select * from (t1 as t2 left join t1 as t3 using (a)) natural right join t1; +a a a +1 1 1 +2 NULL 1 +3 NULL 1 +1 NULL 2 +2 2 2 +3 NULL 2 +1 NULL 3 +2 NULL 3 +3 3 3 +select * from t1 natural right join (t1 as t2 left join t1 as t3 using (a)); +a a a +1 1 1 +2 2 2 +3 3 3 +select * from t1 natural join (t1 as t2 left join t1 as t3 using (a)); +a a +1 1 +2 2 +3 3 +select * from (t1 as t2 left join t1 as t3 using (a)) natural join t1; +a a a +1 1 1 +2 2 2 +3 3 3 +drop table t1; +CREATE TABLE t1 ( aa char(2), id int(11) NOT NULL auto_increment, t2_id int(11) NOT NULL default '0', PRIMARY KEY (id), KEY replace_id (t2_id)) ENGINE=MyISAM; +INSERT INTO t1 VALUES ("1",8264,2506),("2",8299,2517),("3",8301,2518),("4",8302,2519),("5",8303,2520),("6",8304,2521),("7",8305,2522); +CREATE TABLE t2 ( id int(11) NOT NULL auto_increment, PRIMARY KEY (id)) ENGINE=MyISAM; +INSERT INTO t2 VALUES (2517), (2518), (2519), (2520), (2521), (2522); +select * from t1, t2 WHERE t1.t2_id = t2.id and t1.t2_id > 0 order by t1.id LIMIT 0, 5; +aa id t2_id id +2 8299 2517 2517 +3 8301 2518 2518 +4 8302 2519 2519 +5 8303 2520 2520 +6 8304 2521 2521 +drop table t1,t2; +create table t1 (id1 int NOT NULL); +create table t2 (id2 int NOT NULL); +create table t3 (id3 int NOT NULL); +create table t4 (id4 int NOT NULL, id44 int NOT NULL, KEY (id4)); +insert into t1 values (1); +insert into t1 values (2); +insert into t2 values (1); +insert into t4 values (1,1); +explain select * from t1 left join t2 on id1 = id2 left join t3 on id1 = id3 +left join t4 on id3 = id4 where id2 = 1 or id4 = 1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t3 system NULL NULL NULL NULL 0 const row not found +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 +1 SIMPLE t2 ALL NULL NULL NULL NULL 1 +1 SIMPLE t4 ALL id4 NULL NULL NULL 1 Using where +select * from t1 left join t2 on id1 = id2 left join t3 on id1 = id3 +left join t4 on id3 = id4 where id2 = 1 or id4 = 1; +id1 id2 id3 id4 id44 +1 1 NULL NULL NULL +drop table t1,t2,t3,t4; +create table t1(s varchar(10) not null); +create table t2(s varchar(10) not null primary key); +create table t3(s varchar(10) not null primary key); +insert into t1 values ('one\t'), ('two\t'); +insert into t2 values ('one\r'), ('two\t'); +insert into t3 values ('one '), ('two\t'); +select * from t1 where s = 'one'; +s +select * from t2 where s = 'one'; +s +select * from t3 where s = 'one'; +s +one +select * from t1,t2 where t1.s = t2.s; +s s +two two +select * from t2,t3 where t2.s = t3.s; +s s +two two +drop table t1, t2, t3; +CREATE TABLE t1 ( +i int(11) NOT NULL default '0', +c char(10) NOT NULL default '', +PRIMARY KEY (i), +UNIQUE KEY c (c) +) ENGINE=MyISAM; +INSERT INTO t1 VALUES (1,'a'); +INSERT INTO t1 VALUES (2,'b'); +INSERT INTO t1 VALUES (3,'c'); +EXPLAIN SELECT i FROM t1 WHERE i=1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 Using index +EXPLAIN SELECT i FROM t1 WHERE i=1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 Using index +DROP TABLE t1; diff --git a/mysql-test/r/type_blob.result.es b/mysql-test/r/type_blob.result.es new file mode 100644 index 00000000000..84d02b4a4b4 --- /dev/null +++ b/mysql-test/r/type_blob.result.es @@ -0,0 +1,692 @@ +drop table if exists t1,t2,t3,t4,t5,t6,t7; +CREATE TABLE t1 (a blob, b text, c blob(250), d text(70000), e text(70000000)); +show columns from t1; +Field Type Null Key Default Extra +a blob YES NULL +b text YES NULL +c blob YES NULL +d mediumtext YES NULL +e longtext YES NULL +CREATE TABLE t2 (a char(257), b varbinary(70000), c varchar(70000000)); +Warnings: +Warning 1246 Converting column 'a' from CHAR to TEXT +Warning 1246 Converting column 'b' from CHAR to BLOB +Warning 1246 Converting column 'c' from CHAR to TEXT +show columns from t2; +Field Type Null Key Default Extra +a text YES NULL +b mediumblob YES NULL +c longtext YES NULL +create table t3 (a long, b long byte); +show create TABLE t3; +Table Create Table +t3 CREATE TABLE `t3` ( + `a` mediumtext, + `b` mediumblob +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1,t2,t3 +#; +CREATE TABLE t1 (a char(257) default "hello"); +ERROR 42000: Column length too big for column 'a' (max = 255); use BLOB instead +CREATE TABLE t2 (a blob default "hello"); +ERROR 42000: BLOB/TEXT column 'a' can't have a default value +drop table if exists t1,t2; +create table t1 (nr int(5) not null auto_increment,b blob,str char(10), primary key (nr)); +insert into t1 values (null,"a","A"); +insert into t1 values (null,"bbb","BBB"); +insert into t1 values (null,"ccc","CCC"); +select last_insert_id(); +last_insert_id() +3 +select * from t1,t1 as t2; +nr b str nr b str +1 a A 1 a A +2 bbb BBB 1 a A +3 ccc CCC 1 a A +1 a A 2 bbb BBB +2 bbb BBB 2 bbb BBB +3 ccc CCC 2 bbb BBB +1 a A 3 ccc CCC +2 bbb BBB 3 ccc CCC +3 ccc CCC 3 ccc CCC +drop table t1; +create table t1 (a text); +insert into t1 values ('where'); +update t1 set a='Where'; +select * from t1; +a +Where +drop table t1; +create table t1 (t text,c char(10),b blob, d binary(10)); +insert into t1 values (NULL,NULL,NULL,NULL); +insert into t1 values ("","","",""); +insert into t1 values ("hello","hello","hello","hello"); +insert into t1 values ("HELLO","HELLO","HELLO","HELLO"); +insert into t1 values ("HELLO MY","HELLO MY","HELLO MY","HELLO MY"); +insert into t1 values ("a","a","a","a"); +insert into t1 values (1,1,1,1); +insert into t1 values (NULL,NULL,NULL,NULL); +update t1 set c="",b=null where c="1"; +lock tables t1 READ; +show full fields from t1; +Field Type Collation Null Key Default Extra Privileges Comment +t text latin1_swedish_ci YES NULL +c varchar(10) latin1_swedish_ci YES NULL +b blob NULL YES NULL +d varbinary(10) NULL YES NULL +lock tables t1 WRITE; +show full fields from t1; +Field Type Collation Null Key Default Extra Privileges Comment +t text latin1_swedish_ci YES NULL +c varchar(10) latin1_swedish_ci YES NULL +b blob NULL YES NULL +d varbinary(10) NULL YES NULL +unlock tables; +select t from t1 where t like "hello"; +t +hello +HELLO +select c from t1 where c like "hello"; +c +hello +HELLO +select b from t1 where b like "hello"; +b +hello +select d from t1 where d like "hello"; +d +hello +select c from t1 having c like "hello"; +c +hello +HELLO +select d from t1 having d like "hello"; +d +hello +select t from t1 where t like "%HELLO%"; +t +hello +HELLO +HELLO MY +select c from t1 where c like "%HELLO%"; +c +hello +HELLO +HELLO MY +select b from t1 where b like "%HELLO%"; +b +HELLO +HELLO MY +select d from t1 where d like "%HELLO%"; +d +HELLO +HELLO MY +select c from t1 having c like "%HELLO%"; +c +hello +HELLO +HELLO MY +select d from t1 having d like "%HELLO%"; +d +HELLO +HELLO MY +select d from t1 having d like "%HE%LLO%"; +d +HELLO +HELLO MY +select t from t1 order by t; +t +NULL +NULL + +1 +a +hello +HELLO +HELLO MY +select c from t1 order by c; +c +NULL +NULL + + +a +hello +HELLO +HELLO MY +select b from t1 order by b; +b +NULL +NULL +NULL + +HELLO +HELLO MY +a +hello +select d from t1 order by d; +d +NULL +NULL + +1 +HELLO +HELLO MY +a +hello +select distinct t from t1; +t +NULL + +hello +HELLO MY +a +1 +select distinct b from t1; +b +NULL + +hello +HELLO +HELLO MY +a +select distinct t from t1 order by t; +t +NULL + +1 +a +hello +HELLO MY +select distinct b from t1 order by b; +b +NULL + +HELLO +HELLO MY +a +hello +select t from t1 group by t; +t +NULL + +1 +a +hello +HELLO MY +select b from t1 group by b; +b +NULL + +HELLO +HELLO MY +a +hello +set option sql_big_tables=1; +select distinct t from t1; +t +NULL + +hello +HELLO MY +a +1 +select distinct b from t1; +b +NULL + +hello +HELLO +HELLO MY +a +select distinct t from t1 order by t; +t +NULL + +1 +a +hello +HELLO MY +select distinct b from t1 order by b; +b +NULL + +HELLO +HELLO MY +a +hello +select distinct c from t1; +c +NULL + +hello +HELLO MY +a +select distinct d from t1; +d +NULL + +hello +HELLO +HELLO MY +a +1 +select distinct c from t1 order by c; +c +NULL + +a +hello +HELLO MY +select distinct d from t1 order by d; +d +NULL + +1 +HELLO +HELLO MY +a +hello +select c from t1 group by c; +c +NULL + +a +hello +HELLO MY +select d from t1 group by d; +d +NULL + +1 +HELLO +HELLO MY +a +hello +set option sql_big_tables=0; +select distinct * from t1; +t c b d +NULL NULL NULL NULL + +hello hello hello hello +HELLO HELLO HELLO HELLO +HELLO MY HELLO MY HELLO MY HELLO MY +a a a a +1 NULL 1 +select t,count(*) from t1 group by t; +t count(*) +NULL 2 + 1 +1 1 +a 1 +hello 2 +HELLO MY 1 +select b,count(*) from t1 group by b; +b count(*) +NULL 3 + 1 +HELLO 1 +HELLO MY 1 +a 1 +hello 1 +select c,count(*) from t1 group by c; +c count(*) +NULL 2 + 2 +a 1 +hello 2 +HELLO MY 1 +select d,count(*) from t1 group by d; +d count(*) +NULL 2 + 1 +1 1 +HELLO 1 +HELLO MY 1 +a 1 +hello 1 +drop table t1; +create table t1 (a text, unique (a(2100))); +ERROR 42000: Specified key was too long; max key length is 1000 bytes +create table t1 (a text, key (a(2100))); +Warnings: +Warning 1071 Specified key was too long; max key length is 1000 bytes +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` text, + KEY `a` (`a`(1000)) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; +CREATE TABLE t1 ( +t1_id bigint(21) NOT NULL auto_increment, +_field_72 varchar(128) DEFAULT '' NOT NULL, +_field_95 varchar(32), +_field_115 tinyint(4) DEFAULT '0' NOT NULL, +_field_122 tinyint(4) DEFAULT '0' NOT NULL, +_field_126 tinyint(4), +_field_134 tinyint(4), +PRIMARY KEY (t1_id), +UNIQUE _field_72 (_field_72), +KEY _field_115 (_field_115), +KEY _field_122 (_field_122) +); +INSERT INTO t1 VALUES (1,'admin','21232f297a57a5a743894a0e4a801fc3',0,1,NULL,NULL); +INSERT INTO t1 VALUES (2,'hroberts','7415275a8c95952901e42b13a6b78566',0,1,NULL,NULL); +INSERT INTO t1 VALUES (3,'guest','d41d8cd98f00b204e9800998ecf8427e',1,0,NULL,NULL); +CREATE TABLE t2 ( +seq_0_id bigint(21) DEFAULT '0' NOT NULL, +seq_1_id bigint(21) DEFAULT '0' NOT NULL, +PRIMARY KEY (seq_0_id,seq_1_id) +); +INSERT INTO t2 VALUES (1,1); +INSERT INTO t2 VALUES (2,1); +INSERT INTO t2 VALUES (2,2); +CREATE TABLE t3 ( +t3_id bigint(21) NOT NULL auto_increment, +_field_131 varchar(128), +_field_133 tinyint(4) DEFAULT '0' NOT NULL, +_field_135 datetime DEFAULT '0000-00-00 00:00:00' NOT NULL, +_field_137 tinyint(4), +_field_139 datetime DEFAULT '0000-00-00 00:00:00' NOT NULL, +_field_140 blob, +_field_142 tinyint(4) DEFAULT '0' NOT NULL, +_field_145 tinyint(4) DEFAULT '0' NOT NULL, +_field_148 tinyint(4) DEFAULT '0' NOT NULL, +PRIMARY KEY (t3_id), +KEY _field_133 (_field_133), +KEY _field_135 (_field_135), +KEY _field_139 (_field_139), +KEY _field_142 (_field_142), +KEY _field_145 (_field_145), +KEY _field_148 (_field_148) +); +INSERT INTO t3 VALUES (1,'test job 1',0,'0000-00-00 00:00:00',0,'1999-02-25 22:43:32','test\r\njob\r\n1',0,0,0); +INSERT INTO t3 VALUES (2,'test job 2',0,'0000-00-00 00:00:00',0,'1999-02-26 21:08:04','',0,0,0); +CREATE TABLE t4 ( +seq_0_id bigint(21) DEFAULT '0' NOT NULL, +seq_1_id bigint(21) DEFAULT '0' NOT NULL, +PRIMARY KEY (seq_0_id,seq_1_id) +); +INSERT INTO t4 VALUES (1,1); +INSERT INTO t4 VALUES (2,1); +CREATE TABLE t5 ( +t5_id bigint(21) NOT NULL auto_increment, +_field_149 tinyint(4), +_field_156 varchar(128) DEFAULT '' NOT NULL, +_field_157 varchar(128) DEFAULT '' NOT NULL, +_field_158 varchar(128) DEFAULT '' NOT NULL, +_field_159 varchar(128) DEFAULT '' NOT NULL, +_field_160 varchar(128) DEFAULT '' NOT NULL, +_field_161 varchar(128) DEFAULT '' NOT NULL, +PRIMARY KEY (t5_id), +KEY _field_156 (_field_156), +KEY _field_157 (_field_157), +KEY _field_158 (_field_158), +KEY _field_159 (_field_159), +KEY _field_160 (_field_160), +KEY _field_161 (_field_161) +); +INSERT INTO t5 VALUES (1,0,'tomato','','','','',''); +INSERT INTO t5 VALUES (2,0,'cilantro','','','','',''); +CREATE TABLE t6 ( +seq_0_id bigint(21) DEFAULT '0' NOT NULL, +seq_1_id bigint(21) DEFAULT '0' NOT NULL, +PRIMARY KEY (seq_0_id,seq_1_id) +); +INSERT INTO t6 VALUES (1,1); +INSERT INTO t6 VALUES (1,2); +INSERT INTO t6 VALUES (2,2); +CREATE TABLE t7 ( +t7_id bigint(21) NOT NULL auto_increment, +_field_143 tinyint(4), +_field_165 varchar(32), +_field_166 smallint(6) DEFAULT '0' NOT NULL, +PRIMARY KEY (t7_id), +KEY _field_166 (_field_166) +); +INSERT INTO t7 VALUES (1,0,'High',1); +INSERT INTO t7 VALUES (2,0,'Medium',2); +INSERT INTO t7 VALUES (3,0,'Low',3); +select replace(t3._field_140, "\r","^M"),t3_id,min(t3._field_131), min(t3._field_135), min(t3._field_139), min(t3._field_137), min(link_alias_142._field_165), min(link_alias_133._field_72), min(t3._field_145), min(link_alias_148._field_156), replace(min(t3._field_140), "\r","^M"),t3.t3_id from t3 left join t4 on t4.seq_0_id = t3.t3_id left join t7 link_alias_142 on t4.seq_1_id = link_alias_142.t7_id left join t6 on t6.seq_0_id = t3.t3_id left join t1 link_alias_133 on t6.seq_1_id = link_alias_133.t1_id left join t2 on t2.seq_0_id = t3.t3_id left join t5 link_alias_148 on t2.seq_1_id = link_alias_148.t5_id where t3.t3_id in (1) group by t3.t3_id order by link_alias_142._field_166, _field_139, link_alias_133._field_72, _field_135, link_alias_148._field_156; +replace(t3._field_140, "\r","^M") t3_id min(t3._field_131) min(t3._field_135) min(t3._field_139) min(t3._field_137) min(link_alias_142._field_165) min(link_alias_133._field_72) min(t3._field_145) min(link_alias_148._field_156) replace(min(t3._field_140), "\r","^M") t3_id +test^M +job^M +1 1 test job 1 0000-00-00 00:00:00 1999-02-25 22:43:32 0 High admin 0 tomato test^M +job^M +1 1 +drop table t1,t2,t3,t4,t5,t6,t7; +create table t1 (a blob); +insert into t1 values ("empty"),(""); +select a,reverse(a) from t1; +a reverse(a) +empty ytpme + +drop table t1; +create table t1 (a blob, key (a(10))); +insert into t1 values ("bye"),("hello"),("hello"),("hello word"); +select * from t1 where a like "hello%"; +a +hello +hello +hello word +drop table t1; +CREATE TABLE t1 ( +f1 int(11) DEFAULT '0' NOT NULL, +f2 varchar(16) DEFAULT '' NOT NULL, +f5 text, +KEY index_name (f1,f2,f5(16)) +); +INSERT INTO t1 VALUES (0,'traktor','1111111111111'); +INSERT INTO t1 VALUES (1,'traktor','1111111111111111111111111'); +select count(*) from t1 where f2='traktor'; +count(*) +2 +drop table t1; +create table t1 (foobar tinyblob not null, boggle smallint not null, key (foobar(32), boggle)); +insert into t1 values ('fish', 10),('bear', 20); +select foobar, boggle from t1 where foobar = 'fish'; +foobar boggle +fish 10 +select foobar, boggle from t1 where foobar = 'fish' and boggle = 10; +foobar boggle +fish 10 +drop table t1; +create table t1 (id integer auto_increment unique,imagem LONGBLOB not null); +insert into t1 (id) values (1); +select +charset(load_file('../../std_data/words.dat')), +collation(load_file('../../std_data/words.dat')), +coercibility(load_file('../../std_data/words.dat')); +charset(load_file('../../std_data/words.dat')) collation(load_file('../../std_data/words.dat')) coercibility(load_file('../../std_data/words.dat')) +NULL NULL 3 +explain extended select +charset(load_file('../../std_data/words.dat')), +collation(load_file('../../std_data/words.dat')), +coercibility(load_file('../../std_data/words.dat')); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used +Warnings: +Note 1003 select sql_no_cache charset(load_file(_latin1'../../std_data/words.dat')) AS `charset(load_file('../../std_data/words.dat'))`,collation(load_file(_latin1'../../std_data/words.dat')) AS `collation(load_file('../../std_data/words.dat'))`,coercibility(load_file(_latin1'../../std_data/words.dat')) AS `coercibility(load_file('../../std_data/words.dat'))` +update t1 set imagem=load_file('../../std_data/words.dat') where id=1; +Warnings: +Warning 1263 Data truncated; NULL supplied to NOT NULL column 'imagem' at row 1 +select if(imagem is null, "ERROR", "OK"),length(imagem) from t1 where id = 1; +if(imagem is null, "ERROR", "OK") length(imagem) +OK 0 +drop table t1; +create table t1 select load_file('../../std_data/words.dat'); +show full fields from t1; +Field Type Collation Null Key Default Extra Privileges Comment +load_file('../../std_data/words.dat') longblob NULL YES NULL +drop table t1; +create table t1 (id integer primary key auto_increment, txt text not null, unique index txt_index (txt (20))); +insert into t1 (txt) values ('Chevy'), ('Chevy '); +select * from t1 where txt='Chevy'; +id txt +1 Chevy +2 Chevy +select * from t1 where txt='Chevy '; +id txt +1 Chevy +2 Chevy +select * from t1 where txt='Chevy ' or txt='Chevy'; +id txt +1 Chevy +2 Chevy +select * from t1 where txt='Chevy' or txt='Chevy '; +id txt +1 Chevy +2 Chevy +select * from t1 where id='1' or id='2'; +id txt +1 Chevy +2 Chevy +insert into t1 (txt) values('Ford'); +select * from t1 where txt='Chevy' or txt='Chevy ' or txt='Ford'; +id txt +1 Chevy +2 Chevy +3 Ford +select * from t1 where txt='Chevy' or txt='Chevy '; +id txt +1 Chevy +2 Chevy +select * from t1 where txt='Chevy' or txt='Chevy ' or txt=' Chevy'; +id txt +1 Chevy +2 Chevy +select * from t1 where txt in ('Chevy ','Chevy'); +id txt +1 Chevy +2 Chevy +select * from t1 where txt in ('Chevy'); +id txt +1 Chevy +2 Chevy +select * from t1 where txt between 'Chevy' and 'Chevy'; +id txt +1 Chevy +2 Chevy +select * from t1 where txt between 'Chevy' and 'Chevy' or txt='Chevy '; +id txt +1 Chevy +2 Chevy +select * from t1 where txt between 'Chevy' and 'Chevy '; +id txt +1 Chevy +2 Chevy +select * from t1 where txt < 'Chevy '; +id txt +select * from t1 where txt <= 'Chevy'; +id txt +1 Chevy +2 Chevy +select * from t1 where txt > 'Chevy'; +id txt +3 Ford +select * from t1 where txt >= 'Chevy'; +id txt +1 Chevy +2 Chevy +3 Ford +drop table t1; +create table t1 (id integer primary key auto_increment, txt text, unique index txt_index (txt (20))); +insert into t1 (txt) values ('Chevy'), ('Chevy '), (NULL); +select * from t1 where txt='Chevy' or txt is NULL; +id txt +3 NULL +1 Chevy +2 Chevy +explain select * from t1 where txt='Chevy' or txt is NULL; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range txt_index txt_index 23 NULL 2 Using where +select * from t1 where txt='Chevy '; +id txt +1 Chevy +2 Chevy +select * from t1 where txt='Chevy ' or txt='Chevy'; +id txt +1 Chevy +2 Chevy +select * from t1 where txt='Chevy' or txt='Chevy '; +id txt +1 Chevy +2 Chevy +select * from t1 where id='1' or id='2'; +id txt +1 Chevy +2 Chevy +insert into t1 (txt) values('Ford'); +select * from t1 where txt='Chevy' or txt='Chevy ' or txt='Ford'; +id txt +1 Chevy +2 Chevy +4 Ford +select * from t1 where txt='Chevy' or txt='Chevy '; +id txt +1 Chevy +2 Chevy +select * from t1 where txt='Chevy' or txt='Chevy ' or txt=' Chevy'; +id txt +1 Chevy +2 Chevy +select * from t1 where txt in ('Chevy ','Chevy'); +id txt +1 Chevy +2 Chevy +select * from t1 where txt in ('Chevy'); +id txt +1 Chevy +2 Chevy +select * from t1 where txt between 'Chevy' and 'Chevy'; +id txt +1 Chevy +2 Chevy +select * from t1 where txt between 'Chevy' and 'Chevy' or txt='Chevy '; +id txt +1 Chevy +2 Chevy +select * from t1 where txt between 'Chevy' and 'Chevy '; +id txt +1 Chevy +2 Chevy +select * from t1 where txt < 'Chevy '; +id txt +select * from t1 where txt < 'Chevy ' or txt is NULL; +id txt +3 NULL +select * from t1 where txt <= 'Chevy'; +id txt +1 Chevy +2 Chevy +select * from t1 where txt > 'Chevy'; +id txt +4 Ford +select * from t1 where txt >= 'Chevy'; +id txt +1 Chevy +2 Chevy +4 Ford +alter table t1 modify column txt blob; +explain select * from t1 where txt='Chevy' or txt is NULL; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref_or_null txt_index txt_index 23 const 2 Using where +select * from t1 where txt='Chevy' or txt is NULL; +id txt +1 Chevy +3 NULL +explain select * from t1 where txt='Chevy' or txt is NULL order by txt; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref_or_null txt_index txt_index 23 const 2 Using where; Using filesort +select * from t1 where txt='Chevy' or txt is NULL order by txt; +id txt +3 NULL +1 Chevy +drop table t1; +CREATE TABLE t1 ( i int(11) NOT NULL default '0', c text NOT NULL, PRIMARY KEY (i), KEY (c(1),c(1))); +INSERT t1 VALUES (1,''),(2,''),(3,'asdfh'),(4,''); +select max(i) from t1 where c = ''; +max(i) +4 +drop table t1; diff --git a/mysql-test/r/type_float.result.es b/mysql-test/r/type_float.result.es new file mode 100644 index 00000000000..411817bbfef --- /dev/null +++ b/mysql-test/r/type_float.result.es @@ -0,0 +1,143 @@ +drop table if exists t1; +SELECT 10,10.0,10.,.1e+2,100.0e-1; +10 10.0 10. .1e+2 100.0e-1 +10 10.0 10 10 10 +SELECT 6e-05, -6e-05, --6e-05, -6e-05+1.000000; +6e-05 -6e-05 --6e-05 -6e-05+1.000000 +6e-05 -6e-05 6e-05 0.99994 +SELECT 1e1,1.e1,1.0e1,1e+1,1.e+1,1.0e+1,1e-1,1.e-1,1.0e-1; +1e1 1.e1 1.0e1 1e+1 1.e+1 1.0e+1 1e-1 1.e-1 1.0e-1 +10 10 10 10 10 10 0.1 0.1 0.1 +create table t1 (f1 float(24),f2 float(52)); +show full columns from t1; +Field Type Collation Null Key Default Extra Privileges Comment +f1 float NULL YES NULL +f2 double NULL YES NULL +insert into t1 values(10,10),(1e+5,1e+5),(1234567890,1234567890),(1e+10,1e+10),(1e+15,1e+15),(1e+20,1e+20),(1e+50,1e+50),(1e+150,1e+150); +Warnings: +Warning 1264 Data truncated; out of range for column 'f1' at row 7 +Warning 1264 Data truncated; out of range for column 'f1' at row 8 +insert into t1 values(-10,-10),(1e-5,1e-5),(1e-10,1e-10),(1e-15,1e-15),(1e-20,1e-20),(1e-50,1e-50),(1e-150,1e-150); +select * from t1; +f1 f2 +10 10 +100000 100000 +1.23457e+09 1234567890 +1e+10 10000000000 +1e+15 1e+15 +1e+20 1e+20 +3.40282e+38 1e+50 +3.40282e+38 1e+150 +-10 -10 +1e-05 1e-05 +1e-10 1e-10 +1e-15 1e-15 +1e-20 1e-20 +0 1e-50 +0 1e-150 +drop table t1; +create table t1 (datum double); +insert into t1 values (0.5),(1.0),(1.5),(2.0),(2.5); +select * from t1; +datum +0.5 +1 +1.5 +2 +2.5 +select * from t1 where datum < 1.5; +datum +0.5 +1 +select * from t1 where datum > 1.5; +datum +2 +2.5 +select * from t1 where datum = 1.5; +datum +1.5 +drop table t1; +create table t1 (a decimal(7,3) not null, key (a)); +insert into t1 values ("0"),("-0.00"),("-0.01"),("-0.002"),("1"); +select a from t1 order by a; +a +-0.010 +-0.002 +-0.000 +0.000 +1.000 +select min(a) from t1; +min(a) +-0.010 +drop table t1; +create table t1 (c1 double, c2 varchar(20)); +insert t1 values (121,"16"); +select c1 + c1 * (c2 / 100) as col from t1; +col +140.36 +create table t2 select c1 + c1 * (c2 / 100) as col1, round(c1, 5) as col2, round(c1, 35) as col3, sqrt(c1*1e-15) col4 from t1; +select * from t2; +col1 col2 col3 col4 +140.36 121.00000 121 3.47850542618522e-07 +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `col1` double default NULL, + `col2` double(22,5) default NULL, + `col3` double default NULL, + `col4` double default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1,t2; +create table t1 (a float); +insert into t1 values (1); +select max(a),min(a),avg(a) from t1; +max(a) min(a) avg(a) +1 1 1 +drop table t1; +create table t1 (f float, f2 float(24), f3 float(6,2), d double, d2 float(53), d3 double(10,3), de decimal, de2 decimal(6), de3 decimal(5,2), n numeric, n2 numeric(8), n3 numeric(5,6)); +show full columns from t1; +Field Type Collation Null Key Default Extra Privileges Comment +f float NULL YES NULL +f2 float NULL YES NULL +f3 float(6,2) NULL YES NULL +d double NULL YES NULL +d2 double NULL YES NULL +d3 double(10,3) NULL YES NULL +de decimal(10,0) NULL YES NULL +de2 decimal(6,0) NULL YES NULL +de3 decimal(5,2) NULL YES NULL +n decimal(10,0) NULL YES NULL +n2 decimal(8,0) NULL YES NULL +n3 decimal(7,6) NULL YES NULL +drop table t1; +create table t1 (a decimal(7,3) not null, key (a)); +insert into t1 values ("0"),("-0.00"),("-0.01"),("-0.002"),("1"); +select a from t1 order by a; +a +-0.010 +-0.002 +-0.000 +0.000 +1.000 +select min(a) from t1; +min(a) +-0.010 +drop table t1; +create table t1 (a float(200,100), b double(200,100)); +insert t1 values (1.0, 2.0); +select * from t1; +a b +1.000000000000000000000000000000 2.000000000000000000000000000000 +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` float(200,30) default NULL, + `b` double(200,30) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; +create table t1 (c20 char); +insert into t1 values (5000.0); +drop table t1; +create table t1 (f float(54)); +ERROR 42000: Incorrect column specifier for column 'f' +drop table if exists t1; diff --git a/mysql-test/r/type_ranges.result.es b/mysql-test/r/type_ranges.result.es new file mode 100644 index 00000000000..548b00750ea --- /dev/null +++ b/mysql-test/r/type_ranges.result.es @@ -0,0 +1,320 @@ +drop table if exists t1,t2,t3; +SET SQL_WARNINGS=1; +CREATE TABLE t1 ( +auto int(5) unsigned NOT NULL auto_increment, +string char(10) default "hello", +tiny tinyint(4) DEFAULT '0' NOT NULL , +short smallint(6) DEFAULT '1' NOT NULL , +medium mediumint(8) DEFAULT '0' NOT NULL, +long_int int(11) DEFAULT '0' NOT NULL, +longlong bigint(13) DEFAULT '0' NOT NULL, +real_float float(13,1) DEFAULT 0.0 NOT NULL, +real_double double(16,4), +utiny tinyint(3) unsigned DEFAULT '0' NOT NULL, +ushort smallint(5) unsigned zerofill DEFAULT '00000' NOT NULL, +umedium mediumint(8) unsigned DEFAULT '0' NOT NULL, +ulong int(11) unsigned DEFAULT '0' NOT NULL, +ulonglong bigint(13) unsigned DEFAULT '0' NOT NULL, +time_stamp timestamp, +date_field date, +time_field time, +date_time datetime, +blob_col blob, +tinyblob_col tinyblob, +mediumblob_col mediumblob not null, +longblob_col longblob not null, +options enum('one','two','tree') not null, +flags set('one','two','tree') not null, +PRIMARY KEY (auto), +KEY (utiny), +KEY (tiny), +KEY (short), +KEY any_name (medium), +KEY (longlong), +KEY (real_float), +KEY (ushort), +KEY (umedium), +KEY (ulong), +KEY (ulonglong,ulong), +KEY (options,flags) +); +show full fields from t1; +Field Type Collation Null Key Default Extra Privileges Comment +auto int(5) unsigned NULL PRI NULL auto_increment +string varchar(10) latin1_swedish_ci YES hello +tiny tinyint(4) NULL MUL 0 +short smallint(6) NULL MUL 1 +medium mediumint(8) NULL MUL 0 +long_int int(11) NULL 0 +longlong bigint(13) NULL MUL 0 +real_float float(13,1) NULL MUL 0.0 +real_double double(16,4) NULL YES NULL +utiny tinyint(3) unsigned NULL MUL 0 +ushort smallint(5) unsigned zerofill NULL MUL 00000 +umedium mediumint(8) unsigned NULL MUL 0 +ulong int(11) unsigned NULL MUL 0 +ulonglong bigint(13) unsigned NULL MUL 0 +time_stamp timestamp NULL YES CURRENT_TIMESTAMP +date_field date NULL YES NULL +time_field time NULL YES NULL +date_time datetime NULL YES NULL +blob_col blob NULL YES NULL +tinyblob_col tinyblob NULL YES NULL +mediumblob_col mediumblob NULL +longblob_col longblob NULL +options enum('one','two','tree') latin1_swedish_ci MUL one +flags set('one','two','tree') latin1_swedish_ci +show keys from t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 0 PRIMARY 1 auto A 0 NULL NULL BTREE +t1 1 utiny 1 utiny A NULL NULL NULL BTREE +t1 1 tiny 1 tiny A NULL NULL NULL BTREE +t1 1 short 1 short A NULL NULL NULL BTREE +t1 1 any_name 1 medium A NULL NULL NULL BTREE +t1 1 longlong 1 longlong A NULL NULL NULL BTREE +t1 1 real_float 1 real_float A NULL NULL NULL BTREE +t1 1 ushort 1 ushort A NULL NULL NULL BTREE +t1 1 umedium 1 umedium A NULL NULL NULL BTREE +t1 1 ulong 1 ulong A NULL NULL NULL BTREE +t1 1 ulonglong 1 ulonglong A NULL NULL NULL BTREE +t1 1 ulonglong 2 ulong A NULL NULL NULL BTREE +t1 1 options 1 options A NULL NULL NULL BTREE +t1 1 options 2 flags A NULL NULL NULL BTREE +CREATE UNIQUE INDEX test on t1 ( auto ) ; +CREATE INDEX test2 on t1 ( ulonglong,ulong) ; +CREATE INDEX test3 on t1 ( medium ) ; +DROP INDEX test ON t1; +insert into t1 values (10, 1,1,1,1,1,1,1,1,1,1,1,1,1,NULL,0,0,0,1,1,1,1,'one','one'); +insert into t1 values (NULL,2,2,2,2,2,2,2,2,2,2,2,2,2,NULL,NULL,NULL,NULL,NULL,NULL,2,2,'two','two,one'); +insert into t1 values (0,1/3,3,3,3,3,3,3,3,3,3,3,3,3,NULL,'19970303','10:10:10','19970303101010','','','','3',3,3); +insert into t1 values (0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,NULL,19970807,080706,19970403090807,-1,-1,-1,'-1',-1,-1); +Warnings: +Warning 1264 Data truncated; out of range for column 'utiny' at row 1 +Warning 1264 Data truncated; out of range for column 'ushort' at row 1 +Warning 1264 Data truncated; out of range for column 'umedium' at row 1 +Warning 1264 Data truncated; out of range for column 'ulong' at row 1 +Warning 1265 Data truncated for column 'options' at row 1 +Warning 1265 Data truncated for column 'flags' at row 1 +insert into t1 values (0,-4294967295,-4294967295,-4294967295,-4294967295,-4294967295,-4294967295,-4294967295,-4294967295,-4294967295,-4294967295,-4294967295,-4294967295,-4294967295,NULL,0,0,0,-4294967295,-4294967295,-4294967295,'-4294967295',0,"one,two,tree"); +Warnings: +Warning 1265 Data truncated for column 'string' at row 1 +Warning 1264 Data truncated; out of range for column 'tiny' at row 1 +Warning 1264 Data truncated; out of range for column 'short' at row 1 +Warning 1264 Data truncated; out of range for column 'medium' at row 1 +Warning 1264 Data truncated; out of range for column 'long_int' at row 1 +Warning 1264 Data truncated; out of range for column 'utiny' at row 1 +Warning 1264 Data truncated; out of range for column 'ushort' at row 1 +Warning 1264 Data truncated; out of range for column 'umedium' at row 1 +Warning 1264 Data truncated; out of range for column 'ulong' at row 1 +Warning 1265 Data truncated for column 'options' at row 1 +insert into t1 values (0,4294967295,4294967295,4294967295,4294967295,4294967295,4294967295,4294967295,4294967295,4294967295,4294967295,4294967295,4294967295,4294967295,NULL,0,0,0,4294967295,4294967295,4294967295,'4294967295',0,0); +Warnings: +Warning 1264 Data truncated; out of range for column 'tiny' at row 1 +Warning 1264 Data truncated; out of range for column 'short' at row 1 +Warning 1264 Data truncated; out of range for column 'medium' at row 1 +Warning 1264 Data truncated; out of range for column 'long_int' at row 1 +Warning 1264 Data truncated; out of range for column 'utiny' at row 1 +Warning 1264 Data truncated; out of range for column 'ushort' at row 1 +Warning 1264 Data truncated; out of range for column 'umedium' at row 1 +Warning 1265 Data truncated for column 'options' at row 1 +insert into t1 (tiny) values (1); +select auto,string,tiny,short,medium,long_int,longlong,real_float,real_double,utiny,ushort,umedium,ulong,ulonglong,mod(floor(time_stamp/1000000),1000000)-mod(curdate(),1000000),date_field,time_field,date_time,blob_col,tinyblob_col,mediumblob_col,longblob_col from t1; +auto string tiny short medium long_int longlong real_float real_double utiny ushort umedium ulong ulonglong mod(floor(time_stamp/1000000),1000000)-mod(curdate(),1000000) date_field time_field date_time blob_col tinyblob_col mediumblob_col longblob_col +10 1 1 1 1 1 1 1.0 1.0000 1 00001 1 1 1 0 0000-00-00 00:00:00 0000-00-00 00:00:00 1 1 1 1 +11 2 2 2 2 2 2 2.0 2.0000 2 00002 2 2 2 0 NULL NULL NULL NULL NULL 2 2 +12 0.33 3 3 3 3 3 3.0 3.0000 3 00003 3 3 3 0 1997-03-03 10:10:10 1997-03-03 10:10:10 3 +13 -1 -1 -1 -1 -1 -1 -1.0 -1.0000 0 00000 0 0 18446744073709551615 0 1997-08-07 08:07:06 1997-04-03 09:08:07 -1 -1 -1 -1 +14 -429496729 -128 -32768 -8388608 -2147483648 -4294967295 -4294967296.0 -4294967295.0000 0 00000 0 0 18446744069414584321 0 0000-00-00 00:00:00 0000-00-00 00:00:00 -4294967295 -4294967295 -4294967295 -4294967295 +15 4294967295 127 32767 8388607 2147483647 4294967295 4294967296.0 4294967295.0000 255 65535 16777215 4294967295 4294967295 0 0000-00-00 00:00:00 0000-00-00 00:00:00 4294967295 4294967295 4294967295 4294967295 +16 hello 1 1 0 0 0 0.0 NULL 0 00000 0 0 0 0 NULL NULL NULL NULL NULL +ALTER TABLE t1 +add new_field char(10) default "new" not null, +change blob_col new_blob_col varchar(20), +change date_field date_field char(10), +alter column string set default "new default", +alter short drop default, +DROP INDEX utiny, +DROP INDEX ushort, +DROP PRIMARY KEY, +DROP FOREIGN KEY any_name, +ADD INDEX (auto); +LOCK TABLES t1 WRITE; +ALTER TABLE t1 +RENAME as t2, +DROP longblob_col; +UNLOCK TABLES; +ALTER TABLE t2 rename as t3; +LOCK TABLES t3 WRITE ; +ALTER TABLE t3 rename as t1; +UNLOCK TABLES; +select auto,new_field,new_blob_col,date_field from t1 ; +auto new_field new_blob_col date_field +10 new 1 0000-00-00 +11 new NULL NULL +12 new 1997-03-03 +13 new -1 1997-08-07 +14 new -4294967295 0000-00-00 +15 new 4294967295 0000-00-00 +16 new NULL NULL +CREATE TABLE t2 ( +auto int(5) unsigned NOT NULL auto_increment, +string char(20), +mediumblob_col mediumblob not null, +new_field char(2), +PRIMARY KEY (auto) +); +INSERT INTO t2 (string,mediumblob_col,new_field) SELECT string,mediumblob_col,new_field from t1 where auto > 10; +Warnings: +Warning 1265 Data truncated for column 'new_field' at row 2 +Warning 1265 Data truncated for column 'new_field' at row 3 +Warning 1265 Data truncated for column 'new_field' at row 4 +Warning 1265 Data truncated for column 'new_field' at row 5 +Warning 1265 Data truncated for column 'new_field' at row 6 +Warning 1265 Data truncated for column 'new_field' at row 7 +select * from t2; +auto string mediumblob_col new_field +1 2 2 ne +2 0.33 ne +3 -1 -1 ne +4 -429496729 -4294967295 ne +5 4294967295 4294967295 ne +6 hello ne +select distinct flags from t1; +flags + +one,two,tree +one +one,two +select flags from t1 where find_in_set("two",flags)>0; +flags +one,two,tree +one,two,tree +one,two +one,two +select flags from t1 where find_in_set("unknown",flags)>0; +flags +select options,flags from t1 where options="ONE" and flags="ONE"; +options flags +one one +select options,flags from t1 where options="one" and flags="one"; +options flags +one one +drop table t2; +create table t2 select * from t1; +Warnings: +Warning 1265 Data truncated for column 'options' at row 4 +Warning 1265 Data truncated for column 'options' at row 5 +Warning 1265 Data truncated for column 'options' at row 6 +update t2 set string="changed" where auto=16; +show full columns from t1; +Field Type Collation Null Key Default Extra Privileges Comment +auto int(5) unsigned NULL MUL NULL auto_increment +string varchar(10) latin1_swedish_ci YES new defaul +tiny tinyint(4) NULL MUL 0 +short smallint(6) NULL MUL 0 +medium mediumint(8) NULL MUL 0 +long_int int(11) NULL 0 +longlong bigint(13) NULL MUL 0 +real_float float(13,1) NULL MUL 0.0 +real_double double(16,4) NULL YES NULL +utiny tinyint(3) unsigned NULL 0 +ushort smallint(5) unsigned zerofill NULL 00000 +umedium mediumint(8) unsigned NULL MUL 0 +ulong int(11) unsigned NULL MUL 0 +ulonglong bigint(13) unsigned NULL MUL 0 +time_stamp timestamp NULL YES CURRENT_TIMESTAMP +date_field varchar(10) latin1_swedish_ci YES NULL +time_field time NULL YES NULL +date_time datetime NULL YES NULL +new_blob_col varchar(20) latin1_swedish_ci YES NULL +tinyblob_col tinyblob NULL YES NULL +mediumblob_col mediumblob NULL +options enum('one','two','tree') latin1_swedish_ci MUL one +flags set('one','two','tree') latin1_swedish_ci +new_field varchar(10) latin1_swedish_ci new +show full columns from t2; +Field Type Collation Null Key Default Extra Privileges Comment +auto int(5) unsigned NULL 0 +string varchar(10) latin1_swedish_ci YES new defaul +tiny tinyint(4) NULL 0 +short smallint(6) NULL 0 +medium mediumint(8) NULL 0 +long_int int(11) NULL 0 +longlong bigint(13) NULL 0 +real_float float(13,1) NULL 0.0 +real_double double(16,4) NULL YES NULL +utiny tinyint(3) unsigned NULL 0 +ushort smallint(5) unsigned zerofill NULL 00000 +umedium mediumint(8) unsigned NULL 0 +ulong int(11) unsigned NULL 0 +ulonglong bigint(13) unsigned NULL 0 +time_stamp timestamp NULL YES 0000-00-00 00:00:00 +date_field varchar(10) latin1_swedish_ci YES NULL +time_field time NULL YES NULL +date_time datetime NULL YES NULL +new_blob_col varchar(20) latin1_swedish_ci YES NULL +tinyblob_col tinyblob NULL YES NULL +mediumblob_col mediumblob NULL +options enum('one','two','tree') latin1_swedish_ci one +flags set('one','two','tree') latin1_swedish_ci +new_field varchar(10) latin1_swedish_ci new +select t1.auto,t2.auto from t1,t2 where t1.auto=t2.auto and ((t1.string<>t2.string and (t1.string is not null or t2.string is not null)) or (t1.tiny<>t2.tiny and (t1.tiny is not null or t2.tiny is not null)) or (t1.short<>t2.short and (t1.short is not null or t2.short is not null)) or (t1.medium<>t2.medium and (t1.medium is not null or t2.medium is not null)) or (t1.long_int<>t2.long_int and (t1.long_int is not null or t2.long_int is not null)) or (t1.longlong<>t2.longlong and (t1.longlong is not null or t2.longlong is not null)) or (t1.real_float<>t2.real_float and (t1.real_float is not null or t2.real_float is not null)) or (t1.real_double<>t2.real_double and (t1.real_double is not null or t2.real_double is not null)) or (t1.utiny<>t2.utiny and (t1.utiny is not null or t2.utiny is not null)) or (t1.ushort<>t2.ushort and (t1.ushort is not null or t2.ushort is not null)) or (t1.umedium<>t2.umedium and (t1.umedium is not null or t2.umedium is not null)) or (t1.ulong<>t2.ulong and (t1.ulong is not null or t2.ulong is not null)) or (t1.ulonglong<>t2.ulonglong and (t1.ulonglong is not null or t2.ulonglong is not null)) or (t1.time_stamp<>t2.time_stamp and (t1.time_stamp is not null or t2.time_stamp is not null)) or (t1.date_field<>t2.date_field and (t1.date_field is not null or t2.date_field is not null)) or (t1.time_field<>t2.time_field and (t1.time_field is not null or t2.time_field is not null)) or (t1.date_time<>t2.date_time and (t1.date_time is not null or t2.date_time is not null)) or (t1.new_blob_col<>t2.new_blob_col and (t1.new_blob_col is not null or t2.new_blob_col is not null)) or (t1.tinyblob_col<>t2.tinyblob_col and (t1.tinyblob_col is not null or t2.tinyblob_col is not null)) or (t1.mediumblob_col<>t2.mediumblob_col and (t1.mediumblob_col is not null or t2.mediumblob_col is not null)) or (t1.options<>t2.options and (t1.options is not null or t2.options is not null)) or (t1.flags<>t2.flags and (t1.flags is not null or t2.flags is not null)) or (t1.new_field<>t2.new_field and (t1.new_field is not null or t2.new_field is not null))); +auto auto +16 16 +select t1.auto,t2.auto from t1,t2 where t1.auto=t2.auto and not (t1.string<=>t2.string and t1.tiny<=>t2.tiny and t1.short<=>t2.short and t1.medium<=>t2.medium and t1.long_int<=>t2.long_int and t1.longlong<=>t2.longlong and t1.real_float<=>t2.real_float and t1.real_double<=>t2.real_double and t1.utiny<=>t2.utiny and t1.ushort<=>t2.ushort and t1.umedium<=>t2.umedium and t1.ulong<=>t2.ulong and t1.ulonglong<=>t2.ulonglong and t1.time_stamp<=>t2.time_stamp and t1.date_field<=>t2.date_field and t1.time_field<=>t2.time_field and t1.date_time<=>t2.date_time and t1.new_blob_col<=>t2.new_blob_col and t1.tinyblob_col<=>t2.tinyblob_col and t1.mediumblob_col<=>t2.mediumblob_col and t1.options<=>t2.options and t1.flags<=>t2.flags and t1.new_field<=>t2.new_field); +auto auto +16 16 +drop table t2; +create table t2 (primary key (auto)) select auto+1 as auto,1 as t1, "a" as t2, repeat("a",256) as t3, binary repeat("b",256) as t4 from t1; +show full columns from t2; +Field Type Collation Null Key Default Extra Privileges Comment +auto bigint(17) unsigned NULL PRI 0 +t1 bigint(1) NULL 0 +t2 char(1) latin1_swedish_ci +t3 longtext latin1_swedish_ci +t4 longblob NULL +select * from t2; +auto t1 t2 t3 t4 +11 1 a aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +12 1 a aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +13 1 a aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +14 1 a aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +15 1 a aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +16 1 a aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +17 1 a aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +drop table t1,t2; +create table t1 (c int); +insert into t1 values(1),(2); +create table t2 select * from t1; +create table t3 select * from t1, t2; +ERROR 42S21: Duplicate column name 'c' +create table t3 select t1.c AS c1, t2.c AS c2,1 as "const" from t1, t2; +show full columns from t3; +Field Type Collation Null Key Default Extra Privileges Comment +c1 int(11) NULL YES NULL +c2 int(11) NULL YES NULL +const bigint(1) NULL 0 +drop table t1,t2,t3; +create table t1 ( myfield INT NOT NULL, UNIQUE INDEX (myfield), unique (myfield), index(myfield)); +drop table t1; +create table t1 ( id integer unsigned not null primary key ); +create table t2 ( id integer unsigned not null primary key ); +insert into t1 values (1), (2); +insert into t2 values (1); +select t1.id as id_A, t2.id as id_B from t1 left join t2 using ( id ); +id_A id_B +1 1 +2 NULL +create table t3 (id_A integer unsigned not null, id_B integer unsigned null ); +insert into t3 select t1.id as id_A, t2.id as id_B from t1 left join t2 using ( id ); +select * from t3; +id_A id_B +1 1 +2 NULL +drop table t3; +create table t3 select t1.id as id_A, t2.id as id_B from t1 left join t2 using ( id ); +select * from t3; +id_A id_B +1 1 +2 NULL +drop table t1,t2,t3; diff --git a/mysql-test/t/client_test.test b/mysql-test/t/client_test.test new file mode 100644 index 00000000000..eb053b6c902 --- /dev/null +++ b/mysql-test/t/client_test.test @@ -0,0 +1,2 @@ +-- disable_result_log +--exec ../tests/client_test --testcase --user=root --socket=var/tmp/master.sock --port=$MYSQL_TCP_PORT diff --git a/mysql-test/t/ndb_alter_table.test b/mysql-test/t/ndb_alter_table.test index 3cdddfa8dce..aa3da77a1da 100644 --- a/mysql-test/t/ndb_alter_table.test +++ b/mysql-test/t/ndb_alter_table.test @@ -47,6 +47,71 @@ select * from t1 order by col1; insert into t1 values (2, NULL,4,3,5,99,"PENDING","EXTRA",'2004-01-01 00:00:00'); show table status; select * from t1 order by col1; +delete from t1; +insert into t1 values (0,0,4,3,5,99,"PENDING","EXTRA",'2004-01-01 00:00:00'); +SET SQL_MODE=''; +insert into t1 values (1,0,4,3,5,99,"PENDING","EXTRA",'2004-01-01 00:00:00'); +select * from t1 order by col1; +alter table t1 drop column col4_5; +insert into t1 values (2,0,4,3,5,"PENDING","EXTRA",'2004-01-01 00:00:00'); +select * from t1 order by col1; +drop table t1; + + +# +# Check that invalidating dictionary cache works +# + +CREATE TABLE t1 ( + a INT NOT NULL, + b INT NOT NULL +) ENGINE=ndbcluster; + +INSERT INTO t1 VALUES (9410,9412); + +connect (con1,localhost,,,test); +connect (con2,localhost,,,test); + +connection con1; +ALTER TABLE t1 ADD COLUMN c int not null; +select * from t1 order by a; + +connection con2; +select * from t1 order by a; +alter table t1 drop c; + +connection con1; +select * from t1 order by a; +drop table t1; + +connection con2; +--error 1146 +select * from t1 order by a; + +CREATE TABLE t1 ( + a INT NOT NULL PRIMARY KEY, + b INT NOT NULL +) ENGINE=ndbcluster; + +INSERT INTO t1 VALUES (0,1),(17,18); +select * from t1 order by a; +alter table t1 modify column a int not null auto_increment; +select * from t1 order by a; +INSERT INTO t1 VALUES (0,19),(20,21); +select * from t1 order by a; +drop table t1; + +CREATE TABLE t1 ( + a INT NOT NULL PRIMARY KEY, + b INT NOT NULL +) ENGINE=ndbcluster; + +INSERT INTO t1 VALUES (0,1),(17,18); +select * from t1; +alter table t1 add c int not null unique auto_increment; +select * from t1 order by a; +INSERT INTO t1 VALUES (18,19,3),(20,21,0); +select * from t1 order by a; drop table t1; #--disable_warnings diff --git a/mysql-test/t/ndb_charset.test b/mysql-test/t/ndb_charset.test new file mode 100644 index 00000000000..b9f28ed0faf --- /dev/null +++ b/mysql-test/t/ndb_charset.test @@ -0,0 +1,159 @@ +--source include/have_ndb.inc + +--disable_warnings +drop table if exists t1; +--enable_warnings + +# +# Minimal NDB charset test. +# + +# pk - binary + +create table t1 ( + a char(3) character set latin1 collate latin1_bin primary key +) engine=ndb; +# ok +insert into t1 values('aAa'); +insert into t1 values('aaa'); +insert into t1 values('AAA'); +# 3 +select * from t1 order by a; +# 1 +select * from t1 where a = 'aAa'; +# 1 +select * from t1 where a = 'aaa'; +# 0 +select * from t1 where a = 'AaA'; +# 1 +select * from t1 where a = 'AAA'; +drop table t1; + +# pk - case insensitive + +create table t1 ( + a char(3) character set latin1 collate latin1_swedish_ci primary key +) engine=ndb; +# ok +insert into t1 values('aAa'); +# fail +--error 1062 +insert into t1 values('aaa'); +--error 1062 +insert into t1 values('AAA'); +# 1 +select * from t1 order by a; +# 1 +select * from t1 where a = 'aAa'; +# 1 +select * from t1 where a = 'aaa'; +# 1 +select * from t1 where a = 'AaA'; +# 1 +select * from t1 where a = 'AAA'; +drop table t1; + +# unique hash index - binary + +create table t1 ( + p int primary key, + a char(3) character set latin1 collate latin1_bin not null, + unique key(a) +) engine=ndb; +# ok +insert into t1 values(1, 'aAa'); +insert into t1 values(2, 'aaa'); +insert into t1 values(3, 'AAA'); +# 3 +select * from t1 order by p; +# 1 +select * from t1 where a = 'aAa'; +# 1 +select * from t1 where a = 'aaa'; +# 0 +select * from t1 where a = 'AaA'; +# 1 +select * from t1 where a = 'AAA'; +drop table t1; + +# unique hash index - case insensitive + +create table t1 ( + p int primary key, + a char(3) character set latin1 collate latin1_swedish_ci not null, + unique key(a) +) engine=ndb; +# ok +insert into t1 values(1, 'aAa'); +# fail +--error 1169 +insert into t1 values(2, 'aaa'); +--error 1169 +insert into t1 values(3, 'AAA'); +# 1 +select * from t1 order by p; +# 1 +select * from t1 where a = 'aAa'; +# 1 +select * from t1 where a = 'aaa'; +# 1 +select * from t1 where a = 'AaA'; +# 1 +select * from t1 where a = 'AAA'; +drop table t1; + +# ordered index - binary + +create table t1 ( + p int primary key, + a char(3) character set latin1 collate latin1_bin not null, + index(a) +) engine=ndb; +# ok +insert into t1 values(1, 'aAa'); +insert into t1 values(2, 'aaa'); +insert into t1 values(3, 'AAA'); +insert into t1 values(4, 'aAa'); +insert into t1 values(5, 'aaa'); +insert into t1 values(6, 'AAA'); +# 6 +select * from t1 order by p; +# plan +explain select * from t1 where a = 'zZz' order by p; +# 2 +select * from t1 where a = 'aAa' order by p; +# 2 +select * from t1 where a = 'aaa' order by p; +# 0 +select * from t1 where a = 'AaA' order by p; +# 2 +select * from t1 where a = 'AAA' order by p; +drop table t1; + +# ordered index - case insensitive + +create table t1 ( + p int primary key, + a char(3) character set latin1 collate latin1_swedish_ci not null, + index(a) +) engine=ndb; +# ok +insert into t1 values(1, 'aAa'); +insert into t1 values(2, 'aaa'); +insert into t1 values(3, 'AAA'); +insert into t1 values(4, 'aAa'); +insert into t1 values(5, 'aaa'); +insert into t1 values(6, 'AAA'); +# 6 +select * from t1 order by p; +# plan +explain select * from t1 where a = 'zZz' order by p; +# 6 +select * from t1 where a = 'aAa' order by p; +# 6 +select * from t1 where a = 'aaa' order by p; +# 6 +select * from t1 where a = 'AaA' order by p; +# 6 +select * from t1 where a = 'AAA' order by p; +drop table t1; diff --git a/mysql-test/t/ndb_index.test b/mysql-test/t/ndb_index.test index d3977dc3ea4..e65b24a9b20 100644 --- a/mysql-test/t/ndb_index.test +++ b/mysql-test/t/ndb_index.test @@ -9,7 +9,7 @@ CREATE TABLE t1 ( ACCESSNODE varchar(16) NOT NULL, POP varchar(48) NOT NULL, ACCESSTYPE int unsigned NOT NULL, - CUSTOMER_ID varchar(20) NOT NULL, + CUSTOMER_ID varchar(20) collate latin1_bin NOT NULL, PROVIDER varchar(16), TEXPIRE int unsigned, NUM_IP int unsigned, diff --git a/ndb/config/type_ndbapitest.mk.am b/ndb/config/type_ndbapitest.mk.am index 8ac39aec8cf..f1fd8286337 100644 --- a/ndb/config/type_ndbapitest.mk.am +++ b/ndb/config/type_ndbapitest.mk.am @@ -3,7 +3,7 @@ LDADD += $(top_builddir)/ndb/test/src/libNDBT.a \ $(top_builddir)/ndb/src/libndbclient.la \ $(top_builddir)/dbug/libdbug.a \ $(top_builddir)/mysys/libmysys.a \ - $(top_builddir)/strings/libmystrings.a + $(top_builddir)/strings/libmystrings.a @NDB_SCI_LIBS@ INCLUDES += -I$(srcdir) -I$(top_srcdir)/include \ -I$(top_srcdir)/ndb/include \ diff --git a/ndb/config/type_ndbapitools.mk.am b/ndb/config/type_ndbapitools.mk.am index 3b5d40874b2..ed6d8699e05 100644 --- a/ndb/config/type_ndbapitools.mk.am +++ b/ndb/config/type_ndbapitools.mk.am @@ -3,7 +3,7 @@ LDADD += \ $(top_builddir)/ndb/src/libndbclient.la \ $(top_builddir)/dbug/libdbug.a \ $(top_builddir)/mysys/libmysys.a \ - $(top_builddir)/strings/libmystrings.a + $(top_builddir)/strings/libmystrings.a @NDB_SCI_LIBS@ INCLUDES += -I$(srcdir) -I$(top_srcdir)/include \ -I$(top_srcdir)/ndb/include \ diff --git a/ndb/examples/ndbapi_async_example/ndbapi_async.cpp b/ndb/examples/ndbapi_async_example/ndbapi_async.cpp index 7abebcc832d..76ce1a8efe3 100644 --- a/ndb/examples/ndbapi_async_example/ndbapi_async.cpp +++ b/ndb/examples/ndbapi_async_example/ndbapi_async.cpp @@ -46,9 +46,9 @@ * * NdbDictionary::Column * setName() - * setPrimaryKey() * setType() * setLength() + * setPrimaryKey() * setNullable() * * NdbDictionary::Table @@ -234,9 +234,9 @@ int create_table(Ndb * myNdb) * Column REG_NO */ myColumn.setName("REG_NO"); - myColumn.setPrimaryKey(true); myColumn.setType(NdbDictionary::Column::Unsigned); myColumn.setLength(1); + myColumn.setPrimaryKey(true); myColumn.setNullable(false); myTable.addColumn(myColumn); @@ -244,9 +244,9 @@ int create_table(Ndb * myNdb) * Column BRAND */ myColumn.setName("BRAND"); - myColumn.setPrimaryKey(false); myColumn.setType(NdbDictionary::Column::Char); myColumn.setLength(20); + myColumn.setPrimaryKey(false); myColumn.setNullable(false); myTable.addColumn(myColumn); @@ -254,9 +254,9 @@ int create_table(Ndb * myNdb) * Column COLOR */ myColumn.setName("COLOR"); - myColumn.setPrimaryKey(false); myColumn.setType(NdbDictionary::Column::Char); myColumn.setLength(20); + myColumn.setPrimaryKey(false); myColumn.setNullable(false); myTable.addColumn(myColumn); @@ -454,6 +454,7 @@ int populate(Ndb * myNdb, int data, async_callback_t * cbData) int main() { + ndb_init(); Ndb* myNdb = new Ndb( "TEST_DB" ); // Object representing the database /******************************************* @@ -493,5 +494,3 @@ int main() std::cout << "Number of temporary errors: " << tempErrors << std::endl; delete myNdb; } - - diff --git a/ndb/examples/ndbapi_example1/ndbapi_example1.cpp b/ndb/examples/ndbapi_example1/ndbapi_example1.cpp index 879d86de824..03a84aa249b 100644 --- a/ndb/examples/ndbapi_example1/ndbapi_example1.cpp +++ b/ndb/examples/ndbapi_example1/ndbapi_example1.cpp @@ -44,6 +44,7 @@ int main() { + ndb_init(); Ndb* myNdb = new Ndb( "TEST_DB_1" ); // Object representing the database NdbDictionary::Table myTable; NdbDictionary::Column myColumn; @@ -78,16 +79,16 @@ int main() myTable.setName("MYTABLENAME"); myColumn.setName("ATTR1"); - myColumn.setPrimaryKey(true); myColumn.setType(NdbDictionary::Column::Unsigned); myColumn.setLength(1); + myColumn.setPrimaryKey(true); myColumn.setNullable(false); myTable.addColumn(myColumn); myColumn.setName("ATTR2"); - myColumn.setPrimaryKey(false); myColumn.setType(NdbDictionary::Column::Unsigned); myColumn.setLength(1); + myColumn.setPrimaryKey(false); myColumn.setNullable(false); myTable.addColumn(myColumn); diff --git a/ndb/examples/ndbapi_example2/ndbapi_example2.cpp b/ndb/examples/ndbapi_example2/ndbapi_example2.cpp index 1c61721c037..95a7bae66b8 100644 --- a/ndb/examples/ndbapi_example2/ndbapi_example2.cpp +++ b/ndb/examples/ndbapi_example2/ndbapi_example2.cpp @@ -39,6 +39,7 @@ static void callback(int result, NdbConnection* NdbObject, void* aObject); int main() { + ndb_init(); Ndb* myNdb = new Ndb( "TEST_DB_2" ); // Object representing the database NdbConnection* myNdbConnection[2]; // For transactions diff --git a/ndb/examples/ndbapi_example3/ndbapi_example3.cpp b/ndb/examples/ndbapi_example3/ndbapi_example3.cpp index 36d2cf1608c..91d9ff122ba 100644 --- a/ndb/examples/ndbapi_example3/ndbapi_example3.cpp +++ b/ndb/examples/ndbapi_example3/ndbapi_example3.cpp @@ -176,6 +176,7 @@ int executeInsertTransaction(int transactionId, Ndb* myNdb) { int main() { + ndb_init(); Ndb* myNdb = new Ndb( "TEST_DB_1" ); // Object representing the database /******************************************* diff --git a/ndb/examples/ndbapi_example4/ndbapi_example4.cpp b/ndb/examples/ndbapi_example4/ndbapi_example4.cpp index 520172b9b0c..fcb770d49e9 100644 --- a/ndb/examples/ndbapi_example4/ndbapi_example4.cpp +++ b/ndb/examples/ndbapi_example4/ndbapi_example4.cpp @@ -44,6 +44,7 @@ int main() { + ndb_init(); Ndb* myNdb = new Ndb( "TEST_DB_1" ); // Object representing the database NdbDictionary::Table myTable; NdbDictionary::Column myColumn; @@ -79,16 +80,16 @@ int main() myTable.setName("MYTABLENAME"); myColumn.setName("ATTR1"); - myColumn.setPrimaryKey(true); myColumn.setType(NdbDictionary::Column::Unsigned); myColumn.setLength(1); + myColumn.setPrimaryKey(true); myColumn.setNullable(false); myTable.addColumn(myColumn); myColumn.setName("ATTR2"); - myColumn.setPrimaryKey(false); myColumn.setType(NdbDictionary::Column::Unsigned); myColumn.setLength(1); + myColumn.setPrimaryKey(false); myColumn.setNullable(false); myTable.addColumn(myColumn); diff --git a/ndb/examples/ndbapi_example5/ndbapi_example5.cpp b/ndb/examples/ndbapi_example5/ndbapi_example5.cpp index a9d3099883c..77f74e7bb63 100644 --- a/ndb/examples/ndbapi_example5/ndbapi_example5.cpp +++ b/ndb/examples/ndbapi_example5/ndbapi_example5.cpp @@ -65,6 +65,7 @@ int myCreateEvent(Ndb* myNdb, int main() { + ndb_init(); Ndb* myNdb = myCreateNdb(); NdbDictionary::Dictionary *myDict; diff --git a/ndb/examples/ndbapi_scan_example/ndbapi_scan.cpp b/ndb/examples/ndbapi_scan_example/ndbapi_scan.cpp index 7c3a66326c6..22641bc5b57 100644 --- a/ndb/examples/ndbapi_scan_example/ndbapi_scan.cpp +++ b/ndb/examples/ndbapi_scan_example/ndbapi_scan.cpp @@ -47,9 +47,9 @@ * * NdbDictionary::Column * setName() - * setPrimaryKey() * setType() * setLength() + * setPrimaryKey() * setNullable() * * NdbDictionary::Table @@ -165,24 +165,24 @@ int create_table(Ndb * myNdb) myTable.setName("GARAGE"); myColumn.setName("REG_NO"); - myColumn.setPrimaryKey(true); myColumn.setType(NdbDictionary::Column::Unsigned); myColumn.setLength(1); + myColumn.setPrimaryKey(true); myColumn.setNullable(false); myTable.addColumn(myColumn); myColumn.setName("BRAND"); - myColumn.setPrimaryKey(false); myColumn.setType(NdbDictionary::Column::Char); myColumn.setLength(20); + myColumn.setPrimaryKey(false); myColumn.setNullable(false); myTable.addColumn(myColumn); myColumn.setName("COLOR"); - myColumn.setPrimaryKey(false); myColumn.setType(NdbDictionary::Column::Char); myColumn.setLength(20); + myColumn.setPrimaryKey(false); myColumn.setNullable(false); myTable.addColumn(myColumn); @@ -761,6 +761,7 @@ int scan_print(Ndb * myNdb, int parallelism, int main() { + ndb_init(); Ndb* myNdb = new Ndb( "TEST_DB" ); // Object representing the database @@ -813,4 +814,3 @@ int main() delete myNdb; } - diff --git a/ndb/examples/select_all/select_all.cpp b/ndb/examples/select_all/select_all.cpp index 3cdbdc47e62..bd25fb60128 100644 --- a/ndb/examples/select_all/select_all.cpp +++ b/ndb/examples/select_all/select_all.cpp @@ -112,6 +112,7 @@ const char* ResultSetContainer::getAttrName(int i) const {return m_names[i];} int main(int argc, const char** argv) { + ndb_init(); Ndb* myNdb = new Ndb("ndbapi_example4"); // Object representing the database NdbConnection* myNdbConnection; // For transactions NdbOperation* myNdbOperation; // For operations diff --git a/ndb/include/debugger/EventLogger.hpp b/ndb/include/debugger/EventLogger.hpp index 6cd6a83e68d..686989089ae 100644 --- a/ndb/include/debugger/EventLogger.hpp +++ b/ndb/include/debugger/EventLogger.hpp @@ -24,6 +24,32 @@ #include #include +class EventLoggerBase { +public: + virtual ~EventLoggerBase(); + + /** + * LogLevel settings + */ + LogLevel m_logLevel; + + /** + * This matrix defines which event should be printed when + * + * threshold - is in range [0-15] + * severity - DEBUG to ALERT (Type of log message) + */ + struct EventRepLogLevelMatrix { + EventReport::EventType eventType; + LogLevel::EventCategory eventCategory; + Uint32 threshold; + Logger::LoggerLevel severity; + }; + + static const EventRepLogLevelMatrix matrix[]; + static const Uint32 matrixSize; +}; + /** * The EventLogger is primarily used for logging NDB events * in the Management Server. It inherits all logging functionality of Logger. @@ -58,7 +84,7 @@ * @see Logger * @version #@ $Id: EventLogger.hpp,v 1.3 2003/09/01 10:15:52 innpeno Exp $ */ -class EventLogger : public Logger +class EventLogger : public EventLoggerBase, public Logger { public: /** @@ -70,7 +96,7 @@ public: /** * Destructor. */ - ~EventLogger(); + virtual ~EventLogger(); /** * Opens/creates the eventlog with the specified filename. @@ -92,16 +118,6 @@ public: */ void close(); - /** - * Logs the NDB event. - * - * @param nodeId the node id of event origin. - * @param eventType the type of event. - * @param theData the event data. - * @deprecated use log(int eventType, const Uint32* theData, NodeId nodeId) - */ - void log(NodeId nodeId, int eventType, const Uint32* theData); - /** * Logs the NDB event. * @@ -109,32 +125,8 @@ public: * @param theData the event data. * @param nodeId the node id of event origin. */ - void log(int eventType, const Uint32* theData, NodeId nodeId = 0); - - /** - * Returns the current log levels. - * Enable, disable log levels to filter the events that are sent to the - * eventlog. - * - * @return the log level. - */ - LogLevel& getLoglevel(); + virtual void log(int, const Uint32*, NodeId = 0,const class LogLevel * = 0); - /** - * Returns the log level that is used to filter an event. The event will not - * be logged unless its event category's log level is <= levelFilter. - * - * @return the log level filter that is used for all event categories. - */ - int getFilterLevel() const; - /** - * Sets log level filter. The event will be logged if - * the event category's log level is <= 'filterLevel'. - * - * @param level the log level to filter. - */ - void setFilterLevel(int filterLevel); - /** * Returns the event text for the specified event report type. * @@ -143,72 +135,25 @@ public: * @param nodeId a node id. * @return the event report text. */ - static const char* getText(int type, + static const char* getText(char * dst, size_t dst_len, + int type, const Uint32* theData, NodeId nodeId = 0); - - /** - * Find a category matching the string - * - * @param str string to match. - * @param cat the event category. - * @param exactMatch only do exact matching. - * - * @return TRUE if match is found, then cat is modified - * FALSE if match is not found - */ - static bool matchEventCategory(const char * str, - LogLevel::EventCategory * cat, - bool exactMatch = false); /** - * Returns category name or NULL if not found. + * Returns the log level that is used to filter an event. The event will not + * be logged unless its event category's log level is <= levelFilter. * - * @param cat the event category. - * @return category name. + * @return the log level filter that is used for all event categories. */ - static const char * getEventCategoryName(LogLevel::EventCategory cat); + int getFilterLevel() const; /** - * Specifies allowed event categories/log levels. - */ - struct EventCategoryName { - LogLevel::EventCategory category; - const char * name; - }; - - static const EventCategoryName eventCategoryNames[]; - static const Uint32 noOfEventCategoryNames; - - /** - * This matrix defines which event should be printed when + * Sets log level filter. The event will be logged if + * the event category's log level is <= 'filterLevel'. * - * threshold - is in range [0-15] - * severity - DEBUG to ALERT (Type of log message) - */ - struct EventRepLogLevelMatrix { - EventReport::EventType eventType; - LogLevel::EventCategory eventCategory; - Uint32 threshold; - Logger::LoggerLevel severity; - }; - - static const EventRepLogLevelMatrix matrix[]; - - /** - * Default log levels for management nodes. - * - * threshold - is in range [0-15] + * @param level the log level to filter. */ - struct EventLogMatrix { - LogLevel::EventCategory eventCategory; - Uint32 threshold; - }; - - static const EventLogMatrix defEventLogMatrix[]; - - - static const Uint32 matrixSize; - static const Uint32 defEventLogMatrixSize; + void setFilterLevel(int filterLevel); private: /** Prohibit */ @@ -216,11 +161,10 @@ private: EventLogger operator = (const EventLogger&); bool operator == (const EventLogger&); - LogLevel m_logLevel; Uint32 m_filterLevel; STATIC_CONST(MAX_TEXT_LENGTH = 256); - static char m_text[MAX_TEXT_LENGTH]; + char m_text[MAX_TEXT_LENGTH]; }; diff --git a/ndb/include/kernel/LogLevel.hpp b/ndb/include/kernel/LogLevel.hpp index 10cd0d43bee..52c2f70cda8 100644 --- a/ndb/include/kernel/LogLevel.hpp +++ b/ndb/include/kernel/LogLevel.hpp @@ -45,81 +45,30 @@ public: * Copy operator */ LogLevel & operator= (const LogLevel &); - - static const Uint32 MIN_LOGLEVEL_ID = CFG_LOGLEVEL_STARTUP; - + enum EventCategory { - /** - * Events during all kind of startups - */ - llStartUp = CFG_LOGLEVEL_STARTUP - MIN_LOGLEVEL_ID, - - /** - * Events during shutdown - */ - llShutdown = CFG_LOGLEVEL_SHUTDOWN - MIN_LOGLEVEL_ID, - - /** - * Transaction statistics - * Job level - * TCP/IP speed - */ - llStatistic = CFG_LOGLEVEL_STATISTICS - MIN_LOGLEVEL_ID, - - /** - * Checkpoints - */ - llCheckpoint = CFG_LOGLEVEL_CHECKPOINT - MIN_LOGLEVEL_ID, - - /** - * Events during node restart - */ - llNodeRestart = CFG_LOGLEVEL_NODERESTART - MIN_LOGLEVEL_ID, - - /** - * Events related to connection / communication - */ - llConnection = CFG_LOGLEVEL_CONNECTION - MIN_LOGLEVEL_ID, - - /** - * Assorted event w.r.t unexpected happenings - */ - llError = CFG_LOGLEVEL_ERROR - MIN_LOGLEVEL_ID, - - /** - * Assorted event w.r.t warning - */ - llWarning = CFG_LOGLEVEL_WARNING - MIN_LOGLEVEL_ID, - - /** - * Assorted event w.r.t information - */ - llInfo = CFG_LOGLEVEL_INFO - MIN_LOGLEVEL_ID, - - /** - * Events related to global replication - */ - llGrep = CFG_LOGLEVEL_GREP - MIN_LOGLEVEL_ID + llStartUp = CFG_LOGLEVEL_STARTUP - CFG_MIN_LOGLEVEL, + llShutdown = CFG_LOGLEVEL_SHUTDOWN - CFG_MIN_LOGLEVEL, + llStatistic = CFG_LOGLEVEL_STATISTICS - CFG_MIN_LOGLEVEL, + llCheckpoint = CFG_LOGLEVEL_CHECKPOINT - CFG_MIN_LOGLEVEL, + llNodeRestart = CFG_LOGLEVEL_NODERESTART - CFG_MIN_LOGLEVEL, + llConnection = CFG_LOGLEVEL_CONNECTION - CFG_MIN_LOGLEVEL, + llInfo = CFG_LOGLEVEL_INFO - CFG_MIN_LOGLEVEL, + llWarning = CFG_LOGLEVEL_WARNING - CFG_MIN_LOGLEVEL, + llError = CFG_LOGLEVEL_ERROR - CFG_MIN_LOGLEVEL, + llGrep = CFG_LOGLEVEL_GREP - CFG_MIN_LOGLEVEL, + llDebug = CFG_LOGLEVEL_DEBUG - CFG_MIN_LOGLEVEL + ,llBackup = CFG_LOGLEVEL_BACKUP - CFG_MIN_LOGLEVEL }; - struct LogLevelCategoryName { - const char* name; - }; - - /** - * Log/event level category names. Remember to update the names whenever - * a new category is added. - */ - static const LogLevelCategoryName LOGLEVEL_CATEGORY_NAME[]; - /** * No of categories */ -#define _LOGLEVEL_CATEGORIES 10 +#define _LOGLEVEL_CATEGORIES (CFG_MAX_LOGLEVEL - CFG_MIN_LOGLEVEL + 1); static const Uint32 LOGLEVEL_CATEGORIES = _LOGLEVEL_CATEGORIES; - + void clear(); - + /** * Note level is valid as 0-15 */ @@ -130,26 +79,33 @@ public: */ Uint32 getLogLevel(EventCategory ec) const; + /** + * Set this= max(this, ll) per category + */ + LogLevel& set_max(const LogLevel& ll); + + bool operator==(const LogLevel& l) const { + return memcmp(this, &l, sizeof(* this)) == 0; + } + + LogLevel& operator=(const class EventSubscribeReq & req); + private: /** * The actual data */ - Uint32 logLevelData[LOGLEVEL_CATEGORIES]; - - LogLevel(const LogLevel &); + Uint8 logLevelData[LOGLEVEL_CATEGORIES]; }; inline LogLevel::LogLevel(){ - clear(); + clear(); } inline LogLevel & LogLevel::operator= (const LogLevel & org){ - for(Uint32 i = 0; i= 0 && (Uint32) ec < LOGLEVEL_CATEGORIES); - logLevelData[ec] = level; + logLevelData[ec] = (Uint8)level; } inline @@ -173,8 +129,30 @@ Uint32 LogLevel::getLogLevel(EventCategory ec) const{ assert(ec >= 0 && (Uint32) ec < LOGLEVEL_CATEGORIES); - return logLevelData[ec]; + return (Uint32)logLevelData[ec]; } +inline +LogLevel & +LogLevel::set_max(const LogLevel & org){ + for(Uint32 i = 0; i + +inline +LogLevel& +LogLevel::operator=(const EventSubscribeReq& req) +{ + clear(); + for(size_t i = 0; i> 16)] = req.theData[i] & 0xFFFF; + } + return * this; +} #endif diff --git a/ndb/include/kernel/signaldata/CreateTable.hpp b/ndb/include/kernel/signaldata/CreateTable.hpp index 424367f28d5..67e510d2ed0 100644 --- a/ndb/include/kernel/signaldata/CreateTable.hpp +++ b/ndb/include/kernel/signaldata/CreateTable.hpp @@ -89,7 +89,8 @@ public: ArraySizeTooBig = 737, RecordTooBig = 738, InvalidPrimaryKeySize = 739, - NullablePrimaryKey = 740 + NullablePrimaryKey = 740, + InvalidCharset = 743 }; private: diff --git a/ndb/include/kernel/signaldata/DictTabInfo.hpp b/ndb/include/kernel/signaldata/DictTabInfo.hpp index dec7145c897..a9a50f19fbc 100644 --- a/ndb/include/kernel/signaldata/DictTabInfo.hpp +++ b/ndb/include/kernel/signaldata/DictTabInfo.hpp @@ -438,8 +438,8 @@ public: case DictTabInfo::ExtText: AttributeType = DictTabInfo::StringType; AttributeSize = DictTabInfo::an8Bit; - // head + inline part [ attr precision ] - AttributeArraySize = (NDB_BLOB_HEAD_SIZE << 2) + AttributeExtPrecision; + // head + inline part [ attr precision lower half ] + AttributeArraySize = (NDB_BLOB_HEAD_SIZE << 2) + (AttributeExtPrecision & 0xFFFF); return true; }; return false; diff --git a/ndb/include/kernel/signaldata/EventReport.hpp b/ndb/include/kernel/signaldata/EventReport.hpp index b6106bb0ca4..1ad6e1bf7ac 100644 --- a/ndb/include/kernel/signaldata/EventReport.hpp +++ b/ndb/include/kernel/signaldata/EventReport.hpp @@ -135,12 +135,17 @@ public: //GREP GrepSubscriptionInfo = 52, - GrepSubscriptionAlert = 53 - }; + GrepSubscriptionAlert = 53, + //BACKUP + BackupStarted = 54, + BackupFailedToStart = 55, + BackupCompleted = 56, + BackupAborted = 57 + }; + void setEventType(EventType type); EventType getEventType() const; -private: UintR eventType; // DATA 0 }; diff --git a/ndb/include/kernel/signaldata/EventSubscribeReq.hpp b/ndb/include/kernel/signaldata/EventSubscribeReq.hpp index fd2821ea31d..84a1717b1de 100644 --- a/ndb/include/kernel/signaldata/EventSubscribeReq.hpp +++ b/ndb/include/kernel/signaldata/EventSubscribeReq.hpp @@ -27,7 +27,7 @@ * RECIVER: SimBlockCMCtrBlck */ -class EventSubscribeReq { +struct EventSubscribeReq { /** * Receiver(s) */ @@ -38,9 +38,8 @@ class EventSubscribeReq { */ friend class MgmtSrvr; -public: - STATIC_CONST( SignalLength = 22 ); -private: + STATIC_CONST( SignalLength = 2 + LogLevel::LOGLEVEL_CATEGORIES ); + /** * Note: If you use the same blockRef as you have used earlier, * you update your ongoing subscription @@ -53,8 +52,15 @@ private: */ Uint32 noOfEntries; - Uint32 theCategories[10]; - Uint32 theLevels[10]; + Uint32 theData[LogLevel::LOGLEVEL_CATEGORIES]; + + EventSubscribeReq& operator= (const LogLevel& ll){ + noOfEntries = LogLevel::LOGLEVEL_CATEGORIES; + for(size_t i = 0; i +#include "EventSubscribeReq.hpp" #include "SignalData.hpp" /** @@ -39,11 +40,10 @@ class SetLogLevelOrd { friend class NodeLogLevel; private: - STATIC_CONST( SignalLength = 25 ); - + STATIC_CONST( SignalLength = 1 + LogLevel::LOGLEVEL_CATEGORIES ); + Uint32 noOfEntries; - Uint32 theCategories[12]; - Uint32 theLevels[12]; + Uint32 theData[LogLevel::LOGLEVEL_CATEGORIES]; void clear(); @@ -51,6 +51,22 @@ private: * Note level is valid as 0-15 */ void setLogLevel(LogLevel::EventCategory ec, int level = 7); + + SetLogLevelOrd& operator= (const LogLevel& ll){ + noOfEntries = LogLevel::LOGLEVEL_CATEGORIES; + for(size_t i = 0; i +/* call in main() - does not return on error */ +extern int ndb_init(void); +extern void ndb_end(int); + #ifndef HAVE_STRDUP extern char * strdup(const char *s); #endif diff --git a/ndb/include/ndbapi/NdbDictionary.hpp b/ndb/include/ndbapi/NdbDictionary.hpp index 5c470c1d25f..51a6895648f 100644 --- a/ndb/include/ndbapi/NdbDictionary.hpp +++ b/ndb/include/ndbapi/NdbDictionary.hpp @@ -32,6 +32,8 @@ #include class Ndb; +struct charset_info_st; +typedef struct charset_info_st CHARSET_INFO; /** * @class NdbDictionary @@ -257,6 +259,10 @@ public: /** * Set type of column * @param type Type of column + * + * @note setType resets all column attributes + * to (type dependent) defaults and should be the first + * method to call. Default type is Unsigned. */ void setType(Type type); @@ -301,28 +307,36 @@ public: */ int getLength() const; + /** + * For Char or Varchar or Text, set or get MySQL CHARSET_INFO. This + * specifies both character set and collation. See get_charset() + * etc in MySQL. (The cs is not "const" in MySQL). + */ + void setCharset(CHARSET_INFO* cs); + CHARSET_INFO* getCharset() const; + /** * For blob, set or get "inline size" i.e. number of initial bytes * to store in table's blob attribute. This part is normally in * main memory and can be indexed and interpreted. */ - void setInlineSize(int size) { setPrecision(size); } - int getInlineSize() const { return getPrecision(); } + void setInlineSize(int size); + int getInlineSize() const; /** * For blob, set or get "part size" i.e. number of bytes to store in * each tuple of the "blob table". Can be set to zero to omit parts * and to allow only inline bytes ("tinyblob"). */ - void setPartSize(int size) { setScale(size); } - int getPartSize() const { return getScale(); } + void setPartSize(int size); + int getPartSize() const; /** * For blob, set or get "stripe size" i.e. number of consecutive * parts to store in each node group. */ - void setStripeSize(int size) { setLength(size); } - int getStripeSize() const { return getLength(); } + void setStripeSize(int size); + int getStripeSize() const; /** * Get size of element diff --git a/ndb/include/ndbapi/NdbIndexOperation.hpp b/ndb/include/ndbapi/NdbIndexOperation.hpp index 36c3c73db2d..7612fe54d1b 100644 --- a/ndb/include/ndbapi/NdbIndexOperation.hpp +++ b/ndb/include/ndbapi/NdbIndexOperation.hpp @@ -49,6 +49,15 @@ public: * @{ */ + /** + * Define the NdbIndexOperation to be a standard operation of type readTuple. + * When calling NdbConnection::execute, this operation + * reads a tuple. + * + * @return 0 if successful otherwise -1. + */ + int readTuple(LockMode); + /** * Define the NdbIndexOperation to be a standard operation of type readTuple. * When calling NdbConnection::execute, this operation diff --git a/ndb/include/ndbapi/NdbOperation.hpp b/ndb/include/ndbapi/NdbOperation.hpp index 2d08fa57aae..a8bd8b9bfea 100644 --- a/ndb/include/ndbapi/NdbOperation.hpp +++ b/ndb/include/ndbapi/NdbOperation.hpp @@ -51,6 +51,19 @@ public: * @{ */ + /** + * Lock when performing read + */ + + enum LockMode { + LM_Read = 0, + LM_Exclusive = 1, + LM_CommittedRead = 2, +#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL + LM_Dirty = 2 +#endif + }; + /** * Define the NdbOperation to be a standard operation of type insertTuple. * When calling NdbConnection::execute, this operation @@ -88,6 +101,15 @@ public: */ virtual int deleteTuple(); + /** + * Define the NdbOperation to be a standard operation of type readTuple. + * When calling NdbConnection::execute, this operation + * reads a tuple. + * + * @return 0 if successful otherwise -1. + */ + virtual int readTuple(LockMode); + /** * Define the NdbOperation to be a standard operation of type readTuple. * When calling NdbConnection::execute, this operation diff --git a/ndb/include/ndbapi/NdbScanOperation.hpp b/ndb/include/ndbapi/NdbScanOperation.hpp index 6ae71ef5aef..e8a4408469c 100644 --- a/ndb/include/ndbapi/NdbScanOperation.hpp +++ b/ndb/include/ndbapi/NdbScanOperation.hpp @@ -53,18 +53,6 @@ public: IndexCursor = 2 }; - /** - * Lock when performing scan - */ - enum LockMode { - LM_Read = 0, - LM_Exclusive = 1, - LM_CommittedRead = 2, -#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL - LM_Dirty = 2 -#endif - }; - /** * Type of cursor */ diff --git a/ndb/include/ndbapi/ndb_cluster_connection.hpp b/ndb/include/ndbapi/ndb_cluster_connection.hpp index 59d5a038844..f8e6f25ce73 100644 --- a/ndb/include/ndbapi/ndb_cluster_connection.hpp +++ b/ndb/include/ndbapi/ndb_cluster_connection.hpp @@ -19,6 +19,7 @@ #define CLUSTER_CONNECTION_HPP class TransporterFacade; +class LocalConfig; class ConfigRetriever; class NdbThread; @@ -37,6 +38,7 @@ private: void connect_thread(); char *m_connect_string; TransporterFacade *m_facade; + LocalConfig *m_local_config; ConfigRetriever *m_config_retriever; NdbThread *m_connect_thread; int (*m_connect_callback)(void); diff --git a/ndb/include/transporter/TransporterDefinitions.hpp b/ndb/include/transporter/TransporterDefinitions.hpp index 445e8b889d2..a8da8068552 100644 --- a/ndb/include/transporter/TransporterDefinitions.hpp +++ b/ndb/include/transporter/TransporterDefinitions.hpp @@ -59,8 +59,6 @@ struct TCP_TransporterConfiguration { NodeId localNodeId; Uint32 sendBufferSize; // Size of SendBuffer of priority B Uint32 maxReceiveSize; // Maximum no of bytes to receive - Uint32 byteOrder; - bool compression; bool checksum; bool signalId; }; @@ -72,10 +70,8 @@ struct SHM_TransporterConfiguration { Uint32 port; NodeId remoteNodeId; NodeId localNodeId; - bool compression; bool checksum; bool signalId; - int byteOrder; Uint32 shmKey; Uint32 shmSize; @@ -89,10 +85,8 @@ struct OSE_TransporterConfiguration { const char *localHostName; NodeId remoteNodeId; NodeId localNodeId; - bool compression; bool checksum; bool signalId; - int byteOrder; Uint32 prioASignalSize; Uint32 prioBSignalSize; @@ -103,20 +97,20 @@ struct OSE_TransporterConfiguration { * SCI Transporter Configuration */ struct SCI_TransporterConfiguration { + const char *remoteHostName; + const char *localHostName; + Uint32 port; Uint32 sendLimit; // Packet size Uint32 bufferSize; // Buffer size Uint32 nLocalAdapters; // 1 or 2, the number of adapters on local host - Uint32 nRemoteAdapters; Uint32 remoteSciNodeId0; // SCInodeId for adapter 1 Uint32 remoteSciNodeId1; // SCInodeId for adapter 2 NodeId localNodeId; // Local node Id NodeId remoteNodeId; // Remote node Id - Uint32 byteOrder; - bool compression; bool checksum; bool signalId; diff --git a/ndb/include/transporter/TransporterRegistry.hpp b/ndb/include/transporter/TransporterRegistry.hpp index 3c6c307406c..ac6291f9e57 100644 --- a/ndb/include/transporter/TransporterRegistry.hpp +++ b/ndb/include/transporter/TransporterRegistry.hpp @@ -218,15 +218,18 @@ public: void printState(); #endif - unsigned short m_service_port; - + class Transporter_interface { + public: + unsigned short m_service_port; + const char *m_interface; + }; + Vector m_transporter_interface; + void add_transporter_interface(const char *interface, unsigned short port); protected: private: void * callbackObj; - TransporterService *m_transporter_service; - char *m_interface_name; struct NdbThread *m_start_clients_thread; bool m_run_start_clients_thread; diff --git a/ndb/include/util/NdbSqlUtil.hpp b/ndb/include/util/NdbSqlUtil.hpp index 1d3e96d5c7e..3062d1e4e1b 100644 --- a/ndb/include/util/NdbSqlUtil.hpp +++ b/ndb/include/util/NdbSqlUtil.hpp @@ -40,11 +40,14 @@ public: * Compare kernel attribute values. Returns -1, 0, +1 for less, * equal, greater, respectively. Parameters are pointers to values, * full attribute size in words, and size of available data in words. + * There is also pointer to type specific extra info. Char types + * receive CHARSET_INFO in it. + * * If available size is less than full size, CmpUnknown may be * returned. If a value cannot be parsed, it compares like NULL i.e. * less than any valid value. */ - typedef int Cmp(const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size); + typedef int Cmp(const void* info, const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size); enum CmpResult { CmpLess = -1, @@ -55,6 +58,7 @@ public: /** * Kernel data types. Must match m_typeList in NdbSqlUtil.cpp. + * Now also must match types in NdbDictionary. */ struct Type { enum Enum { @@ -90,6 +94,18 @@ public: */ static const Type& getType(Uint32 typeId); + /** + * Get type by id but replace char type by corresponding binary type. + */ + static const Type& getTypeBinary(Uint32 typeId); + + /** + * Check character set. + */ + static bool usable_in_pk(Uint32 typeId, const void* cs); + static bool usable_in_hash_index(Uint32 typeId, const void* cs); + static bool usable_in_ordered_index(Uint32 typeId, const void* cs); + private: /** * List of all types. Must match Type::Enum. diff --git a/ndb/include/util/SocketServer.hpp b/ndb/include/util/SocketServer.hpp index 334fa575e47..3860b9ca84b 100644 --- a/ndb/include/util/SocketServer.hpp +++ b/ndb/include/util/SocketServer.hpp @@ -76,7 +76,7 @@ public: * then close the socket * Returns true if succeding in binding */ - bool tryBind(unsigned short port, const char * intface = 0) const; + static bool tryBind(unsigned short port, const char * intface = 0); /** * Setup socket diff --git a/ndb/src/common/debugger/EventLogger.cpp b/ndb/src/common/debugger/EventLogger.cpp index 69874ab7ecc..03445622e6a 100644 --- a/ndb/src/common/debugger/EventLogger.cpp +++ b/ndb/src/common/debugger/EventLogger.cpp @@ -28,6 +28,10 @@ // // PUBLIC // +EventLoggerBase::~EventLoggerBase() +{ + +} /** * This matrix defines which event should be printed when @@ -35,122 +39,89 @@ * threshold - is in range [0-15] * severity - DEBUG to ALERT (Type of log message) */ -const EventLogger::EventRepLogLevelMatrix EventLogger::matrix[] = { +const EventLoggerBase::EventRepLogLevelMatrix EventLoggerBase::matrix[] = { // CONNECTION - { EventReport::Connected, LogLevel::llConnection, 8, LL_INFO }, - { EventReport::Disconnected, LogLevel::llConnection, 8, LL_ALERT }, - { EventReport::CommunicationClosed, LogLevel::llConnection, 8, LL_INFO }, - { EventReport::CommunicationOpened, LogLevel::llConnection, 8, LL_INFO }, - { EventReport::ConnectedApiVersion, LogLevel::llConnection, 8, LL_INFO }, + { EventReport::Connected, LogLevel::llConnection, 8, Logger::LL_INFO }, + { EventReport::Disconnected, LogLevel::llConnection, 8, Logger::LL_ALERT }, + { EventReport::CommunicationClosed, LogLevel::llConnection, 8, Logger::LL_INFO }, + { EventReport::CommunicationOpened, LogLevel::llConnection, 8, Logger::LL_INFO }, + { EventReport::ConnectedApiVersion, LogLevel::llConnection, 8, Logger::LL_INFO }, // CHECKPOINT - { EventReport::GlobalCheckpointStarted, LogLevel::llCheckpoint, 9, LL_INFO }, - { EventReport::GlobalCheckpointCompleted,LogLevel::llCheckpoint,10, LL_INFO }, - { EventReport::LocalCheckpointStarted, LogLevel::llCheckpoint, 7, LL_INFO }, - { EventReport::LocalCheckpointCompleted,LogLevel::llCheckpoint, 8, LL_INFO }, - { EventReport::LCPStoppedInCalcKeepGci, LogLevel::llCheckpoint, 0, LL_ALERT }, - { EventReport::LCPFragmentCompleted, LogLevel::llCheckpoint, 11, LL_INFO }, - { EventReport::UndoLogBlocked, LogLevel::llCheckpoint, 7, LL_INFO }, + { EventReport::GlobalCheckpointStarted, LogLevel::llCheckpoint, 9, Logger::LL_INFO }, + { EventReport::GlobalCheckpointCompleted,LogLevel::llCheckpoint,10, Logger::LL_INFO }, + { EventReport::LocalCheckpointStarted, LogLevel::llCheckpoint, 7, Logger::LL_INFO }, + { EventReport::LocalCheckpointCompleted,LogLevel::llCheckpoint, 8, Logger::LL_INFO }, + { EventReport::LCPStoppedInCalcKeepGci, LogLevel::llCheckpoint, 0, Logger::LL_ALERT }, + { EventReport::LCPFragmentCompleted, LogLevel::llCheckpoint, 11, Logger::LL_INFO }, + { EventReport::UndoLogBlocked, LogLevel::llCheckpoint, 7, Logger::LL_INFO }, // STARTUP - { EventReport::NDBStartStarted, LogLevel::llStartUp, 1, LL_INFO }, - { EventReport::NDBStartCompleted, LogLevel::llStartUp, 1, LL_INFO }, - { EventReport::STTORRYRecieved, LogLevel::llStartUp,15, LL_INFO }, - { EventReport::StartPhaseCompleted, LogLevel::llStartUp, 4, LL_INFO }, - { EventReport::CM_REGCONF, LogLevel::llStartUp, 3, LL_INFO }, - { EventReport::CM_REGREF, LogLevel::llStartUp, 8, LL_INFO }, - { EventReport::FIND_NEIGHBOURS, LogLevel::llStartUp, 8, LL_INFO }, - { EventReport::NDBStopStarted, LogLevel::llStartUp, 1, LL_INFO }, - { EventReport::NDBStopAborted, LogLevel::llStartUp, 1, LL_INFO }, - { EventReport::StartREDOLog, LogLevel::llStartUp, 10, LL_INFO }, - { EventReport::StartLog, LogLevel::llStartUp, 10, LL_INFO }, - { EventReport::UNDORecordsExecuted, LogLevel::llStartUp, 15, LL_INFO }, + { EventReport::NDBStartStarted, LogLevel::llStartUp, 1, Logger::LL_INFO }, + { EventReport::NDBStartCompleted, LogLevel::llStartUp, 1, Logger::LL_INFO }, + { EventReport::STTORRYRecieved, LogLevel::llStartUp,15, Logger::LL_INFO }, + { EventReport::StartPhaseCompleted, LogLevel::llStartUp, 4, Logger::LL_INFO }, + { EventReport::CM_REGCONF, LogLevel::llStartUp, 3, Logger::LL_INFO }, + { EventReport::CM_REGREF, LogLevel::llStartUp, 8, Logger::LL_INFO }, + { EventReport::FIND_NEIGHBOURS, LogLevel::llStartUp, 8, Logger::LL_INFO }, + { EventReport::NDBStopStarted, LogLevel::llStartUp, 1, Logger::LL_INFO }, + { EventReport::NDBStopAborted, LogLevel::llStartUp, 1, Logger::LL_INFO }, + { EventReport::StartREDOLog, LogLevel::llStartUp, 10, Logger::LL_INFO }, + { EventReport::StartLog, LogLevel::llStartUp, 10, Logger::LL_INFO }, + { EventReport::UNDORecordsExecuted, LogLevel::llStartUp, 15, Logger::LL_INFO }, // NODERESTART - { EventReport::NR_CopyDict, LogLevel::llNodeRestart, 8, LL_INFO }, - { EventReport::NR_CopyDistr, LogLevel::llNodeRestart, 8, LL_INFO }, - { EventReport::NR_CopyFragsStarted, LogLevel::llNodeRestart, 8, LL_INFO }, - { EventReport::NR_CopyFragDone, LogLevel::llNodeRestart, 10, LL_INFO }, - { EventReport::NR_CopyFragsCompleted, LogLevel::llNodeRestart, 8, LL_INFO }, + { EventReport::NR_CopyDict, LogLevel::llNodeRestart, 8, Logger::LL_INFO }, + { EventReport::NR_CopyDistr, LogLevel::llNodeRestart, 8, Logger::LL_INFO }, + { EventReport::NR_CopyFragsStarted, LogLevel::llNodeRestart, 8, Logger::LL_INFO }, + { EventReport::NR_CopyFragDone, LogLevel::llNodeRestart, 10, Logger::LL_INFO }, + { EventReport::NR_CopyFragsCompleted, LogLevel::llNodeRestart, 8, Logger::LL_INFO }, - { EventReport::NodeFailCompleted, LogLevel::llNodeRestart, 8, LL_ALERT}, - { EventReport::NODE_FAILREP, LogLevel::llNodeRestart, 8, LL_ALERT}, - { EventReport::ArbitState, LogLevel::llNodeRestart, 6, LL_INFO }, - { EventReport::ArbitResult, LogLevel::llNodeRestart, 2, LL_ALERT}, - { EventReport::GCP_TakeoverStarted, LogLevel::llNodeRestart, 7, LL_INFO }, - { EventReport::GCP_TakeoverCompleted, LogLevel::llNodeRestart, 7, LL_INFO }, - { EventReport::LCP_TakeoverStarted, LogLevel::llNodeRestart, 7, LL_INFO }, - { EventReport::LCP_TakeoverCompleted, LogLevel::llNodeRestart, 7, LL_INFO }, + { EventReport::NodeFailCompleted, LogLevel::llNodeRestart, 8, Logger::LL_ALERT}, + { EventReport::NODE_FAILREP, LogLevel::llNodeRestart, 8, Logger::LL_ALERT}, + { EventReport::ArbitState, LogLevel::llNodeRestart, 6, Logger::LL_INFO }, + { EventReport::ArbitResult, LogLevel::llNodeRestart, 2, Logger::LL_ALERT}, + { EventReport::GCP_TakeoverStarted, LogLevel::llNodeRestart, 7, Logger::LL_INFO }, + { EventReport::GCP_TakeoverCompleted, LogLevel::llNodeRestart, 7, Logger::LL_INFO }, + { EventReport::LCP_TakeoverStarted, LogLevel::llNodeRestart, 7, Logger::LL_INFO }, + { EventReport::LCP_TakeoverCompleted, LogLevel::llNodeRestart, 7, Logger::LL_INFO }, // STATISTIC - { EventReport::TransReportCounters, LogLevel::llStatistic, 8, LL_INFO }, - { EventReport::OperationReportCounters, LogLevel::llStatistic, 8, LL_INFO }, - { EventReport::TableCreated, LogLevel::llStatistic, 7, LL_INFO }, - { EventReport::JobStatistic, LogLevel::llStatistic, 9, LL_INFO }, - { EventReport::SendBytesStatistic, LogLevel::llStatistic, 9, LL_INFO }, - { EventReport::ReceiveBytesStatistic, LogLevel::llStatistic, 9, LL_INFO }, - { EventReport::MemoryUsage, LogLevel::llStatistic, 5, LL_INFO }, + { EventReport::TransReportCounters, LogLevel::llStatistic, 8, Logger::LL_INFO }, + { EventReport::OperationReportCounters, LogLevel::llStatistic, 8, Logger::LL_INFO }, + { EventReport::TableCreated, LogLevel::llStatistic, 7, Logger::LL_INFO }, + { EventReport::JobStatistic, LogLevel::llStatistic, 9, Logger::LL_INFO }, + { EventReport::SendBytesStatistic, LogLevel::llStatistic, 9, Logger::LL_INFO }, + { EventReport::ReceiveBytesStatistic, LogLevel::llStatistic, 9, Logger::LL_INFO }, + { EventReport::MemoryUsage, LogLevel::llStatistic, 5, Logger::LL_INFO }, // ERROR - { EventReport::TransporterError, LogLevel::llError, 2, LL_ERROR }, - { EventReport::TransporterWarning, LogLevel::llError, 8, LL_WARNING }, - { EventReport::MissedHeartbeat, LogLevel::llError, 8, LL_WARNING }, - { EventReport::DeadDueToHeartbeat, LogLevel::llError, 8, LL_ALERT }, - { EventReport::WarningEvent, LogLevel::llError, 2, LL_WARNING }, + { EventReport::TransporterError, LogLevel::llError, 2, Logger::LL_ERROR }, + { EventReport::TransporterWarning, LogLevel::llError, 8, Logger::LL_WARNING }, + { EventReport::MissedHeartbeat, LogLevel::llError, 8, Logger::LL_WARNING }, + { EventReport::DeadDueToHeartbeat, LogLevel::llError, 8, Logger::LL_ALERT }, + { EventReport::WarningEvent, LogLevel::llError, 2, Logger::LL_WARNING }, // INFO - { EventReport::SentHeartbeat, LogLevel::llInfo, 12, LL_INFO }, - { EventReport::CreateLogBytes, LogLevel::llInfo, 11, LL_INFO }, - { EventReport::InfoEvent, LogLevel::llInfo, 2, LL_INFO }, + { EventReport::SentHeartbeat, LogLevel::llInfo, 12, Logger::LL_INFO }, + { EventReport::CreateLogBytes, LogLevel::llInfo, 11, Logger::LL_INFO }, + { EventReport::InfoEvent, LogLevel::llInfo, 2, Logger::LL_INFO }, //Global replication - { EventReport::GrepSubscriptionInfo, LogLevel::llGrep, 7, LL_INFO}, - { EventReport::GrepSubscriptionAlert, LogLevel::llGrep, 7, LL_ALERT} + { EventReport::GrepSubscriptionInfo, LogLevel::llGrep, 7, Logger::LL_INFO}, + { EventReport::GrepSubscriptionAlert, LogLevel::llGrep, 7, Logger::LL_ALERT}, + + // Backup + { EventReport::BackupStarted, LogLevel::llBackup, 7, Logger::LL_INFO }, + { EventReport::BackupCompleted, LogLevel::llBackup, 7, Logger::LL_INFO }, + { EventReport::BackupFailedToStart, LogLevel::llBackup, 7, Logger::LL_ALERT}, + { EventReport::BackupAborted, LogLevel::llBackup, 7, Logger::LL_ALERT } }; -const Uint32 EventLogger::matrixSize = sizeof(EventLogger::matrix)/ +const Uint32 EventLoggerBase::matrixSize = sizeof(EventLoggerBase::matrix)/ sizeof(EventRepLogLevelMatrix); -/** - * Default log levels for management nodes. - * - * threshold - is in range [0-15] - */ -const EventLogger::EventLogMatrix EventLogger::defEventLogMatrix[] = { - { LogLevel::llStartUp, 7 }, - { LogLevel::llShutdown, 7 }, - { LogLevel::llStatistic, 7 }, - { LogLevel::llCheckpoint, 7 }, - { LogLevel::llNodeRestart, 7 }, - { LogLevel::llConnection, 7 }, - { LogLevel::llError, 15 }, - { LogLevel::llInfo, 7 }, - { LogLevel::llGrep, 7 } -}; - -const Uint32 -EventLogger::defEventLogMatrixSize = sizeof(EventLogger::defEventLogMatrix)/ - sizeof(EventLogMatrix); -/** - * Specifies allowed event categories/log levels that can be set from - * the Management API/interactive shell. - */ -const EventLogger::EventCategoryName EventLogger::eventCategoryNames[] = { - { LogLevel::llStartUp, "STARTUP" }, - { LogLevel::llStatistic, "STATISTICS" }, - { LogLevel::llCheckpoint, "CHECKPOINT" }, - { LogLevel::llNodeRestart, "NODERESTART" }, - { LogLevel::llConnection, "CONNECTION" }, - { LogLevel::llInfo, "INFO" }, - { LogLevel::llGrep, "GREP" } -}; - -const Uint32 -EventLogger::noOfEventCategoryNames = sizeof(EventLogger::eventCategoryNames)/ - sizeof(EventLogger::EventCategoryName); - -char EventLogger::m_text[MAX_TEXT_LENGTH]; - const char* -EventLogger::getText(int type, +EventLogger::getText(char * m_text, size_t m_text_len, + int type, const Uint32* theData, NodeId nodeId) { // TODO: Change the switch implementation... @@ -164,13 +135,13 @@ EventLogger::getText(int type, EventReport::EventType eventType = (EventReport::EventType)type; switch (eventType){ case EventReport::Connected: - ::snprintf(m_text, sizeof(m_text), + ::snprintf(m_text, m_text_len, "%sNode %u Connected", theNodeId, theData[1]); break; case EventReport::ConnectedApiVersion: - ::snprintf(m_text, sizeof(m_text), + ::snprintf(m_text, m_text_len, "%sNode %u: API version %d.%d.%d", theNodeId, theData[1], @@ -179,7 +150,7 @@ EventLogger::getText(int type, getBuild(theData[2])); break; case EventReport::Disconnected: - ::snprintf(m_text, sizeof(m_text), + ::snprintf(m_text, m_text_len, "%sNode %u Disconnected", theNodeId, theData[1]); @@ -188,7 +159,7 @@ EventLogger::getText(int type, //----------------------------------------------------------------------- // REPORT communication to node closed. //----------------------------------------------------------------------- - ::snprintf(m_text, sizeof(m_text), + ::snprintf(m_text, m_text_len, "%sCommunication to Node %u closed", theNodeId, theData[1]); @@ -197,7 +168,7 @@ EventLogger::getText(int type, //----------------------------------------------------------------------- // REPORT communication to node opened. //----------------------------------------------------------------------- - ::snprintf(m_text, sizeof(m_text), + ::snprintf(m_text, m_text_len, "%sCommunication to Node %u opened", theNodeId, theData[1]); @@ -206,7 +177,7 @@ EventLogger::getText(int type, //----------------------------------------------------------------------- // Start of NDB has been initiated. //----------------------------------------------------------------------- - ::snprintf(m_text, sizeof(m_text), + ::snprintf(m_text, m_text_len, "%sStart initiated (version %d.%d.%d)", theNodeId , getMajor(theData[1]), @@ -214,13 +185,13 @@ EventLogger::getText(int type, getBuild(theData[1])); break; case EventReport::NDBStopStarted: - ::snprintf(m_text, sizeof(m_text), + ::snprintf(m_text, m_text_len, "%s%s shutdown initiated", theNodeId, (theData[1] == 1 ? "Cluster" : "Node")); break; case EventReport::NDBStopAborted: - ::snprintf(m_text, sizeof(m_text), + ::snprintf(m_text, m_text_len, "%sNode shutdown aborted", theNodeId); break; @@ -228,7 +199,7 @@ EventLogger::getText(int type, //----------------------------------------------------------------------- // Start of NDB has been completed. //----------------------------------------------------------------------- - ::snprintf(m_text, sizeof(m_text), + ::snprintf(m_text, m_text_len, "%sStarted (version %d.%d.%d)", theNodeId , getMajor(theData[1]), @@ -240,7 +211,7 @@ EventLogger::getText(int type, //----------------------------------------------------------------------- // STTORRY recevied after restart finished. //----------------------------------------------------------------------- - ::snprintf(m_text, sizeof(m_text), + ::snprintf(m_text, m_text_len, "%sSTTORRY received after restart finished", theNodeId); break; @@ -266,7 +237,7 @@ EventLogger::getText(int type, type = ""; break; default:{ - ::snprintf(m_text, sizeof(m_text), + ::snprintf(m_text, m_text_len, "%sStart phase %u completed (unknown = %d)", theNodeId, theData[1], @@ -274,7 +245,7 @@ EventLogger::getText(int type, return m_text; } } - ::snprintf(m_text, sizeof(m_text), + ::snprintf(m_text, m_text_len, "%sStart phase %u completed %s", theNodeId, theData[1], @@ -283,7 +254,7 @@ EventLogger::getText(int type, break; } case EventReport::CM_REGCONF: - ::snprintf(m_text, sizeof(m_text), + ::snprintf(m_text, m_text_len, "%sCM_REGCONF president = %u, own Node = %u, our dynamic id = %u" , theNodeId, @@ -315,7 +286,7 @@ EventLogger::getText(int type, break; }//switch - ::snprintf(m_text, sizeof(m_text), + ::snprintf(m_text, m_text_len, "%sCM_REGREF from Node %u to our Node %u. Cause = %s", theNodeId, theData[2], @@ -328,7 +299,7 @@ EventLogger::getText(int type, // REPORT Node Restart copied a fragment. //----------------------------------------------------------------------- ::snprintf(m_text, - sizeof(m_text), + m_text_len, "%sWe are Node %u with dynamic ID %u, our left neighbour " "is Node %u, our right is Node %u", theNodeId, @@ -344,13 +315,13 @@ EventLogger::getText(int type, if (theData[1] == 0) { if (theData[3] != 0) { - ::snprintf(m_text, sizeof(m_text), + ::snprintf(m_text, m_text_len, "%sNode %u completed failure of Node %u", theNodeId, theData[3], theData[2]); } else { - ::snprintf(m_text, sizeof(m_text), + ::snprintf(m_text, m_text_len, "%sAll nodes completed failure of Node %u", theNodeId, theData[2]); @@ -367,7 +338,7 @@ EventLogger::getText(int type, line = "DBLQH"; } - ::snprintf(m_text, sizeof(m_text), + ::snprintf(m_text, m_text_len, "%sNode failure of %u %s completed", theNodeId, theData[2], @@ -376,7 +347,7 @@ EventLogger::getText(int type, break; case EventReport::NODE_FAILREP: ::snprintf(m_text, - sizeof(m_text), + m_text_len, "%sNode %u has failed. The Node state at failure " "was %u", theNodeId, @@ -395,41 +366,41 @@ EventLogger::getText(int type, const unsigned state = sd->code >> 16; switch (code) { case ArbitCode::ThreadStart: - ::snprintf(m_text, sizeof(m_text), + ::snprintf(m_text, m_text_len, "%sPresident restarts arbitration thread [state=%u]", theNodeId, state); break; case ArbitCode::PrepPart2: sd->ticket.getText(ticketText, sizeof(ticketText)); - ::snprintf(m_text, sizeof(m_text), + ::snprintf(m_text, m_text_len, "%sPrepare arbitrator node %u [ticket=%s]", theNodeId, sd->node, ticketText); break; case ArbitCode::PrepAtrun: sd->ticket.getText(ticketText, sizeof(ticketText)); - ::snprintf(m_text, sizeof(m_text), + ::snprintf(m_text, m_text_len, "%sReceive arbitrator node %u [ticket=%s]", theNodeId, sd->node, ticketText); break; case ArbitCode::ApiStart: sd->ticket.getText(ticketText, sizeof(ticketText)); - ::snprintf(m_text, sizeof(m_text), + ::snprintf(m_text, m_text_len, "%sStarted arbitrator node %u [ticket=%s]", theNodeId, sd->node, ticketText); break; case ArbitCode::ApiFail: - ::snprintf(m_text, sizeof(m_text), + ::snprintf(m_text, m_text_len, "%sLost arbitrator node %u - process failure [state=%u]", theNodeId, sd->node, state); break; case ArbitCode::ApiExit: - ::snprintf(m_text, sizeof(m_text), + ::snprintf(m_text, m_text_len, "%sLost arbitrator node %u - process exit [state=%u]", theNodeId, sd->node, state); break; default: ArbitCode::getErrText(code, errText, sizeof(errText)); - ::snprintf(m_text, sizeof(m_text), + ::snprintf(m_text, m_text_len, "%sLost arbitrator node %u - %s [state=%u]", theNodeId, sd->node, errText, state); break; @@ -446,48 +417,48 @@ EventLogger::getText(int type, const unsigned state = sd->code >> 16; switch (code) { case ArbitCode::LoseNodes: - ::snprintf(m_text, sizeof(m_text), + ::snprintf(m_text, m_text_len, "%sArbitration check lost - less than 1/2 nodes left", theNodeId); break; case ArbitCode::WinGroups: - ::snprintf(m_text, sizeof(m_text), + ::snprintf(m_text, m_text_len, "%sArbitration check won - node group majority", theNodeId); break; case ArbitCode::LoseGroups: - ::snprintf(m_text, sizeof(m_text), + ::snprintf(m_text, m_text_len, "%sArbitration check lost - missing node group", theNodeId); break; case ArbitCode::Partitioning: - ::snprintf(m_text, sizeof(m_text), + ::snprintf(m_text, m_text_len, "%sNetwork partitioning - arbitration required", theNodeId); break; case ArbitCode::WinChoose: - ::snprintf(m_text, sizeof(m_text), + ::snprintf(m_text, m_text_len, "%sArbitration won - positive reply from node %u", theNodeId, sd->node); break; case ArbitCode::LoseChoose: - ::snprintf(m_text, sizeof(m_text), + ::snprintf(m_text, m_text_len, "%sArbitration lost - negative reply from node %u", theNodeId, sd->node); break; case ArbitCode::LoseNorun: - ::snprintf(m_text, sizeof(m_text), + ::snprintf(m_text, m_text_len, "%sNetwork partitioning - no arbitrator available", theNodeId); break; case ArbitCode::LoseNocfg: - ::snprintf(m_text, sizeof(m_text), + ::snprintf(m_text, m_text_len, "%sNetwork partitioning - no arbitrator configured", theNodeId); break; default: ArbitCode::getErrText(code, errText, sizeof(errText)); - ::snprintf(m_text, sizeof(m_text), + ::snprintf(m_text, m_text_len, "%sArbitration failure - %s [state=%u]", theNodeId, errText, state); break; @@ -500,7 +471,7 @@ EventLogger::getText(int type, // node is the master of this global checkpoint. //----------------------------------------------------------------------- ::snprintf(m_text, - sizeof(m_text), + m_text_len, "%sGlobal checkpoint %u started", theNodeId, theData[1]); @@ -510,7 +481,7 @@ EventLogger::getText(int type, // This event reports that a global checkpoint has been completed on this // node and the node is the master of this global checkpoint. //----------------------------------------------------------------------- - ::snprintf(m_text, sizeof(m_text), + ::snprintf(m_text, m_text_len, "%sGlobal checkpoint %u completed", theNodeId, theData[1]); @@ -521,7 +492,7 @@ EventLogger::getText(int type, // node is the master of this local checkpoint. //----------------------------------------------------------------------- ::snprintf(m_text, - sizeof(m_text), + m_text_len, "%sLocal checkpoint %u started. " "Keep GCI = %u oldest restorable GCI = %u", theNodeId, @@ -535,7 +506,7 @@ EventLogger::getText(int type, // node and the node is the master of this local checkpoint. //----------------------------------------------------------------------- ::snprintf(m_text, - sizeof(m_text), + m_text_len, "%sLocal checkpoint %u completed", theNodeId, theData[1]); @@ -544,14 +515,14 @@ EventLogger::getText(int type, //----------------------------------------------------------------------- // This event reports that a table has been created. //----------------------------------------------------------------------- - ::snprintf(m_text, sizeof(m_text), + ::snprintf(m_text, m_text_len, "%sTable with ID = %u created", theNodeId, theData[1]); break; case EventReport::LCPStoppedInCalcKeepGci: if (theData[1] == 0) - ::snprintf(m_text, sizeof(m_text), + ::snprintf(m_text, m_text_len, "%sLocal Checkpoint stopped in CALCULATED_KEEP_GCI", theNodeId); break; @@ -560,7 +531,7 @@ EventLogger::getText(int type, // REPORT Node Restart completed copy of dictionary information. //----------------------------------------------------------------------- ::snprintf(m_text, - sizeof(m_text), + m_text_len, "%sNode restart completed copy of dictionary information", theNodeId); break; @@ -569,7 +540,7 @@ EventLogger::getText(int type, // REPORT Node Restart completed copy of distribution information. //----------------------------------------------------------------------- ::snprintf(m_text, - sizeof(m_text), + m_text_len, "%sNode restart completed copy of distribution information", theNodeId); break; @@ -578,7 +549,7 @@ EventLogger::getText(int type, // REPORT Node Restart is starting to copy the fragments. //----------------------------------------------------------------------- ::snprintf(m_text, - sizeof(m_text), + m_text_len, "%sNode restart starting to copy the fragments " "to Node %u", theNodeId, @@ -589,7 +560,7 @@ EventLogger::getText(int type, // REPORT Node Restart copied a fragment. //----------------------------------------------------------------------- ::snprintf(m_text, - sizeof(m_text), + m_text_len, "%sTable ID = %u, fragment ID = %u have been copied " "to Node %u", theNodeId, @@ -599,7 +570,7 @@ EventLogger::getText(int type, break; case EventReport::NR_CopyFragsCompleted: ::snprintf(m_text, - sizeof(m_text), + m_text_len, "%sNode restart completed copying the fragments " "to Node %u", theNodeId, @@ -607,7 +578,7 @@ EventLogger::getText(int type, break; case EventReport::LCPFragmentCompleted: ::snprintf(m_text, - sizeof(m_text), + m_text_len, "%sTable ID = %u, fragment ID = %u has completed LCP " "on Node %u", theNodeId, @@ -620,7 +591,7 @@ EventLogger::getText(int type, // Report information about transaction activity once per 10 seconds. // ------------------------------------------------------------------- ::snprintf(m_text, - sizeof(m_text), + m_text_len, "%sTrans. Count = %u, Commit Count = %u, " "Read Count = %u, Simple Read Count = %u,\n" "Write Count = %u, AttrInfo Count = %u, " @@ -639,7 +610,7 @@ EventLogger::getText(int type, theData[10]); break; case EventReport::OperationReportCounters: - ::snprintf(m_text, sizeof(m_text), + ::snprintf(m_text, m_text_len, "%sOperations=%u", theNodeId, theData[1]); @@ -649,7 +620,7 @@ EventLogger::getText(int type, // REPORT Undo Logging blocked due to buffer near to overflow. //----------------------------------------------------------------------- ::snprintf(m_text, - sizeof(m_text), + m_text_len, "%sACC Blocked %u and TUP Blocked %u times last second", theNodeId, theData[1], @@ -658,7 +629,7 @@ EventLogger::getText(int type, case EventReport::TransporterError: case EventReport::TransporterWarning: ::snprintf(m_text, - sizeof(m_text), + m_text_len, "%sTransporter to node %d reported error 0x%x", theNodeId, theData[1], @@ -669,7 +640,7 @@ EventLogger::getText(int type, // REPORT Undo Logging blocked due to buffer near to overflow. //----------------------------------------------------------------------- ::snprintf(m_text, - sizeof(m_text), + m_text_len, "%sNode %d missed heartbeat %d", theNodeId, theData[1], @@ -680,21 +651,21 @@ EventLogger::getText(int type, // REPORT Undo Logging blocked due to buffer near to overflow. //----------------------------------------------------------------------- ::snprintf(m_text, - sizeof(m_text), + m_text_len, "%sNode %d declared dead due to missed heartbeat", theNodeId, theData[1]); break; case EventReport::JobStatistic: ::snprintf(m_text, - sizeof(m_text), + m_text_len, "%sMean loop Counter in doJob last 8192 times = %u", theNodeId, theData[1]); break; case EventReport::SendBytesStatistic: ::snprintf(m_text, - sizeof(m_text), + m_text_len, "%sMean send size to Node = %d last 4096 sends = %u bytes", theNodeId, theData[1], @@ -702,7 +673,7 @@ EventLogger::getText(int type, break; case EventReport::ReceiveBytesStatistic: ::snprintf(m_text, - sizeof(m_text), + m_text_len, "%sMean receive size to Node = %d last 4096 sends = %u bytes", theNodeId, theData[1], @@ -710,14 +681,14 @@ EventLogger::getText(int type, break; case EventReport::SentHeartbeat: ::snprintf(m_text, - sizeof(m_text), + m_text_len, "%sNode Sent Heartbeat to node = %d", theNodeId, theData[1]); break; case EventReport::CreateLogBytes: ::snprintf(m_text, - sizeof(m_text), + m_text_len, "%sLog part %u, log file %u, MB %u", theNodeId, theData[1], @@ -726,7 +697,7 @@ EventLogger::getText(int type, break; case EventReport::StartLog: ::snprintf(m_text, - sizeof(m_text), + m_text_len, "%sLog part %u, start MB %u, stop MB %u, last GCI, log exec %u", theNodeId, theData[1], @@ -736,7 +707,7 @@ EventLogger::getText(int type, break; case EventReport::StartREDOLog: ::snprintf(m_text, - sizeof(m_text), + m_text_len, "%sNode: %d StartLog: [GCI Keep: %d LastCompleted: %d NewestRestorable: %d]", theNodeId, theData[1], @@ -753,7 +724,7 @@ EventLogger::getText(int type, } ::snprintf(m_text, - sizeof(m_text), + m_text_len, "%s UNDO %s %d [%d %d %d %d %d %d %d %d %d]", theNodeId, line, @@ -771,36 +742,36 @@ EventLogger::getText(int type, break; case EventReport::InfoEvent: ::snprintf(m_text, - sizeof(m_text), + m_text_len, "%s%s", theNodeId, (char *)&theData[1]); break; case EventReport::WarningEvent: ::snprintf(m_text, - sizeof(m_text), + m_text_len, "%s%s", theNodeId, (char *)&theData[1]); break; case EventReport::GCP_TakeoverStarted: ::snprintf(m_text, - sizeof(m_text), + m_text_len, "%sGCP Take over started", theNodeId); break; case EventReport::GCP_TakeoverCompleted: ::snprintf(m_text, - sizeof(m_text), + m_text_len, "%sGCP Take over completed", theNodeId); break; case EventReport::LCP_TakeoverStarted: ::snprintf(m_text, - sizeof(m_text), + m_text_len, "%sLCP Take over started", theNodeId); break; case EventReport::LCP_TakeoverCompleted: ::snprintf(m_text, - sizeof(m_text), + m_text_len, "%sLCP Take over completed (state = %d)", theNodeId, theData[1]); break; @@ -812,7 +783,7 @@ EventLogger::getText(int type, const int block = theData[5]; const int percent = (used*100)/total; - ::snprintf(m_text, sizeof(m_text), + ::snprintf(m_text, m_text_len, "%s%s usage %s %d%s(%d %dK pages of total %d)", theNodeId, (block==DBACC ? "Index" : (block == DBTUP ?"Data":"")), @@ -822,478 +793,508 @@ EventLogger::getText(int type, ); break; } - - case EventReport::GrepSubscriptionInfo : - { - GrepEvent::Subscription event = (GrepEvent::Subscription)theData[1]; - switch(event) { - case GrepEvent::GrepSS_CreateSubIdConf: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - ::snprintf(m_text, sizeof(m_text), - "Grep::SSCoord: Created subscription id" - " (subId=%d,SubKey=%d)" - " Return code: %d.", - subId, - subKey, - err); - break; - } - case GrepEvent::GrepPS_CreateSubIdConf: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - ::snprintf(m_text, sizeof(m_text), - "Grep::PSCoord: Created subscription id" - " (subId=%d,SubKey=%d)" - " Return code: %d.", - subId, - subKey, - err); - break; - } - case GrepEvent::GrepSS_SubCreateConf: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - const int nodegrp = theData[5]; - ::snprintf(m_text, sizeof(m_text), - "Grep::SSCoord: Created subscription using" - " (subId=%d,SubKey=%d)" - " in primary system. Primary system has %d nodegroup(s)." - " Return code: %d", - subId, - subKey, - nodegrp, - err); - break; - } - case GrepEvent::GrepPS_SubCreateConf: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - ::snprintf(m_text, sizeof(m_text), - "Grep::PSCoord: All participants have created " - "subscriptions" - " using (subId=%d,SubKey=%d)." - " Return code: %d", - subId, - subKey, - err); - break; - } - case GrepEvent::GrepSS_SubStartMetaConf: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - ::snprintf(m_text, sizeof(m_text), - "Grep::SSCoord: Logging started on meta data changes." - " using (subId=%d,SubKey=%d)" - " Return code: %d", - subId, - subKey, - err); - break; - } - case GrepEvent::GrepPS_SubStartMetaConf: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - ::snprintf(m_text, sizeof(m_text), - "Grep::PSCoord: All participants have started " - "logging meta data" - " changes on the subscription subId=%d,SubKey=%d) " - "(N.I yet)." - " Return code: %d", - subId, - subKey, - err); - break; - } - case GrepEvent::GrepSS_SubStartDataConf: { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - ::snprintf(m_text, sizeof(m_text), - "Grep::SSCoord: Logging started on table data changes " - " using (subId=%d,SubKey=%d)" - " Return code: %d", - subId, - subKey, - err); - break; - } - case GrepEvent::GrepPS_SubStartDataConf: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - ::snprintf(m_text, sizeof(m_text), - "Grep::PSCoord: All participants have started logging " - "table data changes on the subscription " - "subId=%d,SubKey=%d)." - " Return code: %d", - subId, - subKey, - err); - break; - } - case GrepEvent::GrepPS_SubSyncMetaConf: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - ::snprintf(m_text, sizeof(m_text), - "Grep::PSCoord: All participants have started " - " synchronization on meta data (META SCAN) using " - "(subId=%d,SubKey=%d)." - " Return code: %d", - subId, - subKey, - err); - break; - } - case GrepEvent::GrepSS_SubSyncMetaConf: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - ::snprintf(m_text, sizeof(m_text), - "Grep::SSCoord: Synchronization started (META SCAN) on " - " meta data using (subId=%d,SubKey=%d)" - " Return code: %d", - subId, - subKey, - err); - break; - } - case GrepEvent::GrepPS_SubSyncDataConf: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - ::snprintf(m_text, sizeof(m_text), - "Grep::PSCoord: All participants have started " - "synchronization " - " on table data (DATA SCAN) using (subId=%d,SubKey=%d)." - " Return code: %d", - subId, - subKey, - err); - break; - } - case GrepEvent::GrepSS_SubSyncDataConf: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - const int gci = theData[5]; - ::snprintf(m_text, sizeof(m_text), - "Grep::SSCoord: Synchronization started (DATA SCAN) on " - "table data using (subId=%d,SubKey=%d). GCI = %d" - " Return code: %d", - subId, - subKey, - gci, - err); - break; - } - case GrepEvent::GrepPS_SubRemoveConf: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - ::snprintf(m_text, sizeof(m_text), - "Grep::PSCoord: All participants have removed " - "subscription (subId=%d,SubKey=%d). I have cleaned " - "up resources I've used." - " Return code: %d", - subId, - subKey, - err); - break; - } - case GrepEvent::GrepSS_SubRemoveConf: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - ::snprintf(m_text, sizeof(m_text), - "Grep::SSCoord: Removed subscription " - "(subId=%d,SubKey=%d)" - " Return code: %d", - subId, - subKey, - err); - break; - } + { + GrepEvent::Subscription event = (GrepEvent::Subscription)theData[1]; + switch(event) { + case GrepEvent::GrepSS_CreateSubIdConf: + { + const int subId = theData[2]; + const int subKey = theData[3]; + const int err = theData[4]; + ::snprintf(m_text, m_text_len, + "Grep::SSCoord: Created subscription id" + " (subId=%d,SubKey=%d)" + " Return code: %d.", + subId, + subKey, + err); + break; + } + case GrepEvent::GrepPS_CreateSubIdConf: + { + const int subId = theData[2]; + const int subKey = theData[3]; + const int err = theData[4]; + ::snprintf(m_text, m_text_len, + "Grep::PSCoord: Created subscription id" + " (subId=%d,SubKey=%d)" + " Return code: %d.", + subId, + subKey, + err); + break; + } + case GrepEvent::GrepSS_SubCreateConf: + { + const int subId = theData[2]; + const int subKey = theData[3]; + const int err = theData[4]; + const int nodegrp = theData[5]; + ::snprintf(m_text, m_text_len, + "Grep::SSCoord: Created subscription using" + " (subId=%d,SubKey=%d)" + " in primary system. Primary system has %d nodegroup(s)." + " Return code: %d", + subId, + subKey, + nodegrp, + err); + break; + } + case GrepEvent::GrepPS_SubCreateConf: + { + const int subId = theData[2]; + const int subKey = theData[3]; + const int err = theData[4]; + ::snprintf(m_text, m_text_len, + "Grep::PSCoord: All participants have created " + "subscriptions" + " using (subId=%d,SubKey=%d)." + " Return code: %d", + subId, + subKey, + err); + break; + } + case GrepEvent::GrepSS_SubStartMetaConf: + { + const int subId = theData[2]; + const int subKey = theData[3]; + const int err = theData[4]; + ::snprintf(m_text, m_text_len, + "Grep::SSCoord: Logging started on meta data changes." + " using (subId=%d,SubKey=%d)" + " Return code: %d", + subId, + subKey, + err); + break; + } + case GrepEvent::GrepPS_SubStartMetaConf: + { + const int subId = theData[2]; + const int subKey = theData[3]; + const int err = theData[4]; + ::snprintf(m_text, m_text_len, + "Grep::PSCoord: All participants have started " + "logging meta data" + " changes on the subscription subId=%d,SubKey=%d) " + "(N.I yet)." + " Return code: %d", + subId, + subKey, + err); + break; + } + case GrepEvent::GrepSS_SubStartDataConf: { + const int subId = theData[2]; + const int subKey = theData[3]; + const int err = theData[4]; + ::snprintf(m_text, m_text_len, + "Grep::SSCoord: Logging started on table data changes " + " using (subId=%d,SubKey=%d)" + " Return code: %d", + subId, + subKey, + err); + break; + } + case GrepEvent::GrepPS_SubStartDataConf: + { + const int subId = theData[2]; + const int subKey = theData[3]; + const int err = theData[4]; + ::snprintf(m_text, m_text_len, + "Grep::PSCoord: All participants have started logging " + "table data changes on the subscription " + "subId=%d,SubKey=%d)." + " Return code: %d", + subId, + subKey, + err); + break; + } + case GrepEvent::GrepPS_SubSyncMetaConf: + { + const int subId = theData[2]; + const int subKey = theData[3]; + const int err = theData[4]; + ::snprintf(m_text, m_text_len, + "Grep::PSCoord: All participants have started " + " synchronization on meta data (META SCAN) using " + "(subId=%d,SubKey=%d)." + " Return code: %d", + subId, + subKey, + err); + break; + } + case GrepEvent::GrepSS_SubSyncMetaConf: + { + const int subId = theData[2]; + const int subKey = theData[3]; + const int err = theData[4]; + ::snprintf(m_text, m_text_len, + "Grep::SSCoord: Synchronization started (META SCAN) on " + " meta data using (subId=%d,SubKey=%d)" + " Return code: %d", + subId, + subKey, + err); + break; + } + case GrepEvent::GrepPS_SubSyncDataConf: + { + const int subId = theData[2]; + const int subKey = theData[3]; + const int err = theData[4]; + ::snprintf(m_text, m_text_len, + "Grep::PSCoord: All participants have started " + "synchronization " + " on table data (DATA SCAN) using (subId=%d,SubKey=%d)." + " Return code: %d", + subId, + subKey, + err); + break; + } + case GrepEvent::GrepSS_SubSyncDataConf: + { + const int subId = theData[2]; + const int subKey = theData[3]; + const int err = theData[4]; + const int gci = theData[5]; + ::snprintf(m_text, m_text_len, + "Grep::SSCoord: Synchronization started (DATA SCAN) on " + "table data using (subId=%d,SubKey=%d). GCI = %d" + " Return code: %d", + subId, + subKey, + gci, + err); + break; + } + case GrepEvent::GrepPS_SubRemoveConf: + { + const int subId = theData[2]; + const int subKey = theData[3]; + const int err = theData[4]; + ::snprintf(m_text, m_text_len, + "Grep::PSCoord: All participants have removed " + "subscription (subId=%d,SubKey=%d). I have cleaned " + "up resources I've used." + " Return code: %d", + subId, + subKey, + err); + break; + } + case GrepEvent::GrepSS_SubRemoveConf: + { + const int subId = theData[2]; + const int subKey = theData[3]; + const int err = theData[4]; + ::snprintf(m_text, m_text_len, + "Grep::SSCoord: Removed subscription " + "(subId=%d,SubKey=%d)" + " Return code: %d", + subId, + subKey, + err); + break; + } default: ::snprintf(m_text, - sizeof(m_text), + m_text_len, "%sUnknown GrepSubscriptonInfo event: %d", theNodeId, theData[1]); - } - break; - } - - case EventReport::GrepSubscriptionAlert : - { - GrepEvent::Subscription event = (GrepEvent::Subscription)theData[1]; - switch(event) - { - case GrepEvent::GrepSS_CreateSubIdRef: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - ::snprintf(m_text, sizeof(m_text), - "Grep::SSCoord:Error code: %d Error message: %s" - " (subId=%d,SubKey=%d)", - err, - GrepError::getErrorDesc((GrepError::Code)err), - subId, - subKey); - break; - } - case GrepEvent::GrepSS_SubCreateRef: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - ::snprintf(m_text, sizeof(m_text), - "Grep::SSCoord: FAILED to Created subscription using" - " (subId=%d,SubKey=%d)in primary system." - " Error code: %d Error Message: %s", - subId, - subKey, - err, - GrepError::getErrorDesc((GrepError::Code)err)); - break; - } - case GrepEvent::GrepSS_SubStartMetaRef: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - ::snprintf(m_text, sizeof(m_text), - "Grep::SSCoord: Logging failed to start on meta " - "data changes." - " using (subId=%d,SubKey=%d)" - " Error code: %d Error Message: %s", - subId, - subKey, - err, - GrepError::getErrorDesc((GrepError::Code)err)); - break; - } - case GrepEvent::GrepSS_SubStartDataRef: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - ::snprintf(m_text, sizeof(m_text), - "Grep::SSCoord: Logging FAILED to start on table data " - " changes using (subId=%d,SubKey=%d)" - " Error code: %d Error Message: %s", - subId, - subKey, - err, - GrepError::getErrorDesc((GrepError::Code)err)); - break; - } - case GrepEvent::GrepSS_SubSyncMetaRef: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - ::snprintf(m_text, sizeof(m_text), - "Grep::SSCoord: Synchronization FAILED (META SCAN) on " - " meta data using (subId=%d,SubKey=%d)" - " Error code: %d Error Message: %s", - subId, - subKey, - err, - GrepError::getErrorDesc((GrepError::Code)err)); - break; - } - case GrepEvent::GrepSS_SubSyncDataRef: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - const int gci = theData[5]; - ::snprintf(m_text, sizeof(m_text), - "Grep::SSCoord: Synchronization FAILED (DATA SCAN) on " - "table data using (subId=%d,SubKey=%d). GCI = %d" - " Error code: %d Error Message: %s", - subId, - subKey, - gci, - err, - GrepError::getErrorDesc((GrepError::Code)err)); - break; - } - case GrepEvent::GrepSS_SubRemoveRef: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - ::snprintf(m_text, sizeof(m_text), - "Grep::SSCoord: Failed to remove subscription " - "(subId=%d,SubKey=%d). " - " Error code: %d Error Message: %s", - subId, - subKey, - err, - GrepError::getErrorDesc((GrepError::Code)err) - ); - break; - } - - case GrepEvent::GrepPS_CreateSubIdRef: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - ::snprintf(m_text, sizeof(m_text), - "Grep::PSCoord: Error code: %d Error Message: %s" - " (subId=%d,SubKey=%d)", - err, - GrepError::getErrorDesc((GrepError::Code)err), - subId, - subKey); - break; - } - case GrepEvent::GrepPS_SubCreateRef: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - ::snprintf(m_text, sizeof(m_text), - "Grep::PSCoord: FAILED to Created subscription using" - " (subId=%d,SubKey=%d)in primary system." - " Error code: %d Error Message: %s", - subId, - subKey, - err, - GrepError::getErrorDesc((GrepError::Code)err)); - break; - } - case GrepEvent::GrepPS_SubStartMetaRef: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - ::snprintf(m_text, sizeof(m_text), - "Grep::PSCoord: Logging failed to start on meta " - "data changes." - " using (subId=%d,SubKey=%d)" - " Error code: %d Error Message: %s", - subId, - subKey, - err, - GrepError::getErrorDesc((GrepError::Code)err)); - break; - } - case GrepEvent::GrepPS_SubStartDataRef: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - ::snprintf(m_text, sizeof(m_text), - "Grep::PSCoord: Logging FAILED to start on table data " - " changes using (subId=%d,SubKey=%d)" - " Error code: %d Error Message: %s", - subId, - subKey, - err, - GrepError::getErrorDesc((GrepError::Code)err)); - break; - } - case GrepEvent::GrepPS_SubSyncMetaRef: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - ::snprintf(m_text, sizeof(m_text), - "Grep::PSCoord: Synchronization FAILED (META SCAN) on " - " meta data using (subId=%d,SubKey=%d)" - " Error code: %d Error Message: %s", - subId, - subKey, - err, - GrepError::getErrorDesc((GrepError::Code)err)); - break; - } - case GrepEvent::GrepPS_SubSyncDataRef: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - const int gci = theData[5]; - ::snprintf(m_text, sizeof(m_text), - "Grep::PSCoord: Synchronization FAILED (DATA SCAN) on " - "table data using (subId=%d,SubKey=%d). GCI = %d. " - " Error code: %d Error Message: %s", - subId, - subKey, - gci, - err, - GrepError::getErrorDesc((GrepError::Code)err)); - break; - } - case GrepEvent::GrepPS_SubRemoveRef: - { - const int subId = theData[2]; - const int subKey = theData[3]; - const int err = theData[4]; - ::snprintf(m_text, sizeof(m_text), - "Grep::PSCoord: Failed to remove subscription " - "(subId=%d,SubKey=%d)." - " Error code: %d Error Message: %s", - subId, - subKey, - err, - GrepError::getErrorDesc((GrepError::Code)err)); - break; - } - case GrepEvent::Rep_Disconnect: - { - const int err = theData[4]; - const int nodeId = theData[5]; - ::snprintf(m_text, sizeof(m_text), - "Rep: Node %d." - " Error code: %d Error Message: %s", - nodeId, - err, - GrepError::getErrorDesc((GrepError::Code)err)); - break; - } - - - default: - ::snprintf(m_text, - sizeof(m_text), - "%sUnknown GrepSubscriptionAlert event: %d", - theNodeId, - theData[1]); - break; - } - break; } + break; + } + case EventReport::GrepSubscriptionAlert : + { + GrepEvent::Subscription event = (GrepEvent::Subscription)theData[1]; + switch(event) + { + case GrepEvent::GrepSS_CreateSubIdRef: + { + const int subId = theData[2]; + const int subKey = theData[3]; + const int err = theData[4]; + ::snprintf(m_text, m_text_len, + "Grep::SSCoord:Error code: %d Error message: %s" + " (subId=%d,SubKey=%d)", + err, + GrepError::getErrorDesc((GrepError::Code)err), + subId, + subKey); + break; + } + case GrepEvent::GrepSS_SubCreateRef: + { + const int subId = theData[2]; + const int subKey = theData[3]; + const int err = theData[4]; + ::snprintf(m_text, m_text_len, + "Grep::SSCoord: FAILED to Created subscription using" + " (subId=%d,SubKey=%d)in primary system." + " Error code: %d Error Message: %s", + subId, + subKey, + err, + GrepError::getErrorDesc((GrepError::Code)err)); + break; + } + case GrepEvent::GrepSS_SubStartMetaRef: + { + const int subId = theData[2]; + const int subKey = theData[3]; + const int err = theData[4]; + ::snprintf(m_text, m_text_len, + "Grep::SSCoord: Logging failed to start on meta " + "data changes." + " using (subId=%d,SubKey=%d)" + " Error code: %d Error Message: %s", + subId, + subKey, + err, + GrepError::getErrorDesc((GrepError::Code)err)); + break; + } + case GrepEvent::GrepSS_SubStartDataRef: + { + const int subId = theData[2]; + const int subKey = theData[3]; + const int err = theData[4]; + ::snprintf(m_text, m_text_len, + "Grep::SSCoord: Logging FAILED to start on table data " + " changes using (subId=%d,SubKey=%d)" + " Error code: %d Error Message: %s", + subId, + subKey, + err, + GrepError::getErrorDesc((GrepError::Code)err)); + break; + } + case GrepEvent::GrepSS_SubSyncMetaRef: + { + const int subId = theData[2]; + const int subKey = theData[3]; + const int err = theData[4]; + ::snprintf(m_text, m_text_len, + "Grep::SSCoord: Synchronization FAILED (META SCAN) on " + " meta data using (subId=%d,SubKey=%d)" + " Error code: %d Error Message: %s", + subId, + subKey, + err, + GrepError::getErrorDesc((GrepError::Code)err)); + break; + } + case GrepEvent::GrepSS_SubSyncDataRef: + { + const int subId = theData[2]; + const int subKey = theData[3]; + const int err = theData[4]; + const int gci = theData[5]; + ::snprintf(m_text, m_text_len, + "Grep::SSCoord: Synchronization FAILED (DATA SCAN) on " + "table data using (subId=%d,SubKey=%d). GCI = %d" + " Error code: %d Error Message: %s", + subId, + subKey, + gci, + err, + GrepError::getErrorDesc((GrepError::Code)err)); + break; + } + case GrepEvent::GrepSS_SubRemoveRef: + { + const int subId = theData[2]; + const int subKey = theData[3]; + const int err = theData[4]; + ::snprintf(m_text, m_text_len, + "Grep::SSCoord: Failed to remove subscription " + "(subId=%d,SubKey=%d). " + " Error code: %d Error Message: %s", + subId, + subKey, + err, + GrepError::getErrorDesc((GrepError::Code)err) + ); + break; + } + + case GrepEvent::GrepPS_CreateSubIdRef: + { + const int subId = theData[2]; + const int subKey = theData[3]; + const int err = theData[4]; + ::snprintf(m_text, m_text_len, + "Grep::PSCoord: Error code: %d Error Message: %s" + " (subId=%d,SubKey=%d)", + err, + GrepError::getErrorDesc((GrepError::Code)err), + subId, + subKey); + break; + } + case GrepEvent::GrepPS_SubCreateRef: + { + const int subId = theData[2]; + const int subKey = theData[3]; + const int err = theData[4]; + ::snprintf(m_text, m_text_len, + "Grep::PSCoord: FAILED to Created subscription using" + " (subId=%d,SubKey=%d)in primary system." + " Error code: %d Error Message: %s", + subId, + subKey, + err, + GrepError::getErrorDesc((GrepError::Code)err)); + break; + } + case GrepEvent::GrepPS_SubStartMetaRef: + { + const int subId = theData[2]; + const int subKey = theData[3]; + const int err = theData[4]; + ::snprintf(m_text, m_text_len, + "Grep::PSCoord: Logging failed to start on meta " + "data changes." + " using (subId=%d,SubKey=%d)" + " Error code: %d Error Message: %s", + subId, + subKey, + err, + GrepError::getErrorDesc((GrepError::Code)err)); + break; + } + case GrepEvent::GrepPS_SubStartDataRef: + { + const int subId = theData[2]; + const int subKey = theData[3]; + const int err = theData[4]; + ::snprintf(m_text, m_text_len, + "Grep::PSCoord: Logging FAILED to start on table data " + " changes using (subId=%d,SubKey=%d)" + " Error code: %d Error Message: %s", + subId, + subKey, + err, + GrepError::getErrorDesc((GrepError::Code)err)); + break; + } + case GrepEvent::GrepPS_SubSyncMetaRef: + { + const int subId = theData[2]; + const int subKey = theData[3]; + const int err = theData[4]; + ::snprintf(m_text, m_text_len, + "Grep::PSCoord: Synchronization FAILED (META SCAN) on " + " meta data using (subId=%d,SubKey=%d)" + " Error code: %d Error Message: %s", + subId, + subKey, + err, + GrepError::getErrorDesc((GrepError::Code)err)); + break; + } + case GrepEvent::GrepPS_SubSyncDataRef: + { + const int subId = theData[2]; + const int subKey = theData[3]; + const int err = theData[4]; + const int gci = theData[5]; + ::snprintf(m_text, m_text_len, + "Grep::PSCoord: Synchronization FAILED (DATA SCAN) on " + "table data using (subId=%d,SubKey=%d). GCI = %d. " + " Error code: %d Error Message: %s", + subId, + subKey, + gci, + err, + GrepError::getErrorDesc((GrepError::Code)err)); + break; + } + case GrepEvent::GrepPS_SubRemoveRef: + { + const int subId = theData[2]; + const int subKey = theData[3]; + const int err = theData[4]; + ::snprintf(m_text, m_text_len, + "Grep::PSCoord: Failed to remove subscription " + "(subId=%d,SubKey=%d)." + " Error code: %d Error Message: %s", + subId, + subKey, + err, + GrepError::getErrorDesc((GrepError::Code)err)); + break; + } + case GrepEvent::Rep_Disconnect: + { + const int err = theData[4]; + const int nodeId = theData[5]; + ::snprintf(m_text, m_text_len, + "Rep: Node %d." + " Error code: %d Error Message: %s", + nodeId, + err, + GrepError::getErrorDesc((GrepError::Code)err)); + break; + } + + + default: + ::snprintf(m_text, + m_text_len, + "%sUnknown GrepSubscriptionAlert event: %d", + theNodeId, + theData[1]); + break; + } + break; + } + + case EventReport::BackupStarted: + ::snprintf(m_text, + m_text_len, + "%sBackup %d started from node %d", + theNodeId, theData[2], refToNode(theData[1])); + break; + case EventReport::BackupFailedToStart: + ::snprintf(m_text, + m_text_len, + "%sBackup request from %d failed to start. Error: %d", + theNodeId, refToNode(theData[1]), theData[2]); + break; + case EventReport::BackupCompleted: + ::snprintf(m_text, + m_text_len, + "%sBackup %d started from node %d completed\n" + " StartGCP: %d StopGCP: %d\n" + " #Records: %d #LogRecords: %d\n" + " Data: %d bytes Log: %d bytes", + theNodeId, theData[2], refToNode(theData[1]), + theData[3], theData[4], theData[6], theData[8], + theData[5], theData[7]); + break; + case EventReport::BackupAborted: + ::snprintf(m_text, + m_text_len, + "%sBackup %d started from %d has been aborted. Error: %d", + theNodeId, + theData[2], + refToNode(theData[1]), + theData[3]); + break; default: ::snprintf(m_text, - sizeof(m_text), + m_text_len, "%sUnknown event: %d", theNodeId, theData[0]); @@ -1302,54 +1303,10 @@ EventLogger::getText(int type, return m_text; } -bool -EventLogger::matchEventCategory(const char * str, - LogLevel::EventCategory * cat, - bool exactMatch){ - unsigned i; - if(cat == 0 || str == 0) - return false; - - char * tmp = strdup(str); - for(i = 0; igetLogLevel(cat) : m_logLevel.getLogLevel(cat); + if (threshold <= set){ switch (severity){ - case LL_ALERT: - alert(EventLogger::getText(eventType, theData, nodeId)); + case Logger::LL_ALERT: + alert(EventLogger::getText(m_text, sizeof(m_text), + eventType, theData, nodeId)); break; - case LL_CRITICAL: - critical(EventLogger::getText(eventType, theData, nodeId)); + case Logger::LL_CRITICAL: + critical(EventLogger::getText(m_text, sizeof(m_text), + eventType, theData, nodeId)); break; - case LL_WARNING: - warning(EventLogger::getText(eventType, theData, nodeId)); + case Logger::LL_WARNING: + warning(EventLogger::getText(m_text, sizeof(m_text), + eventType, theData, nodeId)); break; - case LL_ERROR: - error(EventLogger::getText(eventType, theData, nodeId)); + case Logger::LL_ERROR: + error(EventLogger::getText(m_text, sizeof(m_text), + eventType, theData, nodeId)); break; - case LL_INFO: - info(EventLogger::getText(eventType, theData, nodeId)); + case Logger::LL_INFO: + info(EventLogger::getText(m_text, sizeof(m_text), + eventType, theData, nodeId)); break; - case LL_DEBUG: - debug(EventLogger::getText(eventType, theData, nodeId)); + case Logger::LL_DEBUG: + debug(EventLogger::getText(m_text, sizeof(m_text), + eventType, theData, nodeId)); break; default: - info(EventLogger::getText(eventType, theData, nodeId)); + info(EventLogger::getText(m_text, sizeof(m_text), + eventType, theData, nodeId)); break; } } // if (.. } -LogLevel& -EventLogger::getLoglevel() -{ - return m_logLevel; -} - int EventLogger::getFilterLevel() const { diff --git a/ndb/src/common/debugger/Makefile.am b/ndb/src/common/debugger/Makefile.am index 0278d0d2ba0..d0fb30717cd 100644 --- a/ndb/src/common/debugger/Makefile.am +++ b/ndb/src/common/debugger/Makefile.am @@ -2,7 +2,7 @@ SUBDIRS = signaldata noinst_LTLIBRARIES = libtrace.la -libtrace_la_SOURCES = SignalLoggerManager.cpp DebuggerNames.cpp BlockNames.cpp LogLevel.cpp EventLogger.cpp GrepError.cpp +libtrace_la_SOURCES = SignalLoggerManager.cpp DebuggerNames.cpp BlockNames.cpp EventLogger.cpp GrepError.cpp include $(top_srcdir)/ndb/config/common.mk.am include $(top_srcdir)/ndb/config/type_kernel.mk.am diff --git a/ndb/src/common/mgmcommon/ConfigRetriever.cpp b/ndb/src/common/mgmcommon/ConfigRetriever.cpp index 109c999852b..b4f2d0b9897 100644 --- a/ndb/src/common/mgmcommon/ConfigRetriever.cpp +++ b/ndb/src/common/mgmcommon/ConfigRetriever.cpp @@ -18,6 +18,7 @@ #include #include +#include #include "LocalConfig.hpp" #include @@ -44,11 +45,14 @@ //**************************************************************************** //**************************************************************************** -ConfigRetriever::ConfigRetriever(Uint32 version, Uint32 node_type) { - +ConfigRetriever::ConfigRetriever(LocalConfig &local_config, + Uint32 version, Uint32 node_type) + : _localConfig(local_config) +{ m_handle= 0; m_version = version; m_node_type = node_type; + _ownNodeId = _localConfig._ownNodeId; } ConfigRetriever::~ConfigRetriever(){ @@ -63,23 +67,12 @@ ConfigRetriever::~ConfigRetriever(){ //**************************************************************************** //**************************************************************************** -int -ConfigRetriever::init() { - if (!_localConfig.init(m_connectString.c_str(), - _localConfigFileName.c_str())){ - - setError(CR_ERROR, "error in retrieving contact info for mgmtsrvr"); - _localConfig.printError(); - _localConfig.printUsage(); - return -1; - } - - return _ownNodeId = _localConfig._ownNodeId; -} - int ConfigRetriever::do_connect(int exit_on_connect_failure){ + m_mgmd_port= 0; + m_mgmd_host= 0; + if(!m_handle) m_handle= ndb_mgm_create_handle(); @@ -96,10 +89,18 @@ ConfigRetriever::do_connect(int exit_on_connect_failure){ BaseString tmp; for (unsigned int i = 0; i<_localConfig.ids.size(); i++){ MgmtSrvrId * m = &_localConfig.ids[i]; + DBUG_PRINT("info",("trying %s:%d", + m->name.c_str(), + m->port)); switch(m->type){ case MgmId_TCP: tmp.assfmt("%s:%d", m->name.c_str(), m->port); if (ndb_mgm_connect(m_handle, tmp.c_str()) == 0) { + m_mgmd_port= m->port; + m_mgmd_host= m->name.c_str(); + DBUG_PRINT("info",("connected to ndb_mgmd at %s:%d", + m_mgmd_host, + m_mgmd_port)); return 0; } setError(CR_RETRY, ndb_mgm_get_latest_error_desc(m_handle)); @@ -107,9 +108,10 @@ ConfigRetriever::do_connect(int exit_on_connect_failure){ break; } } - if (exit_on_connect_failure) - return 1; if(latestErrorType == CR_RETRY){ + DBUG_PRINT("info",("CR_RETRY")); + if (exit_on_connect_failure) + return 1; REPORT_WARNING("Failed to retrieve cluster configuration"); ndbout << "(Cause of failure: " << getErrorString() << ")" << endl; ndbout << "Attempt " << retry << " of " << retry_max << ". " @@ -124,6 +126,8 @@ ConfigRetriever::do_connect(int exit_on_connect_failure){ ndb_mgm_destroy_handle(&m_handle); m_handle= 0; + m_mgmd_port= 0; + m_mgmd_host= 0; return -1; } @@ -229,16 +233,6 @@ ConfigRetriever::getErrorString(){ return errorString.c_str(); } -void -ConfigRetriever::setLocalConfigFileName(const char * localConfigFileName) { - _localConfigFileName.assign(localConfigFileName ? localConfigFileName : ""); -} - -void -ConfigRetriever::setConnectString(const char * connectString) { - m_connectString.assign(connectString ? connectString : ""); -} - bool ConfigRetriever::verifyConfig(const struct ndb_mgm_configuration * conf, Uint32 nodeid){ @@ -272,43 +266,15 @@ ConfigRetriever::verifyConfig(const struct ndb_mgm_configuration * conf, Uint32 NdbConfig_SetPath(datadir); } - char localhost[MAXHOSTNAMELEN]; - if(NdbHost_GetHostName(localhost) != 0){ - snprintf(buf, 255, "Unable to get own hostname"); + if (hostname && hostname[0] != 0 && + !SocketServer::tryBind(0,hostname)) { + snprintf(buf, 255, "Config hostname(%s) don't match a local interface," + " tried to bind, error = %d - %s", + hostname, errno, strerror(errno)); setError(CR_ERROR, buf); return false; } - do { - if(strlen(hostname) == 0) - break; - - if(strcasecmp(hostname, localhost) == 0) - break; - - if(strcasecmp(hostname, "localhost") == 0) - break; - - struct in_addr local, config; - bool b1 = false, b2 = false, b3 = false; - b1 = Ndb_getInAddr(&local, localhost) == 0; - b2 = Ndb_getInAddr(&config, hostname) == 0; - b3 = memcmp(&local, &config, sizeof(local)) == 0; - - if(b1 && b2 && b3) - break; - - b1 = Ndb_getInAddr(&local, "localhost") == 0; - b3 = memcmp(&local, &config, sizeof(local)) == 0; - if(b1 && b2 && b3) - break; - - snprintf(buf, 255, "Local hostname(%s) and config hostname(%s) dont match", - localhost, hostname); - setError(CR_ERROR, buf); - return false; - } while(false); - unsigned int _type; if(ndb_mgm_get_int_parameter(it, CFG_TYPE_OF_SECTION, &_type)){ snprintf(buf, 255, "Unable to get type of node(%d) from config", @@ -344,7 +310,7 @@ ConfigRetriever::verifyConfig(const struct ndb_mgm_configuration * conf, Uint32 const char * name; struct in_addr addr; BaseString tmp; - if(!iter.get(CFG_TCP_HOSTNAME_1, &name) && strlen(name)){ + if(!iter.get(CFG_CONNECTION_HOSTNAME_1, &name) && strlen(name)){ if(Ndb_getInAddr(&addr, name) != 0){ tmp.assfmt("Unable to lookup/illegal hostname %s, " "connection from node %d to node %d", @@ -354,7 +320,7 @@ ConfigRetriever::verifyConfig(const struct ndb_mgm_configuration * conf, Uint32 } } - if(!iter.get(CFG_TCP_HOSTNAME_2, &name) && strlen(name)){ + if(!iter.get(CFG_CONNECTION_HOSTNAME_2, &name) && strlen(name)){ if(Ndb_getInAddr(&addr, name) != 0){ tmp.assfmt("Unable to lookup/illegal hostname %s, " "connection from node %d to node %d", diff --git a/ndb/src/common/mgmcommon/IPCConfig.cpp b/ndb/src/common/mgmcommon/IPCConfig.cpp index a76c541f3f6..780504d2c62 100644 --- a/ndb/src/common/mgmcommon/IPCConfig.cpp +++ b/ndb/src/common/mgmcommon/IPCConfig.cpp @@ -133,7 +133,6 @@ IPCConfig::configureTransporters(TransporterRegistry * theTransporterRegistry){ Uint32 compression; Uint32 checksum; if(!tmp->get("SendSignalId", &sendSignalId)) continue; - if(!tmp->get("Compression", &compression)) continue; if(!tmp->get("Checksum", &checksum)) continue; const char * type; @@ -143,8 +142,6 @@ IPCConfig::configureTransporters(TransporterRegistry * theTransporterRegistry){ SHM_TransporterConfiguration conf; conf.localNodeId = the_ownId; conf.remoteNodeId = (nodeId1 != the_ownId ? nodeId1 : nodeId2); - conf.byteOrder = 0; - conf.compression = compression; conf.checksum = checksum; conf.signalId = sendSignalId; @@ -164,8 +161,6 @@ IPCConfig::configureTransporters(TransporterRegistry * theTransporterRegistry){ SCI_TransporterConfiguration conf; conf.localNodeId = the_ownId; conf.remoteNodeId = (nodeId1 != the_ownId ? nodeId1 : nodeId2); - conf.byteOrder = 0; - conf.compression = compression; conf.checksum = checksum; conf.signalId = sendSignalId; @@ -174,18 +169,16 @@ IPCConfig::configureTransporters(TransporterRegistry * theTransporterRegistry){ if(the_ownId == nodeId1){ if(!tmp->get("Node1_NoOfAdapters", &conf.nLocalAdapters)) continue; - if(!tmp->get("Node2_NoOfAdapters", &conf.nRemoteAdapters)) continue; if(!tmp->get("Node2_Adapter", 0, &conf.remoteSciNodeId0)) continue; - if(conf.nRemoteAdapters > 1){ + if(conf.nLocalAdapters > 1){ if(!tmp->get("Node2_Adapter", 1, &conf.remoteSciNodeId1)) continue; } } else { if(!tmp->get("Node2_NoOfAdapters", &conf.nLocalAdapters)) continue; - if(!tmp->get("Node1_NoOfAdapters", &conf.nRemoteAdapters)) continue; if(!tmp->get("Node1_Adapter", 0, &conf.remoteSciNodeId0)) continue; - if(conf.nRemoteAdapters > 1){ + if(conf.nLocalAdapters > 1){ if(!tmp->get("Node1_Adapter", 1, &conf.remoteSciNodeId1)) continue; } } @@ -243,8 +236,6 @@ IPCConfig::configureTransporters(TransporterRegistry * theTransporterRegistry){ conf.localHostName = ownHostName; conf.remoteNodeId = remoteNodeId; conf.localNodeId = ownNodeId; - conf.byteOrder = 0; - conf.compression = compression; conf.checksum = checksum; conf.signalId = sendSignalId; @@ -270,8 +261,6 @@ IPCConfig::configureTransporters(TransporterRegistry * theTransporterRegistry){ conf.localHostName = ownHostName; conf.remoteNodeId = remoteNodeId; conf.localNodeId = ownNodeId; - conf.byteOrder = 0; - conf.compression = compression; conf.checksum = checksum; conf.signalId = sendSignalId; @@ -344,19 +333,29 @@ Uint32 IPCConfig::configureTransporters(Uint32 nodeId, const class ndb_mgm_configuration & config, class TransporterRegistry & tr){ + DBUG_ENTER("IPCConfig::configureTransporters"); - Uint32 noOfTransportersCreated= 0, server_port= 0; + Uint32 noOfTransportersCreated= 0; ndb_mgm_configuration_iterator iter(config, CFG_SECTION_CONNECTION); for(iter.first(); iter.valid(); iter.next()){ Uint32 nodeId1, nodeId2, remoteNodeId; + const char * remoteHostName= 0, * localHostName= 0; if(iter.get(CFG_CONNECTION_NODE_1, &nodeId1)) continue; if(iter.get(CFG_CONNECTION_NODE_2, &nodeId2)) continue; if(nodeId1 != nodeId && nodeId2 != nodeId) continue; remoteNodeId = (nodeId == nodeId1 ? nodeId2 : nodeId1); + { + const char * host1= 0, * host2= 0; + iter.get(CFG_CONNECTION_HOSTNAME_1, &host1); + iter.get(CFG_CONNECTION_HOSTNAME_2, &host2); + localHostName = (nodeId == nodeId1 ? host1 : host2); + remoteHostName = (nodeId == nodeId1 ? host2 : host1); + } + Uint32 sendSignalId = 1; Uint32 checksum = 1; if(iter.get(CFG_CONNECTION_SEND_SIGNAL_ID, &sendSignalId)) continue; @@ -365,71 +364,77 @@ IPCConfig::configureTransporters(Uint32 nodeId, Uint32 type = ~0; if(iter.get(CFG_TYPE_OF_SECTION, &type)) continue; - Uint32 tmp_server_port= 0; - if(iter.get(CFG_CONNECTION_SERVER_PORT, &tmp_server_port)) break; + Uint32 server_port= 0; + if(iter.get(CFG_CONNECTION_SERVER_PORT, &server_port)) break; if (nodeId <= nodeId1 && nodeId <= nodeId2) { - if (server_port && server_port != tmp_server_port) { - ndbout << "internal error in config setup of server ports line= " << __LINE__ << endl; - exit(-1); - } - server_port= tmp_server_port; + tr.add_transporter_interface(localHostName, server_port); } - + DBUG_PRINT("info", ("Transporter between this node %d and node %d using port %d, signalId %d, checksum %d", + nodeId, remoteNodeId, server_port, sendSignalId, checksum)); switch(type){ case CONNECTION_TYPE_SHM:{ SHM_TransporterConfiguration conf; conf.localNodeId = nodeId; conf.remoteNodeId = remoteNodeId; - conf.byteOrder = 0; - conf.compression = 0; conf.checksum = checksum; conf.signalId = sendSignalId; if(iter.get(CFG_SHM_KEY, &conf.shmKey)) break; if(iter.get(CFG_SHM_BUFFER_MEM, &conf.shmSize)) break; - conf.port= tmp_server_port; + conf.port= server_port; if(!tr.createTransporter(&conf)){ + DBUG_PRINT("error", ("Failed to create SHM Transporter from %d to %d", + conf.localNodeId, conf.remoteNodeId)); ndbout << "Failed to create SHM Transporter from: " << conf.localNodeId << " to: " << conf.remoteNodeId << endl; } else { noOfTransportersCreated++; } + DBUG_PRINT("info", ("Created SHM Transporter using shmkey %d, buf size = %d", + conf.shmKey, conf.shmSize)); break; } case CONNECTION_TYPE_SCI:{ SCI_TransporterConfiguration conf; conf.localNodeId = nodeId; conf.remoteNodeId = remoteNodeId; - conf.byteOrder = 0; - conf.compression = 0; conf.checksum = checksum; conf.signalId = sendSignalId; + conf.port= server_port; + conf.localHostName = localHostName; + conf.remoteHostName = remoteHostName; + if(iter.get(CFG_SCI_SEND_LIMIT, &conf.sendLimit)) break; if(iter.get(CFG_SCI_BUFFER_MEM, &conf.bufferSize)) break; - - if(nodeId == nodeId1){ - if(iter.get(CFG_SCI_NODE1_ADAPTERS, &conf.nLocalAdapters)) break; - if(iter.get(CFG_SCI_NODE2_ADAPTERS, &conf.nRemoteAdapters)) break; - if(iter.get(CFG_SCI_NODE2_ADAPTER0, &conf.remoteSciNodeId0)) break; - if(conf.nRemoteAdapters > 1){ - if(iter.get(CFG_SCI_NODE2_ADAPTER1, &conf.remoteSciNodeId1)) break; - } + if (nodeId == nodeId1) { + if(iter.get(CFG_SCI_HOST2_ID_0, &conf.remoteSciNodeId0)) break; + if(iter.get(CFG_SCI_HOST2_ID_1, &conf.remoteSciNodeId1)) break; } else { - if(iter.get(CFG_SCI_NODE2_ADAPTERS, &conf.nLocalAdapters)) break; - if(iter.get(CFG_SCI_NODE1_ADAPTERS, &conf.nRemoteAdapters)) break; - if(iter.get(CFG_SCI_NODE1_ADAPTER0, &conf.remoteSciNodeId0)) break; - if(conf.nRemoteAdapters > 1){ - if(iter.get(CFG_SCI_NODE1_ADAPTER1, &conf.remoteSciNodeId1)) break; - } + if(iter.get(CFG_SCI_HOST1_ID_0, &conf.remoteSciNodeId0)) break; + if(iter.get(CFG_SCI_HOST1_ID_1, &conf.remoteSciNodeId1)) break; } - - if(!tr.createTransporter(&conf)){ + if (conf.remoteSciNodeId1 == 0) { + conf.nLocalAdapters = 1; + } else { + conf.nLocalAdapters = 2; + } + if(!tr.createTransporter(&conf)){ + DBUG_PRINT("error", ("Failed to create SCI Transporter from %d to %d", + conf.localNodeId, conf.remoteNodeId)); ndbout << "Failed to create SCI Transporter from: " << conf.localNodeId << " to: " << conf.remoteNodeId << endl; } else { + DBUG_PRINT("info", ("Created SCI Transporter: Adapters = %d, remote SCI node id %d", + conf.nLocalAdapters, conf.remoteSciNodeId0)); + DBUG_PRINT("info", ("Host 1 = %s, Host 2 = %s, sendLimit = %d, buf size = %d", + conf.localHostName, conf.remoteHostName, conf.sendLimit, conf.bufferSize)); + if (conf.nLocalAdapters > 1) { + DBUG_PRINT("info", ("Fault-tolerant with 2 Remote Adapters, second remote SCI node id = %d", + conf.remoteSciNodeId1)); + } noOfTransportersCreated++; continue; } @@ -437,14 +442,10 @@ IPCConfig::configureTransporters(Uint32 nodeId, case CONNECTION_TYPE_TCP:{ TCP_TransporterConfiguration conf; - const char * host1, * host2; - if(iter.get(CFG_TCP_HOSTNAME_1, &host1)) break; - if(iter.get(CFG_TCP_HOSTNAME_2, &host2)) break; - if(iter.get(CFG_TCP_SEND_BUFFER_SIZE, &conf.sendBufferSize)) break; if(iter.get(CFG_TCP_RECEIVE_BUFFER_SIZE, &conf.maxReceiveSize)) break; - conf.port= tmp_server_port; + conf.port= server_port; const char * proxy; if (!iter.get(CFG_TCP_PROXY, &proxy)) { if (strlen(proxy) > 0 && nodeId2 == nodeId) { @@ -455,10 +456,8 @@ IPCConfig::configureTransporters(Uint32 nodeId, conf.localNodeId = nodeId; conf.remoteNodeId = remoteNodeId; - conf.localHostName = (nodeId == nodeId1 ? host1 : host2); - conf.remoteHostName = (nodeId == nodeId1 ? host2 : host1); - conf.byteOrder = 0; - conf.compression = 0; + conf.localHostName = localHostName; + conf.remoteHostName = remoteHostName; conf.checksum = checksum; conf.signalId = sendSignalId; @@ -468,23 +467,20 @@ IPCConfig::configureTransporters(Uint32 nodeId, } else { noOfTransportersCreated++; } + DBUG_PRINT("info", ("Created TCP Transporter: sendBufferSize = %d, maxReceiveSize = %d", + conf.sendBufferSize, conf.maxReceiveSize)); + break; case CONNECTION_TYPE_OSE:{ OSE_TransporterConfiguration conf; - - const char * host1, * host2; - if(iter.get(CFG_OSE_HOSTNAME_1, &host1)) break; - if(iter.get(CFG_OSE_HOSTNAME_2, &host2)) break; - + if(iter.get(CFG_OSE_PRIO_A_SIZE, &conf.prioASignalSize)) break; if(iter.get(CFG_OSE_PRIO_B_SIZE, &conf.prioBSignalSize)) break; if(iter.get(CFG_OSE_RECEIVE_ARRAY_SIZE, &conf.receiveBufferSize)) break; conf.localNodeId = nodeId; conf.remoteNodeId = remoteNodeId; - conf.localHostName = (nodeId == nodeId1 ? host1 : host2); - conf.remoteHostName = (nodeId == nodeId1 ? host2 : host1); - conf.byteOrder = 0; - conf.compression = 0; + conf.localHostName = localHostName; + conf.remoteHostName = remoteHostName; conf.checksum = checksum; conf.signalId = sendSignalId; @@ -502,9 +498,6 @@ IPCConfig::configureTransporters(Uint32 nodeId, } } } - - tr.m_service_port= server_port; - - return noOfTransportersCreated; + DBUG_RETURN(noOfTransportersCreated); } diff --git a/ndb/src/common/portlib/NdbTCP.cpp b/ndb/src/common/portlib/NdbTCP.cpp index 8448d64222f..a711a586203 100644 --- a/ndb/src/common/portlib/NdbTCP.cpp +++ b/ndb/src/common/portlib/NdbTCP.cpp @@ -15,6 +15,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include #include #include @@ -27,13 +28,14 @@ static NdbMutex LOCK_gethostbyname = NDB_MUTEX_INITIALIZER; extern "C" int Ndb_getInAddr(struct in_addr * dst, const char *address) { + DBUG_ENTER("Ndb_getInAddr"); struct hostent * hostPtr; NdbMutex_Lock(&LOCK_gethostbyname); hostPtr = gethostbyname(address); if (hostPtr != NULL) { dst->s_addr = ((struct in_addr *) *hostPtr->h_addr_list)->s_addr; NdbMutex_Unlock(&LOCK_gethostbyname); - return 0; + DBUG_RETURN(0); } NdbMutex_Unlock(&LOCK_gethostbyname); @@ -47,9 +49,11 @@ Ndb_getInAddr(struct in_addr * dst, const char *address) { #endif ) { - return 0; + DBUG_RETURN(0); } - return -1; + DBUG_PRINT("error",("inet_addr(%s) - %d - %s", + address, errno, strerror(errno))); + DBUG_RETURN(-1); } #if 0 diff --git a/ndb/src/common/transporter/Makefile.am b/ndb/src/common/transporter/Makefile.am index 218b261606d..9d91a210d46 100644 --- a/ndb/src/common/transporter/Makefile.am +++ b/ndb/src/common/transporter/Makefile.am @@ -13,7 +13,7 @@ EXTRA_libtransporter_la_SOURCES = SHM_Transporter.cpp SHM_Transporter.unix.cpp S libtransporter_la_LIBADD = @ndb_transporter_opt_objs@ libtransporter_la_DEPENDENCIES = @ndb_transporter_opt_objs@ -INCLUDES_LOC = -I$(top_srcdir)/ndb/include/kernel -I$(top_srcdir)/ndb/include/transporter +INCLUDES_LOC = -I$(top_srcdir)/ndb/include/kernel -I$(top_srcdir)/ndb/include/transporter @NDB_SCI_INCLUDES@ include $(top_srcdir)/ndb/config/common.mk.am include $(top_srcdir)/ndb/config/type_util.mk.am diff --git a/ndb/src/common/transporter/Packer.cpp b/ndb/src/common/transporter/Packer.cpp index 645517a4b1a..9eba335330d 100644 --- a/ndb/src/common/transporter/Packer.cpp +++ b/ndb/src/common/transporter/Packer.cpp @@ -21,6 +21,7 @@ #include #include +#define MAX_RECEIVED_SIGNALS 1024 Uint32 TransporterRegistry::unpack(Uint32 * readPtr, Uint32 sizeOfData, @@ -30,12 +31,15 @@ TransporterRegistry::unpack(Uint32 * readPtr, LinearSectionPtr ptr[3]; Uint32 usedData = 0; - + Uint32 loop_count = 0; + if(state == NoHalt || state == HaltOutput){ - while(sizeOfData >= 4 + sizeof(Protocol6)){ + while ((sizeOfData >= 4 + sizeof(Protocol6)) && + (loop_count < MAX_RECEIVED_SIGNALS)) { Uint32 word1 = readPtr[0]; Uint32 word2 = readPtr[1]; Uint32 word3 = readPtr[2]; + loop_count++; #if 0 if(Protocol6::getByteOrder(word1) != MY_OWN_BYTE_ORDER){ @@ -112,10 +116,12 @@ TransporterRegistry::unpack(Uint32 * readPtr, } else { /** state = HaltIO || state == HaltInput */ - while(sizeOfData >= 4 + sizeof(Protocol6)){ + while ((sizeOfData >= 4 + sizeof(Protocol6)) && + (loop_count < MAX_RECEIVED_SIGNALS)) { Uint32 word1 = readPtr[0]; Uint32 word2 = readPtr[1]; Uint32 word3 = readPtr[2]; + loop_count++; #if 0 if(Protocol6::getByteOrder(word1) != MY_OWN_BYTE_ORDER){ @@ -208,12 +214,13 @@ TransporterRegistry::unpack(Uint32 * readPtr, IOState state) { static SignalHeader signalHeader; static LinearSectionPtr ptr[3]; + Uint32 loop_count = 0; if(state == NoHalt || state == HaltOutput){ - while(readPtr < eodPtr){ + while ((readPtr < eodPtr) && (loop_count < MAX_RECEIVED_SIGNALS)) { Uint32 word1 = readPtr[0]; Uint32 word2 = readPtr[1]; Uint32 word3 = readPtr[2]; - + loop_count++; #if 0 if(Protocol6::getByteOrder(word1) != MY_OWN_BYTE_ORDER){ //Do funky stuff @@ -280,11 +287,11 @@ TransporterRegistry::unpack(Uint32 * readPtr, } else { /** state = HaltIO || state == HaltInput */ - while(readPtr < eodPtr){ + while ((readPtr < eodPtr) && (loop_count < MAX_RECEIVED_SIGNALS)) { Uint32 word1 = readPtr[0]; Uint32 word2 = readPtr[1]; Uint32 word3 = readPtr[2]; - + loop_count++; #if 0 if(Protocol6::getByteOrder(word1) != MY_OWN_BYTE_ORDER){ //Do funky stuff diff --git a/ndb/src/common/transporter/SCI_Transporter.cpp b/ndb/src/common/transporter/SCI_Transporter.cpp index c52c8a9d8c0..73fbb064599 100644 --- a/ndb/src/common/transporter/SCI_Transporter.cpp +++ b/ndb/src/common/transporter/SCI_Transporter.cpp @@ -24,23 +24,30 @@ #include "TransporterInternalDefinitions.hpp" #include - + +#include +#include + #define FLAGS 0 - -SCI_Transporter::SCI_Transporter(Uint32 packetSize, +#define DEBUG_TRANSPORTER +SCI_Transporter::SCI_Transporter(TransporterRegistry &t_reg, + const char *lHostName, + const char *rHostName, + int r_port, + Uint32 packetSize, Uint32 bufferSize, Uint32 nAdapters, Uint16 remoteSciNodeId0, Uint16 remoteSciNodeId1, NodeId _localNodeId, NodeId _remoteNodeId, - int byte_order, - bool compr, bool chksm, bool signalId, Uint32 reportFreq) : - Transporter(_localNodeId, _remoteNodeId, byte_order, compr, chksm, signalId) -{ + Transporter(t_reg, lHostName, rHostName, r_port, _localNodeId, + _remoteNodeId, 0, false, chksm, signalId) +{ + DBUG_ENTER("SCI_Transporter::SCI_Transporter"); m_PacketSize = (packetSize + 3)/4 ; m_BufferSize = bufferSize; m_sendBuffer.m_buffer = NULL; @@ -56,10 +63,6 @@ SCI_Transporter::SCI_Transporter(Uint32 packetSize, m_initLocal=false; - m_remoteNodes= new Uint16[m_numberOfRemoteNodes]; - if(m_remoteNodes == NULL) { - //DO WHAT?? - } m_swapCounter=0; m_failCounter=0; m_remoteNodes[0]=remoteSciNodeId0; @@ -94,20 +97,19 @@ SCI_Transporter::SCI_Transporter(Uint32 packetSize, i4096=0; i4097=0; #endif - + DBUG_VOID_RETURN; } void SCI_Transporter::disconnectImpl() { + DBUG_ENTER("SCI_Transporter::disconnectImpl"); sci_error_t err; if(m_mapped){ setDisconnect(); -#ifdef DEBUG_TRANSPORTER - ndbout << "DisconnectImpl " << getConnectionStatus() << endl; - ndbout << "remote node " << remoteNodeId << endl; -#endif + DBUG_PRINT("info", ("connect status = %d, remote node = %d", + (int)getConnectionStatus(), remoteNodeId)); disconnectRemote(); disconnectLocal(); } @@ -124,65 +126,56 @@ void SCI_Transporter::disconnectImpl() SCIClose(sciAdapters[i].scidesc, FLAGS, &err); if(err != SCI_ERR_OK) { - reportError(callbackObj, localNodeId, TE_SCI_UNABLE_TO_CLOSE_CHANNEL); -#ifdef DEBUG_TRANSPORTER - fprintf(stderr, - "\nCannot close channel to the driver. Error code 0x%x", - err); -#endif - } + report_error(TE_SCI_UNABLE_TO_CLOSE_CHANNEL); + DBUG_PRINT("error", ("Cannot close channel to the driver. Error code 0x%x", + err)); + } } } m_sciinit=false; #ifdef DEBUG_TRANSPORTER - ndbout << "total: " << i1024+ i10242048 + i2048+i2049 << endl; + ndbout << "total: " << i1024+ i10242048 + i2048+i2049 << endl; ndbout << "<1024: " << i1024 << endl; ndbout << "1024-2047: " << i10242048 << endl; ndbout << "==2048: " << i2048 << endl; ndbout << "2049-4096: " << i20484096 << endl; ndbout << "==4096: " << i4096 << endl; ndbout << ">4096: " << i4097 << endl; - #endif - + DBUG_VOID_RETURN; } bool SCI_Transporter::initTransporter() { - if(m_BufferSize < (2*MAX_MESSAGE_SIZE)){ - m_BufferSize = 2 * MAX_MESSAGE_SIZE; + DBUG_ENTER("SCI_Transporter::initTransporter"); + if(m_BufferSize < (2*MAX_MESSAGE_SIZE + 4096)){ + m_BufferSize = 2 * MAX_MESSAGE_SIZE + 4096; } - // Allocate buffers for sending - Uint32 sz = 0; - if(m_BufferSize < (m_PacketSize * 4)){ - sz = m_BufferSize + MAX_MESSAGE_SIZE; - } else { - /** - * 3 packages - */ - sz = (m_PacketSize * 4) * 3 + MAX_MESSAGE_SIZE; - } + // Allocate buffers for sending, send buffer size plus 2048 bytes for avoiding + // the need to send twice when a large message comes around. Send buffer size is + // measured in words. + Uint32 sz = 4 * m_PacketSize + MAX_MESSAGE_SIZE;; - m_sendBuffer.m_bufferSize = 4 * ((sz + 3) / 4); - m_sendBuffer.m_buffer = new Uint32[m_sendBuffer.m_bufferSize / 4]; + m_sendBuffer.m_sendBufferSize = 4 * ((sz + 3) / 4); + m_sendBuffer.m_buffer = new Uint32[m_sendBuffer.m_sendBufferSize / 4]; m_sendBuffer.m_dataSize = 0; - + + DBUG_PRINT("info", ("Created SCI Send Buffer with buffer size %d and packet size %d", + m_sendBuffer.m_sendBufferSize, m_PacketSize * 4)); if(!getLinkStatus(m_ActiveAdapterId) || - !getLinkStatus(m_StandbyAdapterId)) { -#ifdef DEBUG_TRANSPORTER - ndbout << "The link is not fully operational. " << endl; - ndbout << "Check the cables and the switches" << endl; -#endif + (m_adapters > 1 && + !getLinkStatus(m_StandbyAdapterId))) { + DBUG_PRINT("error", ("The link is not fully operational. Check the cables and the switches")); //reportDisconnect(remoteNodeId, 0); //doDisconnect(); //NDB should terminate - reportError(callbackObj, localNodeId, TE_SCI_LINK_ERROR); - return false; + report_error(TE_SCI_LINK_ERROR); + DBUG_RETURN(false); } - return true; + DBUG_RETURN(true); } // initTransporter() @@ -218,10 +211,8 @@ bool SCI_Transporter::getLinkStatus(Uint32 adapterNo) SCIQuery(SCI_Q_ADAPTER,(void*)(&queryAdapter),(Uint32)NULL,&error); if(error != SCI_ERR_OK) { -#ifdef DEBUG_TRANSPORTER - ndbout << "error querying adapter " << endl; -#endif - return false; + DBUG_PRINT("error", ("error %d querying adapter", error)); + return false; } if(linkstatus<=0) return false; @@ -231,6 +222,7 @@ bool SCI_Transporter::getLinkStatus(Uint32 adapterNo) sci_error_t SCI_Transporter::initLocalSegment() { + DBUG_ENTER("SCI_Transporter::initLocalSegment"); Uint32 segmentSize = m_BufferSize; Uint32 offset = 0; sci_error_t err; @@ -238,16 +230,12 @@ sci_error_t SCI_Transporter::initLocalSegment() { for(Uint32 i=0; i 0){ #ifdef DEBUG_TRANSPORTER @@ -363,15 +342,19 @@ bool SCI_Transporter::doSend() { i4097++; #endif if(startSequence(m_ActiveAdapterId)!=SCI_ERR_OK) { -#ifdef DEBUG_TRANSPORTER - ndbout << "Start sequence failed" << endl; -#endif - reportError(callbackObj, remoteNodeId, TE_SCI_UNABLE_TO_START_SEQUENCE); + DBUG_PRINT("error", ("Start sequence failed")); + report_error(TE_SCI_UNABLE_TO_START_SEQUENCE); return false; } - tryagain: + tryagain: + retry++; + if (retry > 3) { + DBUG_PRINT("error", ("SCI Transfer failed")); + report_error(TE_SCI_UNRECOVERABLE_DATA_TFX_ERROR); + return false; + } Uint32 * insertPtr = (Uint32 *) (m_TargetSegm[m_ActiveAdapterId].writer)->getWritePtr(sizeToSend); @@ -390,44 +373,37 @@ bool SCI_Transporter::doSend() { &err); + if (err != SCI_ERR_OK) { if(err == SCI_ERR_OUT_OF_RANGE) { -#ifdef DEBUG_TRANSPORTER - ndbout << "Data transfer : out of range error \n" << endl; -#endif + DBUG_PRINT("error", ("Data transfer : out of range error")); goto tryagain; } if(err == SCI_ERR_SIZE_ALIGNMENT) { -#ifdef DEBUG_TRANSPORTER - ndbout << "Data transfer : aligne\n" << endl; -#endif + DBUG_PRINT("error", ("Data transfer : alignment error")); + DBUG_PRINT("info", ("sendPtr 0x%x, sizeToSend = %d", sendPtr, sizeToSend)); goto tryagain; } if(err == SCI_ERR_OFFSET_ALIGNMENT) { -#ifdef DEBUG_TRANSPORTER - ndbout << "Data transfer : offset alignment\n" << endl; -#endif + DBUG_PRINT("error", ("Data transfer : offset alignment")); goto tryagain; - } + } if(err == SCI_ERR_TRANSFER_FAILED) { //(m_TargetSegm[m_StandbyAdapterId].writer)->heavyLock(); if(getLinkStatus(m_ActiveAdapterId)) { - retry++; - if(retry>3) { - reportError(callbackObj, - remoteNodeId, TE_SCI_UNRECOVERABLE_DATA_TFX_ERROR); - return false; - } goto tryagain; } + if (m_adapters == 1) { + DBUG_PRINT("error", ("SCI Transfer failed")); + report_error(TE_SCI_UNRECOVERABLE_DATA_TFX_ERROR); + return false; + } m_failCounter++; Uint32 temp=m_ActiveAdapterId; switch(m_swapCounter) { case 0: /**swap from active (0) to standby (1)*/ if(getLinkStatus(m_StandbyAdapterId)) { -#ifdef DEBUG_TRANSPORTER - ndbout << "Swapping from 0 to 1 " << endl; -#endif + DBUG_PRINT("error", ("Swapping from adapter 0 to 1")); failoverShmWriter(); SCIStoreBarrier(m_TargetSegm[m_StandbyAdapterId].sequence,0); m_ActiveAdapterId=m_StandbyAdapterId; @@ -436,26 +412,21 @@ bool SCI_Transporter::doSend() { FLAGS, &err); if(err!=SCI_ERR_OK) { - reportError(callbackObj, - remoteNodeId, TE_SCI_UNABLE_TO_REMOVE_SEQUENCE); + report_error(TE_SCI_UNABLE_TO_REMOVE_SEQUENCE); + DBUG_PRINT("error", ("Unable to remove sequence")); return false; } if(startSequence(m_ActiveAdapterId)!=SCI_ERR_OK) { -#ifdef DEBUG_TRANSPORTER - ndbout << "Start sequence failed" << endl; -#endif - reportError(callbackObj, - remoteNodeId, TE_SCI_UNABLE_TO_START_SEQUENCE); + DBUG_PRINT("error", ("Start sequence failed")); + report_error(TE_SCI_UNABLE_TO_START_SEQUENCE); return false; } m_swapCounter++; -#ifdef DEBUG_TRANSPORTER - ndbout << "failover complete.." << endl; -#endif + DBUG_PRINT("info", ("failover complete")); goto tryagain; } else { - reportError(callbackObj, - remoteNodeId, TE_SCI_UNRECOVERABLE_DATA_TFX_ERROR); + report_error(TE_SCI_UNRECOVERABLE_DATA_TFX_ERROR); + DBUG_PRINT("error", ("SCI Transfer failed")); return false; } return false; @@ -468,20 +439,15 @@ bool SCI_Transporter::doSend() { failoverShmWriter(); m_ActiveAdapterId=m_StandbyAdapterId; m_StandbyAdapterId=temp; -#ifdef DEBUG_TRANSPORTER - ndbout << "Swapping from 1 to 0 " << endl; -#endif + DBUG_PRINT("info", ("Swapping from 1 to 0")); if(createSequence(m_ActiveAdapterId)!=SCI_ERR_OK) { - reportError(callbackObj, - remoteNodeId, TE_SCI_UNABLE_TO_CREATE_SEQUENCE); + DBUG_PRINT("error", ("Unable to create sequence")); + report_error(TE_SCI_UNABLE_TO_CREATE_SEQUENCE); return false; } if(startSequence(m_ActiveAdapterId)!=SCI_ERR_OK) { -#ifdef DEBUG_TRANSPORTER - ndbout << "startSequence failed... disconnecting" << endl; -#endif - reportError(callbackObj, - remoteNodeId, TE_SCI_UNABLE_TO_START_SEQUENCE); + DBUG_PRINT("error", ("startSequence failed... disconnecting")); + report_error(TE_SCI_UNABLE_TO_START_SEQUENCE); return false; } @@ -489,37 +455,36 @@ bool SCI_Transporter::doSend() { , FLAGS, &err); if(err!=SCI_ERR_OK) { - reportError(callbackObj, - remoteNodeId, TE_SCI_UNABLE_TO_REMOVE_SEQUENCE); + DBUG_PRINT("error", ("Unable to remove sequence")); + report_error(TE_SCI_UNABLE_TO_REMOVE_SEQUENCE); return false; } if(createSequence(m_StandbyAdapterId)!=SCI_ERR_OK) { - reportError(callbackObj, - remoteNodeId, TE_SCI_UNABLE_TO_CREATE_SEQUENCE); + DBUG_PRINT("error", ("Unable to create sequence on standby")); + report_error(TE_SCI_UNABLE_TO_CREATE_SEQUENCE); return false; } m_swapCounter=0; -#ifdef DEBUG_TRANSPORTER - ndbout << "failover complete.." << endl; -#endif + DBUG_PRINT("info", ("failover complete..")); goto tryagain; } else { - reportError(callbackObj, - remoteNodeId, TE_SCI_UNRECOVERABLE_DATA_TFX_ERROR); + DBUG_PRINT("error", ("Unrecoverable data transfer error")); + report_error(TE_SCI_UNRECOVERABLE_DATA_TFX_ERROR); return false; } break; default: - reportError(callbackObj, - remoteNodeId, TE_SCI_UNRECOVERABLE_DATA_TFX_ERROR); + DBUG_PRINT("error", ("Unrecoverable data transfer error")); + report_error(TE_SCI_UNRECOVERABLE_DATA_TFX_ERROR); return false; break; } + } } else { SHM_Writer * writer = (m_TargetSegm[m_ActiveAdapterId].writer); writer->updateWritePtr(sizeToSend); @@ -535,13 +500,10 @@ bool SCI_Transporter::doSend() { /** * If we end up here, the SCI segment is full. */ -#ifdef DEBUG_TRANSPORTER - ndbout << "the segment is full for some reason" << endl; -#endif + DBUG_PRINT("error", ("the segment is full for some reason")); return false; } //if } - return true; } // doSend() @@ -557,11 +519,8 @@ void SCI_Transporter::failoverShmWriter() { void SCI_Transporter::setupLocalSegment() { - + DBUG_ENTER("SCI_Transporter::setupLocalSegment"); Uint32 sharedSize = 0; - sharedSize += 16; //SHM_Reader::getSharedSize(); - sharedSize += 16; //SHM_Writer::getSharedSize(); - sharedSize += 32; //SHM_Writer::getSharedSize(); sharedSize =4096; //start of the buffer is page aligend Uint32 sizeOfBuffer = m_BufferSize; @@ -570,27 +529,15 @@ void SCI_Transporter::setupLocalSegment() Uint32 * localReadIndex = (Uint32*)m_SourceSegm[m_ActiveAdapterId].mappedMemory; - Uint32 * localWriteIndex = - (Uint32*)(localReadIndex+ 1); - - Uint32 * localEndOfDataIndex = (Uint32*) - (localReadIndex + 2); - + Uint32 * localWriteIndex = (Uint32*)(localReadIndex+ 1); m_localStatusFlag = (Uint32*)(localReadIndex + 3); - Uint32 * sharedLockIndex = (Uint32*) - (localReadIndex + 4); - - Uint32 * sharedHeavyLock = (Uint32*) - (localReadIndex + 5); - char * localStartOfBuf = (char*) ((char*)m_SourceSegm[m_ActiveAdapterId].mappedMemory+sharedSize); - - * localReadIndex = * localWriteIndex = 0; - * localEndOfDataIndex = sizeOfBuffer -1; - + * localReadIndex = 0; + * localWriteIndex = 0; + const Uint32 slack = MAX_MESSAGE_SIZE; reader = new SHM_Reader(localStartOfBuf, @@ -599,178 +546,240 @@ void SCI_Transporter::setupLocalSegment() localReadIndex, localWriteIndex); - * localReadIndex = 0; - * localWriteIndex = 0; - reader->clear(); + DBUG_VOID_RETURN; } //setupLocalSegment void SCI_Transporter::setupRemoteSegment() { + DBUG_ENTER("SCI_Transporter::setupRemoteSegment"); Uint32 sharedSize = 0; - sharedSize += 16; //SHM_Reader::getSharedSize(); - sharedSize += 16; //SHM_Writer::getSharedSize(); - sharedSize += 32; - sharedSize =4096; //start of the buffer is page aligend + sharedSize =4096; //start of the buffer is page aligned Uint32 sizeOfBuffer = m_BufferSize; + const Uint32 slack = MAX_MESSAGE_SIZE; sizeOfBuffer -= sharedSize; - Uint32 * segPtr = (Uint32*) m_TargetSegm[m_StandbyAdapterId].mappedMemory ; - - Uint32 * remoteReadIndex2 = (Uint32*)segPtr; - Uint32 * remoteWriteIndex2 = (Uint32*) (segPtr + 1); - Uint32 * remoteEndOfDataIndex2 = (Uint32*) (segPtr + 2); - Uint32 * sharedLockIndex2 = (Uint32*) (segPtr + 3); - m_remoteStatusFlag2 = (Uint32*)(segPtr + 4); - Uint32 * sharedHeavyLock2 = (Uint32*) (segPtr + 5); - - - char * remoteStartOfBuf2 = ( char*)((char *)segPtr+sharedSize); - - segPtr = (Uint32*) m_TargetSegm[m_ActiveAdapterId].mappedMemory ; + + Uint32 *segPtr = (Uint32*) m_TargetSegm[m_ActiveAdapterId].mappedMemory ; Uint32 * remoteReadIndex = (Uint32*)segPtr; - Uint32 * remoteWriteIndex = (Uint32*) (segPtr + 1); - Uint32 * remoteEndOfDataIndex = (Uint32*) (segPtr + 2); - Uint32 * sharedLockIndex = (Uint32*) (segPtr + 3); - m_remoteStatusFlag = (Uint32*)(segPtr + 4); - Uint32 * sharedHeavyLock = (Uint32*) (segPtr + 5); + Uint32 * remoteWriteIndex = (Uint32*)(segPtr + 1); + m_remoteStatusFlag = (Uint32*)(segPtr + 3); char * remoteStartOfBuf = ( char*)((char*)segPtr+(sharedSize)); - * remoteReadIndex = * remoteWriteIndex = 0; - * remoteReadIndex2 = * remoteWriteIndex2 = 0; - * remoteEndOfDataIndex = sizeOfBuffer - 1; - * remoteEndOfDataIndex2 = sizeOfBuffer - 1; - - /** - * setup two writers. writer2 is used to mirror the changes of - * writer on the standby - * segment, so that in the case of a failover, we can switch - * to the stdby seg. quickly.* - */ - const Uint32 slack = MAX_MESSAGE_SIZE; - writer = new SHM_Writer(remoteStartOfBuf, sizeOfBuffer, slack, remoteReadIndex, remoteWriteIndex); - writer2 = new SHM_Writer(remoteStartOfBuf2, - sizeOfBuffer, - slack, - remoteReadIndex2, - remoteWriteIndex2); - - * remoteReadIndex = 0; - * remoteWriteIndex = 0; - writer->clear(); - writer2->clear(); m_TargetSegm[0].writer=writer; - m_TargetSegm[1].writer=writer2; m_sendBuffer.m_forceSendLimit = writer->getBufferSize(); if(createSequence(m_ActiveAdapterId)!=SCI_ERR_OK) { - reportThreadError(remoteNodeId, TE_SCI_UNABLE_TO_CREATE_SEQUENCE); + report_error(TE_SCI_UNABLE_TO_CREATE_SEQUENCE); + DBUG_PRINT("error", ("Unable to create sequence on active")); doDisconnect(); } - if(createSequence(m_StandbyAdapterId)!=SCI_ERR_OK) { - reportThreadError(remoteNodeId, TE_SCI_UNABLE_TO_CREATE_SEQUENCE); - doDisconnect(); - } - - + if (m_adapters > 1) { + segPtr = (Uint32*) m_TargetSegm[m_StandbyAdapterId].mappedMemory ; + + Uint32 * remoteReadIndex2 = (Uint32*)segPtr; + Uint32 * remoteWriteIndex2 = (Uint32*) (segPtr + 1); + m_remoteStatusFlag2 = (Uint32*)(segPtr + 3); + + char * remoteStartOfBuf2 = ( char*)((char *)segPtr+sharedSize); + + /** + * setup a writer. writer2 is used to mirror the changes of + * writer on the standby + * segment, so that in the case of a failover, we can switch + * to the stdby seg. quickly.* + */ + writer2 = new SHM_Writer(remoteStartOfBuf2, + sizeOfBuffer, + slack, + remoteReadIndex2, + remoteWriteIndex2); + + * remoteReadIndex = 0; + * remoteWriteIndex = 0; + writer2->clear(); + m_TargetSegm[1].writer=writer2; + if(createSequence(m_StandbyAdapterId)!=SCI_ERR_OK) { + report_error(TE_SCI_UNABLE_TO_CREATE_SEQUENCE); + DBUG_PRINT("error", ("Unable to create sequence on standby")); + doDisconnect(); + } + } + DBUG_VOID_RETURN; } //setupRemoteSegment - - -bool SCI_Transporter::connectImpl(Uint32 timeout) { - - sci_error_t err; - Uint32 offset = 0; - + +bool +SCI_Transporter::init_local() +{ + DBUG_ENTER("SCI_Transporter::init_local"); if(!m_initLocal) { if(initLocalSegment()!=SCI_ERR_OK){ - NdbSleep_MilliSleep(timeout); + NdbSleep_MilliSleep(10); //NDB SHOULD TERMINATE AND COMPUTER REBOOTED! - reportThreadError(localNodeId, TE_SCI_CANNOT_INIT_LOCALSEGMENT); - return false; + report_error(TE_SCI_CANNOT_INIT_LOCALSEGMENT); + DBUG_RETURN(false); } - m_initLocal=true; + m_initLocal=true; } - - if(!m_mapped ) { - - for(Uint32 i=0; i < m_adapters ; i++) { - m_TargetSegm[i].rhm[i].remoteHandle=0; - SCIConnectSegment(sciAdapters[i].scidesc, - &(m_TargetSegm[i].rhm[i].remoteHandle), - m_remoteNodes[i], - remoteSegmentId(localNodeId, remoteNodeId), - i, - 0, - 0, - 0, - 0, - &err); - - if(err != SCI_ERR_OK) { - NdbSleep_MilliSleep(timeout); - return false; - } - - } - - - // Map the remote memory segment into program space - for(Uint32 i=0; i < m_adapters ; i++) { - m_TargetSegm[i].mappedMemory = - SCIMapRemoteSegment((m_TargetSegm[i].rhm[i].remoteHandle), - &(m_TargetSegm[i].rhm[i].map), - offset, - m_BufferSize, - NULL, - FLAGS, - &err); - - - if(err!= SCI_ERR_OK) { -#ifdef DEBUG_TRANSPORTER - ndbout_c("\nCannot map a segment to the remote node %d."); - ndbout_c("Error code 0x%x",m_RemoteSciNodeId, err); -#endif - //NDB SHOULD TERMINATE AND COMPUTER REBOOTED! - reportThreadError(remoteNodeId, TE_SCI_CANNOT_MAP_REMOTESEGMENT); - return false; - } - - - } - m_mapped=true; - setupRemoteSegment(); - setConnected(); -#ifdef DEBUG_TRANSPORTER - ndbout << "connected and mapped to segment : " << endl; - ndbout << "remoteNode: " << m_remoteNodes[0] << endl; - ndbout << "remoteNode: " << m_remotenodes[1] << endl; - ndbout << "remoteSegId: " - << remoteSegmentId(localNodeId, remoteNodeId) - << endl; -#endif - return true; - } - else { - return getConnectionStatus(); - } -} // connectImpl() - + DBUG_RETURN(true); +} +bool +SCI_Transporter::init_remote() +{ + DBUG_ENTER("SCI_Transporter::init_remote"); + sci_error_t err; + Uint32 offset = 0; + if(!m_mapped ) { + DBUG_PRINT("info", ("Map remote segments")); + for(Uint32 i=0; i < m_adapters ; i++) { + m_TargetSegm[i].rhm[i].remoteHandle=0; + SCIConnectSegment(sciAdapters[i].scidesc, + &(m_TargetSegm[i].rhm[i].remoteHandle), + m_remoteNodes[i], + remoteSegmentId(localNodeId, remoteNodeId), + i, + 0, + 0, + 0, + 0, + &err); + + if(err != SCI_ERR_OK) { + NdbSleep_MilliSleep(10); + DBUG_PRINT("error", ("Error connecting segment, err 0x%x", err)); + DBUG_RETURN(false); + } + + } + // Map the remote memory segment into program space + for(Uint32 i=0; i < m_adapters ; i++) { + m_TargetSegm[i].mappedMemory = + SCIMapRemoteSegment((m_TargetSegm[i].rhm[i].remoteHandle), + &(m_TargetSegm[i].rhm[i].map), + offset, + m_BufferSize, + NULL, + FLAGS, + &err); + + + if(err!= SCI_ERR_OK) { + DBUG_PRINT("error", ("Cannot map a segment to the remote node %d. Error code 0x%x",m_RemoteSciNodeId, err)); + //NDB SHOULD TERMINATE AND COMPUTER REBOOTED! + report_error(TE_SCI_CANNOT_MAP_REMOTESEGMENT); + DBUG_RETURN(false); + } + } + m_mapped=true; + setupRemoteSegment(); + setConnected(); + DBUG_PRINT("info", ("connected and mapped to segment, remoteNode: %d", + remoteNodeId)); + DBUG_PRINT("info", ("remoteSegId: %d", + remoteSegmentId(localNodeId, remoteNodeId))); + DBUG_RETURN(true); + } else { + DBUG_RETURN(getConnectionStatus()); + } +} + +bool +SCI_Transporter::connect_client_impl(NDB_SOCKET_TYPE sockfd) +{ + SocketInputStream s_input(sockfd); + SocketOutputStream s_output(sockfd); + char buf[256]; + DBUG_ENTER("SCI_Transporter::connect_client_impl"); + // Wait for server to create and attach + if (s_input.gets(buf, 256) == 0) { + DBUG_PRINT("error", ("No initial response from server in SCI")); + NDB_CLOSE_SOCKET(sockfd); + DBUG_RETURN(false); + } + + if (!init_local()) { + NDB_CLOSE_SOCKET(sockfd); + DBUG_RETURN(false); + } + + // Send ok to server + s_output.println("sci client 1 ok"); + + if (!init_remote()) { + NDB_CLOSE_SOCKET(sockfd); + DBUG_RETURN(false); + } + // Wait for ok from server + if (s_input.gets(buf, 256) == 0) { + DBUG_PRINT("error", ("No second response from server in SCI")); + NDB_CLOSE_SOCKET(sockfd); + DBUG_RETURN(false); + } + // Send ok to server + s_output.println("sci client 2 ok"); + + NDB_CLOSE_SOCKET(sockfd); + DBUG_PRINT("info", ("Successfully connected client to node %d", + remoteNodeId)); + DBUG_RETURN(true); +} + +bool +SCI_Transporter::connect_server_impl(NDB_SOCKET_TYPE sockfd) +{ + SocketOutputStream s_output(sockfd); + SocketInputStream s_input(sockfd); + char buf[256]; + DBUG_ENTER("SCI_Transporter::connect_server_impl"); + + if (!init_local()) { + NDB_CLOSE_SOCKET(sockfd); + DBUG_RETURN(false); + } + // Send ok to client + s_output.println("sci server 1 ok"); + + // Wait for ok from client + if (s_input.gets(buf, 256) == 0) { + DBUG_PRINT("error", ("No response from client in SCI")); + NDB_CLOSE_SOCKET(sockfd); + DBUG_RETURN(false); + } + + if (!init_remote()) { + NDB_CLOSE_SOCKET(sockfd); + DBUG_RETURN(false); + } + // Send ok to client + s_output.println("sci server 2 ok"); + // Wait for ok from client + if (s_input.gets(buf, 256) == 0) { + DBUG_PRINT("error", ("No second response from client in SCI")); + NDB_CLOSE_SOCKET(sockfd); + DBUG_RETURN(false); + } + + NDB_CLOSE_SOCKET(sockfd); + DBUG_PRINT("info", ("Successfully connected server to node %d", + remoteNodeId)); + DBUG_RETURN(true); +} + sci_error_t SCI_Transporter::createSequence(Uint32 adapterid) { sci_error_t err; SCICreateMapSequence((m_TargetSegm[adapterid].rhm[adapterid].map), @@ -795,13 +804,14 @@ sci_error_t SCI_Transporter::startSequence(Uint32 adapterid) { // If there still is an error then data cannot be safely send - return err; + return err; } // startSequence() bool SCI_Transporter::disconnectLocal() -{ +{ + DBUG_ENTER("SCI_Transporter::disconnectLocal"); sci_error_t err; m_ActiveAdapterId=0; @@ -809,31 +819,28 @@ bool SCI_Transporter::disconnectLocal() */ SCIUnmapSegment(m_SourceSegm[0].lhm[0].map,0,&err); - if(err!=SCI_ERR_OK) { - reportError(callbackObj, - remoteNodeId, TE_SCI_UNABLE_TO_UNMAP_SEGMENT); - return false; - } + if(err!=SCI_ERR_OK) { + report_error(TE_SCI_UNABLE_TO_UNMAP_SEGMENT); + DBUG_PRINT("error", ("Unable to unmap segment")); + DBUG_RETURN(false); + } SCIRemoveSegment((m_SourceSegm[m_ActiveAdapterId].localHandle), FLAGS, &err); if(err!=SCI_ERR_OK) { - reportError(callbackObj, remoteNodeId, TE_SCI_UNABLE_TO_REMOVE_SEGMENT); - return false; + report_error(TE_SCI_UNABLE_TO_REMOVE_SEGMENT); + DBUG_PRINT("error", ("Unable to remove segment")); + DBUG_RETURN(false); } - - if(err == SCI_ERR_OK) { -#ifdef DEBUG_TRANSPORTER - printf("Local memory segment is unmapped and removed\n" ); -#endif - } - return true; + DBUG_PRINT("info", ("Local memory segment is unmapped and removed")); + DBUG_RETURN(true); } // disconnectLocal() bool SCI_Transporter::disconnectRemote() { + DBUG_ENTER("SCI_Transporter::disconnectRemote"); sci_error_t err; for(Uint32 i=0; i= send_buf_size) || + (curr_data_size >= sci_buffer_remaining)) { + /** + * The new message will not fit in the send buffer. We need to + * send the send buffer before filling it up with the new + * signal data. If current data size will spill over buffer edge + * we will also send to ensure correct operation. + */ + if (!doSend()) { + /** + * We were not successfull sending, report 0 as meaning buffer full and + * upper levels handle retries and other recovery matters. + */ return 0; } } - + /** + * New signal fits, simply fill it up with more data. + */ Uint32 sz = m_sendBuffer.m_dataSize; return &m_sendBuffer.m_buffer[sz]; } @@ -918,10 +937,11 @@ void SCI_Transporter::updateWritePtr(Uint32 lenBytes, Uint32 prio){ Uint32 sz = m_sendBuffer.m_dataSize; - sz += (lenBytes / 4); + Uint32 packet_size = m_PacketSize; + sz += ((lenBytes + 3) >> 2); m_sendBuffer.m_dataSize = sz; - if(sz > m_PacketSize) { + if(sz > packet_size) { /**------------------------------------------------- * Buffer is full and we are ready to send. We will * not wait since the signal is already in the buffer. @@ -944,7 +964,8 @@ bool SCI_Transporter::getConnectionStatus() { if(*m_localStatusFlag == SCICONNECTED && (*m_remoteStatusFlag == SCICONNECTED || - *m_remoteStatusFlag2 == SCICONNECTED)) + ((m_adapters > 1) && + *m_remoteStatusFlag2 == SCICONNECTED))) return true; else return false; @@ -954,7 +975,9 @@ SCI_Transporter::getConnectionStatus() { void SCI_Transporter::setConnected() { *m_remoteStatusFlag = SCICONNECTED; - *m_remoteStatusFlag2 = SCICONNECTED; + if (m_adapters > 1) { + *m_remoteStatusFlag2 = SCICONNECTED; + } *m_localStatusFlag = SCICONNECTED; } @@ -963,8 +986,10 @@ void SCI_Transporter::setDisconnect() { if(getLinkStatus(m_ActiveAdapterId)) *m_remoteStatusFlag = SCIDISCONNECT; - if(getLinkStatus(m_StandbyAdapterId)) - *m_remoteStatusFlag2 = SCIDISCONNECT; + if (m_adapters > 1) { + if(getLinkStatus(m_StandbyAdapterId)) + *m_remoteStatusFlag2 = SCIDISCONNECT; + } } @@ -981,20 +1006,20 @@ static bool init = false; bool SCI_Transporter::initSCI() { + DBUG_ENTER("SCI_Transporter::initSCI"); if(!init){ sci_error_t error; // Initialize SISCI library SCIInitialize(0, &error); if(error != SCI_ERR_OK) { -#ifdef DEBUG_TRANSPORTER - ndbout_c("\nCannot initialize SISCI library."); - ndbout_c("\nInconsistency between SISCI library and SISCI driver.Error code 0x%x", error); -#endif - return false; + DBUG_PRINT("error", ("Cannot initialize SISCI library.")); + DBUG_PRINT("error", ("Inconsistency between SISCI library and SISCI driver. Error code 0x%x", + error)); + DBUG_RETURN(false); } init = true; } - return true; + DBUG_RETURN(true); } diff --git a/ndb/src/common/transporter/SCI_Transporter.hpp b/ndb/src/common/transporter/SCI_Transporter.hpp index 03496c2ce21..e2f2dfcaf99 100644 --- a/ndb/src/common/transporter/SCI_Transporter.hpp +++ b/ndb/src/common/transporter/SCI_Transporter.hpp @@ -26,7 +26,7 @@ #include - /** +/** * The SCI Transporter * * The design goal of the SCI transporter is to deliver high performance @@ -135,15 +135,17 @@ public: bool getConnectionStatus(); private: - SCI_Transporter(Uint32 packetSize, + SCI_Transporter(TransporterRegistry &t_reg, + const char *local_host, + const char *remote_host, + int port, + Uint32 packetSize, Uint32 bufferSize, Uint32 nAdapters, Uint16 remoteSciNodeId0, Uint16 remoteSciNodeId1, NodeId localNodeID, NodeId remoteNodeID, - int byteorder, - bool compression, bool checksum, bool signalId, Uint32 reportFreq = 4096); @@ -160,7 +162,8 @@ private: /** * For statistics on transfered packets */ -#ifdef DEBUG_TRANSPORTER +//#ifdef DEBUG_TRANSPORTER +#if 1 Uint32 i1024; Uint32 i2048; Uint32 i2049; @@ -177,10 +180,8 @@ private: struct { Uint32 * m_buffer; // The buffer Uint32 m_dataSize; // No of words in buffer - Uint32 m_bufferSize; // Buffer size + Uint32 m_sendBufferSize; // Buffer size Uint32 m_forceSendLimit; // Send when buffer is this full - - bool full() const { return (m_dataSize * 4) > m_forceSendLimit ;} } m_sendBuffer; SHM_Reader * reader; @@ -196,7 +197,7 @@ private: Uint32 m_adapters; Uint32 m_numberOfRemoteNodes; - Uint16* m_remoteNodes; + Uint16 m_remoteNodes[2]; typedef struct SciAdapter { sci_desc_t scidesc; @@ -296,12 +297,11 @@ private: */ bool sendIsPossible(struct timeval * timeout); - void getReceivePtr(Uint32 ** ptr, Uint32 ** eod){ reader->getReadPtr(* ptr, * eod); } - void updateReceivePtr(Uint32 * ptr){ + void updateReceivePtr(Uint32 *ptr){ reader->updateReadPtr(ptr); } @@ -341,7 +341,9 @@ private: */ void failoverShmWriter(); - + bool init_local(); + bool init_remote(); + protected: /** Perform a connection between segment @@ -350,7 +352,8 @@ protected: * retrying. * @return Returns true on success, otherwize falser */ - bool connectImpl(Uint32 timeOutMillis); + bool connect_server_impl(NDB_SOCKET_TYPE sockfd); + bool connect_client_impl(NDB_SOCKET_TYPE sockfd); /** * We will disconnect if: diff --git a/ndb/src/common/transporter/SHM_Buffer.hpp b/ndb/src/common/transporter/SHM_Buffer.hpp index 32e59dd57a2..f49b4fe73cb 100644 --- a/ndb/src/common/transporter/SHM_Buffer.hpp +++ b/ndb/src/common/transporter/SHM_Buffer.hpp @@ -52,7 +52,7 @@ public: } void clear() { - m_readIndex = * m_sharedReadIndex; + m_readIndex = 0; } /** @@ -71,7 +71,7 @@ public: /** * Update read ptr */ - inline void updateReadPtr(Uint32 * readPtr); + inline void updateReadPtr(Uint32 *ptr); private: char * const m_startOfBuffer; @@ -98,8 +98,8 @@ SHM_Reader::empty() const{ */ inline void -SHM_Reader::getReadPtr(Uint32 * & ptr, Uint32 * & eod){ - +SHM_Reader::getReadPtr(Uint32 * & ptr, Uint32 * & eod) +{ Uint32 tReadIndex = m_readIndex; Uint32 tWriteIndex = * m_sharedWriteIndex; @@ -117,14 +117,14 @@ SHM_Reader::getReadPtr(Uint32 * & ptr, Uint32 * & eod){ */ inline void -SHM_Reader::updateReadPtr(Uint32 * ptr){ - - Uint32 tReadIndex = ((char *)ptr) - m_startOfBuffer; +SHM_Reader::updateReadPtr(Uint32 *ptr) +{ + Uint32 tReadIndex = ((char*)ptr) - m_startOfBuffer; assert(tReadIndex < m_totalBufferSize); if(tReadIndex >= m_bufferSize){ - tReadIndex = 0; //-= m_bufferSize; + tReadIndex = 0; } m_readIndex = tReadIndex; @@ -149,7 +149,7 @@ public: } void clear() { - m_writeIndex = * m_sharedWriteIndex; + m_writeIndex = 0; } inline char * getWritePtr(Uint32 sz); @@ -206,7 +206,7 @@ SHM_Writer::updateWritePtr(Uint32 sz){ assert(tWriteIndex < m_totalBufferSize); if(tWriteIndex >= m_bufferSize){ - tWriteIndex = 0; //-= m_bufferSize; + tWriteIndex = 0; } m_writeIndex = tWriteIndex; diff --git a/ndb/src/common/transporter/SHM_Transporter.cpp b/ndb/src/common/transporter/SHM_Transporter.cpp index aa6b650afa8..ab161d8c18c 100644 --- a/ndb/src/common/transporter/SHM_Transporter.cpp +++ b/ndb/src/common/transporter/SHM_Transporter.cpp @@ -32,13 +32,12 @@ SHM_Transporter::SHM_Transporter(TransporterRegistry &t_reg, int r_port, NodeId lNodeId, NodeId rNodeId, - bool compression, bool checksum, bool signalId, key_t _shmKey, Uint32 _shmSize) : Transporter(t_reg, lHostName, rHostName, r_port, lNodeId, rNodeId, - 0, compression, checksum, signalId), + 0, false, checksum, signalId), shmKey(_shmKey), shmSize(_shmSize) { @@ -48,7 +47,7 @@ SHM_Transporter::SHM_Transporter(TransporterRegistry &t_reg, shmBuf = 0; reader = 0; writer = 0; - + setupBuffersDone=false; #ifdef DEBUG_TRANSPORTER printf("shm key (%d - %d) = %d\n", lNodeId, rNodeId, shmKey); @@ -92,8 +91,6 @@ SHM_Transporter::setupBuffers(){ clientStatusFlag = base2 + 4; char * startOfBuf2 = ((char *)base2)+sharedSize; - * sharedReadIndex2 = * sharedWriteIndex2 = 0; - if(isServer){ * serverStatusFlag = 0; reader = new SHM_Reader(startOfBuf1, @@ -109,10 +106,10 @@ SHM_Transporter::setupBuffers(){ sharedWriteIndex2); * sharedReadIndex1 = 0; - * sharedWriteIndex2 = 0; + * sharedWriteIndex1 = 0; * sharedReadIndex2 = 0; - * sharedWriteIndex1 = 0; + * sharedWriteIndex2 = 0; reader->clear(); writer->clear(); @@ -224,6 +221,7 @@ SHM_Transporter::prepareSend(const SignalHeader * const signalHeader, bool SHM_Transporter::connect_server_impl(NDB_SOCKET_TYPE sockfd) { + DBUG_ENTER("SHM_Transporter::connect_server_impl"); SocketOutputStream s_output(sockfd); SocketInputStream s_input(sockfd); char buf[256]; @@ -233,7 +231,7 @@ SHM_Transporter::connect_server_impl(NDB_SOCKET_TYPE sockfd) if (!ndb_shm_create()) { report_error(TE_SHM_UNABLE_TO_CREATE_SEGMENT); NDB_CLOSE_SOCKET(sockfd); - return false; + DBUG_RETURN(false); } _shmSegCreated = true; } @@ -243,7 +241,7 @@ SHM_Transporter::connect_server_impl(NDB_SOCKET_TYPE sockfd) if (!ndb_shm_attach()) { report_error(TE_SHM_UNABLE_TO_ATTACH_SEGMENT); NDB_CLOSE_SOCKET(sockfd); - return false; + DBUG_RETURN(false); } _attached = true; } @@ -254,7 +252,7 @@ SHM_Transporter::connect_server_impl(NDB_SOCKET_TYPE sockfd) // Wait for ok from client if (s_input.gets(buf, 256) == 0) { NDB_CLOSE_SOCKET(sockfd); - return false; + DBUG_RETURN(false); } int r= connect_common(sockfd); @@ -265,17 +263,20 @@ SHM_Transporter::connect_server_impl(NDB_SOCKET_TYPE sockfd) // Wait for ok from client if (s_input.gets(buf, 256) == 0) { NDB_CLOSE_SOCKET(sockfd); - return false; + DBUG_RETURN(false); } + DBUG_PRINT("info", ("Successfully connected server to node %d", + remoteNodeId)); } NDB_CLOSE_SOCKET(sockfd); - return r; + DBUG_RETURN(r); } bool SHM_Transporter::connect_client_impl(NDB_SOCKET_TYPE sockfd) { + DBUG_ENTER("SHM_Transporter::connect_client_impl"); SocketInputStream s_input(sockfd); SocketOutputStream s_output(sockfd); char buf[256]; @@ -283,14 +284,18 @@ SHM_Transporter::connect_client_impl(NDB_SOCKET_TYPE sockfd) // Wait for server to create and attach if (s_input.gets(buf, 256) == 0) { NDB_CLOSE_SOCKET(sockfd); - return false; + DBUG_PRINT("error", ("Server id %d did not attach", + remoteNodeId)); + DBUG_RETURN(false); } // Create if(!_shmSegCreated){ if (!ndb_shm_get()) { NDB_CLOSE_SOCKET(sockfd); - return false; + DBUG_PRINT("error", ("Failed create of shm seg to node %d", + remoteNodeId)); + DBUG_RETURN(false); } _shmSegCreated = true; } @@ -300,7 +305,9 @@ SHM_Transporter::connect_client_impl(NDB_SOCKET_TYPE sockfd) if (!ndb_shm_attach()) { report_error(TE_SHM_UNABLE_TO_ATTACH_SEGMENT); NDB_CLOSE_SOCKET(sockfd); - return false; + DBUG_PRINT("error", ("Failed attach of shm seg to node %d", + remoteNodeId)); + DBUG_RETURN(false); } _attached = true; } @@ -314,21 +321,28 @@ SHM_Transporter::connect_client_impl(NDB_SOCKET_TYPE sockfd) // Wait for ok from server if (s_input.gets(buf, 256) == 0) { NDB_CLOSE_SOCKET(sockfd); - return false; + DBUG_PRINT("error", ("No ok from server node %d", + remoteNodeId)); + DBUG_RETURN(false); } // Send ok to server s_output.println("shm client 2 ok"); + DBUG_PRINT("info", ("Successfully connected client to node %d", + remoteNodeId)); } NDB_CLOSE_SOCKET(sockfd); - return r; + DBUG_RETURN(r); } bool SHM_Transporter::connect_common(NDB_SOCKET_TYPE sockfd) { - if (!checkConnected()) + if (!checkConnected()) { + DBUG_PRINT("error", ("Already connected to node %d", + remoteNodeId)); return false; + } if(!setupBuffersDone) { setupBuffers(); @@ -341,5 +355,7 @@ SHM_Transporter::connect_common(NDB_SOCKET_TYPE sockfd) return true; } + DBUG_PRINT("error", ("Failed to set up buffers to node %d", + remoteNodeId)); return false; } diff --git a/ndb/src/common/transporter/SHM_Transporter.hpp b/ndb/src/common/transporter/SHM_Transporter.hpp index be54d0daa2a..27692209ffe 100644 --- a/ndb/src/common/transporter/SHM_Transporter.hpp +++ b/ndb/src/common/transporter/SHM_Transporter.hpp @@ -38,7 +38,6 @@ public: int r_port, NodeId lNodeId, NodeId rNodeId, - bool compression, bool checksum, bool signalId, key_t shmKey, @@ -127,6 +126,7 @@ protected: private: bool _shmSegCreated; bool _attached; + bool m_connected; key_t shmKey; volatile Uint32 * serverStatusFlag; diff --git a/ndb/src/common/transporter/TCP_Transporter.cpp b/ndb/src/common/transporter/TCP_Transporter.cpp index 8833b51e236..7cfdc224b34 100644 --- a/ndb/src/common/transporter/TCP_Transporter.cpp +++ b/ndb/src/common/transporter/TCP_Transporter.cpp @@ -70,11 +70,10 @@ TCP_Transporter::TCP_Transporter(TransporterRegistry &t_reg, int r_port, NodeId lNodeId, NodeId rNodeId, - int byte_order, - bool compr, bool chksm, bool signalId, + bool chksm, bool signalId, Uint32 _reportFreq) : Transporter(t_reg, lHostName, rHostName, r_port, lNodeId, rNodeId, - byte_order, compr, chksm, signalId), + 0, false, chksm, signalId), m_sendBuffer(sendBufSize) { maxReceiveSize = maxRecvSize; @@ -106,12 +105,14 @@ TCP_Transporter::~TCP_Transporter() { bool TCP_Transporter::connect_server_impl(NDB_SOCKET_TYPE sockfd) { - return connect_common(sockfd); + DBUG_ENTER("TCP_Transpporter::connect_server_impl"); + DBUG_RETURN(connect_common(sockfd)); } bool TCP_Transporter::connect_client_impl(NDB_SOCKET_TYPE sockfd) { - return connect_common(sockfd); + DBUG_ENTER("TCP_Transpporter::connect_client_impl"); + DBUG_RETURN(connect_common(sockfd)); } bool TCP_Transporter::connect_common(NDB_SOCKET_TYPE sockfd) @@ -119,6 +120,8 @@ bool TCP_Transporter::connect_common(NDB_SOCKET_TYPE sockfd) theSocket = sockfd; setSocketOptions(); setSocketNonBlocking(theSocket); + DBUG_PRINT("info", ("Successfully set-up TCP transporter to node %d", + remoteNodeId)); return true; } @@ -359,50 +362,56 @@ TCP_Transporter::doReceive() { // Select-function must return the socket for read // before this method is called // It reads the external TCP/IP interface once - - const int nBytesRead = recv(theSocket, - receiveBuffer.insertPtr, maxReceiveSize, 0); - - if (nBytesRead > 0) { - receiveBuffer.sizeOfData += nBytesRead; - receiveBuffer.insertPtr += nBytesRead; + int size = receiveBuffer.sizeOfBuffer - receiveBuffer.sizeOfData; + if(size > 0){ + const int nBytesRead = recv(theSocket, + receiveBuffer.insertPtr, + size < maxReceiveSize ? size : maxReceiveSize, + 0); - if(receiveBuffer.sizeOfData > receiveBuffer.sizeOfBuffer){ + if (nBytesRead > 0) { + receiveBuffer.sizeOfData += nBytesRead; + receiveBuffer.insertPtr += nBytesRead; + + if(receiveBuffer.sizeOfData > receiveBuffer.sizeOfBuffer){ #ifdef DEBUG_TRANSPORTER - ndbout_c("receiveBuffer.sizeOfData(%d) > receiveBuffer.sizeOfBuffer(%d)", - receiveBuffer.sizeOfData, receiveBuffer.sizeOfBuffer); - ndbout_c("nBytesRead = %d", nBytesRead); + ndbout_c("receiveBuffer.sizeOfData(%d) > receiveBuffer.sizeOfBuffer(%d)", + receiveBuffer.sizeOfData, receiveBuffer.sizeOfBuffer); + ndbout_c("nBytesRead = %d", nBytesRead); #endif - ndbout_c("receiveBuffer.sizeOfData(%d) > receiveBuffer.sizeOfBuffer(%d)", - receiveBuffer.sizeOfData, receiveBuffer.sizeOfBuffer); - report_error(TE_INVALID_MESSAGE_LENGTH); - return 0; - } - - receiveCount ++; - receiveSize += nBytesRead; - - if(receiveCount == reportFreq){ - reportReceiveLen(get_callback_obj(), remoteNodeId, receiveCount, receiveSize); - receiveCount = 0; - receiveSize = 0; + ndbout_c("receiveBuffer.sizeOfData(%d) > receiveBuffer.sizeOfBuffer(%d)", + receiveBuffer.sizeOfData, receiveBuffer.sizeOfBuffer); + report_error(TE_INVALID_MESSAGE_LENGTH); + return 0; + } + + receiveCount ++; + receiveSize += nBytesRead; + + if(receiveCount == reportFreq){ + reportReceiveLen(get_callback_obj(), remoteNodeId, receiveCount, receiveSize); + receiveCount = 0; + receiveSize = 0; + } + return nBytesRead; + } else { +#if defined DEBUG_TRANSPORTER + ndbout_c("Receive Failure(disconnect==%d) to node = %d nBytesSent = %d " + "errno = %d strerror = %s", + DISCONNECT_ERRNO(InetErrno, nBytesRead), + remoteNodeId, nBytesRead, InetErrno, + (char*)ndbstrerror(InetErrno)); +#endif + if(DISCONNECT_ERRNO(InetErrno, nBytesRead)){ + // The remote node has closed down + doDisconnect(); + report_disconnect(InetErrno); + } } return nBytesRead; } else { -#if defined DEBUG_TRANSPORTER - ndbout_c("Receive Failure(disconnect==%d) to node = %d nBytesSent = %d " - "errno = %d strerror = %s", - DISCONNECT_ERRNO(InetErrno, nBytesRead), - remoteNodeId, nBytesRead, InetErrno, - (char*)ndbstrerror(InetErrno)); -#endif - if(DISCONNECT_ERRNO(InetErrno, nBytesRead)){ - // The remote node has closed down - doDisconnect(); - report_disconnect(InetErrno); - } + return 0; } - return nBytesRead; } void diff --git a/ndb/src/common/transporter/TCP_Transporter.hpp b/ndb/src/common/transporter/TCP_Transporter.hpp index 958cfde03a1..48046310bf8 100644 --- a/ndb/src/common/transporter/TCP_Transporter.hpp +++ b/ndb/src/common/transporter/TCP_Transporter.hpp @@ -52,8 +52,7 @@ private: int r_port, NodeId lHostId, NodeId rHostId, - int byteorder, - bool compression, bool checksum, bool signalId, + bool checksum, bool signalId, Uint32 reportFreq = 4096); // Disconnect, delete send buffers and receive buffer diff --git a/ndb/src/common/transporter/TransporterRegistry.cpp b/ndb/src/common/transporter/TransporterRegistry.cpp index fe1d4b04786..cacbbed00f1 100644 --- a/ndb/src/common/transporter/TransporterRegistry.cpp +++ b/ndb/src/common/transporter/TransporterRegistry.cpp @@ -15,6 +15,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include +#include #include #include "TransporterInternalDefinitions.hpp" @@ -48,9 +49,10 @@ SocketServer::Session * TransporterService::newSession(NDB_SOCKET_TYPE sockfd) { + DBUG_ENTER("SocketServer::Session * TransporterService::newSession"); if (m_auth && !m_auth->server_authenticate(sockfd)){ NDB_CLOSE_SOCKET(sockfd); - return 0; + DBUG_RETURN(0); } { @@ -60,27 +62,32 @@ SocketServer::Session * TransporterService::newSession(NDB_SOCKET_TYPE sockfd) char buf[256]; if (s_input.gets(buf, 256) == 0) { NDB_CLOSE_SOCKET(sockfd); - return 0; + DBUG_PRINT("error", ("Could not get node id from client")); + DBUG_RETURN(0); } if (sscanf(buf, "%d", &nodeId) != 1) { NDB_CLOSE_SOCKET(sockfd); - return 0; + DBUG_PRINT("error", ("Error in node id from client")); + DBUG_RETURN(0); } //check that nodeid is valid and that there is an allocated transporter - if ( nodeId < 0 || nodeId >= (int) m_transporter_registry->maxTransporters) { - NDB_CLOSE_SOCKET(sockfd); - return 0; + if ( nodeId < 0 || nodeId >= (int)m_transporter_registry->maxTransporters) { + NDB_CLOSE_SOCKET(sockfd); + DBUG_PRINT("error", ("Node id out of range from client")); + DBUG_RETURN(0); } if (m_transporter_registry->theTransporters[nodeId] == 0) { NDB_CLOSE_SOCKET(sockfd); - return 0; + DBUG_PRINT("error", ("No transporter for this node id from client")); + DBUG_RETURN(0); } //check that the transporter should be connected if (m_transporter_registry->performStates[nodeId] != TransporterRegistry::CONNECTING) { NDB_CLOSE_SOCKET(sockfd); - return 0; + DBUG_PRINT("error", ("Transporter in wrong state for this node id from client")); + DBUG_RETURN(0); } Transporter *t= m_transporter_registry->theTransporters[nodeId]; @@ -93,14 +100,13 @@ SocketServer::Session * TransporterService::newSession(NDB_SOCKET_TYPE sockfd) t->connect_server(sockfd); } - return 0; + DBUG_RETURN(0); } TransporterRegistry::TransporterRegistry(void * callback, unsigned _maxTransporters, unsigned sizeOfLongSignalMemory) { - m_transporter_service= 0; nodeIdSpecified = false; maxTransporters = _maxTransporters; sendCounter = 1; @@ -209,8 +215,6 @@ TransporterRegistry::createTransporter(TCP_TransporterConfiguration *config) { config->port, localNodeId, config->remoteNodeId, - config->byteOrder, - config->compression, config->checksum, config->signalId); if (t == NULL) @@ -264,8 +268,6 @@ TransporterRegistry::createTransporter(OSE_TransporterConfiguration *conf) { conf->localHostName, conf->remoteNodeId, conf->remoteHostName, - conf->byteOrder, - conf->compression, conf->checksum, conf->signalId); if (t == NULL) @@ -306,15 +308,17 @@ TransporterRegistry::createTransporter(SCI_TransporterConfiguration *config) { if(theTransporters[config->remoteNodeId] != NULL) return false; - SCI_Transporter * t = new SCI_Transporter(config->sendLimit, + SCI_Transporter * t = new SCI_Transporter(*this, + config->localHostName, + config->remoteHostName, + config->port, + config->sendLimit, config->bufferSize, config->nLocalAdapters, config->remoteSciNodeId0, config->remoteSciNodeId1, localNodeId, config->remoteNodeId, - config->byteOrder, - config->compression, config->checksum, config->signalId); @@ -357,7 +361,6 @@ TransporterRegistry::createTransporter(SHM_TransporterConfiguration *config) { config->port, localNodeId, config->remoteNodeId, - config->compression, config->checksum, config->signalId, config->shmKey, @@ -855,8 +858,8 @@ TransporterRegistry::performReceive(){ if(t->isConnected() && t->checkConnected()){ Uint32 * readPtr, * eodPtr; t->getReceivePtr(&readPtr, &eodPtr); - readPtr = unpack(readPtr, eodPtr, nodeId, ioStates[nodeId]); - t->updateReceivePtr(readPtr); + Uint32 *newPtr = unpack(readPtr, eodPtr, nodeId, ioStates[nodeId]); + t->updateReceivePtr(newPtr); } } } @@ -870,8 +873,8 @@ TransporterRegistry::performReceive(){ if(t->isConnected() && t->checkConnected()){ Uint32 * readPtr, * eodPtr; t->getReceivePtr(&readPtr, &eodPtr); - readPtr = unpack(readPtr, eodPtr, nodeId, ioStates[nodeId]); - t->updateReceivePtr(readPtr); + Uint32 *newPtr = unpack(readPtr, eodPtr, nodeId, ioStates[nodeId]); + t->updateReceivePtr(newPtr); } } } @@ -1023,7 +1026,9 @@ TransporterRegistry::setIOState(NodeId nodeId, IOState state) { static void * run_start_clients_C(void * me) { + my_thread_init(); ((TransporterRegistry*) me)->start_clients_thread(); + my_thread_end(); NdbThread_Exit(0); return me; } @@ -1106,6 +1111,7 @@ TransporterRegistry::update_connections() void TransporterRegistry::start_clients_thread() { + DBUG_ENTER("TransporterRegistry::start_clients_thread"); while (m_run_start_clients_thread) { NdbSleep_MilliSleep(100); for (int i= 0, n= 0; n < nTransporters && m_run_start_clients_thread; i++){ @@ -1129,6 +1135,7 @@ TransporterRegistry::start_clients_thread() } } } + DBUG_VOID_RETURN; } bool @@ -1159,55 +1166,67 @@ TransporterRegistry::stop_clients() return true; } +void +TransporterRegistry::add_transporter_interface(const char *interface, unsigned short port) +{ + DBUG_ENTER("TransporterRegistry::add_transporter_interface"); + DBUG_PRINT("enter",("interface=%s, port= %d", interface, port)); + if (interface && strlen(interface) == 0) + interface= 0; + + for (unsigned i= 0; i < m_transporter_interface.size(); i++) + { + Transporter_interface &tmp= m_transporter_interface[i]; + if (port != tmp.m_service_port) + continue; + if (interface != 0 && tmp.m_interface != 0 && + strcmp(interface, tmp.m_interface) == 0) + { + DBUG_VOID_RETURN; // found match, no need to insert + } + if (interface == 0 && tmp.m_interface == 0) + { + DBUG_VOID_RETURN; // found match, no need to insert + } + } + Transporter_interface t; + t.m_service_port= port; + t.m_interface= interface; + m_transporter_interface.push_back(t); + DBUG_PRINT("exit",("interface and port added")); + DBUG_VOID_RETURN; +} + bool TransporterRegistry::start_service(SocketServer& socket_server) { -#if 0 - for (int i= 0, n= 0; n < nTransporters; i++){ - Transporter * t = theTransporters[i]; - if (!t) - continue; - n++; - if (t->isServer) { - t->m_service = new TransporterService(new SocketAuthSimple("ndbd passwd")); - if(!socket_server.setup(t->m_service, t->m_r_port, 0)) - { - ndbout_c("Unable to setup transporter service port: %d!\n" - "Please check if the port is already used,\n" - "(perhaps a mgmt server is already running)", - m_service_port); - delete t->m_service; - return false; - } - } + if (m_transporter_interface.size() > 0 && nodeIdSpecified != true) + { + ndbout_c("TransporterRegistry::startReceiving: localNodeId not specified"); + return false; } -#endif - if (m_service_port != 0) { - - m_transporter_service = new TransporterService(new SocketAuthSimple("ndbd", "ndbd passwd")); - - if (nodeIdSpecified != true) { - ndbout_c("TransporterRegistry::startReceiving: localNodeId not specified"); + for (unsigned i= 0; i < m_transporter_interface.size(); i++) + { + Transporter_interface &t= m_transporter_interface[i]; + if (t.m_service_port == 0) + { + continue; + } + TransporterService *transporter_service = + new TransporterService(new SocketAuthSimple("ndbd", "ndbd passwd")); + if(!socket_server.setup(transporter_service, + t.m_service_port, t.m_interface)) + { + ndbout_c("Unable to setup transporter service port: %s:%d!\n" + "Please check if the port is already used,\n" + "(perhaps the node is already running)", + t.m_interface ? t.m_interface : "*", t.m_service_port); + delete transporter_service; return false; } - - //m_interface_name = "ndbd"; - m_interface_name = 0; - - if(!socket_server.setup(m_transporter_service, m_service_port, m_interface_name)) - { - ndbout_c("Unable to setup transporter service port: %d!\n" - "Please check if the port is already used,\n" - "(perhaps a mgmt server is already running)", - m_service_port); - delete m_transporter_service; - return false; - } - m_transporter_service->setTransporterRegistry(this); - } else - m_transporter_service= 0; - + transporter_service->setTransporterRegistry(this); + } return true; } @@ -1281,3 +1300,5 @@ NdbOut & operator <<(NdbOut & out, SignalHeader & sh){ out << "trace: " << (int)sh.theTrace << endl; return out; } + +template class Vector; diff --git a/ndb/src/common/util/Makefile.am b/ndb/src/common/util/Makefile.am index 678added01e..efb249dd330 100644 --- a/ndb/src/common/util/Makefile.am +++ b/ndb/src/common/util/Makefile.am @@ -9,7 +9,7 @@ libgeneral_la_SOURCES = \ NdbSqlUtil.cpp new.cpp \ uucode.c random.c getarg.c version.c \ strdup.c strlcat.c strlcpy.c \ - ConfigValues.cpp + ConfigValues.cpp ndb_init.c include $(top_srcdir)/ndb/config/common.mk.am include $(top_srcdir)/ndb/config/type_util.mk.am diff --git a/ndb/src/common/util/NdbSqlUtil.cpp b/ndb/src/common/util/NdbSqlUtil.cpp index 84a6f6e6c21..6e4e5919e43 100644 --- a/ndb/src/common/util/NdbSqlUtil.cpp +++ b/ndb/src/common/util/NdbSqlUtil.cpp @@ -176,10 +176,29 @@ NdbSqlUtil::getType(Uint32 typeId) return m_typeList[Type::Undefined]; } +const NdbSqlUtil::Type& +NdbSqlUtil::getTypeBinary(Uint32 typeId) +{ + switch (typeId) { + case Type::Char: + typeId = Type::Binary; + break; + case Type::Varchar: + typeId = Type::Varbinary; + break; + case Type::Text: + typeId = Type::Blob; + break; + default: + break; + } + return getType(typeId); +} + // compare int -NdbSqlUtil::cmpTinyint(const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size) +NdbSqlUtil::cmpTinyint(const void* info, const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size) { assert(full >= size && size > 0); union { Uint32 p[1]; Int8 v; } u1, u2; @@ -193,7 +212,7 @@ NdbSqlUtil::cmpTinyint(const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 s } int -NdbSqlUtil::cmpTinyunsigned(const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size) +NdbSqlUtil::cmpTinyunsigned(const void* info, const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size) { assert(full >= size && size > 0); union { Uint32 p[1]; Uint8 v; } u1, u2; @@ -207,7 +226,7 @@ NdbSqlUtil::cmpTinyunsigned(const Uint32* p1, const Uint32* p2, Uint32 full, Uin } int -NdbSqlUtil::cmpSmallint(const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size) +NdbSqlUtil::cmpSmallint(const void* info, const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size) { assert(full >= size && size > 0); union { Uint32 p[1]; Int16 v; } u1, u2; @@ -221,7 +240,7 @@ NdbSqlUtil::cmpSmallint(const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 } int -NdbSqlUtil::cmpSmallunsigned(const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size) +NdbSqlUtil::cmpSmallunsigned(const void* info, const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size) { assert(full >= size && size > 0); union { Uint32 p[1]; Uint16 v; } u1, u2; @@ -235,7 +254,7 @@ NdbSqlUtil::cmpSmallunsigned(const Uint32* p1, const Uint32* p2, Uint32 full, Ui } int -NdbSqlUtil::cmpMediumint(const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size) +NdbSqlUtil::cmpMediumint(const void* info, const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size) { assert(full >= size && size > 0); union { const Uint32* p; const unsigned char* v; } u1, u2; @@ -251,7 +270,7 @@ NdbSqlUtil::cmpMediumint(const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 } int -NdbSqlUtil::cmpMediumunsigned(const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size) +NdbSqlUtil::cmpMediumunsigned(const void* info, const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size) { assert(full >= size && size > 0); union { const Uint32* p; const unsigned char* v; } u1, u2; @@ -267,7 +286,7 @@ NdbSqlUtil::cmpMediumunsigned(const Uint32* p1, const Uint32* p2, Uint32 full, U } int -NdbSqlUtil::cmpInt(const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size) +NdbSqlUtil::cmpInt(const void* info, const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size) { assert(full >= size && size > 0); union { Uint32 p[1]; Int32 v; } u1, u2; @@ -281,7 +300,7 @@ NdbSqlUtil::cmpInt(const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size) } int -NdbSqlUtil::cmpUnsigned(const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size) +NdbSqlUtil::cmpUnsigned(const void* info, const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size) { assert(full >= size && size > 0); union { Uint32 p[1]; Uint32 v; } u1, u2; @@ -295,7 +314,7 @@ NdbSqlUtil::cmpUnsigned(const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 } int -NdbSqlUtil::cmpBigint(const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size) +NdbSqlUtil::cmpBigint(const void* info, const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size) { assert(full >= size && size > 0); if (size >= 2) { @@ -314,7 +333,7 @@ NdbSqlUtil::cmpBigint(const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 si } int -NdbSqlUtil::cmpBigunsigned(const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size) +NdbSqlUtil::cmpBigunsigned(const void* info, const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size) { assert(full >= size && size > 0); if (size >= 2) { @@ -333,7 +352,7 @@ NdbSqlUtil::cmpBigunsigned(const Uint32* p1, const Uint32* p2, Uint32 full, Uint } int -NdbSqlUtil::cmpFloat(const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size) +NdbSqlUtil::cmpFloat(const void* info, const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size) { assert(full >= size && size > 0); union { Uint32 p[1]; float v; } u1, u2; @@ -348,7 +367,7 @@ NdbSqlUtil::cmpFloat(const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 siz } int -NdbSqlUtil::cmpDouble(const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size) +NdbSqlUtil::cmpDouble(const void* info, const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size) { assert(full >= size && size > 0); if (size >= 2) { @@ -368,7 +387,7 @@ NdbSqlUtil::cmpDouble(const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 si } int -NdbSqlUtil::cmpDecimal(const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size) +NdbSqlUtil::cmpDecimal(const void* info, const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size) { assert(full >= size && size > 0); // not used by MySQL or NDB @@ -377,27 +396,34 @@ NdbSqlUtil::cmpDecimal(const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 s } int -NdbSqlUtil::cmpChar(const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size) +NdbSqlUtil::cmpChar(const void* info, const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size) { - assert(full >= size && size > 0); + // collation does not work on prefix for some charsets + assert(full == size && size > 0); /* - * Char is blank-padded to length and null-padded to word size. There - * is no terminator so we compare the full values. + * Char is blank-padded to length and null-padded to word size. */ - union { const Uint32* p; const char* v; } u1, u2; + union { const Uint32* p; const uchar* v; } u1, u2; u1.p = p1; u2.p = p2; - int k = memcmp(u1.v, u2.v, size << 2); - return k < 0 ? -1 : k > 0 ? +1 : full == size ? 0 : CmpUnknown; + // not const in MySQL + CHARSET_INFO* cs = (CHARSET_INFO*)(info); + // length in bytes including null padding to Uint32 + uint l1 = (full << 2); + int k = (*cs->coll->strnncollsp)(cs, u1.v, l1, u2.v, l1); + return k < 0 ? -1 : k > 0 ? +1 : 0; } int -NdbSqlUtil::cmpVarchar(const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size) +NdbSqlUtil::cmpVarchar(const void* info, const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size) { assert(full >= size && size > 0); /* * Varchar is not allowed to contain a null byte and the value is * null-padded. Therefore comparison does not need to use the length. + * + * Not used before MySQL 5.0. Format is likely to change. Handle + * only binary collation for now. */ union { const Uint32* p; const char* v; } u1, u2; u1.p = p1; @@ -408,7 +434,7 @@ NdbSqlUtil::cmpVarchar(const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 s } int -NdbSqlUtil::cmpBinary(const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size) +NdbSqlUtil::cmpBinary(const void* info, const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size) { assert(full >= size && size > 0); /* @@ -422,12 +448,14 @@ NdbSqlUtil::cmpBinary(const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 si } int -NdbSqlUtil::cmpVarbinary(const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size) +NdbSqlUtil::cmpVarbinary(const void* info, const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size) { assert(full >= size && size > 0); /* * Binary data of variable length padded with nulls. The comparison * does not need to use the length. + * + * Not used before MySQL 5.0. Format is likely to change. */ union { const Uint32* p; const unsigned char* v; } u1, u2; u1.p = p1; @@ -438,11 +466,13 @@ NdbSqlUtil::cmpVarbinary(const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 } int -NdbSqlUtil::cmpDatetime(const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size) +NdbSqlUtil::cmpDatetime(const void* info, const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size) { assert(full >= size && size > 0); /* * Datetime is CC YY MM DD hh mm ss \0 + * + * Not used via MySQL. */ union { const Uint32* p; const unsigned char* v; } u1, u2; u1.p = p1; @@ -459,11 +489,13 @@ NdbSqlUtil::cmpDatetime(const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 } int -NdbSqlUtil::cmpTimespec(const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size) +NdbSqlUtil::cmpTimespec(const void* info, const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size) { assert(full >= size && size > 0); /* * Timespec is CC YY MM DD hh mm ss \0 NN NN NN NN + * + * Not used via MySQL. */ union { const Uint32* p; const unsigned char* v; } u1, u2; u1.p = p1; @@ -490,12 +522,11 @@ NdbSqlUtil::cmpTimespec(const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 } int -NdbSqlUtil::cmpBlob(const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size) +NdbSqlUtil::cmpBlob(const void* info, const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size) { assert(full >= size && size > 0); /* - * Blob comparison is on the inline bytes. Except for larger header - * the format is like Varbinary. + * Blob comparison is on the inline bytes (null padded). */ const unsigned head = NDB_BLOB_HEAD_SIZE; // skip blob head @@ -510,25 +541,107 @@ NdbSqlUtil::cmpBlob(const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size } int -NdbSqlUtil::cmpText(const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size) +NdbSqlUtil::cmpText(const void* info, const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size) { - assert(full >= size && size > 0); + // collation does not work on prefix for some charsets + assert(full == size && size > 0); /* - * Text comparison is on the inline bytes. Except for larger header - * the format is like Varchar. + * Text comparison is on the inline bytes (blank padded). Currently + * not supported for multi-byte charsets. */ const unsigned head = NDB_BLOB_HEAD_SIZE; // skip blob head if (size >= head + 1) { - union { const Uint32* p; const char* v; } u1, u2; + union { const Uint32* p; const uchar* v; } u1, u2; u1.p = p1 + head; u2.p = p2 + head; - int k = memcmp(u1.v, u2.v, (size - head) << 2); - return k < 0 ? -1 : k > 0 ? +1 : full == size ? 0 : CmpUnknown; + // not const in MySQL + CHARSET_INFO* cs = (CHARSET_INFO*)(info); + // length in bytes including null padding to Uint32 + uint l1 = (full << 2); + int k = (*cs->coll->strnncollsp)(cs, u1.v, l1, u2.v, l1); + return k < 0 ? -1 : k > 0 ? +1 : 0; } return CmpUnknown; } +// check charset + +bool +NdbSqlUtil::usable_in_pk(Uint32 typeId, const void* info) +{ + const Type& type = getType(typeId); + switch (type.m_typeId) { + case Type::Undefined: + break; + case Type::Char: + { + const CHARSET_INFO *cs = (const CHARSET_INFO*)info; + return + cs != 0 && + cs->cset != 0 && + cs->coll != 0 && + cs->coll->strnxfrm != 0 && + cs->strxfrm_multiply == 1; // current limitation + } + break; + case Type::Varchar: + return true; // Varchar not used via MySQL + case Type::Blob: + case Type::Text: + break; + default: + return true; + } + return false; +} + +bool +NdbSqlUtil::usable_in_hash_index(Uint32 typeId, const void* info) +{ + return usable_in_pk(typeId, info); +} + +bool +NdbSqlUtil::usable_in_ordered_index(Uint32 typeId, const void* info) +{ + const Type& type = getType(typeId); + switch (type.m_typeId) { + case Type::Undefined: + break; + case Type::Char: + { + const CHARSET_INFO *cs = (const CHARSET_INFO*)info; + return + cs != 0 && + cs->cset != 0 && + cs->coll != 0 && + cs->coll->strnxfrm != 0 && + cs->coll->strnncollsp != 0 && + cs->strxfrm_multiply == 1; // current limitation + } + break; + case Type::Varchar: + return true; // Varchar not used via MySQL + case Type::Text: + { + const CHARSET_INFO *cs = (const CHARSET_INFO*)info; + return + cs != 0 && + cs->mbmaxlen == 1 && // extra limitation + cs->cset != 0 && + cs->coll != 0 && + cs->coll->strnxfrm != 0 && + cs->coll->strnncollsp != 0 && + cs->strxfrm_multiply == 1; // current limitation + } + break; + default: + return true; + } + return false; +} + #ifdef NDB_SQL_UTIL_TEST #include @@ -556,6 +669,7 @@ const Testcase testcase[] = { int main(int argc, char** argv) { + ndb_init(); // for charsets unsigned count = argc > 1 ? atoi(argv[1]) : 1000000; ndbout_c("count = %u", count); assert(count != 0); diff --git a/ndb/src/common/util/SocketServer.cpp b/ndb/src/common/util/SocketServer.cpp index 0cc06a54496..c3cffa1399b 100644 --- a/ndb/src/common/util/SocketServer.cpp +++ b/ndb/src/common/util/SocketServer.cpp @@ -16,6 +16,7 @@ #include +#include #include @@ -46,7 +47,7 @@ SocketServer::~SocketServer() { } bool -SocketServer::tryBind(unsigned short port, const char * intface) const { +SocketServer::tryBind(unsigned short port, const char * intface) { struct sockaddr_in servaddr; memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET; @@ -83,7 +84,8 @@ bool SocketServer::setup(SocketServer::Service * service, unsigned short port, const char * intface){ - + DBUG_ENTER("SocketServer::setup"); + DBUG_PRINT("enter",("interface=%s, port=%d", intface, port)); struct sockaddr_in servaddr; memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET; @@ -92,36 +94,44 @@ SocketServer::setup(SocketServer::Service * service, if(intface != 0){ if(Ndb_getInAddr(&servaddr.sin_addr, intface)) - return false; + DBUG_RETURN(false); } const NDB_SOCKET_TYPE sock = socket(AF_INET, SOCK_STREAM, 0); if (sock == NDB_INVALID_SOCKET) { - return false; + DBUG_PRINT("error",("socket() - %d - %s", + errno, strerror(errno))); + DBUG_RETURN(false); } const int on = 1; if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char*)&on, sizeof(on)) == -1) { + DBUG_PRINT("error",("getsockopt() - %d - %s", + errno, strerror(errno))); NDB_CLOSE_SOCKET(sock); - return false; + DBUG_RETURN(false); } if (bind(sock, (struct sockaddr*) &servaddr, sizeof(servaddr)) == -1) { + DBUG_PRINT("error",("bind() - %d - %s", + errno, strerror(errno))); NDB_CLOSE_SOCKET(sock); - return false; + DBUG_RETURN(false); } if (listen(sock, m_maxSessions) == -1){ + DBUG_PRINT("error",("listen() - %d - %s", + errno, strerror(errno))); NDB_CLOSE_SOCKET(sock); - return false; + DBUG_RETURN(false); } ServiceInstance i; i.m_socket = sock; i.m_service = service; m_services.push_back(i); - return true; + DBUG_RETURN(true); } void @@ -177,8 +187,9 @@ void* socketServerThread_C(void* _ss){ SocketServer * ss = (SocketServer *)_ss; + my_thread_init(); ss->doRun(); - + my_thread_end(); NdbThread_Exit(0); return 0; } @@ -287,8 +298,10 @@ void* sessionThread_C(void* _sc){ SocketServer::Session * si = (SocketServer::Session *)_sc; + my_thread_init(); if(!transfer(si->m_socket)){ si->m_stopped = true; + my_thread_end(); NdbThread_Exit(0); return 0; } @@ -301,6 +314,7 @@ sessionThread_C(void* _sc){ } si->m_stopped = true; + my_thread_end(); NdbThread_Exit(0); return 0; } diff --git a/ndb/src/common/debugger/LogLevel.cpp b/ndb/src/common/util/ndb_init.c similarity index 67% rename from ndb/src/common/debugger/LogLevel.cpp rename to ndb/src/common/util/ndb_init.c index f9e2f318432..f3aa734d7f9 100644 --- a/ndb/src/common/debugger/LogLevel.cpp +++ b/ndb/src/common/util/ndb_init.c @@ -14,17 +14,22 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include +#include +#include -const LogLevel::LogLevelCategoryName LogLevel::LOGLEVEL_CATEGORY_NAME[] = { - { "LogLevelStartup" }, - { "LogLevelShutdown" }, - { "LogLevelStatistic" }, - { "LogLevelCheckpoint" }, - { "LogLevelNodeRestart" }, - { "LogLevelConnection" }, - { "LogLevelError" }, - { "LogLevelWarning" }, - { "LogLevelInfo" }, - { "LogLevelGrep" } -}; +int +ndb_init() +{ + if (my_init()) { + const char* err = "my_init() failed - exit\n"; + write(2, err, strlen(err)); + exit(1); + } + return 0; +} + +void +ndb_end(int flags) +{ + my_end(flags); +} diff --git a/ndb/src/cw/cpcd/APIService.cpp b/ndb/src/cw/cpcd/APIService.cpp index 46b043c7004..de0e40cebfc 100644 --- a/ndb/src/cw/cpcd/APIService.cpp +++ b/ndb/src/cw/cpcd/APIService.cpp @@ -47,7 +47,7 @@ ParserRow::IgnoreMinMax, \ 0, 0, \ fun, \ - desc } + desc, 0 } #define CPCD_ARG(name, type, opt, desc) \ { name, \ @@ -58,7 +58,7 @@ ParserRow::IgnoreMinMax, \ 0, 0, \ 0, \ - desc } + desc, 0 } #define CPCD_ARG2(name, type, opt, min, max, desc) \ { name, \ @@ -69,7 +69,7 @@ ParserRow::IgnoreMinMax, \ min, max, \ 0, \ - desc } + desc, 0 } #define CPCD_END() \ { 0, \ @@ -80,7 +80,7 @@ ParserRow::IgnoreMinMax, \ 0, 0, \ 0, \ - 0 } + 0, 0 } #define CPCD_CMD_ALIAS(name, realName, fun) \ { name, \ @@ -91,7 +91,7 @@ ParserRow::IgnoreMinMax, \ 0, 0, \ 0, \ - 0 } + 0, 0 } #define CPCD_ARG_ALIAS(name, realName, fun) \ { name, \ @@ -102,7 +102,7 @@ ParserRow::IgnoreMinMax, \ 0, 0, \ 0, \ - 0 } + 0, 0 } const ParserRow commands[] = diff --git a/ndb/src/cw/cpcd/CPCD.cpp b/ndb/src/cw/cpcd/CPCD.cpp index 44db10422b9..bc9f350755f 100644 --- a/ndb/src/cw/cpcd/CPCD.cpp +++ b/ndb/src/cw/cpcd/CPCD.cpp @@ -378,7 +378,7 @@ CPCD::getProcessList() { } void -CPCD::RequestStatus::err(enum RequestStatusCode status, char *msg) { +CPCD::RequestStatus::err(enum RequestStatusCode status, const char *msg) { m_status = status; snprintf(m_errorstring, sizeof(m_errorstring), "%s", msg); } diff --git a/ndb/src/cw/cpcd/CPCD.hpp b/ndb/src/cw/cpcd/CPCD.hpp index 4a7cab23bab..a5c0bef1dac 100644 --- a/ndb/src/cw/cpcd/CPCD.hpp +++ b/ndb/src/cw/cpcd/CPCD.hpp @@ -91,7 +91,7 @@ public: RequestStatus() { m_status = OK; m_errorstring[0] = '\0'; }; /** @brief Sets an errorcode and a printable message */ - void err(enum RequestStatusCode, char *); + void err(enum RequestStatusCode, const char *); /** @brief Returns the error message */ char *getErrMsg() { return m_errorstring; }; diff --git a/ndb/src/cw/cpcd/Makefile.am b/ndb/src/cw/cpcd/Makefile.am index e276d1a766d..6af44a359fc 100644 --- a/ndb/src/cw/cpcd/Makefile.am +++ b/ndb/src/cw/cpcd/Makefile.am @@ -7,7 +7,7 @@ LDADD_LOC = \ $(top_builddir)/ndb/src/libndbclient.la \ $(top_builddir)/dbug/libdbug.a \ $(top_builddir)/mysys/libmysys.a \ - $(top_builddir)/strings/libmystrings.a + $(top_builddir)/strings/libmystrings.a @NDB_SCI_LIBS@ include $(top_srcdir)/ndb/config/common.mk.am include $(top_srcdir)/ndb/config/type_util.mk.am diff --git a/ndb/src/cw/cpcd/main.cpp b/ndb/src/cw/cpcd/main.cpp index 913c31de1f7..207b81bfa89 100644 --- a/ndb/src/cw/cpcd/main.cpp +++ b/ndb/src/cw/cpcd/main.cpp @@ -28,12 +28,12 @@ #include "common.hpp" -static char *work_dir = CPCD_DEFAULT_WORK_DIR; +static const char *work_dir = CPCD_DEFAULT_WORK_DIR; static int port = CPCD_DEFAULT_TCP_PORT; static int use_syslog = 0; -static char *logfile = NULL; -static char *config_file = CPCD_DEFAULT_CONFIG_FILE; -static char *user = 0; +static const char *logfile = NULL; +static const char *config_file = CPCD_DEFAULT_CONFIG_FILE; +static const char *user = 0; static struct getargs args[] = { { "work-dir", 'w', arg_string, &work_dir, diff --git a/ndb/src/kernel/Makefile.am b/ndb/src/kernel/Makefile.am index a6be3244b41..493ab4f9982 100644 --- a/ndb/src/kernel/Makefile.am +++ b/ndb/src/kernel/Makefile.am @@ -55,7 +55,7 @@ LDADD += \ $(top_builddir)/ndb/src/common/util/libgeneral.la \ $(top_builddir)/dbug/libdbug.a \ $(top_builddir)/mysys/libmysys.a \ - $(top_builddir)/strings/libmystrings.a + $(top_builddir)/strings/libmystrings.a @NDB_SCI_LIBS@ # Don't update the files from bitkeeper %::SCCS/s.% diff --git a/ndb/src/kernel/blocks/backup/Backup.cpp b/ndb/src/kernel/blocks/backup/Backup.cpp index b3e9ff735ac..08a8bf83e20 100644 --- a/ndb/src/kernel/blocks/backup/Backup.cpp +++ b/ndb/src/kernel/blocks/backup/Backup.cpp @@ -40,6 +40,7 @@ #include #include #include +#include #include @@ -944,6 +945,13 @@ Backup::sendBackupRef(BlockReference senderRef, Signal *signal, ref->errorCode = errorCode; ref->masterRef = numberToRef(BACKUP, getMasterNodeId()); sendSignal(senderRef, GSN_BACKUP_REF, signal, BackupRef::SignalLength, JBB); + + if(errorCode != BackupRef::IAmNotMaster){ + signal->theData[0] = EventReport::BackupFailedToStart; + signal->theData[1] = senderRef; + signal->theData[2] = errorCode; + sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 3, JBB); + } } void @@ -1226,7 +1234,13 @@ Backup::defineBackupReply(Signal* signal, BackupRecordPtr ptr, Uint32 nodeId) conf->nodes = ptr.p->nodes; sendSignal(ptr.p->clientRef, GSN_BACKUP_CONF, signal, BackupConf::SignalLength, JBB); - + + signal->theData[0] = EventReport::BackupStarted; + signal->theData[1] = ptr.p->clientRef; + signal->theData[2] = ptr.p->backupId; + ptr.p->nodes.copyto(NdbNodeBitmask::Size, signal->theData+3); + sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 3+NdbNodeBitmask::Size, JBB); + ptr.p->masterData.state.setState(DEFINED); /** * Prepare Trig @@ -2069,6 +2083,18 @@ Backup::stopBackupReply(Signal* signal, BackupRecordPtr ptr, Uint32 nodeId) rep->nodes = ptr.p->nodes; sendSignal(ptr.p->clientRef, GSN_BACKUP_COMPLETE_REP, signal, BackupCompleteRep::SignalLength, JBB); + + signal->theData[0] = EventReport::BackupCompleted; + signal->theData[1] = ptr.p->clientRef; + signal->theData[2] = ptr.p->backupId; + signal->theData[3] = ptr.p->startGCP; + signal->theData[4] = ptr.p->stopGCP; + signal->theData[5] = ptr.p->noOfBytes; + signal->theData[6] = ptr.p->noOfRecords; + signal->theData[7] = ptr.p->noOfLogBytes; + signal->theData[8] = ptr.p->noOfLogRecords; + ptr.p->nodes.copyto(NdbNodeBitmask::Size, signal->theData+9); + sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 9+NdbNodeBitmask::Size, JBB); } /***************************************************************************** @@ -2259,6 +2285,12 @@ Backup::masterSendAbortBackup(Signal* signal, BackupRecordPtr ptr) rep->reason = ptr.p->errorCode; sendSignal(ptr.p->clientRef, GSN_BACKUP_ABORT_REP, signal, BackupAbortRep::SignalLength, JBB); + + signal->theData[0] = EventReport::BackupAborted; + signal->theData[1] = ptr.p->clientRef; + signal->theData[2] = ptr.p->backupId; + signal->theData[3] = ptr.p->errorCode; + sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 4, JBB); }//if // ptr.p->masterData.state.setState(INITIAL); diff --git a/ndb/src/kernel/blocks/backup/read.cpp b/ndb/src/kernel/blocks/backup/read.cpp index 921c352ea13..89cc08ee9de 100644 --- a/ndb/src/kernel/blocks/backup/read.cpp +++ b/ndb/src/kernel/blocks/backup/read.cpp @@ -48,6 +48,7 @@ static Uint32 logEntryNo; int main(int argc, const char * argv[]){ + ndb_init(); if(argc <= 1){ printf("Usage: %s ", argv[0]); exit(1); diff --git a/ndb/src/kernel/blocks/backup/restore/Makefile.am b/ndb/src/kernel/blocks/backup/restore/Makefile.am index eef5bc5a203..16550f13546 100644 --- a/ndb/src/kernel/blocks/backup/restore/Makefile.am +++ b/ndb/src/kernel/blocks/backup/restore/Makefile.am @@ -7,7 +7,7 @@ LDADD_LOC = \ $(top_builddir)/ndb/src/libndbclient.la \ $(top_builddir)/dbug/libdbug.a \ $(top_builddir)/mysys/libmysys.a \ - $(top_builddir)/strings/libmystrings.a + $(top_builddir)/strings/libmystrings.a @NDB_SCI_LIBS@ include $(top_srcdir)/ndb/config/common.mk.am diff --git a/ndb/src/kernel/blocks/backup/restore/main.cpp b/ndb/src/kernel/blocks/backup/restore/main.cpp index a330aa51373..5708415c61e 100644 --- a/ndb/src/kernel/blocks/backup/restore/main.cpp +++ b/ndb/src/kernel/blocks/backup/restore/main.cpp @@ -206,6 +206,7 @@ free_data_callback() int main(int argc, const char** argv) { + ndb_init(); if (!readArguments(argc, argv)) { return -1; @@ -331,7 +332,7 @@ main(int argc, const char** argv) for (i= 0; i < g_consumers.size(); i++) g_consumers[i]->endOfTuples(); - + RestoreLogIterator logIter(metaData); if (!logIter.readHeader()) { @@ -357,7 +358,7 @@ main(int argc, const char** argv) } } clearConsumers(); - return 1; + return 0; } // main template class Vector; diff --git a/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp b/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp index e2085eb612c..234d832655c 100644 --- a/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp +++ b/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp @@ -97,7 +97,7 @@ Cmvmi::Cmvmi(const Configuration & conf) : const ndb_mgm_configuration_iterator * db = theConfig.getOwnConfigIterator(); for(unsigned j = 0; jnoOfEntries; i++){ - category = (LogLevel::EventCategory)llOrd->theCategories[i]; - level = llOrd->theLevels[i]; - + category = (LogLevel::EventCategory)(llOrd->theData[i] >> 16); + level = llOrd->theData[i] & 0xFFFF; + clogLevel.setLogLevel(category, level); } }//execSET_LOGLEVELORD() @@ -196,10 +196,10 @@ void Cmvmi::execEVENT_REP(Signal* signal) Uint32 threshold = 16; LogLevel::EventCategory eventCategory = (LogLevel::EventCategory)0; - for(unsigned int i = 0; i< EventLogger::matrixSize; i++){ - if(EventLogger::matrix[i].eventType == eventType){ - eventCategory = EventLogger::matrix[i].eventCategory; - threshold = EventLogger::matrix[i].threshold; + for(unsigned int i = 0; i< EventLoggerBase::matrixSize; i++){ + if(EventLoggerBase::matrix[i].eventType == eventType){ + eventCategory = EventLoggerBase::matrix[i].eventCategory; + threshold = EventLoggerBase::matrix[i].threshold; break; } } @@ -250,17 +250,7 @@ Cmvmi::execEVENT_SUBSCRIBE_REQ(Signal * signal){ sendSignal(subReq->blockRef, GSN_EVENT_SUBSCRIBE_REF, signal, 1, JBB); return; } - /** - * If it's a new subscription, clear the loglevel - * - * Clear only if noOfEntries is 0, this is needed beacuse we set - * the default loglevels for the MGMT nodes during the inital connect phase. - * See reportConnected(). - */ - if (subReq->noOfEntries == 0){ - ptr.p->logLevel.clear(); - } - + ptr.p->logLevel.clear(); ptr.p->blockRef = subReq->blockRef; } @@ -276,10 +266,9 @@ Cmvmi::execEVENT_SUBSCRIBE_REQ(Signal * signal){ LogLevel::EventCategory category; Uint32 level = 0; for(Uint32 i = 0; inoOfEntries; i++){ - category = (LogLevel::EventCategory)subReq->theCategories[i]; - level = subReq->theLevels[i]; - ptr.p->logLevel.setLogLevel(category, - level); + category = (LogLevel::EventCategory)(subReq->theData[i] >> 16); + level = subReq->theData[i] & 0xFFFF; + ptr.p->logLevel.setLogLevel(category, level); } } @@ -384,11 +373,6 @@ void Cmvmi::execCLOSE_COMREQ(Signal* signal) globalTransporterRegistry.setIOState(i, HaltIO); globalTransporterRegistry.do_disconnect(i); - - /** - * Cancel possible event subscription - */ - cancelSubscription(i); } } if (failNo != 0) { @@ -494,6 +478,8 @@ void Cmvmi::execDISCONNECT_REP(Signal *signal) globalTransporterRegistry.do_connect(hostId); } + cancelSubscription(hostId); + signal->theData[0] = EventReport::Disconnected; signal->theData[1] = hostId; sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB); @@ -539,20 +525,6 @@ void Cmvmi::execCONNECT_REP(Signal *signal){ if(type == NodeInfo::MGM){ jam(); globalTransporterRegistry.setIOState(hostId, NoHalt); - - EventSubscribeReq* dst = (EventSubscribeReq *)&signal->theData[0]; - - for (Uint32 i = 0; i < EventLogger::defEventLogMatrixSize; i++) { - dst->theCategories[i] = EventLogger::defEventLogMatrix[i].eventCategory; - dst->theLevels[i] = EventLogger::defEventLogMatrix[i].threshold; - } - - dst->noOfEntries = EventLogger::defEventLogMatrixSize; - /* The BlockNumber is hardcoded as 1 in MgmtSrvr */ - dst->blockRef = numberToRef(MIN_API_BLOCK_NO, hostId); - - execEVENT_SUBSCRIBE_REQ(signal); - } //------------------------------------------ diff --git a/ndb/src/kernel/blocks/dbdict/Dbdict.cpp b/ndb/src/kernel/blocks/dbdict/Dbdict.cpp index 7126842459e..d1a8128ea7f 100644 --- a/ndb/src/kernel/blocks/dbdict/Dbdict.cpp +++ b/ndb/src/kernel/blocks/dbdict/Dbdict.cpp @@ -15,6 +15,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include +#include #define DBDICT_C #include "Dbdict.hpp" @@ -2866,8 +2867,6 @@ Dbdict::execALTER_TABLE_REQ(Signal* signal) if(parseRecord.errorCode != 0){ jam(); c_opCreateTable.release(alterTabPtr); - parseRecord.tablePtr.p->tabState = TableRecord::NOT_DEFINED; - releaseTableObject(parseRecord.tablePtr.i, false); alterTableRef(signal, req, (AlterTableRef::ErrorCode) parseRecord.errorCode, aParseRecord); @@ -3052,8 +3051,6 @@ Dbdict::execALTER_TAB_REQ(Signal * signal) if(parseRecord.errorCode != 0){ jam(); c_opCreateTable.release(alterTabPtr); - parseRecord.tablePtr.p->tabState = TableRecord::NOT_DEFINED; - releaseTableObject(parseRecord.tablePtr.i, false); alterTabRef(signal, req, (AlterTableRef::ErrorCode) parseRecord.errorCode, aParseRecord); @@ -3438,7 +3435,6 @@ Dbdict::execALTER_TAB_CONF(Signal * signal){ // Release resources TableRecordPtr tabPtr; c_tableRecordPool.getPtr(tabPtr, regAlterTabPtr->m_tablePtrI); - tabPtr.p->tabState = TableRecord::NOT_DEFINED; releaseTableObject(tabPtr.i, false); c_opCreateTable.release(alterTabPtr); c_blockState = BS_IDLE; @@ -3479,12 +3475,19 @@ int Dbdict::handleAlterTab(AlterTabReq * req, jam(); // Table rename // Remove from hashtable +#ifdef VM_TRACE + TableRecordPtr tmp; + ndbrequire(c_tableRecordHash.find(tmp, *origTablePtr.p)); +#endif c_tableRecordHash.remove(origTablePtr); strcpy(regAlterTabPtr->previousTableName, origTablePtr.p->tableName); strcpy(origTablePtr.p->tableName, newTablePtr.p->tableName); // Set new schema version origTablePtr.p->tableVersion = newTablePtr.p->tableVersion; // Put it back +#ifdef VM_TRACE + ndbrequire(!c_tableRecordHash.find(tmp, *origTablePtr.p)); +#endif c_tableRecordHash.add(origTablePtr); return 0; @@ -3505,12 +3508,19 @@ void Dbdict::revertAlterTable(Signal * signal, TableRecordPtr tablePtr; c_tableRecordPool.getPtr(tablePtr, tableId); // Remove from hashtable +#ifdef VM_TRACE + TableRecordPtr tmp; + ndbrequire(c_tableRecordHash.find(tmp, * tablePtr.p)); +#endif c_tableRecordHash.remove(tablePtr); // Restore name strcpy(tablePtr.p->tableName, regAlterTabPtr->previousTableName); // Revert schema version tablePtr.p->tableVersion = tablePtr.p->tableVersion - 1; // Put it back +#ifdef VM_TRACE + ndbrequire(!c_tableRecordHash.find(tmp, * tablePtr.p)); +#endif c_tableRecordHash.add(tablePtr); return; @@ -3572,7 +3582,6 @@ Dbdict::alterTab_writeTableConf(Signal* signal, jam(); // Release resources c_tableRecordPool.getPtr(tabPtr, regAlterTabPtr->m_tablePtrI); - tabPtr.p->tabState = TableRecord::NOT_DEFINED; releaseTableObject(tabPtr.i, false); c_opCreateTable.release(alterTabPtr); c_blockState = BS_IDLE; @@ -4100,6 +4109,8 @@ Dbdict::execADD_FRAGREQ(Signal* signal) { req->noOfKeyAttr = tabPtr.p->noOfPrimkey; req->noOfNewAttr = 0; + // noOfCharsets passed to TUP in upper half + req->noOfNewAttr |= (tabPtr.p->noOfCharsets << 16); req->checksumIndicator = 1; req->noOfAttributeGroups = 1; req->GCPIndicator = 0; @@ -4161,6 +4172,8 @@ Dbdict::sendLQHADDATTRREQ(Signal* signal, entry.attrId = attrPtr.p->attributeId; entry.attrDescriptor = attrPtr.p->attributeDescriptor; entry.extTypeInfo = attrPtr.p->extType; + // charset number passed to TUP, TUX in upper half + entry.extTypeInfo |= (attrPtr.p->extPrecision & ~0xFFFF); if (tabPtr.p->isIndex()) { Uint32 primaryAttrId; if (attrPtr.p->nextAttrInTable != RNIL) { @@ -4456,7 +4469,6 @@ Dbdict::createTab_dropComplete(Signal* signal, TableRecordPtr tabPtr; c_tableRecordPool.getPtr(tabPtr, createTabPtr.p->m_tablePtrI); - tabPtr.p->tabState = TableRecord::NOT_DEFINED; releaseTableObject(tabPtr.i); PageRecordPtr pagePtr; @@ -4540,6 +4552,15 @@ void Dbdict::handleTabInfoInit(SimpleProperties::Reader & it, parseP->errorLine = __LINE__; return; } + + if(parseP->requestType == DictTabInfo::AlterTableFromAPI) + { + ndbrequire(!checkExist); + } + if(!checkExist) + { + ndbrequire(parseP->requestType == DictTabInfo::AlterTableFromAPI); + } /* ---------------------------------------------------------------- */ // Verify that table name is an allowed table name. @@ -4554,14 +4575,15 @@ void Dbdict::handleTabInfoInit(SimpleProperties::Reader & it, TableRecordPtr tablePtr; c_tableRecordHash.find(tablePtr, keyRecord); - - if (checkExist) + + if (checkExist){ jam(); /* ---------------------------------------------------------------- */ // Check if table already existed. /* ---------------------------------------------------------------- */ tabRequire(tablePtr.i == RNIL, CreateTableRef::TableAlreadyExist); - + } + switch (parseP->requestType) { case DictTabInfo::CreateTableFromAPI: { jam(); @@ -4634,12 +4656,13 @@ void Dbdict::handleTabInfoInit(SimpleProperties::Reader & it, strcpy(tablePtr.p->tableName, keyRecord.tableName); if (parseP->requestType != DictTabInfo::AlterTableFromAPI) { jam(); +#ifdef VM_TRACE + ndbout_c("Dbdict: name=%s,id=%u", tablePtr.p->tableName, tablePtr.i); + TableRecordPtr tmp; + ndbrequire(!c_tableRecordHash.find(tmp, * tablePtr.p)); +#endif c_tableRecordHash.add(tablePtr); } - -#ifdef VM_TRACE - ndbout_c("Dbdict: name=%s,id=%u", tablePtr.p->tableName, tablePtr.i); -#endif //tablePtr.p->noOfPrimkey = tableDesc.NoOfKeyAttr; //tablePtr.p->noOfNullAttr = tableDesc.NoOfNullable; @@ -4678,11 +4701,12 @@ void Dbdict::handleTabInfoInit(SimpleProperties::Reader & it, handleTabInfo(it, parseP); - if(parseP->errorCode != 0){ + if(parseP->errorCode != 0) + { /** * Release table */ - releaseTableObject(tablePtr.i); + releaseTableObject(tablePtr.i, checkExist); } }//handleTabInfoInit() @@ -4697,6 +4721,8 @@ void Dbdict::handleTabInfo(SimpleProperties::Reader & it, Uint32 keyLength = 0; Uint32 attrCount = tablePtr.p->noOfAttributes; Uint32 nullCount = 0; + Uint32 noOfCharsets = 0; + Uint16 charsets[128]; Uint32 recordLength = 0; AttributeRecordPtr attrPtr; c_attributeRecordHash.removeAll(); @@ -4751,6 +4777,31 @@ void Dbdict::handleTabInfo(SimpleProperties::Reader & it, attrPtr.p->extPrecision = attrDesc.AttributeExtPrecision; attrPtr.p->extScale = attrDesc.AttributeExtScale; attrPtr.p->extLength = attrDesc.AttributeExtLength; + // charset in upper half of precision + unsigned csNumber = (attrPtr.p->extPrecision >> 16); + if (csNumber != 0) { + CHARSET_INFO* cs = get_charset(csNumber, MYF(0)); + if (cs == NULL) { + parseP->errorCode = CreateTableRef::InvalidCharset; + parseP->errorLine = __LINE__; + return; + } + unsigned i = 0; + while (i < noOfCharsets) { + if (charsets[i] == csNumber) + break; + i++; + } + if (i == noOfCharsets) { + noOfCharsets++; + if (noOfCharsets > sizeof(charsets)/sizeof(charsets[0])) { + parseP->errorCode = CreateTableRef::InvalidFormat; + parseP->errorLine = __LINE__; + return; + } + charsets[i] = csNumber; + } + } /** * Ignore incoming old-style type and recompute it. @@ -4814,6 +4865,7 @@ void Dbdict::handleTabInfo(SimpleProperties::Reader & it, tablePtr.p->noOfPrimkey = keyCount; tablePtr.p->noOfNullAttr = nullCount; + tablePtr.p->noOfCharsets = noOfCharsets; tablePtr.p->tupKeyLength = keyLength; tabRequire(recordLength<= MAX_TUPLE_SIZE_IN_WORDS, @@ -5465,7 +5517,14 @@ void Dbdict::releaseTableObject(Uint32 tableId, bool removeFromHash) AttributeRecordPtr attrPtr; c_tableRecordPool.getPtr(tablePtr, tableId); if (removeFromHash) + { +#ifdef VM_TRACE + TableRecordPtr tmp; + ndbrequire(c_tableRecordHash.find(tmp, * tablePtr.p)); +#endif c_tableRecordHash.remove(tablePtr); + } + tablePtr.p->tabState = TableRecord::NOT_DEFINED; Uint32 nextAttrRecord = tablePtr.p->firstAttribute; while (nextAttrRecord != RNIL) { @@ -6317,6 +6376,8 @@ Dbdict::createIndex_toCreateTable(Signal* signal, OpCreateIndexPtr opPtr) w.add(DictTabInfo::AttributeStoredInd, (Uint32)DictTabInfo::Stored); // ext type overrides w.add(DictTabInfo::AttributeExtType, aRec->extType); + w.add(DictTabInfo::AttributeExtPrecision, aRec->extPrecision); + w.add(DictTabInfo::AttributeExtScale, aRec->extScale); w.add(DictTabInfo::AttributeExtLength, aRec->extLength); w.add(DictTabInfo::AttributeEnd, (Uint32)true); } @@ -6510,6 +6571,8 @@ Dbdict::execDROP_INDX_REQ(Signal* signal) jamEntry(); DropIndxReq* const req = (DropIndxReq*)signal->getDataPtrSend(); OpDropIndexPtr opPtr; + + int err = DropIndxRef::BadRequestType; const Uint32 senderRef = signal->senderBlockRef(); const DropIndxReq::RequestType requestType = req->getRequestType(); if (requestType == DropIndxReq::RT_USER) { @@ -6524,6 +6587,34 @@ Dbdict::execDROP_INDX_REQ(Signal* signal) return; } // forward initial request plus operation key to all + Uint32 indexId= req->getIndexId(); + Uint32 indexVersion= req->getIndexVersion(); + TableRecordPtr tmp; + int res = getMetaTablePtr(tmp, indexId, indexVersion); + switch(res){ + case MetaData::InvalidArgument: + err = DropIndxRef::IndexNotFound; + goto error; + case MetaData::TableNotFound: + case MetaData::InvalidTableVersion: + err = DropIndxRef::InvalidIndexVersion; + goto error; + } + + if (! tmp.p->isIndex()) { + jam(); + err = DropIndxRef::NotAnIndex; + goto error; + } + + if (tmp.p->indexState == TableRecord::IS_DROPPING){ + jam(); + err = DropIndxRef::IndexNotFound; + goto error; + } + + tmp.p->indexState = TableRecord::IS_DROPPING; + req->setOpKey(++c_opRecordSequence); NodeReceiverGroup rg(DBDICT, c_aliveNodes); sendSignal(rg, GSN_DROP_INDX_REQ, @@ -6573,12 +6664,13 @@ Dbdict::execDROP_INDX_REQ(Signal* signal) return; } } +error: jam(); // return to sender OpDropIndex opBad; opPtr.p = &opBad; opPtr.p->save(req); - opPtr.p->m_errorCode = DropIndxRef::BadRequestType; + opPtr.p->m_errorCode = (DropIndxRef::ErrorCode)err; opPtr.p->m_errorLine = __LINE__; dropIndex_sendReply(signal, opPtr, true); } diff --git a/ndb/src/kernel/blocks/dblqh/Dblqh.hpp b/ndb/src/kernel/blocks/dblqh/Dblqh.hpp index 5ddaa67a7d6..a94af7b59c8 100644 --- a/ndb/src/kernel/blocks/dblqh/Dblqh.hpp +++ b/ndb/src/kernel/blocks/dblqh/Dblqh.hpp @@ -455,7 +455,7 @@ public: Uint16 totalAttrReceived; Uint16 fragCopyCreation; Uint16 noOfKeyAttr; - Uint16 noOfNewAttr; + Uint32 noOfNewAttr; // noOfCharsets in upper half Uint16 noOfAttributeGroups; Uint16 lh3DistrBits; Uint16 tableType; diff --git a/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp b/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp index 3b05a133bbb..8342870d69c 100644 --- a/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp +++ b/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp @@ -1444,6 +1444,7 @@ Dblqh::sendAddAttrReq(Signal* signal) tupreq->notused1 = 0; tupreq->attrId = attrId; tupreq->attrDescriptor = entry.attrDescriptor; + tupreq->extTypeInfo = entry.extTypeInfo; sendSignal(fragptr.p->tupBlockref, GSN_TUP_ADD_ATTRREQ, signal, TupAddAttrReq::SignalLength, JBB); return; @@ -7699,6 +7700,7 @@ void Dblqh::accScanConfScanLab(Signal* signal) ndbrequire(sz == boundAiLength); EXECUTE_DIRECT(DBTUX, GSN_TUX_BOUND_INFO, signal, TuxBoundInfo::SignalLength + boundAiLength); + jamEntry(); if (req->errorCode != 0) { jam(); /* diff --git a/ndb/src/kernel/blocks/dbtup/AttributeOffset.hpp b/ndb/src/kernel/blocks/dbtup/AttributeOffset.hpp index 0f3881e9024..2c62adab3e5 100644 --- a/ndb/src/kernel/blocks/dbtup/AttributeOffset.hpp +++ b/ndb/src/kernel/blocks/dbtup/AttributeOffset.hpp @@ -22,26 +22,59 @@ class AttributeOffset { private: static void setOffset(Uint32 & desc, Uint32 offset); + static void setCharsetPos(Uint32 & desc, Uint32 offset); static void setNullFlagPos(Uint32 & desc, Uint32 offset); static Uint32 getOffset(const Uint32 &); + static bool getCharsetFlag(const Uint32 &); + static Uint32 getCharsetPos(const Uint32 &); static Uint32 getNullFlagPos(const Uint32 &); static Uint32 getNullFlagOffset(const Uint32 &); static Uint32 getNullFlagBitOffset(const Uint32 &); static bool isNULL(const Uint32 &, const Uint32 &); }; -#define AO_ATTRIBUTE_OFFSET_MASK (0xffff) -#define AO_NULL_FLAG_POS_MASK (0x7ff) -#define AO_NULL_FLAG_POS_SHIFT (21) -#define AO_NULL_FLAG_WORD_MASK (31) -#define AO_NULL_FLAG_OFFSET_SHIFT (5) +/** + * Allow for 4096 attributes, all nullable, and for 128 different + * character sets. + * + * a = Attribute offset - 11 bits 0-10 ( addr word in 8 kb ) + * c = Has charset flag 1 bits 11-11 + * s = Charset pointer position - 7 bits 12-18 ( in table descriptor ) + * f = Null flag offset in word - 5 bits 20-24 ( address 32 bits ) + * w = Null word offset - 7 bits 25-32 ( f+w addr 4096 attrs ) + * + * 1111111111222222222233 + * 01234567890123456789012345678901 + * aaaaaaaaaaacsssssss fffffwwwwwww + */ + +#define AO_ATTRIBUTE_OFFSET_SHIFT 0 +#define AO_ATTRIBUTE_OFFSET_MASK 0x7ff + +#define AO_CHARSET_FLAG_SHIFT 11 +#define AO_CHARSET_POS_SHIFT 12 +#define AO_CHARSET_POS_MASK 127 + +#define AO_NULL_FLAG_POS_MASK 0xfff // f+w +#define AO_NULL_FLAG_POS_SHIFT 20 + +#define AO_NULL_FLAG_WORD_MASK 31 // f +#define AO_NULL_FLAG_OFFSET_SHIFT 5 inline void AttributeOffset::setOffset(Uint32 & desc, Uint32 offset){ ASSERT_MAX(offset, AO_ATTRIBUTE_OFFSET_MASK, "AttributeOffset::setOffset"); - desc |= offset; + desc |= (offset << AO_ATTRIBUTE_OFFSET_SHIFT); +} + +inline +void +AttributeOffset::setCharsetPos(Uint32 & desc, Uint32 offset) { + ASSERT_MAX(offset, AO_CHARSET_POS_MASK, "AttributeOffset::setCharsetPos"); + desc |= (1 << AO_CHARSET_FLAG_SHIFT); + desc |= (offset << AO_CHARSET_POS_SHIFT); } inline @@ -55,7 +88,21 @@ inline Uint32 AttributeOffset::getOffset(const Uint32 & desc) { - return desc & AO_ATTRIBUTE_OFFSET_MASK; + return (desc >> AO_ATTRIBUTE_OFFSET_SHIFT) & AO_ATTRIBUTE_OFFSET_MASK; +} + +inline +bool +AttributeOffset::getCharsetFlag(const Uint32 & desc) +{ + return (desc >> AO_CHARSET_FLAG_SHIFT) & 1; +} + +inline +Uint32 +AttributeOffset::getCharsetPos(const Uint32 & desc) +{ + return (desc >> AO_CHARSET_POS_SHIFT) & AO_CHARSET_POS_MASK; } inline diff --git a/ndb/src/kernel/blocks/dbtup/Dbtup.hpp b/ndb/src/kernel/blocks/dbtup/Dbtup.hpp index cb7e35ea73e..0e8dd5fbbe8 100644 --- a/ndb/src/kernel/blocks/dbtup/Dbtup.hpp +++ b/ndb/src/kernel/blocks/dbtup/Dbtup.hpp @@ -502,6 +502,7 @@ struct Fragoperrec { Uint32 attributeCount; Uint32 freeNullBit; Uint32 noOfNewAttrCount; + Uint32 charsetIndex; BlockReference lqhBlockrefFrag; }; typedef Ptr FragoperrecPtr; @@ -514,6 +515,7 @@ struct Fragrecord { Uint32 emptyPrimPage; Uint32 firstusedOprec; + Uint32 lastusedOprec; Uint32 thFreeFirst; Uint32 thFreeCopyFirst; @@ -785,6 +787,7 @@ struct Tablerec { ReadFunction* readFunctionArray; UpdateFunction* updateFunctionArray; + CHARSET_INFO** charsetArray; Uint32 readKeyArray; Uint32 tabDescriptor; @@ -796,6 +799,7 @@ struct Tablerec { Uint16 tupheadsize; Uint16 noOfAttr; Uint16 noOfKeyAttr; + Uint16 noOfCharsets; Uint16 noOfNewAttr; Uint16 noOfNullAttr; Uint16 noOfAttributeGroups; @@ -1001,17 +1005,20 @@ public: void tuxGetNode(Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset, Uint32*& node); /* - * TUX reads primary table attributes for index keys. Input is - * attribute ids in AttributeHeader format. Output is pointers to - * attribute data within tuple or 0 for NULL value. + * TUX reads primary table attributes for index keys. Tuple is + * specified by location of original tuple and version number. Input + * is attribute ids in AttributeHeader format. Output is attribute + * data with headers. Uses readAttributes with xfrm option set. + * Returns number of words or negative (-terrorCode) on error. */ - void tuxReadAttrs(Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset, Uint32 tupVersion, Uint32 numAttrs, const Uint32* attrIds, const Uint32** attrData); + int tuxReadAttrs(Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset, Uint32 tupVersion, const Uint32* attrIds, Uint32 numAttrs, Uint32* dataOut); /* * TUX reads primary key without headers into an array of words. Used - * for md5 summing and when returning keyinfo. + * for md5 summing and when returning keyinfo. Returns number of + * words or negative (-terrorCode) on error. */ - void tuxReadKeys(Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset, Uint32* pkSize, Uint32* pkData); + int tuxReadPk(Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset, Uint32* dataOut); /* * TUX checks if tuple is visible to scan. @@ -1365,10 +1372,11 @@ private: //------------------------------------------------------------------ int readAttributes(Page* const pagePtr, Uint32 TupHeadOffset, - Uint32* inBuffer, + const Uint32* inBuffer, Uint32 inBufLen, Uint32* outBuffer, - Uint32 TmaxRead); + Uint32 TmaxRead, + bool xfrmFlag); //------------------------------------------------------------------ //------------------------------------------------------------------ @@ -1614,6 +1622,20 @@ private: Uint32 attrDescriptor, Uint32 attrDes2); +// ***************************************************************** +// Read char routines optionally (tXfrmFlag) apply strxfrm +// ***************************************************************** + + bool readCharNotNULL(Uint32* outBuffer, + AttributeHeader* ahOut, + Uint32 attrDescriptor, + Uint32 attrDes2); + + bool readCharNULLable(Uint32* outBuffer, + AttributeHeader* ahOut, + Uint32 attrDescriptor, + Uint32 attrDes2); + //------------------------------------------------------------------ //------------------------------------------------------------------ bool nullFlagCheck(Uint32 attrDes2); @@ -1632,7 +1654,7 @@ private: //------------------------------------------------------------------ //------------------------------------------------------------------ - void initOpConnection(Operationrec* const regOperPtr); + void initOpConnection(Operationrec* regOperPtr, Fragrecord*); //------------------------------------------------------------------ //------------------------------------------------------------------ @@ -1909,7 +1931,8 @@ private: void updatePackedList(Signal* signal, Uint16 ahostIndex); void setUpDescriptorReferences(Uint32 descriptorReference, - Tablerec* const regTabPtr); + Tablerec* const regTabPtr, + const Uint32* offset); void setUpKeyArray(Tablerec* const regTabPtr); bool addfragtotab(Tablerec* const regTabPtr, Uint32 fragId, Uint32 fragIndex); void deleteFragTab(Tablerec* const regTabPtr, Uint32 fragId); @@ -2098,7 +2121,8 @@ private: //----------------------------------------------------------------------------- // Public methods - Uint32 allocTabDescr(Uint32 noOfAttributes, Uint32 noOfKeyAttr, Uint32 noOfAttributeGroups); + Uint32 getTabDescrOffsets(const Tablerec* regTabPtr, Uint32* offset); + Uint32 allocTabDescr(const Tablerec* regTabPtr, Uint32* offset); void freeTabDescr(Uint32 retRef, Uint32 retNo); Uint32 getTabDescrWord(Uint32 index); void setTabDescrWord(Uint32 index, Uint32 word); @@ -2217,6 +2241,7 @@ private: Uint32 tMaxRead; Uint32 tOutBufIndex; Uint32* tTupleHeader; + bool tXfrmFlag; // updateAttributes module Uint32 tInBufIndex; diff --git a/ndb/src/kernel/blocks/dbtup/DbtupAbort.cpp b/ndb/src/kernel/blocks/dbtup/DbtupAbort.cpp index 1ffc5f06754..e9043a8b52d 100644 --- a/ndb/src/kernel/blocks/dbtup/DbtupAbort.cpp +++ b/ndb/src/kernel/blocks/dbtup/DbtupAbort.cpp @@ -77,7 +77,7 @@ void Dbtup::execTUP_ABORTREQ(Signal* signal) if (regOperPtr.p->optype == ZREAD) { ljam(); freeAllAttrBuffers(regOperPtr.p); - initOpConnection(regOperPtr.p); + initOpConnection(regOperPtr.p, 0); return; }//if @@ -134,7 +134,7 @@ void Dbtup::execTUP_ABORTREQ(Signal* signal) ndbrequire(regOperPtr.p->tupleState == ALREADY_ABORTED); commitUpdate(signal, regOperPtr.p, regFragPtr.p, regTabPtr.p); }//if - initOpConnection(regOperPtr.p); + initOpConnection(regOperPtr.p, regFragPtr.p); }//execTUP_ABORTREQ() void Dbtup::setTupleStateOnPreviousOps(Uint32 prevOpIndex) @@ -459,7 +459,7 @@ void Dbtup::tupkeyErrorLab(Signal* signal) freeAllAttrBuffers(regOperPtr); abortUpdate(signal, regOperPtr, fragptr.p, tabptr.p); removeActiveOpList(regOperPtr); - initOpConnection(regOperPtr); + initOpConnection(regOperPtr, fragptr.p); regOperPtr->transstate = IDLE; regOperPtr->tupleState = NO_OTHER_OP; TupKeyRef * const tupKeyRef = (TupKeyRef *)signal->getDataPtrSend(); diff --git a/ndb/src/kernel/blocks/dbtup/DbtupCommit.cpp b/ndb/src/kernel/blocks/dbtup/DbtupCommit.cpp index fa3667b221e..cbd56c3281f 100644 --- a/ndb/src/kernel/blocks/dbtup/DbtupCommit.cpp +++ b/ndb/src/kernel/blocks/dbtup/DbtupCommit.cpp @@ -224,7 +224,8 @@ void Dbtup::removeActiveOpList(Operationrec* const regOperPtr) /* ---------------------------------------------------------------- */ /* INITIALIZATION OF ONE CONNECTION RECORD TO PREPARE FOR NEXT OP. */ /* ---------------------------------------------------------------- */ -void Dbtup::initOpConnection(Operationrec* const regOperPtr) +void Dbtup::initOpConnection(Operationrec* regOperPtr, + Fragrecord * fragPtrP) { Uint32 RinFragList = regOperPtr->inFragList; regOperPtr->transstate = IDLE; @@ -244,22 +245,18 @@ void Dbtup::initOpConnection(Operationrec* const regOperPtr) regOperPtr->inFragList = ZFALSE; if (tropPrevLinkPtr.i == RNIL) { ljam(); - FragrecordPtr regFragPtr; - regFragPtr.i = regOperPtr->fragmentPtr; - ptrCheckGuard(regFragPtr, cnoOfFragrec, fragrecord); - regFragPtr.p->firstusedOprec = tropNextLinkPtr.i; + fragPtrP->firstusedOprec = tropNextLinkPtr.i; } else { ljam(); ptrCheckGuard(tropPrevLinkPtr, cnoOfOprec, operationrec); tropPrevLinkPtr.p->nextOprecInList = tropNextLinkPtr.i; }//if if (tropNextLinkPtr.i == RNIL) { - ; + fragPtrP->lastusedOprec = tropPrevLinkPtr.i; } else { - ljam(); ptrCheckGuard(tropNextLinkPtr, cnoOfOprec, operationrec); tropNextLinkPtr.p->prevOprecInList = tropPrevLinkPtr.i; - }//if + } regOperPtr->prevOprecInList = RNIL; regOperPtr->nextOprecInList = RNIL; }//if @@ -336,7 +333,7 @@ void Dbtup::execTUP_COMMITREQ(Signal* signal) commitUpdate(signal, regOperPtr.p, regFragPtr.p, regTabPtr.p); removeActiveOpList(regOperPtr.p); }//if - initOpConnection(regOperPtr.p); + initOpConnection(regOperPtr.p, regFragPtr.p); }//execTUP_COMMITREQ() void diff --git a/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp b/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp index 0a47778f7c1..0061ebe812d 100644 --- a/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp +++ b/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp @@ -319,24 +319,20 @@ void Dbtup::linkOpIntoFragList(OperationrecPtr regOperPtr, Fragrecord* const regFragPtr) { OperationrecPtr sopTmpOperPtr; -/* ----------------------------------------------------------------- */ -/* LINK THE OPERATION INTO A DOUBLY LINKED LIST ON THE FRAGMENT*/ -/* PUT IT FIRST IN THIS LIST SINCE IT DOESN'T MATTER WHERE IT */ -/* IS PUT. */ -/* ----------------------------------------------------------------- */ + Uint32 tail = regFragPtr->lastusedOprec; ndbrequire(regOperPtr.p->inFragList == ZFALSE); regOperPtr.p->inFragList = ZTRUE; - regOperPtr.p->prevOprecInList = RNIL; - sopTmpOperPtr.i = regFragPtr->firstusedOprec; - regFragPtr->firstusedOprec = regOperPtr.i; - regOperPtr.p->nextOprecInList = sopTmpOperPtr.i; - if (sopTmpOperPtr.i == RNIL) { - return; + regOperPtr.p->prevOprecInList = tail; + regOperPtr.p->nextOprecInList = RNIL; + sopTmpOperPtr.i = tail; + if (tail == RNIL) { + regFragPtr->firstusedOprec = regOperPtr.i; } else { jam(); ptrCheckGuard(sopTmpOperPtr, cnoOfOprec, operationrec); - sopTmpOperPtr.p->prevOprecInList = regOperPtr.i; + sopTmpOperPtr.p->nextOprecInList = regOperPtr.i; }//if + regFragPtr->lastusedOprec = regOperPtr.i; }//Dbtup::linkOpIntoFragList() /* @@ -903,7 +899,8 @@ int Dbtup::handleReadReq(Signal* signal, &cinBuffer[0], regOperPtr->attrinbufLen, dst, - dstLen); + dstLen, + false); if (TnoOfDataRead != (Uint32)-1) { /* ------------------------------------------------------------------------- */ // We have read all data into coutBuffer. Now send it to the API. @@ -1274,7 +1271,8 @@ int Dbtup::interpreterStartLab(Signal* signal, &cinBuffer[5], RinitReadLen, &dst[0], - dstLen); + dstLen, + false); if (TnoDataRW != (Uint32)-1) { RattroutCounter = TnoDataRW; RinstructionCounter += RinitReadLen; @@ -1347,7 +1345,8 @@ int Dbtup::interpreterStartLab(Signal* signal, &cinBuffer[RinstructionCounter], RfinalRLen, &dst[RattroutCounter], - (dstLen - RattroutCounter)); + (dstLen - RattroutCounter), + false); if (TnoDataRW != (Uint32)-1) { RattroutCounter += TnoDataRW; } else { @@ -1487,7 +1486,8 @@ int Dbtup::interpreterNextLab(Signal* signal, &theAttrinfo, (Uint32)1, &TregMemBuffer[theRegister], - (Uint32)3); + (Uint32)3, + false); if (TnoDataRW == 2) { /* ------------------------------------------------------------- */ // Two words read means that we get the instruction plus one 32 @@ -1833,7 +1833,8 @@ int Dbtup::interpreterNextLab(Signal* signal, Int32 TnoDataR = readAttributes(pagePtr, TupHeadOffset, &attrId, 1, - tmpArea, tmpAreaSz); + tmpArea, tmpAreaSz, + false); if (TnoDataR == -1) { jam(); @@ -1929,7 +1930,8 @@ int Dbtup::interpreterNextLab(Signal* signal, Int32 TnoDataR = readAttributes(pagePtr, TupHeadOffset, &attrId, 1, - tmpArea, tmpAreaSz); + tmpArea, tmpAreaSz, + false); if (TnoDataR == -1) { jam(); @@ -1957,7 +1959,8 @@ int Dbtup::interpreterNextLab(Signal* signal, Int32 TnoDataR = readAttributes(pagePtr, TupHeadOffset, &attrId, 1, - tmpArea, tmpAreaSz); + tmpArea, tmpAreaSz, + false); if (TnoDataR == -1) { jam(); diff --git a/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp b/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp index 1e57f127fbc..d33adcd08e1 100644 --- a/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp +++ b/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp @@ -963,6 +963,7 @@ void Dbtup::initializeFragrecord() regFragPtr.p->nextfreefrag = regFragPtr.i + 1; regFragPtr.p->checkpointVersion = RNIL; regFragPtr.p->firstusedOprec = RNIL; + regFragPtr.p->lastusedOprec = RNIL; regFragPtr.p->fragStatus = IDLE; }//for regFragPtr.i = cnoOfFragrec - 1; @@ -1067,6 +1068,7 @@ Dbtup::initTab(Tablerec* const regTabPtr) }//for regTabPtr->readFunctionArray = NULL; regTabPtr->updateFunctionArray = NULL; + regTabPtr->charsetArray = NULL; regTabPtr->tabDescriptor = RNIL; regTabPtr->attributeGroupDescriptor = RNIL; @@ -1163,7 +1165,7 @@ void Dbtup::execTUPSEIZEREQ(Signal* signal) return; }//if regOperPtr.p->optype = ZREAD; - initOpConnection(regOperPtr.p); + initOpConnection(regOperPtr.p, 0); regOperPtr.p->userpointer = userPtr; regOperPtr.p->userblockref = userRef; signal->theData[0] = regOperPtr.p->userpointer; diff --git a/ndb/src/kernel/blocks/dbtup/DbtupIndex.cpp b/ndb/src/kernel/blocks/dbtup/DbtupIndex.cpp index ec2c63c736e..2dd707ebafc 100644 --- a/ndb/src/kernel/blocks/dbtup/DbtupIndex.cpp +++ b/ndb/src/kernel/blocks/dbtup/DbtupIndex.cpp @@ -112,10 +112,11 @@ Dbtup::tuxGetNode(Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset, Uint32*& no node = &pagePtr.p->pageWord[pageOffset] + attrDataOffset; } -void -Dbtup::tuxReadAttrs(Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset, Uint32 tupVersion, Uint32 numAttrs, const Uint32* attrIds, const Uint32** attrData) +int +Dbtup::tuxReadAttrs(Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset, Uint32 tupVersion, const Uint32* attrIds, Uint32 numAttrs, Uint32* dataOut) { ljamEntry(); + // use own variables instead of globals FragrecordPtr fragPtr; fragPtr.i = fragPtrI; ptrCheckGuard(fragPtr, cnoOfFragrec, fragrecord); @@ -134,6 +135,7 @@ Dbtup::tuxReadAttrs(Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset, Uint32 tu while (true) { ptrCheckGuard(opPtr, cnoOfOprec, operationrec); if (opPtr.p->realPageIdC != RNIL) { + // update page and offset pagePtr.i = opPtr.p->realPageIdC; pageOffset = opPtr.p->pageOffsetC; ptrCheckGuard(pagePtr, cnoOfPage, page); @@ -147,33 +149,34 @@ Dbtup::tuxReadAttrs(Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset, Uint32 tu ndbrequire(++loopGuard < (1 << ZTUP_VERSION_BITS)); } } - const Uint32 tabDescriptor = tablePtr.p->tabDescriptor; - const Uint32* tupleHeader = &pagePtr.p->pageWord[pageOffset]; - for (Uint32 i = 0; i < numAttrs; i++) { - AttributeHeader ah(attrIds[i]); - const Uint32 attrId = ah.getAttributeId(); - const Uint32 index = tabDescriptor + (attrId << ZAD_LOG_SIZE); - const Uint32 desc1 = tableDescriptor[index].tabDescr; - const Uint32 desc2 = tableDescriptor[index + 1].tabDescr; - if (AttributeDescriptor::getNullable(desc1)) { - Uint32 offset = AttributeOffset::getNullFlagOffset(desc2); - ndbrequire(offset < tablePtr.p->tupNullWords); - offset += tablePtr.p->tupNullIndex; - ndbrequire(offset < tablePtr.p->tupheadsize); - if (AttributeOffset::isNULL(tupleHeader[offset], desc2)) { - ljam(); - attrData[i] = 0; - continue; - } - } - attrData[i] = tupleHeader + AttributeOffset::getOffset(desc2); + // read key attributes from found tuple version + // save globals + TablerecPtr tabptr_old = tabptr; + FragrecordPtr fragptr_old = fragptr; + OperationrecPtr operPtr_old = operPtr; + // new globals + tabptr = tablePtr; + fragptr = fragPtr; + operPtr.i = RNIL; + operPtr.p = NULL; + // do it + int ret = readAttributes(pagePtr.p, pageOffset, attrIds, numAttrs, dataOut, ZNIL, true); + // restore globals + tabptr = tabptr_old; + fragptr = fragptr_old; + operPtr = operPtr_old; + // done + if (ret == (Uint32)-1) { + ret = terrorCode ? (-(int)terrorCode) : -1; } + return ret; } -void -Dbtup::tuxReadKeys(Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset, Uint32* pkSize, Uint32* pkData) +int +Dbtup::tuxReadPk(Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset, Uint32* dataOut) { ljamEntry(); + // use own variables instead of globals FragrecordPtr fragPtr; fragPtr.i = fragPtrI; ptrCheckGuard(fragPtr, cnoOfFragrec, fragrecord); @@ -184,25 +187,45 @@ Dbtup::tuxReadKeys(Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset, Uint32* pk pagePtr.i = pageId; ptrCheckGuard(pagePtr, cnoOfPage, page); const Uint32 tabDescriptor = tablePtr.p->tabDescriptor; - const Uint32 numAttrs = tablePtr.p->noOfKeyAttr; const Uint32* attrIds = &tableDescriptor[tablePtr.p->readKeyArray].tabDescr; - const Uint32* tupleHeader = &pagePtr.p->pageWord[pageOffset]; - Uint32 size = 0; - for (Uint32 i = 0; i < numAttrs; i++) { - AttributeHeader ah(attrIds[i]); - const Uint32 attrId = ah.getAttributeId(); - const Uint32 index = tabDescriptor + (attrId << ZAD_LOG_SIZE); - const Uint32 desc1 = tableDescriptor[index].tabDescr; - const Uint32 desc2 = tableDescriptor[index + 1].tabDescr; - ndbrequire(! AttributeDescriptor::getNullable(desc1)); - const Uint32 attrSize = AttributeDescriptor::getSizeInWords(desc1); - const Uint32* attrData = tupleHeader + AttributeOffset::getOffset(desc2); - for (Uint32 j = 0; j < attrSize; j++) { - pkData[size + j] = attrData[j]; + const Uint32 numAttrs = tablePtr.p->noOfKeyAttr; + // read pk attributes from original tuple + // save globals + TablerecPtr tabptr_old = tabptr; + FragrecordPtr fragptr_old = fragptr; + OperationrecPtr operPtr_old = operPtr; + // new globals + tabptr = tablePtr; + fragptr = fragPtr; + operPtr.i = RNIL; + operPtr.p = NULL; + // do it + int ret = readAttributes(pagePtr.p, pageOffset, attrIds, numAttrs, dataOut, ZNIL, true); + // restore globals + tabptr = tabptr_old; + fragptr = fragptr_old; + operPtr = operPtr_old; + // done + if (ret != (Uint32)-1) { + // remove headers + Uint32 n = 0; + Uint32 i = 0; + while (n < numAttrs) { + const AttributeHeader ah(dataOut[i]); + Uint32 size = ah.getDataSize(); + ndbrequire(size != 0); + for (Uint32 j = 0; j < size; j++) { + dataOut[i + j - n] = dataOut[i + j + 1]; + } + n += 1; + i += 1 + size; } - size += attrSize; + ndbrequire(i == ret); + ret -= numAttrs; + } else { + ret = terrorCode ? (-(int)terrorCode) : -1; } - *pkSize = size; + return ret; } bool diff --git a/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp b/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp index 09889a51fa3..efea312b865 100644 --- a/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp +++ b/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp @@ -20,12 +20,14 @@ #include #include #include +#include #include #include #include #include #include #include "AttributeOffset.hpp" +#include #define ljam() { jamLine(20000 + __LINE__); } #define ljamEntry() { jamEntryLine(20000 + __LINE__); } @@ -52,7 +54,10 @@ void Dbtup::execTUPFRAGREQ(Signal* signal) /* Uint32 schemaVersion = signal->theData[8];*/ Uint32 noOfKeyAttr = signal->theData[9]; - Uint32 noOfNewAttr = signal->theData[10]; + Uint32 noOfNewAttr = (signal->theData[10] & 0xFFFF); + /* DICT sends number of character sets in upper half */ + Uint32 noOfCharsets = (signal->theData[10] >> 16); + Uint32 checksumIndicator = signal->theData[11]; Uint32 noOfAttributeGroups = signal->theData[12]; Uint32 globalCheckpointIdIndicator = signal->theData[13]; @@ -75,6 +80,7 @@ void Dbtup::execTUPFRAGREQ(Signal* signal) fragOperPtr.p->attributeCount = noOfAttributes; fragOperPtr.p->freeNullBit = noOfNullAttr; fragOperPtr.p->noOfNewAttrCount = noOfNewAttr; + fragOperPtr.p->charsetIndex = 0; ndbrequire(reqinfo == ZADDFRAG); @@ -156,6 +162,7 @@ void Dbtup::execTUPFRAGREQ(Signal* signal) regTabPtr.p->tupheadsize = regTabPtr.p->tupGCPIndex; regTabPtr.p->noOfKeyAttr = noOfKeyAttr; + regTabPtr.p->noOfCharsets = noOfCharsets; regTabPtr.p->noOfAttr = noOfAttributes; regTabPtr.p->noOfNewAttr = noOfNewAttr; regTabPtr.p->noOfNullAttr = noOfNullAttr; @@ -163,13 +170,14 @@ void Dbtup::execTUPFRAGREQ(Signal* signal) regTabPtr.p->notNullAttributeMask.clear(); - Uint32 tableDescriptorRef = allocTabDescr(noOfAttributes, noOfKeyAttr, noOfAttributeGroups); + Uint32 offset[10]; + Uint32 tableDescriptorRef = allocTabDescr(regTabPtr.p, offset); if (tableDescriptorRef == RNIL) { ljam(); fragrefuse4Lab(signal, fragOperPtr, regFragPtr, regTabPtr.p, fragId); return; }//if - setUpDescriptorReferences(tableDescriptorRef, regTabPtr.p); + setUpDescriptorReferences(tableDescriptorRef, regTabPtr.p, offset); } else { ljam(); fragOperPtr.p->definingFragment = false; @@ -251,6 +259,9 @@ void Dbtup::execTUP_ADD_ATTRREQ(Signal* signal) ptrCheckGuard(fragOperPtr, cnoOfFragoprec, fragoperrec); Uint32 attrId = signal->theData[2]; Uint32 attrDescriptor = signal->theData[3]; + // DICT sends extended type (ignored) and charset number + Uint32 extType = (signal->theData[4] & 0xFF); + Uint32 csNumber = (signal->theData[4] >> 16); regTabPtr.i = fragOperPtr.p->tableidFrag; ptrCheckGuard(regTabPtr, cnoOfTablerec, tablerec); @@ -304,6 +315,29 @@ void Dbtup::execTUP_ADD_ATTRREQ(Signal* signal) } else { ndbrequire(false); }//if + if (csNumber != 0) { + CHARSET_INFO* cs = get_charset(csNumber, MYF(0)); + if (cs == NULL) { + ljam(); + terrorCode = TupAddAttrRef::InvalidCharset; + addattrrefuseLab(signal, regFragPtr, fragOperPtr, regTabPtr.p, fragId); + return; + } + Uint32 i = 0; + while (i < fragOperPtr.p->charsetIndex) { + ljam(); + if (regTabPtr.p->charsetArray[i] == cs) + break; + i++; + } + if (i == fragOperPtr.p->charsetIndex) { + ljam(); + fragOperPtr.p->charsetIndex++; + } + ndbrequire(i < regTabPtr.p->noOfCharsets); + regTabPtr.p->charsetArray[i] = cs; + AttributeOffset::setCharsetPos(attrDes2, i); + } setTabDescrWord(firstTabDesIndex + 1, attrDes2); if (regTabPtr.p->tupheadsize > MAX_TUPLE_SIZE_IN_WORDS) { @@ -340,20 +374,28 @@ void Dbtup::execTUP_ADD_ATTRREQ(Signal* signal) return; }//Dbtup::execTUP_ADD_ATTRREQ() -void Dbtup::setUpDescriptorReferences(Uint32 descriptorReference, - Tablerec* const regTabPtr) -{ - Uint32 noOfAttributes = regTabPtr->noOfAttr; - descriptorReference += ZTD_SIZE; - ReadFunction * tmp = (ReadFunction*)&tableDescriptor[descriptorReference].tabDescr; - regTabPtr->readFunctionArray = tmp; - regTabPtr->updateFunctionArray = (UpdateFunction*)(tmp + noOfAttributes); +/* + * Descriptor has these parts: + * + * 0 readFunctionArray ( one for each attribute ) + * 1 updateFunctionArray ( ditto ) + * 2 charsetArray ( pointers to distinct CHARSET_INFO ) + * 3 readKeyArray ( attribute ids of keys ) + * 4 attributeGroupDescriptor ( currently size 1 but unused ) + * 5 tabDescriptor ( attribute descriptors, each ZAD_SIZE ) + */ - TableDescriptor * start = &tableDescriptor[descriptorReference]; - TableDescriptor * end = (TableDescriptor*)(tmp + 2 * noOfAttributes); - regTabPtr->readKeyArray = descriptorReference + (end - start); - regTabPtr->attributeGroupDescriptor = regTabPtr->readKeyArray + regTabPtr->noOfKeyAttr; - regTabPtr->tabDescriptor = regTabPtr->attributeGroupDescriptor + regTabPtr->noOfAttributeGroups; +void Dbtup::setUpDescriptorReferences(Uint32 descriptorReference, + Tablerec* const regTabPtr, + const Uint32* offset) +{ + Uint32* desc = &tableDescriptor[descriptorReference].tabDescr; + regTabPtr->readFunctionArray = (ReadFunction*)(desc + offset[0]); + regTabPtr->updateFunctionArray = (UpdateFunction*)(desc + offset[1]); + regTabPtr->charsetArray = (CHARSET_INFO**)(desc + offset[2]); + regTabPtr->readKeyArray = descriptorReference + offset[3]; + regTabPtr->attributeGroupDescriptor = descriptorReference + offset[4]; + regTabPtr->tabDescriptor = descriptorReference + offset[5]; }//Dbtup::setUpDescriptorReferences() Uint32 @@ -491,14 +533,18 @@ void Dbtup::releaseTabDescr(Tablerec* const regTabPtr) Uint32 descriptor = regTabPtr->readKeyArray; if (descriptor != RNIL) { ljam(); + Uint32 offset[10]; + getTabDescrOffsets(regTabPtr, offset); + regTabPtr->tabDescriptor = RNIL; regTabPtr->readKeyArray = RNIL; regTabPtr->readFunctionArray = NULL; regTabPtr->updateFunctionArray = NULL; + regTabPtr->charsetArray = NULL; regTabPtr->attributeGroupDescriptor= RNIL; - Uint32 sizeFunctionArrays = 2 * (regTabPtr->noOfAttr * sizeOfReadFunction()); - descriptor -= (sizeFunctionArrays + ZTD_SIZE); + // move to start of descriptor + descriptor -= offset[3]; Uint32 retNo = getTabDescrWord(descriptor + ZTD_DATASIZE); ndbrequire(getTabDescrWord(descriptor + ZTD_HEADER) == ZTD_TYPE_NORMAL); ndbrequire(retNo == getTabDescrWord((descriptor + retNo) - ZTD_TR_SIZE)); diff --git a/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp b/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp index cc47ef7e78f..a4e7cb47249 100644 --- a/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp +++ b/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp @@ -35,6 +35,7 @@ Dbtup::setUpQueryRoutines(Tablerec* const regTabPtr) for (Uint32 i = 0; i < regTabPtr->noOfAttr; i++) { Uint32 attrDescriptorStart = startDescriptor + (i << ZAD_LOG_SIZE); Uint32 attrDescriptor = tableDescriptor[attrDescriptorStart].tabDescr; + Uint32 attrOffset = tableDescriptor[attrDescriptorStart + 1].tabDescr; if (!AttributeDescriptor::getDynamic(attrDescriptor)) { if ((AttributeDescriptor::getArrayType(attrDescriptor) == ZNON_ARRAY) || (AttributeDescriptor::getArrayType(attrDescriptor) == ZFIXED_ARRAY)) { @@ -54,6 +55,11 @@ Dbtup::setUpQueryRoutines(Tablerec* const regTabPtr) } else { ndbrequire(false); }//if + // replace read function of char attribute + if (AttributeOffset::getCharsetFlag(attrOffset)) { + ljam(); + regTabPtr->readFunctionArray[i] = &Dbtup::readCharNotNULL; + } } else { if (AttributeDescriptor::getSizeInWords(attrDescriptor) == 1) { ljam(); @@ -72,6 +78,11 @@ Dbtup::setUpQueryRoutines(Tablerec* const regTabPtr) regTabPtr->readFunctionArray[i] = &Dbtup::readFixedSizeTHZeroWordNULLable; regTabPtr->updateFunctionArray[i] = &Dbtup::updateFixedSizeTHManyWordNULLable; }//if + // replace read function of char attribute + if (AttributeOffset::getCharsetFlag(attrOffset)) { + ljam(); + regTabPtr->readFunctionArray[i] = &Dbtup::readCharNULLable; + } }//if } else if (AttributeDescriptor::getArrayType(attrDescriptor) == ZVAR_ARRAY) { if (!AttributeDescriptor::getNullable(attrDescriptor)) { @@ -146,10 +157,11 @@ Dbtup::setUpQueryRoutines(Tablerec* const regTabPtr) /* ---------------------------------------------------------------- */ int Dbtup::readAttributes(Page* const pagePtr, Uint32 tupHeadOffset, - Uint32* inBuffer, + const Uint32* inBuffer, Uint32 inBufLen, Uint32* outBuffer, - Uint32 maxRead) + Uint32 maxRead, + bool xfrmFlag) { Tablerec* const regTabPtr = tabptr.p; Uint32 numAttributes = regTabPtr->noOfAttr; @@ -162,6 +174,7 @@ int Dbtup::readAttributes(Page* const pagePtr, tCheckOffset = regTabPtr->tupheadsize; tMaxRead = maxRead; tTupleHeader = &pagePtr->pageWord[tupHeadOffset]; + tXfrmFlag = xfrmFlag; ndbrequire(tupHeadOffset + tCheckOffset <= ZWORDS_ON_PAGE); while (inBufIndex < inBufLen) { @@ -542,6 +555,74 @@ Dbtup::readDynSmallVarSize(Uint32* outBuffer, return false; }//Dbtup::readDynSmallVarSize() + +bool +Dbtup::readCharNotNULL(Uint32* outBuffer, + AttributeHeader* ahOut, + Uint32 attrDescriptor, + Uint32 attrDes2) +{ + Uint32 indexBuf = tOutBufIndex; + Uint32 readOffset = AttributeOffset::getOffset(attrDes2); + Uint32 attrNoOfWords = AttributeDescriptor::getSizeInWords(attrDescriptor); + Uint32 newIndexBuf = indexBuf + attrNoOfWords; + Uint32 maxRead = tMaxRead; + + ndbrequire((readOffset + attrNoOfWords - 1) < tCheckOffset); + if (newIndexBuf <= maxRead) { + ljam(); + ahOut->setDataSize(attrNoOfWords); + if (! tXfrmFlag) { + MEMCOPY_NO_WORDS(&outBuffer[indexBuf], + &tTupleHeader[readOffset], + attrNoOfWords); + } else { + ljam(); + Tablerec* regTabPtr = tabptr.p; + Uint32 i = AttributeOffset::getCharsetPos(attrDes2); + ndbrequire(i < tabptr.p->noOfCharsets); + // not const in MySQL + CHARSET_INFO* cs = tabptr.p->charsetArray[i]; + // XXX should strip Uint32 null padding + const unsigned nBytes = attrNoOfWords << 2; + unsigned n = + (*cs->coll->strnxfrm)(cs, + (uchar*)&outBuffer[indexBuf], + nBytes, + (const uchar*)&tTupleHeader[readOffset], + nBytes); + // pad with ascii spaces + while (n < nBytes) + ((uchar*)&outBuffer[indexBuf])[n++] = 0x20; + } + tOutBufIndex = newIndexBuf; + return true; + } else { + ljam(); + terrorCode = ZTRY_TO_READ_TOO_MUCH_ERROR; + return false; + } +} + +bool +Dbtup::readCharNULLable(Uint32* outBuffer, + AttributeHeader* ahOut, + Uint32 attrDescriptor, + Uint32 attrDes2) +{ + if (!nullFlagCheck(attrDes2)) { + ljam(); + return readCharNotNULL(outBuffer, + ahOut, + attrDescriptor, + attrDes2); + } else { + ljam(); + ahOut->setNULL(); + return true; + } +} + /* ---------------------------------------------------------------------- */ /* THIS ROUTINE IS USED TO UPDATE A NUMBER OF ATTRIBUTES. IT IS */ /* USED BY THE INSERT ROUTINE, THE UPDATE ROUTINE AND IT CAN BE */ diff --git a/ndb/src/kernel/blocks/dbtup/DbtupTabDesMan.cpp b/ndb/src/kernel/blocks/dbtup/DbtupTabDesMan.cpp index d31ab43f108..642ba270760 100644 --- a/ndb/src/kernel/blocks/dbtup/DbtupTabDesMan.cpp +++ b/ndb/src/kernel/blocks/dbtup/DbtupTabDesMan.cpp @@ -31,12 +31,33 @@ /* memory attached to fragments (could be allocated per table */ /* instead. Performs its task by a buddy algorithm. */ /* **************************************************************** */ -Uint32 Dbtup::allocTabDescr(Uint32 noOfAttributes, Uint32 noOfKeyAttr, Uint32 noOfAttributeGroups) + +Uint32 +Dbtup::getTabDescrOffsets(const Tablerec* regTabPtr, Uint32* offset) +{ + // belongs to configure.in + unsigned sizeOfPointer = sizeof(CHARSET_INFO*); + ndbrequire((sizeOfPointer & 0x3) == 0); + sizeOfPointer = (sizeOfPointer >> 2); + // do in layout order and return offsets (see DbtupMeta.cpp) + Uint32 allocSize = 0; + // magically aligned to 8 bytes + offset[0] = allocSize += ZTD_SIZE; + offset[1] = allocSize += regTabPtr->noOfAttr * sizeOfReadFunction(); + offset[2] = allocSize += regTabPtr->noOfAttr * sizeOfReadFunction(); + offset[3] = allocSize += regTabPtr->noOfCharsets * sizeOfPointer; + offset[4] = allocSize += regTabPtr->noOfKeyAttr; + offset[5] = allocSize += regTabPtr->noOfAttributeGroups; + allocSize += regTabPtr->noOfAttr * ZAD_SIZE; + allocSize += ZTD_TRAILER_SIZE; + // return number of words + return allocSize; +} + +Uint32 Dbtup::allocTabDescr(const Tablerec* regTabPtr, Uint32* offset) { Uint32 reference = RNIL; - Uint32 allocSize = (ZTD_SIZE + ZTD_TRAILER_SIZE) + (noOfAttributes * ZAD_SIZE); - allocSize += noOfAttributeGroups; - allocSize += ((2 * noOfAttributes * sizeOfReadFunction()) + noOfKeyAttr); + Uint32 allocSize = getTabDescrOffsets(regTabPtr, offset); /* ---------------------------------------------------------------- */ /* ALWAYS ALLOCATE A MULTIPLE OF 16 BYTES */ /* ---------------------------------------------------------------- */ diff --git a/ndb/src/kernel/blocks/dbtup/DbtupTrigger.cpp b/ndb/src/kernel/blocks/dbtup/DbtupTrigger.cpp index a93ff4566e7..c0b49364ee6 100644 --- a/ndb/src/kernel/blocks/dbtup/DbtupTrigger.cpp +++ b/ndb/src/kernel/blocks/dbtup/DbtupTrigger.cpp @@ -751,7 +751,8 @@ bool Dbtup::readTriggerInfo(TupTriggerData* const trigPtr, &tableDescriptor[regTabPtr->readKeyArray].tabDescr, regTabPtr->noOfKeyAttr, keyBuffer, - ZATTR_BUFFER_SIZE); + ZATTR_BUFFER_SIZE, + true); ndbrequire(noPrimKey != (Uint32)-1); Uint32 numAttrsToRead; @@ -792,7 +793,8 @@ bool Dbtup::readTriggerInfo(TupTriggerData* const trigPtr, &readBuffer[0], numAttrsToRead, mainBuffer, - ZATTR_BUFFER_SIZE); + ZATTR_BUFFER_SIZE, + true); ndbrequire(noMainWords != (Uint32)-1); } else { ljam(); @@ -816,7 +818,8 @@ bool Dbtup::readTriggerInfo(TupTriggerData* const trigPtr, &readBuffer[0], numAttrsToRead, copyBuffer, - ZATTR_BUFFER_SIZE); + ZATTR_BUFFER_SIZE, + true); ndbrequire(noCopyWords != (Uint32)-1); if ((noMainWords == noCopyWords) && diff --git a/ndb/src/kernel/blocks/dbtux/Dbtux.hpp b/ndb/src/kernel/blocks/dbtux/Dbtux.hpp index 36ac20611bb..8dca52cec04 100644 --- a/ndb/src/kernel/blocks/dbtux/Dbtux.hpp +++ b/ndb/src/kernel/blocks/dbtux/Dbtux.hpp @@ -162,11 +162,6 @@ private: // AttributeHeader size is assumed to be 1 word static const unsigned AttributeHeaderSize = 1; - /* - * Array of pointers to TUP table attributes. Always read-on|y. - */ - typedef const Uint32** TableData; - /* * Logical tuple address, "local key". Identifies table tuples. */ @@ -330,11 +325,15 @@ private: /* * Attribute metadata. Size must be multiple of word size. + * + * Prefix comparison of char data must use strxfrm and binary + * comparison. The charset is currently unused. */ struct DescAttr { Uint32 m_attrDesc; // standard AttributeDescriptor Uint16 m_primaryAttrId; - Uint16 m_typeId; + unsigned m_typeId : 6; + unsigned m_charset : 10; }; static const unsigned DescAttrSize = sizeof(DescAttr) >> 2; @@ -553,9 +552,9 @@ private: void execREAD_CONFIG_REQ(Signal* signal); // utils void setKeyAttrs(const Frag& frag); - void readKeyAttrs(const Frag& frag, TreeEnt ent, unsigned start, TableData keyData); - void readTablePk(const Frag& frag, TreeEnt ent, unsigned& pkSize, Data pkData); - void copyAttrs(const Frag& frag, TableData data1, Data data2, unsigned maxlen2 = MaxAttrDataSize); + void readKeyAttrs(const Frag& frag, TreeEnt ent, unsigned start, Data keyData); + void readTablePk(const Frag& frag, TreeEnt ent, Data pkData, unsigned& pkSize); + void copyAttrs(const Frag& frag, ConstData data1, Data data2, unsigned maxlen2 = MaxAttrDataSize); /* * DbtuxMeta.cpp @@ -622,17 +621,15 @@ private: /* * DbtuxSearch.cpp */ - void searchToAdd(Signal* signal, Frag& frag, TableData searchKey, TreeEnt searchEnt, TreePos& treePos); - void searchToRemove(Signal* signal, Frag& frag, TableData searchKey, TreeEnt searchEnt, TreePos& treePos); + void searchToAdd(Signal* signal, Frag& frag, ConstData searchKey, TreeEnt searchEnt, TreePos& treePos); + void searchToRemove(Signal* signal, Frag& frag, ConstData searchKey, TreeEnt searchEnt, TreePos& treePos); void searchToScan(Signal* signal, Frag& frag, ConstData boundInfo, unsigned boundCount, TreePos& treePos); /* * DbtuxCmp.cpp */ - int cmpSearchKey(const Frag& frag, unsigned& start, TableData searchKey, ConstData entryData, unsigned maxlen = MaxAttrDataSize); - int cmpSearchKey(const Frag& frag, unsigned& start, TableData searchKey, TableData entryKey); + int cmpSearchKey(const Frag& frag, unsigned& start, ConstData searchKey, ConstData entryData, unsigned maxlen = MaxAttrDataSize); int cmpScanBound(const Frag& frag, unsigned dir, ConstData boundInfo, unsigned boundCount, ConstData entryData, unsigned maxlen = MaxAttrDataSize); - int cmpScanBound(const Frag& frag, unsigned dir, ConstData boundInfo, unsigned boundCount, TableData entryKey); /* * DbtuxDebug.cpp @@ -679,17 +676,27 @@ private: Uint32 c_typeOfStart; /* - * Array of index key attribute ids in AttributeHeader format. - * Includes fixed attribute sizes. This is global data set at - * operation start and is not passed as a parameter. + * Global data set at operation start. Unpacked from index metadata. + * Not passed as parameter to methods. Invalid across timeslices. + * + * TODO inline all into index metadata */ + + // index key attr ids with sizes in AttributeHeader format Data c_keyAttrs; - // buffer for search key data as pointers to TUP storage - TableData c_searchKey; + // pointers to index key comparison functions + NdbSqlUtil::Cmp** c_sqlCmp; - // buffer for current entry key data as pointers to TUP storage - TableData c_entryKey; + /* + * Other buffers used during the operation. + */ + + // buffer for search key data with headers + Data c_searchKey; + + // buffer for current entry key data with headers + Data c_entryKey; // buffer for scan bounds and keyinfo (primary key) Data c_dataBuffer; diff --git a/ndb/src/kernel/blocks/dbtux/DbtuxCmp.cpp b/ndb/src/kernel/blocks/dbtux/DbtuxCmp.cpp index debb5252386..549720cc17c 100644 --- a/ndb/src/kernel/blocks/dbtux/DbtuxCmp.cpp +++ b/ndb/src/kernel/blocks/dbtux/DbtuxCmp.cpp @@ -18,21 +18,24 @@ #include "Dbtux.hpp" /* - * Search key vs node prefix. + * Search key vs node prefix or entry * - * The comparison starts at given attribute position (in fact 0). The - * position is updated by number of equal initial attributes found. The - * prefix may be partial in which case CmpUnknown may be returned. + * The comparison starts at given attribute position. The position is + * updated by number of equal initial attributes found. The entry data + * may be partial in which case CmpUnknown may be returned. */ int -Dbtux::cmpSearchKey(const Frag& frag, unsigned& start, TableData searchKey, ConstData entryData, unsigned maxlen) +Dbtux::cmpSearchKey(const Frag& frag, unsigned& start, ConstData searchKey, ConstData entryData, unsigned maxlen) { const unsigned numAttrs = frag.m_numAttrs; const DescEnt& descEnt = getDescEnt(frag.m_descPage, frag.m_descOff); // number of words of attribute data left unsigned len2 = maxlen; - // skip to right position in search key - searchKey += start; + // skip to right position in search key only + for (unsigned i = 0; i < start; i++) { + jam(); + searchKey += AttributeHeaderSize + searchKey.ah().getDataSize(); + } int ret = 0; while (start < numAttrs) { if (len2 <= AttributeHeaderSize) { @@ -41,22 +44,21 @@ Dbtux::cmpSearchKey(const Frag& frag, unsigned& start, TableData searchKey, Cons break; } len2 -= AttributeHeaderSize; - if (*searchKey != 0) { + if (! searchKey.ah().isNULL()) { if (! entryData.ah().isNULL()) { jam(); // current attribute const DescAttr& descAttr = descEnt.m_descAttr[start]; - const NdbSqlUtil::Type& type = NdbSqlUtil::getType(descAttr.m_typeId); - ndbassert(type.m_typeId != NdbSqlUtil::Type::Undefined); // full data size const unsigned size1 = AttributeDescriptor::getSizeInWords(descAttr.m_attrDesc); ndbrequire(size1 != 0 && size1 == entryData.ah().getDataSize()); const unsigned size2 = min(size1, len2); len2 -= size2; // compare - const Uint32* const p1 = *searchKey; + NdbSqlUtil::Cmp* const cmp = c_sqlCmp[start]; + const Uint32* const p1 = &searchKey[AttributeHeaderSize]; const Uint32* const p2 = &entryData[AttributeHeaderSize]; - ret = (*type.m_cmp)(p1, p2, size1, size2); + ret = (*cmp)(0, p1, p2, size1, size2); if (ret != 0) { jam(); break; @@ -75,7 +77,7 @@ Dbtux::cmpSearchKey(const Frag& frag, unsigned& start, TableData searchKey, Cons break; } } - searchKey += 1; + searchKey += AttributeHeaderSize + searchKey.ah().getDataSize(); entryData += AttributeHeaderSize + entryData.ah().getDataSize(); start++; } @@ -83,60 +85,7 @@ Dbtux::cmpSearchKey(const Frag& frag, unsigned& start, TableData searchKey, Cons } /* - * Search key vs tree entry. - * - * Start position is updated as in previous routine. - */ -int -Dbtux::cmpSearchKey(const Frag& frag, unsigned& start, TableData searchKey, TableData entryKey) -{ - const unsigned numAttrs = frag.m_numAttrs; - const DescEnt& descEnt = getDescEnt(frag.m_descPage, frag.m_descOff); - // skip to right position - searchKey += start; - entryKey += start; - int ret = 0; - while (start < numAttrs) { - if (*searchKey != 0) { - if (*entryKey != 0) { - jam(); - // current attribute - const DescAttr& descAttr = descEnt.m_descAttr[start]; - const NdbSqlUtil::Type& type = NdbSqlUtil::getType(descAttr.m_typeId); - ndbassert(type.m_typeId != NdbSqlUtil::Type::Undefined); - // full data size - const unsigned size1 = AttributeDescriptor::getSizeInWords(descAttr.m_attrDesc); - // compare - const Uint32* const p1 = *searchKey; - const Uint32* const p2 = *entryKey; - ret = (*type.m_cmp)(p1, p2, size1, size1); - if (ret != 0) { - jam(); - break; - } - } else { - jam(); - // not NULL > NULL - ret = +1; - break; - } - } else { - if (*entryKey != 0) { - jam(); - // NULL < not NULL - ret = -1; - break; - } - } - searchKey += 1; - entryKey += 1; - start++; - } - return ret; -} - -/* - * Scan bound vs node prefix. + * Scan bound vs node prefix or entry. * * Compare lower or upper bound and index attribute data. The attribute * data may be partial in which case CmpUnknown may be returned. @@ -183,9 +132,8 @@ Dbtux::cmpScanBound(const Frag& frag, unsigned dir, ConstData boundInfo, unsigne jam(); // current attribute const unsigned index = boundInfo.ah().getAttributeId(); + ndbrequire(index < frag.m_numAttrs); const DescAttr& descAttr = descEnt.m_descAttr[index]; - const NdbSqlUtil::Type& type = NdbSqlUtil::getType(descAttr.m_typeId); - ndbassert(type.m_typeId != NdbSqlUtil::Type::Undefined); ndbrequire(entryData.ah().getAttributeId() == descAttr.m_primaryAttrId); // full data size const unsigned size1 = boundInfo.ah().getDataSize(); @@ -193,9 +141,10 @@ Dbtux::cmpScanBound(const Frag& frag, unsigned dir, ConstData boundInfo, unsigne const unsigned size2 = min(size1, len2); len2 -= size2; // compare + NdbSqlUtil::Cmp* const cmp = c_sqlCmp[index]; const Uint32* const p1 = &boundInfo[AttributeHeaderSize]; const Uint32* const p2 = &entryData[AttributeHeaderSize]; - int ret = (*type.m_cmp)(p1, p2, size1, size2); + int ret = (*cmp)(0, p1, p2, size1, size2); if (ret != 0) { jam(); return ret; @@ -244,72 +193,3 @@ Dbtux::cmpScanBound(const Frag& frag, unsigned dir, ConstData boundInfo, unsigne return +1; } } - -/* - * Scan bound vs tree entry. - */ -int -Dbtux::cmpScanBound(const Frag& frag, unsigned dir, ConstData boundInfo, unsigned boundCount, TableData entryKey) -{ - const DescEnt& descEnt = getDescEnt(frag.m_descPage, frag.m_descOff); - // direction 0-lower 1-upper - ndbrequire(dir <= 1); - // initialize type to equality - unsigned type = 4; - while (boundCount != 0) { - // get and skip bound type - type = boundInfo[0]; - boundInfo += 1; - if (! boundInfo.ah().isNULL()) { - if (*entryKey != 0) { - jam(); - // current attribute - const unsigned index = boundInfo.ah().getAttributeId(); - const DescAttr& descAttr = descEnt.m_descAttr[index]; - const NdbSqlUtil::Type& type = NdbSqlUtil::getType(descAttr.m_typeId); - ndbassert(type.m_typeId != NdbSqlUtil::Type::Undefined); - // full data size - const unsigned size1 = AttributeDescriptor::getSizeInWords(descAttr.m_attrDesc); - // compare - const Uint32* const p1 = &boundInfo[AttributeHeaderSize]; - const Uint32* const p2 = *entryKey; - int ret = (*type.m_cmp)(p1, p2, size1, size1); - if (ret != 0) { - jam(); - return ret; - } - } else { - jam(); - // not NULL > NULL - return +1; - } - } else { - jam(); - if (*entryKey != 0) { - jam(); - // NULL < not NULL - return -1; - } - } - boundInfo += AttributeHeaderSize + boundInfo.ah().getDataSize(); - entryKey += 1; - boundCount -= 1; - } - if (dir == 0) { - // lower bound - jam(); - if (type == 1) { - jam(); - return +1; - } - return -1; - } else { - // upper bound - jam(); - if (type == 3) { - jam(); - return -1; - } - return +1; - } -} diff --git a/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp b/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp index 11f4f12b7f6..8d31d2c6a55 100644 --- a/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp +++ b/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp @@ -207,14 +207,10 @@ Dbtux::printNode(Signal* signal, Frag& frag, NdbOut& out, TupLoc loc, PrintPar& } // check ordering within node for (unsigned j = 1; j < node.getOccup(); j++) { - unsigned start = 0; const TreeEnt ent1 = node.getEnt(j - 1); const TreeEnt ent2 = node.getEnt(j); - if (j == 1) { - readKeyAttrs(frag, ent1, start, c_searchKey); - } else { - memcpy(c_searchKey, c_entryKey, frag.m_numAttrs << 2); - } + unsigned start = 0; + readKeyAttrs(frag, ent1, start, c_searchKey); readKeyAttrs(frag, ent2, start, c_entryKey); int ret = cmpSearchKey(frag, start, c_searchKey, c_entryKey); if (ret == 0) diff --git a/ndb/src/kernel/blocks/dbtux/DbtuxGen.cpp b/ndb/src/kernel/blocks/dbtux/DbtuxGen.cpp index f6f1610c8c1..39cd8e25184 100644 --- a/ndb/src/kernel/blocks/dbtux/DbtuxGen.cpp +++ b/ndb/src/kernel/blocks/dbtux/DbtuxGen.cpp @@ -16,8 +16,6 @@ #define DBTUX_GEN_CPP #include "Dbtux.hpp" -#include -#include Dbtux::Dbtux(const Configuration& conf) : SimulatedBlock(DBTUX, conf), @@ -202,8 +200,9 @@ Dbtux::execREAD_CONFIG_REQ(Signal* signal) } // allocate buffers c_keyAttrs = (Uint32*)allocRecord("c_keyAttrs", sizeof(Uint32), MaxIndexAttributes); - c_searchKey = (TableData)allocRecord("c_searchKey", sizeof(Uint32*), MaxIndexAttributes); - c_entryKey = (TableData)allocRecord("c_entryKey", sizeof(Uint32*), MaxIndexAttributes); + c_sqlCmp = (NdbSqlUtil::Cmp**)allocRecord("c_sqlCmp", sizeof(NdbSqlUtil::Cmp*), MaxIndexAttributes); + c_searchKey = (Uint32*)allocRecord("c_searchKey", sizeof(Uint32), MaxAttrDataSize); + c_entryKey = (Uint32*)allocRecord("c_entryKey", sizeof(Uint32), MaxAttrDataSize); c_dataBuffer = (Uint32*)allocRecord("c_dataBuffer", sizeof(Uint64), (MaxAttrDataSize + 1) >> 1); // ack ReadConfigConf * conf = (ReadConfigConf*)signal->getDataPtrSend(); @@ -218,7 +217,8 @@ Dbtux::execREAD_CONFIG_REQ(Signal* signal) void Dbtux::setKeyAttrs(const Frag& frag) { - Data keyAttrs = c_keyAttrs; // global + Data keyAttrs = c_keyAttrs; // global + NdbSqlUtil::Cmp** sqlCmp = c_sqlCmp; // global const unsigned numAttrs = frag.m_numAttrs; const DescEnt& descEnt = getDescEnt(frag.m_descPage, frag.m_descOff); for (unsigned i = 0; i < numAttrs; i++) { @@ -227,75 +227,71 @@ Dbtux::setKeyAttrs(const Frag& frag) // set attr id and fixed size keyAttrs.ah() = AttributeHeader(descAttr.m_primaryAttrId, size); keyAttrs += 1; + // set comparison method pointer + const NdbSqlUtil::Type& sqlType = NdbSqlUtil::getTypeBinary(descAttr.m_typeId); + ndbrequire(sqlType.m_cmp != 0); + *(sqlCmp++) = sqlType.m_cmp; } } void -Dbtux::readKeyAttrs(const Frag& frag, TreeEnt ent, unsigned start, TableData keyData) +Dbtux::readKeyAttrs(const Frag& frag, TreeEnt ent, unsigned start, Data keyData) { ConstData keyAttrs = c_keyAttrs; // global const Uint32 tableFragPtrI = frag.m_tupTableFragPtrI[ent.m_fragBit]; const TupLoc tupLoc = ent.m_tupLoc; const Uint32 tupVersion = ent.m_tupVersion; ndbrequire(start < frag.m_numAttrs); - const unsigned numAttrs = frag.m_numAttrs - start; - // start applies to both keys and output data + const Uint32 numAttrs = frag.m_numAttrs - start; + // skip to start position in keyAttrs only keyAttrs += start; - keyData += start; - c_tup->tuxReadAttrs(tableFragPtrI, tupLoc.m_pageId, tupLoc.m_pageOffset, tupVersion, numAttrs, keyAttrs, keyData); + int ret = c_tup->tuxReadAttrs(tableFragPtrI, tupLoc.m_pageId, tupLoc.m_pageOffset, tupVersion, keyAttrs, numAttrs, keyData); jamEntry(); + // TODO handle error + ndbrequire(ret > 0); } void -Dbtux::readTablePk(const Frag& frag, TreeEnt ent, unsigned& pkSize, Data pkData) +Dbtux::readTablePk(const Frag& frag, TreeEnt ent, Data pkData, unsigned& pkSize) { const Uint32 tableFragPtrI = frag.m_tupTableFragPtrI[ent.m_fragBit]; const TupLoc tupLoc = ent.m_tupLoc; - Uint32 size = 0; - c_tup->tuxReadKeys(tableFragPtrI, tupLoc.m_pageId, tupLoc.m_pageOffset, &size, pkData); - ndbrequire(size != 0); - pkSize = size; + int ret = c_tup->tuxReadPk(tableFragPtrI, tupLoc.m_pageId, tupLoc.m_pageOffset, pkData); + jamEntry(); + // TODO handle error + ndbrequire(ret > 0); + pkSize = ret; } /* - * Input is pointers to table attributes. Output is array of attribute - * data with headers. Copies whatever fits. + * Copy attribute data with headers. Input is all index key data. + * Copies whatever fits. */ void -Dbtux::copyAttrs(const Frag& frag, TableData data1, Data data2, unsigned maxlen2) +Dbtux::copyAttrs(const Frag& frag, ConstData data1, Data data2, unsigned maxlen2) { - ConstData keyAttrs = c_keyAttrs; // global - const unsigned numAttrs = frag.m_numAttrs; + unsigned n = frag.m_numAttrs; unsigned len2 = maxlen2; - for (unsigned n = 0; n < numAttrs; n++) { + while (n != 0) { jam(); - const unsigned attrId = keyAttrs.ah().getAttributeId(); - const unsigned dataSize = keyAttrs.ah().getDataSize(); - const Uint32* const p1 = *data1; - if (p1 != 0) { + const unsigned dataSize = data1.ah().getDataSize(); + // copy header + if (len2 == 0) + return; + data2[0] = data1[0]; + data1 += 1; + data2 += 1; + len2 -= 1; + // copy data + for (unsigned i = 0; i < dataSize; i++) { if (len2 == 0) return; - data2.ah() = AttributeHeader(attrId, dataSize); - data2 += 1; - len2 -= 1; - unsigned n = dataSize; - for (unsigned i = 0; i < dataSize; i++) { - if (len2 == 0) - return; - *data2 = p1[i]; - data2 += 1; - len2 -= 1; - } - } else { - if (len2 == 0) - return; - data2.ah() = AttributeHeader(attrId, 0); - data2.ah().setNULL(); - data2 += 1; + data2[i] = data1[i]; len2 -= 1; } - keyAttrs += 1; - data1 += 1; + data1 += dataSize; + data2 += dataSize; + n -= 1; } #ifdef VM_TRACE memset(data2, DataFillByte, len2 << 2); diff --git a/ndb/src/kernel/blocks/dbtux/DbtuxMeta.cpp b/ndb/src/kernel/blocks/dbtux/DbtuxMeta.cpp index 4bb3b940d91..3c0af3ca79d 100644 --- a/ndb/src/kernel/blocks/dbtux/DbtuxMeta.cpp +++ b/ndb/src/kernel/blocks/dbtux/DbtuxMeta.cpp @@ -178,19 +178,31 @@ Dbtux::execTUX_ADD_ATTRREQ(Signal* signal) descAttr.m_attrDesc = req->attrDescriptor; descAttr.m_primaryAttrId = req->primaryAttrId; descAttr.m_typeId = req->extTypeInfo & 0xFF; + descAttr.m_charset = (req->extTypeInfo >> 16); #ifdef VM_TRACE if (debugFlags & DebugMeta) { debugOut << "Add frag " << fragPtr.i << " attr " << attrId << " " << descAttr << endl; } #endif - // check if type is valid and has a comparison method - const NdbSqlUtil::Type& type = NdbSqlUtil::getType(descAttr.m_typeId); + // check that type is valid and has a binary comparison method + const NdbSqlUtil::Type& type = NdbSqlUtil::getTypeBinary(descAttr.m_typeId); if (type.m_typeId == NdbSqlUtil::Type::Undefined || type.m_cmp == 0) { jam(); errorCode = TuxAddAttrRef::InvalidAttributeType; break; } +#ifdef dbtux_uses_charset + if (descAttr.m_charset != 0) { + CHARSET_INFO *cs = get_charset(descAttr.m_charset, MYF(0)); + // here use the non-binary type + if (! NdbSqlUtil::usable_in_ordered_index(descAttr.m_typeId, cs)) { + jam(); + errorCode = TuxAddAttrRef::InvalidCharset; + break; + } + } +#endif if (indexPtr.p->m_numAttrs == fragOpPtr.p->m_numAttrsRecvd) { jam(); // initialize tree header diff --git a/ndb/src/kernel/blocks/dbtux/DbtuxScan.cpp b/ndb/src/kernel/blocks/dbtux/DbtuxScan.cpp index c4c33ff931f..5b161d3c4ce 100644 --- a/ndb/src/kernel/blocks/dbtux/DbtuxScan.cpp +++ b/ndb/src/kernel/blocks/dbtux/DbtuxScan.cpp @@ -112,6 +112,7 @@ Dbtux::execACC_SCANREQ(Signal* signal) void Dbtux::execTUX_BOUND_INFO(Signal* signal) { + jamEntry(); struct BoundInfo { unsigned offset; unsigned size; @@ -389,7 +390,7 @@ Dbtux::execACC_CHECK_SCAN(Signal* signal) jam(); const TreeEnt ent = scan.m_scanPos.m_ent; // read tuple key - readTablePk(frag, ent, pkSize, pkData); + readTablePk(frag, ent, pkData, pkSize); // get read lock or exclusive lock AccLockReq* const lockReq = (AccLockReq*)signal->getDataPtrSend(); lockReq->returnCode = RNIL; @@ -480,7 +481,7 @@ Dbtux::execACC_CHECK_SCAN(Signal* signal) jam(); if (pkSize == 0) { jam(); - readTablePk(frag, ent, pkSize, pkData); + readTablePk(frag, ent, pkData, pkSize); } } // conf signal diff --git a/ndb/src/kernel/blocks/dbtux/DbtuxSearch.cpp b/ndb/src/kernel/blocks/dbtux/DbtuxSearch.cpp index 84048b308bc..bffbb8f5594 100644 --- a/ndb/src/kernel/blocks/dbtux/DbtuxSearch.cpp +++ b/ndb/src/kernel/blocks/dbtux/DbtuxSearch.cpp @@ -25,7 +25,7 @@ * TODO optimize for initial equal attrs in node min/max */ void -Dbtux::searchToAdd(Signal* signal, Frag& frag, TableData searchKey, TreeEnt searchEnt, TreePos& treePos) +Dbtux::searchToAdd(Signal* signal, Frag& frag, ConstData searchKey, TreeEnt searchEnt, TreePos& treePos) { const TreeHead& tree = frag.m_tree; const unsigned numAttrs = frag.m_numAttrs; @@ -144,7 +144,7 @@ Dbtux::searchToAdd(Signal* signal, Frag& frag, TableData searchKey, TreeEnt sear * to it. */ void -Dbtux::searchToRemove(Signal* signal, Frag& frag, TableData searchKey, TreeEnt searchEnt, TreePos& treePos) +Dbtux::searchToRemove(Signal* signal, Frag& frag, ConstData searchKey, TreeEnt searchEnt, TreePos& treePos) { const TreeHead& tree = frag.m_tree; const unsigned numAttrs = frag.m_numAttrs; diff --git a/ndb/src/kernel/blocks/dbtux/Times.txt b/ndb/src/kernel/blocks/dbtux/Times.txt index 84819ddcf97..03473353a52 100644 --- a/ndb/src/kernel/blocks/dbtux/Times.txt +++ b/ndb/src/kernel/blocks/dbtux/Times.txt @@ -83,7 +83,7 @@ optim 13 mc02/a 39 ms 59 ms 50 pct mc02/c 9 ms 12 ms 44 pct mc02/d 246 ms 289 ms 17 pct -[ case d: what happened to PK read performance? ] +[ case d: bug in testOIBasic killed PK read performance ] optim 14 mc02/a 41 ms 60 ms 44 pct mc02/b 46 ms 81 ms 73 pct @@ -91,5 +91,21 @@ optim 14 mc02/a 41 ms 60 ms 44 pct mc02/d 242 ms 285 ms 17 pct [ case b: do long keys suffer from many subroutine calls? ] +[ case d: bug in testOIBasic killed PK read performance ] + +none mc02/a 35 ms 60 ms 71 pct + mc02/b 42 ms 75 ms 76 pct + mc02/c 5 ms 12 ms 106 pct + mc02/d 165 ms 238 ms 44 pct + +[ johan re-installed mc02 as fedora gcc-3.3.2 ] +[ case c: table scan has improved... ] + +charsets mc02/a 35 ms 60 ms 71 pct + mc02/b 42 ms 84 ms 97 pct + mc02/c 5 ms 12 ms 109 pct + mc02/d 190 ms 236 ms 23 pct + +[ case b: TUX can no longer use pointers to TUP data ] vim: set et: diff --git a/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp b/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp index ff4876b1506..568ed6c6566 100644 --- a/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp +++ b/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp @@ -103,7 +103,7 @@ void Ndbcntr::execCONTINUEB(Signal* signal) } Uint64 now = NdbTick_CurrentMillisecond(); - if(c_start.m_startFailureTimeout > now){ + if(now > c_start.m_startFailureTimeout){ ndbrequire(false); } @@ -446,13 +446,17 @@ void Ndbcntr::execREAD_NODESCONF(Signal* signal) ndb_mgm_get_int_parameter(p, CFG_DB_START_PARTITION_TIMEOUT, &to_2); ndb_mgm_get_int_parameter(p, CFG_DB_START_FAILURE_TIMEOUT, &to_3); + c_start.m_startTime = NdbTick_CurrentMillisecond(); c_start.m_startPartialTimeout = setTimeout(c_start.m_startTime, to_1); c_start.m_startPartitionedTimeout = setTimeout(c_start.m_startTime, to_2); c_start.m_startFailureTimeout = setTimeout(c_start.m_startTime, to_3); - + UpgradeStartup::sendCmAppChg(* this, signal, 0); // ADD sendCntrStartReq(signal); + + signal->theData[0] = ZSTARTUP; + sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 1000, 1); return; } diff --git a/ndb/src/kernel/blocks/ndbcntr/NdbcntrSysTable.cpp b/ndb/src/kernel/blocks/ndbcntr/NdbcntrSysTable.cpp index 40e6aa2dcd7..2a65271a32a 100644 --- a/ndb/src/kernel/blocks/ndbcntr/NdbcntrSysTable.cpp +++ b/ndb/src/kernel/blocks/ndbcntr/NdbcntrSysTable.cpp @@ -46,7 +46,7 @@ Ndbcntr::g_sysTable_SYSTAB_0 = { static const Ndbcntr::SysColumn column_NDBEVENTS_0[] = { { 0, "NAME", - DictTabInfo::ExtChar, MAX_TAB_NAME_SIZE, + DictTabInfo::ExtBinary, MAX_TAB_NAME_SIZE, true, false }, { 1, "EVENT_TYPE", @@ -54,7 +54,7 @@ column_NDBEVENTS_0[] = { false, false }, { 2, "TABLE_NAME", - DictTabInfo::ExtChar, MAX_TAB_NAME_SIZE, + DictTabInfo::ExtBinary, MAX_TAB_NAME_SIZE, false, false }, { 3, "ATTRIBUTE_MASK", diff --git a/ndb/src/kernel/main.cpp b/ndb/src/kernel/main.cpp index 491733975a8..9c25da79065 100644 --- a/ndb/src/kernel/main.cpp +++ b/ndb/src/kernel/main.cpp @@ -19,6 +19,7 @@ #include #include "Configuration.hpp" +#include #include #include "vm/SimBlockList.hpp" @@ -56,6 +57,7 @@ const char programName[] = "NDB Kernel"; NDB_MAIN(ndb_kernel){ + ndb_init(); // Print to stdout/console g_eventLogger.createConsoleHandler(); g_eventLogger.setCategory("NDB"); @@ -66,12 +68,19 @@ NDB_MAIN(ndb_kernel){ // Parse command line options Configuration* theConfig = globalEmulatorData.theConfiguration; if(!theConfig->init(argc, argv)){ - return 0; + return NRT_Default; } + LocalConfig local_config; + if (!local_config.init(theConfig->getConnectString(),0)){ + local_config.printError(); + local_config.printUsage(); + return NRT_Default; + } + { // Do configuration signal(SIGPIPE, SIG_IGN); - theConfig->fetch_configuration(); + theConfig->fetch_configuration(local_config); } chdir(NdbConfig_get_path(0)); @@ -134,7 +143,7 @@ NDB_MAIN(ndb_kernel){ exit(0); } g_eventLogger.info("Ndb has terminated (pid %d) restarting", child); - theConfig->fetch_configuration(); + theConfig->fetch_configuration(local_config); } g_eventLogger.info("Angel pid: %d ndb pid: %d", getppid(), getpid()); @@ -243,6 +252,9 @@ systemInfo(const Configuration & config, const LogLevel & logLevel){ if(logLevel.getLogLevel(LogLevel::llStartUp) > 0){ g_eventLogger.info("NDB Cluster -- DB node %d", globalData.ownId); g_eventLogger.info("%s --", NDB_VERSION_STRING); + if (config.get_mgmd_host()) + g_eventLogger.info("Configuration fetched at %s port %d", + config.get_mgmd_host(), config.get_mgmd_port()); #ifdef NDB_SOLARIS // ok g_eventLogger.info("NDB is running on a machine with %d processor(s) at %d MHz", processor, speed); diff --git a/ndb/src/kernel/vm/Configuration.cpp b/ndb/src/kernel/vm/Configuration.cpp index 3099c71b792..fd5d79b92e7 100644 --- a/ndb/src/kernel/vm/Configuration.cpp +++ b/ndb/src/kernel/vm/Configuration.cpp @@ -15,8 +15,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include -#include +#include #include "Configuration.hpp" #include #include "GlobalData.hpp" @@ -105,7 +105,6 @@ Configuration::init(int argc, const char** argv){ } // check for depricated flag '-i' - my_init(); #ifndef DBUG_OFF if (debug_option) DBUG_PUSH(debug_option); @@ -186,7 +185,7 @@ Configuration::closeConfiguration(){ } void -Configuration::fetch_configuration(){ +Configuration::fetch_configuration(LocalConfig &local_config){ /** * Fetch configuration from management server */ @@ -194,21 +193,22 @@ Configuration::fetch_configuration(){ delete m_config_retriever; } - m_config_retriever= new ConfigRetriever(NDB_VERSION, NODE_TYPE_DB); - m_config_retriever->setConnectString(_connectString ? _connectString : ""); - if(m_config_retriever->init() == -1 || - m_config_retriever->do_connect() == -1){ - + m_mgmd_port= 0; + m_mgmd_host= 0; + m_config_retriever= new ConfigRetriever(local_config, NDB_VERSION, NODE_TYPE_DB); + if(m_config_retriever->do_connect() == -1){ const char * s = m_config_retriever->getErrorString(); if(s == 0) s = "No error given!"; - /* Set stop on error to true otherwise NDB will go into an restart loop... */ ERROR_SET(fatal, ERR_INVALID_CONFIG, "Could connect to ndb_mgmd", s); } + m_mgmd_port= m_config_retriever->get_mgmd_port(); + m_mgmd_host= m_config_retriever->get_mgmd_host(); + ConfigRetriever &cr= *m_config_retriever; if((globalData.ownId = cr.allocNodeId()) == 0){ @@ -418,6 +418,11 @@ Configuration::setRestartOnErrorInsert(int i){ m_restartOnErrorInsert = i; } +const char * +Configuration::getConnectString() const { + return _connectString; +} + char * Configuration::getConnectStringCopy() const { if(_connectString != 0) @@ -506,7 +511,7 @@ Configuration::calcSizeAlt(ConfigValues * ownConfig){ for(unsigned j = 0; jsetLogLevel((LogLevel::EventCategory)j, tmp); } } diff --git a/ndb/src/kernel/vm/Configuration.hpp b/ndb/src/kernel/vm/Configuration.hpp index e84ff8d9193..2ea32ffea37 100644 --- a/ndb/src/kernel/vm/Configuration.hpp +++ b/ndb/src/kernel/vm/Configuration.hpp @@ -21,6 +21,7 @@ #include class ConfigRetriever; +class LocalConfig; class Configuration { public: @@ -32,7 +33,7 @@ public: */ bool init(int argc, const char** argv); - void fetch_configuration(); + void fetch_configuration(LocalConfig &local_config); void setupConfiguration(); void closeConfiguration(); @@ -54,6 +55,7 @@ public: const char * programName() const; const char * fileSystemPath() const; const char * backupFilePath() const; + const char * getConnectString() const; char * getConnectStringCopy() const; /** @@ -65,6 +67,9 @@ public: const ndb_mgm_configuration_iterator * getOwnConfigIterator() const; + Uint32 get_mgmd_port() const {return m_mgmd_port;}; + const char *get_mgmd_host() const {return m_mgmd_host;}; + class LogLevel * m_logLevel; private: friend class Cmvmi; @@ -93,6 +98,8 @@ private: char * _backupPath; bool _initialStart; char * _connectString; + Uint32 m_mgmd_port; + const char *m_mgmd_host; bool _daemonMode; void calcSizeAlt(class ConfigValues * ); diff --git a/ndb/src/kernel/vm/FastScheduler.hpp b/ndb/src/kernel/vm/FastScheduler.hpp index 9749dab5d85..dc707e47eef 100644 --- a/ndb/src/kernel/vm/FastScheduler.hpp +++ b/ndb/src/kernel/vm/FastScheduler.hpp @@ -141,7 +141,7 @@ int FastScheduler::checkDoJob() { /* - * Joob buffer overload protetction + * Job buffer overload protetction * If the job buffer B is filled over a certain limit start * to execute the signals in the job buffer's */ diff --git a/ndb/src/kernel/vm/MetaData.hpp b/ndb/src/kernel/vm/MetaData.hpp index f6a941e8f9f..11e262664c1 100644 --- a/ndb/src/kernel/vm/MetaData.hpp +++ b/ndb/src/kernel/vm/MetaData.hpp @@ -107,6 +107,9 @@ public: /* Number of primary key attributes (should be computed) */ Uint16 noOfPrimkey; + /* Number of distinct character sets (computed) */ + Uint16 noOfCharsets; + /* Length of primary key in words (should be computed) */ /* For ordered index this is tree node size in words */ Uint16 tupKeyLength; diff --git a/ndb/src/mgmapi/mgmapi.cpp b/ndb/src/mgmapi/mgmapi.cpp index 08b83a8d750..fccd5c7983b 100644 --- a/ndb/src/mgmapi/mgmapi.cpp +++ b/ndb/src/mgmapi/mgmapi.cpp @@ -954,13 +954,52 @@ struct ndb_mgm_event_categories { const char* name; enum ndb_mgm_event_category category; +} categories[] = { + { "STARTUP", NDB_MGM_EVENT_CATEGORY_STARTUP }, + { "SHUTDOWN", NDB_MGM_EVENT_CATEGORY_SHUTDOWN }, + { "STATISTICS", NDB_MGM_EVENT_CATEGORY_STATISTIC }, + { "NODERESTART", NDB_MGM_EVENT_CATEGORY_NODE_RESTART }, + { "CONNECTION", NDB_MGM_EVENT_CATEGORY_CONNECTION }, + { "CHECKPOINT", NDB_MGM_EVENT_CATEGORY_CHECKPOINT }, + { "DEBUG", NDB_MGM_EVENT_CATEGORY_DEBUG }, + { "INFO", NDB_MGM_EVENT_CATEGORY_INFO }, + { "ERROR", NDB_MGM_EVENT_CATEGORY_ERROR }, + { "GREP", NDB_MGM_EVENT_CATEGORY_GREP }, + { "BACKUP", NDB_MGM_EVENT_CATEGORY_BACKUP }, + { 0, NDB_MGM_ILLEGAL_EVENT_CATEGORY } }; +extern "C" +ndb_mgm_event_category +ndb_mgm_match_event_category(const char * status) +{ + if(status == 0) + return NDB_MGM_ILLEGAL_EVENT_CATEGORY; + + for(int i = 0; categories[i].name !=0 ; i++) + if(strcmp(status, categories[i].name) == 0) + return categories[i].category; + + return NDB_MGM_ILLEGAL_EVENT_CATEGORY; +} + +extern "C" +const char * +ndb_mgm_get_event_category_string(enum ndb_mgm_event_category status) +{ + int i; + for(i = 0; categories[i].name != 0; i++) + if(categories[i].category == status) + return categories[i].name; + + return 0; +} + extern "C" int ndb_mgm_set_loglevel_clusterlog(NdbMgmHandle handle, int nodeId, - /*enum ndb_mgm_event_category*/ - char * category, int level, + enum ndb_mgm_event_category cat, + int level, struct ndb_mgm_reply* /*reply*/) { SET_ERROR(handle, NDB_MGM_NO_ERROR, @@ -975,14 +1014,14 @@ ndb_mgm_set_loglevel_clusterlog(NdbMgmHandle handle, int nodeId, Properties args; args.put("node", nodeId); - args.put("category", category); + args.put("category", cat); args.put("level", level); - + const Properties *reply; reply = ndb_mgm_call(handle, clusterlog_reply, "set cluster loglevel", &args); CHECK_REPLY(reply, -1); - + BaseString result; reply->get("result", result); if(strcmp(result.c_str(), "Ok") != 0) { @@ -997,8 +1036,8 @@ ndb_mgm_set_loglevel_clusterlog(NdbMgmHandle handle, int nodeId, extern "C" int ndb_mgm_set_loglevel_node(NdbMgmHandle handle, int nodeId, - /*enum ndb_mgm_event_category category*/ - char * category, int level, + enum ndb_mgm_event_category category, + int level, struct ndb_mgm_reply* /*reply*/) { SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_set_loglevel_node"); @@ -1030,6 +1069,48 @@ ndb_mgm_set_loglevel_node(NdbMgmHandle handle, int nodeId, return 0; } +extern "C" +int +ndb_mgm_listen_event(NdbMgmHandle handle, int filter[]) +{ + SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_listen_event"); + const ParserRow stat_reply[] = { + MGM_CMD("listen event", NULL, ""), + MGM_ARG("result", Int, Mandatory, "Error message"), + MGM_ARG("msg", String, Optional, "Error message"), + MGM_END() + }; + CHECK_HANDLE(handle, -1); + + SocketClient s(handle->hostname, handle->port); + const NDB_SOCKET_TYPE sockfd = s.connect(); + if (sockfd < 0) { + setError(handle, NDB_MGM_COULD_NOT_CONNECT_TO_SOCKET, __LINE__, + "Unable to connect to"); + return -1; + } + + Properties args; + { + BaseString tmp; + for(int i = 0; filter[i] != 0; i += 2){ + tmp.appfmt("%d=%d ", filter[i+1], filter[i]); + } + args.put("filter", tmp.c_str()); + } + + int tmp = handle->socket; + handle->socket = sockfd; + + const Properties *reply; + reply = ndb_mgm_call(handle, stat_reply, "listen event", &args); + + handle->socket = tmp; + + CHECK_REPLY(reply, -1); + return sockfd; +} + extern "C" int ndb_mgm_get_stat_port(NdbMgmHandle handle, struct ndb_mgm_reply* /*reply*/) diff --git a/ndb/src/mgmclient/CommandInterpreter.cpp b/ndb/src/mgmclient/CommandInterpreter.cpp index 91d057f8c30..fbb74d7c151 100644 --- a/ndb/src/mgmclient/CommandInterpreter.cpp +++ b/ndb/src/mgmclient/CommandInterpreter.cpp @@ -611,9 +611,9 @@ CommandInterpreter::executeHelp(char* parameters) << endl; ndbout << " = "; - for(Uint32 i = 0; inode_states[i].node_id; else { - ndbout << "Unable to locate management server, shutdown manually with #STOP" + ndbout << "Unable to locate management server, " + << "shutdown manually with STOP" << endl; + return; } } } @@ -721,11 +723,13 @@ const char *status_string(ndb_mgm_node_status status) static void print_nodes(ndb_mgm_cluster_state *state, ndb_mgm_configuration_iterator *it, - const char *proc_name, int no_proc, ndb_mgm_node_type type, int master_id) + const char *proc_name, int no_proc, ndb_mgm_node_type type, + int master_id) { int i; ndbout << "[" << proc_name - << "(" << ndb_mgm_get_node_type_string(type) << ")]\t" << no_proc << " node(s)" << endl; + << "(" << ndb_mgm_get_node_type_string(type) << ")]\t" + << no_proc << " node(s)" << endl; for(i=0; i < state->no_of_nodes; i++) { struct ndb_mgm_node_state *node_state= &(state->node_states[i]); if(node_state->node_type == type) { @@ -733,7 +737,9 @@ print_nodes(ndb_mgm_cluster_state *state, ndb_mgm_configuration_iterator *it, ndbout << "id=" << node_id; if(node_state->version != 0) { const char *hostname= node_state->connect_address; - if (hostname == 0 || strlen(hostname) == 0 || strcmp(hostname,"0.0.0.0") == 0) + if (hostname == 0 + || strlen(hostname) == 0 + || strcmp(hostname,"0.0.0.0") == 0) ndbout << " "; else ndbout << "\t@" << hostname; @@ -761,7 +767,8 @@ print_nodes(ndb_mgm_cluster_state *state, ndb_mgm_configuration_iterator *it, ndb_mgm_get_string_parameter(it, CFG_NODE_HOST, &config_hostname); if (config_hostname == 0 || config_hostname[0] == 0) config_hostname= "any host"; - ndbout << " (not connected, accepting connect from " << config_hostname << ")" << endl; + ndbout << " (not connected, accepting connect from " + << config_hostname << ")" << endl; } } } @@ -1240,55 +1247,40 @@ CommandInterpreter::executeLogLevel(int processId, const char* parameters, { connect(); (void) all; - (void) parameters; - SetLogLevelOrd logLevel; logLevel.clear(); - LogLevel::EventCategory cat; - int level; - if (emptyString(parameters) || (strcmp(parameters, "ALL") == 0)) { - for(Uint32 i = 0; i 15){ - ndbout << "Invalid loglevel specification row, level 0-15" << endl; - free(tmpString); - return ; - } - logLevel.setLogLevel(cat, level); - - item = strtok_r(NULL, ", ", &tmpPtr); - } - free(tmpString); + BaseString tmp(parameters); + Vector spec; + tmp.split(spec, "="); + if(spec.size() != 2){ + ndbout << "Invalid loglevel specification: " << parameters << endl; + return; } + spec[0].trim().ndb_toupper(); + int category = ndb_mgm_match_event_category(spec[0].c_str()); + if(category == NDB_MGM_ILLEGAL_EVENT_CATEGORY){ + category = atoi(spec[0].c_str()); + if(category < NDB_MGM_MIN_EVENT_CATEGORY || + category > NDB_MGM_MAX_EVENT_CATEGORY){ + ndbout << "Unknown category: \"" << spec[0].c_str() << "\"" << endl; + return; + } + } + + int level = atoi(spec[1].c_str()); + if(level < 0 || level > 15){ + ndbout << "Invalid level: " << spec[1].c_str() << endl; + return; + } + struct ndb_mgm_reply reply; int result; result = ndb_mgm_set_loglevel_node(m_mgmsrv, - processId, // fast fix - pekka - (char*)EventLogger::getEventCategoryName(cat), + processId, + (ndb_mgm_event_category)category, level, &reply); - + if (result < 0) { ndbout_c("Executing LOGLEVEL on node %d failed.", processId); printError(); @@ -1296,7 +1288,7 @@ CommandInterpreter::executeLogLevel(int processId, const char* parameters, ndbout << "Executing LOGLEVEL on node " << processId << " OK!" << endl; } - + } //***************************************************************************** @@ -1626,54 +1618,41 @@ CommandInterpreter::executeEventReporting(int processId, bool all) { connect(); - SetLogLevelOrd logLevel; logLevel.clear(); - char categoryTxt[255]; - int level; - LogLevel::EventCategory cat; - if (emptyString(parameters) || (strcmp(parameters, "ALL") == 0)) { - for(Uint32 i = 0; i 15){ - ndbout << "Invalid loglevel specification row, level 0-15" << endl; - free(tmpString); - return ; - } - logLevel.setLogLevel(cat, level); - - item = strtok_r(NULL, ", ", &tmpPtr); - } - free(tmpString); + BaseString tmp(parameters); + Vector spec; + tmp.split(spec, "="); + if(spec.size() != 2){ + ndbout << "Invalid loglevel specification: " << parameters << endl; + return; } + + spec[0].trim().ndb_toupper(); + int category = ndb_mgm_match_event_category(spec[0].c_str()); + if(category == NDB_MGM_ILLEGAL_EVENT_CATEGORY){ + category = atoi(spec[0].c_str()); + if(category < NDB_MGM_MIN_EVENT_CATEGORY || + category > NDB_MGM_MAX_EVENT_CATEGORY){ + ndbout << "Unknown category: \"" << spec[0].c_str() << "\"" << endl; + return; + } + } + + int level = atoi(spec[1].c_str()); + if(level < 0 || level > 15){ + ndbout << "Invalid level: " << spec[1].c_str() << endl; + return; + } + + struct ndb_mgm_reply reply; int result; - result = - ndb_mgm_set_loglevel_clusterlog(m_mgmsrv, - processId, // fast fix - pekka - (char*) - EventLogger::getEventCategoryName(cat), - level, - &reply); + result = ndb_mgm_set_loglevel_clusterlog(m_mgmsrv, + processId, // fast fix - pekka + (ndb_mgm_event_category)category, + level, + &reply); if (result != 0) { ndbout_c("Executing CLUSTERLOG on node %d failed", processId); @@ -1693,13 +1672,45 @@ CommandInterpreter::executeStartBackup(char* /*parameters*/) connect(); struct ndb_mgm_reply reply; unsigned int backupId; + + int filter[] = { 15, NDB_MGM_EVENT_CATEGORY_BACKUP, 0 }; + int fd = ndb_mgm_listen_event(m_mgmsrv, filter); int result = ndb_mgm_start_backup(m_mgmsrv, &backupId, &reply); if (result != 0) { ndbout << "Start of backup failed" << endl; printError(); - } else { - ndbout << "Backup started. Backup id " << backupId << "." << endl; + close(fd); + return; } + + char *tmp; + char buf[1024]; + { + SocketInputStream in(fd); + int count = 0; + do { + tmp = in.gets(buf, 1024); + if(tmp) + { + ndbout << tmp; + int id; + if(sscanf(tmp, "%*[^:]: Backup %d ", &id) == 1 && id == backupId){ + count++; + } + } + } while(count < 2); + } + + SocketInputStream in(fd, 10); + do { + tmp = in.gets(buf, 1024); + if(tmp && tmp[0] != 0) + { + ndbout << tmp; + } + } while(tmp && tmp[0] != 0); + + close(fd); } void diff --git a/ndb/src/mgmclient/Makefile.am b/ndb/src/mgmclient/Makefile.am index 72ddc9d098b..e271c7bed53 100644 --- a/ndb/src/mgmclient/Makefile.am +++ b/ndb/src/mgmclient/Makefile.am @@ -16,7 +16,7 @@ LDADD_LOC = $(top_builddir)/ndb/src/libndbclient.la \ $(top_builddir)/dbug/libdbug.a \ $(top_builddir)/mysys/libmysys.a \ $(top_builddir)/strings/libmystrings.a \ - @TERMCAP_LIB@ + @TERMCAP_LIB@ @NDB_SCI_LIBS@ ndb_mgm_LDFLAGS = @ndb_bin_am_ldflags@ diff --git a/ndb/src/mgmclient/main.cpp b/ndb/src/mgmclient/main.cpp index df6659df0b1..69f968677cd 100644 --- a/ndb/src/mgmclient/main.cpp +++ b/ndb/src/mgmclient/main.cpp @@ -44,6 +44,7 @@ handler(int sig){ } int main(int argc, const char** argv){ + ndb_init(); int optind = 0; const char *_host = 0; int _port = 0; diff --git a/ndb/src/mgmsrv/CommandInterpreter.cpp b/ndb/src/mgmsrv/CommandInterpreter.cpp index 316b6d5795e..2c2aeda21ed 100644 --- a/ndb/src/mgmsrv/CommandInterpreter.cpp +++ b/ndb/src/mgmsrv/CommandInterpreter.cpp @@ -52,7 +52,7 @@ static const char* helpTexts[] = { "{|ALL} CLUSTERLOG {=}+ Set log level for cluster log", "QUIT Quit management server", }; -static const int noOfHelpTexts = sizeof(helpTexts)/sizeof(const char*); +static const unsigned noOfHelpTexts = sizeof(helpTexts)/sizeof(const char*); static const char* helpTextShow = "SHOW prints NDB Cluster information\n\n" @@ -389,14 +389,14 @@ void CommandInterpreter::executeHelp(char* parameters) { << endl; ndbout << " = "; - for(i = 0; i = " << "0 - 15" << endl; @@ -831,12 +831,13 @@ void CommandInterpreter::executeStatus(int processId, //***************************************************************************** void CommandInterpreter::executeLogLevel(int processId, const char* parameters, bool all) { +#if 0 (void)all; // Don't want compiler warning SetLogLevelOrd logLevel; logLevel.clear(); if (emptyString(parameters) || (strcmp(parameters, "ALL") == 0)) { - for(Uint32 i = 0; iget("NodeId1", &id1)); require(ctx.m_currentSection->get("NodeId2", &id2)); + require(ctx.m_currentSection->get("HostName1", &hostName1)); + require(ctx.m_currentSection->get("HostName2", &hostName2)); + DBUG_PRINT("info",("NodeId1=%d HostName1=\"%s\"",id1,hostName1)); + DBUG_PRINT("info",("NodeId2=%d HostName2=\"%s\"",id2,hostName2)); + if (id1 > id2) { Uint32 tmp= id1; + const char *tmp_name= hostName1; + hostName1= hostName2; id1= id2; + hostName2= tmp_name; id2= tmp; } const Properties * node; require(ctx.m_config->get("Node", id1, &node)); - BaseString hostname; - require(node->get("HostName", hostname)); + BaseString hostname(hostName1); + // require(node->get("HostName", hostname)); if (hostname.c_str()[0] == 0) { - ctx.reportError("Hostname required on nodeid %d since it will act as server.", id1); + ctx.reportError("Hostname required on nodeid %d since it will " + "act as server.", id1); DBUG_RETURN(false); } Uint32 port= 0; - if (!node->get("ServerPort", &port) && !ctx.m_userProperties.get("ServerPort_", id1, &port)) { + if (!node->get("ServerPort", &port) && + !ctx.m_userProperties.get("ServerPort_", id1, &port)) { Uint32 adder= 0; { BaseString server_port_adder(hostname); @@ -2932,7 +3007,8 @@ fixPortNumber(InitConfigFileParser::Context & ctx, const char * data){ Uint32 base= 0; if (!ctx.m_userProperties.get("ServerPortBase", &base)){ - if(!(ctx.m_userDefaults && ctx.m_userDefaults->get("PortNumber", &base)) && + if(!(ctx.m_userDefaults && + ctx.m_userDefaults->get("PortNumber", &base)) && !ctx.m_systemDefaults->get("PortNumber", &base)) { base= strtoll(NDB_BASE_PORT,0,0)+2; // ctx.reportError("Cannot retrieve base port number"); @@ -2945,12 +3021,15 @@ fixPortNumber(InitConfigFileParser::Context & ctx, const char * data){ } if(ctx.m_currentSection->contains("PortNumber")) { - ndbout << "PortNumber should no longer be specificied per connection, please remove from config. Will be changed to " << port << endl; + ndbout << "PortNumber should no longer be specificied " + << "per connection, please remove from config. " + << "Will be changed to " << port << endl; ctx.m_currentSection->put("PortNumber", port, true); } else ctx.m_currentSection->put("PortNumber", port); - DBUG_PRINT("info", ("connection %d-%d port %d host %s", id1, id2, port, hostname.c_str())); + DBUG_PRINT("info", ("connection %d-%d port %d host %s", + id1, id2, port, hostname.c_str())); DBUG_RETURN(true); } diff --git a/ndb/src/mgmsrv/Makefile.am b/ndb/src/mgmsrv/Makefile.am index 8fa9ec5f63e..3b57b027827 100644 --- a/ndb/src/mgmsrv/Makefile.am +++ b/ndb/src/mgmsrv/Makefile.am @@ -12,8 +12,6 @@ ndb_mgmd_SOURCES = \ main.cpp \ Services.cpp \ convertStrToInt.cpp \ - NodeLogLevel.cpp \ - NodeLogLevelList.cpp \ SignalQueue.cpp \ MgmtSrvrConfig.cpp \ ConfigInfo.cpp \ @@ -29,7 +27,7 @@ LDADD_LOC = $(top_builddir)/ndb/src/libndbclient.la \ $(top_builddir)/ndb/src/common/editline/libeditline.a \ $(top_builddir)/dbug/libdbug.a \ $(top_builddir)/mysys/libmysys.a \ - $(top_builddir)/strings/libmystrings.a + $(top_builddir)/strings/libmystrings.a @NDB_SCI_LIBS@ @TERMCAP_LIB@ DEFS_LOC = -DDEFAULT_MYSQL_HOME="\"$(MYSQLBASEdir)\"" \ diff --git a/ndb/src/mgmsrv/MgmtSrvr.cpp b/ndb/src/mgmsrv/MgmtSrvr.cpp index 8380f3fd86a..92a8025295f 100644 --- a/ndb/src/mgmsrv/MgmtSrvr.cpp +++ b/ndb/src/mgmsrv/MgmtSrvr.cpp @@ -15,7 +15,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include -#include +#include #include "MgmtSrvr.hpp" #include "MgmtErrorReporter.hpp" @@ -45,7 +45,6 @@ #include #include -#include "NodeLogLevel.hpp" #include #include @@ -62,71 +61,16 @@ #endif extern int global_flag_send_heartbeat_now; - -static -void -CmdBackupCallback(const MgmtSrvr::BackupEvent & event) -{ - char str[255]; - - ndbout << endl; - - bool ok = false; - switch(event.Event){ - case MgmtSrvr::BackupEvent::BackupStarted: - ok = true; - snprintf(str, sizeof(str), - "Backup %d started", event.Started.BackupId); - break; - case MgmtSrvr::BackupEvent::BackupFailedToStart: - ok = true; - snprintf(str, sizeof(str), - "Backup failed to start (Error %d)", - event.FailedToStart.ErrorCode); - break; - case MgmtSrvr::BackupEvent::BackupCompleted: - ok = true; - snprintf(str, sizeof(str), - "Backup %d completed", - event.Completed.BackupId); - ndbout << str << endl; - - snprintf(str, sizeof(str), - " StartGCP: %d StopGCP: %d", - event.Completed.startGCP, event.Completed.stopGCP); - ndbout << str << endl; - - snprintf(str, sizeof(str), - " #Records: %d #LogRecords: %d", - event.Completed.NoOfRecords, event.Completed.NoOfLogRecords); - ndbout << str << endl; - - snprintf(str, sizeof(str), - " Data: %d bytes Log: %d bytes", - event.Completed.NoOfBytes, event.Completed.NoOfLogBytes); - break; - case MgmtSrvr::BackupEvent::BackupAborted: - ok = true; - snprintf(str, sizeof(str), - "Backup %d has been aborted reason %d", - event.Aborted.BackupId, - event.Aborted.Reason); - break; - } - if(!ok){ - snprintf(str, sizeof(str), "Unknown backup event: %d", event.Event); - } - ndbout << str << endl; -} - +extern int g_no_nodeid_checks; void * MgmtSrvr::logLevelThread_C(void* m) { MgmtSrvr *mgm = (MgmtSrvr*)m; - + my_thread_init(); mgm->logLevelThreadRun(); + my_thread_end(); NdbThread_Exit(0); /* NOTREACHED */ return 0; @@ -136,9 +80,10 @@ void * MgmtSrvr::signalRecvThread_C(void *m) { MgmtSrvr *mgm = (MgmtSrvr*)m; - + my_thread_init(); mgm->signalRecvThreadRun(); + my_thread_end(); NdbThread_Exit(0); /* NOTREACHED */ return 0; @@ -188,44 +133,65 @@ MgmtSrvr::signalRecvThreadRun() EventLogger g_EventLogger; +static NdbOut& +operator<<(NdbOut& out, const LogLevel & ll) +{ + out << "[LogLevel: "; + for(size_t i = 0; inext()) != NULL) { - if (n->getNodeId() == _startedNodeId) { - setNodeLogLevel(_startedNodeId, n->getLogLevelOrd(), true); - } + SetLogLevelOrd ord; + + m_started_nodes.lock(); + while(m_started_nodes.size() > 0){ + Uint32 node = m_started_nodes[0]; + m_started_nodes.erase(0, false); + m_started_nodes.unlock(); + + setEventReportingLevelImpl(node, req); + + ord = m_nodeLogLevel[node]; + setNodeLogLevelImpl(node, ord); + + m_started_nodes.lock(); + } + m_started_nodes.unlock(); + + m_log_level_requests.lock(); + while(m_log_level_requests.size() > 0){ + req = m_log_level_requests[0]; + m_log_level_requests.erase(0, false); + m_log_level_requests.unlock(); + + LogLevel tmp; + tmp = req; + + if(req.blockRef == 0){ + req.blockRef = _ownReference; + setEventReportingLevelImpl(0, req); + } else { + ord = req; + setNodeLogLevelImpl(req.blockRef, ord); } - // Cluster log - while ((n = _clusterLogLevelList->next()) != NULL) { - if (n->getNodeId() == _startedNodeId) { - setEventReportingLevel(_startedNodeId, n->getLogLevelOrd(), true); - } - } - _startedNodeId = 0; - - NdbMutex_Unlock(threadMutex); - - } // if (_startedNodeId != 0) { - + m_log_level_requests.lock(); + } + m_log_level_requests.unlock(); NdbSleep_MilliSleep(_logLevelThreadSleep); - } // while (!_isStopThread) - - NdbMutex_Destroy(threadMutex); -} - -void -MgmtSrvr::setStatisticsListner(StatisticsListner* listner) -{ - m_statisticsListner = listner; + } } void @@ -272,7 +238,7 @@ class ErrorItem { public: int _errorCode; - const BaseString _errorText; + const char * _errorText; }; bool @@ -429,110 +395,37 @@ MgmtSrvr::getPort() const { ndb_mgm_destroy_iterator(iter); - /***************** - * Set Stat Port * - *****************/ -#if 0 - if (!mgmProps->get("PortNumberStats", &tmp)){ - ndbout << "Could not find PortNumberStats in the configuration file." - << endl; - return false; - } - glob.port_stats = tmp; -#endif - -#if 0 - const char * host; - if(ndb_mgm_get_string_parameter(iter, mgmProps->get("ExecuteOnComputer", host)){ - ndbout << "Failed to find \"ExecuteOnComputer\" for my node" << endl; - ndbout << "Unable to verify own hostname" << endl; - return false; - } - - const char * hostname; - { - const Properties * p; - char buf[255]; - snprintf(buf, sizeof(buf), "Computer_%s", host.c_str()); - if(!glob.cluster_config->get(buf, &p)){ - ndbout << "Failed to find computer " << host << " in config" << endl; - ndbout << "Unable to verify own hostname" << endl; - return false; - } - if(!p->get("HostName", &hostname)){ - ndbout << "Failed to find \"HostName\" for computer " << host - << " in config" << endl; - ndbout << "Unable to verify own hostname" << endl; - return false; - } - if(NdbHost_GetHostName(buf) != 0){ - ndbout << "Unable to get own hostname" << endl; - ndbout << "Unable to verify own hostname" << endl; - return false; - } - } - - const char * ip_address; - if(mgmProps->get("IpAddress", &ip_address)){ - glob.use_specific_ip = true; - glob.interface_name = strdup(ip_address); - return true; - } - - glob.interface_name = strdup(hostname); -#endif - return port; } -int -MgmtSrvr::getStatPort() const { -#if 0 - const Properties *mgmProps; - if(!getConfig()->get("Node", _ownNodeId, &mgmProps)) - return -1; - - int tmp = -1; - if(!mgmProps->get("PortNumberStats", (Uint32 *)&tmp)) - return -1; - - return tmp; -#else - return -1; -#endif -} - /* Constructor */ MgmtSrvr::MgmtSrvr(NodeId nodeId, const BaseString &configFilename, - const BaseString &ndb_config_filename, + LocalConfig &local_config, Config * config): _blockNumber(1), // Hard coded block number since it makes it easy to send // signals to other management servers. _ownReference(0), + m_allocated_resources(*this), theSignalIdleList(NULL), theWaitState(WAIT_SUBSCRIBE_CONF), - theConfCount(0), - m_allocated_resources(*this) { - + m_statisticsListner(this), + m_local_config(local_config) +{ + DBUG_ENTER("MgmtSrvr::MgmtSrvr"); _config = NULL; - _isStatPortActive = false; - _isClusterLogStatActive = false; _isStopThread = false; _logLevelThread = NULL; _logLevelThreadSleep = 500; m_signalRecvThread = NULL; - _startedNodeId = 0; theFacade = 0; m_newConfig = NULL; m_configFilename = configFilename; - setCallback(CmdBackupCallback); - m_localNdbConfigFilename = ndb_config_filename; m_nextConfigGenerationNumber = 0; @@ -583,33 +476,64 @@ MgmtSrvr::MgmtSrvr(NodeId nodeId, ndb_mgm_destroy_iterator(iter); } - m_statisticsListner = NULL; - - _nodeLogLevelList = new NodeLogLevelList(); - _clusterLogLevelList = new NodeLogLevelList(); - _props = NULL; - _ownNodeId= 0; NodeId tmp= nodeId; BaseString error_string; - if (!alloc_node_id(&tmp, NDB_MGM_NODE_TYPE_MGM, 0, 0, error_string)){ +#if 0 + char my_hostname[256]; + struct sockaddr_in tmp_addr; + SOCKET_SIZE_TYPE addrlen= sizeof(tmp_addr); + if (!g_no_nodeid_checks) { + if (gethostname(my_hostname, sizeof(my_hostname))) { + ndbout << "error: gethostname() - " << strerror(errno) << endl; + exit(-1); + } + if (Ndb_getInAddr(&(((sockaddr_in*)&tmp_addr)->sin_addr),my_hostname)) { + ndbout << "error: Ndb_getInAddr(" << my_hostname << ") - " + << strerror(errno) << endl; + exit(-1); + } + } + if (!alloc_node_id(&tmp, NDB_MGM_NODE_TYPE_MGM, + (struct sockaddr *)&tmp_addr, + &addrlen, error_string)){ ndbout << "Unable to obtain requested nodeid: " << error_string.c_str() << endl; exit(-1); } +#else + if (!alloc_node_id(&tmp, NDB_MGM_NODE_TYPE_MGM, + 0, 0, error_string)){ + ndbout << "Unable to obtain requested nodeid: " + << error_string.c_str() << endl; + exit(-1); + } +#endif _ownNodeId = tmp; { DBUG_PRINT("info", ("verifyConfig")); - ConfigRetriever cr(NDB_VERSION, NDB_MGM_NODE_TYPE_MGM); + ConfigRetriever cr(m_local_config, NDB_VERSION, NDB_MGM_NODE_TYPE_MGM); if (!cr.verifyConfig(config->m_configValues, _ownNodeId)) { ndbout << cr.getErrorString() << endl; exit(-1); } } + { + MgmStatService::StatListener se; + se.m_socket = -1; + for(size_t t = 0; ttheClusterMgr->getNodeInfo(processId); - version = node.m_info.m_version; - if(theFacade->theClusterMgr->getNodeInfo(processId).connected) - if(m_versionRec.callback != 0) - m_versionRec.callback(processId, version, this,0); - else - if(m_versionRec.callback != 0) - m_versionRec.callback(processId, 0, this,0); - + if (getOwnNodeId() == processId) + { + version= NDB_VERSION; } - - if (getNodeType(processId) == NDB_MGM_NODE_TYPE_API) { + else if (getNodeType(processId) == NDB_MGM_NODE_TYPE_NDB) + { + ClusterMgr::Node node= theFacade->theClusterMgr->getNodeInfo(processId); + if(node.connected) + version= node.m_info.m_version; + else + version= 0; + } + else if (getNodeType(processId) == NDB_MGM_NODE_TYPE_API || + getNodeType(processId) == NDB_MGM_NODE_TYPE_MGM) + { return sendVersionReq(processId); } + if(m_versionRec.callback != 0) + m_versionRec.callback(processId, version, this,0); m_versionRec.inUse = false ; - return 0; + m_versionRec.version[processId]= version; + + return 0; } int @@ -1460,17 +1384,14 @@ MgmtSrvr::status(int processId, Uint32 * nodegroup, Uint32 * connectCount) { - if (getNodeType(processId) == NDB_MGM_NODE_TYPE_API) { + if (getNodeType(processId) == NDB_MGM_NODE_TYPE_API || + getNodeType(processId) == NDB_MGM_NODE_TYPE_MGM) { if(versionNode(processId, false,0,0) ==0) * version = m_versionRec.version[processId]; else * version = 0; } - if (getNodeType(processId) == NDB_MGM_NODE_TYPE_MGM) { - * version = NDB_VERSION; - } - const ClusterMgr::Node node = theFacade->theClusterMgr->getNodeInfo(processId); @@ -1540,175 +1461,72 @@ MgmtSrvr::status(int processId, return -1; } - - -//**************************************************************************** -//**************************************************************************** -int -MgmtSrvr::startStatisticEventReporting(int level) -{ - SetLogLevelOrd ll; - NodeId nodeId = 0; - - ll.clear(); - ll.setLogLevel(LogLevel::llStatistic, level); - - if (level > 0) { - _isStatPortActive = true; - } else { - _isStatPortActive = false; - - if (_isClusterLogStatActive) { - return 0; - } - } - - while (getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) { - setEventReportingLevelImpl(nodeId, ll); - } - - return 0; -} - -int -MgmtSrvr::setEventReportingLevel(int processId, const SetLogLevelOrd & ll, - bool isResend) -{ - for (Uint32 i = 0; i < ll.noOfEntries; i++) { - if (ll.theCategories[i] == LogLevel::llStatistic) { - if (ll.theLevels[i] > 0) { - _isClusterLogStatActive = true; - break; - } else { - _isClusterLogStatActive = false; - - if (_isStatPortActive) { - return 0; - } - break; - } - } // if (ll.theCategories - } // for (int i = 0 - - return setEventReportingLevelImpl(processId, ll, isResend); -} int MgmtSrvr::setEventReportingLevelImpl(int processId, - const SetLogLevelOrd & ll, - bool isResend) + const EventSubscribeReq& ll) { - Uint32 i; - for(i = 0; inext()) != NULL) { - if (n->getNodeId() == processId && - n->getCategory() == ll.theCategories[i]) { - - n->setLevel(ll.theLevels[i]); - found = true; - } - } - if (!found) { - _clusterLogLevelList->add(new NodeLogLevel(processId, ll)); - } - } - } - + int result = okToSendTo(processId, true); if (result != 0) { return result; } - NdbApiSignal* signal = getSignal(); - if (signal == NULL) { - return COULD_NOT_ALLOCATE_MEMORY; - } + NdbApiSignal signal(_ownReference); EventSubscribeReq * dst = - CAST_PTR(EventSubscribeReq, signal->getDataPtrSend()); - for(i = 0; itheCategories[i] = ll.theCategories[i]; - dst->theLevels[i] = ll.theLevels[i]; - } - - dst->noOfEntries = ll.noOfEntries; - dst->blockRef = _ownReference; + CAST_PTR(EventSubscribeReq, signal.getDataPtrSend()); - signal->set(TestOrd::TraceAPI, CMVMI, GSN_EVENT_SUBSCRIBE_REQ, - EventSubscribeReq::SignalLength); + * dst = ll; + + signal.set(TestOrd::TraceAPI, CMVMI, GSN_EVENT_SUBSCRIBE_REQ, + EventSubscribeReq::SignalLength); + + theFacade->lock_mutex(); + send(&signal, processId, NODE_TYPE_DB); + theFacade->unlock_mutex(); - result = sendSignal(processId, WAIT_SUBSCRIBE_CONF, signal, true); - if (result == -1) { - return SEND_OR_RECEIVE_FAILED; - } - else { - // Increment the conf counter - theConfCount++; - } - return 0; } //**************************************************************************** //**************************************************************************** int -MgmtSrvr::setNodeLogLevel(int processId, const SetLogLevelOrd & ll, - bool isResend) +MgmtSrvr::setNodeLogLevelImpl(int processId, const SetLogLevelOrd & ll) { - Uint32 i; - for(i = 0; inext()) != NULL) { - if (n->getNodeId() == processId && - n->getCategory() == ll.theCategories[i]) { - - n->setLevel(ll.theLevels[i]); - found = true; - } - } - if (!found) { - _clusterLogLevelList->add(new NodeLogLevel(processId, ll)); - } - } - } - int result = okToSendTo(processId, true); if (result != 0) { return result; } - NdbApiSignal* signal = getSignal(); - if (signal == NULL) { - return COULD_NOT_ALLOCATE_MEMORY; - } - - SetLogLevelOrd * dst = CAST_PTR(SetLogLevelOrd, signal->getDataPtrSend()); - - for(i = 0; itheCategories[i] = ll.theCategories[i]; - dst->theLevels[i] = ll.theLevels[i]; - } + NdbApiSignal signal(_ownReference); - dst->noOfEntries = ll.noOfEntries; + SetLogLevelOrd * dst = CAST_PTR(SetLogLevelOrd, signal.getDataPtrSend()); - signal->set(TestOrd::TraceAPI, CMVMI, GSN_SET_LOGLEVELORD, - SetLogLevelOrd::SignalLength); - - result = sendSignal(processId, NO_WAIT, signal, true); - if (result == -1) { - return SEND_OR_RECEIVE_FAILED; - } + * dst = ll; + + signal.set(TestOrd::TraceAPI, CMVMI, GSN_SET_LOGLEVELORD, + SetLogLevelOrd::SignalLength); + + theFacade->lock_mutex(); + theFacade->sendSignalUnCond(&signal, processId); + theFacade->unlock_mutex(); return 0; } +int +MgmtSrvr::send(NdbApiSignal* signal, Uint32 node, Uint32 node_type){ + Uint32 max = (node == 0) ? MAX_NODES : node + 1; + + for(; node < max; node++){ + while(nodeTypes[node] != (int)node_type && node < max) node++; + if(nodeTypes[node] != (int)node_type) + break; + theFacade->sendSignalUnCond(signal, node); + } + return 0; +} //**************************************************************************** //**************************************************************************** @@ -2003,7 +1821,7 @@ const char* MgmtSrvr::getErrorText(int errorCode) for (int i = 0; i < noOfErrorCodes; ++i) { if (errorCode == errorTable[i]._errorCode) { - return errorTable[i]._errorText.c_str(); + return errorTable[i]._errorText; } } @@ -2011,21 +1829,6 @@ const char* MgmtSrvr::getErrorText(int errorCode) return text; } -/***************************************************************************** - * Handle reception of various signals - *****************************************************************************/ - -int -MgmtSrvr::handleSTATISTICS_CONF(NdbApiSignal* signal) -{ - //ndbout << "MgmtSrvr::handleSTATISTICS_CONF" << endl; - - int x = signal->readData(1); - //ndbout << "MgmtSrvr::handleSTATISTICS_CONF, x: " << x << endl; - _statistics._test1 = x; - return 0; -} - void MgmtSrvr::handleReceivedSignal(NdbApiSignal* signal) { @@ -2049,51 +1852,7 @@ MgmtSrvr::handleReceivedSignal(NdbApiSignal* signal) } break; - case GSN_STATISTICS_CONF: - if (theWaitState != WAIT_STATISTICS) { - g_EventLogger.warning("MgmtSrvr::handleReceivedSignal, unexpected " - "signal received, gsn %d, theWaitState = %d", - gsn, theWaitState); - - return; - } - returnCode = handleSTATISTICS_CONF(signal); - if (returnCode != -1) { - theWaitState = NO_WAIT; - } - break; - - - case GSN_SET_VAR_CONF: - if (theWaitState != WAIT_SET_VAR) { - g_EventLogger.warning("MgmtSrvr::handleReceivedSignal, unexpected " - "signal received, gsn %d, theWaitState = %d", - gsn, theWaitState); - return; - } - theWaitState = NO_WAIT; - _setVarReqResult = 0; - break; - - case GSN_SET_VAR_REF: - if (theWaitState != WAIT_SET_VAR) { - g_EventLogger.warning("MgmtSrvr::handleReceivedSignal, unexpected " - "signal received, gsn %d, theWaitState = %d", - gsn, theWaitState); - return; - } - theWaitState = NO_WAIT; - _setVarReqResult = -1; - break; - case GSN_EVENT_SUBSCRIBE_CONF: - theConfCount--; // OK, we've received a conf message - if (theConfCount < 0) { - g_EventLogger.warning("MgmtSrvr::handleReceivedSignal, unexpected " - "signal received, gsn %d, theWaitState = %d", - gsn, theWaitState); - theConfCount = 0; - } break; case GSN_EVENT_REP: @@ -2173,7 +1932,6 @@ MgmtSrvr::handleReceivedSignal(NdbApiSignal* signal) event.Completed.NoOfLogBytes = rep->noOfLogBytes; event.Completed.NoOfRecords = rep->noOfRecords; event.Completed.NoOfLogRecords = rep->noOfLogRecords; - event.Completed.stopGCP = rep->stopGCP; event.Completed.startGCP = rep->startGCP; event.Nodes = rep->nodes; @@ -2276,20 +2034,19 @@ void MgmtSrvr::handleStatus(NodeId nodeId, bool alive) { if (alive) { - _startedNodeId = nodeId; // Used by logLevelThreadRun() + m_started_nodes.push_back(nodeId); Uint32 theData[25]; theData[0] = EventReport::Connected; theData[1] = nodeId; + eventReport(_ownNodeId, theData); } else { handleStopReply(nodeId, 0); - theConfCount++; // Increment the event subscr conf count because - + Uint32 theData[25]; theData[0] = EventReport::Disconnected; theData[1] = nodeId; - + eventReport(_ownNodeId, theData); - g_EventLogger.info("Lost connection to node %d", nodeId); } } @@ -2337,32 +2094,42 @@ MgmtSrvr::alloc_node_id(NodeId * nodeId, SOCKET_SIZE_TYPE *client_addr_len, BaseString &error_string) { - Guard g(&f_node_id_mutex); -#if 0 - ndbout << "MgmtSrvr::getFreeNodeId type=" << type - << " *nodeid=" << *nodeId << endl; -#endif - - NodeBitmask connected_nodes(m_reserved_nodes); - if (theFacade && theFacade->theClusterMgr) { - for(Uint32 i = 0; i < MAX_NODES; i++) - if (getNodeType(i) == NDB_MGM_NODE_TYPE_NDB) { - const ClusterMgr::Node &node= theFacade->theClusterMgr->getNodeInfo(i); - if (node.connected) - connected_nodes.bitOR(node.m_state.m_connected_nodes); - } + DBUG_ENTER("MgmtSrvr::alloc_node_id"); + DBUG_PRINT("enter", ("nodeid=%d, type=%d, client_addr=%d", + *nodeId, type, client_addr)); + if (g_no_nodeid_checks) { + if (*nodeId == 0) { + error_string.appfmt("no-nodeid-ckecks set in manegment server.\n" + "node id must be set explicitly in connectstring"); + DBUG_RETURN(false); + } + DBUG_RETURN(true); + } + Guard g(&f_node_id_mutex); + int no_mgm= 0; + NodeBitmask connected_nodes(m_reserved_nodes); + for(Uint32 i = 0; i < MAX_NODES; i++) + { + if (getNodeType(i) == NDB_MGM_NODE_TYPE_NDB && + theFacade && theFacade->theClusterMgr) { + const ClusterMgr::Node &node= theFacade->theClusterMgr->getNodeInfo(i); + if (node.connected) { + connected_nodes.bitOR(node.m_state.m_connected_nodes); + } + } else if (getNodeType(i) == NDB_MGM_NODE_TYPE_MGM) + no_mgm++; } - bool found_matching_id= false; bool found_matching_type= false; bool found_free_node= false; - const char *config_hostname = 0; + unsigned id_found= 0; + const char *config_hostname= 0; struct in_addr config_addr= {0}; int r_config_addr= -1; unsigned type_c= 0; - ndb_mgm_configuration_iterator iter(*(ndb_mgm_configuration *)_config->m_configValues, - CFG_SECTION_NODE); + ndb_mgm_configuration_iterator + iter(*(ndb_mgm_configuration *)_config->m_configValues, CFG_SECTION_NODE); for(iter.first(); iter.valid(); iter.next()) { unsigned tmp= 0; if(iter.get(CFG_NODE_ID, &tmp)) abort(); @@ -2370,15 +2137,16 @@ MgmtSrvr::alloc_node_id(NodeId * nodeId, continue; found_matching_id= true; if(iter.get(CFG_TYPE_OF_SECTION, &type_c)) abort(); - if(type_c != type) + if(type_c != (unsigned)type) continue; found_matching_type= true; if (connected_nodes.get(tmp)) continue; found_free_node= true; if(iter.get(CFG_NODE_HOST, &config_hostname)) abort(); - - if (config_hostname && config_hostname[0] != 0 && client_addr) { + if (config_hostname && config_hostname[0] == 0) + config_hostname= 0; + else if (client_addr) { // check hostname compatability const void *tmp_in= &(((sockaddr_in*)client_addr)->sin_addr); if((r_config_addr= Ndb_getInAddr(&config_addr, config_hostname)) != 0 @@ -2388,39 +2156,76 @@ MgmtSrvr::alloc_node_id(NodeId * nodeId, || memcmp(&tmp_addr, tmp_in, sizeof(config_addr)) != 0) { // not localhost #if 0 - ndbout << "MgmtSrvr::getFreeNodeId compare failed for \"" << config_hostname - << "\" id=" << tmp << endl; + ndbout << "MgmtSrvr::getFreeNodeId compare failed for \"" + << config_hostname + << "\" id=" << tmp << endl; #endif continue; } // connecting through localhost - // check if config_hostname match hostname - char my_hostname[256]; - if (gethostname(my_hostname, sizeof(my_hostname)) != 0) - continue; - if(Ndb_getInAddr(&tmp_addr, my_hostname) != 0 - || memcmp(&tmp_addr, &config_addr, sizeof(config_addr)) != 0) { - // no match + // check if config_hostname is local + if (!SocketServer::tryBind(0,config_hostname)) { continue; } } + } else { // client_addr == 0 + if (!SocketServer::tryBind(0,config_hostname)) { + continue; + } } - *nodeId= tmp; - if (client_addr) - m_connect_address[tmp]= ((struct sockaddr_in *)client_addr)->sin_addr; - else - Ndb_getInAddr(&(m_connect_address[tmp]), "localhost"); - m_reserved_nodes.set(tmp); -#if 0 - ndbout << "MgmtSrvr::getFreeNodeId found type=" << type - << " *nodeid=" << *nodeId << endl; -#endif - return true; + if (*nodeId != 0 || + type != NDB_MGM_NODE_TYPE_MGM || + no_mgm == 1) { // any match is ok + id_found= tmp; + break; + } + if (id_found) { // mgmt server may only have one match + error_string.appfmt("Ambiguous node id's %d and %d.\n" + "Suggest specifying node id in connectstring,\n" + "or specifying unique host names in config file.", + id_found, tmp); + DBUG_RETURN(false); + } + if (config_hostname == 0) { + error_string.appfmt("Ambiguity for node id %d.\n" + "Suggest specifying node id in connectstring,\n" + "or specifying unique host names in config file,\n" + "or specifying just one mgmt server in config file.", + tmp); + DBUG_RETURN(false); + } + id_found= tmp; // mgmt server matched, check for more matches + } + + if (id_found) + { + *nodeId= id_found; + DBUG_PRINT("info", ("allocating node id %d",*nodeId)); + { + int r= 0; + if (client_addr) + m_connect_address[id_found]= + ((struct sockaddr_in *)client_addr)->sin_addr; + else if (config_hostname) + r= Ndb_getInAddr(&(m_connect_address[id_found]), config_hostname); + else { + char name[256]; + r= gethostname(name, sizeof(name)); + if (r == 0) { + name[sizeof(name)-1]= 0; + r= Ndb_getInAddr(&(m_connect_address[id_found]), name); + } + } + if (r) + m_connect_address[id_found].s_addr= 0; + } + m_reserved_nodes.set(id_found); + DBUG_RETURN(true); } if (found_matching_type && !found_free_node) { - // we have a temporary error which might be due to that we have got the latest - // connect status from db-nodes. Force update. + // we have a temporary error which might be due to that + // we have got the latest connect status from db-nodes. Force update. global_flag_send_heartbeat_now= 1; } @@ -2429,7 +2234,8 @@ MgmtSrvr::alloc_node_id(NodeId * nodeId, const char *alias, *str; alias= ndb_mgm_get_node_type_alias_string(type, &str); type_string.assfmt("%s(%s)", alias, str); - alias= ndb_mgm_get_node_type_alias_string((enum ndb_mgm_node_type)type_c, &str); + alias= ndb_mgm_get_node_type_alias_string((enum ndb_mgm_node_type)type_c, + &str); type_c_string.assfmt("%s(%s)", alias, str); } @@ -2438,11 +2244,14 @@ MgmtSrvr::alloc_node_id(NodeId * nodeId, if (found_matching_type) if (found_free_node) error_string.appfmt("Connection done from wrong host ip %s.", - inet_ntoa(((struct sockaddr_in *)(client_addr))->sin_addr)); + inet_ntoa(((struct sockaddr_in *) + (client_addr))->sin_addr)); else - error_string.appfmt("No free node id found for %s.", type_string.c_str()); + error_string.appfmt("No free node id found for %s.", + type_string.c_str()); else - error_string.appfmt("No %s node defined in config file.", type_string.c_str()); + error_string.appfmt("No %s node defined in config file.", + type_string.c_str()); else error_string.append("No nodes defined in config file."); } else { @@ -2451,19 +2260,23 @@ MgmtSrvr::alloc_node_id(NodeId * nodeId, if (found_free_node) { // have to split these into two since inet_ntoa overwrites itself error_string.appfmt("Connection with id %d done from wrong host ip %s,", - *nodeId, inet_ntoa(((struct sockaddr_in *)(client_addr))->sin_addr)); + *nodeId, inet_ntoa(((struct sockaddr_in *) + (client_addr))->sin_addr)); error_string.appfmt(" expected %s(%s).", config_hostname, - r_config_addr ? "lookup failed" : inet_ntoa(config_addr)); + r_config_addr ? + "lookup failed" : inet_ntoa(config_addr)); } else - error_string.appfmt("Id %d already allocated by another node.", *nodeId); + error_string.appfmt("Id %d already allocated by another node.", + *nodeId); else error_string.appfmt("Id %d configured as %s, connect attempted as %s.", - *nodeId, type_c_string.c_str(), type_string.c_str()); + *nodeId, type_c_string.c_str(), + type_string.c_str()); else - error_string.appfmt("No node defined with id=%d in config file.", *nodeId); + error_string.appfmt("No node defined with id=%d in config file.", + *nodeId); } - - return false; + DBUG_RETURN(false); } bool @@ -2483,91 +2296,23 @@ MgmtSrvr::getNextNodeId(NodeId * nodeId, enum ndb_mgm_node_type type) const return true; } +#include "Services.hpp" + void MgmtSrvr::eventReport(NodeId nodeId, const Uint32 * theData) { const EventReport * const eventReport = (EventReport *)&theData[0]; - + EventReport::EventType type = eventReport->getEventType(); - - if (type == EventReport::TransReportCounters || - type == EventReport::OperationReportCounters) { - - if (_isClusterLogStatActive) { - g_EventLogger.log(type, theData, nodeId); - } - - if (_isStatPortActive) { - char theTime[128]; - struct tm* tm_now; - time_t now; - now = time((time_t*)NULL); -#ifdef NDB_WIN32 - tm_now = localtime(&now); -#else - tm_now = gmtime(&now); -#endif - - snprintf(theTime, sizeof(theTime), - STATISTIC_DATE, - tm_now->tm_year + 1900, - tm_now->tm_mon, - tm_now->tm_mday, - tm_now->tm_hour, - tm_now->tm_min, - tm_now->tm_sec); - - char str[255]; - - if (type == EventReport::TransReportCounters) { - snprintf(str, sizeof(str), - STATISTIC_LINE, - theTime, - (int)now, - nodeId, - theData[1], - theData[2], - theData[3], - // theData[4], simple reads - theData[5], - theData[6], - theData[7], - theData[8]); - } else if (type == EventReport::OperationReportCounters) { - snprintf(str, sizeof(str), - OP_STATISTIC_LINE, - theTime, - (int)now, - nodeId, - theData[1]); - } - - if(m_statisticsListner != 0){ - m_statisticsListner->println_statistics(str); - } - } - - return; - - } // if (type == - // Log event - g_EventLogger.log(type, theData, nodeId); - + g_EventLogger.log(type, theData, nodeId, + &m_statisticsListner.m_clients[0].m_logLevel); + m_statisticsListner.log(type, theData, nodeId); } /*************************************************************************** * Backup ***************************************************************************/ - -MgmtSrvr::BackupCallback -MgmtSrvr::setCallback(BackupCallback aCall) -{ - BackupCallback ret = m_backupCallback; - m_backupCallback = aCall; - return ret; -} - int MgmtSrvr::startBackup(Uint32& backupId, bool waitCompleted) { @@ -2674,102 +2419,18 @@ MgmtSrvr::abortBackup(Uint32 backupId) void MgmtSrvr::backupCallback(BackupEvent & event) { - char str[255]; - - bool ok = false; + m_lastBackupEvent = event; switch(event.Event){ - case BackupEvent::BackupStarted: - ok = true; - snprintf(str, sizeof(str), - "Backup %d started", event.Started.BackupId); - break; case BackupEvent::BackupFailedToStart: - ok = true; - snprintf(str, sizeof(str), - "Backup failed to start (Backup error %d)", - event.FailedToStart.ErrorCode); - break; - case BackupEvent::BackupCompleted: - ok = true; - snprintf(str, sizeof(str), - "Backup %d completed", - event.Completed.BackupId); - g_EventLogger.info(str); - - snprintf(str, sizeof(str), - " StartGCP: %d StopGCP: %d", - event.Completed.startGCP, event.Completed.stopGCP); - g_EventLogger.info(str); - - snprintf(str, sizeof(str), - " #Records: %d #LogRecords: %d", - event.Completed.NoOfRecords, event.Completed.NoOfLogRecords); - g_EventLogger.info(str); - - snprintf(str, sizeof(str), - " Data: %d bytes Log: %d bytes", - event.Completed.NoOfBytes, event.Completed.NoOfLogBytes); - break; case BackupEvent::BackupAborted: - ok = true; - snprintf(str, sizeof(str), - "Backup %d has been aborted reason %d", - event.Aborted.BackupId, - event.Aborted.Reason); + case BackupEvent::BackupCompleted: + theWaitState = NO_WAIT; break; - } - if(!ok){ - snprintf(str, sizeof(str), - "Unknown backup event: %d", - event.Event); - - } - g_EventLogger.info(str); - - switch (theWaitState){ - case WAIT_BACKUP_STARTED: - switch(event.Event){ - case BackupEvent::BackupStarted: - case BackupEvent::BackupFailedToStart: - m_lastBackupEvent = event; + case BackupEvent::BackupStarted: + if(theWaitState == WAIT_BACKUP_STARTED) theWaitState = NO_WAIT; - break; - default: - snprintf(str, sizeof(str), - "Received event %d in unexpected state WAIT_BACKUP_STARTED", - event.Event); - g_EventLogger.info(str); - return; - } - - break; - case WAIT_BACKUP_COMPLETED: - switch(event.Event){ - case BackupEvent::BackupCompleted: - case BackupEvent::BackupAborted: - case BackupEvent::BackupFailedToStart: - m_lastBackupEvent = event; - theWaitState = NO_WAIT; - break; - default: - snprintf(str, sizeof(str), - "Received event %d in unexpected state WAIT_BACKUP_COMPLETED", - event.Event); - g_EventLogger.info(str); - return; - } - break; - default: - snprintf(str, sizeof(str), "Received event %d in unexpected state = %d", - event.Event, theWaitState); - g_EventLogger.info(str); - return; - - } - - if(m_backupCallback != 0){ - (* m_backupCallback)(event); } + return; } @@ -2957,15 +2618,15 @@ MgmtSrvr::setDbParameter(int node, int param, const char * value, switch(p_type){ case 0: res = i2.set(param, val_32); - ndbout_c("Updateing node %d param: %d to %d", node, param, val_32); + ndbout_c("Updating node %d param: %d to %d", node, param, val_32); break; case 1: res = i2.set(param, val_64); - ndbout_c("Updateing node %d param: %d to %Ld", node, param, val_32); + ndbout_c("Updating node %d param: %d to %Ld", node, param, val_32); break; case 2: res = i2.set(param, val_char); - ndbout_c("Updateing node %d param: %d to %s", node, param, val_char); + ndbout_c("Updating node %d param: %d to %s", node, param, val_char); break; default: abort(); @@ -2981,3 +2642,7 @@ template class Vector; #if __SUNPRO_CC != 0x560 template bool SignalQueue::waitFor(Vector&, SigMatch*&, NdbApiSignal*&, unsigned); #endif + +template class MutexVector; +template class MutexVector; +template class MutexVector; diff --git a/ndb/src/mgmsrv/MgmtSrvr.hpp b/ndb/src/mgmsrv/MgmtSrvr.hpp index d7f9f7a1af3..c6157db489a 100644 --- a/ndb/src/mgmsrv/MgmtSrvr.hpp +++ b/ndb/src/mgmsrv/MgmtSrvr.hpp @@ -28,8 +28,8 @@ #include #include "SignalQueue.hpp" #include - -#include "NodeLogLevelList.hpp" +#include +#include /** * @desc Block number for Management server. @@ -43,6 +43,29 @@ class Config; class SetLogLevelOrd; class SocketServer; +class MgmStatService : public EventLoggerBase +{ + friend class MgmtSrvr; +public: + struct StatListener : public EventLoggerBase { + NDB_SOCKET_TYPE m_socket; + }; + +private: + class MgmtSrvr * m_mgmsrv; + MutexVector m_clients; +public: + MgmStatService(class MgmtSrvr * m) : m_clients(5) { + m_mgmsrv = m; + } + + void add_listener(const StatListener&); + + void log(int eventType, const Uint32* theData, NodeId nodeId); + + void stopSessions(); +}; + /** * @class MgmtSrvr * @brief Main class for the management server. @@ -63,11 +86,6 @@ class SocketServer; class MgmtSrvr { public: - class StatisticsListner { - public: - virtual void println_statistics(const BaseString &s) = 0; - }; - // some compilers need all of this class Allocated_resources; friend class Allocated_resources; @@ -84,11 +102,6 @@ public: NodeBitmask m_reserved_nodes; }; - /** - * Set a reference to the socket server. - */ - void setStatisticsListner(StatisticsListner* listner); - /** * Start/initate the event log. */ @@ -150,15 +163,6 @@ public: STATIC_CONST( OPERATION_IN_PROGRESS = 6667 ); STATIC_CONST( NO_CONTACT_WITH_DB_NODES = 5030 ); - /** - * This class holds all statistical variables fetched with - * the getStatistics methods. - */ - class Statistics { // TODO, Real statistic data to be added - public: - int _test1; - }; - /** * This enum specifies the different signal loggig modes possible to set * with the setSignalLoggingMode method. @@ -169,7 +173,7 @@ public: MgmtSrvr(NodeId nodeId, /* Local nodeid */ const BaseString &config_filename, /* Where to save config */ - const BaseString &ndb_config_filename, /* Ndb.cfg filename */ + LocalConfig &local_config, /* Ndb.cfg filename */ Config * config); NodeId getOwnNodeId() const {return _ownNodeId;}; @@ -206,7 +210,7 @@ public: typedef void (* EnterSingleCallback)(int nodeId, void * anyData, int errorCode); typedef void (* ExitSingleCallback)(int nodeId, void * anyData, - int errorCode); + int errorCode); /** * Lock configuration @@ -313,13 +317,6 @@ public: bool abort = false, int * stopCount = 0, StopCallback = 0, void * anyData = 0); - int setEventReportingLevel(int processId, - const class SetLogLevelOrd & logLevel, - bool isResend = false); - - int startStatisticEventReporting(int level = 5); - - struct BackupEvent { enum Event { BackupStarted = 1, @@ -356,8 +353,6 @@ public: /** * Backup functionallity */ - typedef void (* BackupCallback)(const BackupEvent& Event); - BackupCallback setCallback(BackupCallback); int startBackup(Uint32& backupId, bool waitCompleted = false); int abortBackup(Uint32 backupId); int performBackup(Uint32* backupId); @@ -377,22 +372,8 @@ public: // INVALID_LEVEL //************************************************************************** - /** - * Sets the Node's log level, i.e., its local event reporting. - * - * @param processId the DB node id. - * @param logLevel the log level. - * @param isResend Flag to indicate for resending log levels - * during node restart - - * @return 0 if successful or NO_CONTACT_WITH_PROCESS, - * SEND_OR_RECEIVE_FAILED, - * COULD_NOT_ALLOCATE_MEMORY - */ - int setNodeLogLevel(int processId, - const class SetLogLevelOrd & logLevel, - bool isResend = false); - + int setEventReportingLevelImpl(int processId, const EventSubscribeReq& ll); + int setNodeLogLevelImpl(int processId, const SetLogLevelOrd & ll); /** * Insert an error in a DB process. @@ -508,11 +489,6 @@ public: */ NodeId getPrimaryNode() const; - /** - * Returns the statistics port number. - * @return statistic port number. - */ - int getStatPort() const; /** * Returns the port number. * @return port number. @@ -526,10 +502,7 @@ public: private: //************************************************************************** - int setEventReportingLevelImpl(int processId, - const class SetLogLevelOrd & logLevel, - bool isResend = false); - + int setEventReportingLevel(int processId, LogLevel::EventCategory, Uint32); /** * Check if it is possible to send a signal to a (DB) process @@ -555,18 +528,14 @@ private: NdbMutex *m_configMutex; const Config * _config; Config * m_newConfig; + LocalConfig &m_local_config; BaseString m_configFilename; - BaseString m_localNdbConfigFilename; Uint32 m_nextConfigGenerationNumber; NodeBitmask m_reserved_nodes; Allocated_resources m_allocated_resources; struct in_addr m_connect_address[MAX_NODES]; - int _setVarReqResult; // The result of the SET_VAR_REQ response - Statistics _statistics; // handleSTATISTICS_CONF store the result here, - // and getStatistics reads it. - //************************************************************************** // Specific signal handling methods //************************************************************************** @@ -598,14 +567,6 @@ private: // Returns: - //************************************************************************** - int handleSTATISTICS_CONF(NdbApiSignal* signal); - //************************************************************************** - // Description: Handle reception of signal STATISTICS_CONF - // Parameters: - // signal: The recieved signal - // Returns: TODO, to be defined - //************************************************************************** - void handle_MGM_LOCK_CONFIG_REQ(NdbApiSignal *signal); void handle_MGM_UNLOCK_CONFIG_REQ(NdbApiSignal *signal); @@ -631,7 +592,6 @@ private: */ enum WaitSignalType { NO_WAIT, // We don't expect to receive any signal - WAIT_STATISTICS, // Accept STATISTICS_CONF WAIT_SET_VAR, // Accept SET_VAR_CONF and SET_VAR_REF WAIT_SUBSCRIBE_CONF, // Accept event subscription confirmation WAIT_STOP, @@ -733,14 +693,6 @@ private: class SignalQueue m_signalRecvQueue; - enum ndb_mgm_node_type nodeTypes[MAX_NODES]; - - int theConfCount; // The number of expected conf signals - - StatisticsListner * m_statisticsListner; // Used for sending statistics info - bool _isStatPortActive; - bool _isClusterLogStatActive; - struct StopRecord { StopRecord(){ inUse = false; callback = 0; singleUserMode = false;} bool inUse; @@ -765,10 +717,16 @@ private: void handleStopReply(NodeId nodeId, Uint32 errCode); int translateStopRef(Uint32 errCode); - + bool _isStopThread; int _logLevelThreadSleep; - int _startedNodeId; + MutexVector m_started_nodes; + MutexVector m_log_level_requests; + LogLevel m_nodeLogLevel[MAX_NODES]; + enum ndb_mgm_node_type nodeTypes[MAX_NODES]; + friend class MgmApiSession; + friend class MgmStatService; + MgmStatService m_statisticsListner; /** * Handles the thread wich upon a 'Node is started' event will @@ -782,15 +740,12 @@ private: static void *signalRecvThread_C(void *); void signalRecvThreadRun(); - NodeLogLevelList* _nodeLogLevelList; - NodeLogLevelList* _clusterLogLevelList; - void backupCallback(BackupEvent &); - BackupCallback m_backupCallback; BackupEvent m_lastBackupEvent; Config *_props; + int send(class NdbApiSignal* signal, Uint32 node, Uint32 node_type); public: /** * This method does not exist diff --git a/ndb/src/mgmsrv/MgmtSrvrConfig.cpp b/ndb/src/mgmsrv/MgmtSrvrConfig.cpp index 44c2aadd1e2..1d51061e909 100644 --- a/ndb/src/mgmsrv/MgmtSrvrConfig.cpp +++ b/ndb/src/mgmsrv/MgmtSrvrConfig.cpp @@ -288,8 +288,7 @@ MgmtSrvr::readConfig() { Config * MgmtSrvr::fetchConfig() { - ConfigRetriever cr(NDB_VERSION, NODE_TYPE_MGM); - cr.setLocalConfigFileName(m_localNdbConfigFilename.c_str()); + ConfigRetriever cr(m_local_config, NDB_VERSION, NODE_TYPE_MGM); struct ndb_mgm_configuration * tmp = cr.getConfig(); if(tmp != 0){ Config * conf = new Config(); diff --git a/ndb/src/mgmsrv/NodeLogLevel.cpp b/ndb/src/mgmsrv/NodeLogLevel.cpp deleted file mode 100644 index 5271cdb0f2b..00000000000 --- a/ndb/src/mgmsrv/NodeLogLevel.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/* Copyright (C) 2003 MySQL AB - - 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 "NodeLogLevel.hpp" -// TODO_RONM: Clearly getCategory and getLevel is not correctly coded. Must be taken care of. - -NodeLogLevel::NodeLogLevel(int nodeId, const SetLogLevelOrd& ll) -{ - m_nodeId = nodeId; - m_logLevel = ll; -} - -NodeLogLevel::~NodeLogLevel() -{ -} - -int -NodeLogLevel::getNodeId() const -{ - return m_nodeId; -} - -Uint32 -NodeLogLevel::getCategory() const -{ - for (Uint32 i = 0; i < m_logLevel.noOfEntries; i++) - { - return m_logLevel.theCategories[i]; - } - return 0; -} - -int -NodeLogLevel::getLevel() const -{ - for (Uint32 i = 0; i < m_logLevel.noOfEntries; i++) - { - return m_logLevel.theLevels[i]; - } - return 0; -} - -void -NodeLogLevel::setLevel(int level) -{ - for (Uint32 i = 0; i < m_logLevel.noOfEntries; i++) - { - m_logLevel.theLevels[i] = level; - } - -} - -SetLogLevelOrd -NodeLogLevel::getLogLevelOrd() const -{ - return m_logLevel; -} diff --git a/ndb/src/mgmsrv/NodeLogLevel.hpp b/ndb/src/mgmsrv/NodeLogLevel.hpp deleted file mode 100644 index 3ad758cde99..00000000000 --- a/ndb/src/mgmsrv/NodeLogLevel.hpp +++ /dev/null @@ -1,54 +0,0 @@ -/* Copyright (C) 2003 MySQL AB - - 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 */ - -#ifndef NODELOGLEVEL_H -#define NODELOGLEVEL_H - -#include - -#include - -/** - * Holds a DB node's log level settings for both local and event log levels. - * It only holds one log level setting even though SetLogLevelOrd can handle - * multiple log levels at once, it is not used in that way in the managment - * server. - * - * @version #@ $Id: NodeLogLevel.hpp,v 1.2 2003/07/05 17:40:22 elathal Exp $ - */ -class NodeLogLevel -{ -public: - NodeLogLevel(int nodeId, const SetLogLevelOrd& ll); - ~NodeLogLevel(); - - int getNodeId() const; - Uint32 getCategory() const; - int getLevel() const; - void setLevel(int level); - SetLogLevelOrd getLogLevelOrd() const; - -private: - NodeLogLevel(); - NodeLogLevel(const NodeLogLevel&); - bool operator == (const NodeLogLevel&); - NodeLogLevel operator = (const NodeLogLevel&); - - int m_nodeId; - SetLogLevelOrd m_logLevel; -}; - -#endif diff --git a/ndb/src/mgmsrv/NodeLogLevelList.cpp b/ndb/src/mgmsrv/NodeLogLevelList.cpp deleted file mode 100644 index 6c7c091c1a8..00000000000 --- a/ndb/src/mgmsrv/NodeLogLevelList.cpp +++ /dev/null @@ -1,182 +0,0 @@ -/* Copyright (C) 2003 MySQL AB - - 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 - -#include "NodeLogLevelList.hpp" -#include "NodeLogLevel.hpp" - -// -// PUBLIC -// - -NodeLogLevelList::NodeLogLevelList() : - m_size(0), - m_pHeadNode(NULL), - m_pTailNode(NULL), - m_pCurrNode(NULL) -{ -} - -NodeLogLevelList::~NodeLogLevelList() -{ - removeAll(); -} - -void -NodeLogLevelList::add(NodeLogLevel* pNewNode) -{ - NodeLogLevelNode* pNode = new NodeLogLevelNode(); - - if (m_pHeadNode == NULL) - { - m_pHeadNode = pNode; - pNode->pPrev = NULL; - } - else - { - m_pTailNode->pNext = pNode; - pNode->pPrev = m_pTailNode; - } - m_pTailNode = pNode; - pNode->pNext = NULL; - pNode->pHandler = pNewNode; - - m_size++; -} - -bool -NodeLogLevelList::remove(NodeLogLevel* pRemoveNode) -{ - NodeLogLevelNode* pNode = m_pHeadNode; - bool removed = false; - do - { - if (pNode->pHandler == pRemoveNode) - { - removeNode(pNode); - removed = true; - break; - } - } while ( (pNode = next(pNode)) != NULL); - - return removed; -} - -void -NodeLogLevelList::removeAll() -{ - while (m_pHeadNode != NULL) - { - removeNode(m_pHeadNode); - } -} - -NodeLogLevel* -NodeLogLevelList::next() -{ - NodeLogLevel* pHandler = NULL; - if (m_pCurrNode == NULL) - { - m_pCurrNode = m_pHeadNode; - if (m_pCurrNode != NULL) - { - pHandler = m_pCurrNode->pHandler; - } - } - else - { - m_pCurrNode = next(m_pCurrNode); // Next node - if (m_pCurrNode != NULL) - { - pHandler = m_pCurrNode->pHandler; - } - } - - return pHandler; -} - -int -NodeLogLevelList::size() const -{ - return m_size; -} - -// -// PRIVATE -// - -NodeLogLevelList::NodeLogLevelNode* -NodeLogLevelList::next(NodeLogLevelNode* pNode) -{ - NodeLogLevelNode* pCurr = pNode; - if (pNode->pNext != NULL) - { - pCurr = pNode->pNext; - } - else - { - // Tail - pCurr = NULL; - } - return pCurr; -} - -NodeLogLevelList::NodeLogLevelNode* -NodeLogLevelList::prev(NodeLogLevelNode* pNode) -{ - NodeLogLevelNode* pCurr = pNode; - if (pNode->pPrev != NULL) // head - { - pCurr = pNode->pPrev; - } - else - { - // Head - pCurr = NULL; - } - - return pCurr; -} - -void -NodeLogLevelList::removeNode(NodeLogLevelNode* pNode) -{ - if (pNode->pPrev == NULL) // If head - { - m_pHeadNode = pNode->pNext; - } - else - { - pNode->pPrev->pNext = pNode->pNext; - } - - if (pNode->pNext == NULL) // if tail - { - m_pTailNode = pNode->pPrev; - } - else - { - pNode->pNext->pPrev = pNode->pPrev; - } - - pNode->pNext = NULL; - pNode->pPrev = NULL; - delete pNode->pHandler; // Delete log handler - delete pNode; - - m_size--; -} diff --git a/ndb/src/mgmsrv/NodeLogLevelList.hpp b/ndb/src/mgmsrv/NodeLogLevelList.hpp deleted file mode 100644 index 4a55ee211e2..00000000000 --- a/ndb/src/mgmsrv/NodeLogLevelList.hpp +++ /dev/null @@ -1,93 +0,0 @@ -/* Copyright (C) 2003 MySQL AB - - 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 */ - -#ifndef NODELOGLEVELLIST_H -#define NODELOGLEVELLIST_H - -class NodeLogLevel; - -/** - * Provides a simple linked list of NodeLogLevel. - * - * @see NodeLogLevel - * @version #@ $Id: NodeLogLevelList.hpp,v 1.1 2002/08/09 12:53:50 eyualex Exp $ - */ -class NodeLogLevelList -{ -public: - /** - * Default Constructor. - */ - NodeLogLevelList(); - - /** - * Destructor. - */ - ~NodeLogLevelList(); - - /** - * Adds a new node. - * - * @param pNewHandler a new NodeLogLevel. - */ - void add(NodeLogLevel* pNewNode); - - /** - * Removes a NodeLogLevel from the list and call its destructor. - * - * @param pRemoveHandler the NodeLogLevel to remove - */ - bool remove(NodeLogLevel* pRemoveNode); - - /** - * Removes all items. - */ - void removeAll(); - - /** - * Returns the next node in the list. - * returns a node or NULL. - */ - NodeLogLevel* next(); - - /** - * Returns the size of the list. - */ - int size() const; -private: - /** List node */ - struct NodeLogLevelNode - { - NodeLogLevelNode* pPrev; - NodeLogLevelNode* pNext; - NodeLogLevel* pHandler; - }; - - NodeLogLevelNode* next(NodeLogLevelNode* pNode); - NodeLogLevelNode* prev(NodeLogLevelNode* pNode); - - void removeNode(NodeLogLevelNode* pNode); - - int m_size; - - NodeLogLevelNode* m_pHeadNode; - NodeLogLevelNode* m_pTailNode; - NodeLogLevelNode* m_pCurrNode; -}; - -#endif - - diff --git a/ndb/src/mgmsrv/Services.cpp b/ndb/src/mgmsrv/Services.cpp index c529e277e0e..684c10dbd4d 100644 --- a/ndb/src/mgmsrv/Services.cpp +++ b/ndb/src/mgmsrv/Services.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -133,7 +134,7 @@ ParserRow commands[] = { MGM_ARG("public key", String, Mandatory, "Public key"), MGM_CMD("get version", &MgmApiSession::getVersion, ""), - + MGM_CMD("get status", &MgmApiSession::getStatus, ""), MGM_CMD("get info clusterlog", &MgmApiSession::getInfoClusterLog, ""), @@ -236,7 +237,11 @@ ParserRow commands[] = { MGM_ARG("node", String, Mandatory, "Node"), MGM_ARG("parameter", String, Mandatory, "Parameter"), MGM_ARG("value", String, Mandatory, "Value"), - + + MGM_CMD("listen event", &MgmApiSession::listen_event, ""), + MGM_ARG("node", Int, Optional, "Node"), + MGM_ARG("filter", String, Mandatory, "Event category"), + MGM_END() }; @@ -289,7 +294,8 @@ MgmApiSession::runSession() { break; } } - NDB_CLOSE_SOCKET(m_socket); + if(m_socket >= 0) + NDB_CLOSE_SOCKET(m_socket); } #ifdef MGM_GET_CONFIG_BACKWARDS_COMPAT @@ -418,7 +424,8 @@ MgmApiSession::get_nodeid(Parser_t::Context &, &addr, &addrlen, error_string)){ const char *alias; const char *str; - alias= ndb_mgm_get_node_type_alias_string((enum ndb_mgm_node_type)nodetype, &str); + alias= ndb_mgm_get_node_type_alias_string((enum ndb_mgm_node_type) + nodetype, &str); m_output->println(cmd); m_output->println("result: %s", error_string.c_str()); m_output->println(""); @@ -554,7 +561,7 @@ MgmApiSession::getStatPort(Parser_t::Context &, const class Properties &) { m_output->println("get statport reply"); - m_output->println("tcpport: %d", m_mgmsrv.getStatPort()); + m_output->println("tcpport: %d", 0); m_output->println(""); } @@ -756,13 +763,12 @@ MgmApiSession::bye(Parser::Context &, void MgmApiSession::setClusterLogLevel(Parser::Context &, Properties const &args) { - Uint32 node, level; - BaseString categoryName, errorString; + Uint32 node, level, category; + BaseString errorString; SetLogLevelOrd logLevel; int result; - logLevel.clear(); args.get("node", &node); - args.get("category", categoryName); + args.get("category", &category); args.get("level", &level); /* XXX should use constants for this value */ @@ -771,25 +777,17 @@ MgmApiSession::setClusterLogLevel(Parser::Context &, goto error; } - categoryName.ndb_toupper(); - - LogLevel::EventCategory category; - if(!EventLogger::matchEventCategory(categoryName.c_str(), &category)) { - errorString.assign("Unknown category"); - goto error; - } - - logLevel.setLogLevel(category, level); - result = m_mgmsrv.setEventReportingLevel(node, logLevel); - + EventSubscribeReq req; + req.blockRef = 0; + req.noOfEntries = 1; + req.theData[0] = (category << 16) | level; + m_mgmsrv.m_log_level_requests.push_back(req); + m_output->println("set cluster loglevel reply"); - if(result != 0) - m_output->println("result: %s", m_mgmsrv.getErrorText(result)); - else - m_output->println("result: Ok"); + m_output->println("result: Ok"); m_output->println(""); return; - error: +error: m_output->println("set cluster loglevel reply"); m_output->println("result: %s", errorString.c_str()); m_output->println(""); @@ -798,13 +796,13 @@ MgmApiSession::setClusterLogLevel(Parser::Context &, void MgmApiSession::setLogLevel(Parser::Context &, Properties const &args) { - Uint32 node = 0, level = 0; - BaseString categoryName, errorString; + Uint32 node = 0, level = 0, category; + BaseString errorString; SetLogLevelOrd logLevel; int result; logLevel.clear(); args.get("node", &node); - args.get("category", categoryName); + args.get("category", &category); args.get("level", &level); /* XXX should use constants for this value */ @@ -813,23 +811,14 @@ MgmApiSession::setLogLevel(Parser::Context &, goto error; } - categoryName.ndb_toupper(); - - LogLevel::EventCategory category; - if(!EventLogger::matchEventCategory(categoryName.c_str(), &category)) { - errorString.assign("Unknown category"); - goto error; - } - - logLevel.setLogLevel(category, level); - - result = m_mgmsrv.setNodeLogLevel(node, logLevel); - + EventSubscribeReq req; + req.blockRef = node; + req.noOfEntries = 1; + req.theData[0] = (category << 16) | level; + m_mgmsrv.m_log_level_requests.push_back(req); + m_output->println("set loglevel reply"); - if(result != 0) - m_output->println("result: %s", m_mgmsrv.getErrorText(result)); - else - m_output->println("result: Ok"); + m_output->println("result: Ok"); m_output->println(""); return; error: @@ -1248,33 +1237,91 @@ MgmApiSession::configChange(Parser_t::Context &, m_output->println(""); } -void -MgmStatService::println_statistics(const BaseString &line){ - MutexVector copy(m_sockets.size()); - m_sockets.lock(); - int i; - for(i = m_sockets.size() - 1; i >= 0; i--){ - if(println_socket(m_sockets[i], MAX_WRITE_TIMEOUT, line.c_str()) == -1){ - copy.push_back(m_sockets[i]); - m_sockets.erase(i, false); +static NdbOut& +operator<<(NdbOut& out, const LogLevel & ll) +{ + out << "[LogLevel: "; + for(size_t i = 0; i= 0; i--){ - NDB_CLOSE_SOCKET(copy[i]); - copy.erase(i); + + char m_text[256]; + EventLogger::getText(m_text, sizeof(m_text), eventType, theData, nodeId); + + Vector copy; + m_clients.lock(); + int i; + for(i = m_clients.size() - 1; i >= 0; i--){ + if(threshold <= m_clients[i].m_logLevel.getLogLevel(cat)){ + if(m_clients[i].m_socket >= 0 && + println_socket(m_clients[i].m_socket, + MAX_WRITE_TIMEOUT, m_text) == -1){ + copy.push_back(m_clients[i].m_socket); + m_clients.erase(i, false); + } + } } - if(m_sockets.size() == 0 || false){ - m_mgmsrv->startStatisticEventReporting(0); + m_clients.unlock(); + + for(i = 0; (unsigned)im_log_level_requests.push_back(req); + } + } +} + +void +MgmStatService::add_listener(const StatListener& client){ + m_clients.push_back(client); + LogLevel tmp = m_logLevel; + tmp.set_max(client.m_logLevel); + + if(!(tmp == m_logLevel)){ + m_logLevel = tmp; + EventSubscribeReq req; + req = tmp; + req.blockRef = 0; + m_mgmsrv->m_log_level_requests.push_back(req); } } void MgmStatService::stopSessions(){ - for(int i = m_sockets.size() - 1; i >= 0; i--){ - NDB_CLOSE_SOCKET(m_sockets[i]); - m_sockets.erase(i); + for(int i = m_clients.size() - 1; i >= 0; i--){ + if(m_clients[i].m_socket >= 0){ + NDB_CLOSE_SOCKET(m_clients[i].m_socket); + m_clients.erase(i); + } } } @@ -1298,6 +1345,75 @@ MgmApiSession::setParameter(Parser_t::Context &, m_output->println(""); } +void +MgmApiSession::listen_event(Parser::Context & ctx, + Properties const & args) { + + BaseString node, param, value; + args.get("node", node); + args.get("filter", param); + + int result = 0; + BaseString msg; + + MgmStatService::StatListener le; + le.m_socket = m_socket; + + Vector list; + param.trim(); + param.split(list, " ,"); + for(size_t i = 0; i spec; + list[i].trim(); + list[i].split(spec, "=:"); + if(spec.size() != 2){ + msg.appfmt("Invalid filter specification: >%s< >%s< %d", + param.c_str(), list[i].c_str(), spec.size()); + result = -1; + goto done; + } + + spec[0].trim().ndb_toupper(); + int category = ndb_mgm_match_event_category(spec[0].c_str()); + if(category == NDB_MGM_ILLEGAL_EVENT_CATEGORY){ + category = atoi(spec[0].c_str()); + if(category < NDB_MGM_MIN_EVENT_CATEGORY || + category > NDB_MGM_MAX_EVENT_CATEGORY){ + msg.appfmt("Unknown category: >%s<", spec[0].c_str()); + result = -1; + goto done; + } + } + + int level = atoi(spec[1].c_str()); + if(level < 0 || level > 15){ + msg.appfmt("Invalid level: >%s<", spec[1].c_str()); + result = -1; + goto done; + } + category -= CFG_MIN_LOGLEVEL; + le.m_logLevel.setLogLevel((LogLevel::EventCategory)category, level); + } + + if(list.size() == 0){ + msg.appfmt("Empty filter specification"); + result = -1; + goto done; + } + + m_mgmsrv.m_statisticsListner.add_listener(le); + + m_stop = true; + m_socket = -1; + +done: + m_output->println("listen event"); + m_output->println("result: %d", result); + if(result != 0) + m_output->println("msg: %s", msg.c_str()); + m_output->println(""); +} + template class MutexVector; template class Vector const*>; template class Vector; diff --git a/ndb/src/mgmsrv/Services.hpp b/ndb/src/mgmsrv/Services.hpp index 9cf8b59be8f..e47820826b6 100644 --- a/ndb/src/mgmsrv/Services.hpp +++ b/ndb/src/mgmsrv/Services.hpp @@ -83,7 +83,8 @@ public: void configChange(Parser_t::Context &ctx, const class Properties &args); void setParameter(Parser_t::Context &ctx, const class Properties &args); - + void listen_event(Parser_t::Context &ctx, const class Properties &args); + void repCommand(Parser_t::Context &ctx, const class Properties &args); }; @@ -103,28 +104,4 @@ public: } }; -class MgmStatService : public SocketServer::Service, - public MgmtSrvr::StatisticsListner -{ - class MgmtSrvr * m_mgmsrv; - MutexVector m_sockets; -public: - MgmStatService() : m_sockets(5) { - m_mgmsrv = 0; - } - - void setMgm(class MgmtSrvr * mgmsrv){ - m_mgmsrv = mgmsrv; - } - - SocketServer::Session * newSession(NDB_SOCKET_TYPE socket){ - m_sockets.push_back(socket); - m_mgmsrv->startStatisticEventReporting(5); - return 0; - } - - void stopSessions(); - - void println_statistics(const BaseString &line); -}; #endif diff --git a/ndb/src/mgmsrv/main.cpp b/ndb/src/mgmsrv/main.cpp index 323a836cdd4..1a2b95391a9 100644 --- a/ndb/src/mgmsrv/main.cpp +++ b/ndb/src/mgmsrv/main.cpp @@ -15,7 +15,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include -#include #include "MgmtSrvr.hpp" #include "EventLogger.hpp" @@ -70,7 +69,6 @@ struct MgmGlobals { bool use_specific_ip; char * interface_name; int port; - int port_stats; /** The configuration of the cluster */ Config * cluster_config; @@ -82,6 +80,7 @@ struct MgmGlobals { SocketServer * socketServer; }; +int g_no_nodeid_checks= 0; static MgmGlobals glob; @@ -118,7 +117,9 @@ struct getargs args[] = { "Specify configuration file connect string (will default use Ndb.cfg if available)", "filename" }, { "interactive", 0, arg_flag, &glob.interactive, - "Run interactive. Not supported but provided for testing purposes", "" }, + "Run interactive. Not supported but provided for testing purposes", "" }, + { "no-nodeid-checks", 0, arg_flag, &g_no_nodeid_checks, + "Do not provide any node id checks", "" }, { "nodaemon", 0, arg_flag, &glob.non_interactive, "Don't run as daemon, but don't read from stdin", "non-interactive" } }; @@ -129,6 +130,7 @@ int num_args = sizeof(args) / sizeof(args[0]); * MAIN */ NDB_MAIN(mgmsrv){ + ndb_init(); /** * OSE specific. Enable shared ownership of file system resources. * This is needed in order to use the cluster log since the events @@ -151,7 +153,6 @@ NDB_MAIN(mgmsrv){ glob.daemon= 0; } - my_init(); #ifndef DBUG_OFF if (debug_option) DBUG_PUSH(debug_option); @@ -169,20 +170,22 @@ NDB_MAIN(mgmsrv){ MgmApiService * mapi = new MgmApiService(); - MgmStatService * mstat = new MgmStatService(); - /**************************** * Read configuration files * ****************************/ - if (!readLocalConfig()) + LocalConfig local_config; + if(!local_config.init(0,glob.local_config_filename)){ + local_config.printError(); goto error_end; + } + glob.localNodeId = local_config._ownNodeId; + if (!readGlobalConfig()) goto error_end; glob.mgmObject = new MgmtSrvr(glob.localNodeId, BaseString(glob.config_filename), - BaseString(glob.local_config_filename == 0 ? - "" : glob.local_config_filename), + local_config, glob.cluster_config); chdir(NdbConfig_get_path(0)); @@ -230,13 +233,6 @@ NDB_MAIN(mgmsrv){ goto error_end; } - if(!glob.socketServer->setup(mstat, glob.port_stats, glob.interface_name)){ - ndbout_c("Unable to setup statistic port: %d!\nPlease check if the port" - " is already used.", glob.port_stats); - delete mstat; - goto error_end; - } - if(!glob.mgmObject->check_start()){ ndbout_c("Unable to check start management server."); ndbout_c("Probably caused by illegal initial configuration file."); @@ -267,10 +263,7 @@ NDB_MAIN(mgmsrv){ } //glob.mgmObject->saveConfig(); - - mstat->setMgm(glob.mgmObject); mapi->setMgm(glob.mgmObject); - glob.mgmObject->setStatisticsListner(mstat); char msg[256]; snprintf(msg, sizeof(msg), @@ -278,8 +271,8 @@ NDB_MAIN(mgmsrv){ ndbout_c(msg); g_EventLogger.info(msg); - snprintf(msg, 256, "Id: %d, Command port: %d, Statistics port: %d", - glob.localNodeId, glob.port, glob.port_stats); + snprintf(msg, 256, "Id: %d, Command port: %d", + glob.localNodeId, glob.port); ndbout_c(msg); g_EventLogger.info(msg); @@ -309,7 +302,6 @@ NDB_MAIN(mgmsrv){ MgmGlobals::MgmGlobals(){ // Default values port = 0; - port_stats = 0; config_filename = NULL; local_config_filename = NULL; interface_name = 0; @@ -332,38 +324,10 @@ MgmGlobals::~MgmGlobals(){ free(interface_name); } -/** - * @fn readLocalConfig - * @param glob : Global variables - * @return true if success, false otherwise. - * - * How to get LOCAL CONFIGURATION FILE: - * 1. Use local config file name (-l) - * 2. Use environment NDB_HOME + Ndb.cfg - * If NDB_HOME is not set this results in reading from local dir - */ -static bool -readLocalConfig(){ - // Read local config file - LocalConfig lc; - if(!lc.init(glob.local_config_filename)){ - lc.printError(); - return false; - } - - glob.localNodeId = lc._ownNodeId; - return true; -} - - /** * @fn readGlobalConfig * @param glob : Global variables * @return true if success, false otherwise. - * - * How to get the GLOBAL CONFIGURATION: - * 1. Use config file name (this is a text file)(-c) - * 2. Use name from line 2 of local config file, ex: file:///c/ndb/Ndb_cfg.bin */ static bool readGlobalConfig() { diff --git a/ndb/src/mgmsrv/mkconfig/mkconfig.cpp b/ndb/src/mgmsrv/mkconfig/mkconfig.cpp index 3b2046d7b49..28823aaa35e 100644 --- a/ndb/src/mgmsrv/mkconfig/mkconfig.cpp +++ b/ndb/src/mgmsrv/mkconfig/mkconfig.cpp @@ -32,6 +32,7 @@ void usage(const char * prg){ NDB_COMMAND(mkconfig, "mkconfig", "mkconfig", "Make a binary configuration from a config file", 16384){ + ndb_init(); if(argc < 3){ usage(argv[0]); return 0; diff --git a/ndb/src/ndbapi/Ndb.cpp b/ndb/src/ndbapi/Ndb.cpp index 7312eafb2f5..cb126a221a8 100644 --- a/ndb/src/ndbapi/Ndb.cpp +++ b/ndb/src/ndbapi/Ndb.cpp @@ -327,7 +327,11 @@ Ndb::startTransaction(Uint32 aPriority, const char * keyData, Uint32 keyLen) } else { nodeId = 0; }//if - DBUG_RETURN(startTransactionLocal(aPriority, nodeId)); + { + NdbConnection *trans= startTransactionLocal(aPriority, nodeId); + DBUG_PRINT("exit",("start trans= 0x%x", trans)); + DBUG_RETURN(trans); + } } else { DBUG_RETURN(NULL); }//if @@ -451,7 +455,7 @@ Ndb::startTransactionLocal(Uint32 aPriority, Uint32 nodeId) abort(); } #endif - DBUG_PRINT("exit", ("transaction id: %d", tConnection->getTransactionId())); + DBUG_PRINT("exit", ("transid= %lld", tConnection->getTransactionId())); DBUG_RETURN(tConnection); }//Ndb::startTransactionLocal() @@ -465,6 +469,8 @@ void Ndb::closeTransaction(NdbConnection* aConnection) { DBUG_ENTER("Ndb::closeTransaction"); + DBUG_PRINT("enter",("close trans= 0x%x, transid= %lld", + aConnection, aConnection->getTransactionId())); NdbConnection* tCon; NdbConnection* tPreviousCon; diff --git a/ndb/src/ndbapi/NdbDictionary.cpp b/ndb/src/ndbapi/NdbDictionary.cpp index 1e28fbc2db5..c8414ec16a3 100644 --- a/ndb/src/ndbapi/NdbDictionary.cpp +++ b/ndb/src/ndbapi/NdbDictionary.cpp @@ -65,7 +65,7 @@ NdbDictionary::Column::getName() const { void NdbDictionary::Column::setType(Type t){ - m_impl.m_type = t; + m_impl.init(t); } NdbDictionary::Column::Type @@ -103,6 +103,54 @@ NdbDictionary::Column::getLength() const{ return m_impl.m_length; } +void +NdbDictionary::Column::setInlineSize(int size) +{ + m_impl.m_precision = size; +} + +void +NdbDictionary::Column::setCharset(CHARSET_INFO* cs) +{ + m_impl.m_cs = cs; +} + +CHARSET_INFO* +NdbDictionary::Column::getCharset() const +{ + return m_impl.m_cs; +} + +int +NdbDictionary::Column::getInlineSize() const +{ + return m_impl.m_precision; +} + +void +NdbDictionary::Column::setPartSize(int size) +{ + m_impl.m_scale = size; +} + +int +NdbDictionary::Column::getPartSize() const +{ + return m_impl.m_scale; +} + +void +NdbDictionary::Column::setStripeSize(int size) +{ + m_impl.m_length = size; +} + +int +NdbDictionary::Column::getStripeSize() const +{ + return m_impl.m_length; +} + int NdbDictionary::Column::getSize() const{ return m_impl.m_attrSize; @@ -808,7 +856,12 @@ NdbDictionary::Dictionary::listObjects(List& list, Object::Type type) int NdbDictionary::Dictionary::listIndexes(List& list, const char * tableName) { - return m_impl.listIndexes(list, tableName); + const NdbDictionary::Table* tab= getTable(tableName); + if(tab == 0) + { + return -1; + } + return m_impl.listIndexes(list, tab->getTableId()); } const struct NdbError & @@ -821,6 +874,8 @@ NdbDictionary::Dictionary::getNdbError() const { NdbOut& operator<<(NdbOut& out, const NdbDictionary::Column& col) { + const CHARSET_INFO *cs = col.getCharset(); + const char *csname = cs ? cs->name : "?"; out << col.getName() << " "; switch (col.getType()) { case NdbDictionary::Column::Tinyint: @@ -863,10 +918,10 @@ operator<<(NdbOut& out, const NdbDictionary::Column& col) out << "Decimal(" << col.getScale() << "," << col.getPrecision() << ")"; break; case NdbDictionary::Column::Char: - out << "Char(" << col.getLength() << ")"; + out << "Char(" << col.getLength() << ";" << csname << ")"; break; case NdbDictionary::Column::Varchar: - out << "Varchar(" << col.getLength() << ")"; + out << "Varchar(" << col.getLength() << ";" << csname << ")"; break; case NdbDictionary::Column::Binary: out << "Binary(" << col.getLength() << ")"; @@ -886,7 +941,7 @@ operator<<(NdbOut& out, const NdbDictionary::Column& col) break; case NdbDictionary::Column::Text: out << "Text(" << col.getInlineSize() << "," << col.getPartSize() - << ";" << col.getStripeSize() << ")"; + << ";" << col.getStripeSize() << ";" << csname << ")"; break; case NdbDictionary::Column::Undefined: out << "Undefined"; diff --git a/ndb/src/ndbapi/NdbDictionaryImpl.cpp b/ndb/src/ndbapi/NdbDictionaryImpl.cpp index 815ecf8ca6c..9abe52fb030 100644 --- a/ndb/src/ndbapi/NdbDictionaryImpl.cpp +++ b/ndb/src/ndbapi/NdbDictionaryImpl.cpp @@ -36,6 +36,7 @@ #include "NdbEventOperationImpl.hpp" #include "NdbBlob.hpp" #include +#include #define DEBUG_PRINT 0 #define INCOMPATIBLE_VERSION -2 @@ -64,6 +65,7 @@ NdbColumnImpl::operator=(const NdbColumnImpl& col) m_name = col.m_name; m_type = col.m_type; m_precision = col.m_precision; + m_cs = col.m_cs; m_scale = col.m_scale; m_length = col.m_length; m_pk = col.m_pk; @@ -87,10 +89,66 @@ NdbColumnImpl::operator=(const NdbColumnImpl& col) } void -NdbColumnImpl::init() +NdbColumnImpl::init(Type t) { + // do not use default_charset_info as it may not be initialized yet + // use binary collation until NDB tests can handle charsets + CHARSET_INFO* default_cs = &my_charset_latin1_bin; m_attrId = -1; - m_type = NdbDictionary::Column::Unsigned; + m_type = t; + switch (m_type) { + case Tinyint: + case Tinyunsigned: + case Smallint: + case Smallunsigned: + case Mediumint: + case Mediumunsigned: + case Int: + case Unsigned: + case Bigint: + case Bigunsigned: + case Float: + case Double: + m_precision = 0; + m_scale = 0; + m_length = 1; + m_cs = NULL; + break; + case Decimal: + m_precision = 10; + m_scale = 0; + m_length = 1; + m_cs = NULL; + break; + case Char: + case Varchar: + m_precision = 0; + m_scale = 0; + m_length = 1; + m_cs = default_cs; + break; + case Binary: + case Varbinary: + case Datetime: + case Timespec: + m_precision = 0; + m_scale = 0; + m_length = 1; + m_cs = NULL; + break; + case Blob: + m_precision = 256; + m_scale = 8000; + m_length = 4; + m_cs = NULL; + break; + case Text: + m_precision = 256; + m_scale = 8000; + m_length = 4; + m_cs = default_cs; + break; + } m_pk = false; m_nullable = false; m_tupleKey = false; @@ -98,12 +156,10 @@ NdbColumnImpl::init() m_distributionKey = false; m_distributionGroup = false; m_distributionGroupBits = 8; - m_length = 1; - m_scale = 5; - m_precision = 5; m_keyInfoPos = 0; - m_attrSize = 4, - m_arraySize = 1, + // next 2 are set at run time + m_attrSize = 0; + m_arraySize = 0; m_autoIncrement = false; m_autoIncrementInitialValue = 1; m_blobTable = NULL; @@ -146,52 +202,12 @@ NdbColumnImpl::equal(const NdbColumnImpl& col) const return false; } } - if(m_length != col.m_length){ + if (m_precision != col.m_precision || + m_scale != col.m_scale || + m_length != col.m_length || + m_cs != col.m_cs) { return false; } - - switch(m_type){ - case NdbDictionary::Column::Undefined: - break; - case NdbDictionary::Column::Tinyint: - case NdbDictionary::Column::Tinyunsigned: - case NdbDictionary::Column::Smallint: - case NdbDictionary::Column::Smallunsigned: - case NdbDictionary::Column::Mediumint: - case NdbDictionary::Column::Mediumunsigned: - case NdbDictionary::Column::Int: - case NdbDictionary::Column::Unsigned: - case NdbDictionary::Column::Float: - break; - case NdbDictionary::Column::Decimal: - if(m_scale != col.m_scale || - m_precision != col.m_precision){ - return false; - } - break; - case NdbDictionary::Column::Char: - case NdbDictionary::Column::Varchar: - case NdbDictionary::Column::Binary: - case NdbDictionary::Column::Varbinary: - if(m_length != col.m_length){ - return false; - } - break; - case NdbDictionary::Column::Bigint: - case NdbDictionary::Column::Bigunsigned: - case NdbDictionary::Column::Double: - case NdbDictionary::Column::Datetime: - case NdbDictionary::Column::Timespec: - break; - case NdbDictionary::Column::Blob: - case NdbDictionary::Column::Text: - if (m_precision != col.m_precision || - m_scale != col.m_scale || - m_length != col.m_length) { - return false; - } - break; - } if (m_autoIncrement != col.m_autoIncrement){ return false; } @@ -209,14 +225,18 @@ NdbColumnImpl::create_psuedo(const char * name){ if(!strcmp(name, "NDB$FRAGMENT")){ col->setType(NdbDictionary::Column::Unsigned); col->m_impl.m_attrId = AttributeHeader::FRAGMENT; + col->m_impl.m_attrSize = 4; + col->m_impl.m_arraySize = 1; } else if(!strcmp(name, "NDB$ROW_COUNT")){ col->setType(NdbDictionary::Column::Bigunsigned); col->m_impl.m_attrId = AttributeHeader::ROW_COUNT; col->m_impl.m_attrSize = 8; + col->m_impl.m_arraySize = 1; } else if(!strcmp(name, "NDB$COMMIT_COUNT")){ col->setType(NdbDictionary::Column::Bigunsigned); col->m_impl.m_attrId = AttributeHeader::COMMIT_COUNT; col->m_impl.m_attrSize = 8; + col->m_impl.m_arraySize = 1; } else { abort(); } @@ -1127,6 +1147,7 @@ indexTypeMapping[] = { { -1, -1 } }; +// TODO: remove, api-kernel type codes must match now static const ApiKernelMapping columnTypeMapping[] = { @@ -1233,9 +1254,23 @@ NdbDictInterface::parseTableInfo(NdbTableImpl ** ret, return 703; } col->m_extType = attrDesc.AttributeExtType; - col->m_precision = attrDesc.AttributeExtPrecision; + col->m_precision = (attrDesc.AttributeExtPrecision & 0xFFFF); col->m_scale = attrDesc.AttributeExtScale; col->m_length = attrDesc.AttributeExtLength; + // charset in upper half of precision + unsigned cs_number = (attrDesc.AttributeExtPrecision >> 16); + // charset is defined exactly for char types + if (col->getCharType() != (cs_number != 0)) { + delete impl; + return 703; + } + if (col->getCharType()) { + col->m_cs = get_charset(cs_number, MYF(0)); + if (col->m_cs == NULL) { + delete impl; + return 743; + } + } // translate to old kernel types and sizes if (! attrDesc.translateExtType()) { @@ -1372,16 +1407,15 @@ int NdbDictionaryImpl::alterTable(NdbTableImpl &impl) // Remove cached information and let it be refreshed at next access if (m_localHash.get(originalInternalName) != NULL) { m_localHash.drop(originalInternalName); + m_globalHash->lock(); NdbTableImpl * cachedImpl = m_globalHash->get(originalInternalName); // If in local cache it must be in global if (!cachedImpl) abort(); - m_globalHash->lock(); m_globalHash->drop(cachedImpl); m_globalHash->unlock(); } } - return ret; } @@ -1486,9 +1520,23 @@ NdbDictInterface::createOrAlterTable(Ndb & ndb, getKernelConstant(col->m_type, columnTypeMapping, DictTabInfo::ExtUndefined); - tmpAttr.AttributeExtPrecision = col->m_precision; + tmpAttr.AttributeExtPrecision = ((unsigned)col->m_precision & 0xFFFF); tmpAttr.AttributeExtScale = col->m_scale; tmpAttr.AttributeExtLength = col->m_length; + // charset is defined exactly for char types + if (col->getCharType() != (col->m_cs != NULL)) { + m_error.code = 703; + return -1; + } + // primary key type check + if (col->m_pk && ! NdbSqlUtil::usable_in_pk(col->m_type, col->m_cs)) { + m_error.code = 743; + return -1; + } + // charset in upper half of precision + if (col->getCharType()) { + tmpAttr.AttributeExtPrecision |= (col->m_cs->number << 16); + } // DICT will ignore and recompute this (void)tmpAttr.translateExtType(); @@ -1665,6 +1713,7 @@ NdbDictionaryImpl::dropTable(const char * name) int NdbDictionaryImpl::dropTable(NdbTableImpl & impl) { + int res; const char * name = impl.getName(); if(impl.m_status == NdbDictionary::Object::New){ return dropTable(name); @@ -1676,28 +1725,34 @@ NdbDictionaryImpl::dropTable(NdbTableImpl & impl) } List list; - if (listIndexes(list, name) == -1) + if ((res = listIndexes(list, impl.m_tableId)) == -1){ return -1; + } for (unsigned i = 0; i < list.count; i++) { const List::Element& element = list.elements[i]; - if (dropIndex(element.name, name) == -1) + if ((res = dropIndex(element.name, name)) == -1) + { return -1; + } } - + if (impl.m_noOfBlobs != 0) { - if (dropBlobTables(impl) != 0) + if (dropBlobTables(impl) != 0){ return -1; + } } - + int ret = m_receiver.dropTable(impl); - if(ret == 0){ + if(ret == 0 || m_error.code == 709){ const char * internalTableName = impl.m_internalName.c_str(); - + m_localHash.drop(internalTableName); m_globalHash->lock(); m_globalHash->drop(&impl); m_globalHash->unlock(); + + return 0; } return ret; @@ -1713,8 +1768,9 @@ NdbDictionaryImpl::dropBlobTables(NdbTableImpl & t) char btname[NdbBlob::BlobTableNameSize]; NdbBlob::getBlobTableName(btname, &t, &c); if (dropTable(btname) != 0) { - if (m_error.code != 709) + if (m_error.code != 709){ return -1; + } } } return 0; @@ -1950,6 +2006,14 @@ NdbDictInterface::createIndex(Ndb & ndb, m_error.code = 4245; return -1; } + // index key type check + if (it == DictTabInfo::UniqueHashIndex && + ! NdbSqlUtil::usable_in_hash_index(col->m_type, col->m_cs) || + it == DictTabInfo::OrderedIndex && + ! NdbSqlUtil::usable_in_ordered_index(col->m_type, col->m_cs)) { + m_error.code = 743; + return -1; + } attributeList.id[i] = col->m_attrId; } if (it == DictTabInfo::UniqueHashIndex) { @@ -2075,7 +2139,6 @@ NdbDictionaryImpl::dropIndex(NdbIndexImpl & impl, const char * tableName) m_globalHash->drop(impl.m_table); m_globalHash->unlock(); } - return ret; } @@ -2759,14 +2822,11 @@ NdbDictionaryImpl::listObjects(List& list, NdbDictionary::Object::Type type) } int -NdbDictionaryImpl::listIndexes(List& list, const char * tableName) +NdbDictionaryImpl::listIndexes(List& list, Uint32 indexId) { ListTablesReq req; - NdbTableImpl* impl = getTable(tableName); - if (impl == 0) - return -1; req.requestData = 0; - req.setTableId(impl->m_tableId); + req.setTableId(indexId); req.setListNames(true); req.setListIndexes(true); return m_receiver.listObjects(list, req.requestData, m_ndb.usingFullyQualifiedNames()); diff --git a/ndb/src/ndbapi/NdbDictionaryImpl.hpp b/ndb/src/ndbapi/NdbDictionaryImpl.hpp index da5e7e45c36..1fe92db94ed 100644 --- a/ndb/src/ndbapi/NdbDictionaryImpl.hpp +++ b/ndb/src/ndbapi/NdbDictionaryImpl.hpp @@ -52,7 +52,7 @@ public: NdbColumnImpl(NdbDictionary::Column &); // This is not a copy constructor ~NdbColumnImpl(); NdbColumnImpl& operator=(const NdbColumnImpl&); - void init(); + void init(Type t = Unsigned); int m_attrId; BaseString m_name; @@ -60,6 +60,7 @@ public: int m_precision; int m_scale; int m_length; + CHARSET_INFO * m_cs; // not const in MySQL bool m_pk; bool m_tupleKey; @@ -82,6 +83,7 @@ public: Uint32 m_keyInfoPos; Uint32 m_extType; // used by restore (kernel type in versin v2x) bool getInterpretableType() const ; + bool getCharType() const; bool getBlobType() const; /** @@ -388,7 +390,7 @@ public: int stopSubscribeEvent(NdbEventImpl &); int listObjects(List& list, NdbDictionary::Object::Type type); - int listIndexes(List& list, const char * tableName); + int listIndexes(List& list, Uint32 indexId); NdbTableImpl * getTable(const char * tableName, void **data= 0); Ndb_local_table_info * get_local_table_info(const char * internalName); @@ -446,6 +448,14 @@ NdbColumnImpl::getInterpretableType() const { m_type == NdbDictionary::Column::Bigunsigned); } +inline +bool +NdbColumnImpl::getCharType() const { + return (m_type == NdbDictionary::Column::Char || + m_type == NdbDictionary::Column::Varchar || + m_type == NdbDictionary::Column::Text); +} + inline bool NdbColumnImpl::getBlobType() const { diff --git a/ndb/src/ndbapi/NdbIndexOperation.cpp b/ndb/src/ndbapi/NdbIndexOperation.cpp index 0742f8d911c..c62f6962e25 100644 --- a/ndb/src/ndbapi/NdbIndexOperation.cpp +++ b/ndb/src/ndbapi/NdbIndexOperation.cpp @@ -85,6 +85,11 @@ NdbIndexOperation::indxInit(const NdbIndexImpl * anIndex, return 0; } +int NdbIndexOperation::readTuple(NdbOperation::LockMode lm) +{ + return NdbOperation::readTuple(lm); +} + int NdbIndexOperation::readTuple() { // First check that index is unique @@ -164,6 +169,7 @@ int NdbIndexOperation::equal_impl(const NdbColumnImpl* tAttrInfo, Uint32 tData; Uint32 tKeyInfoPosition; const char* aValue = aValuePassed; + Uint32 xfrmData[1024]; Uint32 tempData[1024]; if ((theStatus == OperationDefined) && @@ -224,6 +230,21 @@ int NdbIndexOperation::equal_impl(const NdbColumnImpl* tAttrInfo, m_theIndexDefined[i][2] = true; Uint32 sizeInBytes = tAttrInfo->m_attrSize * tAttrInfo->m_arraySize; + const char* aValueToWrite = aValue; + + CHARSET_INFO* cs = tAttrInfo->m_cs; + if (cs != 0) { + // current limitation: strxfrm does not increase length + assert(cs->strxfrm_multiply == 1); + unsigned n = + (*cs->coll->strnxfrm)(cs, + (uchar*)xfrmData, sizeof(xfrmData), + (const uchar*)aValue, sizeInBytes); + while (n < sizeInBytes) + ((uchar*)xfrmData)[n++] = 0x20; + aValue = (char*)xfrmData; + } + Uint32 bitsInLastWord = 8 * (sizeInBytes & 3) ; Uint32 totalSizeInWords = (sizeInBytes + 3)/4;// Inc. bits in last word Uint32 sizeInWords = sizeInBytes / 4; // Exc. bits in last word @@ -314,13 +335,20 @@ int NdbIndexOperation::equal_impl(const NdbColumnImpl* tAttrInfo, if ((tOpType == InsertRequest) || (tOpType == WriteRequest)) { if (!tAttrInfo->m_indexOnly){ + // invalid data can crash kernel + if (cs != NULL && + (*cs->cset->well_formed_len)(cs, + aValueToWrite, + aValueToWrite + sizeInBytes, + sizeInBytes) != sizeInBytes) + goto equal_error4; Uint32 ahValue; Uint32 sz = totalSizeInWords; AttributeHeader::init(&ahValue, tAttrId, sz); insertATTRINFO( ahValue ); - insertATTRINFOloop((Uint32*)aValue, sizeInWords); + insertATTRINFOloop((Uint32*)aValueToWrite, sizeInWords); if (bitsInLastWord != 0) { - tData = *(Uint32*)(aValue + (sizeInWords << 2)); + tData = *(Uint32*)(aValueToWrite + (sizeInWords << 2)); tData = convertEndian(tData); tData = tData & ((1 << bitsInLastWord) - 1); tData = convertEndian(tData); @@ -411,7 +439,10 @@ int NdbIndexOperation::equal_impl(const NdbColumnImpl* tAttrInfo, equal_error3: setErrorCodeAbort(4209); - + return -1; + + equal_error4: + setErrorCodeAbort(744); return -1; } diff --git a/ndb/src/ndbapi/NdbLinHash.hpp b/ndb/src/ndbapi/NdbLinHash.hpp index f786600607f..f245a261a04 100644 --- a/ndb/src/ndbapi/NdbLinHash.hpp +++ b/ndb/src/ndbapi/NdbLinHash.hpp @@ -287,17 +287,14 @@ NdbLinHash::deleteKey ( const char* str, Uint32 len){ NdbElement_t **chainp = &directory[dir]->elements[seg]; for(NdbElement_t * chain = *chainp; chain != 0; chain = chain->next){ if(chain->len == len && !memcmp(chain->str, str, len)){ + C *data= chain->theData; if (oldChain == 0) { - C *data= chain->theData; - delete chain; - * chainp = 0; - return data; + * chainp = chain->next; } else { - C *data= chain->theData; oldChain->next = chain->next; - delete chain; - return data; } + delete chain; + return data; } else { oldChain = chain; } diff --git a/ndb/src/ndbapi/NdbOperationDefine.cpp b/ndb/src/ndbapi/NdbOperationDefine.cpp index 6d995e06582..1cbfedd21b1 100644 --- a/ndb/src/ndbapi/NdbOperationDefine.cpp +++ b/ndb/src/ndbapi/NdbOperationDefine.cpp @@ -103,6 +103,24 @@ NdbOperation::writeTuple() * int readTuple(); *****************************************************************************/ int +NdbOperation::readTuple(NdbOperation::LockMode lm) +{ + switch(lm) { + case LM_Read: + return readTuple(); + break; + case LM_Exclusive: + return readTupleExclusive(); + break; + case LM_CommittedRead: + return readTuple(); + break; + }; +} +/****************************************************************************** + * int readTuple(); + *****************************************************************************/ +int NdbOperation::readTuple() { NdbConnection* tNdbCon = theNdbCon; @@ -492,6 +510,17 @@ NdbOperation::setValue( const NdbColumnImpl* tAttrInfo, // Insert Attribute Id into ATTRINFO part. const Uint32 sizeInBytes = tAttrInfo->m_attrSize * tAttrInfo->m_arraySize; + + CHARSET_INFO* cs = tAttrInfo->m_cs; + // invalid data can crash kernel + if (cs != NULL && + (*cs->cset->well_formed_len)(cs, + aValue, + aValue + sizeInBytes, + sizeInBytes) != sizeInBytes) { + setErrorCodeAbort(744); + return -1; + } #if 0 tAttrSize = tAttrInfo->theAttrSize; tArraySize = tAttrInfo->theArraySize; diff --git a/ndb/src/ndbapi/NdbOperationSearch.cpp b/ndb/src/ndbapi/NdbOperationSearch.cpp index 19cb133dbf7..e5166fc4a82 100644 --- a/ndb/src/ndbapi/NdbOperationSearch.cpp +++ b/ndb/src/ndbapi/NdbOperationSearch.cpp @@ -60,6 +60,7 @@ NdbOperation::equal_impl(const NdbColumnImpl* tAttrInfo, Uint32 tData; Uint32 tKeyInfoPosition; const char* aValue = aValuePassed; + Uint32 xfrmData[1024]; Uint32 tempData[1024]; if ((theStatus == OperationDefined) && @@ -117,6 +118,21 @@ NdbOperation::equal_impl(const NdbColumnImpl* tAttrInfo, theTupleKeyDefined[i][2] = true; Uint32 sizeInBytes = tAttrInfo->m_attrSize * tAttrInfo->m_arraySize; + const char* aValueToWrite = aValue; + + CHARSET_INFO* cs = tAttrInfo->m_cs; + if (cs != 0) { + // current limitation: strxfrm does not increase length + assert(cs->strxfrm_multiply == 1); + unsigned n = + (*cs->coll->strnxfrm)(cs, + (uchar*)xfrmData, sizeof(xfrmData), + (const uchar*)aValue, sizeInBytes); + while (n < sizeInBytes) + ((uchar*)xfrmData)[n++] = 0x20; + aValue = (char*)xfrmData; + } + Uint32 bitsInLastWord = 8 * (sizeInBytes & 3) ; Uint32 totalSizeInWords = (sizeInBytes + 3)/4; // Inc. bits in last word Uint32 sizeInWords = sizeInBytes / 4; // Exc. bits in last word @@ -206,13 +222,20 @@ NdbOperation::equal_impl(const NdbColumnImpl* tAttrInfo, if ((tOpType == InsertRequest) || (tOpType == WriteRequest)) { if (!tAttrInfo->m_indexOnly){ + // invalid data can crash kernel + if (cs != NULL && + (*cs->cset->well_formed_len)(cs, + aValueToWrite, + aValueToWrite + sizeInBytes, + sizeInBytes) != sizeInBytes) + goto equal_error4; Uint32 ahValue; const Uint32 sz = totalSizeInWords; AttributeHeader::init(&ahValue, tAttrId, sz); insertATTRINFO( ahValue ); - insertATTRINFOloop((Uint32*)aValue, sizeInWords); + insertATTRINFOloop((Uint32*)aValueToWrite, sizeInWords); if (bitsInLastWord != 0) { - tData = *(Uint32*)(aValue + (sizeInWords << 2)); + tData = *(Uint32*)(aValueToWrite + (sizeInWords << 2)); tData = convertEndian(tData); tData = tData & ((1 << bitsInLastWord) - 1); tData = convertEndian(tData); @@ -311,6 +334,10 @@ NdbOperation::equal_impl(const NdbColumnImpl* tAttrInfo, equal_error3: setErrorCodeAbort(4209); return -1; + + equal_error4: + setErrorCodeAbort(744); + return -1; } /****************************************************************************** diff --git a/ndb/src/ndbapi/NdbScanOperation.cpp b/ndb/src/ndbapi/NdbScanOperation.cpp index 86c174c4545..3ff2a32d418 100644 --- a/ndb/src/ndbapi/NdbScanOperation.cpp +++ b/ndb/src/ndbapi/NdbScanOperation.cpp @@ -47,11 +47,13 @@ NdbScanOperation::NdbScanOperation(Ndb* aNdb) : m_sent_receivers = 0; m_receivers = 0; m_array = new Uint32[1]; // skip if on delete in fix_receivers + theSCAN_TABREQ = 0; } NdbScanOperation::~NdbScanOperation() { for(Uint32 i = 0; irelease(); theNdb->releaseNdbScanRec(m_receivers[i]); } delete[] m_array; @@ -191,7 +193,7 @@ NdbResultSet* NdbScanOperation::readTuples(NdbScanOperation::LockMode lm, return 0; } - theSCAN_TABREQ = theNdb->getSignal(); + theSCAN_TABREQ = (!theSCAN_TABREQ ? theNdb->getSignal() : theSCAN_TABREQ); if (theSCAN_TABREQ == NULL) { setErrorCodeAbort(4000); return 0; @@ -719,6 +721,12 @@ void NdbScanOperation::release() for(Uint32 i = 0; irelease(); } + if(theSCAN_TABREQ) + { + theNdb->releaseSignal(theSCAN_TABREQ); + theSCAN_TABREQ = 0; + } + NdbOperation::release(); } /*************************************************************************** @@ -1096,30 +1104,43 @@ NdbIndexScanOperation::setBound(const NdbColumnImpl* tAttrInfo, theStatus == SetBound && (0 <= type && type <= 4) && len <= 8000) { - // bound type - + // insert bound type insertATTRINFO(type); - // attribute header Uint32 sizeInBytes = tAttrInfo->m_attrSize * tAttrInfo->m_arraySize; + // normalize char bound + CHARSET_INFO* cs = tAttrInfo->m_cs; + Uint32 xfrmData[2000]; + if (cs != NULL && aValue != NULL) { + // current limitation: strxfrm does not increase length + assert(cs->strxfrm_multiply == 1); + unsigned n = + (*cs->coll->strnxfrm)(cs, + (uchar*)xfrmData, sizeof(xfrmData), + (const uchar*)aValue, sizeInBytes); + while (n < sizeInBytes) + ((uchar*)xfrmData)[n++] = 0x20; + aValue = (char*)xfrmData; + } if (len != sizeInBytes && (len != 0)) { setErrorCodeAbort(4209); return -1; } + // insert attribute header len = aValue != NULL ? sizeInBytes : 0; Uint32 tIndexAttrId = tAttrInfo->m_attrId; Uint32 sizeInWords = (len + 3) / 4; AttributeHeader ah(tIndexAttrId, sizeInWords); insertATTRINFO(ah.m_value); if (len != 0) { - // attribute data + // insert attribute data if ((UintPtr(aValue) & 0x3) == 0 && (len & 0x3) == 0) insertATTRINFOloop((const Uint32*)aValue, sizeInWords); else { - Uint32 temp[2000]; - memcpy(temp, aValue, len); + Uint32 tempData[2000]; + memcpy(tempData, aValue, len); while ((len & 0x3) != 0) - ((char*)temp)[len++] = 0; - insertATTRINFOloop(temp, sizeInWords); + ((char*)tempData)[len++] = 0; + insertATTRINFOloop(tempData, sizeInWords); } } @@ -1206,11 +1227,11 @@ NdbIndexScanOperation::compare(Uint32 skip, Uint32 cols, if((r1_null ^ (unsigned)r2->isNULL())){ return (r1_null ? -1 : 1); } - Uint32 type = NdbColumnImpl::getImpl(* r1->m_column).m_extType; + const NdbColumnImpl & col = NdbColumnImpl::getImpl(* r1->m_column); Uint32 size = (r1->theAttrSize * r1->theArraySize + 3) / 4; if(!r1_null){ - const NdbSqlUtil::Type& t = NdbSqlUtil::getType(type); - int r = (*t.m_cmp)(d1, d2, size, size); + const NdbSqlUtil::Type& sqlType = NdbSqlUtil::getType(col.m_extType); + int r = (*sqlType.m_cmp)(col.m_cs, d1, d2, size, size); if(r){ assert(r != NdbSqlUtil::CmpUnknown); return r; diff --git a/ndb/src/ndbapi/NdbScanReceiver.cpp b/ndb/src/ndbapi/NdbScanReceiver.cpp deleted file mode 100644 index 6c8c16c3ecf..00000000000 --- a/ndb/src/ndbapi/NdbScanReceiver.cpp +++ /dev/null @@ -1,187 +0,0 @@ -/* Copyright (C) 2003 MySQL AB - - 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 "NdbScanReceiver.hpp" -#include - -#include - -#include - - -/*************************************************************************** - * int receiveKEYINFO20( NdbApiSignal* aSignal) - * - * Remark: Handles the reception of the KEYINFO20 signal. - * Save a copy of the signal in list - * - ***************************************************************************/ -int -NdbScanReceiver::receiveKEYINFO20( NdbApiSignal* aSignal){ - const KeyInfo20 * const keyInfo = CAST_CONSTPTR(KeyInfo20, aSignal->getDataPtr()); - if (theStatus != Waiting){ - //ndbout << "Dropping KEYINFO20, theStatus="<getLength() < 5){ - //ndbout << "Dropping KEYINFO20, length="<getLength() << endl; - } - Uint64 tCurrTransId = theNdbOp->theNdbCon->getTransactionId(); - Uint64 tRecTransId = (Uint64)keyInfo->transId1 + ((Uint64)keyInfo->transId2 << 32); - if ((tRecTransId - tCurrTransId) != (Uint64)0){ - //ndbout << "Dropping KEYINFO20 wrong transid" << endl; - return -1; - } - - NdbApiSignal * tCopy = new NdbApiSignal(0);//getSignal(); - if (tCopy == NULL) { - theNdbOp->setErrorCode(4000); - return 2; // theWaitState = NO_WAIT - } - // Put copy last in list of KEYINFO20 signals - tCopy->copyFrom(aSignal); - tCopy->next(NULL); - if (theFirstKEYINFO20_Recv == NULL) - theFirstKEYINFO20_Recv = tCopy; - else - theLastKEYINFO20_Recv->next(tCopy); - theLastKEYINFO20_Recv = tCopy; - - theTotalKI_Len = keyInfo->keyLen; // This is the total length of all signals - theTotalRecKI_Len += aSignal->getLength() - 5; - return theNdbOp->theNdbCon->checkNextScanResultComplete(); -} - -/*************************************************************************** - * int receiveTRANSID_AI_SCAN( NdbApiSignal* aSignal) - * - * Remark: Handles the reception of the TRANSID_AI_signal with - * 22 signal data words. - * Save a copy of the signal in list and check if all - * signals belonging to this resultset is receieved. - * - ***************************************************************************/ -int -NdbScanReceiver::receiveTRANSID_AI_SCAN( NdbApiSignal* aSignal) -{ - const Uint32* aDataPtr = aSignal->getDataPtr(); - if (theStatus != Waiting){ - //ndbout << "Dropping TRANSID_AI, theStatus="<getLength() < 3){ - //ndbout << "Dropping TRANSID_AI, length="<getLength() << endl; - return -1; - } - if (theNdbOp == NULL){ - //ndbout << "Dropping TRANSID_AI, theNdbOp == NULL" << endl; - return -1; - } - if (theNdbOp->theNdbCon == NULL){ - //ndbout << "Dropping TRANSID_AI, theNdbOp->theNdbCon == NULL" << endl; - return -1; - } - Uint64 tCurrTransId = theNdbOp->theNdbCon->getTransactionId(); - Uint64 tRecTransId = (Uint64)aDataPtr[1] + ((Uint64)aDataPtr[2] << 32); - if ((tRecTransId - tCurrTransId) != (Uint64)0){ - //ndbout << "Dropping TRANSID_AI wrong transid" << endl; - return -1; - } - - NdbApiSignal * tCopy = new NdbApiSignal(0);//getSignal(); - if (tCopy == NULL){ - theNdbOp->setErrorCode(4000); - return 2; // theWaitState = NO_WAIT - } - tCopy->copyFrom(aSignal); - tCopy->next(NULL); - if (theFirstTRANSID_AI_Recv == NULL) - theFirstTRANSID_AI_Recv = tCopy; - else - theLastTRANSID_AI_Recv->next(tCopy); - theLastTRANSID_AI_Recv = tCopy; - theTotalRecAI_Len += aSignal->getLength() - 3; - - return theNdbOp->theNdbCon->checkNextScanResultComplete(); -} - -/*************************************************************************** - * int executeSavedSignals() - * - * Remark: Execute all saved TRANSID_AI signals into the parent NdbOperation - * - * - ***************************************************************************/ -int -NdbScanReceiver::executeSavedSignals(){ - - NdbApiSignal* tSignal = theFirstTRANSID_AI_Recv; - while (tSignal != NULL) { - const Uint32* tDataPtr = tSignal->getDataPtr(); - - int tRet = theNdbOp->receiveREAD_AI((Uint32*)&tDataPtr[3], - tSignal->getLength() - 3); - if (tRet != -1){ - // -1 means that more signals are wanted ? - // Make sure there are no more signals in the list - assert(tSignal->next() == NULL); - } - tSignal = tSignal->next(); - } - // receiveREAD_AI may not copy to application buffers - NdbRecAttr* tRecAttr = theNdbOp->theFirstRecAttr; - while (tRecAttr != NULL) { - if (tRecAttr->copyoutRequired()) // copy to application buffer - tRecAttr->copyout(); - tRecAttr = tRecAttr->next(); - } - // Release TRANSID_AI signals for this receiver - while(theFirstTRANSID_AI_Recv != NULL){ - NdbApiSignal* tmp = theFirstTRANSID_AI_Recv; - theFirstTRANSID_AI_Recv = tmp->next(); - delete tmp; - } - - // theNdbOp->theNdb->releaseSignalsInList(&theFirstTRANSID_AI_Recv); - theFirstTRANSID_AI_Recv = NULL; - theLastTRANSID_AI_Recv = NULL; - theStatus = Executed; - - return 0; -} - - -void -NdbScanReceiver::prepareNextScanResult(){ - if(theStatus == Executed){ - - // theNdbOp->theNdb->releaseSignalsInList(&theFirstKEYINFO20_Recv); - while(theFirstKEYINFO20_Recv != NULL){ - NdbApiSignal* tmp = theFirstKEYINFO20_Recv; - theFirstKEYINFO20_Recv = tmp->next(); - delete tmp; - } - theFirstKEYINFO20_Recv = NULL; - theLastKEYINFO20_Recv = NULL; - theTotalRecAI_Len = 0; - theTotalRecKI_Len = 0; - if (theLockMode == true) - theTotalKI_Len = 0xFFFFFFFF; - else - theTotalKI_Len = 0; - theStatus = Waiting; - } -} diff --git a/ndb/src/ndbapi/NdbScanReceiver.hpp b/ndb/src/ndbapi/NdbScanReceiver.hpp deleted file mode 100644 index 72f9e48f02c..00000000000 --- a/ndb/src/ndbapi/NdbScanReceiver.hpp +++ /dev/null @@ -1,210 +0,0 @@ -/* Copyright (C) 2003 MySQL AB - - 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 */ - -#ifndef NdbScanReceiver_H -#define NdbScanReceiver_H - -#include "Ndb.hpp" -#include "NdbConnection.hpp" -#include "NdbOperation.hpp" -#include "NdbApiSignal.hpp" -#include "NdbReceiver.hpp" -#include - - -class NdbScanReceiver -{ - enum ReceiverStatus { Init, - Waiting, - Completed, - Executed, - Released }; - - friend class Ndb; - friend class NdbOperation; -public: - NdbScanReceiver(Ndb *aNdb) : - theReceiver(aNdb), - theNdbOp(NULL), - theFirstTRANSID_AI_Recv(NULL), - theLastTRANSID_AI_Recv(NULL), - theFirstKEYINFO20_Recv(NULL), - theLastKEYINFO20_Recv(NULL), - theTotalRecAI_Len(0), - theTotalKI_Len(0xFFFFFFFF), - theTotalRecKI_Len(0), - theStatus(Init), - theNextScanRec(NULL) - { - theReceiver.init(NdbReceiver::NDB_SCANRECEIVER, this); - } - - int checkMagicNumber(); - int receiveTRANSID_AI_SCAN(NdbApiSignal*); - int receiveKEYINFO20(NdbApiSignal*); - int executeSavedSignals(); - void prepareNextScanResult(); - - NdbScanReceiver* next(); - void next(NdbScanReceiver*); - - bool isCompleted(Uint32 aiLenToReceive); - void setCompleted(); - - void init(NdbOperation* aNdbOp, bool lockMode); - - Uint32 ptr2int() { return theReceiver.getId(); }; -private: - NdbScanReceiver(); - void release(); - - NdbReceiver theReceiver; - - NdbOperation* theNdbOp; - NdbApiSignal* theFirstTRANSID_AI_Recv; - NdbApiSignal* theLastTRANSID_AI_Recv; - NdbApiSignal* theFirstKEYINFO20_Recv; - NdbApiSignal* theLastKEYINFO20_Recv; - - Uint32 theTotalRecAI_Len; - Uint32 theTotalKI_Len; - Uint32 theTotalRecKI_Len; - ReceiverStatus theStatus; - Uint32 theMagicNumber; - NdbScanReceiver* theNextScanRec; - bool theLockMode; - -}; - -inline -void -NdbScanReceiver::init(NdbOperation* aNdbOp, bool lockMode){ - assert(theStatus == Init || theStatus == Released); - theNdbOp = aNdbOp; - theMagicNumber = 0xA0B1C2D3; - theTotalRecAI_Len = 0; - - /* If we are locking the records for take over - * KI_len to receive is at least 1, since we don't know yet - * how much KI we are expecting(this is written in the first KI signal) - * set theTotalKI_Len to FFFFFFFF, this will make the ScanReciever wait for - * at least the first KI, and when that is received we will know if - * we are expecting another one - */ - theLockMode = lockMode; - if (theLockMode == true) - theTotalKI_Len = 0xFFFFFFFF; - else - theTotalKI_Len = 0; - theTotalRecKI_Len = 0; - - assert(theNextScanRec == NULL); - theNextScanRec = NULL; - assert(theFirstTRANSID_AI_Recv == NULL); - theFirstTRANSID_AI_Recv = NULL; - assert(theLastTRANSID_AI_Recv == NULL); - theLastTRANSID_AI_Recv = NULL; - assert(theFirstKEYINFO20_Recv == NULL); - theFirstKEYINFO20_Recv = NULL; - theLastKEYINFO20_Recv = NULL; - - theStatus = Waiting; -}; - - -inline -void -NdbScanReceiver::release(){ - theStatus = Released; - // theNdbOp->theNdb->releaseSignalsInList(&theFirstTRANSID_AI_Recv); - while(theFirstTRANSID_AI_Recv != NULL){ - NdbApiSignal* tmp = theFirstTRANSID_AI_Recv; - theFirstTRANSID_AI_Recv = tmp->next(); - delete tmp; - } - theFirstTRANSID_AI_Recv = NULL; - theLastTRANSID_AI_Recv = NULL; - // theNdbOp->theNdb->releaseSignalsInList(&theFirstKEYINFO20_Recv); - while(theFirstKEYINFO20_Recv != NULL){ - NdbApiSignal* tmp = theFirstKEYINFO20_Recv; - theFirstKEYINFO20_Recv = tmp->next(); - delete tmp; - } - theFirstKEYINFO20_Recv = NULL; - theLastKEYINFO20_Recv = NULL; - theNdbOp = NULL; - theTotalRecAI_Len = 0; - theTotalRecKI_Len = 0; - theTotalKI_Len = 0xFFFFFFFF; -}; - -inline -int -NdbScanReceiver::checkMagicNumber() -{ - if (theMagicNumber != 0xA0B1C2D3) - return -1; - return 0; -} - -inline -NdbScanReceiver* -NdbScanReceiver::next(){ - return theNextScanRec; -} - -inline -void -NdbScanReceiver::next(NdbScanReceiver* aScanRec){ - theNextScanRec = aScanRec; -} - -inline -bool -NdbScanReceiver::isCompleted(Uint32 aiLenToReceive){ - assert(theStatus == Waiting || theStatus == Completed); -#if 0 - ndbout << "NdbScanReceiver::isCompleted"<connect(); } NdbMutex_Unlock(&createNdbMutex); setup(global_ndb_cluster_connection, aDataBase, aSchema); + DBUG_VOID_RETURN; } Ndb::Ndb( Ndb_cluster_connection *ndb_cluster_connection, const char* aDataBase , const char* aSchema) { + DBUG_ENTER("Ndb::Ndb()"); + DBUG_PRINT("enter",("Ndb::Ndb this=0x%x", this)); if (global_ndb_cluster_connection != 0 && global_ndb_cluster_connection != ndb_cluster_connection) abort(); // old and new Ndb constructor used mixed theNoOfNdbObjects= -1; setup(ndb_cluster_connection, aDataBase, aSchema); + DBUG_VOID_RETURN; } void Ndb::setup(Ndb_cluster_connection *ndb_cluster_connection, @@ -215,6 +219,7 @@ void Ndb::setConnectString(const char * connectString) Ndb::~Ndb() { DBUG_ENTER("Ndb::~Ndb()"); + DBUG_PRINT("enter",("Ndb::~Ndb this=0x%x",this)); doDisconnect(); delete theDictionary; @@ -242,10 +247,6 @@ Ndb::~Ndb() // closeSchemaTransaction(theSchemaConToNdbList); while ( theConIdleList != NULL ) freeNdbCon(); - while ( theSignalIdleList != NULL ) - freeSignal(); - while (theRecAttrIdleList != NULL) - freeRecAttr(); while (theOpIdleList != NULL) freeOperation(); while (theScanOpIdleList != NULL) @@ -264,6 +265,10 @@ Ndb::~Ndb() freeNdbScanRec(); while (theNdbBlobIdleList != NULL) freeNdbBlob(); + while (theRecAttrIdleList != NULL) + freeRecAttr(); + while ( theSignalIdleList != NULL ) + freeSignal(); releaseTransactionArrays(); startTransactionNodeSelectionData.release(); diff --git a/ndb/src/ndbapi/TransporterFacade.hpp b/ndb/src/ndbapi/TransporterFacade.hpp index 76beaa708f1..8b6e38a0611 100644 --- a/ndb/src/ndbapi/TransporterFacade.hpp +++ b/ndb/src/ndbapi/TransporterFacade.hpp @@ -236,7 +236,6 @@ public: NdbMutex* theMutexPtr; private: static TransporterFacade* theFacadeInstance; - static ConfigRetriever *s_config_retriever; public: GlobalDictCache m_globalDictCache; diff --git a/ndb/src/ndbapi/ndb_cluster_connection.cpp b/ndb/src/ndbapi/ndb_cluster_connection.cpp index 27695cec187..5be4f0f9f91 100644 --- a/ndb/src/ndbapi/ndb_cluster_connection.cpp +++ b/ndb/src/ndbapi/ndb_cluster_connection.cpp @@ -16,6 +16,7 @@ #include #include +#include #include #include @@ -30,14 +31,18 @@ static int g_run_connect_thread= 0; Ndb_cluster_connection::Ndb_cluster_connection(const char *connect_string) { + DBUG_ENTER("Ndb_cluster_connection"); + DBUG_PRINT("enter",("Ndb_cluster_connection this=0x%x", this)); m_facade= TransporterFacade::theFacadeInstance= new TransporterFacade(); if (connect_string) - m_connect_string= strdup(connect_string); + m_connect_string= my_strdup(connect_string,MYF(MY_WME)); else m_connect_string= 0; m_config_retriever= 0; + m_local_config= 0; m_connect_thread= 0; m_connect_callback= 0; + DBUG_VOID_RETURN; } extern "C" pthread_handler_decl(run_ndb_cluster_connection_connect_thread, me) @@ -55,6 +60,7 @@ void Ndb_cluster_connection::connect_thread() DBUG_ENTER("Ndb_cluster_connection::connect_thread"); int r; do { + NdbSleep_SecSleep(1); if ((r = connect(1)) == 0) break; if (r == -1) { @@ -75,6 +81,7 @@ int Ndb_cluster_connection::start_connect_thread(int (*connect_callback)(void)) m_connect_callback= connect_callback; if ((r = connect(1)) == 1) { + DBUG_PRINT("info",("starting thread")); m_connect_thread= NdbThread_Create(run_ndb_cluster_connection_connect_thread, (void**)this, 32768, @@ -99,10 +106,16 @@ int Ndb_cluster_connection::connect(int reconnect) do { if (m_config_retriever == 0) { - m_config_retriever= new ConfigRetriever(NDB_VERSION, NODE_TYPE_API); - m_config_retriever->setConnectString(m_connect_string); - if(m_config_retriever->init() == -1) - break; + if (m_local_config == 0) { + m_local_config= new LocalConfig(); + if (!m_local_config->init(m_connect_string,0)) { + ndbout << "Configuration error: Unable to retrieve local config" << endl; + m_local_config->printError(); + m_local_config->printUsage(); + DBUG_RETURN(-1); + } + } + m_config_retriever= new ConfigRetriever(*m_local_config, NDB_VERSION, NODE_TYPE_API); } else if (reconnect == 0) @@ -118,6 +131,7 @@ int Ndb_cluster_connection::connect(int reconnect) else if(m_config_retriever->do_connect() == -1) break; + Uint32 nodeId = m_config_retriever->allocNodeId(); for(Uint32 i = 0; nodeId == 0 && i<5; i++){ NdbSleep_SecSleep(3); @@ -145,6 +159,8 @@ int Ndb_cluster_connection::connect(int reconnect) Ndb_cluster_connection::~Ndb_cluster_connection() { + DBUG_ENTER("~Ndb_cluster_connection"); + DBUG_PRINT("enter",("~Ndb_cluster_connection this=0x%x", this)); TransporterFacade::stop_instance(); if (m_connect_thread) { @@ -161,10 +177,12 @@ Ndb_cluster_connection::~Ndb_cluster_connection() abort(); TransporterFacade::theFacadeInstance= 0; } - if (m_connect_string) - free(m_connect_string); + my_free(m_connect_string,MYF(MY_ALLOW_ZERO_PTR)); if (m_config_retriever) delete m_config_retriever; + if (m_local_config) + delete m_local_config; + DBUG_VOID_RETURN; } diff --git a/ndb/src/ndbapi/ndberror.c b/ndb/src/ndbapi/ndberror.c index fdae5475d56..fdfd8a15fb0 100644 --- a/ndb/src/ndbapi/ndberror.c +++ b/ndb/src/ndbapi/ndberror.c @@ -281,6 +281,9 @@ ErrorBundle ErrorCodes[] = { { 739, SE, "Unsupported primary key length" }, { 740, SE, "Nullable primary key not supported" }, { 741, SE, "Unsupported alter table" }, + { 742, SE, "Unsupported attribute type in index" }, + { 743, SE, "Unsupported character set in table or index" }, + { 744, SE, "Character string is invalid for given character set" }, { 241, SE, "Invalid schema object version" }, { 283, SE, "Table is being dropped" }, { 284, SE, "Table not defined in transaction coordinator" }, diff --git a/ndb/test/include/NDBT_Table.hpp b/ndb/test/include/NDBT_Table.hpp index 59db3ed1092..d2f99b85187 100644 --- a/ndb/test/include/NDBT_Table.hpp +++ b/ndb/test/include/NDBT_Table.hpp @@ -33,10 +33,10 @@ public: { assert(_name != 0); + setType(_type); + setLength(_length); setNullable(_nullable); setPrimaryKey(_pk); - setLength(_length); - setType(_type); } }; diff --git a/ndb/test/ndbapi/acid.cpp b/ndb/test/ndbapi/acid.cpp index 157b3c7b3ef..3eb1625be26 100644 --- a/ndb/test/ndbapi/acid.cpp +++ b/ndb/test/ndbapi/acid.cpp @@ -434,6 +434,7 @@ extern "C" void* NdbThreadFuncRead(void* pArg) NDB_COMMAND(acid, "acid", "acid", "acid", 65535) { + ndb_init(); long nSeconds = 60; int rc = NDBT_OK; diff --git a/ndb/test/ndbapi/acid2.cpp b/ndb/test/ndbapi/acid2.cpp index 434a0450daa..7bd7ec00ac5 100644 --- a/ndb/test/ndbapi/acid2.cpp +++ b/ndb/test/ndbapi/acid2.cpp @@ -610,6 +610,7 @@ extern "C" void* ThreadFunc(void*) int main(int argc, char* argv[]) { + ndb_init(); Uint32 nSeconds = 1; Uint32 nThread = 1; diff --git a/ndb/test/ndbapi/bank/Bank.cpp b/ndb/test/ndbapi/bank/Bank.cpp index 4581d1a9842..c6029259357 100644 --- a/ndb/test/ndbapi/bank/Bank.cpp +++ b/ndb/test/ndbapi/bank/Bank.cpp @@ -156,7 +156,14 @@ int Bank::performTransactionImpl1(int fromAccountId, int check; + // Ok, all clear to do the transaction + Uint64 transId; + if (getNextTransactionId(transId) != NDBT_OK){ + return NDBT_FAILED; + } + NdbConnection* pTrans = m_ndb.startTransaction(); + if( pTrans == NULL ) { const NdbError err = m_ndb.getNdbError(); if (err.status == NdbError::TemporaryError){ @@ -167,6 +174,13 @@ int Bank::performTransactionImpl1(int fromAccountId, return NDBT_FAILED; } + Uint64 currTime; + if (prepareGetCurrTimeOp(pTrans, currTime) != NDBT_OK){ + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + /** * Check balance on from account */ @@ -205,29 +219,6 @@ int Bank::performTransactionImpl1(int fromAccountId, return NDBT_FAILED; } - check = pTrans->execute(NoCommit); - if( check == -1 ) { - const NdbError err = pTrans->getNdbError(); - m_ndb.closeTransaction(pTrans); - if (err.status == NdbError::TemporaryError){ - ERR(err); - return NDBT_TEMPORARY; - } - ERR(err); - return NDBT_FAILED; - } - - Uint32 balanceFrom = balanceFromRec->u_32_value(); - // ndbout << "balanceFrom: " << balanceFrom << endl; - - if (((Int64)balanceFrom - amount) < 0){ - m_ndb.closeTransaction(pTrans); - //ndbout << "Not enough funds" << endl; - return NOT_ENOUGH_FUNDS; - } - - Uint32 fromAccountType = fromAccountTypeRec->u_32_value(); - /** * Read balance on to account */ @@ -278,21 +269,22 @@ int Bank::performTransactionImpl1(int fromAccountId, return NDBT_FAILED; } + + Uint32 balanceFrom = balanceFromRec->u_32_value(); + // ndbout << "balanceFrom: " << balanceFrom << endl; + + if (((Int64)balanceFrom - amount) < 0){ + m_ndb.closeTransaction(pTrans); + //ndbout << "Not enough funds" << endl; + return NOT_ENOUGH_FUNDS; + } + + Uint32 fromAccountType = fromAccountTypeRec->u_32_value(); + Uint32 balanceTo = balanceToRec->u_32_value(); // ndbout << "balanceTo: " << balanceTo << endl; Uint32 toAccountType = toAccountTypeRec->u_32_value(); - // Ok, all clear to do the transaction - Uint64 transId; - if (getNextTransactionId(transId) != NDBT_OK){ - return NDBT_FAILED; - } - - Uint64 currTime; - if (getCurrTime(currTime) != NDBT_OK){ - return NDBT_FAILED; - } - /** * Update balance on from account */ @@ -1988,35 +1980,13 @@ int Bank::readSystemValue(SystemValueId sysValId, Uint64 & value){ ERR(m_ndb.getNdbError()); return NDBT_FAILED; } - - NdbOperation* pOp = pTrans->getNdbOperation("SYSTEM_VALUES"); - if (pOp == NULL) { + + if (prepareReadSystemValueOp(pTrans, sysValId, value) != NDBT_OK) { ERR(pTrans->getNdbError()); m_ndb.closeTransaction(pTrans); return NDBT_FAILED; } - - check = pOp->readTuple(); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - check = pOp->equal("SYSTEM_VALUES_ID", sysValId); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - NdbRecAttr* valueRec = pOp->getValue("VALUE"); - if( valueRec ==NULL ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - + check = pTrans->execute(Commit); if( check == -1 ) { ERR(pTrans->getNdbError()); @@ -2024,13 +1994,38 @@ int Bank::readSystemValue(SystemValueId sysValId, Uint64 & value){ return NDBT_FAILED; } - value = valueRec->u_64_value(); - m_ndb.closeTransaction(pTrans); return NDBT_OK; } +int Bank::prepareReadSystemValueOp(NdbConnection* pTrans, SystemValueId sysValId, Uint64 & value){ + + int check; + + NdbOperation* pOp = pTrans->getNdbOperation("SYSTEM_VALUES"); + if (pOp == NULL) { + return NDBT_FAILED; + } + + check = pOp->readTuple(); + if( check == -1 ) { + return NDBT_FAILED; + } + + check = pOp->equal("SYSTEM_VALUES_ID", sysValId); + if( check == -1 ) { + return NDBT_FAILED; + } + + NdbRecAttr* valueRec = pOp->getValue("VALUE", (char *)&value); + if( valueRec == NULL ) { + return NDBT_FAILED; + } + + return NDBT_OK; +} + int Bank::writeSystemValue(SystemValueId sysValId, Uint64 value){ int check; @@ -2307,6 +2302,10 @@ int Bank::getCurrTime(Uint64 &time){ return readSystemValue(CurrentTime, time); } +int Bank::prepareGetCurrTimeOp(NdbConnection *pTrans, Uint64 &time){ + return prepareReadSystemValueOp(pTrans, CurrentTime, time); +} + int Bank::performSumAccounts(int maxSleepBetweenSums, int yield){ if (init() != NDBT_OK) diff --git a/ndb/test/ndbapi/bank/Bank.hpp b/ndb/test/ndbapi/bank/Bank.hpp index e6816fd7111..34c5ff51cc2 100644 --- a/ndb/test/ndbapi/bank/Bank.hpp +++ b/ndb/test/ndbapi/bank/Bank.hpp @@ -29,7 +29,7 @@ public: Bank(); - int createAndLoadBank(bool overWrite); + int createAndLoadBank(bool overWrite, int num_accounts=10); int dropBank(); int performTransactions(int maxSleepBetweenTrans = 20, int yield=0); @@ -118,6 +118,9 @@ private: int incCurrTime(Uint64 &value); int getCurrTime(Uint64 &time); + int prepareReadSystemValueOp(NdbConnection*, SystemValueId sysValId, Uint64 &time); + int prepareGetCurrTimeOp(NdbConnection*, Uint64 &time); + int createTables(); int createTable(const char* tabName); diff --git a/ndb/test/ndbapi/bank/BankLoad.cpp b/ndb/test/ndbapi/bank/BankLoad.cpp index bbaac27735b..39dc8097115 100644 --- a/ndb/test/ndbapi/bank/BankLoad.cpp +++ b/ndb/test/ndbapi/bank/BankLoad.cpp @@ -53,7 +53,7 @@ int Bank::getNumAccountTypes(){ return accountTypesSize; } -int Bank::createAndLoadBank(bool ovrWrt){ +int Bank::createAndLoadBank(bool ovrWrt, int num_accounts){ m_ndb.init(); if (m_ndb.waitUntilReady() != 0) @@ -78,7 +78,7 @@ int Bank::createAndLoadBank(bool ovrWrt){ if (loadAccountType() != NDBT_OK) return NDBT_FAILED; - if (loadAccount(10) != NDBT_OK) + if (loadAccount(num_accounts) != NDBT_OK) return NDBT_FAILED; if (loadSystemValues() != NDBT_OK) diff --git a/ndb/test/ndbapi/bank/bankCreator.cpp b/ndb/test/ndbapi/bank/bankCreator.cpp index 5331ec6ba69..301d8bda6d2 100644 --- a/ndb/test/ndbapi/bank/bankCreator.cpp +++ b/ndb/test/ndbapi/bank/bankCreator.cpp @@ -27,6 +27,7 @@ int main(int argc, const char** argv){ + ndb_init(); int _help = 0; struct getargs args[] = { diff --git a/ndb/test/ndbapi/bank/bankMakeGL.cpp b/ndb/test/ndbapi/bank/bankMakeGL.cpp index 54bc559fbf9..9e2762ed8ae 100644 --- a/ndb/test/ndbapi/bank/bankMakeGL.cpp +++ b/ndb/test/ndbapi/bank/bankMakeGL.cpp @@ -27,6 +27,7 @@ int main(int argc, const char** argv){ + ndb_init(); int _help = 0; struct getargs args[] = { diff --git a/ndb/test/ndbapi/bank/bankSumAccounts.cpp b/ndb/test/ndbapi/bank/bankSumAccounts.cpp index c0a903f9034..b576161b27b 100644 --- a/ndb/test/ndbapi/bank/bankSumAccounts.cpp +++ b/ndb/test/ndbapi/bank/bankSumAccounts.cpp @@ -27,6 +27,7 @@ int main(int argc, const char** argv){ + ndb_init(); int _help = 0; struct getargs args[] = { diff --git a/ndb/test/ndbapi/bank/bankTimer.cpp b/ndb/test/ndbapi/bank/bankTimer.cpp index ba3165fccb4..874afd9c21e 100644 --- a/ndb/test/ndbapi/bank/bankTimer.cpp +++ b/ndb/test/ndbapi/bank/bankTimer.cpp @@ -28,6 +28,7 @@ int main(int argc, const char** argv){ + ndb_init(); int _help = 0; int _wait = 30; diff --git a/ndb/test/ndbapi/bank/bankTransactionMaker.cpp b/ndb/test/ndbapi/bank/bankTransactionMaker.cpp index fe9b53e0c8d..e5ff9aeb918 100644 --- a/ndb/test/ndbapi/bank/bankTransactionMaker.cpp +++ b/ndb/test/ndbapi/bank/bankTransactionMaker.cpp @@ -28,6 +28,7 @@ int main(int argc, const char** argv){ + ndb_init(); int _help = 0; int _wait = 20; diff --git a/ndb/test/ndbapi/bank/bankValidateAllGLs.cpp b/ndb/test/ndbapi/bank/bankValidateAllGLs.cpp index f9d974bb5f7..cf298ecc8e3 100644 --- a/ndb/test/ndbapi/bank/bankValidateAllGLs.cpp +++ b/ndb/test/ndbapi/bank/bankValidateAllGLs.cpp @@ -28,6 +28,7 @@ int main(int argc, const char** argv){ + ndb_init(); int _help = 0; struct getargs args[] = { diff --git a/ndb/test/ndbapi/bank/testBank.cpp b/ndb/test/ndbapi/bank/testBank.cpp index 77ac1172d7c..3ef2799cd3c 100644 --- a/ndb/test/ndbapi/bank/testBank.cpp +++ b/ndb/test/ndbapi/bank/testBank.cpp @@ -141,6 +141,7 @@ TESTCASE("Bank", NDBT_TESTSUITE_END(testBank); int main(int argc, const char** argv){ + ndb_init(); // Tables should not be auto created testBank.setCreateTable(false); diff --git a/ndb/test/ndbapi/benchronja.cpp b/ndb/test/ndbapi/benchronja.cpp index ce0aee35e8f..91b2a041186 100644 --- a/ndb/test/ndbapi/benchronja.cpp +++ b/ndb/test/ndbapi/benchronja.cpp @@ -66,6 +66,7 @@ static int ThreadReady[MAXTHREADS]; static int ThreadStart[MAXTHREADS]; NDB_COMMAND(benchronja, "benchronja", "benchronja", "benchronja", 65535){ + ndb_init(); ThreadNdb tabThread[MAXTHREADS]; int i = 0 ; diff --git a/ndb/test/ndbapi/bulk_copy.cpp b/ndb/test/ndbapi/bulk_copy.cpp index 18881cae216..8821a92fb27 100644 --- a/ndb/test/ndbapi/bulk_copy.cpp +++ b/ndb/test/ndbapi/bulk_copy.cpp @@ -221,6 +221,7 @@ int insertFile(Ndb* pNdb, int main(int argc, const char** argv){ + ndb_init(); const char* _tabname = NULL; int _help = 0; diff --git a/ndb/test/ndbapi/cdrserver.cpp b/ndb/test/ndbapi/cdrserver.cpp index 8354d28f53f..8d15061e94b 100644 --- a/ndb/test/ndbapi/cdrserver.cpp +++ b/ndb/test/ndbapi/cdrserver.cpp @@ -113,6 +113,7 @@ using namespace std; int main(int argc, const char** argv) { + ndb_init(); /******** NDB ***********/ /* Ndb MyNdb( "TEST_DB" ); diff --git a/ndb/test/ndbapi/celloDb.cpp b/ndb/test/ndbapi/celloDb.cpp index ec61e783585..2d6401c355a 100644 --- a/ndb/test/ndbapi/celloDb.cpp +++ b/ndb/test/ndbapi/celloDb.cpp @@ -73,6 +73,7 @@ static int failed = 0 ; NDB_COMMAND(celloDb, "celloDb", "celloDb", "celloDb", 65535) { + ndb_init(); int tTableId; int i; diff --git a/ndb/test/ndbapi/create_all_tabs.cpp b/ndb/test/ndbapi/create_all_tabs.cpp index 55d04888144..97236b98b36 100644 --- a/ndb/test/ndbapi/create_all_tabs.cpp +++ b/ndb/test/ndbapi/create_all_tabs.cpp @@ -25,6 +25,7 @@ int main(int argc, const char** argv){ + ndb_init(); int _temp = false; int _help = 0; diff --git a/ndb/test/ndbapi/create_tab.cpp b/ndb/test/ndbapi/create_tab.cpp index c2e3b7f64ea..f3f18982ed0 100644 --- a/ndb/test/ndbapi/create_tab.cpp +++ b/ndb/test/ndbapi/create_tab.cpp @@ -25,6 +25,7 @@ int main(int argc, const char** argv){ + ndb_init(); int _temp = false; int _help = 0; diff --git a/ndb/test/ndbapi/drop_all_tabs.cpp b/ndb/test/ndbapi/drop_all_tabs.cpp index 59c57396acd..c024a81a5e6 100644 --- a/ndb/test/ndbapi/drop_all_tabs.cpp +++ b/ndb/test/ndbapi/drop_all_tabs.cpp @@ -23,6 +23,7 @@ #include int main(int argc, const char** argv){ + ndb_init(); int _help = 0; struct getargs args[] = { diff --git a/ndb/test/ndbapi/flexAsynch.cpp b/ndb/test/ndbapi/flexAsynch.cpp index 9192ec21b93..8c0ba46130c 100644 --- a/ndb/test/ndbapi/flexAsynch.cpp +++ b/ndb/test/ndbapi/flexAsynch.cpp @@ -145,6 +145,7 @@ tellThreads(StartType what) NDB_COMMAND(flexAsynch, "flexAsynch", "flexAsynch", "flexAsynch", 65535) { + ndb_init(); ThreadNdb* pThreadData; int tLoops=0, i; int returnValue = NDBT_OK; diff --git a/ndb/test/ndbapi/flexBench.cpp b/ndb/test/ndbapi/flexBench.cpp index 38c8f6e280f..b19944498f4 100644 --- a/ndb/test/ndbapi/flexBench.cpp +++ b/ndb/test/ndbapi/flexBench.cpp @@ -281,6 +281,7 @@ tellThreads(ThreadData* pt, StartType what) NDB_COMMAND(flexBench, "flexBench", "flexBench", "flexbench", 65535) { + ndb_init(); ThreadData* pThreadsData; int tLoops = 0, i; int returnValue = NDBT_OK; diff --git a/ndb/test/ndbapi/flexHammer.cpp b/ndb/test/ndbapi/flexHammer.cpp index c1c47923de9..80cc7c5a53f 100644 --- a/ndb/test/ndbapi/flexHammer.cpp +++ b/ndb/test/ndbapi/flexHammer.cpp @@ -178,6 +178,7 @@ tellThreads(ThreadNdb* threadArrayP, const StartType what) NDB_COMMAND(flexHammer, "flexHammer", "flexHammer", "flexHammer", 65535) //main(int argc, const char** argv) { + ndb_init(); ThreadNdb* pThreads = NULL; // Pointer to thread data array Ndb* pMyNdb = NULL; // Pointer to Ndb object int tLoops = 0; diff --git a/ndb/test/ndbapi/flexScan.cpp b/ndb/test/ndbapi/flexScan.cpp index 5b5b4dde730..b09d71fb010 100644 --- a/ndb/test/ndbapi/flexScan.cpp +++ b/ndb/test/ndbapi/flexScan.cpp @@ -297,6 +297,7 @@ static int checkThreadResults(ThreadNdb *threadArrayP, char *action) NDB_COMMAND(flexScan, "flexScan", "flexScan", "flexScan", 65535) { + ndb_init(); ThreadNdb* pThreads = NULL; Ndb* pMyNdb = NULL; int tLoops = 0; diff --git a/ndb/test/ndbapi/flexTT.cpp b/ndb/test/ndbapi/flexTT.cpp index c0ff31d1677..162fc080218 100644 --- a/ndb/test/ndbapi/flexTT.cpp +++ b/ndb/test/ndbapi/flexTT.cpp @@ -171,6 +171,7 @@ tellThreads(StartType what) NDB_COMMAND(flexTT, "flexTT", "flexTT", "flexTT", 65535) { + ndb_init(); ThreadNdb* pThreadData; int returnValue = NDBT_OK; int i; diff --git a/ndb/test/ndbapi/flexTimedAsynch.cpp b/ndb/test/ndbapi/flexTimedAsynch.cpp index 761be53fdd3..27380cc79fd 100644 --- a/ndb/test/ndbapi/flexTimedAsynch.cpp +++ b/ndb/test/ndbapi/flexTimedAsynch.cpp @@ -174,6 +174,7 @@ void deleteAttributeSpace(){ NDB_COMMAND(flexTimedAsynch, "flexTimedAsynch", "flexTimedAsynch [-tpoilcas]", "flexTimedAsynch", 65535) { + ndb_init(); ThreadNdb tabThread[MAXTHREADS]; int tLoops=0; int returnValue; diff --git a/ndb/test/ndbapi/flex_bench_mysql.cpp b/ndb/test/ndbapi/flex_bench_mysql.cpp index 7cc883ab3e6..8e1fbcd9058 100644 --- a/ndb/test/ndbapi/flex_bench_mysql.cpp +++ b/ndb/test/ndbapi/flex_bench_mysql.cpp @@ -308,6 +308,7 @@ tellThreads(ThreadData* pt, StartType what) NDB_COMMAND(flexBench, "flexBench", "flexBench", "flexbench", 65535) { + ndb_init(); ThreadData* pThreadsData; int tLoops = 0; int returnValue = NDBT_OK; diff --git a/ndb/test/ndbapi/index.cpp b/ndb/test/ndbapi/index.cpp index 508186de529..c22da594164 100644 --- a/ndb/test/ndbapi/index.cpp +++ b/ndb/test/ndbapi/index.cpp @@ -81,63 +81,63 @@ static void createTable(Ndb &myNdb, bool storeInACC, bool twoKey, bool longKey) int res; column.setName("NAME"); - column.setPrimaryKey(true); column.setType(NdbDictionary::Column::Char); column.setLength((longKey)? 1024 // 1KB => long key :12); + column.setPrimaryKey(true); column.setNullable(false); table.addColumn(column); if (twoKey) { column.setName("KEY2"); - column.setPrimaryKey(true); column.setType(NdbDictionary::Column::Unsigned); column.setLength(1); + column.setPrimaryKey(true); column.setNullable(false); table.addColumn(column); } column.setName("PNUM1"); - column.setPrimaryKey(false); column.setType(NdbDictionary::Column::Unsigned); column.setLength(1); + column.setPrimaryKey(false); column.setNullable(false); table.addColumn(column); column.setName("PNUM2"); - column.setPrimaryKey(false); column.setType(NdbDictionary::Column::Unsigned); column.setLength(1); + column.setPrimaryKey(false); column.setNullable(false); table.addColumn(column); column.setName("PNUM3"); - column.setPrimaryKey(false); column.setType(NdbDictionary::Column::Unsigned); column.setLength(1); + column.setPrimaryKey(false); column.setNullable(false); table.addColumn(column); column.setName("PNUM4"); - column.setPrimaryKey(false); column.setType(NdbDictionary::Column::Unsigned); column.setLength(1); + column.setPrimaryKey(false); column.setNullable(false); table.addColumn(column); column.setName("AGE"); - column.setPrimaryKey(false); column.setType(NdbDictionary::Column::Unsigned); column.setLength(1); + column.setPrimaryKey(false); column.setNullable(false); table.addColumn(column); column.setName("STRING_AGE"); - column.setPrimaryKey(false); column.setType(NdbDictionary::Column::Char); column.setLength(1); column.setLength(256); + column.setPrimaryKey(false); column.setNullable(false); table.addColumn(column); @@ -771,6 +771,7 @@ static void dropIndex(Ndb &myNdb, unsigned int noOfIndexes) NDB_COMMAND(indexTest, "indexTest", "indexTest", "indexTest", 65535) { + ndb_init(); bool createTableOp, createIndexOp, dropIndexOp, insertOp, updateOp, deleteOp, readOp, readIndexOp, updateIndexOp, deleteIndexOp, twoKey, longKey; unsigned int noOfTuples = 1; unsigned int noOfOperations = 1; diff --git a/ndb/test/ndbapi/index2.cpp b/ndb/test/ndbapi/index2.cpp index e49113d2f1b..f739468d7df 100644 --- a/ndb/test/ndbapi/index2.cpp +++ b/ndb/test/ndbapi/index2.cpp @@ -81,16 +81,16 @@ static void createTable(Ndb &myNdb, bool storeInACC, bool twoKey, bool longKey) int res; column.setName("X"); - column.setPrimaryKey(true); column.setType(NdbDictionary::Column::Unsigned); column.setLength(1); + column.setPrimaryKey(true); column.setNullable(false); table.addColumn(column); column.setName("Y"); - column.setPrimaryKey(false); column.setType(NdbDictionary::Column::Unsigned); column.setLength(1); + column.setPrimaryKey(false); column.setNullable(false); table.addColumn(column); @@ -608,6 +608,7 @@ static void dropIndex(Ndb &myNdb, unsigned int noOfIndexes) NDB_COMMAND(indexTest, "indexTest", "indexTest", "indexTest", 65535) { + ndb_init(); bool createTableOp, createIndexOp, dropIndexOp, insertOp, updateOp, deleteOp, readOp, readIndexOp, updateIndexOp, deleteIndexOp, twoKey, longKey; unsigned int noOfTuples = 1; unsigned int noOfOperations = 1; diff --git a/ndb/test/ndbapi/initronja.cpp b/ndb/test/ndbapi/initronja.cpp index b3215104822..3ce274e4319 100644 --- a/ndb/test/ndbapi/initronja.cpp +++ b/ndb/test/ndbapi/initronja.cpp @@ -46,6 +46,7 @@ static char attrName[MAXATTR][MAXSTRLEN]; inline int InsertRecords(Ndb*, int) ; NDB_COMMAND(initronja, "initronja", "initronja", "initronja", 65535){ + ndb_init(); Ndb* pNdb = NULL ; NdbSchemaCon *MySchemaTransaction = NULL ; diff --git a/ndb/test/ndbapi/interpreterInTup.cpp b/ndb/test/ndbapi/interpreterInTup.cpp index 47960cd5d12..20d84e6e96d 100644 --- a/ndb/test/ndbapi/interpreterInTup.cpp +++ b/ndb/test/ndbapi/interpreterInTup.cpp @@ -105,6 +105,7 @@ int bTestPassed = 0; int main(int argc, const char** argv) { + ndb_init(); int operationType = 0; int tupTest = 0; diff --git a/ndb/test/ndbapi/mainAsyncGenerator.cpp b/ndb/test/ndbapi/mainAsyncGenerator.cpp index f613c66d07b..16cb50e160f 100644 --- a/ndb/test/ndbapi/mainAsyncGenerator.cpp +++ b/ndb/test/ndbapi/mainAsyncGenerator.cpp @@ -282,6 +282,7 @@ threadRoutine(void *arg) NDB_COMMAND(DbAsyncGenerator, "DbAsyncGenerator", "DbAsyncGenerator", "DbAsyncGenerator", 65535) { + ndb_init(); int i; int j; int k; diff --git a/ndb/test/ndbapi/msa.cpp b/ndb/test/ndbapi/msa.cpp index 7a734f9cb79..e39f7a8c64a 100644 --- a/ndb/test/ndbapi/msa.cpp +++ b/ndb/test/ndbapi/msa.cpp @@ -971,6 +971,7 @@ void ShowHelp(const char* szCmd) int main(int argc, char* argv[]) { + ndb_init(); int iRes = -1; g_nNumThreads = 0; g_nMaxCallsPerSecond = 0; diff --git a/ndb/test/ndbapi/restarter.cpp b/ndb/test/ndbapi/restarter.cpp index 9a522f5dcac..d6831494b48 100644 --- a/ndb/test/ndbapi/restarter.cpp +++ b/ndb/test/ndbapi/restarter.cpp @@ -28,6 +28,7 @@ #include int main(int argc, const char** argv){ + ndb_init(); const char* _hostName = NULL; int _loops = 10; diff --git a/ndb/test/ndbapi/restarter2.cpp b/ndb/test/ndbapi/restarter2.cpp index f2bcf6f8e7b..846748a7bba 100644 --- a/ndb/test/ndbapi/restarter2.cpp +++ b/ndb/test/ndbapi/restarter2.cpp @@ -26,6 +26,7 @@ #include int main(int argc, const char** argv){ + ndb_init(); const char* _hostName = NULL; int _loops = 10; diff --git a/ndb/test/ndbapi/restarts.cpp b/ndb/test/ndbapi/restarts.cpp index 0ec2883d53c..184e754de4a 100644 --- a/ndb/test/ndbapi/restarts.cpp +++ b/ndb/test/ndbapi/restarts.cpp @@ -27,6 +27,7 @@ #include int main(int argc, const char** argv){ + ndb_init(); const char* _restartName = NULL; int _loops = 1; diff --git a/ndb/test/ndbapi/size.cpp b/ndb/test/ndbapi/size.cpp index c506771ebde..ff178b11d68 100644 --- a/ndb/test/ndbapi/size.cpp +++ b/ndb/test/ndbapi/size.cpp @@ -19,6 +19,7 @@ int main(void) { + ndb_init(); printf("cdrstruct=%d\n",sizeof(struct cdr_record)); printf("long int=%d\n",sizeof(long int)); printf("int=%d\n",sizeof(int)); diff --git a/ndb/test/ndbapi/slow_select.cpp b/ndb/test/ndbapi/slow_select.cpp index a953e1539d0..625dbc34457 100644 --- a/ndb/test/ndbapi/slow_select.cpp +++ b/ndb/test/ndbapi/slow_select.cpp @@ -36,6 +36,7 @@ static void lookup(); int main(void){ + ndb_init(); Ndb g_ndb("test"); g_ndb.init(1024); diff --git a/ndb/test/ndbapi/testBackup.cpp b/ndb/test/ndbapi/testBackup.cpp index d328a7db292..77b9d0a4baa 100644 --- a/ndb/test/ndbapi/testBackup.cpp +++ b/ndb/test/ndbapi/testBackup.cpp @@ -149,6 +149,9 @@ int runRestartInitial(NDBT_Context* ctx, NDBT_Step* step){ if (restarter.restartAll(true) != 0) return NDBT_FAILED; + if (restarter.waitClusterStarted() != 0) + return NDBT_FAILED; + return NDBT_OK; } @@ -215,7 +218,7 @@ int runDropTable(NDBT_Context* ctx, NDBT_Step* step){ int runCreateBank(NDBT_Context* ctx, NDBT_Step* step){ Bank bank; int overWriteExisting = true; - if (bank.createAndLoadBank(overWriteExisting) != NDBT_OK) + if (bank.createAndLoadBank(overWriteExisting, 10) != NDBT_OK) return NDBT_FAILED; return NDBT_OK; } @@ -413,7 +416,6 @@ TESTCASE("BackupOne", INITIALIZER(runRestoreOne); VERIFIER(runVerifyOne); FINALIZER(runClearTable); - FINALIZER(runDropTable); } TESTCASE("BackupBank", "Test that backup and restore works during transaction load\n" @@ -428,6 +430,15 @@ TESTCASE("BackupBank", INITIALIZER(runCreateBank); STEP(runBankTimer); STEP(runBankTransactions); + STEP(runBankTransactions); + STEP(runBankTransactions); + STEP(runBankTransactions); + STEP(runBankTransactions); + STEP(runBankTransactions); + STEP(runBankTransactions); + STEP(runBankTransactions); + STEP(runBankTransactions); + STEP(runBankTransactions); STEP(runBankGL); // TODO STEP(runBankSum); STEP(runBackupBank); @@ -473,6 +484,7 @@ TESTCASE("FailSlave", NDBT_TESTSUITE_END(testBackup); int main(int argc, const char** argv){ + ndb_init(); return testBackup.execute(argc, argv); } diff --git a/ndb/test/ndbapi/testBasic.cpp b/ndb/test/ndbapi/testBasic.cpp index 26622f9b066..7d03016b87a 100644 --- a/ndb/test/ndbapi/testBasic.cpp +++ b/ndb/test/ndbapi/testBasic.cpp @@ -1278,6 +1278,7 @@ TESTCASE("MassiveTransaction", NDBT_TESTSUITE_END(testBasic); int main(int argc, const char** argv){ + ndb_init(); return testBasic.execute(argc, argv); } diff --git a/ndb/test/ndbapi/testBasicAsynch.cpp b/ndb/test/ndbapi/testBasicAsynch.cpp index a97920e53da..6daa22fdc6a 100644 --- a/ndb/test/ndbapi/testBasicAsynch.cpp +++ b/ndb/test/ndbapi/testBasicAsynch.cpp @@ -181,6 +181,7 @@ TESTCASE("PkDeleteAsynch", NDBT_TESTSUITE_END(testBasicAsynch); int main(int argc, const char** argv){ + ndb_init(); return testBasicAsynch.execute(argc, argv); } diff --git a/ndb/test/ndbapi/testBlobs.cpp b/ndb/test/ndbapi/testBlobs.cpp index 64881ca39ab..e18f4a8bd1a 100644 --- a/ndb/test/ndbapi/testBlobs.cpp +++ b/ndb/test/ndbapi/testBlobs.cpp @@ -1338,6 +1338,7 @@ static struct { NDB_COMMAND(testOdbcDriver, "testBlobs", "testBlobs", "testBlobs", 65535) { + ndb_init(); while (++argv, --argc > 0) { const char* arg = argv[0]; if (strcmp(arg, "-batch") == 0) { diff --git a/ndb/test/ndbapi/testDataBuffers.cpp b/ndb/test/ndbapi/testDataBuffers.cpp index 2e29dbb0d7b..94658d5c6b9 100644 --- a/ndb/test/ndbapi/testDataBuffers.cpp +++ b/ndb/test/ndbapi/testDataBuffers.cpp @@ -545,6 +545,7 @@ testcase(int flag) NDB_COMMAND(testDataBuffers, "testDataBuffers", "testDataBuffers", "testDataBuffers", 65535) { + ndb_init(); while (++argv, --argc > 0) { char const* p = argv[0]; if (*p++ != '-' || strlen(p) != 1) diff --git a/ndb/test/ndbapi/testDeadlock.cpp b/ndb/test/ndbapi/testDeadlock.cpp index f51b3cea1e5..a445823b8a8 100644 --- a/ndb/test/ndbapi/testDeadlock.cpp +++ b/ndb/test/ndbapi/testDeadlock.cpp @@ -491,6 +491,7 @@ wl1822_main(char scantx) NDB_COMMAND(testOdbcDriver, "testDeadlock", "testDeadlock", "testDeadlock", 65535) { + ndb_init(); while (++argv, --argc > 0) { const char* arg = argv[0]; if (strcmp(arg, "-scan") == 0) { diff --git a/ndb/test/ndbapi/testDict.cpp b/ndb/test/ndbapi/testDict.cpp index a0c7bb1414b..7cba5ce4cc8 100644 --- a/ndb/test/ndbapi/testDict.cpp +++ b/ndb/test/ndbapi/testDict.cpp @@ -1128,9 +1128,9 @@ runCreateAutoincrementTable(NDBT_Context* ctx, NDBT_Step* step){ myTable.setName(tabname); myColumn.setName("ATTR1"); - myColumn.setPrimaryKey(true); myColumn.setType(NdbDictionary::Column::Unsigned); myColumn.setLength(1); + myColumn.setPrimaryKey(true); myColumn.setNullable(false); myColumn.setAutoIncrement(true); if (startvalue != ~0) // check that default value starts with 1 @@ -1576,6 +1576,7 @@ TESTCASE("DictionaryPerf", NDBT_TESTSUITE_END(testDict); int main(int argc, const char** argv){ + ndb_init(); // Tables should not be auto created testDict.setCreateTable(false); myRandom48Init(NdbTick_CurrentMillisecond()); diff --git a/ndb/test/ndbapi/testGrep.cpp b/ndb/test/ndbapi/testGrep.cpp index 0bf84cb4ec8..713aefbeafa 100644 --- a/ndb/test/ndbapi/testGrep.cpp +++ b/ndb/test/ndbapi/testGrep.cpp @@ -533,6 +533,7 @@ TESTCASE("FailSlave", NDBT_TESTSUITE_END(testGrep); int main(int argc, const char** argv){ + ndb_init(); return testGrep.execute(argc, argv); } diff --git a/ndb/test/ndbapi/testGrepVerify.cpp b/ndb/test/ndbapi/testGrepVerify.cpp index 05445c1ba1b..52dcda9a162 100644 --- a/ndb/test/ndbapi/testGrepVerify.cpp +++ b/ndb/test/ndbapi/testGrepVerify.cpp @@ -40,6 +40,7 @@ continue; } int main(int argc, const char** argv){ + ndb_init(); const char * connectString = NULL; diff --git a/ndb/test/ndbapi/testIndex.cpp b/ndb/test/ndbapi/testIndex.cpp index 6ebbfd8b680..bef3b310c96 100644 --- a/ndb/test/ndbapi/testIndex.cpp +++ b/ndb/test/ndbapi/testIndex.cpp @@ -1528,6 +1528,7 @@ TESTCASE("UniqueNull", NDBT_TESTSUITE_END(testIndex); int main(int argc, const char** argv){ + ndb_init(); return testIndex.execute(argc, argv); } diff --git a/ndb/test/ndbapi/testInterpreter.cpp b/ndb/test/ndbapi/testInterpreter.cpp index 9c584d6f581..0baba33d2b2 100644 --- a/ndb/test/ndbapi/testInterpreter.cpp +++ b/ndb/test/ndbapi/testInterpreter.cpp @@ -224,6 +224,7 @@ TESTCASE("NdbErrorOperation", NDBT_TESTSUITE_END(testInterpreter); int main(int argc, const char** argv){ + ndb_init(); // TABLE("T1"); return testInterpreter.execute(argc, argv); } diff --git a/ndb/test/ndbapi/testMgm.cpp b/ndb/test/ndbapi/testMgm.cpp index d5b9372cc9b..ef653d3f972 100644 --- a/ndb/test/ndbapi/testMgm.cpp +++ b/ndb/test/ndbapi/testMgm.cpp @@ -178,6 +178,7 @@ TESTCASE("SingleUserMode", NDBT_TESTSUITE_END(testMgm); int main(int argc, const char** argv){ + ndb_init(); myRandom48Init(NdbTick_CurrentMillisecond()); return testMgm.execute(argc, argv); } diff --git a/ndb/test/ndbapi/testNdbApi.cpp b/ndb/test/ndbapi/testNdbApi.cpp index 5b171d42578..47987629fe3 100644 --- a/ndb/test/ndbapi/testNdbApi.cpp +++ b/ndb/test/ndbapi/testNdbApi.cpp @@ -1006,6 +1006,7 @@ TESTCASE("NdbErrorOperation", NDBT_TESTSUITE_END(testNdbApi); int main(int argc, const char** argv){ + ndb_init(); // TABLE("T1"); return testNdbApi.execute(argc, argv); } diff --git a/ndb/test/ndbapi/testNodeRestart.cpp b/ndb/test/ndbapi/testNodeRestart.cpp index 89b38c78e71..6bfe59f8d3f 100644 --- a/ndb/test/ndbapi/testNodeRestart.cpp +++ b/ndb/test/ndbapi/testNodeRestart.cpp @@ -434,6 +434,7 @@ TESTCASE("StopOnError", NDBT_TESTSUITE_END(testNodeRestart); int main(int argc, const char** argv){ + ndb_init(); #if 0 // It might be interesting to have longer defaults for num // loops in this test diff --git a/ndb/test/ndbapi/testOIBasic.cpp b/ndb/test/ndbapi/testOIBasic.cpp index 29d03f0c33e..f9eb3514926 100644 --- a/ndb/test/ndbapi/testOIBasic.cpp +++ b/ndb/test/ndbapi/testOIBasic.cpp @@ -28,6 +28,7 @@ #include #include #include +#include // options @@ -37,6 +38,8 @@ struct Opt { const char* m_bound; const char* m_case; bool m_core; + const char* m_csname; + CHARSET_INFO* m_cs; bool m_dups; NdbDictionary::Object::FragmentType m_fragtype; unsigned m_idxloop; @@ -59,6 +62,8 @@ struct Opt { m_bound("01234"), m_case(0), m_core(false), + m_csname("latin1_bin"), + m_cs(0), m_dups(false), m_fragtype(NdbDictionary::Object::FragUndefined), m_idxloop(4), @@ -94,6 +99,7 @@ printhelp() << " -bound xyz use only these bound types 0-4 [" << d.m_bound << "]" << endl << " -case abc only given test cases (letters a-z)" << endl << " -core core dump on error [" << d.m_core << "]" << endl + << " -csname S charset (collation) of non-pk char column [" << d.m_csname << "]" << endl << " -dups allow duplicate tuples from index scan [" << d.m_dups << "]" << endl << " -fragtype T fragment type single/small/medium/large" << endl << " -index xyz only given index numbers (digits 1-9)" << endl @@ -979,10 +985,14 @@ createtable(Par par) for (unsigned k = 0; k < tab.m_cols; k++) { const Col& col = tab.m_col[k]; NdbDictionary::Column c(col.m_name); - c.setPrimaryKey(col.m_pk); c.setType(col.m_type); c.setLength(col.m_length); + c.setPrimaryKey(col.m_pk); c.setNullable(col.m_nullable); + if (c.getCharset()) { // test if char type + if (! col.m_pk) + c.setCharset(par.m_cs); + } t.addColumn(c); } con.m_dic = con.m_ndb->getDictionary(); @@ -2236,9 +2246,8 @@ pkreadfast(Par par, unsigned count) keyrow.calc(par, i); CHK(keyrow.selrow(par) == 0); NdbRecAttr* rec; - CHK(con.getValue((Uint32)0, rec) == 0); - CHK(con.executeScan() == 0); // get 1st column + CHK(con.getValue((Uint32)0, rec) == 0); CHK(con.execute(Commit) == 0); con.closeTransaction(); } @@ -3150,6 +3159,10 @@ runtest(Par par) LL1("start"); if (par.m_seed != 0) srandom(par.m_seed); + assert(par.m_csname != 0); + CHARSET_INFO* cs; + CHK((cs = get_charset_by_name(par.m_csname, MYF(0))) != 0 || (cs = get_charset_by_csname(par.m_csname, MY_CS_PRIMARY, MYF(0))) != 0); + par.m_cs = cs; Con con; CHK(con.connect() == 0); par.m_con = &con; @@ -3201,6 +3214,7 @@ runtest(Par par) NDB_COMMAND(testOIBasic, "testOIBasic", "testOIBasic", "testOIBasic", 65535) { + ndb_init(); while (++argv, --argc > 0) { const char* arg = argv[0]; if (*arg != '-') { @@ -3232,6 +3246,12 @@ NDB_COMMAND(testOIBasic, "testOIBasic", "testOIBasic", "testOIBasic", 65535) g_opt.m_core = true; continue; } + if (strcmp(arg, "-csname") == 0) { + if (++argv, --argc > 0) { + g_opt.m_csname = strdup(argv[0]); + continue; + } + } if (strcmp(arg, "-dups") == 0) { g_opt.m_dups = true; continue; diff --git a/ndb/test/ndbapi/testOperations.cpp b/ndb/test/ndbapi/testOperations.cpp index bb58e69e898..ba41e1d1c40 100644 --- a/ndb/test/ndbapi/testOperations.cpp +++ b/ndb/test/ndbapi/testOperations.cpp @@ -230,6 +230,7 @@ runClearTable(NDBT_Context* ctx, NDBT_Step* step){ int main(int argc, const char** argv){ + ndb_init(); NDBT_TestSuite ts("testOperations"); for(Uint32 i = 0; igetNumLoops(); + int records = ctx->getNumRecords(); + NdbRestarter restarter; + Uint32 i = 1; + + Uint32 currentRestartNodeIndex = 1; + UtilTransactions utilTrans(*ctx->getTab()); + HugoTransactions hugoTrans(*ctx->getTab()); + + int args[] = { DumpStateOrd::DihMaxTimeBetweenLCP }; + int dump[] = { DumpStateOrd::DihStartLcpImmediately }; + + do { + CHECK(restarter.dumpStateAllNodes(args, 1) == 0); + + HugoOperations ops(* ctx->getTab()); + CHECK(ops.startTransaction(pNdb) == 0); + for(i = 0; i<10; i++){ + CHECK(ops.pkInsertRecord(pNdb, i, 1, 1) == 0); + CHECK(ops.execute_NoCommit(pNdb) == 0); + } + for(i = 0; i<10; i++){ + CHECK(ops.pkUpdateRecord(pNdb, i, 1) == 0); + CHECK(ops.execute_NoCommit(pNdb) == 0); + } + NdbSleep_SecSleep(10); + CHECK(restarter.dumpStateAllNodes(dump, 1) == 0); + NdbSleep_SecSleep(10); + CHECK(ops.execute_Commit(pNdb) == 0); + + CHECK(restarter.restartAll() == 0); + CHECK(restarter.waitClusterStarted(timeout) == 0); + CHECK(pNdb->waitUntilReady(timeout) == 0); + ops.closeTransaction(pNdb); + } while(0); + + g_info << "runSystemRestart9 finished" << endl; return result; } @@ -1176,9 +1221,23 @@ TESTCASE("SR8", STEP(runSystemRestart8); FINALIZER(runClearTable); } +TESTCASE("SR9", + "Perform partition win system restart with other nodes delayed\n" + "* 1. Start transaction\n" + "* 2. insert (1,1)\n" + "* 3. update (1,2)\n" + "* 4. start lcp\n" + "* 5. commit\n" + "* 6. restart\n"){ + INITIALIZER(runWaitStarted); + INITIALIZER(runClearTable); + STEP(runSystemRestart9); + FINALIZER(runClearTable); +} NDBT_TESTSUITE_END(testSystemRestart); int main(int argc, const char** argv){ + ndb_init(); return testSystemRestart.execute(argc, argv); } diff --git a/ndb/test/ndbapi/testTimeout.cpp b/ndb/test/ndbapi/testTimeout.cpp index 62e69125073..5cabb86541d 100644 --- a/ndb/test/ndbapi/testTimeout.cpp +++ b/ndb/test/ndbapi/testTimeout.cpp @@ -406,6 +406,7 @@ TESTCASE("BuddyTransNoTimeout5", NDBT_TESTSUITE_END(testTimeout); int main(int argc, const char** argv){ + ndb_init(); myRandom48Init(NdbTick_CurrentMillisecond()); return testTimeout.execute(argc, argv); } diff --git a/ndb/test/ndbapi/testTransactions.cpp b/ndb/test/ndbapi/testTransactions.cpp index 67a2df24390..2dca9e24fb4 100644 --- a/ndb/test/ndbapi/testTransactions.cpp +++ b/ndb/test/ndbapi/testTransactions.cpp @@ -364,6 +364,7 @@ runClearTable(NDBT_Context* ctx, NDBT_Step* step){ int main(int argc, const char** argv){ + ndb_init(); NDBT_TestSuite ts("testOperations"); for(Uint32 i = 0; i 0) NdbSleep_MilliSleep(doSleep); - if (first_batch || !oneTrans) { + // if (first_batch || !oneTrans) { + if (first_batch || !pTrans) { first_batch = false; pTrans = pNdb->startTransaction(); - if (pTrans == NULL) { const NdbError err = pNdb->getNdbError(); @@ -774,8 +774,10 @@ HugoTransactions::loadTable(Ndb* pNdb, // Execute the transaction and insert the record if (!oneTrans || (c + batch) >= records) { - closeTrans = true; + // closeTrans = true; + closeTrans = false; check = pTrans->execute( Commit ); + pTrans->restart(); } else { closeTrans = false; check = pTrans->execute( NoCommit ); @@ -783,7 +785,7 @@ HugoTransactions::loadTable(Ndb* pNdb, if(check == -1 ) { const NdbError err = pTrans->getNdbError(); pNdb->closeTransaction(pTrans); - + pTrans= 0; switch(err.status){ case NdbError::Success: ERR(err); @@ -825,6 +827,7 @@ HugoTransactions::loadTable(Ndb* pNdb, else{ if (closeTrans) { pNdb->closeTransaction(pTrans); + pTrans= 0; } } diff --git a/ndb/test/src/NDBT_Test.cpp b/ndb/test/src/NDBT_Test.cpp index ba316bac01b..4ff94bcf296 100644 --- a/ndb/test/src/NDBT_Test.cpp +++ b/ndb/test/src/NDBT_Test.cpp @@ -15,7 +15,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include -#include #include "NDBT.hpp" #include "NDBT_Test.hpp" @@ -990,7 +989,6 @@ int NDBT_TestSuite::execute(int argc, const char** argv){ } #ifndef DBUG_OFF - my_init(); if (debug_option) DBUG_PUSH(debug_option); #endif diff --git a/ndb/test/src/NdbBackup.cpp b/ndb/test/src/NdbBackup.cpp index f33c5d8c313..ad26dbeab16 100644 --- a/ndb/test/src/NdbBackup.cpp +++ b/ndb/test/src/NdbBackup.cpp @@ -69,7 +69,11 @@ NdbBackup::getBackupDataDirForNode(int _node_id){ /** * Fetch configuration from management server */ - ConfigRetriever cr(0, NODE_TYPE_API); + LocalConfig lc; + if (!lc.init(0,0)) { + abort(); + } + ConfigRetriever cr(lc, 0, NODE_TYPE_API); ndb_mgm_configuration * p = 0; BaseString tmp; tmp.assfmt("%s:%d", host.c_str(), port); @@ -140,14 +144,16 @@ NdbBackup::execRestore(bool _restore_data, */ snprintf(buf, buf_len, - "scp %s:%s/BACKUP/BACKUP-%d/* .", + "scp %s:%s/BACKUP/BACKUP-%d/BACKUP-%d*.%d.* .", host, path, - _backup_id); + _backup_id, + _backup_id, + _node_id); ndbout << "buf: "<< buf < 1); - // restore metadata first - res = execRestore(false, true, ndbNodes[0].node_id, _backup_id); - + // restore metadata first and data for first node + res = execRestore(true, true, ndbNodes[0].node_id, _backup_id); - // Restore data once for each node - for(size_t i = 0; i < ndbNodes.size(); i++){ - res = execRestore(true, false, ndbNodes[i].node_id, _backup_id); - } + // Restore data once for each node + for(size_t i = 1; i < ndbNodes.size(); i++){ + res = execRestore(true, false, ndbNodes[i].node_id, _backup_id); } return 0; diff --git a/ndb/test/tools/copy_tab.cpp b/ndb/test/tools/copy_tab.cpp index 33ce8e01d9a..30141acaa78 100644 --- a/ndb/test/tools/copy_tab.cpp +++ b/ndb/test/tools/copy_tab.cpp @@ -24,6 +24,7 @@ #include int main(int argc, const char** argv){ + ndb_init(); const char* _tabname = NULL; const char* _to_tabname = NULL; diff --git a/ndb/test/tools/cpcc.cpp b/ndb/test/tools/cpcc.cpp index e30d458ffee..dd59e577f2c 100644 --- a/ndb/test/tools/cpcc.cpp +++ b/ndb/test/tools/cpcc.cpp @@ -173,6 +173,7 @@ add_hosts(Vector & hosts, BaseString list){ int main(int argc, const char** argv){ + ndb_init(); int help = 0; const char *cmd=0, *name=0, *group=0, *owner=0; int list = 0, start = 0, stop = 0, rm = 0; diff --git a/ndb/test/tools/create_index.cpp b/ndb/test/tools/create_index.cpp index f883755ea24..75a657522f6 100644 --- a/ndb/test/tools/create_index.cpp +++ b/ndb/test/tools/create_index.cpp @@ -26,6 +26,7 @@ int main(int argc, const char** argv){ + ndb_init(); const char* _dbname = "TEST_DB"; int _help = 0; diff --git a/ndb/test/tools/hugoCalculator.cpp b/ndb/test/tools/hugoCalculator.cpp index 7f2751be2ba..82c4bbff1a4 100644 --- a/ndb/test/tools/hugoCalculator.cpp +++ b/ndb/test/tools/hugoCalculator.cpp @@ -28,6 +28,7 @@ int main(int argc, const char** argv) { + ndb_init(); int _row = 0; int _column = 0; int _updates = 0; diff --git a/ndb/test/tools/hugoFill.cpp b/ndb/test/tools/hugoFill.cpp index dee6ce2e6c8..6253bd1bb12 100644 --- a/ndb/test/tools/hugoFill.cpp +++ b/ndb/test/tools/hugoFill.cpp @@ -25,6 +25,7 @@ int main(int argc, const char** argv){ + ndb_init(); int _records = 0; const char* _tabname = NULL; diff --git a/ndb/test/tools/hugoLoad.cpp b/ndb/test/tools/hugoLoad.cpp index be7f878d106..c697ad22aad 100644 --- a/ndb/test/tools/hugoLoad.cpp +++ b/ndb/test/tools/hugoLoad.cpp @@ -24,6 +24,7 @@ int main(int argc, const char** argv){ + ndb_init(); int _records = 0; const char* _tabname = NULL; diff --git a/ndb/test/tools/hugoLockRecords.cpp b/ndb/test/tools/hugoLockRecords.cpp index e2c2cd13f00..629408d401d 100644 --- a/ndb/test/tools/hugoLockRecords.cpp +++ b/ndb/test/tools/hugoLockRecords.cpp @@ -27,6 +27,7 @@ #include int main(int argc, const char** argv){ + ndb_init(); int _records = 0; int _loops = 1; diff --git a/ndb/test/tools/hugoPkDelete.cpp b/ndb/test/tools/hugoPkDelete.cpp index 1855f19796f..78a90ebcb46 100644 --- a/ndb/test/tools/hugoPkDelete.cpp +++ b/ndb/test/tools/hugoPkDelete.cpp @@ -27,6 +27,7 @@ #include int main(int argc, const char** argv){ + ndb_init(); int _records = 0; int _loops = 1; diff --git a/ndb/test/tools/hugoPkRead.cpp b/ndb/test/tools/hugoPkRead.cpp index 50351f08195..cf08b137e8e 100644 --- a/ndb/test/tools/hugoPkRead.cpp +++ b/ndb/test/tools/hugoPkRead.cpp @@ -28,6 +28,7 @@ int main(int argc, const char** argv){ + ndb_init(); int _records = 0; int _loops = 1; diff --git a/ndb/test/tools/hugoPkReadRecord.cpp b/ndb/test/tools/hugoPkReadRecord.cpp index 85f20bd2060..38b7cae2bf4 100644 --- a/ndb/test/tools/hugoPkReadRecord.cpp +++ b/ndb/test/tools/hugoPkReadRecord.cpp @@ -28,6 +28,7 @@ int main(int argc, const char** argv) { + ndb_init(); int _row = 0; int _hex = 0; int _primaryKey = 0; diff --git a/ndb/test/tools/hugoPkUpdate.cpp b/ndb/test/tools/hugoPkUpdate.cpp index e7edc3a991d..286be14a01c 100644 --- a/ndb/test/tools/hugoPkUpdate.cpp +++ b/ndb/test/tools/hugoPkUpdate.cpp @@ -27,6 +27,7 @@ #include int main(int argc, const char** argv){ + ndb_init(); int _records = 0; int _loops = 1; diff --git a/ndb/test/tools/hugoScanRead.cpp b/ndb/test/tools/hugoScanRead.cpp index 47ea8f4a8a7..cdfdcea4654 100644 --- a/ndb/test/tools/hugoScanRead.cpp +++ b/ndb/test/tools/hugoScanRead.cpp @@ -27,6 +27,7 @@ #include int main(int argc, const char** argv){ + ndb_init(); int _records = 0; int _loops = 1; diff --git a/ndb/test/tools/hugoScanUpdate.cpp b/ndb/test/tools/hugoScanUpdate.cpp index 3e2255ca0f3..96a487a02bf 100644 --- a/ndb/test/tools/hugoScanUpdate.cpp +++ b/ndb/test/tools/hugoScanUpdate.cpp @@ -27,6 +27,7 @@ #include int main(int argc, const char** argv){ + ndb_init(); int _records = 0; int _loops = 1; diff --git a/ndb/test/tools/restart.cpp b/ndb/test/tools/restart.cpp index 88cfb231a72..9ad20801fd7 100644 --- a/ndb/test/tools/restart.cpp +++ b/ndb/test/tools/restart.cpp @@ -27,6 +27,7 @@ #include int main(int argc, const char** argv){ + ndb_init(); const char* _hostName = NULL; int _initial = 0; diff --git a/ndb/test/tools/transproxy.cpp b/ndb/test/tools/transproxy.cpp index 384a8a34f03..90e216ec785 100644 --- a/ndb/test/tools/transproxy.cpp +++ b/ndb/test/tools/transproxy.cpp @@ -346,6 +346,7 @@ start() int main(int av, char** ac) { + ndb_init(); debug("start"); hostname = "ndb-srv7"; if (Ndb_getInAddr(&hostaddr.sin_addr, hostname) != 0) { diff --git a/ndb/test/tools/verify_index.cpp b/ndb/test/tools/verify_index.cpp index 1295b657e9b..6c8e304e1a1 100644 --- a/ndb/test/tools/verify_index.cpp +++ b/ndb/test/tools/verify_index.cpp @@ -27,6 +27,7 @@ int main(int argc, const char** argv){ + ndb_init(); int _parallelism = 240; const char* _tabname = NULL; const char* _indexname = NULL; diff --git a/ndb/tools/delete_all.cpp b/ndb/tools/delete_all.cpp index 5110947c6a2..aa5798376ae 100644 --- a/ndb/tools/delete_all.cpp +++ b/ndb/tools/delete_all.cpp @@ -26,6 +26,7 @@ static int clear_table(Ndb* pNdb, const NdbDictionary::Table* pTab, int parallelism=240); int main(int argc, const char** argv){ + ndb_init(); const char* _tabname = NULL; const char* _dbname = "TEST_DB"; diff --git a/ndb/tools/desc.cpp b/ndb/tools/desc.cpp index 859a9544a79..0ab11a0fdd2 100644 --- a/ndb/tools/desc.cpp +++ b/ndb/tools/desc.cpp @@ -22,6 +22,7 @@ int main(int argc, const char** argv){ + ndb_init(); const char* _tabname = NULL; const char* _dbname = "TEST_DB"; int _unqualified = 0; diff --git a/ndb/tools/drop_index.cpp b/ndb/tools/drop_index.cpp index 327f15741c9..70c29461c23 100644 --- a/ndb/tools/drop_index.cpp +++ b/ndb/tools/drop_index.cpp @@ -23,6 +23,7 @@ #include int main(int argc, const char** argv){ + ndb_init(); const char* _tabname = NULL; const char* _dbname = "TEST_DB"; diff --git a/ndb/tools/drop_tab.cpp b/ndb/tools/drop_tab.cpp index 70e5d85aabe..15c229cb0fb 100644 --- a/ndb/tools/drop_tab.cpp +++ b/ndb/tools/drop_tab.cpp @@ -23,6 +23,7 @@ #include int main(int argc, const char** argv){ + ndb_init(); const char* _tabname = NULL; const char* _dbname = "TEST_DB"; diff --git a/ndb/tools/listTables.cpp b/ndb/tools/listTables.cpp index d6465f3214f..4b24929ee4b 100644 --- a/ndb/tools/listTables.cpp +++ b/ndb/tools/listTables.cpp @@ -22,7 +22,6 @@ */ #include -#include #include #include @@ -167,6 +166,7 @@ const char *debug_option= 0; #endif int main(int argc, const char** argv){ + ndb_init(); int _loops = 1; const char* _tabname = NULL; const char* _dbname = "TEST_DB"; @@ -209,7 +209,6 @@ int main(int argc, const char** argv){ _tabname = argv[optind]; #ifndef DBUG_OFF - my_init(); if (debug_option) DBUG_PUSH(debug_option); #endif diff --git a/ndb/tools/ndbsql.cpp b/ndb/tools/ndbsql.cpp index 6af5f47f6f4..1997e4abebd 100644 --- a/ndb/tools/ndbsql.cpp +++ b/ndb/tools/ndbsql.cpp @@ -671,6 +671,7 @@ void print_help_virtual() { int main(int argc, const char** argv) { + ndb_init(); const char* usage = "Usage: ndbsql [-h] [-d dsn] [-f file] [stmt]\n-h help\n-d \n-f batch mode\nstmt single SQL statement\n"; const char* dsn = "TEST_DB"; bool helpFlg = false, batchMode = false; diff --git a/ndb/tools/select_all.cpp b/ndb/tools/select_all.cpp index eb95947fc0f..8fb8437ba5f 100644 --- a/ndb/tools/select_all.cpp +++ b/ndb/tools/select_all.cpp @@ -16,7 +16,6 @@ #include -#include #include @@ -42,6 +41,7 @@ int scanReadRecords(Ndb*, bool orderby); int main(int argc, const char** argv){ + ndb_init(); int _parallelism = 240; const char* _delimiter = "\t"; int _header = true; @@ -89,7 +89,6 @@ int main(int argc, const char** argv){ _tabname = argv[optind]; #ifndef DBUG_OFF - my_init(); if (debug_option) DBUG_PUSH(debug_option); #endif diff --git a/ndb/tools/select_count.cpp b/ndb/tools/select_count.cpp index bb7c9dea49b..6650421e637 100644 --- a/ndb/tools/select_count.cpp +++ b/ndb/tools/select_count.cpp @@ -33,6 +33,7 @@ select_count(Ndb* pNdb, const NdbDictionary::Table* pTab, UtilTransactions::ScanLock lock); int main(int argc, const char** argv){ + ndb_init(); const char* _dbname = "TEST_DB"; int _parallelism = 240; int _help = 0; diff --git a/ndb/tools/waiter.cpp b/ndb/tools/waiter.cpp index 63469c6d746..c27b46c9356 100644 --- a/ndb/tools/waiter.cpp +++ b/ndb/tools/waiter.cpp @@ -30,6 +30,7 @@ int waitClusterStatus(const char* _addr, ndb_mgm_node_status _status, unsigned int _timeout); int main(int argc, const char** argv){ + ndb_init(); const char* _hostName = NULL; int _no_contact = 0; diff --git a/sql/Makefile.am b/sql/Makefile.am index d951aae91e1..19bdf8055f3 100644 --- a/sql/Makefile.am +++ b/sql/Makefile.am @@ -37,7 +37,7 @@ LDADD = @isam_libs@ \ $(top_builddir)/mysys/libmysys.a \ $(top_builddir)/dbug/libdbug.a \ $(top_builddir)/regex/libregex.a \ - $(top_builddir)/strings/libmystrings.a @ZLIB_LIBS@ + $(top_builddir)/strings/libmystrings.a @ZLIB_LIBS@ @NDB_SCI_LIBS@ mysqld_LDADD = @MYSQLD_EXTRA_LDFLAGS@ \ @bdb_libs@ @innodb_libs@ @pstack_libs@ \ diff --git a/sql/field.h b/sql/field.h index e12dd60c13b..3d22c6904a7 100644 --- a/sql/field.h +++ b/sql/field.h @@ -179,7 +179,14 @@ public: virtual void make_field(Send_field *)=0; virtual void sort_string(char *buff,uint length)=0; virtual bool optimize_range(uint idx, uint part); - virtual bool store_for_compare() { return 0; } + /* + This should be true for fields which, when compared with constant + items, can be casted to longlong. In this case we will at 'fix_fields' + stage cast the constant items to longlongs and at the execution stage + use field->val_int() for comparison. Used to optimize clauses like + 'a_column BETWEEN date_const, date_const'. + */ + virtual bool can_be_compared_as_longlong() const { return FALSE; } virtual void free() {} Field *new_field(MEM_ROOT *root, struct st_table *new_table) { @@ -566,7 +573,7 @@ public: void sort_string(char *buff,uint length); uint32 pack_length() const { return 8; } void sql_type(String &str) const; - bool store_for_compare() { return 1; } + bool can_be_compared_as_longlong() const { return TRUE; } uint32 max_length() { return 20; } field_cast_enum field_cast_type() { return FIELD_CAST_LONGLONG; } }; @@ -694,7 +701,7 @@ public: void sort_string(char *buff,uint length); uint32 pack_length() const { return 4; } void sql_type(String &str) const; - bool store_for_compare() { return 1; } + bool can_be_compared_as_longlong() const { return TRUE; } bool zero_pack() const { return 0; } void set_time(); virtual void set_default() @@ -740,7 +747,7 @@ public: String *val_str(String*,String *); bool send_binary(Protocol *protocol); void sql_type(String &str) const; - bool store_for_compare() { return 1; } + bool can_be_compared_as_longlong() const { return TRUE; } field_cast_enum field_cast_type() { return FIELD_CAST_YEAR; } }; @@ -772,7 +779,7 @@ public: void sort_string(char *buff,uint length); uint32 pack_length() const { return 4; } void sql_type(String &str) const; - bool store_for_compare() { return 1; } + bool can_be_compared_as_longlong() const { return TRUE; } bool zero_pack() const { return 1; } field_cast_enum field_cast_type() { return FIELD_CAST_DATE; } }; @@ -802,7 +809,7 @@ public: void sort_string(char *buff,uint length); uint32 pack_length() const { return 3; } void sql_type(String &str) const; - bool store_for_compare() { return 1; } + bool can_be_compared_as_longlong() const { return TRUE; } bool zero_pack() const { return 1; } bool get_date(TIME *ltime,uint fuzzydate); bool get_time(TIME *ltime); @@ -839,7 +846,7 @@ public: void sort_string(char *buff,uint length); uint32 pack_length() const { return 3; } void sql_type(String &str) const; - bool store_for_compare() { return 1; } + bool can_be_compared_as_longlong() const { return TRUE; } bool zero_pack() const { return 1; } field_cast_enum field_cast_type() { return FIELD_CAST_TIME; } }; @@ -875,7 +882,7 @@ public: void sort_string(char *buff,uint length); uint32 pack_length() const { return 8; } void sql_type(String &str) const; - bool store_for_compare() { return 1; } + bool can_be_compared_as_longlong() const { return TRUE; } bool zero_pack() const { return 1; } bool get_date(TIME *ltime,uint fuzzydate); bool get_time(TIME *ltime); diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 4e474568671..0f4d9630fe1 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -140,6 +140,16 @@ static int ndb_to_mysql_error(const NdbError *err) } + +inline +int execute_no_commit(ha_ndbcluster *h, NdbConnection *trans) +{ + int m_batch_execute= 0; + if (false && m_batch_execute) + return 0; + return trans->execute(NoCommit); +} + /* Place holder for ha_ndbcluster thread specific data */ @@ -219,7 +229,8 @@ void ha_ndbcluster::no_uncommitted_rows_init(THD *thd) void ha_ndbcluster::no_uncommitted_rows_update(int c) { DBUG_ENTER("ha_ndbcluster::no_uncommitted_rows_update"); - struct Ndb_table_local_info *info= (struct Ndb_table_local_info *)m_table_info; + struct Ndb_table_local_info *info= + (struct Ndb_table_local_info *)m_table_info; info->no_uncommitted_rows_count+= c; DBUG_PRINT("info", ("id=%d, no_uncommitted_rows_count=%d", ((const NDBTAB *)m_table)->getTableId(), @@ -600,58 +611,60 @@ int ha_ndbcluster::get_metadata(const char *path) { NDBDICT *dict= m_ndb->getDictionary(); const NDBTAB *tab; - const void *data, *pack_data; - const char **key_name; - uint ndb_columns, mysql_columns, length, pack_length; int error; + bool invalidating_ndb_table= false; + DBUG_ENTER("get_metadata"); DBUG_PRINT("enter", ("m_tabname: %s, path: %s", m_tabname, path)); - if (!(tab= dict->getTable(m_tabname))) - ERR_RETURN(dict->getNdbError()); - DBUG_PRINT("info", ("Table schema version: %d", tab->getObjectVersion())); - - /* - This is the place to check that the table we got from NDB - is equal to the one on local disk - */ - ndb_columns= (uint) tab->getNoOfColumns(); - mysql_columns= table->fields; - if (table->primary_key == MAX_KEY) - ndb_columns--; - if (ndb_columns != mysql_columns) - { - DBUG_PRINT("error", - ("Wrong number of columns, ndb: %d mysql: %d", - ndb_columns, mysql_columns)); - DBUG_RETURN(HA_ERR_OLD_METADATA); - } - - /* - Compare FrmData in NDB with frm file from disk. - */ - error= 0; - if (readfrm(path, &data, &length) || - packfrm(data, length, &pack_data, &pack_length)) - { - my_free((char*)data, MYF(MY_ALLOW_ZERO_PTR)); - my_free((char*)pack_data, MYF(MY_ALLOW_ZERO_PTR)); - DBUG_RETURN(1); - } + do { + const void *data, *pack_data; + uint length, pack_length; + + if (!(tab= dict->getTable(m_tabname))) + ERR_RETURN(dict->getNdbError()); + DBUG_PRINT("info", ("Table schema version: %d", tab->getObjectVersion())); + /* + Compare FrmData in NDB with frm file from disk. + */ + error= 0; + if (readfrm(path, &data, &length) || + packfrm(data, length, &pack_data, &pack_length)) + { + my_free((char*)data, MYF(MY_ALLOW_ZERO_PTR)); + my_free((char*)pack_data, MYF(MY_ALLOW_ZERO_PTR)); + DBUG_RETURN(1); + } - if ((pack_length != tab->getFrmLength()) || - (memcmp(pack_data, tab->getFrmData(), pack_length))) - { - DBUG_PRINT("error", - ("metadata, pack_length: %d getFrmLength: %d memcmp: %d", - pack_length, tab->getFrmLength(), - memcmp(pack_data, tab->getFrmData(), pack_length))); - DBUG_DUMP("pack_data", (char*)pack_data, pack_length); - DBUG_DUMP("frm", (char*)tab->getFrmData(), tab->getFrmLength()); - error= HA_ERR_OLD_METADATA; - } - my_free((char*)data, MYF(0)); - my_free((char*)pack_data, MYF(0)); + if ((pack_length != tab->getFrmLength()) || + (memcmp(pack_data, tab->getFrmData(), pack_length))) + { + if (!invalidating_ndb_table) + { + DBUG_PRINT("info", ("Invalidating table")); + dict->invalidateTable(m_tabname); + invalidating_ndb_table= true; + } + else + { + DBUG_PRINT("error", + ("metadata, pack_length: %d getFrmLength: %d memcmp: %d", + pack_length, tab->getFrmLength(), + memcmp(pack_data, tab->getFrmData(), pack_length))); + DBUG_DUMP("pack_data", (char*)pack_data, pack_length); + DBUG_DUMP("frm", (char*)tab->getFrmData(), tab->getFrmLength()); + error= HA_ERR_OLD_METADATA; + invalidating_ndb_table= false; + } + } + else + { + invalidating_ndb_table= false; + } + my_free((char*)data, MYF(0)); + my_free((char*)pack_data, MYF(0)); + } while (invalidating_ndb_table); + if (error) DBUG_RETURN(error); @@ -790,14 +803,14 @@ int ha_ndbcluster::get_ndb_lock_type(enum thr_lock_type type) { int lm; if (type == TL_WRITE_ALLOW_WRITE) - lm= NdbScanOperation::LM_Exclusive; + lm= NdbOperation::LM_Exclusive; else if (uses_blob_value(retrieve_all_fields)) /* TODO use a new scan mode to read + lock + keyinfo */ - lm= NdbScanOperation::LM_Exclusive; + lm= NdbOperation::LM_Exclusive; else - lm= NdbScanOperation::LM_CommittedRead; + lm= NdbOperation::LM_CommittedRead; return lm; } @@ -939,8 +952,10 @@ int ha_ndbcluster::pk_read(const byte *key, uint key_len, byte *buf) DBUG_PRINT("enter", ("key_len: %u", key_len)); DBUG_DUMP("key", (char*)key, key_len); + NdbOperation::LockMode lm= + (NdbOperation::LockMode)get_ndb_lock_type(m_lock.type); if (!(op= trans->getNdbOperation((const NDBTAB *) m_table)) || - op->readTuple() != 0) + op->readTuple(lm) != 0) ERR_RETURN(trans->getNdbError()); if (table->primary_key == MAX_KEY) @@ -1008,8 +1023,10 @@ int ha_ndbcluster::complemented_pk_read(const byte *old_data, byte *new_data) // We have allready retrieved all fields, nothing to complement DBUG_RETURN(0); + NdbOperation::LockMode lm= + (NdbOperation::LockMode)get_ndb_lock_type(m_lock.type); if (!(op= trans->getNdbOperation((const NDBTAB *) m_table)) || - op->readTuple() != 0) + op->readTuple(lm) != 0) ERR_RETURN(trans->getNdbError()); int res; @@ -1028,7 +1045,7 @@ int ha_ndbcluster::complemented_pk_read(const byte *old_data, byte *new_data) } } - if (trans->execute(NoCommit) != 0) + if (execute_no_commit(this,trans) != 0) { table->status= STATUS_NOT_FOUND; DBUG_RETURN(ndb_err(trans)); @@ -1060,10 +1077,12 @@ int ha_ndbcluster::unique_index_read(const byte *key, DBUG_DUMP("key", (char*)key, key_len); DBUG_PRINT("enter", ("name: %s", get_unique_index_name(active_index))); + NdbOperation::LockMode lm= + (NdbOperation::LockMode)get_ndb_lock_type(m_lock.type); if (!(op= trans->getNdbIndexOperation((NDBINDEX *) m_index[active_index].unique_index, (const NDBTAB *) m_table)) || - op->readTuple() != 0) + op->readTuple(lm) != 0) ERR_RETURN(trans->getNdbError()); // Set secondary index key(s) @@ -1140,7 +1159,7 @@ inline int ha_ndbcluster::next_result(byte *buf) */ if (ops_pending && blobs_pending) { - if (trans->execute(NoCommit) != 0) + if (execute_no_commit(this,trans) != 0) DBUG_RETURN(ndb_err(trans)); ops_pending= 0; blobs_pending= false; @@ -1168,7 +1187,7 @@ inline int ha_ndbcluster::next_result(byte *buf) DBUG_PRINT("info", ("ops_pending: %d", ops_pending)); if (current_thd->transaction.on) { - if (ops_pending && (trans->execute(NoCommit) != 0)) + if (ops_pending && (execute_no_commit(this,trans) != 0)) DBUG_RETURN(ndb_err(trans)); } else @@ -1322,14 +1341,13 @@ int ha_ndbcluster::ordered_index_scan(const key_range *start_key, DBUG_EXECUTE("enter", print_key(end_key, "end_key");); index_name= get_index_name(active_index); - if (!(op= trans->getNdbIndexScanOperation((NDBINDEX *) - m_index[active_index].index, - (const NDBTAB *) m_table))) - ERR_RETURN(trans->getNdbError()); - NdbScanOperation::LockMode lm= (NdbScanOperation::LockMode) - get_ndb_lock_type(m_lock.type); - if (!(cursor= op->readTuples(lm, 0, parallelism, sorted))) + NdbOperation::LockMode lm= + (NdbOperation::LockMode)get_ndb_lock_type(m_lock.type); + if (!(op= trans->getNdbIndexScanOperation((NDBINDEX *) + m_index[active_index].index, + (const NDBTAB *) m_table)) || + !(cursor= op->readTuples(lm, 0, parallelism, sorted))) ERR_RETURN(trans->getNdbError()); m_active_cursor= cursor; @@ -1387,11 +1405,10 @@ int ha_ndbcluster::filtered_scan(const byte *key, uint key_len, DBUG_PRINT("info", ("Starting a new filtered scan on %s", m_tabname)); - if (!(op= trans->getNdbScanOperation((const NDBTAB *) m_table))) - ERR_RETURN(trans->getNdbError()); - NdbScanOperation::LockMode lm= (NdbScanOperation::LockMode) - get_ndb_lock_type(m_lock.type); - if (!(cursor= op->readTuples(lm, 0, parallelism))) + NdbOperation::LockMode lm= + (NdbOperation::LockMode)get_ndb_lock_type(m_lock.type); + if (!(op= trans->getNdbScanOperation((const NDBTAB *) m_table)) || + !(cursor= op->readTuples(lm, 0, parallelism))) ERR_RETURN(trans->getNdbError()); m_active_cursor= cursor; @@ -1458,11 +1475,10 @@ int ha_ndbcluster::full_table_scan(byte *buf) DBUG_ENTER("full_table_scan"); DBUG_PRINT("enter", ("Starting new scan on %s", m_tabname)); - if (!(op=trans->getNdbScanOperation((const NDBTAB *) m_table))) - ERR_RETURN(trans->getNdbError()); - NdbScanOperation::LockMode lm= (NdbScanOperation::LockMode) - get_ndb_lock_type(m_lock.type); - if (!(cursor= op->readTuples(lm, 0, parallelism))) + NdbOperation::LockMode lm= + (NdbOperation::LockMode)get_ndb_lock_type(m_lock.type); + if (!(op=trans->getNdbScanOperation((const NDBTAB *) m_table)) || + !(cursor= op->readTuples(lm, 0, parallelism))) ERR_RETURN(trans->getNdbError()); m_active_cursor= cursor; DBUG_RETURN(define_read_attrs(buf, op)); @@ -1508,7 +1524,7 @@ int ha_ndbcluster::define_read_attrs(byte* buf, NdbOperation* op) ERR_RETURN(op->getNdbError()); } - if (trans->execute(NoCommit) != 0) + if (execute_no_commit(this,trans) != 0) DBUG_RETURN(ndb_err(trans)); DBUG_PRINT("exit", ("Scan started successfully")); DBUG_RETURN(next_result(buf)); @@ -1601,7 +1617,7 @@ int ha_ndbcluster::write_row(byte *record) bulk_insert_not_flushed= false; if (thd->transaction.on) { - if (trans->execute(NoCommit) != 0) + if (execute_no_commit(this,trans) != 0) { skip_auto_increment= true; no_uncommitted_rows_execute_failure(); @@ -1776,7 +1792,7 @@ int ha_ndbcluster::update_row(const byte *old_data, byte *new_data) } // Execute update operation - if (!cursor && trans->execute(NoCommit) != 0) { + if (!cursor && execute_no_commit(this,trans) != 0) { no_uncommitted_rows_execute_failure(); DBUG_RETURN(ndb_err(trans)); } @@ -1846,7 +1862,7 @@ int ha_ndbcluster::delete_row(const byte *record) } // Execute delete operation - if (trans->execute(NoCommit) != 0) { + if (execute_no_commit(this,trans) != 0) { no_uncommitted_rows_execute_failure(); DBUG_RETURN(ndb_err(trans)); } @@ -2276,7 +2292,7 @@ int ha_ndbcluster::close_scan() deleteing/updating transaction before closing the scan */ DBUG_PRINT("info", ("ops_pending: %d", ops_pending)); - if (trans->execute(NoCommit) != 0) { + if (execute_no_commit(this,trans) != 0) { no_uncommitted_rows_execute_failure(); DBUG_RETURN(ndb_err(trans)); } @@ -2599,7 +2615,7 @@ int ha_ndbcluster::end_bulk_insert() "rows_inserted:%d, bulk_insert_rows: %d", rows_inserted, bulk_insert_rows)); bulk_insert_not_flushed= false; - if (trans->execute(NoCommit) != 0) { + if (execute_no_commit(this,trans) != 0) { no_uncommitted_rows_execute_failure(); my_errno= error= ndb_err(trans); } @@ -2953,6 +2969,8 @@ static int create_ndb_column(NDBCOL &col, { // Set name col.setName(field->field_name); + // Get char set + CHARSET_INFO *cs= field->charset(); // Set type and sizes const enum enum_field_types mysql_type= field->real_type(); switch (mysql_type) { @@ -3024,15 +3042,19 @@ static int create_ndb_column(NDBCOL &col, case MYSQL_TYPE_STRING: if (field->flags & BINARY_FLAG) col.setType(NDBCOL::Binary); - else + else { col.setType(NDBCOL::Char); + col.setCharset(cs); + } col.setLength(field->pack_length()); break; case MYSQL_TYPE_VAR_STRING: if (field->flags & BINARY_FLAG) col.setType(NDBCOL::Varbinary); - else + else { col.setType(NDBCOL::Varchar); + col.setCharset(cs); + } col.setLength(field->pack_length()); break; // Blob types (all come in as MYSQL_TYPE_BLOB) @@ -3040,8 +3062,10 @@ static int create_ndb_column(NDBCOL &col, case MYSQL_TYPE_TINY_BLOB: if (field->flags & BINARY_FLAG) col.setType(NDBCOL::Blob); - else + else { col.setType(NDBCOL::Text); + col.setCharset(cs); + } col.setInlineSize(256); // No parts col.setPartSize(0); @@ -3051,8 +3075,10 @@ static int create_ndb_column(NDBCOL &col, case MYSQL_TYPE_BLOB: if (field->flags & BINARY_FLAG) col.setType(NDBCOL::Blob); - else + else { col.setType(NDBCOL::Text); + col.setCharset(cs); + } // Use "<=" even if "<" is the exact condition if (field->max_length() <= (1 << 8)) goto mysql_type_tiny_blob; @@ -3071,8 +3097,10 @@ static int create_ndb_column(NDBCOL &col, case MYSQL_TYPE_MEDIUM_BLOB: if (field->flags & BINARY_FLAG) col.setType(NDBCOL::Blob); - else + else { col.setType(NDBCOL::Text); + col.setCharset(cs); + } col.setInlineSize(256); col.setPartSize(4000); col.setStripeSize(8); @@ -3081,8 +3109,10 @@ static int create_ndb_column(NDBCOL &col, case MYSQL_TYPE_LONG_BLOB: if (field->flags & BINARY_FLAG) col.setType(NDBCOL::Blob); - else + else { col.setType(NDBCOL::Text); + col.setCharset(cs); + } col.setInlineSize(256); col.setPartSize(8000); col.setStripeSize(4); @@ -3375,7 +3405,9 @@ longlong ha_ndbcluster::get_auto_increment() DBUG_ENTER("get_auto_increment"); DBUG_PRINT("enter", ("m_tabname: %s", m_tabname)); int cache_size= - (rows_to_insert > autoincrement_prefetch) ? + (rows_to_insert - rows_inserted < autoincrement_prefetch) ? + rows_to_insert - rows_inserted + : (rows_to_insert > autoincrement_prefetch) ? rows_to_insert : autoincrement_prefetch; Uint64 auto_value= @@ -3719,12 +3751,14 @@ bool ndbcluster_init() { g_ndb->waitUntilReady(10); } - else if(res == 1 && g_ndb_cluster_connection->start_connect_thread()) + else if(res == 1) { - DBUG_PRINT("error", ("g_ndb_cluster_connection->start_connect_thread()")); - DBUG_RETURN(TRUE); + if (g_ndb_cluster_connection->start_connect_thread()) { + DBUG_PRINT("error", ("g_ndb_cluster_connection->start_connect_thread()")); + DBUG_RETURN(TRUE); + } } - else + else { DBUG_ASSERT(res == -1); DBUG_PRINT("error", ("permanent error")); @@ -3737,7 +3771,7 @@ bool ndbcluster_init() ndbcluster_inited= 1; #ifdef USE_DISCOVER_ON_STARTUP - if (ndb_discover_tables() != 0) + if (res == 0 && ndb_discover_tables() != 0) DBUG_RETURN(TRUE); #endif DBUG_RETURN(false); diff --git a/sql/ha_ndbcluster.h b/sql/ha_ndbcluster.h index c0ef172413f..eb4556a606b 100644 --- a/sql/ha_ndbcluster.h +++ b/sql/ha_ndbcluster.h @@ -264,6 +264,8 @@ class ha_ndbcluster: public handler void no_uncommitted_rows_update(int); void no_uncommitted_rows_init(THD *); void no_uncommitted_rows_reset(THD *); + + friend int execute_no_commit(ha_ndbcluster*, NdbConnection*); }; bool ndbcluster_init(void); diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 8950ad0c594..bb1ea09d6bc 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -243,7 +243,7 @@ void Item_bool_func2::fix_length_and_dec() if (args[0]->type() == FIELD_ITEM) { Field *field=((Item_field*) args[0])->field; - if (field->store_for_compare()) + if (field->can_be_compared_as_longlong()) { if (convert_constant_item(field,&args[1])) { @@ -256,7 +256,7 @@ void Item_bool_func2::fix_length_and_dec() if (args[1]->type() == FIELD_ITEM) { Field *field=((Item_field*) args[1])->field; - if (field->store_for_compare()) + if (field->can_be_compared_as_longlong()) { if (convert_constant_item(field,&args[0])) { @@ -856,7 +856,7 @@ void Item_func_between::fix_length_and_dec() if (args[0]->type() == FIELD_ITEM) { Field *field=((Item_field*) args[0])->field; - if (field->store_for_compare()) + if (field->can_be_compared_as_longlong()) { if (convert_constant_item(field,&args[1])) cmp_type=INT_RESULT; // Works for all types. diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 65e26346834..6d7a4ff269d 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -3303,6 +3303,8 @@ copy_data_between_tables(TABLE *from,TABLE *to, List all_fields; ha_rows examined_rows; bool auto_increment_field_copied= 0; + ulong old_sql_mode; + bool no_auto_on_zero; DBUG_ENTER("copy_data_between_tables"); if (!(copy= new Copy_field[to->fields])) @@ -3361,6 +3363,11 @@ copy_data_between_tables(TABLE *from,TABLE *to, goto err; } + /* Turn on NO_AUTO_VALUE_ON_ZERO if not already on */ + old_sql_mode= thd->variables.sql_mode; + if (!(no_auto_on_zero= thd->variables.sql_mode & MODE_NO_AUTO_VALUE_ON_ZERO)) + thd->variables.sql_mode|= MODE_NO_AUTO_VALUE_ON_ZERO; + /* Handler must be told explicitly to retrieve all columns, because this function does not set field->query_id in the columns to the current query id */ @@ -3417,6 +3424,11 @@ copy_data_between_tables(TABLE *from,TABLE *to, to->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY); ha_enable_transaction(thd,TRUE); + + /* Turn off NO_AUTO_VALUE_ON_ZERO if it was not already off */ + if (!no_auto_on_zero) + thd->variables.sql_mode= old_sql_mode; + /* Ensure that the new table is saved properly to disk so that we can do a rename diff --git a/tests/client_test.c b/tests/client_test.c index a2b0791baa2..06a655cd3fb 100644 --- a/tests/client_test.c +++ b/tests/client_test.c @@ -27,11 +27,19 @@ #include #include #include +#ifdef HAVE_SYS_PARAM_H +/* Include to get MAXPATHLEN */ +#include +#endif +#ifndef MAXPATHLEN +#define MAXPATHLEN 256 +#endif #define MAX_TEST_QUERY_LENGTH 300 /* MAX QUERY BUFFER LENGTH */ /* set default options */ +static int opt_testcase = 0; static char *opt_db= 0; static char *opt_user= 0; static char *opt_password= 0; @@ -183,7 +191,7 @@ static void client_connect() if (!(mysql= mysql_init(NULL))) { myerror("mysql_init() failed"); - exit(0); + exit(1); } if (!(mysql_real_connect(mysql, opt_host, opt_user, @@ -193,7 +201,7 @@ static void client_connect() myerror("connection failed"); mysql_close(mysql); fprintf(stdout, "\n Check the connection options using --help or -?\n"); - exit(0); + exit(1); } fprintf(stdout, " OK"); @@ -4071,14 +4079,14 @@ static void test_stmt_close() if (!(lmysql= mysql_init(NULL))) { myerror("mysql_init() failed"); - exit(0); + exit(1); } if (!(mysql_real_connect(lmysql, opt_host, opt_user, opt_password, current_db, opt_port, opt_unix_socket, 0))) { myerror("connection failed"); - exit(0); + exit(1); } fprintf(stdout, " OK"); @@ -4688,7 +4696,7 @@ static void test_manual_sample() { fprintf(stderr, "\n drop table failed"); fprintf(stderr, "\n %s", mysql_error(mysql)); - exit(0); + exit(1); } if (mysql_query(mysql, "CREATE TABLE test_table(col1 int, col2 varchar(50), \ col3 smallint, \ @@ -4696,7 +4704,7 @@ static void test_manual_sample() { fprintf(stderr, "\n create table failed"); fprintf(stderr, "\n %s", mysql_error(mysql)); - exit(0); + exit(1); } /* Prepare a insert query with 3 parameters */ @@ -4705,7 +4713,7 @@ static void test_manual_sample() { fprintf(stderr, "\n prepare, insert failed"); fprintf(stderr, "\n %s", mysql_error(mysql)); - exit(0); + exit(1); } fprintf(stdout, "\n prepare, insert successful"); @@ -4716,7 +4724,7 @@ static void test_manual_sample() if (param_count != 3) /* validate parameter count */ { fprintf(stderr, "\n invalid parameter count returned by MySQL"); - exit(0); + exit(1); } /* Bind the data for the parameters */ @@ -4747,7 +4755,7 @@ static void test_manual_sample() { fprintf(stderr, "\n param bind failed"); fprintf(stderr, "\n %s", mysql_stmt_error(stmt)); - exit(0); + exit(1); } /* Specify the data */ @@ -4762,7 +4770,7 @@ static void test_manual_sample() { fprintf(stderr, "\n execute 1 failed"); fprintf(stderr, "\n %s", mysql_stmt_error(stmt)); - exit(0); + exit(1); } /* Get the total rows affected */ @@ -4772,7 +4780,7 @@ static void test_manual_sample() if (affected_rows != 1) /* validate affected rows */ { fprintf(stderr, "\n invalid affected rows by MySQL"); - exit(0); + exit(1); } /* Re-execute the insert, by changing the values */ @@ -4786,7 +4794,7 @@ static void test_manual_sample() { fprintf(stderr, "\n execute 2 failed"); fprintf(stderr, "\n %s", mysql_stmt_error(stmt)); - exit(0); + exit(1); } /* Get the total rows affected */ @@ -4796,7 +4804,7 @@ static void test_manual_sample() if (affected_rows != 1) /* validate affected rows */ { fprintf(stderr, "\n invalid affected rows by MySQL"); - exit(0); + exit(1); } /* Close the statement */ @@ -4804,7 +4812,7 @@ static void test_manual_sample() { fprintf(stderr, "\n failed while closing the statement"); fprintf(stderr, "\n %s", mysql_stmt_error(stmt)); - exit(0); + exit(1); } assert(2 == my_stmt_result("SELECT * FROM test_table")); @@ -4813,7 +4821,7 @@ static void test_manual_sample() { fprintf(stderr, "\n drop table failed"); fprintf(stderr, "\n %s", mysql_error(mysql)); - exit(0); + exit(1); } fprintf(stdout, "Success !!!"); } @@ -4865,7 +4873,7 @@ static void test_prepare_alter() check_execute(stmt, rc); if (thread_query((char *)"ALTER TABLE test_prep_alter change id id_new varchar(20)")) - exit(0); + exit(1); is_null= 1; rc= mysql_stmt_execute(stmt); @@ -6486,7 +6494,7 @@ static void test_prepare_grant() ER_UNKNOWN_COM_ERROR= 1047 */ if (mysql_errno(mysql) != 1047) - exit(0); + exit(1); } else { @@ -6497,7 +6505,7 @@ static void test_prepare_grant() if (!(lmysql= mysql_init(NULL))) { myerror("mysql_init() failed"); - exit(0); + exit(1); } if (!(mysql_real_connect(lmysql, opt_host, "test_grant", "", current_db, opt_port, @@ -6505,7 +6513,7 @@ static void test_prepare_grant() { myerror("connection failed"); mysql_close(lmysql); - exit(0); + exit(1); } fprintf(stdout, " OK"); @@ -6559,8 +6567,8 @@ static void test_frm_bug() MYSQL_RES *result; MYSQL_ROW row; FILE *test_file; - char data_dir[NAME_LEN]; - char test_frm[255]; + char data_dir[MAXPATHLEN]; + char test_frm[MAXPATHLEN]; int rc; myheader("test_frm_bug"); @@ -6581,7 +6589,7 @@ static void test_frm_bug() bind[0].buffer_type= MYSQL_TYPE_STRING; bind[0].buffer= data_dir; - bind[0].buffer_length= NAME_LEN; + bind[0].buffer_length= MAXPATHLEN; bind[0].is_null= 0; bind[0].length= 0; bind[1]= bind[0]; @@ -6605,7 +6613,7 @@ static void test_frm_bug() { fprintf(stdout, "\n ERROR: my_fopen failed for '%s'", test_frm); fprintf(stdout, "\n test cancelled"); - return; + exit(1); } fprintf(test_file, "this is a junk file for test"); @@ -6894,7 +6902,7 @@ static void test_drop_temp() ER_UNKNOWN_COM_ERROR= 1047 */ if (mysql_errno(mysql) != 1047) - exit(0); + exit(1); } else { @@ -6904,7 +6912,7 @@ static void test_drop_temp() if (!(lmysql= mysql_init(NULL))) { myerror("mysql_init() failed"); - exit(0); + exit(1); } rc= mysql_query(mysql, "flush privileges"); @@ -6917,7 +6925,7 @@ static void test_drop_temp() mysql= lmysql; myerror("connection failed"); mysql_close(lmysql); - exit(0); + exit(1); } fprintf(stdout, " OK"); @@ -10447,6 +10455,8 @@ static struct my_option client_test_long_options[] = (char **) &opt_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"socket", 'S', "Socket file to use for connection", (char **) &opt_unix_socket, (char **) &opt_unix_socket, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"testcase", 'c', "May disable some code when runs as mysql-test-run testcase.", + 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"count", 't', "Number of times test to be executed", (char **) &opt_count, (char **) &opt_count, 0, GET_UINT, REQUIRED_ARG, 1, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} @@ -10490,6 +10500,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), case '#': DBUG_PUSH(argument ? argument : default_dbug_option); break; + case 'c': + opt_testcase = 1; + break; case 'p': if (argument) { @@ -10740,6 +10753,5 @@ int main(int argc, char **argv) print_test_output(); my_end(0); - return(0); + exit(0); } -