Commit 565c2fdb authored by ingo@mysql.com's avatar ingo@mysql.com

Merge mysql.com:/home/mydev/mysql-5.0

into mysql.com:/home/mydev/mysql-5.0-5000
parents 9bf63b14 b3a66285
......@@ -64,8 +64,8 @@ AC_DEFUN([MYSQL_CHECK_NDB_OPTIONS], [
AC_ARG_WITH([ndb-ccflags],
[
--with-ndb-ccflags Extra CC options for ndb compile],
[ndb_cxxflags_fix=$withval],
[ndb_cxxflags_fix=])
[ndb_cxxflags_fix="$ndb_cxxflags_fix $withval"],
[ndb_cxxflags_fix=$ndb_cxxflags_fix])
AC_MSG_CHECKING([for NDB Cluster options])
AC_MSG_RESULT([])
......
......@@ -962,6 +962,7 @@ esac
MAX_C_OPTIMIZE="-O3"
MAX_CXX_OPTIMIZE="-O3"
ndb_cxxflags_fix=
case $SYSTEM_TYPE-$MACHINE_TYPE-$ac_cv_prog_gcc in
# workaround for Sun Forte/x86 see BUG#4681
*solaris*-i?86-no)
......
......@@ -35,13 +35,72 @@ sub mtr_get_opts_from_file ($) {
while ( <FILE> )
{
chomp;
s/\$MYSQL_TEST_DIR/$::glob_mysql_test_dir/g;
push(@args, split(' ', $_));
# --set-variable=init_connect=set @a='a\\0c'
s/^\s+//; # Remove leading space
s/\s+$//; # Remove ending space
# This is strange, but we need to fill whitespace inside
# quotes with something, to remove later. We do this to
# be able to split on space. Else, we have trouble with
# options like
#
# --someopt="--insideopt1 --insideopt2"
#
# But still with this, we are not 100% sure it is right,
# we need a shell to do it right.
# print STDERR "\n";
# print STDERR "AAA: $_\n";
s/\'([^\'\"]*)\'/unspace($1,"\x0a")/ge;
s/\"([^\'\"]*)\"/unspace($1,"\x0b")/ge;
s/\'([^\'\"]*)\'/unspace($1,"\x0a")/ge;
s/\"([^\'\"]*)\"/unspace($1,"\x0b")/ge;
# print STDERR "BBB: $_\n";
# foreach my $arg (/(--?\w.*?)(?=\s+--?\w|$)/)
# FIXME ENV vars should be expanded!!!!
foreach my $arg (split(/[ \t]+/))
{
$arg =~ tr/\x11\x0a\x0b/ \'\"/; # Put back real chars
# The outermost quotes has to go
$arg =~ s/^([^\'\"]*)\'(.*)\'([^\'\"]*)$/$1$2$3/
or $arg =~ s/^([^\'\"]*)\"(.*)\"([^\'\"]*)$/$1$2$3/;
$arg =~ s/\\\\/\\/g;
$arg =~ s/\$\{(\w+)\}/envsubst($1)/ge;
$arg =~ s/\$(\w+)/envsubst($1)/ge;
# print STDERR "ARG: $arg\n";
push(@args, $arg);
}
}
close FILE;
return \@args;
}
sub envsubst {
my $string= shift;
if ( ! defined $ENV{$string} )
{
mtr_error("opt file referense \$$string that is unknown");
}
return $ENV{$string};
}
sub unspace {
my $string= shift;
my $quote= shift;
$string =~ s/[ \t]/\x11/g;
return "$quote$string$quote";
}
sub mtr_fromfile ($) {
my $file= shift;
......
......@@ -4,7 +4,7 @@
# and is part of the translation of the Bourne shell script with the
# same name.
use Carp qw(cluck);
#use Carp qw(cluck);
use strict;
use POSIX ":sys_wait_h";
......@@ -64,18 +64,6 @@ sub spawn_impl ($$$$$$$) {
my $error= shift;
my $pid_file= shift; # FIXME
# FIXME really needing a PATH???
# $ENV{'PATH'}= "/bin:/usr/bin:/usr/local/bin:/usr/bsd:/usr/X11R6/bin:/usr/openwin/bin:/usr/bin/X11:$ENV{'PATH'}";
$ENV{'TZ'}= "GMT-3"; # for UNIX_TIMESTAMP tests to work
$ENV{'LC_COLLATE'}= "C";
$ENV{'MYSQL_TEST_DIR'}= $::glob_mysql_test_dir;
$ENV{'MASTER_MYPORT'}= $::opt_master_myport;
$ENV{'SLAVE_MYPORT'}= $::opt_slave_myport;
# $ENV{'MYSQL_TCP_PORT'}= '@MYSQL_TCP_PORT@'; # FIXME
$ENV{'MYSQL_TCP_PORT'}= 3306;
$ENV{'MASTER_MYSOCK'}= $::master->[0]->{'path_mysock'};
if ( $::opt_script_debug )
{
print STDERR "\n";
......@@ -85,17 +73,21 @@ sub spawn_impl ($$$$$$$) {
print STDERR "#### ", "STDERR $error\n" if $error;
if ( $join )
{
print STDERR "#### ", "run";
print STDERR "#### ", "RUN ";
}
else
{
print STDERR "#### ", "spawn";
print STDERR "#### ", "SPAWN ";
}
print STDERR "$path ", join(" ",@$arg_list_t), "\n";
print STDERR "#### ", "-" x 78, "\n";
}
my $pid= fork();
if ( ! defined $pid )
{
mtr_error("$path ($pid) can't be forked");
}
if ( $pid )
{
......@@ -104,17 +96,22 @@ sub spawn_impl ($$$$$$$) {
{
# We run a command and wait for the result
# FIXME this need to be improved
waitpid($pid,0);
my $res= waitpid($pid,0);
if ( $res == -1 )
{
mtr_error("$path ($pid) got lost somehow");
}
my $exit_value= $? >> 8;
my $signal_num= $? & 127;
my $dumped_core= $? & 128;
if ( $signal_num )
{
mtr_error("spawn got signal $signal_num");
mtr_error("$path ($pid) got signal $signal_num");
}
if ( $dumped_core )
{
mtr_error("spawn dumped core");
mtr_error("$path ($pid) dumped core");
}
return $exit_value;
}
......@@ -326,7 +323,8 @@ sub mtr_stop_mysqld_servers ($$) {
mtr_init_args(\$args);
mtr_add_arg($args, "--no-defaults");
mtr_add_arg($args, "-uroot");
mtr_add_arg($args, "--user=%s", $::opt_user);
mtr_add_arg($args, "--password=");
if ( -e $srv->{'sockfile'} )
{
mtr_add_arg($args, "--socket=%s", $srv->{'sockfile'});
......@@ -336,7 +334,8 @@ sub mtr_stop_mysqld_servers ($$) {
mtr_add_arg($args, "--port=%s", $srv->{'port'});
}
mtr_add_arg($args, "--connect_timeout=5");
mtr_add_arg($args, "--shutdown_timeout=70");
mtr_add_arg($args, "--shutdown_timeout=20");
mtr_add_arg($args, "--protocol=tcp"); # FIXME new thing, will it help?!
mtr_add_arg($args, "shutdown");
# We don't wait for termination of mysqladmin
mtr_spawn($::exe_mysqladmin, $args,
......@@ -361,6 +360,10 @@ sub mtr_stop_mysqld_servers ($$) {
{
last PIDSOCKFILEREMOVED;
}
if ( $loop % 20 == 1 )
{
mtr_warning("Still processes alive after 10 seconds, retrying for $loop seconds...");
}
mtr_debug("Sleep for 1 second waiting for pid and socket file removal");
sleep(1); # One second
}
......@@ -464,4 +467,40 @@ sub stop_reap_all {
$SIG{CHLD}= 'DEFAULT';
}
##############################################################################
#
# Wait for a file to be created
#
##############################################################################
sub sleep_until_file_created ($$) {
my $pidfile= shift;
my $timeout= shift;
my $loop= $timeout;
while ( $loop-- )
{
if ( -r $pidfile )
{
return;
}
mtr_debug("Sleep for 1 second waiting for creation of $pidfile");
if ( $loop % 20 == 1 )
{
mtr_warning("Waiting for $pidfile to be created, still trying for $loop seconds...");
}
sleep(1);
}
if ( ! -r $pidfile )
{
mtr_error("No $pidfile was created");
}
}
1;
......@@ -232,6 +232,8 @@ our $opt_local_master;
our $master; # Will be struct in C
our $slave;
our $opt_master_myport;
our $opt_slave_myport;
our $opt_ndbcluster_port;
our $opt_ndbconnectstring;
......@@ -248,16 +250,10 @@ our $opt_skip_rpl;
our $opt_skip_test;
our $opt_sleep;
our $opt_ps_protocol;
# FIXME all of the sleep time handling needs cleanup
our $opt_sleep_time_after_restart= 1;
our $opt_sleep_time_for_delete= 10;
our $opt_sleep_time_for_first_master= 400; # enough time create innodb tables
our $opt_sleep_time_for_second_master= 400;
our $opt_sleep_time_for_first_slave= 400;
our $opt_sleep_time_for_second_slave= 30;
our $opt_sleep_time_after_restart= 1;
our $opt_sleep_time_for_delete= 10;
our $opt_socket;
......@@ -270,7 +266,7 @@ our $opt_strace_client;
our $opt_timer;
our $opt_user;
our $opt_user_test;
our $opt_valgrind;
......@@ -299,6 +295,7 @@ sub main ();
sub initial_setup ();
sub command_line_setup ();
sub executable_setup ();
sub environment_setup ();
sub kill_and_cleanup ();
sub collect_test_cases ($);
sub sleep_until_file_created ($$);
......@@ -332,6 +329,7 @@ sub main () {
initial_setup();
command_line_setup();
executable_setup();
environment_setup();
signal_setup();
if ( $opt_gcov )
......@@ -449,12 +447,9 @@ sub command_line_setup () {
$path_manager_log= "$glob_mysql_test_dir/var/log/manager.log";
$opt_current_test= "$glob_mysql_test_dir/var/log/current_test";
my $opt_master_myport= 9306;
my $opt_slave_myport= 9308;
$opt_ndbcluster_port= 9350;
$opt_sleep_time_for_delete= 10;
my $opt_user;
$opt_master_myport= 9306;
$opt_slave_myport= 9308;
$opt_ndbcluster_port= 9350;
# Read the command line
# Note: Keep list, and the order, in sync with usage at end of this file
......@@ -545,6 +540,7 @@ sub command_line_setup () {
$master->[0]->{'path_mypid'}= "$glob_mysql_test_dir/var/run/master.pid";
$master->[0]->{'path_mysock'}= "$opt_tmpdir/master.sock";
$master->[0]->{'path_myport'}= $opt_master_myport;
$master->[0]->{'start_timeout'}= 400; # enough time create innodb tables
$master->[1]->{'path_myddir'}= "$glob_mysql_test_dir/var/master1-data";
$master->[1]->{'path_myerr'}= "$glob_mysql_test_dir/var/log/master1.err";
......@@ -552,6 +548,7 @@ sub command_line_setup () {
$master->[1]->{'path_mypid'}= "$glob_mysql_test_dir/var/run/master1.pid";
$master->[1]->{'path_mysock'}= "$opt_tmpdir/master1.sock";
$master->[1]->{'path_myport'}= $opt_master_myport + 1;
$master->[1]->{'start_timeout'}= 400; # enough time create innodb tables
$slave->[0]->{'path_myddir'}= "$glob_mysql_test_dir/var/slave-data";
$slave->[0]->{'path_myerr'}= "$glob_mysql_test_dir/var/log/slave.err";
......@@ -559,6 +556,7 @@ sub command_line_setup () {
$slave->[0]->{'path_mypid'}= "$glob_mysql_test_dir/var/run/slave.pid";
$slave->[0]->{'path_mysock'}= "$opt_tmpdir/slave.sock";
$slave->[0]->{'path_myport'}= $opt_slave_myport;
$slave->[0]->{'start_timeout'}= 400;
$slave->[1]->{'path_myddir'}= "$glob_mysql_test_dir/var/slave1-data";
$slave->[1]->{'path_myerr'}= "$glob_mysql_test_dir/var/log/slave1.err";
......@@ -566,6 +564,7 @@ sub command_line_setup () {
$slave->[1]->{'path_mypid'}= "$glob_mysql_test_dir/var/run/slave1.pid";
$slave->[1]->{'path_mysock'}= "$opt_tmpdir/slave1.sock";
$slave->[1]->{'path_myport'}= $opt_slave_myport + 1;
$slave->[1]->{'start_timeout'}= 30;
$slave->[2]->{'path_myddir'}= "$glob_mysql_test_dir/var/slave2-data";
$slave->[2]->{'path_myerr'}= "$glob_mysql_test_dir/var/log/slave2.err";
......@@ -573,6 +572,7 @@ sub command_line_setup () {
$slave->[2]->{'path_mypid'}= "$glob_mysql_test_dir/var/run/slave2.pid";
$slave->[2]->{'path_mysock'}= "$opt_tmpdir/slave2.sock";
$slave->[2]->{'path_myport'}= $opt_slave_myport + 2;
$slave->[2]->{'start_timeout'}= 30;
# Do sanity checks of command line arguments
......@@ -594,16 +594,6 @@ sub command_line_setup () {
$master->[0]->{'path_mysock'}= $opt_socket;
}
# --------------------------------------------------------------------------
# Set LD_LIBRARY_PATH if we are using shared libraries
# --------------------------------------------------------------------------
$ENV{'LD_LIBRARY_PATH'}=
"$glob_basedir/lib:$glob_basedir/libmysql/.libs" .
($ENV{'LD_LIBRARY_PATH'} ? ":$ENV{'LD_LIBRARY_PATH'}" : "");
$ENV{'DYLD_LIBRARY_PATH'}=
"$glob_basedir/lib:$glob_basedir/libmysql/.libs" .
($ENV{'DYLD_LIBRARY_PATH'} ? ":$ENV{'DYLD_LIBRARY_PATH'}" : "");
# --------------------------------------------------------------------------
# Look at the command line options and set script flags
# --------------------------------------------------------------------------
......@@ -741,7 +731,7 @@ sub executable_setup () {
}
else
{
mtr_error("Cannot find embedded server 'mysqltest'");
mtr_error("Can't find embedded server 'mysqltest'");
}
$path_tests_bindir= "$glob_basedir/libmysqld/examples";
}
......@@ -831,6 +821,41 @@ sub executable_setup () {
}
##############################################################################
#
# Set environment to be used by childs of this process
#
##############################################################################
# Note that some env is setup in spawn/run, in "mtr_process.pl"
sub environment_setup () {
# --------------------------------------------------------------------------
# Set LD_LIBRARY_PATH if we are using shared libraries
# --------------------------------------------------------------------------
$ENV{'LD_LIBRARY_PATH'}=
"$glob_basedir/lib:$glob_basedir/libmysql/.libs" .
($ENV{'LD_LIBRARY_PATH'} ? ":$ENV{'LD_LIBRARY_PATH'}" : "");
$ENV{'DYLD_LIBRARY_PATH'}=
"$glob_basedir/lib:$glob_basedir/libmysql/.libs" .
($ENV{'DYLD_LIBRARY_PATH'} ? ":$ENV{'DYLD_LIBRARY_PATH'}" : "");
# --------------------------------------------------------------------------
# Also command lines in .opt files may contain env vars
# --------------------------------------------------------------------------
$ENV{'LC_COLLATE'}= "C";
$ENV{'MYSQL_TEST_DIR'}= $glob_mysql_test_dir;
$ENV{'MASTER_MYPORT'}= $opt_master_myport;
$ENV{'SLAVE_MYPORT'}= $opt_slave_myport;
# $ENV{'MYSQL_TCP_PORT'}= '@MYSQL_TCP_PORT@'; # FIXME
$ENV{'MYSQL_TCP_PORT'}= 3306;
$ENV{'MASTER_MYSOCK'}= $master->[0]->{'path_mysock'};
}
##############################################################################
#
# If we get a ^C, we try to clean up before termination
......@@ -922,6 +947,7 @@ sub collect_test_cases ($) {
# ----------------------------------------------------------------------
$tinfo->{'path'}= $path;
$tinfo->{'timezone'}= "GMT-3"; # for UNIX_TIMESTAMP tests to work
if ( defined mtr_match_prefix($tname,"rpl") )
{
......@@ -967,7 +993,7 @@ sub collect_test_cases ($) {
if ( defined $value )
{
$ENV{'TZ'}= $value; # FIXME pass this on somehow....
$tinfo->{'timezone'}= $value;
$extra_master_opt= [];
$tinfo->{'master_restart'}= 0;
last;
......@@ -1071,6 +1097,7 @@ sub kill_and_cleanup () {
# leftovers from previous runs.
mtr_report("Killing Possible Leftover Processes");
mkpath("$glob_mysql_test_dir/var/log"); # Needed for mysqladmin log
mtr_kill_leftovers();
}
......@@ -1092,52 +1119,28 @@ sub kill_and_cleanup () {
mkpath("$glob_mysql_test_dir/var/tmp");
mkpath($opt_tmpdir);
# FIXME do we really need to create these all, or are they
# created for us when tables are created?
rmtree("$master->[0]->{'path_myddir'}");
mkpath("$master->[0]->{'path_myddir'}/mysql"); # Need to create subdir?!
mkpath("$master->[0]->{'path_myddir'}/mysql");
mkpath("$master->[0]->{'path_myddir'}/test");
rmtree("$master->[1]->{'path_myddir'}");
mkpath("$master->[1]->{'path_myddir'}/mysql"); # Need to create subdir?!
mkpath("$master->[1]->{'path_myddir'}/mysql");
mkpath("$master->[1]->{'path_myddir'}/test");
rmtree("$slave->[0]->{'path_myddir'}");
mkpath("$slave->[0]->{'path_myddir'}/mysql"); # Need to create subdir?!
mkpath("$slave->[0]->{'path_myddir'}/mysql");
mkpath("$slave->[0]->{'path_myddir'}/test");
rmtree("$slave->[1]->{'path_myddir'}");
mkpath("$slave->[1]->{'path_myddir'}/mysql"); # Need to create subdir?!
mkpath("$slave->[1]->{'path_myddir'}/mysql");
mkpath("$slave->[1]->{'path_myddir'}/test");
rmtree("$slave->[2]->{'path_myddir'}");
mkpath("$slave->[2]->{'path_myddir'}/mysql"); # Need to create subdir?!
mkpath("$slave->[2]->{'path_myddir'}/mysql");
mkpath("$slave->[2]->{'path_myddir'}/test");
$opt_wait_for_master= $opt_sleep_time_for_first_master;
$opt_wait_for_slave= $opt_sleep_time_for_first_slave;
}
# FIXME
sub sleep_until_file_created ($$) {
my $pidfile= shift;
my $timeout= shift;
my $loop= $timeout * 2;
while ( $loop-- )
{
if ( -r $pidfile )
{
return;
}
mtr_debug("Sleep for 1 second waiting for creation of $pidfile");
sleep(1);
}
if ( ! -r $pidfile )
{
mtr_error("No $pidfile was created");
}
}
......@@ -1251,11 +1254,11 @@ sub run_suite () {
mtr_print_thick_line();
mtr_report("Finding Tests in $suite suite");
mtr_report("Finding Tests in the '$suite' suite");
my $tests= collect_test_cases($suite);
mtr_report("Starting Tests in $suite suite");
mtr_report("Starting Tests in the '$suite' suite");
mtr_print_header();
......@@ -1412,6 +1415,8 @@ sub run_testcase ($) {
# the preparation.
# ----------------------------------------------------------------------
$ENV{'TZ'}= $tinfo->{'timezone'};
mtr_report_test_name($tinfo);
mtr_tofile($master->[0]->{'path_myerr'},"CURRENT_TEST: $tname\n");
......@@ -1778,6 +1783,7 @@ sub mysqld_arguments ($$$$$) {
}
# FIXME strange,.....
# FIXME MYSQL_MYPORT is not set anythere?!
if ( $opt_local_master )
{
mtr_add_arg($args, "%s--host=127.0.0.1", $prefix);
......@@ -1888,8 +1894,7 @@ sub mysqld_start ($$$$) {
$master->[$idx]->{'path_myerr'}, "") )
{
sleep_until_file_created($master->[$idx]->{'path_mypid'},
$opt_wait_for_master);
$opt_wait_for_master= $opt_sleep_time_for_second_master;
$master->[$idx]->{'start_timeout'});
return $pid;
}
}
......@@ -1901,8 +1906,7 @@ sub mysqld_start ($$$$) {
$slave->[$idx]->{'path_myerr'}, "") )
{
sleep_until_file_created($slave->[$idx]->{'path_mypid'},
$opt_wait_for_slave);
$opt_wait_for_slave= $opt_sleep_time_for_second_slave;
$master->[$idx]->{'start_timeout'});
return $pid;
}
}
......@@ -1970,7 +1974,6 @@ sub run_mysqltest ($$) {
my $tinfo= shift;
my $master_opts= shift;
# FIXME set where????
my $cmdline_mysqldump= "$exe_mysqldump --no-defaults -uroot " .
"--socket=$master->[0]->{'path_mysock'} --password=";
if ( $opt_debug )
......@@ -1992,6 +1995,9 @@ sub run_mysqltest ($$) {
"$exe_mysql --host=localhost --port=$master->[0]->{'path_myport'} " .
"--socket=$master->[0]->{'path_mysock'} --user=root --password=";
# FIXME really needing a PATH???
# $ENV{'PATH'}= "/bin:/usr/bin:/usr/local/bin:/usr/bsd:/usr/X11R6/bin:/usr/openwin/bin:/usr/bin/X11:$ENV{'PATH'}";
$ENV{'MYSQL'}= $exe_mysql;
$ENV{'MYSQL_DUMP'}= $cmdline_mysqldump;
$ENV{'MYSQL_BINLOG'}= $exe_mysqlbinlog;
......
......@@ -973,7 +973,13 @@ start_ndbcluster()
else
NDBCLUSTER_EXTRA_OPTS="--small"
fi
./ndb/ndbcluster $NDBCLUSTER_OPTS $NDBCLUSTER_EXTRA_OPTS --initial || exit 1
NDB_STARTED=1
./ndb/ndbcluster $NDBCLUSTER_OPTS $NDBCLUSTER_EXTRA_OPTS --initial || NDB_STARTED=0
if [ x$NDB_STARTED != x1 ] ; then
if [ x$FORCE != x1 ] ; then
exit 1
fi
fi
NDB_CONNECTSTRING="host=localhost:$NDBCLUSTER_PORT"
else
NDB_CONNECTSTRING="$USE_RUNNING_NDBCLUSTER"
......@@ -1541,6 +1547,12 @@ run_testcase ()
fi
fi
fi
if [ "x$START_AND_EXIT" = "x1" ] ; then
echo "Servers started, exiting"
exit
fi
cd $MYSQL_TEST_DIR
if [ -f $tf ] ; then
......@@ -1676,10 +1688,6 @@ then
mysql_loadstd
fi
if [ "x$START_AND_EXIT" = "x1" ] ; then
echo "Servers started, exiting"
exit
fi
$ECHO "Starting Tests"
......
......@@ -353,11 +353,6 @@ drop table t1;
use test2;
drop table t2;
drop database test2;
show databases;
Database
information_schema
mysql
test
use test;
drop database if exists test_only_ndb_tables;
create database test_only_ndb_tables;
......
......@@ -449,7 +449,6 @@ drop table t1;
use test2;
drop table t2;
drop database test2;
show databases;
use test;
#########################################################
......
......@@ -2976,6 +2976,8 @@ void Dbdih::execCOPY_FRAGREF(Signal* signal)
SystemError * const sysErr = (SystemError*)&signal->theData[0];
sysErr->errorCode = SystemError::CopyFragRefError;
sysErr->errorRef = reference();
sysErr->data1 = errorCode;
sysErr->data2 = 0;
sendSignal(cntrRef, GSN_SYSTEM_ERROR, signal,
SystemError::SignalLength, JBB);
return;
......@@ -4492,6 +4494,8 @@ void Dbdih::handleTakeOverNewMaster(Signal* signal, Uint32 takeOverPtrI)
SystemError * const sysErr = (SystemError*)&signal->theData[0];
sysErr->errorCode = SystemError::CopyFragRefError;
sysErr->errorRef = reference();
sysErr->data1= 0;
sysErr->data2= __LINE__;
sendSignal(cntrRef, GSN_SYSTEM_ERROR, signal,
SystemError::SignalLength, JBB);
}
......
......@@ -315,7 +315,7 @@ ndb_mgm_call(NdbMgmHandle handle, const ParserRow<ParserDummy> *command_reply,
ndbout << "Error in mgm protocol parser. "
<< "cmd: '" << cmd
<< "' status=" << (Uint32)ctx.m_status
<< ", curr=" << (Uint32)ctx.m_currentToken
<< ", curr=" << ctx.m_currentToken
<< endl;
DBUG_PRINT("info",("parser.parse returned NULL"));
}
......
......@@ -973,6 +973,7 @@ inline uint field_in_record_is_null (
int ha_federated::write_row(byte * buf)
{
int x= 0, num_fields= 0;
Field **field;
ulong current_query_id= 1;
ulong tmp_query_id;
int all_fields_have_same_query_id= 1;
......@@ -1021,7 +1022,7 @@ int ha_federated::write_row(byte * buf)
0 if it remains 0, then that means no fields were specified in the query
such as in the case of INSERT INTO table VALUES (val1, val2, valN)
*/
for (Field **field= table->field; *field ; field++, x++)
for (field= table->field; *field ; field++, x++)
{
if (x > 0 && tmp_query_id != (*field)->query_id)
all_fields_have_same_query_id= 0;
......@@ -1032,7 +1033,7 @@ int ha_federated::write_row(byte * buf)
loop through the field pointer array, add any fields to both the values
list and the fields list that match the current query id
*/
for (Field **field= table->field; *field ; field++, x++)
for (field= table->field; *field ; field++, x++)
{
DBUG_PRINT("ha_federated::write_row", ("field type %d", (*field)->type()));
// if there is a query id and if it's equal to the current query id
......
......@@ -4901,7 +4901,8 @@ ndb_get_table_statistics(Ndb* ndb, const char * table,
if (check == -1)
break;
Uint64 rows, commits, size, mem;
Uint64 rows, commits, mem;
Uint32 size;
pOp->getValue(NdbDictionary::Column::ROW_COUNT, (char*)&rows);
pOp->getValue(NdbDictionary::Column::COMMIT_COUNT, (char*)&commits);
pOp->getValue(NdbDictionary::Column::ROW_SIZE, (char*)&size);
......
......@@ -725,7 +725,7 @@ QUICK_RANGE_SELECT::QUICK_RANGE_SELECT(THD *thd, TABLE *table, uint key_nr,
key_part_info= head->key_info[index].key_part;
my_init_dynamic_array(&ranges, sizeof(QUICK_RANGE*), 16, 16);
/* 'thd' is not accessible in QUICK_RANGE_SELECT::get_next_init(). */
/* 'thd' is not accessible in QUICK_RANGE_SELECT::reset(). */
multi_range_bufsiz= thd->variables.read_rnd_buff_size;
multi_range_count= thd->variables.multi_range_count;
multi_range_length= 0;
......@@ -749,9 +749,6 @@ int QUICK_RANGE_SELECT::init()
{
DBUG_ENTER("QUICK_RANGE_SELECT::init");
if ((error= get_next_init()))
DBUG_RETURN(error);
if (file->inited == handler::NONE)
DBUG_RETURN(error= file->ha_index_init(index));
error= 0;
......@@ -5655,9 +5652,8 @@ int QUICK_INDEX_MERGE_SELECT::read_keys_and_merge()
We reuse the same instance of handler so we need to call both init and
reset here.
*/
if (cur_quick->init())
if (cur_quick->init() || cur_quick->reset())
DBUG_RETURN(1);
cur_quick->reset();
unique= new Unique(refpos_order_cmp, (void *)head->file,
head->file->ref_length,
......@@ -5675,10 +5671,8 @@ int QUICK_INDEX_MERGE_SELECT::read_keys_and_merge()
if (cur_quick->file->inited != handler::NONE)
cur_quick->file->ha_index_end();
if (cur_quick->init())
if (cur_quick->init() || cur_quick->reset())
DBUG_RETURN(1);
/* QUICK_RANGE_SELECT::reset never fails */
cur_quick->reset();
}
if (result)
......@@ -5745,9 +5739,8 @@ int QUICK_INDEX_MERGE_SELECT::get_next()
if (pk_quick_select)
{
doing_pk_scan= TRUE;
if ((result= pk_quick_select->init()))
if ((result= pk_quick_select->init()) || (result= pk_quick_select->reset()))
DBUG_RETURN(result);
pk_quick_select->reset();
DBUG_RETURN(pk_quick_select->get_next());
}
}
......@@ -5908,28 +5901,15 @@ int QUICK_ROR_UNION_SELECT::get_next()
DBUG_RETURN(error);
}
/*
Initialize data structures needed by get_next().
SYNOPSIS
QUICK_RANGE_SELECT::get_next_init()
DESCRIPTION
This is called from get_next() at its first call for an object.
It allocates memory buffers and sets size variables.
RETURN
0 OK.
!= 0 Error.
*/
int QUICK_RANGE_SELECT::get_next_init(void)
int QUICK_RANGE_SELECT::reset()
{
uint mrange_bufsiz;
byte *mrange_buff;
DBUG_ENTER("QUICK_RANGE_SELECT::get_next_init");
DBUG_ENTER("QUICK_RANGE_SELECT::reset");
next=0;
range= NULL;
cur_range= (QUICK_RANGE**) ranges.buffer;
/* Do not allocate the buffers twice. */
if (multi_range_length)
{
......@@ -5937,15 +5917,8 @@ int QUICK_RANGE_SELECT::get_next_init(void)
DBUG_RETURN(0);
}
/* If the ranges are not yet initialized, wait for the next call. */
if (! ranges.elements)
{
DBUG_RETURN(0);
}
/*
Allocate the ranges array.
*/
/* Allocate the ranges array. */
DBUG_ASSERT(ranges.elements);
multi_range_length= min(multi_range_count, ranges.elements);
DBUG_ASSERT(multi_range_length > 0);
while (multi_range_length && ! (multi_range= (KEY_MULTI_RANGE*)
......@@ -5962,9 +5935,7 @@ int QUICK_RANGE_SELECT::get_next_init(void)
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
}
/*
Allocate the handler buffer if necessary.
*/
/* Allocate the handler buffer if necessary. */
if (file->table_flags() & HA_NEED_READ_RANGE_BUFFER)
{
mrange_bufsiz= min(multi_range_bufsiz,
......@@ -5992,9 +5963,6 @@ int QUICK_RANGE_SELECT::get_next_init(void)
multi_range_buff->buffer_end= mrange_buff + mrange_bufsiz;
multi_range_buff->end_of_used_area= mrange_buff;
}
/* Initialize the current QUICK_RANGE pointer. */
cur_range= (QUICK_RANGE**) ranges.buffer;
DBUG_RETURN(0);
}
......@@ -7948,10 +7916,10 @@ int QUICK_GROUP_MIN_MAX_SELECT::reset(void)
file->extra(HA_EXTRA_KEYREAD); /* We need only the key attributes */
result= file->ha_index_init(index);
result= file->index_last(record);
if (quick_prefix_select)
quick_prefix_select->reset();
if (result)
DBUG_RETURN(result);
if (quick_prefix_select && quick_prefix_select->reset())
DBUG_RETURN(1);
/* Save the prefix of the last group. */
key_copy(last_prefix, record, index_info, group_prefix_len);
......
......@@ -59,6 +59,44 @@ class QUICK_RANGE :public Sql_alloc {
/*
Quick select interface.
This class is a parent for all QUICK_*_SELECT and FT_SELECT classes.
The usage scenario is as follows:
1. Create quick select
quick= new QUICK_XXX_SELECT(...);
2. Perform lightweight initialization. This can be done in 2 ways:
2.a: Regular initialization
if (quick->init())
{
//the only valid action after failed init() call is delete
delete quick;
}
2.b: Special initialization for quick selects merged by QUICK_ROR_*_SELECT
if (quick->init_ror_merged_scan())
delete quick;
3. Perform zero, one, or more scans.
while (...)
{
// initialize quick select for scan. This may allocate
// buffers and/or prefetch rows.
if (quick->reset())
{
//the only valid action after failed reset() call is delete
delete quick;
//abort query
}
// perform the scan
do
{
res= quick->get_next();
} while (res && ...)
}
4. Delete the select:
delete quick;
*/
class QUICK_SELECT_I
......@@ -117,27 +155,16 @@ class QUICK_SELECT_I
reset() should be called when it is certain that row retrieval will be
necessary. This call may do heavyweight initialization like buffering first
N records etc. If reset() call fails get_next() must not be called.
Note that reset() may be called several times if this quick select
executes in a subselect.
Note that reset() may be called several times if
* the quick select is executed in a subselect
* a JOIN buffer is used
RETURN
0 OK
other Error code
*/
virtual int reset(void) = 0;
/*
Initialize get_next() for row retrieval.
SYNOPSIS
get_next_init()
get_next_init() must be called before the first get_next().
If get_next_init() call fails get_next() must not be called.
RETURN
0 OK
other Error code
*/
virtual int get_next_init() { return false; }
virtual int get_next() = 0; /* get next record to retrieve */
/* Range end should be called when we have looped over the whole index */
......@@ -284,18 +311,7 @@ class QUICK_RANGE_SELECT : public QUICK_SELECT_I
~QUICK_RANGE_SELECT();
int init();
int reset(void)
{
next=0;
range= NULL;
cur_range= (QUICK_RANGE**) ranges.buffer;
/*
Note: in opt_range.cc there are places where it is assumed that this
function always succeeds
*/
return 0;
}
int get_next_init(void);
int reset(void);
int get_next();
void range_end();
int get_next_prefix(uint prefix_length, byte *cur_prefix);
......@@ -310,6 +326,8 @@ class QUICK_RANGE_SELECT : public QUICK_SELECT_I
#ifndef DBUG_OFF
void dbug_dump(int indent, bool verbose);
#endif
private:
/* Used only by QUICK_SELECT_DESC */
QUICK_RANGE_SELECT(const QUICK_RANGE_SELECT& org) : QUICK_SELECT_I()
{
bcopy(&org, this, sizeof(*this));
......@@ -685,6 +703,7 @@ class FT_SELECT: public QUICK_RANGE_SELECT {
QUICK_RANGE_SELECT (thd, table, key, 1) { init(); }
~FT_SELECT() { file->ft_end(); }
int init() { return error=file->ft_init(); }
int reset() { return 0; }
int get_next() { return error=file->ft_read(record); }
int get_type() { return QS_TYPE_FULLTEXT; }
};
......
......@@ -100,19 +100,8 @@ void init_read_record(READ_RECORD *info,THD *thd, TABLE *table,
}
else if (select && select->quick)
{
int error;
DBUG_PRINT("info",("using rr_quick"));
if (!table->file->inited)
table->file->ha_index_init(select->quick->index);
info->read_record=rr_quick;
if ((error= select->quick->get_next_init()))
{
/* Cannot return error code here. Instead print to error log. */
table->file->print_error(error,MYF(ME_NOREFRESH));
thd->fatal_error();
}
}
else if (table->sort.record_pointers)
{
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment