Merge mysql.com:/home/jonas/src/mysql-5.0

into mysql.com:/home/jonas/src/mysql-5.0-ndb


sql/mysqld.cc:
  Auto merged
sql/sql_insert.cc:
  Auto merged
This commit is contained in:
unknown 2005-02-03 17:05:55 +01:00
commit d595ac8df8
83 changed files with 1484 additions and 454 deletions

View file

@ -9,5 +9,5 @@ then
(cd gemini && aclocal && autoheader && aclocal && automake && autoconf) (cd gemini && aclocal && autoheader && aclocal && automake && autoconf)
fi fi
CC=ecc CFLAGS="-w1 -DEXTRA_DEBUG -DSAFEMALLOC -DSAFE_MUTEX -O2" CXX=ecc CXXFLAGS="-w1 -DEXTRA_DEBUG -DSAFEMALLOC -DSAFE_MUTEX -O2" ./configure --prefix=/usr/local/mysql --with-extra-charsets=complex --enable-thread-safe-client --with-mysqld-ldflags=-all-static --with-client-ldflags=-all-static --with-debug --with-innodb --with-embedded-server CC=ecc CFLAGS="-w1 -DEXTRA_DEBUG -DSAFEMALLOC -DSAFE_MUTEX -O2" CXX=ecc CXXFLAGS="-w1 -DEXTRA_DEBUG -DSAFEMALLOC -DSAFE_MUTEX -O2" ./configure --prefix=/usr/local/mysql --with-extra-charsets=complex --enable-thread-safe-client --with-mysqld-ldflags=-all-static --with-client-ldflags=-all-static --with-debug --with-innodb --with-embedded-server --with-archive-storage-engine
gmake gmake

View file

@ -210,10 +210,16 @@ if (-d $target_dir)
} }
else else
{ {
&logger("Renaming $target_dir to $target_dir.old." . $$); # Get the time stamp of "configure.in"
@stat= stat("$target_dir/configure.in");
my $mtime= $stat[9];
my ($sec,$min,$hour,$mday,$mon,$year) = localtime($mtime);
my $mtime= sprintf("%04d-%02d-%02d-%02d:%02d", $year+1900, $mon+1, $mday, $hour, $min);
&logger("Renaming $target_dir to $target_dir-$mtime");
$command= "mv "; $command= "mv ";
$command.= "-v " if ($opt_verbose || defined $opt_log); $command.= "-v " if ($opt_verbose || defined $opt_log);
$command.= "$target_dir $target_dir.old." . $$; $command.= "$target_dir $target_dir-$mtime";
&run_command($command, "Could not rename $target_dir!"); &run_command($command, "Could not rename $target_dir!");
} }
} }

View file

@ -7,7 +7,7 @@ use Sys::Hostname;
@config_options= (); @config_options= ();
@make_options= (); @make_options= ();
$opt_distribution=$opt_user=$opt_config_env=$opt_config_extra_env=""; $opt_comment=$opt_distribution=$opt_user=$opt_config_env=$opt_config_extra_env="";
$opt_dbd_options=$opt_perl_options=$opt_config_options=$opt_make_options=$opt_suffix=""; $opt_dbd_options=$opt_perl_options=$opt_config_options=$opt_make_options=$opt_suffix="";
$opt_tmp=$opt_version_suffix=""; $opt_tmp=$opt_version_suffix="";
$opt_bundled_zlib=$opt_help=$opt_delete=$opt_debug=$opt_stage=$opt_no_test=$opt_no_perl=$opt_one_error=$opt_with_low_memory=$opt_fast_benchmark=$opt_static_client=$opt_static_server=$opt_static_perl=$opt_sur=$opt_with_small_disk=$opt_local_perl=$opt_tcpip=$opt_build_thread=$opt_use_old_distribution=$opt_enable_shared=$opt_no_crash_me=$opt_no_strip=$opt_with_archive=$opt_with_cluster=$opt_with_csv=$opt_with_example=$opt_with_debug=$opt_no_benchmark=$opt_no_mysqltest=$opt_without_embedded=$opt_readline=0; $opt_bundled_zlib=$opt_help=$opt_delete=$opt_debug=$opt_stage=$opt_no_test=$opt_no_perl=$opt_one_error=$opt_with_low_memory=$opt_fast_benchmark=$opt_static_client=$opt_static_server=$opt_static_perl=$opt_sur=$opt_with_small_disk=$opt_local_perl=$opt_tcpip=$opt_build_thread=$opt_use_old_distribution=$opt_enable_shared=$opt_no_crash_me=$opt_no_strip=$opt_with_archive=$opt_with_cluster=$opt_with_csv=$opt_with_example=$opt_with_debug=$opt_no_benchmark=$opt_no_mysqltest=$opt_without_embedded=$opt_readline=0;
@ -17,6 +17,7 @@ GetOptions(
"bdb", "bdb",
"build-thread=i", "build-thread=i",
"bundled-zlib", "bundled-zlib",
"comment=s",
"config-env=s" => \@config_env, "config-env=s" => \@config_env,
"config-extra-env=s" => \@config_extra_env, "config-extra-env=s" => \@config_extra_env,
"config-options=s" => \@config_options, "config-options=s" => \@config_options,
@ -111,6 +112,7 @@ $log="$pwd/Logs/$host-$major.$minor$opt_version_suffix.log";
$opt_distribution =~ /(mysql[^\/]*)\.tar/; $opt_distribution =~ /(mysql[^\/]*)\.tar/;
$ver=$1; $ver=$1;
$gcc_version=which("gcc"); $gcc_version=which("gcc");
$opt_comment= "Official MySQL$opt_version_suffix binary" unless $opt_comment;
if (defined($gcc_version) && ! $opt_config_env) if (defined($gcc_version) && ! $opt_config_env)
{ {
$tmp=`$gcc_version -v 2>&1`; $tmp=`$gcc_version -v 2>&1`;
@ -305,7 +307,7 @@ if ($opt_stage <= 1)
} }
$prefix="/usr/local/mysql"; $prefix="/usr/local/mysql";
check_system("$opt_config_env ./configure --prefix=$prefix --localstatedir=$prefix/data --libexecdir=$prefix/bin --with-comment=\"Official MySQL$opt_version_suffix binary\" --with-extra-charsets=complex --with-server-suffix=\"$opt_version_suffix\" --enable-thread-safe-client --enable-local-infile $opt_config_options","Thank you for choosing MySQL"); check_system("$opt_config_env ./configure --prefix=$prefix --localstatedir=$prefix/data --libexecdir=$prefix/bin --with-comment=\"$opt_comment\" --with-extra-charsets=complex --with-server-suffix=\"$opt_version_suffix\" --enable-thread-safe-client --enable-local-infile $opt_config_options","Thank you for choosing MySQL");
if (-d "$pwd/$host/include-mysql") if (-d "$pwd/$host/include-mysql")
{ {
safe_system("cp -r $pwd/$host/include-mysql/* $pwd/$host/$ver/include"); safe_system("cp -r $pwd/$host/include-mysql/* $pwd/$host/$ver/include");
@ -532,6 +534,10 @@ When running several Do-compile runs in parallel, each build
should have its own thread ID, so running the test suites should have its own thread ID, so running the test suites
does not cause conflicts with duplicate TCP port numbers. does not cause conflicts with duplicate TCP port numbers.
--comment=<comment>
Replace the default compilation comment that is embedded into
the mysqld binary.
--config-env=<environment for configure> --config-env=<environment for configure>
To set up the environment, like 'CC=cc CXX=gcc CXXFLAGS=-O3' To set up the environment, like 'CC=cc CXX=gcc CXXFLAGS=-O3'
@ -689,16 +695,20 @@ sub abort
if ($opt_user) if ($opt_user)
{ {
$mail_header_file="$opt_tmp/do-command.$$"; # Take the last 40 lines of the build log
open(TMP,">$mail_header_file"); open(LOG, "$log") or die $!;
my @log= <LOG>;
close LOG;
splice @log => 0, -40;
my $mail_file="$opt_tmp/do-command.$$";
open(TMP,">$mail_file") or die $!;
print TMP "From: mysqldev\@$full_host_name\n"; print TMP "From: mysqldev\@$full_host_name\n";
print TMP "To: $email\n"; print TMP "To: $email\n";
print TMP "Subject: $host($uname): $ver$opt_version_suffix compilation failed\n\n"; print TMP "Subject: $host($uname): $ver$opt_version_suffix compilation failed\n\n";
print TMP @log;
close TMP; close TMP;
system("tail -n 40 $log > $log.mail"); system("$sendmail -t -f $email < $mail_file");
system("cat $mail_header_file $log.mail | $sendmail -t -f $email"); unlink($mail_file);
unlink($mail_header_file);
unlink("$log.mail");
} }
exit 1; exit 1;
} }

View file

@ -1009,6 +1009,7 @@ static void usage(void)
print_defaults("my",load_default_groups); print_defaults("my",load_default_groups);
puts("\nWhere command is a one or more of: (Commands may be shortened)\n\ puts("\nWhere command is a one or more of: (Commands may be shortened)\n\
create databasename Create a new database\n\ create databasename Create a new database\n\
debug Instruct server to write debug information to log\n\
drop databasename Delete a database and all its tables\n\ drop databasename Delete a database and all its tables\n\
extended-status Gives an extended status message from the server\n\ extended-status Gives an extended status message from the server\n\
flush-hosts Flush all cached hosts\n\ flush-hosts Flush all cached hosts\n\

View file

@ -2195,27 +2195,27 @@ static my_bool dump_all_views_in_db(char *database)
RETURN RETURN
void void
*/ */
static void get_actual_table_name( const char *old_table_name,
char *new_table_name, static void get_actual_table_name(const char *old_table_name,
int buf_size ) char *new_table_name,
int buf_size)
{ {
MYSQL_RES *tableRes; MYSQL_RES *tableRes;
MYSQL_ROW row; MYSQL_ROW row;
char query[ NAME_LEN + 50 ]; char query[ NAME_LEN + 50 ];
DBUG_ENTER("get_actual_table_name");
DBUG_ENTER("get_actual_table_name"); sprintf( query, "SHOW TABLES LIKE '%s'", old_table_name);
if (mysql_query_with_error_report(sock, 0, query))
{
safe_exit(EX_MYSQLERR);
}
sprintf( query, "SHOW TABLES LIKE '%s'", old_table_name ); tableRes= mysql_store_result( sock );
if (mysql_query_with_error_report(sock, 0, query)) row= mysql_fetch_row( tableRes );
{ strmake(new_table_name, row[0], buf_size-1);
safe_exit(EX_MYSQLERR); mysql_free_result(tableRes);
} }
tableRes = mysql_store_result( sock );
row = mysql_fetch_row( tableRes );
strncpy( new_table_name, row[0], buf_size );
mysql_free_result(tableRes);
} /* get_actual_table_name */
static int dump_selected_tables(char *db, char **table_names, int tables) static int dump_selected_tables(char *db, char **table_names, int tables)

View file

@ -218,12 +218,14 @@ int main(int argc,char *argv[])
string 'Unknown Error'. To avoid printing it we try to find the string 'Unknown Error'. To avoid printing it we try to find the
error string by asking for an impossible big error message. error string by asking for an impossible big error message.
*/ */
msg = strerror(10000); msg= strerror(10000);
/* allocate a buffer for unknown_error since strerror always returns the same pointer /*
on some platforms such as Windows */ Allocate a buffer for unknown_error since strerror always returns
unknown_error = malloc( strlen(msg)+1 ); the same pointer on some platforms such as Windows
strcpy( unknown_error, msg ); */
unknown_error= malloc(strlen(msg)+1);
strmov(unknown_error, msg);
for ( ; argc-- > 0 ; argv++) for ( ; argc-- > 0 ; argv++)
{ {
@ -276,7 +278,7 @@ int main(int argc,char *argv[])
/* if we allocated a buffer for unknown_error, free it now */ /* if we allocated a buffer for unknown_error, free it now */
if (unknown_error) if (unknown_error)
free(unknown_error); free(unknown_error);
exit(error); exit(error);
return error; return error;

View file

@ -686,7 +686,9 @@ buf_read_recv_pages(
fprintf(stderr, fprintf(stderr,
"InnoDB: Error: InnoDB has waited for 50 seconds for pending\n" "InnoDB: Error: InnoDB has waited for 50 seconds for pending\n"
"InnoDB: reads to the buffer pool to be finished.\n" "InnoDB: reads to the buffer pool to be finished.\n"
"InnoDB: Number of pending reads %lu\n", (ulong) buf_pool->n_pend_reads); "InnoDB: Number of pending reads %lu, pending pread calls %lu\n",
(ulong) buf_pool->n_pend_reads,
(ulong)os_file_n_pending_preads);
os_aio_print_debug = TRUE; os_aio_print_debug = TRUE;
} }

View file

@ -3013,8 +3013,8 @@ fil_load_single_table_tablespaces(void)
/* printf( /* printf(
" Looking at file %s\n", fileinfo.name); */ " Looking at file %s\n", fileinfo.name); */
if (fileinfo.type == OS_FILE_TYPE_DIR if (fileinfo.type == OS_FILE_TYPE_DIR) {
|| dbinfo.type == OS_FILE_TYPE_UNKNOWN) {
goto next_file_item; goto next_file_item;
} }

View file

@ -279,7 +279,15 @@ rec_get_next_offs(
/* Note that for 64 KiB pages, field_value can 'wrap around' /* Note that for 64 KiB pages, field_value can 'wrap around'
and the debug assertion is not valid */ and the debug assertion is not valid */
ut_ad((int16_t)field_value /* In the following assertion, field_value is interpreted
as signed 16-bit integer in 2's complement arithmetics.
If all platforms defined int16_t in the standard headers,
the expression could be written simpler as
(int16_t) field_value + ut_align_offset(...) < UNIV_PAGE_SIZE
*/
ut_ad((field_value >= 32768
? field_value - 65536
: field_value)
+ ut_align_offset(rec, UNIV_PAGE_SIZE) + ut_align_offset(rec, UNIV_PAGE_SIZE)
< UNIV_PAGE_SIZE); < UNIV_PAGE_SIZE);
#endif #endif

View file

@ -225,6 +225,21 @@ trx_savepoint_for_mysql(
position corresponding to this position corresponding to this
connection at the time of the connection at the time of the
savepoint */ savepoint */
/***********************************************************************
Releases a named savepoint. Savepoints which
were set after this savepoint are deleted. */
ulint
trx_release_savepoint_for_mysql(
/*================================*/
/* out: if no savepoint
of the name found then
DB_NO_SAVEPOINT,
otherwise DB_SUCCESS */
trx_t* trx, /* in: transaction handle */
const char* savepoint_name); /* in: savepoint name */
/*********************************************************************** /***********************************************************************
Frees savepoint structs. */ Frees savepoint structs. */

View file

@ -80,10 +80,6 @@ memory is read outside the allocated blocks. */
/* Make a non-inline debug version */ /* Make a non-inline debug version */
#ifdef DBUG_ON
#define UNIV_DEBUG
#endif /* DBUG_ON */
/* /*
#define UNIV_DEBUG #define UNIV_DEBUG
#define UNIV_MEM_DEBUG #define UNIV_MEM_DEBUG

View file

@ -711,12 +711,12 @@ http://www.mysql.com/doc/en/Windows_symbolic_links.html */
} else if (lpFindFileData->dwFileAttributes } else if (lpFindFileData->dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY) { & FILE_ATTRIBUTE_DIRECTORY) {
info->type = OS_FILE_TYPE_DIR; info->type = OS_FILE_TYPE_DIR;
} else if (lpFindFileData->dwFileAttributes
& FILE_ATTRIBUTE_NORMAL) {
/* TODO: are FILE_ATTRIBUTE_NORMAL files really all normal files? */
info->type = OS_FILE_TYPE_FILE;
} else { } else {
info->type = OS_FILE_TYPE_UNKNOWN; /* It is probably safest to assume that all other
file types are normal. Better to check them rather
than blindly skip them. */
info->type = OS_FILE_TYPE_FILE;
} }
} }
@ -834,7 +834,7 @@ os_file_create_directory(
rcode = CreateDirectory(pathname, NULL); rcode = CreateDirectory(pathname, NULL);
if (!(rcode != 0 || if (!(rcode != 0 ||
(GetLastError() == ERROR_FILE_EXISTS && !fail_if_exists))) { (GetLastError() == ERROR_ALREADY_EXISTS && !fail_if_exists))) {
/* failure */ /* failure */
os_file_handle_error(pathname, "CreateDirectory"); os_file_handle_error(pathname, "CreateDirectory");
@ -918,8 +918,9 @@ try_again:
file = CreateFile(name, file = CreateFile(name,
access, access,
FILE_SHARE_READ,/* file can be read also by other FILE_SHARE_READ | FILE_SHARE_WRITE,
processes */ /* file can be read ansd written also
by other processes */
NULL, /* default security attributes */ NULL, /* default security attributes */
create_flag, create_flag,
attributes, attributes,
@ -1024,7 +1025,7 @@ os_file_create_simple_no_error_handling(
DWORD create_flag; DWORD create_flag;
DWORD access; DWORD access;
DWORD attributes = 0; DWORD attributes = 0;
DWORD share_mode = FILE_SHARE_READ; DWORD share_mode = FILE_SHARE_READ | FILE_SHARE_WRITE;
ut_a(name); ut_a(name);
@ -1347,7 +1348,7 @@ loop:
return(TRUE); return(TRUE);
} }
if (GetLastError() == ERROR_PATH_NOT_FOUND) { if (GetLastError() == ERROR_FILE_NOT_FOUND) {
/* the file does not exist, this not an error */ /* the file does not exist, this not an error */
return(TRUE); return(TRUE);
@ -1408,7 +1409,7 @@ loop:
return(TRUE); return(TRUE);
} }
if (GetLastError() == ERROR_PATH_NOT_FOUND) { if (GetLastError() == ERROR_FILE_NOT_FOUND) {
/* If the file does not exist, we classify this as a 'mild' /* If the file does not exist, we classify this as a 'mild'
error and return */ error and return */

View file

@ -51,14 +51,19 @@ innobase_invalidate_query_cache(
chars count */ chars count */
/********************************************************************** /**********************************************************************
This function returns true if SQL-query in the current thread This function returns true if
1) SQL-query in the current thread
is either REPLACE or LOAD DATA INFILE REPLACE. is either REPLACE or LOAD DATA INFILE REPLACE.
2) SQL-query in the current thread
is INSERT ON DUPLICATE KEY UPDATE.
NOTE that /mysql/innobase/row/row0ins.c must contain the NOTE that /mysql/innobase/row/row0ins.c must contain the
prototype for this function ! */ prototype for this function ! */
ibool ibool
innobase_query_is_replace(void); innobase_query_is_update(void);
/*===========================*/
/************************************************************************* /*************************************************************************
Creates an insert node struct. */ Creates an insert node struct. */
@ -1597,12 +1602,12 @@ row_ins_scan_sec_index_for_duplicate(
offsets = rec_get_offsets(rec, index, offsets, offsets = rec_get_offsets(rec, index, offsets,
ULINT_UNDEFINED, &heap); ULINT_UNDEFINED, &heap);
if (innobase_query_is_replace()) { if (innobase_query_is_update()) {
/* The manual defines the REPLACE semantics that it /* If the SQL-query will update or replace
is either an INSERT or DELETE(s) for duplicate key duplicate key we will take X-lock for
+ INSERT. Therefore, we should take X-lock for duplicates ( REPLACE, LOAD DATAFILE REPLACE,
duplicates */ INSERT ON DUPLICATE KEY UPDATE). */
err = row_ins_set_exclusive_rec_lock(LOCK_ORDINARY, err = row_ins_set_exclusive_rec_lock(LOCK_ORDINARY,
rec, index, offsets, thr); rec, index, offsets, thr);
@ -1720,12 +1725,12 @@ row_ins_duplicate_error_in_clust(
sure that in roll-forward we get the same duplicate sure that in roll-forward we get the same duplicate
errors as in original execution */ errors as in original execution */
if (innobase_query_is_replace()) { if (innobase_query_is_update()) {
/* The manual defines the REPLACE semantics /* If the SQL-query will update or replace
that it is either an INSERT or DELETE(s) duplicate key we will take X-lock for
for duplicate key + INSERT. Therefore, we duplicates ( REPLACE, LOAD DATAFILE REPLACE,
should take X-lock for duplicates */ INSERT ON DUPLICATE KEY UPDATE). */
err = row_ins_set_exclusive_rec_lock( err = row_ins_set_exclusive_rec_lock(
LOCK_REC_NOT_GAP,rec,cursor->index, LOCK_REC_NOT_GAP,rec,cursor->index,
@ -1759,12 +1764,12 @@ row_ins_duplicate_error_in_clust(
offsets = rec_get_offsets(rec, cursor->index, offsets, offsets = rec_get_offsets(rec, cursor->index, offsets,
ULINT_UNDEFINED, &heap); ULINT_UNDEFINED, &heap);
/* The manual defines the REPLACE semantics that it if (innobase_query_is_update()) {
is either an INSERT or DELETE(s) for duplicate key
+ INSERT. Therefore, we should take X-lock for
duplicates. */
if (innobase_query_is_replace()) { /* If the SQL-query will update or replace
duplicate key we will take X-lock for
duplicates ( REPLACE, LOAD DATAFILE REPLACE,
INSERT ON DUPLICATE KEY UPDATE). */
err = row_ins_set_exclusive_rec_lock( err = row_ins_set_exclusive_rec_lock(
LOCK_REC_NOT_GAP, rec, LOCK_REC_NOT_GAP, rec,

View file

@ -316,6 +316,51 @@ trx_savepoint_for_mysql(
return(DB_SUCCESS); return(DB_SUCCESS);
} }
/***********************************************************************
Releases a named savepoint. Savepoints which
were set after this savepoint are deleted. */
ulint
trx_release_savepoint_for_mysql(
/*================================*/
/* out: if no savepoint
of the name found then
DB_NO_SAVEPOINT,
otherwise DB_SUCCESS */
trx_t* trx, /* in: transaction handle */
const char* savepoint_name) /* in: savepoint name */
{
trx_named_savept_t* savep;
savep = UT_LIST_GET_FIRST(trx->trx_savepoints);
while (savep != NULL) {
if (0 == ut_strcmp(savep->name, savepoint_name)) {
/* Found */
break;
}
savep = UT_LIST_GET_NEXT(trx_savepoints, savep);
}
if (savep == NULL) {
return(DB_NO_SAVEPOINT);
}
/* We can now free all savepoints strictly later than this one */
trx_roll_savepoints_free(trx, savep);
/* Now we can free this savepoint too */
UT_LIST_REMOVE(trx_savepoints, trx->trx_savepoints, savep);
mem_free(savep->name);
mem_free(savep);
return(DB_SUCCESS);
}
/*********************************************************************** /***********************************************************************
Returns a transaction savepoint taken at this point in time. */ Returns a transaction savepoint taken at this point in time. */

View file

@ -44,13 +44,13 @@ ut_get_high32(
/* out: a >> 32 */ /* out: a >> 32 */
ulint a) /* in: ulint */ ulint a) /* in: ulint */
{ {
#if SIZEOF_LONG == 4 ib_longlong i;
UT_NOT_USED(a);
return 0; i = (ib_longlong)a;
#else
return(a >> 32); i = i >> 32;
#endif
return((ulint)i);
} }
/************************************************************ /************************************************************

View file

@ -500,6 +500,7 @@ export MASTER_MYPORT MASTER_MYPORT1 SLAVE_MYPORT MYSQL_TCP_PORT MASTER_MYSOCK MA
NDBCLUSTER_BASE_PORT=`expr $NDBCLUSTER_PORT + 2` NDBCLUSTER_BASE_PORT=`expr $NDBCLUSTER_PORT + 2`
NDBCLUSTER_OPTS="--port=$NDBCLUSTER_PORT --port-base=$NDBCLUSTER_BASE_PORT --data-dir=$MYSQL_TEST_DIR/var --ndb_mgm-extra-opts=$NDB_MGM_EXTRA_OPTS --ndb_mgmd-extra-opts=$NDB_MGMD_EXTRA_OPTS --ndbd-extra-opts=$NDBD_EXTRA_OPTS" NDBCLUSTER_OPTS="--port=$NDBCLUSTER_PORT --port-base=$NDBCLUSTER_BASE_PORT --data-dir=$MYSQL_TEST_DIR/var --ndb_mgm-extra-opts=$NDB_MGM_EXTRA_OPTS --ndb_mgmd-extra-opts=$NDB_MGMD_EXTRA_OPTS --ndbd-extra-opts=$NDBD_EXTRA_OPTS"
NDB_BACKUP_DIR=$MYSQL_TEST_DIR/var/ndbcluster-$NDBCLUSTER_PORT NDB_BACKUP_DIR=$MYSQL_TEST_DIR/var/ndbcluster-$NDBCLUSTER_PORT
NDB_TOOLS_OUTPUT=$MYSQL_TEST_DIR/var/log/ndb_tools.log
if [ x$SOURCE_DIST = x1 ] ; then if [ x$SOURCE_DIST = x1 ] ; then
MY_BASEDIR=$MYSQL_TEST_DIR MY_BASEDIR=$MYSQL_TEST_DIR
@ -700,6 +701,7 @@ export CLIENT_BINDIR MYSQL_CLIENT_TEST CHARSETSDIR
export NDB_TOOLS_DIR export NDB_TOOLS_DIR
export NDB_MGM export NDB_MGM
export NDB_BACKUP_DIR export NDB_BACKUP_DIR
export NDB_TOOLS_OUTPUT
export PURIFYOPTIONS export PURIFYOPTIONS
MYSQL_TEST_ARGS="--no-defaults --socket=$MASTER_MYSOCK --database=$DB \ MYSQL_TEST_ARGS="--no-defaults --socket=$MASTER_MYSOCK --database=$DB \
@ -1071,6 +1073,7 @@ start_ndbcluster()
{ {
if [ ! -z "$USE_NDBCLUSTER" ] if [ ! -z "$USE_NDBCLUSTER" ]
then then
rm -f $NDB_TOOLS_OUTPUT
if [ -z "$USE_RUNNING_NDBCLUSTER" ] if [ -z "$USE_RUNNING_NDBCLUSTER" ]
then then
echo "Starting ndbcluster" echo "Starting ndbcluster"

View file

@ -39,3 +39,6 @@ DROP TABLE t1;
SELECT CHAR(31) = '', '' = CHAR(31); SELECT CHAR(31) = '', '' = CHAR(31);
CHAR(31) = '' '' = CHAR(31) CHAR(31) = '' '' = CHAR(31)
0 0 0 0
SELECT CHAR(30) = '', '' = CHAR(30);
CHAR(30) = '' '' = CHAR(30)
0 0

View file

@ -330,6 +330,15 @@ SELECT MIN(price) min, MAX(price) max, AVG(price) avg FROM (SELECT SUBSTRING( MA
min max avg min max avg
10.00 10.00 10 10.00 10.00 10
DROP TABLE t1; DROP TABLE t1;
create table t1 (a integer, b integer);
insert into t1 values (1,4), (2,2),(2,2), (4,1),(4,1),(4,1),(4,1);
select distinct sum(b) from t1 group by a;
sum(b)
4
select distinct sum(b) from (select a,b from t1) y group by a;
sum(b)
4
drop table t1;
CREATE TABLE t1 (a char(10), b char(10)); CREATE TABLE t1 (a char(10), b char(10));
INSERT INTO t1 VALUES ('root','localhost'), ('root','%'); INSERT INTO t1 VALUES ('root','localhost'), ('root','%');
SELECT * FROM (SELECT (SELECT a.a FROM t1 AS a WHERE a.a = b.a) FROM t1 AS b) AS c; SELECT * FROM (SELECT (SELECT a.a FROM t1 AS a WHERE a.a = b.a) FROM t1 AS b) AS c;

View file

@ -328,6 +328,19 @@ trim(trailing 'foo' from 'foo')
select trim(leading 'foo' from 'foo'); select trim(leading 'foo' from 'foo');
trim(leading 'foo' from 'foo') trim(leading 'foo' from 'foo')
select quote(ltrim(concat(' ', 'a')));
quote(ltrim(concat(' ', 'a')))
'a'
select quote(trim(concat(' ', 'a')));
quote(trim(concat(' ', 'a')))
'a'
CREATE TABLE t1 SELECT 1 UNION SELECT 2 UNION SELECT 3;
SELECT QUOTE('A') FROM t1;
QUOTE('A')
'A'
'A'
'A'
DROP TABLE t1;
select 1=_latin1'1'; select 1=_latin1'1';
1=_latin1'1' 1=_latin1'1'
1 1
@ -694,12 +707,6 @@ select count(*) as total, left(c,10) as reg from t1 group by reg order by reg de
total reg total reg
10 2004-12-10 10 2004-12-10
drop table t1; drop table t1;
select quote(ltrim(concat(' ', 'a')));
quote(ltrim(concat(' ', 'a')))
'a'
select quote(trim(concat(' ', 'a')));
quote(trim(concat(' ', 'a')))
'a'
select trim(null from 'kate') as "must_be_null"; select trim(null from 'kate') as "must_be_null";
must_be_null must_be_null
NULL NULL
@ -712,3 +719,26 @@ NULL
select trim(trailing NULL from 'xyz') as "must_be_null"; select trim(trailing NULL from 'xyz') as "must_be_null";
must_be_null must_be_null
NULL NULL
CREATE TABLE t1 (
id int(11) NOT NULL auto_increment,
a bigint(20) unsigned default NULL,
PRIMARY KEY (id)
) ENGINE=MyISAM;
INSERT INTO t1 VALUES
('0','16307858876001849059');
SELECT CONV('e251273eb74a8ee3', 16, 10);
CONV('e251273eb74a8ee3', 16, 10)
16307858876001849059
EXPLAIN
SELECT id
FROM t1
WHERE a = 16307858876001849059;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 system NULL NULL NULL NULL 1
EXPLAIN
SELECT id
FROM t1
WHERE a = CONV('e251273eb74a8ee3', 16, 10);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 system NULL NULL NULL NULL 1
DROP TABLE t1;

View file

@ -371,11 +371,11 @@ alter table t0 add filler1 char(200), add filler2 char(200), add filler3 char(20
update t0 set key2=1, key3=1, key4=1, key5=1,key6=1,key7=1 where key7 < 500; update t0 set key2=1, key3=1, key4=1, key5=1,key6=1,key7=1 where key7 < 500;
explain select max(A.key1 + B.key1 + A.key2 + B.key2 + A.key3 + B.key3 + A.key4 + B.key4 + A.key5 + B.key5) explain select max(A.key1 + B.key1 + A.key2 + B.key2 + A.key3 + B.key3 + A.key4 + B.key4 + A.key5 + B.key5)
from t0 as A, t0 as B from t0 as A, t0 as B
where (A.key1 = 1 and A.key2 = 1 and A.key3 = 1 and A.key4=1 and A.key5=1 and A.key6=1 and A.key7 = 1 or A.key8=1) where (A.key1 = 1 and A.key2 = 1 and A.key3 = 1 and A.key4=1 and A.key5=1 and A.key6=1 and A.key7or16 = 1 or A.key8=1)
and (B.key1 = 1 and B.key2 = 1 and B.key3 = 1 and B.key4=1 and B.key5=1 and B.key6=1 and B.key7 = 1 or B.key8=1); and (B.key1 = 1 and B.key2 = 1 and B.key3 = 1 and B.key4=1 and B.key5=1 and B.key6=1 and B.key7or16 = 1 or B.key8=1);
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE A index_merge i1,i2,i3,i4,i5,i6,i7,i8 i2,i3,i4,i5,i6,i8 4,4,4,4,4,4 NULL 16 Using union(intersect(i2,i3,i4,i5,i6),i8); Using where 1 SIMPLE A index_merge i1,i2,i3,i4,i5,i6,i7?,i8 i2,i3,i4,i5,i6,i7?,i8 X NULL 7or16 Using union(intersect(i2,i3,i4,i5,i6,i7?),i8); Using where
1 SIMPLE B index_merge i1,i2,i3,i4,i5,i6,i7,i8 i2,i3,i4,i5,i6,i8 4,4,4,4,4,4 NULL 16 Using union(intersect(i2,i3,i4,i5,i6),i8); Using where 1 SIMPLE B index_merge i1,i2,i3,i4,i5,i6,i7?,i8 i2,i3,i4,i5,i6,i7?,i8 X NULL 7or16 Using union(intersect(i2,i3,i4,i5,i6,i7?),i8); Using where
select max(A.key1 + B.key1 + A.key2 + B.key2 + A.key3 + B.key3 + A.key4 + B.key4 + A.key5 + B.key5) select max(A.key1 + B.key1 + A.key2 + B.key2 + A.key3 + B.key3 + A.key4 + B.key4 + A.key5 + B.key5)
from t0 as A, t0 as B from t0 as A, t0 as B
where (A.key1 = 1 and A.key2 = 1 and A.key3 = 1 and A.key4=1 and A.key5=1 and A.key6=1 and A.key7 = 1 or A.key8=1) where (A.key1 = 1 and A.key2 = 1 and A.key3 = 1 and A.key4=1 and A.key5=1 and A.key6=1 and A.key7 = 1 or A.key8=1)

View file

@ -249,6 +249,30 @@ n
4 4
5 5
6 6
set autocommit=0;
begin;
savepoint `my_savepoint`;
insert into t1 values (7);
savepoint `savept2`;
insert into t1 values (3);
select n from t1;
n
3
4
5
6
7
rollback to savepoint `savept2`;
release savepoint `my_savepoint`;
select n from t1;
n
4
5
6
7
rollback to savepoint `my_savepoint`;
ERROR HY000: Got error 153 during ROLLBACK
set autocommit=1;
rollback; rollback;
drop table t1; drop table t1;
create table t1 (n int not null primary key) engine=innodb; create table t1 (n int not null primary key) engine=innodb;
@ -1609,14 +1633,14 @@ t2 CREATE TABLE `t2` (
drop table t2, t1; drop table t2, t1;
show status like "binlog_cache_use"; show status like "binlog_cache_use";
Variable_name Value Variable_name Value
Binlog_cache_use 24 Binlog_cache_use 25
show status like "binlog_cache_disk_use"; show status like "binlog_cache_disk_use";
Variable_name Value Variable_name Value
Binlog_cache_disk_use 0 Binlog_cache_disk_use 0
create table t1 (a int) engine=innodb; create table t1 (a int) engine=innodb;
show status like "binlog_cache_use"; show status like "binlog_cache_use";
Variable_name Value Variable_name Value
Binlog_cache_use 25 Binlog_cache_use 26
show status like "binlog_cache_disk_use"; show status like "binlog_cache_disk_use";
Variable_name Value Variable_name Value
Binlog_cache_disk_use 1 Binlog_cache_disk_use 1
@ -1625,7 +1649,7 @@ delete from t1;
commit; commit;
show status like "binlog_cache_use"; show status like "binlog_cache_use";
Variable_name Value Variable_name Value
Binlog_cache_use 26 Binlog_cache_use 27
show status like "binlog_cache_disk_use"; show status like "binlog_cache_disk_use";
Variable_name Value Variable_name Value
Binlog_cache_disk_use 1 Binlog_cache_disk_use 1
@ -1693,10 +1717,10 @@ Variable_name Value
Innodb_rows_deleted 2070 Innodb_rows_deleted 2070
show status like "Innodb_rows_inserted"; show status like "Innodb_rows_inserted";
Variable_name Value Variable_name Value
Innodb_rows_inserted 31706 Innodb_rows_inserted 31708
show status like "Innodb_rows_read"; show status like "Innodb_rows_read";
Variable_name Value Variable_name Value
Innodb_rows_read 80153 Innodb_rows_read 80162
show status like "Innodb_rows_updated"; show status like "Innodb_rows_updated";
Variable_name Value Variable_name Value
Innodb_rows_updated 29530 Innodb_rows_updated 29530

View file

@ -2168,3 +2168,51 @@ ERROR 42S22: Unknown column 'a2' in 'scalar IN/ALL/ANY subquery'
select * from t1 where a1 > any(select b1 from t2); select * from t1 where a1 > any(select b1 from t2);
a1 a1
drop table t1,t2; drop table t1,t2;
create table t1 (a integer, b integer);
select (select * from t1) = (select 1,2);
(select * from t1) = (select 1,2)
NULL
select (select 1,2) = (select * from t1);
(select 1,2) = (select * from t1)
NULL
select row(1,2) = ANY (select * from t1);
row(1,2) = ANY (select * from t1)
0
select row(1,2) != ALL (select * from t1);
row(1,2) != ALL (select * from t1)
1
drop table t1;
create table t1 (a integer, b integer);
select row(1,(2,2)) in (select * from t1 );
ERROR 21000: Operand should contain 2 column(s)
select row(1,(2,2)) = (select * from t1 );
ERROR 21000: Operand should contain 2 column(s)
select (select * from t1) = row(1,(2,2));
ERROR 21000: Operand should contain 1 column(s)
drop table t1;
create table t1 (a integer);
insert into t1 values (1);
select 1 = ALL (select 1 from t1 where 1 = xx ), 1 as xx ;
ERROR 42S22: Reference 'xx' not supported (forward reference in item list)
select 1 = ALL (select 1 from t1 where 1 = xx ), 1 as xx;
ERROR 42S22: Reference 'xx' not supported (forward reference in item list)
select 1 as xx, 1 = ALL ( select 1 from t1 where 1 = xx );
xx 1 = ALL ( select 1 from t1 where 1 = xx )
1 1
select 1 = ALL (select 1 from t1 where 1 = xx ), 1 as xx;
ERROR 42S22: Reference 'xx' not supported (forward reference in item list)
select 1 = ALL (select 1 from t1 where 1 = xx ), 1 as xx from DUAL;
ERROR 42S22: Reference 'xx' not supported (forward reference in item list)
drop table t1;
CREATE TABLE `t1` ( `a` char(3) NOT NULL default '', `b` char(3) NOT NULL default '', `c` char(3) NOT NULL default '', PRIMARY KEY (`a`,`b`,`c`)) ENGINE=InnoDB;
CREATE TABLE t2 LIKE t1;
INSERT INTO t1 VALUES (1,1,1);
INSERT INTO t2 VALUES (1,1,1);
PREPARE my_stmt FROM "SELECT t1.b, count(*) FROM t1 group by t1.b having
count(*) > ALL (SELECT COUNT(*) FROM t2 WHERE t2.a=1 GROUP By t2.b)";
EXECUTE my_stmt;
b count(*)
EXECUTE my_stmt;
b count(*)
deallocate prepare my_stmt;
drop table t1,t2;

View file

@ -33,3 +33,5 @@ DROP TABLE t1;
# Bug #8134: Comparison against CHAR(31) at end of string # Bug #8134: Comparison against CHAR(31) at end of string
SELECT CHAR(31) = '', '' = CHAR(31); SELECT CHAR(31) = '', '' = CHAR(31);
# Extra test
SELECT CHAR(30) = '', '' = CHAR(30);

View file

@ -214,6 +214,16 @@ insert into t1 values (128, 'rozn', 2, now(), 10),(128, 'rozn', 1, now(), 10);
SELECT MIN(price) min, MAX(price) max, AVG(price) avg FROM (SELECT SUBSTRING( MAX(concat(date_,";",price)), 12) price FROM t1 WHERE itemid=128 AND grpid='rozn' GROUP BY itemid, grpid, vendor) lastprices; SELECT MIN(price) min, MAX(price) max, AVG(price) avg FROM (SELECT SUBSTRING( MAX(concat(date_,";",price)), 12) price FROM t1 WHERE itemid=128 AND grpid='rozn' GROUP BY itemid, grpid, vendor) lastprices;
DROP TABLE t1; DROP TABLE t1;
#
# DISTINCT over grouped select on subquery in the FROM clause
#
create table t1 (a integer, b integer);
insert into t1 values (1,4), (2,2),(2,2), (4,1),(4,1),(4,1),(4,1);
select distinct sum(b) from t1 group by a;
select distinct sum(b) from (select a,b from t1) y group by a;
drop table t1;
# #
# Test for bug #7413 "Subquery with non-scalar results participating in # Test for bug #7413 "Subquery with non-scalar results participating in
# select list of derived table crashes server" aka "VIEW with sub query can # select list of derived table crashes server" aka "VIEW with sub query can

View file

@ -196,6 +196,18 @@ select trim(trailing 'foo' from 'foo');
select trim(leading 'foo' from 'foo'); select trim(leading 'foo' from 'foo');
# #
# crashing bug with QUOTE() and LTRIM() or TRIM() fixed
# Bug #7495
#
select quote(ltrim(concat(' ', 'a')));
select quote(trim(concat(' ', 'a')));
# Bad results from QUOTE(). Bug #8248
CREATE TABLE t1 SELECT 1 UNION SELECT 2 UNION SELECT 3;
SELECT QUOTE('A') FROM t1;
DROP TABLE t1;
# Test collation and coercibility # Test collation and coercibility
# #
@ -430,12 +442,6 @@ create table t1 (a int not null primary key, b varchar(40), c datetime);
insert into t1 (a,b,c) values (1,'Tom','2004-12-10 12:13:14'),(2,'ball games','2004-12-10 12:13:14'), (3,'Basil','2004-12-10 12:13:14'), (4,'Dean','2004-12-10 12:13:14'),(5,'Ellis','2004-12-10 12:13:14'), (6,'Serg','2004-12-10 12:13:14'), (7,'Sergei','2004-12-10 12:13:14'),(8,'Georg','2004-12-10 12:13:14'),(9,'Salle','2004-12-10 12:13:14'),(10,'Sinisa','2004-12-10 12:13:14'); insert into t1 (a,b,c) values (1,'Tom','2004-12-10 12:13:14'),(2,'ball games','2004-12-10 12:13:14'), (3,'Basil','2004-12-10 12:13:14'), (4,'Dean','2004-12-10 12:13:14'),(5,'Ellis','2004-12-10 12:13:14'), (6,'Serg','2004-12-10 12:13:14'), (7,'Sergei','2004-12-10 12:13:14'),(8,'Georg','2004-12-10 12:13:14'),(9,'Salle','2004-12-10 12:13:14'),(10,'Sinisa','2004-12-10 12:13:14');
select count(*) as total, left(c,10) as reg from t1 group by reg order by reg desc limit 0,12; select count(*) as total, left(c,10) as reg from t1 group by reg order by reg desc limit 0,12;
drop table t1; drop table t1;
# crashing bug with QUOTE() and LTRIM() or TRIM() fixed
# Bug #7495
#
select quote(ltrim(concat(' ', 'a')));
select quote(trim(concat(' ', 'a')));
# #
# Bug#7455 unexpected result: TRIM(<NULL> FROM <whatever>) gives NOT NULL # Bug#7455 unexpected result: TRIM(<NULL> FROM <whatever>) gives NOT NULL
@ -446,3 +452,30 @@ select trim(null from 'kate') as "must_be_null";
select trim('xyz' from null) as "must_be_null"; select trim('xyz' from null) as "must_be_null";
select trim(leading NULL from 'kate') as "must_be_null"; select trim(leading NULL from 'kate') as "must_be_null";
select trim(trailing NULL from 'xyz') as "must_be_null"; select trim(trailing NULL from 'xyz') as "must_be_null";
#
# Bug #7751 - conversion for a bigint unsigned constant
#
CREATE TABLE t1 (
id int(11) NOT NULL auto_increment,
a bigint(20) unsigned default NULL,
PRIMARY KEY (id)
) ENGINE=MyISAM;
INSERT INTO t1 VALUES
('0','16307858876001849059');
SELECT CONV('e251273eb74a8ee3', 16, 10);
EXPLAIN
SELECT id
FROM t1
WHERE a = 16307858876001849059;
EXPLAIN
SELECT id
FROM t1
WHERE a = CONV('e251273eb74a8ee3', 16, 10);
DROP TABLE t1;

View file

@ -306,6 +306,11 @@ select max(A.key1 + B.key1 + A.key2 + B.key2 + A.key3 + B.key3 + A.key4 + B.key4
alter table t0 add filler1 char(200), add filler2 char(200), add filler3 char(200); alter table t0 add filler1 char(200), add filler2 char(200), add filler3 char(200);
update t0 set key2=1, key3=1, key4=1, key5=1,key6=1,key7=1 where key7 < 500; update t0 set key2=1, key3=1, key4=1, key5=1,key6=1,key7=1 where key7 < 500;
# The next query will not use index i7 in intersection if the OS doesn't
# support file sizes > 2GB. (ha_myisam::ref_length depends on this and index
# scan cost estimates depend on ha_myisam::ref_length)
--replace_result "4,4,4,4,4,4,4" X "4,4,4,4,4,4" X "i6,i7" "i6,i7?" "i6" "i6,i7?" 7 7or16 16 7or16
explain select max(A.key1 + B.key1 + A.key2 + B.key2 + A.key3 + B.key3 + A.key4 + B.key4 + A.key5 + B.key5) explain select max(A.key1 + B.key1 + A.key2 + B.key2 + A.key3 + B.key3 + A.key4 + B.key4 + A.key5 + B.key5)
from t0 as A, t0 as B from t0 as A, t0 as B
where (A.key1 = 1 and A.key2 = 1 and A.key3 = 1 and A.key4=1 and A.key5=1 and A.key6=1 and A.key7 = 1 or A.key8=1) where (A.key1 = 1 and A.key2 = 1 and A.key3 = 1 and A.key4=1 and A.key5=1 and A.key6=1 and A.key7 = 1 or A.key8=1)

View file

@ -129,6 +129,19 @@ insert into t1 values (6);
-- error 1062 -- error 1062
insert into t1 values (4); insert into t1 values (4);
select n from t1; select n from t1;
set autocommit=0;
begin;
savepoint `my_savepoint`;
insert into t1 values (7);
savepoint `savept2`;
insert into t1 values (3);
select n from t1;
rollback to savepoint `savept2`;
release savepoint `my_savepoint`;
select n from t1;
-- error 1181
rollback to savepoint `my_savepoint`;
set autocommit=1;
# nop # nop
rollback; rollback;
drop table t1; drop table t1;

View file

@ -199,7 +199,7 @@ insert into t4 values (1, "Automatic");
select * from t4; select * from t4;
# Remove the table from NDB # Remove the table from NDB
system exec $NDB_TOOLS_DIR/ndb_drop_table --no-defaults -d test t4 > /dev/null ; system exec $NDB_TOOLS_DIR/ndb_drop_table --no-defaults -d test t4 >> $NDB_TOOLS_OUTPUT ;
# #
# Test that correct error is returned # Test that correct error is returned
@ -230,7 +230,7 @@ select * from t4;
flush tables; flush tables;
# Remove the table from NDB # Remove the table from NDB
system exec $NDB_TOOLS_DIR/ndb_drop_table --no-defaults -d test t4 > /dev/null ; system exec $NDB_TOOLS_DIR/ndb_drop_table --no-defaults -d test t4 >> $NDB_TOOLS_OUTPUT ;
SHOW TABLES; SHOW TABLES;
@ -264,8 +264,8 @@ insert into t8 values (8, "myisam table 8");
insert into t9 values (9); insert into t9 values (9);
# Remove t3, t5 from NDB # Remove t3, t5 from NDB
system exec $NDB_TOOLS_DIR/ndb_drop_table --no-defaults -d test t3 > /dev/null ; system exec $NDB_TOOLS_DIR/ndb_drop_table --no-defaults -d test t3 >> $NDB_TOOLS_OUTPUT ;
system exec $NDB_TOOLS_DIR/ndb_drop_table --no-defaults -d test t5 > /dev/null ; system exec $NDB_TOOLS_DIR/ndb_drop_table --no-defaults -d test t5 >> $NDB_TOOLS_OUTPUT ;
# Remove t6, t7 from disk # Remove t6, t7 from disk
system rm var/master-data/test/t6.frm > /dev/null ; system rm var/master-data/test/t6.frm > /dev/null ;
system rm var/master-data/test/t7.frm > /dev/null ; system rm var/master-data/test/t7.frm > /dev/null ;
@ -498,4 +498,4 @@ create table t10 (
insert into t10 values (1, 'kalle'); insert into t10 values (1, 'kalle');
--exec $NDB_TOOLS_DIR/ndb_drop_table --no-defaults -d test `$NDB_TOOLS_DIR/ndb_show_tables --no-defaults | grep BLOB` > /dev/null 2>&1 || true --exec $NDB_TOOLS_DIR/ndb_drop_table --no-defaults -d test `$NDB_TOOLS_DIR/ndb_show_tables --no-defaults | grep BLOB` >> $NDB_TOOLS_OUTPUT 2>&1 || true

View file

@ -142,10 +142,10 @@ create table t8_c engine=ndbcluster as select * from t8;
create table t9_c engine=ndbcluster as select * from t9; create table t9_c engine=ndbcluster as select * from t9;
--exec $NDB_MGM --no-defaults -e "start backup" > /dev/null --exec $NDB_MGM --no-defaults -e "start backup" >> $NDB_TOOLS_OUTPUT
drop table t1_c,t2_c,t3_c,t4_c,t5_c,t6_c,t7_c,t8_c,t9_c; drop table t1_c,t2_c,t3_c,t4_c,t5_c,t6_c,t7_c,t8_c,t9_c;
--exec $NDB_TOOLS_DIR/ndb_restore --no-defaults -b 1 -n 1 -m -r --print --print_meta $NDB_BACKUP_DIR/BACKUP/BACKUP-1 > /tmp/ndb_restore.out --exec $NDB_TOOLS_DIR/ndb_restore --no-defaults -b 1 -n 1 -m -r --print --print_meta $NDB_BACKUP_DIR/BACKUP/BACKUP-1 >> $NDB_TOOLS_OUTPUT
--exec $NDB_TOOLS_DIR/ndb_restore --no-defaults -b 1 -n 2 -r --print --print_meta $NDB_BACKUP_DIR/BACKUP/BACKUP-1 > /tmp/ndb_restore.out --exec $NDB_TOOLS_DIR/ndb_restore --no-defaults -b 1 -n 2 -r --print --print_meta $NDB_BACKUP_DIR/BACKUP/BACKUP-1 >> $NDB_TOOLS_OUTPUT
show tables; show tables;

View file

@ -1419,8 +1419,11 @@ SELECT f1 FROM t1
WHERE f1 <> ALL ( SELECT SUM(f1) AS sf1 FROM t2 HAVING sf1 > 10000); WHERE f1 <> ALL ( SELECT SUM(f1) AS sf1 FROM t2 HAVING sf1 > 10000);
drop table t1,t2; drop table t1,t2;
#
# Test for BUG#7885: Server crash when 'any' subselect compared to # Test for BUG#7885: Server crash when 'any' subselect compared to
# non-existant field. # non-existant field.
#
create table t1 (a1 int); create table t1 (a1 int);
create table t2 (b1 int); create table t2 (b1 int);
--error 1054 --error 1054
@ -1428,3 +1431,56 @@ select * from t1 where a2 > any(select b1 from t2);
select * from t1 where a1 > any(select b1 from t2); select * from t1 where a1 > any(select b1 from t2);
drop table t1,t2; drop table t1,t2;
#
# Comparison subquery with * and row
#
create table t1 (a integer, b integer);
select (select * from t1) = (select 1,2);
select (select 1,2) = (select * from t1);
# queries whih can be converted to IN
select row(1,2) = ANY (select * from t1);
select row(1,2) != ALL (select * from t1);
drop table t1;
#
# Comparison subquery and row with nested rows
#
create table t1 (a integer, b integer);
-- error 1241
select row(1,(2,2)) in (select * from t1 );
-- error 1241
select row(1,(2,2)) = (select * from t1 );
-- error 1241
select (select * from t1) = row(1,(2,2));
drop table t1;
#
# Forward reference detection
#
create table t1 (a integer);
insert into t1 values (1);
-- error 1247
select 1 = ALL (select 1 from t1 where 1 = xx ), 1 as xx ;
-- error 1247
select 1 = ALL (select 1 from t1 where 1 = xx ), 1 as xx;
select 1 as xx, 1 = ALL ( select 1 from t1 where 1 = xx );
-- error 1247
select 1 = ALL (select 1 from t1 where 1 = xx ), 1 as xx;
-- error 1247
select 1 = ALL (select 1 from t1 where 1 = xx ), 1 as xx from DUAL;
drop table t1;
#
# cleaning up of results of subselects (BUG#8125)
#
CREATE TABLE `t1` ( `a` char(3) NOT NULL default '', `b` char(3) NOT NULL default '', `c` char(3) NOT NULL default '', PRIMARY KEY (`a`,`b`,`c`)) ENGINE=InnoDB;
CREATE TABLE t2 LIKE t1;
INSERT INTO t1 VALUES (1,1,1);
INSERT INTO t2 VALUES (1,1,1);
PREPARE my_stmt FROM "SELECT t1.b, count(*) FROM t1 group by t1.b having
count(*) > ALL (SELECT COUNT(*) FROM t2 WHERE t2.a=1 GROUP By t2.b)";
EXECUTE my_stmt;
EXECUTE my_stmt;
deallocate prepare my_stmt;
drop table t1,t2;

View file

@ -43,7 +43,7 @@ static int compare_bin(uchar *a, uint a_length, uchar *b, uint b_length,
return 0; return 0;
if (skip_end_space && a_length != b_length) if (skip_end_space && a_length != b_length)
{ {
int swap= 0; int swap= 1;
/* /*
We are using space compression. We have to check if longer key We are using space compression. We have to check if longer key
has next character < ' ', in which case it's less than the shorter has next character < ' ', in which case it's less than the shorter
@ -57,12 +57,12 @@ static int compare_bin(uchar *a, uint a_length, uchar *b, uint b_length,
/* put shorter key in a */ /* put shorter key in a */
a_length= b_length; a_length= b_length;
a= b; a= b;
swap= -1 ^ 1; /* swap sign of result */ swap= -1; /* swap sign of result */
} }
for (end= a + a_length-length; a < end ; a++) for (end= a + a_length-length; a < end ; a++)
{ {
if (*a != ' ') if (*a != ' ')
return ((int) *a - (int) ' ') ^ swap; return (*a < ' ') ? -swap : swap;
} }
return 0; return 0;
} }

View file

@ -804,6 +804,8 @@ private:
void remove_list(NdbOperation*& head, NdbOperation*); void remove_list(NdbOperation*& head, NdbOperation*);
void define_scan_op(NdbIndexScanOperation*); void define_scan_op(NdbIndexScanOperation*);
friend class HugoOperations;
}; };
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL

View file

@ -3201,7 +3201,7 @@ Backup::execSTART_BACKUP_REQ(Signal* signal)
return; return;
}//if }//if
tabPtr.p->triggerAllocated[i] = true; tabPtr.p->triggerAllocated[j] = true;
trigPtr.p->backupPtr = ptr.i; trigPtr.p->backupPtr = ptr.i;
trigPtr.p->tableId = tabPtr.p->tableId; trigPtr.p->tableId = tabPtr.p->tableId;
trigPtr.p->tab_ptr_i = tabPtr.i; trigPtr.p->tab_ptr_i = tabPtr.i;

View file

@ -4385,7 +4385,8 @@ void Dbacc::commitOperation(Signal* signal)
Uint32 tmp2Olq; Uint32 tmp2Olq;
if ((operationRecPtr.p->commitDeleteCheckFlag == ZFALSE) && if ((operationRecPtr.p->commitDeleteCheckFlag == ZFALSE) &&
(operationRecPtr.p->operation != ZSCAN_OP)) { (operationRecPtr.p->operation != ZSCAN_OP) &&
(operationRecPtr.p->operation != ZREAD)) {
jam(); jam();
/* This method is used to check whether the end result of the transaction /* This method is used to check whether the end result of the transaction
will be to delete the tuple. In this case all operation will be marked will be to delete the tuple. In this case all operation will be marked

View file

@ -33,6 +33,8 @@ public:
int closeTransaction(Ndb*); int closeTransaction(Ndb*);
NdbTransaction* getTransaction(); NdbTransaction* getTransaction();
void refresh(); void refresh();
void setTransactionId(Uint64);
int pkInsertRecord(Ndb*, int pkInsertRecord(Ndb*,
int recordNo, int recordNo,

View file

@ -191,7 +191,7 @@ public:
NDBT_TestCase(NDBT_TestSuite* psuite, NDBT_TestCase(NDBT_TestSuite* psuite,
const char* name, const char* name,
const char* comment); const char* comment);
virtual ~NDBT_TestCase(){} virtual ~NDBT_TestCase() {}
// This is the default executor of a test case // This is the default executor of a test case
// When a test case is executed it will need to be suplied with a number of // When a test case is executed it will need to be suplied with a number of
@ -228,6 +228,8 @@ protected:
void stopTimer(NDBT_Context*); void stopTimer(NDBT_Context*);
void printTimer(NDBT_Context*); void printTimer(NDBT_Context*);
BaseString _name;
BaseString _comment;
const char* name; const char* name;
const char* comment; const char* comment;
NDBT_TestSuite* suite; NDBT_TestSuite* suite;

View file

@ -98,6 +98,15 @@ OperationTestCase matrix[] = {
result = NDBT_FAILED; \ result = NDBT_FAILED; \
break; } break; }
#define C3(b) if (!(b)) { \
g_err << "ERR: "<< step->getName() \
<< " failed on line " << __LINE__ << endl; \
abort(); return NDBT_FAILED; }
#define C3(b) if (!(b)) { \
g_err << "ERR: failed on line " << __LINE__ << endl; \
return NDBT_FAILED; }
int int
runOp(HugoOperations & hugoOps, runOp(HugoOperations & hugoOps,
Ndb * pNdb, Ndb * pNdb,
@ -228,11 +237,369 @@ runClearTable(NDBT_Context* ctx, NDBT_Step* step){
return NDBT_OK; return NDBT_OK;
} }
enum OPS { o_DONE= 0, o_INS= 1, o_UPD= 2, o_DEL= 3 };
typedef Vector<OPS> Sequence;
static
bool
valid(const Sequence& s)
{
if(s.size() == 0)
return false;
for(size_t i = 1; i<s.size(); i++)
{
switch(s[i]){
case o_INS:
if(s[i-1] != o_DEL)
return false;
break;
case o_UPD:
case o_DEL:
if(s[i-1] == o_DEL)
return false;
break;
case o_DONE:
return true;
}
}
return true;
}
static
NdbOut& operator<<(NdbOut& out, const Sequence& s)
{
out << "[ ";
for(size_t i = 0; i<s.size(); i++)
{
switch(s[i]){
case o_INS:
out << "INS ";
break;
case o_DEL:
out << "DEL ";
break;
case o_UPD:
out << "UPD ";
break;
case o_DONE:
abort();
}
}
out << "]";
return out;
}
static
void
generate(Sequence& out, int no)
{
while(no & 3)
{
out.push_back((OPS)(no & 3));
no >>= 2;
}
}
static
void
generate(Vector<int>& out, size_t len)
{
int max= 1;
while(len)
{
max <<= 2;
len--;
}
len= 1;
for(int i = 0; i<max; i++)
{
Sequence tmp;
generate(tmp, i);
if(tmp.size() >= len && valid(tmp))
{
out.push_back(i);
len= tmp.size();
}
else
{
//ndbout << "DISCARD: " << tmp << endl;
}
}
}
static const Uint32 DUMMY = 0;
static const Uint32 ROW = 1;
int
verify_other(NDBT_Context* ctx,
Ndb* pNdb, int seq, OPS latest, bool initial_row, bool commit)
{
Uint32 no_wait = NdbOperation::LM_CommittedRead*
ctx->getProperty("NoWait", (Uint32)1);
for(size_t j = no_wait; j<3; j++)
{
HugoOperations other(*ctx->getTab());
C3(other.startTransaction(pNdb) == 0);
C3(other.pkReadRecord(pNdb, ROW, 1, (NdbOperation::LockMode)j) == 0);
int tmp= other.execute_Commit(pNdb);
if(seq == 0){
if(j == NdbOperation::LM_CommittedRead)
{
C3(initial_row? tmp==0 && other.verifyUpdatesValue(0) == 0 : tmp==626);
}
else
{
C3(tmp == 266);
}
}
else if(commit)
{
switch(latest){
case o_INS:
case o_UPD:
C3(tmp == 0 && other.verifyUpdatesValue(seq) == 0);
break;
case o_DEL:
C3(tmp == 626);
break;
case o_DONE:
abort();
}
}
else
{
// rollback
C3(initial_row? tmp==0 && other.verifyUpdatesValue(0) == 0 : tmp==626);
}
}
return NDBT_OK;
}
int
verify_savepoint(NDBT_Context* ctx,
Ndb* pNdb, int seq, OPS latest,
Uint64 transactionId)
{
bool initial_row= (seq == 0) && latest == o_INS;
for(size_t j = 0; j<3; j++)
{
const NdbOperation::LockMode lm= (NdbOperation::LockMode)j;
HugoOperations same(*ctx->getTab());
C3(same.startTransaction(pNdb) == 0);
same.setTransactionId(transactionId); // Cheat
/**
* Increase savepoint to <em>k</em>
*/
for(size_t l = 1; l<=seq; l++)
{
C3(same.pkReadRecord(pNdb, DUMMY, 1, lm) == 0); // Read dummy row
C3(same.execute_NoCommit(pNdb) == 0);
g_info << "savepoint: " << l << endl;
}
g_info << "op(" << seq << "): "
<< " lock mode " << lm << endl;
C3(same.pkReadRecord(pNdb, ROW, 1, lm) == 0); // Read real row
int tmp= same.execute_Commit(pNdb);
if(seq == 0)
{
if(initial_row)
{
C3(tmp == 0 && same.verifyUpdatesValue(0) == 0);
} else
{
C3(tmp == 626);
}
}
else
{
switch(latest){
case o_INS:
case o_UPD:
C3(tmp == 0 && same.verifyUpdatesValue(seq) == 0);
break;
case o_DEL:
C3(tmp == 626);
break;
case o_DONE:
abort();
}
}
}
return NDBT_OK;
}
int
runOperations(NDBT_Context* ctx, NDBT_Step* step)
{
int tmp;
Ndb* pNdb = GETNDB(step);
Uint32 seqNo = ctx->getProperty("Sequence", (Uint32)0);
Uint32 commit= ctx->getProperty("Commit", (Uint32)1);
if(seqNo == 0)
{
return NDBT_FAILED;
}
Sequence seq;
generate(seq, seqNo);
{
// Dummy row
HugoOperations hugoOps(*ctx->getTab());
C3(hugoOps.startTransaction(pNdb) == 0);
C3(hugoOps.pkInsertRecord(pNdb, DUMMY, 1, 0) == 0);
C3(hugoOps.execute_Commit(pNdb) == 0);
}
const bool initial_row= (seq[0] != o_INS);
if(initial_row)
{
HugoOperations hugoOps(*ctx->getTab());
C3(hugoOps.startTransaction(pNdb) == 0);
C3(hugoOps.pkInsertRecord(pNdb, ROW, 1, 0) == 0);
C3(hugoOps.execute_Commit(pNdb) == 0);
}
HugoOperations trans1(*ctx->getTab());
C3(trans1.startTransaction(pNdb) == 0);
for(size_t i = 0; i<seq.size(); i++)
{
/**
* Perform operation
*/
switch(seq[i]){
case o_INS:
C3(trans1.pkInsertRecord(pNdb, ROW, 1, i+1) == 0);
break;
case o_UPD:
C3(trans1.pkUpdateRecord(pNdb, ROW, 1, i+1) == 0);
break;
case o_DEL:
C3(trans1.pkDeleteRecord(pNdb, ROW, 1) == 0);
break;
case o_DONE:
abort();
}
C3(trans1.execute_NoCommit(pNdb) == 0);
/**
* Verify other transaction
*/
if(verify_other(ctx, pNdb, 0, seq[0], initial_row, commit) != NDBT_OK)
return NDBT_FAILED;
/**
* Verify savepoint read
*/
Uint64 transactionId= trans1.getTransaction()->getTransactionId();
for(size_t k=0; k<=i+1; k++)
{
if(verify_savepoint(ctx, pNdb, k,
k>0 ? seq[k-1] : initial_row ? o_INS : o_DONE,
transactionId) != NDBT_OK)
return NDBT_FAILED;
}
}
if(commit)
{
C3(trans1.execute_Commit(pNdb) == 0);
}
else
{
C3(trans1.execute_Rollback(pNdb) == 0);
}
if(verify_other(ctx, pNdb, seq.size(), seq.back(),
initial_row, commit) != NDBT_OK)
return NDBT_FAILED;
return NDBT_OK;
}
int int
main(int argc, const char** argv){ main(int argc, const char** argv){
ndb_init(); ndb_init();
Vector<int> tmp;
generate(tmp, 5);
NDBT_TestSuite ts("testOperations"); NDBT_TestSuite ts("testOperations");
for(size_t i = 0; i<tmp.size(); i++)
{
BaseString name;
Sequence s;
generate(s, tmp[i]);
for(size_t j = 0; j<s.size(); j++){
switch(s[j]){
case o_INS:
name.append("_INS");
break;
case o_DEL:
name.append("_DEL");
break;
case o_UPD:
name.append("_UPD");
break;
case o_DONE:
abort();
}
}
BaseString n1;
n1.append(name);
n1.append("_COMMIT");
NDBT_TestCaseImpl1 *pt = new NDBT_TestCaseImpl1(&ts,
n1.c_str()+1, "");
pt->setProperty("Sequence", tmp[i]);
pt->addInitializer(new NDBT_Initializer(pt,
"runClearTable",
runClearTable));
pt->addStep(new NDBT_ParallelStep(pt,
"run",
runOperations));
pt->addFinalizer(new NDBT_Finalizer(pt,
"runClearTable",
runClearTable));
ts.addTest(pt);
name.append("_ABORT");
pt = new NDBT_TestCaseImpl1(&ts, name.c_str()+1, "");
pt->setProperty("Sequence", tmp[i]);
pt->setProperty("Commit", (Uint32)0);
pt->addInitializer(new NDBT_Initializer(pt,
"runClearTable",
runClearTable));
pt->addStep(new NDBT_ParallelStep(pt,
"run",
runOperations));
pt->addFinalizer(new NDBT_Finalizer(pt,
"runClearTable",
runClearTable));
ts.addTest(pt);
}
for(Uint32 i = 0; i<sizeof(matrix)/sizeof(matrix[0]); i++){ for(Uint32 i = 0; i<sizeof(matrix)/sizeof(matrix[0]); i++){
NDBT_TestCaseImpl1 *pt = new NDBT_TestCaseImpl1(&ts, matrix[i].name, ""); NDBT_TestCaseImpl1 *pt = new NDBT_TestCaseImpl1(&ts, matrix[i].name, "");
@ -270,3 +637,5 @@ main(int argc, const char** argv){
return ts.execute(argc, argv); return ts.execute(argc, argv);
} }
template class Vector<OPS>;
template class Vector<Sequence>;

View file

@ -45,6 +45,13 @@ int HugoOperations::setTransaction(NdbTransaction* new_trans){
return NDBT_OK; return NDBT_OK;
} }
void
HugoOperations::setTransactionId(Uint64 id){
if (pTrans != NULL){
pTrans->setTransactionId(id);
}
}
int HugoOperations::closeTransaction(Ndb* pNdb){ int HugoOperations::closeTransaction(Ndb* pNdb){
if (pTrans != NULL){ if (pTrans != NULL){
@ -369,6 +376,10 @@ HugoOperations::HugoOperations(const NdbDictionary::Table& _tab,
HugoOperations::~HugoOperations(){ HugoOperations::~HugoOperations(){
deallocRows(); deallocRows();
if (pTrans != NULL){
pTrans->close();
pTrans = NULL;
}
} }

View file

@ -68,20 +68,20 @@ HugoTransactions::scanReadRecords(Ndb* pNdb,
pOp = getScanOperation(pTrans); pOp = getScanOperation(pTrans);
if (pOp == NULL) { if (pOp == NULL) {
ERR(pTrans->getNdbError()); ERR(pTrans->getNdbError());
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
if( pOp ->readTuples(lm, 0, parallelism) ) { if( pOp ->readTuples(lm, 0, parallelism) ) {
ERR(pTrans->getNdbError()); ERR(pTrans->getNdbError());
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
check = pOp->interpret_exit_ok(); check = pOp->interpret_exit_ok();
if( check == -1 ) { if( check == -1 ) {
ERR(pTrans->getNdbError()); ERR(pTrans->getNdbError());
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
@ -89,7 +89,7 @@ HugoTransactions::scanReadRecords(Ndb* pNdb,
if((row.attributeStore(a) = if((row.attributeStore(a) =
pOp->getValue(tab.getColumn(a)->getName())) == 0) { pOp->getValue(tab.getColumn(a)->getName())) == 0) {
ERR(pTrans->getNdbError()); ERR(pTrans->getNdbError());
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
} }
@ -99,13 +99,13 @@ HugoTransactions::scanReadRecords(Ndb* pNdb,
const NdbError err = pTrans->getNdbError(); const NdbError err = pTrans->getNdbError();
if (err.status == NdbError::TemporaryError){ if (err.status == NdbError::TemporaryError){
ERR(err); ERR(err);
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
NdbSleep_MilliSleep(50); NdbSleep_MilliSleep(50);
retryAttempt++; retryAttempt++;
continue; continue;
} }
ERR(err); ERR(err);
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
@ -124,7 +124,7 @@ HugoTransactions::scanReadRecords(Ndb* pNdb,
while((eof = pOp->nextResult(true)) == 0){ while((eof = pOp->nextResult(true)) == 0){
rows++; rows++;
if (calc.verifyRowValues(&row) != 0){ if (calc.verifyRowValues(&row) != 0){
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
@ -134,11 +134,11 @@ HugoTransactions::scanReadRecords(Ndb* pNdb,
pOp->close(); pOp->close();
if( check == -1 ) { if( check == -1 ) {
ERR(pTrans->getNdbError()); ERR(pTrans->getNdbError());
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_OK; return NDBT_OK;
} }
} }
@ -147,7 +147,7 @@ HugoTransactions::scanReadRecords(Ndb* pNdb,
if (err.status == NdbError::TemporaryError){ if (err.status == NdbError::TemporaryError){
ERR_INFO(err); ERR_INFO(err);
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
NdbSleep_MilliSleep(50); NdbSleep_MilliSleep(50);
switch (err.code){ switch (err.code){
case 488: case 488:
@ -161,17 +161,17 @@ HugoTransactions::scanReadRecords(Ndb* pNdb,
continue; continue;
} }
ERR(err); ERR(err);
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
g_info << rows << " rows have been read" << endl; g_info << rows << " rows have been read" << endl;
if (records != 0 && rows != records){ if (records != 0 && rows != records){
g_err << "Check expected number of records failed" << endl g_err << "Check expected number of records failed" << endl
<< " expected=" << records <<", " << endl << " expected=" << records <<", " << endl
<< " read=" << rows << endl; << " read=" << rows << endl;
return NDBT_FAILED; return NDBT_FAILED;
} }
@ -241,7 +241,7 @@ HugoTransactions::scanReadRecords(Ndb* pNdb,
if((row.attributeStore(a) = if((row.attributeStore(a) =
pOp->getValue(tab.getColumn(a)->getName())) == 0) { pOp->getValue(tab.getColumn(a)->getName())) == 0) {
ERR(pTrans->getNdbError()); ERR(pTrans->getNdbError());
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
} }
@ -251,13 +251,13 @@ HugoTransactions::scanReadRecords(Ndb* pNdb,
const NdbError err = pTrans->getNdbError(); const NdbError err = pTrans->getNdbError();
if (err.status == NdbError::TemporaryError){ if (err.status == NdbError::TemporaryError){
ERR(err); ERR(err);
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
NdbSleep_MilliSleep(50); NdbSleep_MilliSleep(50);
retryAttempt++; retryAttempt++;
continue; continue;
} }
ERR(err); ERR(err);
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
@ -276,7 +276,7 @@ HugoTransactions::scanReadRecords(Ndb* pNdb,
while((eof = pOp->nextResult(true)) == 0){ while((eof = pOp->nextResult(true)) == 0){
rows++; rows++;
if (calc.verifyRowValues(&row) != 0){ if (calc.verifyRowValues(&row) != 0){
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
@ -286,11 +286,11 @@ HugoTransactions::scanReadRecords(Ndb* pNdb,
pOp->close(); pOp->close();
if( check == -1 ) { if( check == -1 ) {
ERR(pTrans->getNdbError()); ERR(pTrans->getNdbError());
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_OK; return NDBT_OK;
} }
} }
@ -299,7 +299,7 @@ HugoTransactions::scanReadRecords(Ndb* pNdb,
if (err.status == NdbError::TemporaryError){ if (err.status == NdbError::TemporaryError){
ERR_INFO(err); ERR_INFO(err);
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
NdbSleep_MilliSleep(50); NdbSleep_MilliSleep(50);
switch (err.code){ switch (err.code){
case 488: case 488:
@ -313,17 +313,17 @@ HugoTransactions::scanReadRecords(Ndb* pNdb,
continue; continue;
} }
ERR(err); ERR(err);
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
g_info << rows << " rows have been read" << endl; g_info << rows << " rows have been read" << endl;
if (records != 0 && rows != records){ if (records != 0 && rows != records){
g_err << "Check expected number of records failed" << endl g_err << "Check expected number of records failed" << endl
<< " expected=" << records <<", " << endl << " expected=" << records <<", " << endl
<< " read=" << rows << endl; << " read=" << rows << endl;
return NDBT_FAILED; return NDBT_FAILED;
} }
@ -337,9 +337,9 @@ HugoTransactions::scanReadRecords(Ndb* pNdb,
int int
HugoTransactions::scanUpdateRecords(Ndb* pNdb, HugoTransactions::scanUpdateRecords(Ndb* pNdb,
int records, int records,
int abortPercent, int abortPercent,
int parallelism){ int parallelism){
if(m_defaultScanUpdateMethod == 1){ if(m_defaultScanUpdateMethod == 1){
return scanUpdateRecords1(pNdb, records, abortPercent, parallelism); return scanUpdateRecords1(pNdb, records, abortPercent, parallelism);
} else if(m_defaultScanUpdateMethod == 2){ } else if(m_defaultScanUpdateMethod == 2){
@ -383,7 +383,7 @@ HugoTransactions::scanUpdateRecords3(Ndb* pNdb,
while (true){ while (true){
restart: restart:
if (retryAttempt++ >= retryMax){ if (retryAttempt++ >= retryMax){
g_info << "ERROR: has retried this operation " << retryAttempt g_info << "ERROR: has retried this operation " << retryAttempt
<< " times, failing!" << endl; << " times, failing!" << endl;
@ -404,13 +404,13 @@ HugoTransactions::scanUpdateRecords3(Ndb* pNdb,
pOp = getScanOperation(pTrans); pOp = getScanOperation(pTrans);
if (pOp == NULL) { if (pOp == NULL) {
ERR(pTrans->getNdbError()); ERR(pTrans->getNdbError());
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
if( pOp->readTuplesExclusive(parallelism) ) { if( pOp->readTuplesExclusive(parallelism) ) {
ERR(pTrans->getNdbError()); ERR(pTrans->getNdbError());
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
@ -418,7 +418,7 @@ HugoTransactions::scanUpdateRecords3(Ndb* pNdb,
for(a=0; a<tab.getNoOfColumns(); a++){ for(a=0; a<tab.getNoOfColumns(); a++){
if((row.attributeStore(a) = pOp->getValue(tab.getColumn(a)->getName())) == NULL){ if((row.attributeStore(a) = pOp->getValue(tab.getColumn(a)->getName())) == NULL){
ERR(pTrans->getNdbError()); ERR(pTrans->getNdbError());
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
} }
@ -427,7 +427,7 @@ HugoTransactions::scanUpdateRecords3(Ndb* pNdb,
if( check == -1 ) { if( check == -1 ) {
const NdbError err = pTrans->getNdbError(); const NdbError err = pTrans->getNdbError();
ERR(err); ERR(err);
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
if (err.status == NdbError::TemporaryError){ if (err.status == NdbError::TemporaryError){
NdbSleep_MilliSleep(50); NdbSleep_MilliSleep(50);
continue; continue;
@ -452,7 +452,7 @@ HugoTransactions::scanUpdateRecords3(Ndb* pNdb,
NdbOperation* pUp = pOp->updateCurrentTuple(); NdbOperation* pUp = pOp->updateCurrentTuple();
if(pUp == 0){ if(pUp == 0){
ERR(pTrans->getNdbError()); ERR(pTrans->getNdbError());
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
const int updates = calc.getUpdatesValue(&row) + 1; const int updates = calc.getUpdatesValue(&row) + 1;
@ -461,7 +461,7 @@ HugoTransactions::scanUpdateRecords3(Ndb* pNdb,
if (tab.getColumn(a)->getPrimaryKey() == false){ if (tab.getColumn(a)->getPrimaryKey() == false){
if(setValueForAttr(pUp, a, r, updates ) != 0){ if(setValueForAttr(pUp, a, r, updates ) != 0){
ERR(pTrans->getNdbError()); ERR(pTrans->getNdbError());
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
} }
@ -470,7 +470,7 @@ HugoTransactions::scanUpdateRecords3(Ndb* pNdb,
if (rows == abortCount && abortTrans == true){ if (rows == abortCount && abortTrans == true){
g_info << "Scan is aborted" << endl; g_info << "Scan is aborted" << endl;
// This scan should be aborted // This scan should be aborted
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_OK; return NDBT_OK;
} }
} while((check = pOp->nextResult(false)) == 0); } while((check = pOp->nextResult(false)) == 0);
@ -482,7 +482,7 @@ HugoTransactions::scanUpdateRecords3(Ndb* pNdb,
const NdbError err = pTrans->getNdbError(); const NdbError err = pTrans->getNdbError();
if( check == -1 ) { if( check == -1 ) {
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
ERR(err); ERR(err);
if (err.status == NdbError::TemporaryError){ if (err.status == NdbError::TemporaryError){
NdbSleep_MilliSleep(50); NdbSleep_MilliSleep(50);
@ -494,7 +494,7 @@ HugoTransactions::scanUpdateRecords3(Ndb* pNdb,
const NdbError err = pTrans->getNdbError(); const NdbError err = pTrans->getNdbError();
if( check == -1 ) { if( check == -1 ) {
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
ERR(err); ERR(err);
if (err.status == NdbError::TemporaryError){ if (err.status == NdbError::TemporaryError){
NdbSleep_MilliSleep(50); NdbSleep_MilliSleep(50);
@ -503,7 +503,7 @@ HugoTransactions::scanUpdateRecords3(Ndb* pNdb,
return NDBT_FAILED; return NDBT_FAILED;
} }
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
g_info << rows << " rows have been updated" << endl; g_info << rows << " rows have been updated" << endl;
return NDBT_OK; return NDBT_OK;
@ -575,7 +575,7 @@ HugoTransactions::loadTable(Ndb* pNdb,
if(pkInsertRecord(pNdb, c, batch) != NDBT_OK) if(pkInsertRecord(pNdb, c, batch) != NDBT_OK)
{ {
ERR(pTrans->getNdbError()); ERR(pTrans->getNdbError());
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
@ -591,7 +591,7 @@ HugoTransactions::loadTable(Ndb* pNdb,
} }
if(check == -1 ) { if(check == -1 ) {
const NdbError err = pTrans->getNdbError(); const NdbError err = pTrans->getNdbError();
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
pTrans= 0; pTrans= 0;
switch(err.status){ switch(err.status){
case NdbError::Success: case NdbError::Success:
@ -633,7 +633,7 @@ HugoTransactions::loadTable(Ndb* pNdb,
} }
else{ else{
if (closeTrans) { if (closeTrans) {
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
pTrans= 0; pTrans= 0;
} }
} }
@ -644,7 +644,7 @@ HugoTransactions::loadTable(Ndb* pNdb,
} }
if(pTrans) if(pTrans)
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_OK; return NDBT_OK;
} }
@ -696,7 +696,7 @@ HugoTransactions::fillTable(Ndb* pNdb,
if(pkInsertRecord(pNdb, c, batch) != NDBT_OK) if(pkInsertRecord(pNdb, c, batch) != NDBT_OK)
{ {
ERR(pTrans->getNdbError()); ERR(pTrans->getNdbError());
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
@ -704,7 +704,7 @@ HugoTransactions::fillTable(Ndb* pNdb,
check = pTrans->execute( Commit, CommitAsMuchAsPossible ); check = pTrans->execute( Commit, CommitAsMuchAsPossible );
if(check == -1 ) { if(check == -1 ) {
const NdbError err = pTrans->getNdbError(); const NdbError err = pTrans->getNdbError();
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
switch(err.status){ switch(err.status){
case NdbError::Success: case NdbError::Success:
@ -756,7 +756,7 @@ HugoTransactions::fillTable(Ndb* pNdb,
} }
} }
else{ else{
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
} }
// Step to next record // Step to next record
@ -1088,7 +1088,7 @@ HugoTransactions::pkReadRecords(Ndb* pNdb,
if(pkReadRecord(pNdb, r, batch, lm) != NDBT_OK) if(pkReadRecord(pNdb, r, batch, lm) != NDBT_OK)
{ {
ERR(pTrans->getNdbError()); ERR(pTrans->getNdbError());
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
@ -1098,7 +1098,7 @@ HugoTransactions::pkReadRecords(Ndb* pNdb,
if (err.status == NdbError::TemporaryError){ if (err.status == NdbError::TemporaryError){
ERR(err); ERR(err);
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
NdbSleep_MilliSleep(50); NdbSleep_MilliSleep(50);
retryAttempt++; retryAttempt++;
continue; continue;
@ -1111,7 +1111,7 @@ HugoTransactions::pkReadRecords(Ndb* pNdb,
default: default:
ERR(err); ERR(err);
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
} else { } else {
@ -1122,13 +1122,13 @@ HugoTransactions::pkReadRecords(Ndb* pNdb,
{ {
rows_found++; rows_found++;
if (calc.verifyRowValues(rows[0]) != 0){ if (calc.verifyRowValues(rows[0]) != 0){
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
} }
if(check != 1 || rows_found > batch) if(check != 1 || rows_found > batch)
{ {
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
else if(rows_found < batch) else if(rows_found < batch)
@ -1146,7 +1146,7 @@ HugoTransactions::pkReadRecords(Ndb* pNdb,
{ {
for (int b=0; (b<batch) && (r+b<records); b++){ for (int b=0; (b<batch) && (r+b<records); b++){
if (calc.verifyRowValues(rows[b]) != 0){ if (calc.verifyRowValues(rows[b]) != 0){
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
reads++; reads++;
@ -1155,7 +1155,7 @@ HugoTransactions::pkReadRecords(Ndb* pNdb,
} }
} }
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
} }
deallocRows(); deallocRows();
g_info << reads << " records read" << endl; g_info << reads << " records read" << endl;
@ -1209,7 +1209,7 @@ HugoTransactions::pkUpdateRecords(Ndb* pNdb,
if(pkReadRecord(pNdb, r, batch, NdbOperation::LM_Exclusive) != NDBT_OK) if(pkReadRecord(pNdb, r, batch, NdbOperation::LM_Exclusive) != NDBT_OK)
{ {
ERR(pTrans->getNdbError()); ERR(pTrans->getNdbError());
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
@ -1219,13 +1219,13 @@ HugoTransactions::pkUpdateRecords(Ndb* pNdb,
if (err.status == NdbError::TemporaryError){ if (err.status == NdbError::TemporaryError){
ERR(err); ERR(err);
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
NdbSleep_MilliSleep(50); NdbSleep_MilliSleep(50);
retryAttempt++; retryAttempt++;
continue; continue;
} }
ERR(err); ERR(err);
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
@ -1237,7 +1237,7 @@ HugoTransactions::pkUpdateRecords(Ndb* pNdb,
do { do {
if (calc.verifyRowValues(rows[0]) != 0){ if (calc.verifyRowValues(rows[0]) != 0){
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
@ -1246,7 +1246,7 @@ HugoTransactions::pkUpdateRecords(Ndb* pNdb,
if(pkUpdateRecord(pNdb, r+rows_found, 1, updates) != NDBT_OK) if(pkUpdateRecord(pNdb, r+rows_found, 1, updates) != NDBT_OK)
{ {
ERR(pTrans->getNdbError()); ERR(pTrans->getNdbError());
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
rows_found++; rows_found++;
@ -1259,7 +1259,7 @@ HugoTransactions::pkUpdateRecords(Ndb* pNdb,
} }
if(check != 1 || rows_found != batch) if(check != 1 || rows_found != batch)
{ {
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
} }
@ -1269,7 +1269,7 @@ HugoTransactions::pkUpdateRecords(Ndb* pNdb,
{ {
if (calc.verifyRowValues(rows[b]) != 0) if (calc.verifyRowValues(rows[b]) != 0)
{ {
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
@ -1278,7 +1278,7 @@ HugoTransactions::pkUpdateRecords(Ndb* pNdb,
if(pkUpdateRecord(pNdb, r+b, 1, updates) != NDBT_OK) if(pkUpdateRecord(pNdb, r+b, 1, updates) != NDBT_OK)
{ {
ERR(pTrans->getNdbError()); ERR(pTrans->getNdbError());
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
} }
@ -1289,21 +1289,21 @@ HugoTransactions::pkUpdateRecords(Ndb* pNdb,
if (err.status == NdbError::TemporaryError){ if (err.status == NdbError::TemporaryError){
ERR(err); ERR(err);
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
NdbSleep_MilliSleep(50); NdbSleep_MilliSleep(50);
retryAttempt++; retryAttempt++;
continue; continue;
} }
ERR(err); ERR(err);
ndbout << "r = " << r << endl; ndbout << "r = " << r << endl;
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
else{ else{
updated += batch; updated += batch;
} }
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
r += batch; // Read next record r += batch; // Read next record
} }
@ -1348,15 +1348,15 @@ HugoTransactions::pkInterpretedUpdateRecords(Ndb* pNdb,
NdbOperation* pOp = pTrans->getNdbOperation(tab.getName()); NdbOperation* pOp = pTrans->getNdbOperation(tab.getName());
if (pOp == NULL) { if (pOp == NULL) {
ERR(pTrans->getNdbError()); ERR(pTrans->getNdbError());
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
check = pOp->readTupleExclusive(); check = pOp->readTupleExclusive();
if( check == -1 ) { if( check == -1 ) {
ERR(pTrans->getNdbError()); ERR(pTrans->getNdbError());
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
// Define primary keys // Define primary keys
@ -1364,7 +1364,7 @@ HugoTransactions::pkInterpretedUpdateRecords(Ndb* pNdb,
if (tab.getColumn(a)->getPrimaryKey() == true){ if (tab.getColumn(a)->getPrimaryKey() == true){
if(equalForAttr(pOp, a, r) != 0){ if(equalForAttr(pOp, a, r) != 0){
ERR(pTrans->getNdbError()); ERR(pTrans->getNdbError());
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
} }
@ -1376,7 +1376,7 @@ HugoTransactions::pkInterpretedUpdateRecords(Ndb* pNdb,
if((row.attributeStore(a) = if((row.attributeStore(a) =
pOp->getValue(tab.getColumn(a)->getName())) == 0) { pOp->getValue(tab.getColumn(a)->getName())) == 0) {
ERR(pTrans->getNdbError()); ERR(pTrans->getNdbError());
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
} }
@ -1388,13 +1388,13 @@ HugoTransactions::pkInterpretedUpdateRecords(Ndb* pNdb,
if (err.status == NdbError::TemporaryError){ if (err.status == NdbError::TemporaryError){
ERR(err); ERR(err);
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
NdbSleep_MilliSleep(50); NdbSleep_MilliSleep(50);
retryAttempt++; retryAttempt++;
continue; continue;
} }
ERR(err); ERR(err);
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
@ -1404,14 +1404,14 @@ HugoTransactions::pkInterpretedUpdateRecords(Ndb* pNdb,
pUpdOp = pTrans->getNdbOperation(tab.getName()); pUpdOp = pTrans->getNdbOperation(tab.getName());
if (pUpdOp == NULL) { if (pUpdOp == NULL) {
ERR(pTrans->getNdbError()); ERR(pTrans->getNdbError());
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
check = pUpdOp->interpretedUpdateTuple(); check = pUpdOp->interpretedUpdateTuple();
if( check == -1 ) { if( check == -1 ) {
ERR(pTrans->getNdbError()); ERR(pTrans->getNdbError());
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
@ -1420,7 +1420,7 @@ HugoTransactions::pkInterpretedUpdateRecords(Ndb* pNdb,
if (tab.getColumn(a)->getPrimaryKey() == true){ if (tab.getColumn(a)->getPrimaryKey() == true){
if(equalForAttr(pUpdOp, a, r) != 0){ if(equalForAttr(pUpdOp, a, r) != 0){
ERR(pTrans->getNdbError()); ERR(pTrans->getNdbError());
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
} }
@ -1437,7 +1437,7 @@ HugoTransactions::pkInterpretedUpdateRecords(Ndb* pNdb,
check = pUpdOp->incValue(attr->getName(), valToIncWith); check = pUpdOp->incValue(attr->getName(), valToIncWith);
if( check == -1 ) { if( check == -1 ) {
ERR(pTrans->getNdbError()); ERR(pTrans->getNdbError());
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
} }
@ -1449,7 +1449,7 @@ HugoTransactions::pkInterpretedUpdateRecords(Ndb* pNdb,
(calc.isUpdateCol(a) == false)){ (calc.isUpdateCol(a) == false)){
if(setValueForAttr(pUpdOp, a, r, updates ) != 0){ if(setValueForAttr(pUpdOp, a, r, updates ) != 0){
ERR(pTrans->getNdbError()); ERR(pTrans->getNdbError());
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
} }
@ -1463,14 +1463,14 @@ HugoTransactions::pkInterpretedUpdateRecords(Ndb* pNdb,
if (err.status == NdbError::TemporaryError){ if (err.status == NdbError::TemporaryError){
ERR(err); ERR(err);
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
NdbSleep_MilliSleep(50); NdbSleep_MilliSleep(50);
retryAttempt++; retryAttempt++;
continue; continue;
} }
ERR(err); ERR(err);
ndbout << "r = " << r << endl; ndbout << "r = " << r << endl;
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
else{ else{
@ -1478,7 +1478,7 @@ HugoTransactions::pkInterpretedUpdateRecords(Ndb* pNdb,
} }
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
r++; // Read next record r++; // Read next record
@ -1533,7 +1533,7 @@ HugoTransactions::pkDelRecords(Ndb* pNdb,
if(pkDeleteRecord(pNdb, r, batch) != NDBT_OK) if(pkDeleteRecord(pNdb, r, batch) != NDBT_OK)
{ {
ERR(pTrans->getNdbError()); ERR(pTrans->getNdbError());
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
@ -1544,7 +1544,7 @@ HugoTransactions::pkDelRecords(Ndb* pNdb,
switch(err.status){ switch(err.status){
case NdbError::TemporaryError: case NdbError::TemporaryError:
ERR(err); ERR(err);
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
NdbSleep_MilliSleep(50); NdbSleep_MilliSleep(50);
retryAttempt++; retryAttempt++;
continue; continue;
@ -1563,20 +1563,20 @@ HugoTransactions::pkDelRecords(Ndb* pNdb,
} }
} }
ERR(err); ERR(err);
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
break; break;
default: default:
ERR(err); ERR(err);
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
} }
else { else {
deleted += batch; deleted += batch;
} }
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
r += batch; // Read next record r += batch; // Read next record
@ -1641,7 +1641,7 @@ HugoTransactions::lockRecords(Ndb* pNdb,
if(pkReadRecord(pNdb, r, lockBatch, lm) != NDBT_OK) if(pkReadRecord(pNdb, r, lockBatch, lm) != NDBT_OK)
{ {
ERR(pTrans->getNdbError()); ERR(pTrans->getNdbError());
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
@ -1656,18 +1656,18 @@ HugoTransactions::lockRecords(Ndb* pNdb,
if (err.status == NdbError::TemporaryError){ if (err.status == NdbError::TemporaryError){
ERR(err); ERR(err);
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
NdbSleep_MilliSleep(50); NdbSleep_MilliSleep(50);
retryAttempt++; retryAttempt++;
continue; continue;
} }
ERR(err); ERR(err);
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
for (int b=0; (b<lockBatch) && (r+b<records); b++){ for (int b=0; (b<lockBatch) && (r+b<records); b++){
if (calc.verifyRowValues(rows[b]) != 0){ if (calc.verifyRowValues(rows[b]) != 0){
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
} }
@ -1682,26 +1682,26 @@ HugoTransactions::lockRecords(Ndb* pNdb,
if (err.status == NdbError::TemporaryError){ if (err.status == NdbError::TemporaryError){
ERR(err); ERR(err);
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
NdbSleep_MilliSleep(50); NdbSleep_MilliSleep(50);
retryAttempt++; retryAttempt++;
continue; continue;
} }
ERR(err); ERR(err);
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
else{ else{
for (int b=0; (b<lockBatch) && (r<records); b++){ for (int b=0; (b<lockBatch) && (r<records); b++){
if (calc.verifyRowValues(rows[b]) != 0){ if (calc.verifyRowValues(rows[b]) != 0){
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
r++; // Read next record r++; // Read next record
} }
} }
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
} }
deallocRows(); deallocRows();
@ -1765,7 +1765,7 @@ HugoTransactions::indexReadRecords(Ndb* pNdb,
pOp = pTrans->getNdbIndexOperation(idxName, tab.getName()); pOp = pTrans->getNdbIndexOperation(idxName, tab.getName());
if (pOp == NULL) { if (pOp == NULL) {
ERR(pTrans->getNdbError()); ERR(pTrans->getNdbError());
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
check = pOp->readTuple(); check = pOp->readTuple();
@ -1773,7 +1773,7 @@ HugoTransactions::indexReadRecords(Ndb* pNdb,
pOp = sOp = pTrans->getNdbIndexScanOperation(idxName, tab.getName()); pOp = sOp = pTrans->getNdbIndexScanOperation(idxName, tab.getName());
if (sOp == NULL) { if (sOp == NULL) {
ERR(pTrans->getNdbError()); ERR(pTrans->getNdbError());
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
check = sOp->readTuples(); check = sOp->readTuples();
@ -1781,7 +1781,7 @@ HugoTransactions::indexReadRecords(Ndb* pNdb,
if( check == -1 ) { if( check == -1 ) {
ERR(pTrans->getNdbError()); ERR(pTrans->getNdbError());
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
@ -1790,7 +1790,7 @@ HugoTransactions::indexReadRecords(Ndb* pNdb,
if (tab.getColumn(a)->getPrimaryKey() == true){ if (tab.getColumn(a)->getPrimaryKey() == true){
if(equalForAttr(pOp, a, r+b) != 0){ if(equalForAttr(pOp, a, r+b) != 0){
ERR(pTrans->getNdbError()); ERR(pTrans->getNdbError());
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
} }
@ -1801,7 +1801,7 @@ HugoTransactions::indexReadRecords(Ndb* pNdb,
if((rows[b]->attributeStore(a) = if((rows[b]->attributeStore(a) =
pOp->getValue(tab.getColumn(a)->getName())) == 0) { pOp->getValue(tab.getColumn(a)->getName())) == 0) {
ERR(pTrans->getNdbError()); ERR(pTrans->getNdbError());
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
} }
@ -1814,7 +1814,7 @@ HugoTransactions::indexReadRecords(Ndb* pNdb,
if (err.status == NdbError::TemporaryError){ if (err.status == NdbError::TemporaryError){
ERR(err); ERR(err);
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
NdbSleep_MilliSleep(50); NdbSleep_MilliSleep(50);
retryAttempt++; retryAttempt++;
continue; continue;
@ -1827,13 +1827,13 @@ HugoTransactions::indexReadRecords(Ndb* pNdb,
default: default:
ERR(err); ERR(err);
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
} else{ } else{
for (int b=0; (b<batch) && (r+b<records); b++){ for (int b=0; (b<batch) && (r+b<records); b++){
if (calc.verifyRowValues(rows[b]) != 0){ if (calc.verifyRowValues(rows[b]) != 0){
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
reads++; reads++;
@ -1842,11 +1842,11 @@ HugoTransactions::indexReadRecords(Ndb* pNdb,
if(ordered && sOp->nextResult(true) == 0){ if(ordered && sOp->nextResult(true) == 0){
ndbout << "Error when comparing records " ndbout << "Error when comparing records "
<< " - index op next_result to many" << endl; << " - index op next_result to many" << endl;
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
} }
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
} }
deallocRows(); deallocRows();
g_info << reads << " records read" << endl; g_info << reads << " records read" << endl;
@ -1905,21 +1905,21 @@ HugoTransactions::indexUpdateRecords(Ndb* pNdb,
pOp = pTrans->getNdbIndexOperation(idxName, tab.getName()); pOp = pTrans->getNdbIndexOperation(idxName, tab.getName());
if (pOp == NULL) { if (pOp == NULL) {
ERR(pTrans->getNdbError()); ERR(pTrans->getNdbError());
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
check = pOp->readTupleExclusive(); check = pOp->readTupleExclusive();
if( check == -1 ) { if( check == -1 ) {
ERR(pTrans->getNdbError()); ERR(pTrans->getNdbError());
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
} else { } else {
pOp = sOp = pTrans->getNdbIndexScanOperation(idxName, tab.getName()); pOp = sOp = pTrans->getNdbIndexScanOperation(idxName, tab.getName());
if (pOp == NULL) { if (pOp == NULL) {
ERR(pTrans->getNdbError()); ERR(pTrans->getNdbError());
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
@ -1932,7 +1932,7 @@ HugoTransactions::indexUpdateRecords(Ndb* pNdb,
if (tab.getColumn(a)->getPrimaryKey() == true){ if (tab.getColumn(a)->getPrimaryKey() == true){
if(equalForAttr(pOp, a, r+b) != 0){ if(equalForAttr(pOp, a, r+b) != 0){
ERR(pTrans->getNdbError()); ERR(pTrans->getNdbError());
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
} }
@ -1943,7 +1943,7 @@ HugoTransactions::indexUpdateRecords(Ndb* pNdb,
if((rows[b]->attributeStore(a) = if((rows[b]->attributeStore(a) =
pOp->getValue(tab.getColumn(a)->getName())) == 0) { pOp->getValue(tab.getColumn(a)->getName())) == 0) {
ERR(pTrans->getNdbError()); ERR(pTrans->getNdbError());
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
} }
@ -1954,7 +1954,7 @@ HugoTransactions::indexUpdateRecords(Ndb* pNdb,
if( check == -1 ) { if( check == -1 ) {
const NdbError err = pTrans->getNdbError(); const NdbError err = pTrans->getNdbError();
ERR(err); ERR(err);
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
if (err.status == NdbError::TemporaryError){ if (err.status == NdbError::TemporaryError){
NdbSleep_MilliSleep(50); NdbSleep_MilliSleep(50);
@ -1966,13 +1966,13 @@ HugoTransactions::indexUpdateRecords(Ndb* pNdb,
if(ordered && check != 0){ if(ordered && check != 0){
g_err << check << " - Row: " << r << " not found!!" << endl; g_err << check << " - Row: " << r << " not found!!" << endl;
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
for(b = 0; b<batch && (b+r)<records; b++){ for(b = 0; b<batch && (b+r)<records; b++){
if (calc.verifyRowValues(rows[b]) != 0){ if (calc.verifyRowValues(rows[b]) != 0){
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
@ -1988,13 +1988,13 @@ HugoTransactions::indexUpdateRecords(Ndb* pNdb,
if (pUpdOp == NULL) { if (pUpdOp == NULL) {
ERR(pTrans->getNdbError()); ERR(pTrans->getNdbError());
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
if( check == -1 ) { if( check == -1 ) {
ERR(pTrans->getNdbError()); ERR(pTrans->getNdbError());
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
@ -2003,7 +2003,7 @@ HugoTransactions::indexUpdateRecords(Ndb* pNdb,
if (tab.getColumn(a)->getPrimaryKey() == true){ if (tab.getColumn(a)->getPrimaryKey() == true){
if(equalForAttr(pUpdOp, a, r+b) != 0){ if(equalForAttr(pUpdOp, a, r+b) != 0){
ERR(pTrans->getNdbError()); ERR(pTrans->getNdbError());
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
} }
@ -2014,7 +2014,7 @@ HugoTransactions::indexUpdateRecords(Ndb* pNdb,
if (tab.getColumn(a)->getPrimaryKey() == false){ if (tab.getColumn(a)->getPrimaryKey() == false){
if(setValueForAttr(pUpdOp, a, r+b, updates ) != 0){ if(setValueForAttr(pUpdOp, a, r+b, updates ) != 0){
ERR(pTrans->getNdbError()); ERR(pTrans->getNdbError());
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
return NDBT_FAILED; return NDBT_FAILED;
} }
} }
@ -2025,7 +2025,7 @@ HugoTransactions::indexUpdateRecords(Ndb* pNdb,
if( check == -1 ) { if( check == -1 ) {
const NdbError err = pTrans->getNdbError(); const NdbError err = pTrans->getNdbError();
ERR(err); ERR(err);
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
if (err.status == NdbError::TemporaryError){ if (err.status == NdbError::TemporaryError){
NdbSleep_MilliSleep(50); NdbSleep_MilliSleep(50);
@ -2038,7 +2038,7 @@ HugoTransactions::indexUpdateRecords(Ndb* pNdb,
updated += batch; updated += batch;
} }
pNdb->closeTransaction(pTrans); closeTransaction(pNdb);
r+= batch; // Read next record r+= batch; // Read next record
} }

View file

@ -330,13 +330,17 @@ NDBT_Finalizer::NDBT_Finalizer(NDBT_TestCase* ptest,
NDBT_TestCase::NDBT_TestCase(NDBT_TestSuite* psuite, NDBT_TestCase::NDBT_TestCase(NDBT_TestSuite* psuite,
const char* pname, const char* pname,
const char* pcomment) : const char* pcomment) :
name(pname) , name(strdup(pname)) ,
comment(pcomment), comment(strdup(pcomment)),
suite(psuite){ suite(psuite)
{
_name.assign(pname);
_comment.assign(pcomment);
name= _name.c_str();
comment= _comment.c_str();
assert(suite != NULL); assert(suite != NULL);
} }
NDBT_TestCaseImpl1::NDBT_TestCaseImpl1(NDBT_TestSuite* psuite, NDBT_TestCaseImpl1::NDBT_TestCaseImpl1(NDBT_TestSuite* psuite,
const char* pname, const char* pname,
const char* pcomment) : const char* pcomment) :

View file

@ -106,8 +106,11 @@ BIN_FILES="extra/comp_err$BS extra/replace$BS extra/perror$BS \
client/mysql$BS client/mysqlshow$BS client/mysqladmin$BS \ client/mysql$BS client/mysqlshow$BS client/mysqladmin$BS \
client/mysqldump$BS client/mysqlimport$BS \ client/mysqldump$BS client/mysqlimport$BS \
client/mysqltest$BS client/mysqlcheck$BS \ client/mysqltest$BS client/mysqlcheck$BS \
client/mysqlbinlog$BS \ client/mysqlbinlog$BS \
"; tests/mysql_client_test$BS \
libmysqld/examples/mysql_client_test_embedded$BS \
libmysqld/examples/mysqltest_embedded$BS \
";
# Platform-specific bin files: # Platform-specific bin files:
if [ $BASE_SYSTEM = "netware" ] ; then if [ $BASE_SYSTEM = "netware" ] ; then
@ -126,8 +129,9 @@ else
client/.libs/mysqltest client/.libs/mysqlcheck \ client/.libs/mysqltest client/.libs/mysqlcheck \
client/.libs/mysqlbinlog client/.libs/mysqlmanagerc \ client/.libs/mysqlbinlog client/.libs/mysqlmanagerc \
client/.libs/mysqlmanager-pwgen tools/.libs/mysqlmanager \ client/.libs/mysqlmanager-pwgen tools/.libs/mysqlmanager \
tests/.libs/mysql_client_test libmysqld/examples/mysql_client_test_embedded \ tests/.libs/mysql_client_test \
libmysqld/examples/mysqltest_embedded \ libmysqld/examples/.libs/mysql_client_test_embedded \
libmysqld/examples/.libs/mysqltest_embedded \
"; ";
fi fi

View file

@ -43,18 +43,20 @@
handle bulk inserts as well (that is if someone was trying to read at handle bulk inserts as well (that is if someone was trying to read at
the same time since we would want to flush). the same time since we would want to flush).
A "meta" file is kept. All this file does is contain information on A "meta" file is kept alongside the data file. This file serves two purpose.
the number of rows. The first purpose is to track the number of rows in the table. The second
purpose is to determine if the table was closed properly or not. When the
meta file is first opened it is marked as dirty. It is opened when the table
itself is opened for writing. When the table is closed the new count for rows
is written to the meta file and the file is marked as clean. If the meta file
is opened and it is marked as dirty, it is assumed that a crash occured. At
this point an error occurs and the user is told to rebuild the file.
A rebuild scans the rows and rewrites the meta file. If corruption is found
in the data file then the meta file is not repaired.
No attempts at durability are made. You can corrupt your data. A repair At some point a recovery method for such a drastic case needs to be divised.
method was added to repair the meta file that stores row information,
but if your data file gets corrupted I haven't solved that. I could
create a repair that would solve this, but do you want to take a
chance of loosing your data?
Locks are row level, and you will get a consistant read. Transactions Locks are row level, and you will get a consistant read.
will be added later (they are not that hard to add at this
stage).
For performance as far as table scans go it is quite fast. I don't have For performance as far as table scans go it is quite fast. I don't have
good numbers but locally it has out performed both Innodb and MyISAM. For good numbers but locally it has out performed both Innodb and MyISAM. For
@ -89,7 +91,6 @@
compression but may speed up ordered searches). compression but may speed up ordered searches).
Checkpoint the meta file to allow for faster rebuilds. Checkpoint the meta file to allow for faster rebuilds.
Dirty open (right now the meta file is repaired if a crash occured). Dirty open (right now the meta file is repaired if a crash occured).
Transactions.
Option to allow for dirty reads, this would lower the sync calls, which would make Option to allow for dirty reads, this would lower the sync calls, which would make
inserts a lot faster, but would mean highly arbitrary reads. inserts a lot faster, but would mean highly arbitrary reads.
@ -347,6 +348,7 @@ ARCHIVE_SHARE *ha_archive::get_share(const char *table_name, TABLE *table)
share->crashed= TRUE; share->crashed= TRUE;
else else
(void)write_meta_file(share->meta_file, share->rows_recorded, TRUE); (void)write_meta_file(share->meta_file, share->rows_recorded, TRUE);
/* /*
It is expensive to open and close the data files and since you can't have It is expensive to open and close the data files and since you can't have
a gzip file that can be both read and written we keep a writer open a gzip file that can be both read and written we keep a writer open
@ -393,7 +395,8 @@ int ha_archive::free_share(ARCHIVE_SHARE *share)
(void)write_meta_file(share->meta_file, share->rows_recorded, FALSE); (void)write_meta_file(share->meta_file, share->rows_recorded, FALSE);
if (gzclose(share->archive_write) == Z_ERRNO) if (gzclose(share->archive_write) == Z_ERRNO)
rc= 1; rc= 1;
my_close(share->meta_file,MYF(0)); if (my_close(share->meta_file, MYF(0)))
rc= 1;
my_free((gptr) share, MYF(0)); my_free((gptr) share, MYF(0));
} }
pthread_mutex_unlock(&archive_mutex); pthread_mutex_unlock(&archive_mutex);

View file

@ -586,16 +586,13 @@ uint ha_federated::convert_row_to_internal_format(byte *record, MYSQL_ROW row)
DBUG_RETURN(0); DBUG_RETURN(0);
} }
bool ha_federated::create_where_from_key( bool ha_federated::create_where_from_key(String *to, KEY *key_info,
String *to, const byte *key, uint key_length)
KEY *key_info,
const byte *key,
uint key_length
)
{ {
uint second_loop= 0; uint second_loop= 0;
KEY_PART_INFO *key_part; KEY_PART_INFO *key_part;
bool needs_quotes; bool needs_quotes;
String tmp;
DBUG_ENTER("ha_federated::create_where_from_key"); DBUG_ENTER("ha_federated::create_where_from_key");
for (key_part= key_info->key_part ; (int) key_length > 0 ; key_part++) for (key_part= key_info->key_part ; (int) key_length > 0 ; key_part++)
@ -656,7 +653,9 @@ bool ha_federated::create_where_from_key(
uint blob_length= uint2korr(key); uint blob_length= uint2korr(key);
key+= HA_KEY_BLOB_LENGTH; key+= HA_KEY_BLOB_LENGTH;
key_length-= HA_KEY_BLOB_LENGTH; key_length-= HA_KEY_BLOB_LENGTH;
if (append_escaped(to, (char *)(key), blob_length))
tmp.set_quick((char*) key, blob_length, &my_charset_bin);
if (append_escaped(to, &tmp))
DBUG_RETURN(1); DBUG_RETURN(1);
DBUG_PRINT("ha_federated::create_where_from_key", ("blob type %s", to->c_ptr_quick())); DBUG_PRINT("ha_federated::create_where_from_key", ("blob type %s", to->c_ptr_quick()));
@ -666,7 +665,8 @@ bool ha_federated::create_where_from_key(
{ {
length= uint2korr(key); length= uint2korr(key);
key+= HA_KEY_BLOB_LENGTH; key+= HA_KEY_BLOB_LENGTH;
if (append_escaped(to, (char *)(key), length)) tmp.set_quick((char*) key, length, &my_charset_bin);
if (append_escaped(to, &tmp))
DBUG_RETURN(1); DBUG_RETURN(1);
DBUG_PRINT("ha_federated::create_where_from_key", ("varchar type %s", to->c_ptr_quick())); DBUG_PRINT("ha_federated::create_where_from_key", ("varchar type %s", to->c_ptr_quick()));
@ -680,7 +680,7 @@ bool ha_federated::create_where_from_key(
res= field->val_str(&str, (char *)(key)); res= field->val_str(&str, (char *)(key));
if (field->result_type() == STRING_RESULT) if (field->result_type() == STRING_RESULT)
{ {
if (append_escaped(to, (char *) res->ptr(), res->length())) if (append_escaped(to, res))
DBUG_RETURN(1); DBUG_RETURN(1);
res= field->val_str(&str, (char *)(key)); res= field->val_str(&str, (char *)(key));
@ -1235,7 +1235,7 @@ int ha_federated::update_row(
update_string.append(new_field_value); update_string.append(new_field_value);
new_field_value.length(0); new_field_value.length(0);
if (x+1 < table->s->fields) if ((uint) x+1 < table->s->fields)
{ {
update_string.append(", "); update_string.append(", ");
if (! has_a_primary_key) if (! has_a_primary_key)
@ -1311,7 +1311,7 @@ int ha_federated::delete_row(const byte * buf)
delete_string.append(data_string); delete_string.append(data_string);
data_string.length(0); data_string.length(0);
if (x+1 < table->s->fields) if ((uint) x+1 < table->s->fields)
delete_string.append(" AND "); delete_string.append(" AND ");
} }

View file

@ -1612,6 +1612,31 @@ innobase_rollback_to_savepoint(
DBUG_RETURN(convert_error_code_to_mysql(error, NULL)); DBUG_RETURN(convert_error_code_to_mysql(error, NULL));
} }
/*********************************************************************
Release transaction savepoint name. */
int
innobase_release_savepoint_name(
/*===========================*/
/* out: 0 if success, HA_ERR_NO_SAVEPOINT if
no savepoint with the given name */
THD* thd, /* in: handle to the MySQL thread of the user
whose transaction should be rolled back */
char* savepoint_name) /* in: savepoint name */
{
ib_longlong mysql_binlog_cache_pos;
int error = 0;
trx_t* trx;
DBUG_ENTER("innobase_release_savepoint_name");
trx = check_trx_exists(thd);
error = trx_release_savepoint_for_mysql(trx, savepoint_name);
DBUG_RETURN(convert_error_code_to_mysql(error, NULL));
}
/********************************************************************* /*********************************************************************
Sets a transaction savepoint. */ Sets a transaction savepoint. */
@ -4846,12 +4871,12 @@ ha_innobase::update_table_comment(
dict_print_info_on_foreign_keys(FALSE, file, dict_print_info_on_foreign_keys(FALSE, file,
prebuilt->trx, prebuilt->table); prebuilt->trx, prebuilt->table);
flen = ftell(file); flen = ftell(file);
if(length + flen + 3 > 64000) { if (flen < 0) {
flen = 0;
} else if (length + flen + 3 > 64000) {
flen = 64000 - 3 - length; flen = 64000 - 3 - length;
} }
ut_ad(flen > 0);
/* allocate buffer for the full string, and /* allocate buffer for the full string, and
read the contents of the temporary file */ read the contents of the temporary file */
@ -4915,12 +4940,12 @@ ha_innobase::get_foreign_key_create_info(void)
prebuilt->trx->op_info = (char*)""; prebuilt->trx->op_info = (char*)"";
flen = ftell(file); flen = ftell(file);
if(flen > 64000 - 1) { if (flen < 0) {
flen = 0;
} else if(flen > 64000 - 1) {
flen = 64000 - 1; flen = 64000 - 1;
} }
ut_ad(flen >= 0);
/* allocate buffer for the string, and /* allocate buffer for the string, and
read the contents of the temporary file */ read the contents of the temporary file */
@ -5521,12 +5546,12 @@ innodb_show_status(
srv_printf_innodb_monitor(srv_monitor_file); srv_printf_innodb_monitor(srv_monitor_file);
flen = ftell(srv_monitor_file); flen = ftell(srv_monitor_file);
os_file_set_eof(srv_monitor_file); os_file_set_eof(srv_monitor_file);
if(flen > 64000 - 1) { if (flen < 0) {
flen = 0;
} else if (flen > 64000 - 1) {
flen = 64000 - 1; flen = 64000 - 1;
} }
ut_ad(flen > 0);
/* allocate buffer for the string, and /* allocate buffer for the string, and
read the contents of the temporary file */ read the contents of the temporary file */
@ -6117,13 +6142,19 @@ innobase_get_at_most_n_mbchars(
extern "C" { extern "C" {
/********************************************************************** /**********************************************************************
This function returns true if SQL-query in the current thread This function returns true if
1) SQL-query in the current thread
is either REPLACE or LOAD DATA INFILE REPLACE. is either REPLACE or LOAD DATA INFILE REPLACE.
2) SQL-query in the current thread
is INSERT ON DUPLICATE KEY UPDATE.
NOTE that /mysql/innobase/row/row0ins.c must contain the NOTE that /mysql/innobase/row/row0ins.c must contain the
prototype for this function ! */ prototype for this function ! */
ibool ibool
innobase_query_is_replace(void) innobase_query_is_update(void)
/*===========================*/ /*===========================*/
{ {
THD* thd; THD* thd;
@ -6135,9 +6166,14 @@ innobase_query_is_replace(void)
( thd->lex->sql_command == SQLCOM_LOAD && ( thd->lex->sql_command == SQLCOM_LOAD &&
thd->lex->duplicates == DUP_REPLACE )) { thd->lex->duplicates == DUP_REPLACE )) {
return true; return true;
} else {
return false;
} }
if ( thd->lex->sql_command == SQLCOM_INSERT &&
thd->lex->duplicates == DUP_UPDATE ) {
return true;
}
return false;
} }
} }

View file

@ -244,6 +244,9 @@ int innobase_savepoint(
THD* thd, THD* thd,
char* savepoint_name, char* savepoint_name,
my_off_t binlog_cache_pos); my_off_t binlog_cache_pos);
int innobase_release_savepoint_name(
THD* thd,
char* savepoint_name);
int innobase_close_connection(THD *thd); int innobase_close_connection(THD *thd);
int innobase_drop_database(char *path); int innobase_drop_database(char *path);
bool innodb_show_status(THD* thd); bool innodb_show_status(THD* thd);

View file

@ -869,6 +869,35 @@ int ha_rollback_to_savepoint(THD *thd, char *savepoint_name)
DBUG_RETURN(error); DBUG_RETURN(error);
} }
int ha_release_savepoint_name(THD *thd, char *savepoint_name)
{
my_off_t binlog_cache_pos=0;
bool operation_done=0;
int error=0;
DBUG_ENTER("ha_release_savepoint_name");
#ifdef USING_TRANSACTIONS
if (opt_using_transactions)
{
#ifdef HAVE_INNOBASE_DB
if ((error=innobase_release_savepoint_name(thd, savepoint_name)))
{
my_error(ER_ERROR_DURING_ROLLBACK, MYF(0), error);
error=1;
}
else if (mysql_bin_log.is_open())
{
Query_log_event qinfo(thd, thd->query, thd->query_length, TRUE, FALSE);
if (mysql_bin_log.write(&qinfo))
error= 1;
}
operation_done=1;
#endif
}
#endif /* USING_TRANSACTIONS */
DBUG_RETURN(error);
}
/* /*
Sets a transaction savepoint. Sets a transaction savepoint.

View file

@ -653,6 +653,7 @@ int ha_commit_trans(THD *thd, THD_TRANS *trans);
int ha_rollback_trans(THD *thd, THD_TRANS *trans); int ha_rollback_trans(THD *thd, THD_TRANS *trans);
int ha_rollback_to_savepoint(THD *thd, char *savepoint_name); int ha_rollback_to_savepoint(THD *thd, char *savepoint_name);
int ha_savepoint(THD *thd, char *savepoint_name); int ha_savepoint(THD *thd, char *savepoint_name);
int ha_release_savepoint_name(THD *thd, char *savepoint_name);
int ha_autocommit_or_rollback(THD *thd, int error); int ha_autocommit_or_rollback(THD *thd, int error);
void ha_set_spin_retries(uint retries); void ha_set_spin_retries(uint retries);
bool ha_flush_logs(void); bool ha_flush_logs(void);

View file

@ -1775,12 +1775,13 @@ resolve_ref_in_select_and_group(THD *thd, Item_ident *ref, SELECT_LEX *select)
if (select_ref != not_found_item && !ambiguous_fields) if (select_ref != not_found_item && !ambiguous_fields)
{ {
DBUG_ASSERT(*select_ref); DBUG_ASSERT(*select_ref);
if (! (*select_ref)->fixed) if (!select->ref_pointer_array[counter])
{ {
my_error(ER_ILLEGAL_REFERENCE, MYF(0), my_error(ER_ILLEGAL_REFERENCE, MYF(0),
ref->name, "forward reference in item list"); ref->name, "forward reference in item list");
return NULL; return NULL;
} }
DBUG_ASSERT((*select_ref)->fixed);
return (select->ref_pointer_array + counter); return (select->ref_pointer_array + counter);
} }
if (group_by_ref) if (group_by_ref)

View file

@ -215,7 +215,7 @@ class Item_bool_rowready_func2 :public Item_bool_func2
public: public:
Item_bool_rowready_func2(Item *a, Item *b) :Item_bool_func2(a, b) Item_bool_rowready_func2(Item *a, Item *b) :Item_bool_func2(a, b)
{ {
allowed_arg_cols= a->cols(); allowed_arg_cols= 0; // Fetch this value from first argument
} }
Item *neg_transformer(THD *thd); Item *neg_transformer(THD *thd);
virtual Item *negated_item(); virtual Item *negated_item();
@ -427,7 +427,10 @@ class Item_func_interval :public Item_int_func
double *intervals; double *intervals;
public: public:
Item_func_interval(Item_row *a) Item_func_interval(Item_row *a)
:Item_int_func(a),row(a),intervals(0) { allowed_arg_cols= a->cols(); } :Item_int_func(a),row(a),intervals(0)
{
allowed_arg_cols= 0; // Fetch this value from first argument
}
longlong val_int(); longlong val_int();
void fix_length_and_dec(); void fix_length_and_dec();
const char *func_name() const { return "interval"; } const char *func_name() const { return "interval"; }
@ -780,7 +783,7 @@ class Item_func_in :public Item_int_func
Item_func_in(List<Item> &list) Item_func_in(List<Item> &list)
:Item_int_func(list), array(0), in_item(0), have_null(0) :Item_int_func(list), array(0), in_item(0), have_null(0)
{ {
allowed_arg_cols= args[0]->cols(); allowed_arg_cols= 0; // Fetch this value from first argument
} }
longlong val_int(); longlong val_int();
void fix_length_and_dec(); void fix_length_and_dec();

View file

@ -308,10 +308,23 @@ Item_func::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
We can't yet set item to *arg as fix_fields may change *arg We can't yet set item to *arg as fix_fields may change *arg
We shouldn't call fix_fields() twice, so check 'fixed' field first We shouldn't call fix_fields() twice, so check 'fixed' field first
*/ */
if ((!(*arg)->fixed && (*arg)->fix_fields(thd, tables, arg)) || if ((!(*arg)->fixed && (*arg)->fix_fields(thd, tables, arg)))
(*arg)->check_cols(allowed_arg_cols))
return TRUE; /* purecov: inspected */ return TRUE; /* purecov: inspected */
item= *arg; item= *arg;
if (allowed_arg_cols)
{
if (item->check_cols(allowed_arg_cols))
return 1;
}
else
{
/* we have to fetch allowed_arg_cols from first argument */
DBUG_ASSERT(arg == args); // it is first argument
allowed_arg_cols= item->cols();
DBUG_ASSERT(allowed_arg_cols); // Can't be 0 any more
}
if (item->maybe_null) if (item->maybe_null)
maybe_null=1; maybe_null=1;

View file

@ -32,6 +32,10 @@ class Item_func :public Item_result_field
{ {
protected: protected:
Item **args, *tmp_arg[2]; Item **args, *tmp_arg[2];
/*
Allowed numbers of columns in result (usually 1, which means scalar value)
0 means get this number from first argument
*/
uint allowed_arg_cols; uint allowed_arg_cols;
public: public:
uint arg_count; uint arg_count;

View file

@ -2189,6 +2189,7 @@ String *Item_func_conv::val_str(String *str)
return 0; return 0;
} }
null_value=0; null_value=0;
unsigned_flag= !(from_base < 0);
if (from_base < 0) if (from_base < 0)
dec= my_strntoll(res->charset(),res->ptr(),res->length(),-from_base,&endptr,&err); dec= my_strntoll(res->charset(),res->ptr(),res->length(),-from_base,&endptr,&err);
else else
@ -2643,18 +2644,13 @@ String *Item_func_quote::val_str(String *str)
for (from= (char*) arg->ptr(), end= from + arg_length; from < end; from++) for (from= (char*) arg->ptr(), end= from + arg_length; from < end; from++)
new_length+= get_esc_bit(escmask, (uchar) *from); new_length+= get_esc_bit(escmask, (uchar) *from);
/* if (tmp_value.alloc(new_length))
We have to use realloc() instead of alloc() as we want to keep the
old result in arg
*/
if (arg->realloc(new_length))
goto null; goto null;
/* /*
As 'arg' and 'str' may be the same string, we must replace characters We replace characters from the end to the beginning
from the end to the beginning
*/ */
to= (char*) arg->ptr() + new_length - 1; to= (char*) tmp_value.ptr() + new_length - 1;
*to--= '\''; *to--= '\'';
for (start= (char*) arg->ptr(),end= start + arg_length; end-- != start; to--) for (start= (char*) arg->ptr(),end= start + arg_length; end-- != start; to--)
{ {
@ -2682,10 +2678,10 @@ String *Item_func_quote::val_str(String *str)
} }
} }
*to= '\''; *to= '\'';
arg->length(new_length); tmp_value.length(new_length);
str->set_charset(collation.collation); tmp_value.set_charset(collation.collation);
null_value= 0; null_value= 0;
return arg; return &tmp_value;
null: null:
null_value= 1; null_value= 1;

View file

@ -596,6 +596,7 @@ public:
class Item_func_quote :public Item_str_func class Item_func_quote :public Item_str_func
{ {
String tmp_value;
public: public:
Item_func_quote(Item *a) :Item_str_func(a) {} Item_func_quote(Item *a) :Item_str_func(a) {}
const char *func_name() const { return "quote"; } const char *func_name() const { return "quote"; }

View file

@ -995,6 +995,10 @@ Item_in_subselect::row_value_transformer(JOIN *join)
List_iterator_fast<Item> li(select_lex->item_list); List_iterator_fast<Item> li(select_lex->item_list);
for (uint i= 0; i < n; i++) for (uint i= 0; i < n; i++)
{ {
DBUG_ASSERT(left_expr->fixed && select_lex->ref_pointer_array[i]->fixed);
if (select_lex->ref_pointer_array[i]->
check_cols(left_expr->el(i)->cols()))
goto err;
Item *func= new Item_ref_null_helper(this, Item *func= new Item_ref_null_helper(this,
select_lex->ref_pointer_array+i, select_lex->ref_pointer_array+i,
(char *) "<no matter>", (char *) "<no matter>",
@ -1117,6 +1121,7 @@ void subselect_single_select_engine::cleanup()
DBUG_ENTER("subselect_single_select_engine::cleanup"); DBUG_ENTER("subselect_single_select_engine::cleanup");
prepared= optimized= executed= 0; prepared= optimized= executed= 0;
join= 0; join= 0;
result->cleanup();
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
@ -1125,6 +1130,7 @@ void subselect_union_engine::cleanup()
{ {
DBUG_ENTER("subselect_union_engine::cleanup"); DBUG_ENTER("subselect_union_engine::cleanup");
unit->reinit_exec_mechanism(); unit->reinit_exec_mechanism();
result->cleanup();
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
@ -1132,6 +1138,10 @@ void subselect_union_engine::cleanup()
void subselect_uniquesubquery_engine::cleanup() void subselect_uniquesubquery_engine::cleanup()
{ {
DBUG_ENTER("subselect_uniquesubquery_engine::cleanup"); DBUG_ENTER("subselect_uniquesubquery_engine::cleanup");
/*
subselect_uniquesubquery_engine have not 'result' assigbed, so we do not
cleanup() it
*/
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
@ -1415,13 +1425,15 @@ int subselect_indexsubquery_engine::exec()
uint subselect_single_select_engine::cols() uint subselect_single_select_engine::cols()
{ {
return select_lex->item_list.elements; DBUG_ASSERT(select_lex->join); // should be called after fix_fields()
return select_lex->join->fields_list.elements;
} }
uint subselect_union_engine::cols() uint subselect_union_engine::cols()
{ {
return unit->first_select()->item_list.elements; DBUG_ASSERT(unit->is_prepared()); // should be called after fix_fields()
return unit->types.elements;
} }

View file

@ -99,6 +99,7 @@ static SYMBOL symbols[] = {
{ "CASCADE", SYM(CASCADE)}, { "CASCADE", SYM(CASCADE)},
{ "CASCADED", SYM(CASCADED)}, { "CASCADED", SYM(CASCADED)},
{ "CASE", SYM(CASE_SYM)}, { "CASE", SYM(CASE_SYM)},
{ "CHAIN", SYM(CHAIN_SYM)},
{ "CHANGE", SYM(CHANGE)}, { "CHANGE", SYM(CHANGE)},
{ "CHANGED", SYM(CHANGED)}, { "CHANGED", SYM(CHANGED)},
{ "CHAR", SYM(CHAR_SYM)}, { "CHAR", SYM(CHAR_SYM)},
@ -385,6 +386,7 @@ static SYMBOL symbols[] = {
{ "RELAY_LOG_FILE", SYM(RELAY_LOG_FILE_SYM)}, { "RELAY_LOG_FILE", SYM(RELAY_LOG_FILE_SYM)},
{ "RELAY_LOG_POS", SYM(RELAY_LOG_POS_SYM)}, { "RELAY_LOG_POS", SYM(RELAY_LOG_POS_SYM)},
{ "RELAY_THREAD", SYM(RELAY_THREAD)}, { "RELAY_THREAD", SYM(RELAY_THREAD)},
{ "RELEASE", SYM(RELEASE_SYM)},
{ "RELOAD", SYM(RELOAD)}, { "RELOAD", SYM(RELOAD)},
{ "RENAME", SYM(RENAME)}, { "RENAME", SYM(RENAME)},
{ "REPAIR", SYM(REPAIR)}, { "REPAIR", SYM(REPAIR)},

View file

@ -715,7 +715,6 @@ bool mysql_do(THD *thd, List<Item> &values);
/* sql_analyse.h */ /* sql_analyse.h */
bool append_escaped(String *to_str, String *from_str); bool append_escaped(String *to_str, String *from_str);
bool append_escaped(String *to_str, char *from, uint from_len);
/* sql_show.cc */ /* sql_show.cc */
bool mysqld_show_open_tables(THD *thd,const char *wild); bool mysqld_show_open_tables(THD *thd,const char *wild);

View file

@ -4176,7 +4176,7 @@ enum options_mysqld
OPT_NDB_FORCE_SEND, OPT_NDB_AUTOINCREMENT_PREFETCH_SZ, OPT_NDB_FORCE_SEND, OPT_NDB_AUTOINCREMENT_PREFETCH_SZ,
OPT_NDB_SHM, OPT_NDB_OPTIMIZED_NODE_SELECTION, OPT_NDB_SHM, OPT_NDB_OPTIMIZED_NODE_SELECTION,
OPT_SKIP_SAFEMALLOC, OPT_SKIP_SAFEMALLOC,
OPT_TEMP_POOL, OPT_TX_ISOLATION, OPT_TEMP_POOL, OPT_TX_ISOLATION, OPT_COMPLETION_TYPE,
OPT_SKIP_STACK_TRACE, OPT_SKIP_SYMLINKS, OPT_SKIP_STACK_TRACE, OPT_SKIP_SYMLINKS,
OPT_MAX_BINLOG_DUMP_EVENTS, OPT_SPORADIC_BINLOG_DUMP_FAIL, OPT_MAX_BINLOG_DUMP_EVENTS, OPT_SPORADIC_BINLOG_DUMP_FAIL,
OPT_SAFE_USER_CREATE, OPT_SQL_MODE, OPT_SAFE_USER_CREATE, OPT_SQL_MODE,
@ -4251,7 +4251,11 @@ enum options_mysqld
OPT_RANGE_ALLOC_BLOCK_SIZE, OPT_RANGE_ALLOC_BLOCK_SIZE,
OPT_QUERY_ALLOC_BLOCK_SIZE, OPT_QUERY_PREALLOC_SIZE, OPT_QUERY_ALLOC_BLOCK_SIZE, OPT_QUERY_PREALLOC_SIZE,
OPT_TRANS_ALLOC_BLOCK_SIZE, OPT_TRANS_PREALLOC_SIZE, OPT_TRANS_ALLOC_BLOCK_SIZE, OPT_TRANS_PREALLOC_SIZE,
OPT_SYNC_FRM, OPT_SYNC_BINLOG, OPT_BDB_NOSYNC, OPT_SYNC_FRM, OPT_SYNC_BINLOG,
OPT_SYNC_REPLICATION,
OPT_SYNC_REPLICATION_SLAVE_ID,
OPT_SYNC_REPLICATION_TIMEOUT,
OPT_BDB_NOSYNC,
OPT_ENABLE_SHARED_MEMORY, OPT_ENABLE_SHARED_MEMORY,
OPT_SHARED_MEMORY_BASE_NAME, OPT_SHARED_MEMORY_BASE_NAME,
OPT_OLD_PASSWORDS, OPT_OLD_PASSWORDS,
@ -4363,6 +4367,10 @@ Disable with --skip-bdb (will save memory).",
{"collation-server", OPT_DEFAULT_COLLATION, "Set the default collation.", {"collation-server", OPT_DEFAULT_COLLATION, "Set the default collation.",
(gptr*) &default_collation_name, (gptr*) &default_collation_name, (gptr*) &default_collation_name, (gptr*) &default_collation_name,
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 }, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
{"completion-type", OPT_COMPLETION_TYPE, "Default completion type.",
(gptr*) &global_system_variables.completion_type,
(gptr*) &max_system_variables.completion_type, 0, GET_ULONG,
REQUIRED_ARG, 0, 0, 2, 0, 1, 0},
{"concurrent-insert", OPT_CONCURRENT_INSERT, {"concurrent-insert", OPT_CONCURRENT_INSERT,
"Use concurrent insert with MyISAM. Disable with --skip-concurrent-insert.", "Use concurrent insert with MyISAM. Disable with --skip-concurrent-insert.",
(gptr*) &myisam_concurrent_insert, (gptr*) &myisam_concurrent_insert, (gptr*) &myisam_concurrent_insert, (gptr*) &myisam_concurrent_insert,
@ -5443,6 +5451,23 @@ The minimum value for this variable is 4096.",
(gptr*) &sync_binlog_period, (gptr*) &sync_binlog_period,
(gptr*) &sync_binlog_period, 0, GET_ULONG, REQUIRED_ARG, 0, 0, ~0L, 0, 1, (gptr*) &sync_binlog_period, 0, GET_ULONG, REQUIRED_ARG, 0, 0, ~0L, 0, 1,
0}, 0},
#ifdef DOES_NOTHING_YET
{"sync-replication", OPT_SYNC_REPLICATION,
"Enable synchronous replication",
(gptr*) &global_system_variables.sync_replication,
(gptr*) &global_system_variables.sync_replication,
0, GET_ULONG, REQUIRED_ARG, 0, 0, 1, 0, 1, 0},
{"sync-replication-slave-id", OPT_SYNC_REPLICATION_SLAVE_ID,
"Synchronous replication is wished for this slave",
(gptr*) &global_system_variables.sync_replication_slave_id,
(gptr*) &global_system_variables.sync_replication_slave_id,
0, GET_ULONG, REQUIRED_ARG, 0, 0, ~0L, 0, 1, 0},
{"sync-replication-timeout", OPT_SYNC_REPLICATION_TIMEOUT,
"Synchronous replication timeout",
(gptr*) &global_system_variables.sync_replication_timeout,
(gptr*) &global_system_variables.sync_replication_timeout,
0, GET_ULONG, REQUIRED_ARG, 10, 0, ~0L, 0, 1, 0},
#endif
{"sync-frm", OPT_SYNC_FRM, "Sync .frm to disk on create. Enabled by default", {"sync-frm", OPT_SYNC_FRM, "Sync .frm to disk on create. Enabled by default",
(gptr*) &opt_sync_frm, (gptr*) &opt_sync_frm, 0, GET_BOOL, NO_ARG, 1, 0, (gptr*) &opt_sync_frm, (gptr*) &opt_sync_frm, 0, GET_BOOL, NO_ARG, 1, 0,
0, 0, 0, 0}, 0, 0, 0, 0},

View file

@ -100,6 +100,8 @@ static int check_pseudo_thread_id(THD *thd, set_var *var);
static bool set_log_bin(THD *thd, set_var *var); static bool set_log_bin(THD *thd, set_var *var);
static void fix_low_priority_updates(THD *thd, enum_var_type type); static void fix_low_priority_updates(THD *thd, enum_var_type type);
static void fix_tx_isolation(THD *thd, enum_var_type type); static void fix_tx_isolation(THD *thd, enum_var_type type);
static int check_completion_type(THD *thd, set_var *var);
static void fix_completion_type(THD *thd, enum_var_type type);
static void fix_net_read_timeout(THD *thd, enum_var_type type); static void fix_net_read_timeout(THD *thd, enum_var_type type);
static void fix_net_write_timeout(THD *thd, enum_var_type type); static void fix_net_write_timeout(THD *thd, enum_var_type type);
static void fix_net_retry_count(THD *thd, enum_var_type type); static void fix_net_retry_count(THD *thd, enum_var_type type);
@ -149,6 +151,10 @@ sys_var_character_set_database sys_character_set_database("character_set_databas
sys_var_character_set_client sys_character_set_client("character_set_client"); sys_var_character_set_client sys_character_set_client("character_set_client");
sys_var_character_set_connection sys_character_set_connection("character_set_connection"); sys_var_character_set_connection sys_character_set_connection("character_set_connection");
sys_var_character_set_results sys_character_set_results("character_set_results"); sys_var_character_set_results sys_character_set_results("character_set_results");
sys_var_thd_ulong sys_completion_type("completion_type",
&SV::completion_type,
check_completion_type,
fix_completion_type);
sys_var_collation_connection sys_collation_connection("collation_connection"); sys_var_collation_connection sys_collation_connection("collation_connection");
sys_var_collation_database sys_collation_database("collation_database"); sys_var_collation_database sys_collation_database("collation_database");
sys_var_collation_server sys_collation_server("collation_server"); sys_var_collation_server sys_collation_server("collation_server");
@ -352,6 +358,14 @@ sys_var_thd_storage_engine sys_storage_engine("storage_engine",
&SV::table_type); &SV::table_type);
#ifdef HAVE_REPLICATION #ifdef HAVE_REPLICATION
sys_var_sync_binlog_period sys_sync_binlog_period("sync_binlog", &sync_binlog_period); sys_var_sync_binlog_period sys_sync_binlog_period("sync_binlog", &sync_binlog_period);
sys_var_thd_ulong sys_sync_replication("sync_replication",
&SV::sync_replication);
sys_var_thd_ulong sys_sync_replication_slave_id(
"sync_replication_slave_id",
&SV::sync_replication_slave_id);
sys_var_thd_ulong sys_sync_replication_timeout(
"sync_replication_timeout",
&SV::sync_replication_timeout);
#endif #endif
sys_var_bool_ptr sys_sync_frm("sync_frm", &opt_sync_frm); sys_var_bool_ptr sys_sync_frm("sync_frm", &opt_sync_frm);
sys_var_long_ptr sys_table_cache_size("table_cache", sys_var_long_ptr sys_table_cache_size("table_cache",
@ -532,6 +546,7 @@ sys_var *sys_variables[]=
&sys_collation_connection, &sys_collation_connection,
&sys_collation_database, &sys_collation_database,
&sys_collation_server, &sys_collation_server,
&sys_completion_type,
&sys_concurrent_insert, &sys_concurrent_insert,
&sys_connect_timeout, &sys_connect_timeout,
&sys_date_format, &sys_date_format,
@ -640,6 +655,9 @@ sys_var *sys_variables[]=
&sys_storage_engine, &sys_storage_engine,
#ifdef HAVE_REPLICATION #ifdef HAVE_REPLICATION
&sys_sync_binlog_period, &sys_sync_binlog_period,
&sys_sync_replication,
&sys_sync_replication_slave_id,
&sys_sync_replication_timeout,
#endif #endif
&sys_sync_frm, &sys_sync_frm,
&sys_table_cache_size, &sys_table_cache_size,
@ -708,6 +726,7 @@ struct show_var_st init_vars[]= {
{sys_collation_connection.name,(char*) &sys_collation_connection, SHOW_SYS}, {sys_collation_connection.name,(char*) &sys_collation_connection, SHOW_SYS},
{sys_collation_database.name,(char*) &sys_collation_database, SHOW_SYS}, {sys_collation_database.name,(char*) &sys_collation_database, SHOW_SYS},
{sys_collation_server.name,(char*) &sys_collation_server, SHOW_SYS}, {sys_collation_server.name,(char*) &sys_collation_server, SHOW_SYS},
{sys_completion_type.name, (char*) &sys_completion_type, SHOW_SYS},
{sys_concurrent_insert.name,(char*) &sys_concurrent_insert, SHOW_SYS}, {sys_concurrent_insert.name,(char*) &sys_concurrent_insert, SHOW_SYS},
{sys_connect_timeout.name, (char*) &sys_connect_timeout, SHOW_SYS}, {sys_connect_timeout.name, (char*) &sys_connect_timeout, SHOW_SYS},
{"datadir", mysql_real_data_home, SHOW_CHAR}, {"datadir", mysql_real_data_home, SHOW_CHAR},
@ -907,6 +926,9 @@ struct show_var_st init_vars[]= {
{sys_storage_engine.name, (char*) &sys_storage_engine, SHOW_SYS}, {sys_storage_engine.name, (char*) &sys_storage_engine, SHOW_SYS},
#ifdef HAVE_REPLICATION #ifdef HAVE_REPLICATION
{sys_sync_binlog_period.name,(char*) &sys_sync_binlog_period, SHOW_SYS}, {sys_sync_binlog_period.name,(char*) &sys_sync_binlog_period, SHOW_SYS},
{sys_sync_replication.name, (char*) &sys_sync_replication, SHOW_SYS},
{sys_sync_replication_slave_id.name, (char*) &sys_sync_replication_slave_id,SHOW_SYS},
{sys_sync_replication_timeout.name, (char*) &sys_sync_replication_timeout,SHOW_SYS},
#endif #endif
{sys_sync_frm.name, (char*) &sys_sync_frm, SHOW_SYS}, {sys_sync_frm.name, (char*) &sys_sync_frm, SHOW_SYS},
#ifdef HAVE_TZNAME #ifdef HAVE_TZNAME
@ -1122,6 +1144,21 @@ static void fix_tx_isolation(THD *thd, enum_var_type type)
thd->variables.tx_isolation); thd->variables.tx_isolation);
} }
static void fix_completion_type(THD *thd __attribute__(unused),
enum_var_type type __attribute__(unused)) {}
static int check_completion_type(THD *thd, set_var *var)
{
longlong val= var->value->val_int();
if (val < 0 || val > 2)
{
char buf[64];
my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), var->var->name, llstr(val, buf));
return 1;
}
return 0;
}
/* /*
If we are changing the thread variable, we have to copy it to NET too If we are changing the thread variable, we have to copy it to NET too

View file

@ -59,8 +59,6 @@ int compare_ulonglong2(void* cmp_arg __attribute__((unused)),
return compare_ulonglong(s,t); return compare_ulonglong(s,t);
} }
bool append_escaped(String *to_str, String *from_str);
bool append_escaped(String *to_str, char *from, uint from_len);
Procedure * Procedure *
proc_analyse_init(THD *thd, ORDER *param, select_result *result, proc_analyse_init(THD *thd, ORDER *param, select_result *result,
@ -1087,38 +1085,3 @@ bool append_escaped(String *to_str, String *from_str)
} }
return 0; return 0;
} }
bool append_escaped(String *to_str, char *from, uint from_len)
{
char *end, c;
if (to_str->realloc(to_str->length() + from_len))
return 1;
end= from + from_len;
for (; from < end; from++)
{
c= *from;
switch (c) {
case '\0':
c= '0';
break;
case '\032':
c= 'Z';
break;
case '\\':
case '\'':
break;
default:
goto normal_character;
}
if (to_str->append('\\'))
return 1;
normal_character:
if (to_str->append(c))
return 1;
}
return 0;
}

View file

@ -2758,6 +2758,20 @@ bool setup_fields(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
thd->allow_sum_func= allow_sum_func; thd->allow_sum_func= allow_sum_func;
thd->where="field list"; thd->where="field list";
/*
To prevent fail on forward lookup we fill it with zerows,
then if we got pointer on zero after find_item_in_list we will know
that it is forward lookup.
There is other way to solve problem: fill array with pointers to list,
but it will be slower.
TODO: remove it when (if) we made one list for allfields and
ref_pointer_array
*/
if (ref_pointer_array)
bzero(ref_pointer_array, sizeof(Item *) * fields.elements);
Item **ref= ref_pointer_array; Item **ref= ref_pointer_array;
while ((item= it++)) while ((item= it++))
{ {

View file

@ -1303,6 +1303,14 @@ bool select_singlerow_subselect::send_data(List<Item> &items)
} }
void select_max_min_finder_subselect::cleanup()
{
DBUG_ENTER("select_max_min_finder_subselect::cleanup");
cache= 0;
DBUG_VOID_RETURN;
}
bool select_max_min_finder_subselect::send_data(List<Item> &items) bool select_max_min_finder_subselect::send_data(List<Item> &items)
{ {
DBUG_ENTER("select_max_min_finder_subselect::send_data"); DBUG_ENTER("select_max_min_finder_subselect::send_data");

View file

@ -408,6 +408,7 @@ struct system_variables
ulong table_type; ulong table_type;
ulong tmp_table_size; ulong tmp_table_size;
ulong tx_isolation; ulong tx_isolation;
ulong completion_type;
/* Determines which non-standard SQL behaviour should be enabled */ /* Determines which non-standard SQL behaviour should be enabled */
ulong sql_mode; ulong sql_mode;
/* check of key presence in updatable view */ /* check of key presence in updatable view */
@ -430,6 +431,11 @@ struct system_variables
my_bool low_priority_updates; my_bool low_priority_updates;
my_bool new_mode; my_bool new_mode;
my_bool query_cache_wlock_invalidate; my_bool query_cache_wlock_invalidate;
#ifdef HAVE_REPLICATION
ulong sync_replication;
ulong sync_replication_slave_id;
ulong sync_replication_timeout;
#endif /* HAVE_REPLICATION */
#ifdef HAVE_INNOBASE_DB #ifdef HAVE_INNOBASE_DB
my_bool innodb_table_locks; my_bool innodb_table_locks;
#endif /* HAVE_INNOBASE_DB */ #endif /* HAVE_INNOBASE_DB */
@ -1509,6 +1515,7 @@ public:
select_max_min_finder_subselect(Item_subselect *item, bool mx) select_max_min_finder_subselect(Item_subselect *item, bool mx)
:select_subselect(item), cache(0), fmax(mx) :select_subselect(item), cache(0), fmax(mx)
{} {}
void cleanup();
bool send_data(List<Item> &items); bool send_data(List<Item> &items);
bool cmp_real(); bool cmp_real();
bool cmp_int(); bool cmp_int();

View file

@ -1811,13 +1811,13 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
is the same table (Bug #6034). Do the preparation after the select phase is the same table (Bug #6034). Do the preparation after the select phase
in select_insert::prepare2(). in select_insert::prepare2().
*/ */
if (info.ignore || info.handle_duplicates != DUP_ERROR)
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
table->file->start_bulk_insert((ha_rows) 0); table->file->start_bulk_insert((ha_rows) 0);
} }
restore_record(table,s->default_values); // Get empty record restore_record(table,s->default_values); // Get empty record
table->next_number_field=table->found_next_number_field; table->next_number_field=table->found_next_number_field;
thd->cuted_fields=0; thd->cuted_fields=0;
if (info.ignore || info.handle_duplicates != DUP_ERROR)
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
thd->no_trans_update= 0; thd->no_trans_update= 0;
thd->abort_on_warning= (!info.ignore && thd->abort_on_warning= (!info.ignore &&
(thd->variables.sql_mode & (thd->variables.sql_mode &
@ -1847,14 +1847,9 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
int select_insert::prepare2(void) int select_insert::prepare2(void)
{ {
DBUG_ENTER("select_insert::prepare2"); DBUG_ENTER("select_insert::prepare2");
if (thd->lex->current_select->options & OPTION_BUFFER_RESULT) if (thd->lex->current_select->options & OPTION_BUFFER_RESULT)
{
if (info.ignore || info.handle_duplicates != DUP_ERROR)
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
table->file->start_bulk_insert((ha_rows) 0); table->file->start_bulk_insert((ha_rows) 0);
} DBUG_RETURN(0);
return 0;
} }

View file

@ -177,7 +177,10 @@ void lex_start(THD *thd, uchar *buf,uint length)
void lex_end(LEX *lex) void lex_end(LEX *lex)
{ {
lex->select_lex.expr_list.delete_elements(); // If error when parsing sql-varargs for (SELECT_LEX *sl= lex->all_selects_list;
sl;
sl= sl->next_select_in_list())
sl->expr_list.delete_elements(); // If error when parsing sql-varargs
x_free(lex->yacc_yyss); x_free(lex->yacc_yyss);
x_free(lex->yacc_yyvs); x_free(lex->yacc_yyvs);
} }

View file

@ -67,7 +67,7 @@ enum enum_sql_command {
SQLCOM_ASSIGN_TO_KEYCACHE, SQLCOM_PRELOAD_KEYS, SQLCOM_ASSIGN_TO_KEYCACHE, SQLCOM_PRELOAD_KEYS,
SQLCOM_FLUSH, SQLCOM_KILL, SQLCOM_ANALYZE, SQLCOM_FLUSH, SQLCOM_KILL, SQLCOM_ANALYZE,
SQLCOM_ROLLBACK, SQLCOM_ROLLBACK_TO_SAVEPOINT, SQLCOM_ROLLBACK, SQLCOM_ROLLBACK_TO_SAVEPOINT,
SQLCOM_COMMIT, SQLCOM_SAVEPOINT, SQLCOM_COMMIT, SQLCOM_SAVEPOINT, SQLCOM_RELEASE_SAVEPOINT,
SQLCOM_SLAVE_START, SQLCOM_SLAVE_STOP, SQLCOM_SLAVE_START, SQLCOM_SLAVE_STOP,
SQLCOM_BEGIN, SQLCOM_LOAD_MASTER_TABLE, SQLCOM_CHANGE_MASTER, SQLCOM_BEGIN, SQLCOM_LOAD_MASTER_TABLE, SQLCOM_CHANGE_MASTER,
SQLCOM_RENAME_TABLE, SQLCOM_BACKUP_TABLE, SQLCOM_RESTORE_TABLE, SQLCOM_RENAME_TABLE, SQLCOM_BACKUP_TABLE, SQLCOM_RESTORE_TABLE,
@ -416,6 +416,7 @@ public:
void print(String *str); void print(String *str);
ulong init_prepare_fake_select_lex(THD *thd); ulong init_prepare_fake_select_lex(THD *thd);
inline bool is_prepared() { return prepared; }
bool change_result(select_subselect *result, select_subselect *old_result); bool change_result(select_subselect *result, select_subselect *old_result);
void set_limit(st_select_lex *values, st_select_lex *sl); void set_limit(st_select_lex *values, st_select_lex *sl);
@ -718,6 +719,7 @@ typedef struct st_lex
uint8 create_view_check; uint8 create_view_check;
bool drop_if_exists, drop_temporary, local_file, one_shot_set; bool drop_if_exists, drop_temporary, local_file, one_shot_set;
bool in_comment, ignore_space, verbose, no_write_to_binlog; bool in_comment, ignore_space, verbose, no_write_to_binlog;
bool tx_chain, tx_release;
/* special JOIN::prepare mode: changing of query is prohibited */ /* special JOIN::prepare mode: changing of query is prohibited */
bool view_prepare_mode; bool view_prepare_mode;
bool safe_to_cache_query; bool safe_to_cache_query;

View file

@ -134,6 +134,28 @@ static bool end_active_trans(THD *thd)
DBUG_RETURN(error); DBUG_RETURN(error);
} }
static bool begin_trans(THD *thd)
{
int error=0;
if (thd->locked_tables)
{
thd->lock=thd->locked_tables;
thd->locked_tables=0; // Will be automatically closed
close_thread_tables(thd); // Free tables
}
if (end_active_trans(thd))
error= -1;
else
{
LEX *lex= thd->lex;
thd->options= ((thd->options & (ulong) ~(OPTION_STATUS_NO_TRANS_UPDATE)) |
OPTION_BEGIN);
thd->server_status|= SERVER_STATUS_IN_TRANS;
if (lex->start_transaction_opt & MYSQL_START_TRANS_OPT_WITH_CONS_SNAPSHOT)
error= ha_start_consistent_snapshot(thd);
}
return error;
}
#ifdef HAVE_REPLICATION #ifdef HAVE_REPLICATION
inline bool all_tables_not_ok(THD *thd, TABLE_LIST *tables) inline bool all_tables_not_ok(THD *thd, TABLE_LIST *tables)
@ -690,6 +712,8 @@ static int check_connection(THD *thd)
DBUG_PRINT("info", DBUG_PRINT("info",
("New connection received on %s", vio_description(net->vio))); ("New connection received on %s", vio_description(net->vio)));
vio_in_addr(net->vio,&thd->remote.sin_addr);
if (!thd->host) // If TCP/IP connection if (!thd->host) // If TCP/IP connection
{ {
char ip[30]; char ip[30];
@ -734,7 +758,6 @@ static int check_connection(THD *thd)
DBUG_PRINT("info",("Host: %s",thd->host)); DBUG_PRINT("info",("Host: %s",thd->host));
thd->host_or_ip= thd->host; thd->host_or_ip= thd->host;
thd->ip= 0; thd->ip= 0;
bzero((char*) &thd->remote, sizeof(struct sockaddr));
} }
vio_keepalive(net->vio, TRUE); vio_keepalive(net->vio, TRUE);
ulong pkt_len= 0; ulong pkt_len= 0;
@ -1262,6 +1285,127 @@ err:
DBUG_RETURN(error); DBUG_RETURN(error);
} }
/*
Ends the current transaction and (maybe) begin the next
First uint4 in packet is completion type
Remainder is savepoint name (if required)
SYNOPSIS
mysql_endtrans()
thd Current thread
completion Completion type
savepoint_name Savepoint when doing ROLLBACK_SAVEPOINT_NAME
or RELEASE_SAVEPOINT_NAME
release (OUT) indicator for release operation
RETURN
0 - OK
*/
enum enum_mysql_completiontype {
ROLLBACK_RELEASE=-2,
COMMIT_RELEASE=-1,
COMMIT=0,
ROLLBACK=1,
SAVEPOINT_NAME_ROLLBACK=2,
SAVEPOINT_NAME_RELEASE=4,
COMMIT_AND_CHAIN=6,
ROLLBACK_AND_CHAIN=7,
};
int mysql_endtrans(THD *thd, enum enum_mysql_completiontype completion,
char *savepoint_name)
{
bool do_release= 0;
int res= 0;
LEX *lex= thd->lex;
DBUG_ENTER("mysql_endtrans");
switch (completion) {
case COMMIT:
/*
We don't use end_active_trans() here to ensure that this works
even if there is a problem with the OPTION_AUTO_COMMIT flag
(Which of course should never happen...)
*/
thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE);
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
if (!(res= ha_commit(thd)))
send_ok(thd);
break;
case COMMIT_RELEASE:
do_release= 1;
case COMMIT_AND_CHAIN:
res= end_active_trans(thd);
if (!res && completion == COMMIT_AND_CHAIN)
res= begin_trans(thd);
if (!res)
send_ok(thd);
break;
case ROLLBACK_RELEASE:
do_release= 1;
case ROLLBACK:
case ROLLBACK_AND_CHAIN:
{
bool warn= 0;
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
if (!ha_rollback(thd))
{
/*
If a non-transactional table was updated, warn; don't warn if this is a
slave thread (because when a slave thread executes a ROLLBACK, it has
been read from the binary log, so it's 100% sure and normal to produce
error ER_WARNING_NOT_COMPLETE_ROLLBACK. If we sent the warning to the
slave SQL thread, it would not stop the thread but just be printed in
the error log; but we don't want users to wonder why they have this
message in the error log, so we don't send it.
*/
warn= (thd->options & OPTION_STATUS_NO_TRANS_UPDATE) &&
!thd->slave_thread;
}
else
res= -1;
thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE);
if (!res && (completion == ROLLBACK_AND_CHAIN))
res= begin_trans(thd);
if (!res)
{
if (warn)
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARNING_NOT_COMPLETE_ROLLBACK,
ER(ER_WARNING_NOT_COMPLETE_ROLLBACK));
send_ok(thd);
}
break;
}
case SAVEPOINT_NAME_ROLLBACK:
if (!(res=ha_rollback_to_savepoint(thd, savepoint_name)))
{
if ((thd->options & OPTION_STATUS_NO_TRANS_UPDATE) && !thd->slave_thread)
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARNING_NOT_COMPLETE_ROLLBACK,
ER(ER_WARNING_NOT_COMPLETE_ROLLBACK));
send_ok(thd);
}
break;
case SAVEPOINT_NAME_RELEASE:
if (!(res=ha_release_savepoint_name(thd, savepoint_name)))
send_ok(thd);
break;
default:
res= -1;
my_error(ER_UNKNOWN_COM_ERROR, MYF(0));
DBUG_RETURN(-1);
}
if (res < 0)
my_error(thd->killed_errno(), MYF(0));
else if ((res == 0) && do_release)
thd->killed= THD::KILL_CONNECTION;
DBUG_RETURN(res);
}
#ifndef EMBEDDED_LIBRARY #ifndef EMBEDDED_LIBRARY
@ -3648,74 +3792,23 @@ unsent_create_error:
break; break;
case SQLCOM_BEGIN: case SQLCOM_BEGIN:
if (thd->locked_tables) if (begin_trans(thd))
{
thd->lock=thd->locked_tables;
thd->locked_tables=0; // Will be automatically closed
close_thread_tables(thd); // Free tables
}
if (end_active_trans(thd))
goto error; goto error;
else else
{ send_ok(thd);
thd->options= ((thd->options & (ulong) ~(OPTION_STATUS_NO_TRANS_UPDATE)) |
OPTION_BEGIN);
thd->server_status|= SERVER_STATUS_IN_TRANS;
if (!(lex->start_transaction_opt & MYSQL_START_TRANS_OPT_WITH_CONS_SNAPSHOT) ||
!(res= ha_start_consistent_snapshot(thd)))
send_ok(thd);
}
break; break;
case SQLCOM_COMMIT: case SQLCOM_COMMIT:
/* if (mysql_endtrans(thd, lex->tx_release ? COMMIT_RELEASE :
We don't use end_active_trans() here to ensure that this works lex->tx_chain ? COMMIT_AND_CHAIN : COMMIT, 0))
even if there is a problem with the OPTION_AUTO_COMMIT flag
(Which of course should never happen...)
*/
{
thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE);
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
if (!ha_commit(thd))
{
send_ok(thd);
}
else
goto error; goto error;
break; break;
}
case SQLCOM_ROLLBACK: case SQLCOM_ROLLBACK:
thd->server_status&= ~SERVER_STATUS_IN_TRANS; if (mysql_endtrans(thd, lex->tx_release ? ROLLBACK_RELEASE :
if (!ha_rollback(thd)) lex->tx_chain ? ROLLBACK_AND_CHAIN : ROLLBACK, 0))
{ goto error;
/*
If a non-transactional table was updated, warn; don't warn if this is a
slave thread (because when a slave thread executes a ROLLBACK, it has
been read from the binary log, so it's 100% sure and normal to produce
error ER_WARNING_NOT_COMPLETE_ROLLBACK. If we sent the warning to the
slave SQL thread, it would not stop the thread but just be printed in
the error log; but we don't want users to wonder why they have this
message in the error log, so we don't send it.
*/
if ((thd->options & OPTION_STATUS_NO_TRANS_UPDATE) && !thd->slave_thread)
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARNING_NOT_COMPLETE_ROLLBACK,
ER(ER_WARNING_NOT_COMPLETE_ROLLBACK));
send_ok(thd);
}
else
res= TRUE;
thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE);
break; break;
case SQLCOM_ROLLBACK_TO_SAVEPOINT: case SQLCOM_ROLLBACK_TO_SAVEPOINT:
if (!ha_rollback_to_savepoint(thd, lex->savepoint_name)) if (mysql_endtrans(thd, SAVEPOINT_NAME_ROLLBACK, lex->savepoint_name))
{
if ((thd->options & OPTION_STATUS_NO_TRANS_UPDATE) && !thd->slave_thread)
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARNING_NOT_COMPLETE_ROLLBACK,
ER(ER_WARNING_NOT_COMPLETE_ROLLBACK));
send_ok(thd);
}
else
goto error; goto error;
break; break;
case SQLCOM_SAVEPOINT: case SQLCOM_SAVEPOINT:
@ -3724,6 +3817,10 @@ unsent_create_error:
else else
goto error; goto error;
break; break;
case SQLCOM_RELEASE_SAVEPOINT:
if (mysql_endtrans(thd, SAVEPOINT_NAME_RELEASE, lex->savepoint_name))
goto error;
break;
case SQLCOM_CREATE_PROCEDURE: case SQLCOM_CREATE_PROCEDURE:
case SQLCOM_CREATE_SPFUNCTION: case SQLCOM_CREATE_SPFUNCTION:
{ {

View file

@ -1435,7 +1435,7 @@ JOIN::exec()
curr_join->select_distinct=0; /* Each row is unique */ curr_join->select_distinct=0; /* Each row is unique */
curr_join->join_free(0); /* Free quick selects */ curr_join->join_free(0); /* Free quick selects */
if (select_distinct && ! group_list) if (curr_join->select_distinct && ! curr_join->group_list)
{ {
thd->proc_info="Removing duplicates"; thd->proc_info="Removing duplicates";
if (curr_join->tmp_having) if (curr_join->tmp_having)

View file

@ -1786,7 +1786,9 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
enum enum_schema_tables schema_table_idx; enum enum_schema_tables schema_table_idx;
thr_lock_type lock_type; thr_lock_type lock_type;
List<char> bases; List<char> bases;
List_iterator_fast<char> it(bases);
COND *partial_cond; COND *partial_cond;
int error= 1;
DBUG_ENTER("get_all_tables"); DBUG_ENTER("get_all_tables");
LINT_INIT(end); LINT_INIT(end);
@ -1803,13 +1805,11 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
if (schema_table->process_table(thd, show_table_list, if (schema_table->process_table(thd, show_table_list,
table, res, show_table_list->db, table, res, show_table_list->db,
show_table_list->alias)) show_table_list->alias))
{ goto err;
DBUG_RETURN(1);
}
close_thread_tables(thd, 0, 0, old_open_tables); close_thread_tables(thd, 0, 0, old_open_tables);
show_table_list->table= 0; show_table_list->table= 0;
lex->all_selects_list= select_lex; error= 0;
DBUG_RETURN(0); goto err;
} }
lex->all_selects_list= &sel; lex->all_selects_list= &sel;
@ -1822,14 +1822,14 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
/* information schema name always is first in list */ /* information schema name always is first in list */
if (schema_db_add(thd, &bases, idx_field_vals.db_value, &with_i_schema)) if (schema_db_add(thd, &bases, idx_field_vals.db_value, &with_i_schema))
return 1; goto err;
if (mysql_find_files(thd, &bases, NullS, mysql_data_home, if (mysql_find_files(thd, &bases, NullS, mysql_data_home,
idx_field_vals.db_value, 1)) idx_field_vals.db_value, 1))
return 1; goto err;
List_iterator_fast<char> it(bases);
partial_cond= make_cond_for_info_schema(cond, tables); partial_cond= make_cond_for_info_schema(cond, tables);
it.rewind(); /* To get access to new elements in basis list */
while ((base_name= it++) || while ((base_name= it++) ||
/* /*
generate error for non existing database. generate error for non existing database.
@ -1851,7 +1851,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
if (with_i_schema) // information schema table names if (with_i_schema) // information schema table names
{ {
if (schema_tables_add(thd, &files, idx_field_vals.table_value)) if (schema_tables_add(thd, &files, idx_field_vals.table_value))
DBUG_RETURN(1); goto err;
} }
else else
{ {
@ -1860,7 +1860,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
len= FN_LEN - len; len= FN_LEN - len;
if (mysql_find_files(thd, &files, base_name, if (mysql_find_files(thd, &files, base_name,
path, idx_field_vals.table_value, 0)) path, idx_field_vals.table_value, 0))
DBUG_RETURN(1); goto err;
} }
List_iterator_fast<char> it_files(files); List_iterator_fast<char> it_files(files);
@ -1906,16 +1906,14 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
int res; int res;
TABLE *old_open_tables= thd->open_tables; TABLE *old_open_tables= thd->open_tables;
if (make_table_list(thd, &sel, base_name, file_name)) if (make_table_list(thd, &sel, base_name, file_name))
DBUG_RETURN(1); goto err;
TABLE_LIST *show_table_list= (TABLE_LIST*) sel.table_list.first; TABLE_LIST *show_table_list= (TABLE_LIST*) sel.table_list.first;
show_table_list->lock_type= lock_type; show_table_list->lock_type= lock_type;
res= open_and_lock_tables(thd, show_table_list); res= open_and_lock_tables(thd, show_table_list);
if (schema_table->process_table(thd, show_table_list, table, if (schema_table->process_table(thd, show_table_list, table,
res, base_name, res, base_name,
show_table_list->alias)) show_table_list->alias))
{ goto err;
DBUG_RETURN(1);
}
close_thread_tables(thd, 0, 0, old_open_tables); close_thread_tables(thd, 0, 0, old_open_tables);
} }
} }
@ -1927,8 +1925,11 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
with_i_schema= 0; with_i_schema= 0;
} }
} }
error= 0;
err:
lex->all_selects_list= select_lex; lex->all_selects_list= select_lex;
DBUG_RETURN(0); DBUG_RETURN(error);
} }

View file

@ -2394,7 +2394,10 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table,
strxmov(src_path, (*tmp_table)->s->path, reg_ext, NullS); strxmov(src_path, (*tmp_table)->s->path, reg_ext, NullS);
else else
{ {
fn_format( src_path, src_table, src_db, reg_ext, MYF(MY_UNPACK_FILENAME)); strxmov(src_path, mysql_data_home, "/", src_db, "/", src_table,
reg_ext, NullS);
/* Resolve symlinks (for windows) */
fn_format(src_path, src_path, "", "", MYF(MY_UNPACK_FILENAME));
if (access(src_path, F_OK)) if (access(src_path, F_OK))
{ {
my_error(ER_BAD_TABLE_ERROR, MYF(0), src_table); my_error(ER_BAD_TABLE_ERROR, MYF(0), src_table);
@ -2421,7 +2424,9 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table,
} }
else else
{ {
fn_format( dst_path, table_name, db, reg_ext, MYF(MY_UNPACK_FILENAME)); strxmov(dst_path, mysql_data_home, "/", db, "/", table_name,
reg_ext, NullS);
fn_format(dst_path, dst_path, "", "", MYF(MY_UNPACK_FILENAME));
if (!access(dst_path, F_OK)) if (!access(dst_path, F_OK))
goto table_exists; goto table_exists;
} }

View file

@ -120,7 +120,7 @@ int mysql_update(THD *thd,
bool used_key_is_modified, transactional_table, log_delayed; bool used_key_is_modified, transactional_table, log_delayed;
int res; int res;
int error=0; int error=0;
uint used_index= MAX_KEY; uint used_index;
#ifndef NO_EMBEDDED_ACCESS_CHECKS #ifndef NO_EMBEDDED_ACCESS_CHECKS
uint want_privilege; uint want_privilege;
#endif #endif
@ -264,7 +264,10 @@ int mysql_update(THD *thd,
else if ((used_index=table->file->key_used_on_scan) < MAX_KEY) else if ((used_index=table->file->key_used_on_scan) < MAX_KEY)
used_key_is_modified=check_if_key_used(table, used_index, fields); used_key_is_modified=check_if_key_used(table, used_index, fields);
else else
{
used_key_is_modified=0; used_key_is_modified=0;
used_index= MAX_KEY;
}
if (used_key_is_modified || order) if (used_key_is_modified || order)
{ {
/* /*

View file

@ -219,6 +219,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token CASCADE %token CASCADE
%token CASCADED %token CASCADED
%token CAST_SYM %token CAST_SYM
%token CHAIN_SYM
%token CHARSET %token CHARSET
%token CHECKSUM_SYM %token CHECKSUM_SYM
%token CHECK_SYM %token CHECK_SYM
@ -385,6 +386,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token REDUNDANT_SYM %token REDUNDANT_SYM
%token REFERENCES %token REFERENCES
%token REGEXP %token REGEXP
%token RELEASE_SYM
%token RELOAD %token RELOAD
%token RENAME %token RENAME
%token REPEATABLE_SYM %token REPEATABLE_SYM
@ -690,7 +692,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
table_option opt_if_not_exists opt_no_write_to_binlog opt_var_type table_option opt_if_not_exists opt_no_write_to_binlog opt_var_type
opt_var_ident_type delete_option opt_temporary all_or_any opt_distinct opt_var_ident_type delete_option opt_temporary all_or_any opt_distinct
opt_ignore_leaves fulltext_options spatial_type union_option opt_ignore_leaves fulltext_options spatial_type union_option
start_transaction_opts start_transaction_opts opt_chain opt_work_and_chain opt_release
%type <ulong_num> %type <ulong_num>
ULONG_NUM raid_types merge_insert_types ULONG_NUM raid_types merge_insert_types
@ -777,7 +779,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
query verb_clause create change select do drop insert replace insert2 query verb_clause create change select do drop insert replace insert2
insert_values update delete truncate rename insert_values update delete truncate rename
show describe load alter optimize keycache preload flush show describe load alter optimize keycache preload flush
reset purge begin commit rollback savepoint reset purge begin commit rollback savepoint release
slave master_def master_defs master_file_def slave_until_opts slave master_def master_defs master_file_def slave_until_opts
repair restore backup analyze check start checksum repair restore backup analyze check start checksum
field_list field_list_item field_spec kill column_def key_def field_list field_list_item field_spec kill column_def key_def
@ -876,6 +878,7 @@ statement:
| preload | preload
| prepare | prepare
| purge | purge
| release
| rename | rename
| repair | repair
| replace | replace
@ -6901,6 +6904,7 @@ keyword:
| BTREE_SYM {} | BTREE_SYM {}
| CACHE_SYM {} | CACHE_SYM {}
| CASCADED {} | CASCADED {}
| CHAIN_SYM {}
| CHANGED {} | CHANGED {}
| CHARSET {} | CHARSET {}
| CHECKSUM_SYM {} | CHECKSUM_SYM {}
@ -7854,25 +7858,66 @@ opt_work:
| WORK_SYM {;} | WORK_SYM {;}
; ;
opt_chain:
/* empty */ { $$= (Lex->thd->variables.completion_type == 1); }
| AND_SYM NO_SYM CHAIN_SYM { $$=0; }
| AND_SYM CHAIN_SYM { $$=1; }
;
opt_release:
/* empty */ { $$= (Lex->thd->variables.completion_type == 2); }
| RELEASE_SYM { $$=1; }
| NO_SYM RELEASE_SYM { $$=0; }
;
opt_work_and_chain:
opt_work opt_chain { $$=$2; }
;
opt_savepoint:
/* empty */ {}
| SAVEPOINT_SYM {}
;
commit: commit:
COMMIT_SYM { Lex->sql_command = SQLCOM_COMMIT;}; COMMIT_SYM opt_work_and_chain opt_release
{
Lex->sql_command= SQLCOM_COMMIT;
Lex->tx_chain= $2;
Lex->tx_release= $3;
}
;
rollback: rollback:
ROLLBACK_SYM ROLLBACK_SYM opt_work_and_chain opt_release
{ {
Lex->sql_command = SQLCOM_ROLLBACK; Lex->sql_command= SQLCOM_ROLLBACK;
Lex->tx_chain= $2;
Lex->tx_release= $3;
} }
| ROLLBACK_SYM TO_SYM SAVEPOINT_SYM ident | ROLLBACK_SYM opt_work
TO_SYM opt_savepoint ident
{ {
Lex->sql_command = SQLCOM_ROLLBACK_TO_SAVEPOINT; Lex->sql_command = SQLCOM_ROLLBACK_TO_SAVEPOINT;
Lex->savepoint_name = $4.str; Lex->savepoint_name = $5.str;
}; }
;
savepoint: savepoint:
SAVEPOINT_SYM ident SAVEPOINT_SYM ident
{ {
Lex->sql_command = SQLCOM_SAVEPOINT; Lex->sql_command = SQLCOM_SAVEPOINT;
Lex->savepoint_name = $2.str; Lex->savepoint_name = $2.str;
}; }
;
release:
RELEASE_SYM SAVEPOINT_SYM ident
{
Lex->sql_command = SQLCOM_RELEASE_SAVEPOINT;
Lex->savepoint_name = $3.str;
}
;
/* /*
UNIONS : glue selects together UNIONS : glue selects together

View file

@ -277,7 +277,7 @@ static int my_strnncollsp_big5(CHARSET_INFO * cs __attribute__((unused)),
if (!res && a_length != b_length) if (!res && a_length != b_length)
{ {
const uchar *end; const uchar *end;
int swap= 0; int swap= 1;
if (diff_if_only_endspace_difference) if (diff_if_only_endspace_difference)
res= 1; /* Assume 'a' is bigger */ res= 1; /* Assume 'a' is bigger */
/* /*
@ -295,7 +295,7 @@ static int my_strnncollsp_big5(CHARSET_INFO * cs __attribute__((unused)),
for (end= a + a_length-length; a < end ; a++) for (end= a + a_length-length; a < end ; a++)
{ {
if (*a != ' ') if (*a != ' ')
return ((int) *a - (int) ' ') ^ swap; return (*a < ' ') ? -swap : swap;
} }
} }
return res; return res;

View file

@ -169,7 +169,7 @@ static int my_strnncollsp_8bit_bin(CHARSET_INFO * cs __attribute__((unused)),
res= 0; res= 0;
if (a_length != b_length) if (a_length != b_length)
{ {
int swap= 0; int swap= 1;
/* /*
Check the next not space character of the longer key. If it's < ' ', Check the next not space character of the longer key. If it's < ' ',
then it's smaller than the other key. then it's smaller than the other key.
@ -187,7 +187,7 @@ static int my_strnncollsp_8bit_bin(CHARSET_INFO * cs __attribute__((unused)),
for (end= a + a_length-length; a < end ; a++) for (end= a + a_length-length; a < end ; a++)
{ {
if (*a != ' ') if (*a != ' ')
return ((int) *a - (int) ' ') ^ swap; return (*a < ' ') ? -swap : swap;
} }
} }
return res; return res;

View file

@ -2638,7 +2638,7 @@ static int my_strnncollsp_gbk(CHARSET_INFO * cs __attribute__((unused)),
if (!res && a_length != b_length) if (!res && a_length != b_length)
{ {
const uchar *end; const uchar *end;
int swap= 0; int swap= 1;
if (diff_if_only_endspace_difference) if (diff_if_only_endspace_difference)
res= 1; /* Assume 'a' is bigger */ res= 1; /* Assume 'a' is bigger */
/* /*
@ -2656,7 +2656,7 @@ static int my_strnncollsp_gbk(CHARSET_INFO * cs __attribute__((unused)),
for (end= a + a_length-length; a < end ; a++) for (end= a + a_length-length; a < end ; a++)
{ {
if (*a != ' ') if (*a != ' ')
return ((int) *a - (int) ' ') ^ swap; return (*a < ' ') ? -swap : swap;
} }
} }
return res; return res;

View file

@ -617,7 +617,7 @@ static int my_strnncollsp_latin1_de(CHARSET_INFO *cs __attribute__((unused)),
res= 0; res= 0;
if (a != a_end || b != b_end) if (a != a_end || b != b_end)
{ {
int swap= 0; int swap= 1;
if (diff_if_only_endspace_difference) if (diff_if_only_endspace_difference)
res= 1; /* Assume 'a' is bigger */ res= 1; /* Assume 'a' is bigger */
/* /*
@ -635,7 +635,7 @@ static int my_strnncollsp_latin1_de(CHARSET_INFO *cs __attribute__((unused)),
for ( ; a < a_end ; a++) for ( ; a < a_end ; a++)
{ {
if (*a != ' ') if (*a != ' ')
return ((int) *a - (int) ' ') ^ swap; return (*a < ' ') ? -swap : swap;
} }
} }
return res; return res;

View file

@ -399,7 +399,7 @@ static int my_strnncollsp_mb_bin(CHARSET_INFO * cs __attribute__((unused)),
res= 0; res= 0;
if (a_length != b_length) if (a_length != b_length)
{ {
int swap= 0; int swap= 1;
if (diff_if_only_endspace_difference) if (diff_if_only_endspace_difference)
res= 1; /* Assume 'a' is bigger */ res= 1; /* Assume 'a' is bigger */
/* /*
@ -417,7 +417,7 @@ static int my_strnncollsp_mb_bin(CHARSET_INFO * cs __attribute__((unused)),
for (end= a + a_length-length; a < end ; a++) for (end= a + a_length-length; a < end ; a++)
{ {
if (*a != ' ') if (*a != ' ')
return ((int) *a - (int) ' ') ^ swap; return (*a < ' ') ? -swap : swap;
} }
} }
return res; return res;

View file

@ -162,7 +162,7 @@ int my_strnncollsp_simple(CHARSET_INFO * cs, const uchar *a, uint a_length,
res= 0; res= 0;
if (a_length != b_length) if (a_length != b_length)
{ {
int swap= 0; int swap= 1;
if (diff_if_only_endspace_difference) if (diff_if_only_endspace_difference)
res= 1; /* Assume 'a' is bigger */ res= 1; /* Assume 'a' is bigger */
/* /*
@ -174,13 +174,13 @@ int my_strnncollsp_simple(CHARSET_INFO * cs, const uchar *a, uint a_length,
/* put shorter key in s */ /* put shorter key in s */
a_length= b_length; a_length= b_length;
a= b; a= b;
swap= -1^1; /* swap sign of result */ swap= -1; /* swap sign of result */
res= -res; res= -res;
} }
for (end= a + a_length-length; a < end ; a++) for (end= a + a_length-length; a < end ; a++)
{ {
if (*a != ' ') if (*a != ' ')
return ((int) *a - (int) ' ') ^ swap; return (*a < ' ') ? -swap : swap;
} }
} }
return res; return res;

View file

@ -256,7 +256,7 @@ static int my_strnncollsp_sjis(CHARSET_INFO *cs __attribute__((unused)),
if (!res && (a != a_end || b != b_end)) if (!res && (a != a_end || b != b_end))
{ {
int swap= 0; int swap= 1;
if (diff_if_only_endspace_difference) if (diff_if_only_endspace_difference)
res= 1; /* Assume 'a' is bigger */ res= 1; /* Assume 'a' is bigger */
/* /*
@ -274,7 +274,7 @@ static int my_strnncollsp_sjis(CHARSET_INFO *cs __attribute__((unused)),
for (; a < a_end ; a++) for (; a < a_end ; a++)
{ {
if (*a != ' ') if (*a != ' ')
return ((int) *a - (int) ' ') ^ swap; return (*a < ' ') ? -swap : swap;
} }
} }
return res; return res;

View file

@ -593,7 +593,7 @@ int my_strnncollsp_tis620(CHARSET_INFO * cs __attribute__((unused)),
} }
if (a_length != b_length) if (a_length != b_length)
{ {
int swap= 0; int swap= 1;
if (diff_if_only_endspace_difference) if (diff_if_only_endspace_difference)
res= 1; /* Assume 'a' is bigger */ res= 1; /* Assume 'a' is bigger */
/* /*
@ -612,7 +612,7 @@ int my_strnncollsp_tis620(CHARSET_INFO * cs __attribute__((unused)),
{ {
if (*a != ' ') if (*a != ' ')
{ {
res= ((int) *a - (int) ' ') ^ swap; res= (*a < ' ') ? -swap : swap;
goto ret; goto ret;
} }
} }

View file

@ -280,7 +280,7 @@ static int my_strnncollsp_ucs2(CHARSET_INFO *cs __attribute__((unused)),
if (slen != tlen) if (slen != tlen)
{ {
int swap= 0; int swap= 1;
if (slen < tlen) if (slen < tlen)
{ {
s= t; s= t;
@ -291,7 +291,7 @@ static int my_strnncollsp_ucs2(CHARSET_INFO *cs __attribute__((unused)),
for ( ; s < se ; s+= 2) for ( ; s < se ; s+= 2)
{ {
if (s[0] || s[1] != ' ') if (s[0] || s[1] != ' ')
return (((int)s[0] << 8) + (int) s[1] - (int) ' ') ^ swap; return (s[0] == 0 && s[1] < ' ') ? -swap : swap;
} }
} }
return 0; return 0;

View file

@ -2093,7 +2093,7 @@ static int my_strnncollsp_utf8(CHARSET_INFO *cs,
if (slen != tlen) if (slen != tlen)
{ {
int swap= 0; int swap= 1;
if (diff_if_only_endspace_difference) if (diff_if_only_endspace_difference)
res= 1; /* Assume 'a' is bigger */ res= 1; /* Assume 'a' is bigger */
if (slen < tlen) if (slen < tlen)
@ -2117,7 +2117,7 @@ static int my_strnncollsp_utf8(CHARSET_INFO *cs,
for ( ; s < se; s++) for ( ; s < se; s++)
{ {
if (*s != ' ') if (*s != ' ')
return ((int)*s - (int) ' ') ^ swap; return (*s < ' ') ? -swap : swap;
} }
} }
return res; return res;

View file

@ -276,7 +276,7 @@ void vio_in_addr(Vio *vio, struct in_addr *in)
{ {
DBUG_ENTER("vio_in_addr"); DBUG_ENTER("vio_in_addr");
if (vio->localhost) if (vio->localhost)
bzero((char*) in, sizeof(*in)); /* This should never be executed */ bzero((char*) in, sizeof(*in));
else else
*in=vio->remote.sin_addr; *in=vio->remote.sin_addr;
DBUG_VOID_RETURN; DBUG_VOID_RETURN;

View file

@ -259,7 +259,7 @@ void vio_ssl_in_addr(Vio *vio, struct in_addr *in)
{ {
DBUG_ENTER("vio_ssl_in_addr"); DBUG_ENTER("vio_ssl_in_addr");
if (vio->localhost) if (vio->localhost)
bzero((char*) in, sizeof(*in)); /* This should never be executed */ bzero((char*) in, sizeof(*in));
else else
*in=vio->remote.sin_addr; *in=vio->remote.sin_addr;
DBUG_VOID_RETURN; DBUG_VOID_RETURN;