diff options
240 files changed, 7232 insertions, 2258 deletions
diff --git a/Makefile.am b/Makefile.am index 88e0f949657..18477afb398 100644 --- a/Makefile.am +++ b/Makefile.am @@ -58,7 +58,8 @@ tags: test test-force test-full test-force-full test-force-mem \ test-pl test-force-pl test-full-pl test-force-full-pl test-force-pl-mem \ test-unit test-ps test-nr test-pr test-ns test-binlog-statement \ - test-ext-funcs test-ext-rpl test-ext-partitions test-ext \ + test-ext-funcs test-ext-rpl test-ext-partitions test-ext-jp \ + test-ext-stress test-ext \ test-fast test-fast-cursor test-fast-view test-fast-prepare \ test-full-qa @@ -144,6 +145,8 @@ test-bt: cd mysql-test ; MTR_BUILD_THREAD=auto \ @PERL@ ./mysql-test-run.pl --comment=NIST+ps --force --suite=nist --ps-protocol ; \ fi + -cd mysql-test ; MTR_BUILD_THREAD=auto \ + @PERL@ ./mysql-test-run.pl --force --comment=stress --suite=stress # Re-enable the "rowlock" suite when bug#28685 is fixed # -cd mysql-test ; MTR_BUILD_THREAD=auto \ @@ -182,12 +185,17 @@ test-ext-jp: cd mysql-test ; \ @PERL@ ./mysql-test-run.pl --force --suite=jp -test-ext: test-ext-funcs test-ext-rpl test-ext-partitions test-ext-jp +test-ext-stress: + cd mysql-test ; \ + @PERL@ ./mysql-test-run.pl --force --big-test --suite=stress + +test-ext: test-ext-funcs test-ext-rpl test-ext-partitions test-ext-jp test-ext-stress test-fast: cd mysql-test ; \ @PERL@ ./mysql-test-run.pl $(subset) --force --skip-ndb --skip-innodb --skip-im --skip-rpl ; \ - @PERL@ ./mysql-test-run.pl $(subset) --force --suite=funcs_1 --do-test=myisam + @PERL@ ./mysql-test-run.pl $(subset) --force --suite=funcs_1 --do-test=myisam ; \ + @PERL@ ./mysql-test-run.pl $(subset) --force --suite=stress --do-test=ddl_myisam test-fast-view: $(MAKE) subset=--view-protocol test-fast diff --git a/client/mysql.cc b/client/mysql.cc index 7970fa4db2f..fe057c8b8a4 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -1089,7 +1089,12 @@ static int read_and_execute(bool interactive) something else is still in console input buffer */ } while (tmpbuf.alloced_length() <= clen); - line= buffer.c_ptr(); + /* + An empty line is returned from my_cgets when there's error reading : + Ctrl-c for example + */ + if (line) + line= buffer.c_ptr(); #endif /* __NETWARE__ */ #else if (opt_outfile) diff --git a/client/mysqldump.c b/client/mysqldump.c index fe7c03fe77e..0f30ebddacc 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -4458,10 +4458,9 @@ static my_bool get_view_structure(char *table, char* db) result_table); check_io(sql_file); } + fprintf(sql_file, "/*!50001 DROP TABLE %s*/;\n", opt_quoted_table); if (opt_drop) { - fprintf(sql_file, "/*!50001 DROP TABLE IF EXISTS %s*/;\n", - opt_quoted_table); fprintf(sql_file, "/*!50001 DROP VIEW IF EXISTS %s*/;\n", opt_quoted_table); check_io(sql_file); diff --git a/client/mysqltest.c b/client/mysqltest.c index 0a1b57ff80a..e5b9a2eaf12 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -264,6 +264,7 @@ enum enum_commands { Q_REPLACE_REGEX, Q_REMOVE_FILE, Q_FILE_EXIST, Q_WRITE_FILE, Q_COPY_FILE, Q_PERL, Q_DIE, Q_EXIT, Q_SKIP, Q_CHMOD_FILE, Q_APPEND_FILE, Q_CAT_FILE, Q_DIFF_FILES, + Q_SEND_QUIT, Q_UNKNOWN, /* Unknown command. */ Q_COMMENT, /* Comments, ignored. */ @@ -351,6 +352,7 @@ const char *command_names[]= "append_file", "cat_file", "diff_files", + "send_quit", 0 }; @@ -2541,6 +2543,48 @@ void do_diff_files(struct st_command *command) DBUG_VOID_RETURN; } + /* + SYNOPSIS + do_send_quit + command called command + + DESCRIPTION + Sends a simple quit command to the server for the named connection. + + */ + +void do_send_quit(struct st_command *command) +{ + char *p= command->first_argument, *name; + struct st_connection *con; + + DBUG_ENTER("do_send_quit"); + DBUG_PRINT("enter",("name: '%s'",p)); + + if (!*p) + die("Missing connection name in do_send_quit"); + name= p; + while (*p && !my_isspace(charset_info,*p)) + p++; + + if (*p) + *p++= 0; + command->last_argument= p; + + /* Loop through connection pool for connection to close */ + for (con= connections; con < next_con; con++) + { + DBUG_PRINT("info", ("con->name: %s", con->name)); + if (!strcmp(con->name, name)) + { + simple_command(&con->mysql,COM_QUIT,NullS,0,1); + DBUG_VOID_RETURN; + } + } + die("connection '%s' not found in connection pool", name); +} + + /* SYNOPSIS do_perl @@ -3454,11 +3498,10 @@ void do_close_connection(struct st_command *command) my_free(con->name, MYF(0)); /* - When the connection is closed set name to "closed_connection" + When the connection is closed set name to "-closed_connection-" to make it possible to reuse the connection name. - The connection slot will not be reused */ - if (!(con->name = my_strdup("closed_connection", MYF(MY_WME)))) + if (!(con->name = my_strdup("-closed_connection-", MYF(MY_WME)))) die("Out of memory"); DBUG_VOID_RETURN; @@ -3636,6 +3679,7 @@ void do_connect(struct st_command *command) int con_port= opt_port; char *con_options; bool con_ssl= 0, con_compress= 0; + struct st_connection* con_slot; static DYNAMIC_STRING ds_connection_name; static DYNAMIC_STRING ds_host; @@ -3717,19 +3761,24 @@ void do_connect(struct st_command *command) con_options= end; } - if (next_con == connections_end) - die("Connection limit exhausted, you can have max %d connections", - (int) (sizeof(connections)/sizeof(struct st_connection))); - if (find_connection_by_name(ds_connection_name.str)) die("Connection %s already exists", ds_connection_name.str); + + if (next_con != connections_end) + con_slot= next_con; + else + { + if (!(con_slot= find_connection_by_name("-closed_connection-"))) + die("Connection limit exhausted, you can have max %d connections", + (int) (sizeof(connections)/sizeof(struct st_connection))); + } - if (!mysql_init(&next_con->mysql)) + if (!mysql_init(&con_slot->mysql)) die("Failed on mysql_init()"); if (opt_compress || con_compress) - mysql_options(&next_con->mysql, MYSQL_OPT_COMPRESS, NullS); - mysql_options(&next_con->mysql, MYSQL_OPT_LOCAL_INFILE, 0); - mysql_options(&next_con->mysql, MYSQL_SET_CHARSET_NAME, + mysql_options(&con_slot->mysql, MYSQL_OPT_COMPRESS, NullS); + mysql_options(&con_slot->mysql, MYSQL_OPT_LOCAL_INFILE, 0); + mysql_options(&con_slot->mysql, MYSQL_SET_CHARSET_NAME, charset_info->csname); if (opt_charsets_dir) mysql_options(&cur_con->mysql, MYSQL_SET_CHARSET_DIR, @@ -3738,12 +3787,12 @@ void do_connect(struct st_command *command) #ifdef HAVE_OPENSSL if (opt_use_ssl || con_ssl) { - mysql_ssl_set(&next_con->mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca, + mysql_ssl_set(&con_slot->mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca, opt_ssl_capath, opt_ssl_cipher); #if MYSQL_VERSION_ID >= 50000 /* Turn on ssl_verify_server_cert only if host is "localhost" */ opt_ssl_verify_server_cert= !strcmp(ds_host.str, "localhost"); - mysql_options(&next_con->mysql, MYSQL_OPT_SSL_VERIFY_SERVER_CERT, + mysql_options(&con_slot->mysql, MYSQL_OPT_SSL_VERIFY_SERVER_CERT, &opt_ssl_verify_server_cert); #endif } @@ -3757,16 +3806,19 @@ void do_connect(struct st_command *command) if (ds_database.length && !strcmp(ds_database.str,"*NO-ONE*")) dynstr_set(&ds_database, ""); - if (connect_n_handle_errors(command, &next_con->mysql, + if (connect_n_handle_errors(command, &con_slot->mysql, ds_host.str,ds_user.str, ds_password.str, ds_database.str, con_port, ds_sock.str)) { DBUG_PRINT("info", ("Inserting connection %s in connection pool", ds_connection_name.str)); - if (!(next_con->name= my_strdup(ds_connection_name.str, MYF(MY_WME)))) + if (!(con_slot->name= my_strdup(ds_connection_name.str, MYF(MY_WME)))) die("Out of memory"); - cur_con= next_con++; + cur_con= con_slot; + + if (con_slot == next_con) + next_con++; /* if we used the next_con slot, advance the pointer */ } dynstr_free(&ds_connection_name); @@ -6335,6 +6387,7 @@ int main(int argc, char **argv) case Q_WRITE_FILE: do_write_file(command); break; case Q_APPEND_FILE: do_append_file(command); break; case Q_DIFF_FILES: do_diff_files(command); break; + case Q_SEND_QUIT: do_send_quit(command); break; case Q_CAT_FILE: do_cat_file(command); break; case Q_COPY_FILE: do_copy_file(command); break; case Q_CHMOD_FILE: do_chmod_file(command); break; diff --git a/extra/yassl/include/openssl/ssl.h b/extra/yassl/include/openssl/ssl.h index 7dd33e3fcad..efd0dec75b6 100644 --- a/extra/yassl/include/openssl/ssl.h +++ b/extra/yassl/include/openssl/ssl.h @@ -277,6 +277,8 @@ int SSL_session_reused(SSL*); int SSL_set_rfd(SSL*, int); int SSL_set_wfd(SSL*, int); void SSL_set_shutdown(SSL*, int); +void SSL_set_quiet_shutdown(SSL *ssl,int mode); +int SSL_get_quiet_shutdown(SSL *ssl); int SSL_want_read(SSL*); int SSL_want_write(SSL*); diff --git a/extra/yassl/include/yassl_int.hpp b/extra/yassl/include/yassl_int.hpp index 94cb85c3300..b7bd35f5fa2 100644 --- a/extra/yassl/include/yassl_int.hpp +++ b/extra/yassl/include/yassl_int.hpp @@ -584,6 +584,7 @@ class SSL { Socket socket_; // socket wrapper Buffers buffers_; // buffered handshakes and data Log log_; // logger + bool quietShutdown_; // shutdown without handshakes // optimization variables bool has_data_; // buffered data ready? @@ -610,6 +611,7 @@ public: Buffers& useBuffers(); bool HasData() const; + bool GetQuietShutdown() const; // sets void set_pending(Cipher suite); @@ -621,6 +623,7 @@ public: void SetError(YasslError); int SetCompression(); void UnSetCompression(); + void SetQuietShutdown(bool mode); // helpers bool isTLS() const; diff --git a/extra/yassl/src/ssl.cpp b/extra/yassl/src/ssl.cpp index 86dfa1c6ebd..c3d580a93ab 100644 --- a/extra/yassl/src/ssl.cpp +++ b/extra/yassl/src/ssl.cpp @@ -411,8 +411,10 @@ int SSL_clear(SSL* ssl) int SSL_shutdown(SSL* ssl) { - Alert alert(warning, close_notify); - sendAlert(*ssl, alert); + if (!ssl->GetQuietShutdown()) { + Alert alert(warning, close_notify); + sendAlert(*ssl, alert); + } ssl->useLog().ShowTCP(ssl->getSocket().get_fd(), true); GetErrors().Remove(); @@ -421,6 +423,18 @@ int SSL_shutdown(SSL* ssl) } +void SSL_set_quiet_shutdown(SSL *ssl,int mode) +{ + ssl->SetQuietShutdown(mode != 0); +} + + +int SSL_get_quiet_shutdown(SSL *ssl) +{ + return ssl->GetQuietShutdown(); +} + + /* on by default but allow user to turn off */ long SSL_CTX_set_session_cache_mode(SSL_CTX* ctx, long mode) { diff --git a/extra/yassl/src/yassl_int.cpp b/extra/yassl/src/yassl_int.cpp index ae16abf9e49..f5ab2f200a5 100644 --- a/extra/yassl/src/yassl_int.cpp +++ b/extra/yassl/src/yassl_int.cpp @@ -291,7 +291,7 @@ const ClientKeyFactory& sslFactory::getClientKey() const SSL::SSL(SSL_CTX* ctx) : secure_(ctx->getMethod()->getVersion(), crypto_.use_random(), ctx->getMethod()->getSide(), ctx->GetCiphers(), ctx, - ctx->GetDH_Parms().set_), has_data_(false) + ctx->GetDH_Parms().set_), quietShutdown_(false), has_data_(false) { if (int err = crypto_.get_random().GetError()) { SetError(YasslError(err)); @@ -773,6 +773,12 @@ void SSL::SetError(YasslError ye) // TODO: add string here } +// set the quiet shutdown mode (close_nofiy not sent or received on shutdown) +void SSL::SetQuietShutdown(bool mode) +{ + quietShutdown_ = mode; +} + Buffers& SSL::useBuffers() { @@ -1330,6 +1336,12 @@ YasslError SSL::GetError() const } +bool SSL::GetQuietShutdown() const +{ + return quietShutdown_; +} + + bool SSL::GetMultiProtocol() const { return secure_.GetContext()->getMethod()->multipleProtocol(); diff --git a/include/Makefile.am b/include/Makefile.am index b803f614a93..0796341cc91 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -33,7 +33,7 @@ noinst_HEADERS = config-win.h config-netware.h \ mysys_err.h my_base.h help_start.h help_end.h \ my_nosys.h my_alarm.h queues.h rijndael.h sha1.h \ my_aes.h my_tree.h my_trie.h hash.h thr_alarm.h \ - thr_lock.h t_ctype.h violite.h md5.h base64.h \ + thr_lock.h t_ctype.h violite.h my_md5.h base64.h \ mysql_version.h.in my_handler.h my_time.h \ my_vle.h my_user.h my_atomic.h atomic/nolock.h \ atomic/rwlock.h atomic/x86-gcc.h atomic/x86-msvc.h \ diff --git a/include/my_base.h b/include/my_base.h index bbc0c0f1f5c..04127b81b78 100644 --- a/include/my_base.h +++ b/include/my_base.h @@ -299,6 +299,7 @@ enum ha_base_keytype { #define HA_PACK_RECORD 2 /* Request packed record format */ #define HA_CREATE_TMP_TABLE 4 #define HA_CREATE_CHECKSUM 8 +#define HA_CREATE_KEEP_FILES 16 /* don't overwrite .MYD and MYI */ #define HA_CREATE_DELAY_KEY_WRITE 64 #define HA_CREATE_RELIES_ON_SQL_LAYER 128 diff --git a/include/md5.h b/include/my_md5.h index f92976b3beb..f92976b3beb 100644 --- a/include/md5.h +++ b/include/my_md5.h diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index a05d061204b..46d0c8f1037 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -4939,7 +4939,7 @@ static my_bool reset_stmt_handle(MYSQL_STMT *stmt, uint flags) Reset stored result set if so was requested or it's a part of cursor fetch. */ - if (result->data && (flags & RESET_STORE_RESULT)) + if (flags & RESET_STORE_RESULT) { /* Result buffered */ free_root(&result->alloc, MYF(MY_KEEP_PREALLOC)); diff --git a/mysql-test/Makefile.am b/mysql-test/Makefile.am index acb9ba36bda..c783158b46c 100644 --- a/mysql-test/Makefile.am +++ b/mysql-test/Makefile.am @@ -26,7 +26,7 @@ EXTRA_SCRIPTS = mysql-test-run-shell.sh install_test_db.sh \ valgrind.supp $(PRESCRIPTS) EXTRA_DIST = $(EXTRA_SCRIPTS) suite GENSCRIPTS = mysql-test-run-shell install_test_db mtr mysql-test-run -PRESCRIPTS = mysql-test-run.pl +PRESCRIPTS = mysql-test-run.pl mysql-stress-test.pl test_SCRIPTS = $(GENSCRIPTS) $(PRESCRIPTS) test_DATA = std_data/client-key.pem std_data/client-cert.pem \ std_data/cacert.pem std_data/server-cert.pem \ diff --git a/mysql-test/extra/binlog_tests/binlog.test b/mysql-test/extra/binlog_tests/binlog.test index 57008b6af3c..0d2ed7ad509 100644 --- a/mysql-test/extra/binlog_tests/binlog.test +++ b/mysql-test/extra/binlog_tests/binlog.test @@ -80,72 +80,11 @@ drop table t1; --replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/ /Server ver: [^,]*,/Server version,/ show binlog events from 0; -set autocommit= 1; -reset master; -create table t1(n int) engine=innodb; -insert into t1 values (1); -insert into t1 values (2); -insert into t1 values (3); -commit; -drop table t1; ---replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/ /Server ver: [^,]*,/Server version,/ -show binlog events from 0; - -reset master; -create table t1(n int) engine=myisam; -begin; -insert into t1 values (4); -insert into t1 values (5); -insert into t1 values (6); -commit; -drop table t1; ---replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/ /Server ver: [^,]*,/Server version,/ -show binlog events from 0; - -# now show this also works for SHOW MASTER STATUS -# as this is what "mysqldump --master-data=1" uses. - -set autocommit= 1; -reset master; -create table t1(n int) engine=innodb; -show master status; -insert into t1 values (1); -show master status; -insert into t1 values (2); -insert into t1 values (3); -show master status; -commit; -show master status; -drop table t1; ---replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/ /Server ver: [^,]*,/Server version,/ -show binlog events from 0; - -set autocommit= 0; -reset master; -create table t1(n int) engine=myisam; -show master status; -insert into t1 values (4); -show master status; -insert into t1 values (5); -insert into t1 values (6); - -show master status; -commit; -show master status; -drop table t1; ---replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/ /Server ver: [^,]*,/Server version,/ -show binlog events from 0; - -set session autocommit = @ac; - # now show that nothing breaks if we need to read from the cache more # than once, resulting in split event-headers set @bcs = @@binlog_cache_size; -set @ac = @@autocommit; - set global binlog_cache_size=4096; -set autocommit= 0; reset master; create table t1 (a int) engine=innodb; diff --git a/mysql-test/extra/binlog_tests/ctype_cp932.test b/mysql-test/extra/binlog_tests/ctype_cp932.test index fc2fa934641..0839f5d43aa 100644 --- a/mysql-test/extra/binlog_tests/ctype_cp932.test +++ b/mysql-test/extra/binlog_tests/ctype_cp932.test @@ -404,6 +404,28 @@ SET collation_connection='cp932_bin'; -- source include/ctype_filesort.inc # +# Bug#29333 myisam corruption with +# character set cp932 collate cp932_japanese_ci +# +create table t2 (a char(1)); +insert into t2 values ('0'),('1'),('2'),('3'),('4'),('5'),('6'),('7'); +insert into t2 values ('8'),('9'),('A'),('B'),('C'),('D'),('E'),('F'); +create table t1 ( + a varchar(2) character set cp932 +) engine=myisam; +--disable_warnings +insert into t1 +select unhex(concat(t24.a, t23.a, t22.a, t21.a)) +from t2 t21, t2 t22, t2 t23, t2 t24; +--enable_warnings +delete from t1 where a=''; +alter table t1 add key(a); +check table t1; +drop table t1; +drop table t2; + + +# # Bug#12547: Inserting long string into varchar causes table crash in cp932 # create table t1 (col1 varchar(1)) character set cp932; diff --git a/mysql-test/include/have_ndb.inc b/mysql-test/include/have_ndb.inc index 3d9cbf5a379..cfc5b5d0ff8 100644 --- a/mysql-test/include/have_ndb.inc +++ b/mysql-test/include/have_ndb.inc @@ -1,6 +1,10 @@ # Check that server is compiled and started with support for NDB -disable_query_log; ---require r/true.require -select (support = 'YES' or support = 'DEFAULT') as `TRUE` from information_schema.engines where engine = 'ndbcluster'; ---source include/ndb_not_readonly.inc -enable_query_log; +#disable_query_log; +#--require r/true.require +#select (support = 'YES' or support = 'DEFAULT') as `TRUE` from information_schema.engines where engine = 'ndbcluster'; +#--source include/ndb_not_readonly.inc +#enable_query_log; +# always make sure we have both mysql servers started ok before test starts +# there are some initial startup bugs that are avoided by doing this, avoiding sporadic +# failures in mysql-test-run +--source include/have_multi_ndb.inc diff --git a/mysql-test/include/index_merge1.inc b/mysql-test/include/index_merge1.inc index a3a874a8ed2..2ecdbe583c2 100644 --- a/mysql-test/include/index_merge1.inc +++ b/mysql-test/include/index_merge1.inc @@ -439,3 +439,51 @@ INSERT INTO t2(a,b) VALUES(1,2); SELECT t2.a FROM t1,t2 WHERE t2.b=2 AND t2.a=1; UNLOCK TABLES; DROP TABLE t1, t2; + +# +# BUG#29740: HA_KEY_SCAN_NOT_ROR wasn't set for HEAP engine +# +CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `filler` char(200) DEFAULT NULL, + `b` int(11) DEFAULT NULL, + KEY `a` (`a`), + KEY `b` (`b`) +) ENGINE=MEMORY DEFAULT CHARSET=latin1; + +insert into t1 values +(0, 'filler', 0), (1, 'filler', 1), (2, 'filler', 2), (3, 'filler', 3), +(4, 'filler', 4), (5, 'filler', 5), (6, 'filler', 6), (7, 'filler', 7), +(8, 'filler', 8), (9, 'filler', 9), (0, 'filler', 0), (1, 'filler', 1), +(2, 'filler', 2), (3, 'filler', 3), (4, 'filler', 4), (5, 'filler', 5), +(6, 'filler', 6), (7, 'filler', 7), (8, 'filler', 8), (9, 'filler', 9), +(10, 'filler', 10), (11, 'filler', 11), (12, 'filler', 12), (13, 'filler', 13), +(14, 'filler', 14), (15, 'filler', 15), (16, 'filler', 16), (17, 'filler', 17), +(18, 'filler', 18), (19, 'filler', 19), (4, '5 ', 0), (5, '4 ', 0), +(4, '4 ', 0), (4, 'qq ', 5), (5, 'qq ', 4), (4, 'zz ', 4); + +create table t2( + `a` int(11) DEFAULT NULL, + `filler` char(200) DEFAULT NULL, + `b` int(11) DEFAULT NULL, + KEY USING BTREE (`a`), + KEY USING BTREE (`b`) +) ENGINE=MEMORY DEFAULT CHARSET=latin1; +insert into t2 select * from t1; + +--echo must use sort-union rather than union: +--replace_column 9 # +explain select * from t1 where a=4 or b=4; +--sorted_result +select * from t1 where a=4 or b=4; +--sorted_result +select * from t1 ignore index(a,b) where a=4 or b=4; + +--echo must use union, not sort-union: +--replace_column 9 # +explain select * from t2 where a=4 or b=4; +--sorted_result +select * from t2 where a=4 or b=4; + +drop table t1, t2; + diff --git a/mysql-test/include/innodb_trx_weight.inc b/mysql-test/include/innodb_trx_weight.inc new file mode 100644 index 00000000000..56d3d47da36 --- /dev/null +++ b/mysql-test/include/innodb_trx_weight.inc @@ -0,0 +1,51 @@ +-- connect (con1,localhost,root,,) +-- connect (con2,localhost,root,,) + +-- connection con1 +SET autocommit=0; +SELECT * FROM t1 FOR UPDATE; +-- if ($con1_extra_sql_present) { + -- eval $con1_extra_sql +-- } + +-- connection con2 +SET autocommit=0; +SELECT * FROM t2 FOR UPDATE; +-- if ($con2_extra_sql_present) { + -- eval $con2_extra_sql +-- } + +-- if ($con1_should_be_rolledback) { + -- connection con1 + -- send + INSERT INTO t2 VALUES (0); + + -- connection con2 + INSERT INTO t1 VALUES (0); + ROLLBACK; + + -- connection con1 + -- error ER_LOCK_DEADLOCK + -- reap +-- } +# else +-- if (!$con1_should_be_rolledback) { + -- connection con2 + -- send + INSERT INTO t1 VALUES (0); + + -- connection con1 + INSERT INTO t2 VALUES (0); + ROLLBACK; + + -- connection con2 + -- error ER_LOCK_DEADLOCK + -- reap +-- } + +-- connection default + +DELETE FROM t5_nontrans; + +-- disconnect con1 +-- disconnect con2 diff --git a/mysql-test/include/mix1.inc b/mysql-test/include/mix1.inc index c032aaea50e..e863e59fad6 100644 --- a/mysql-test/include/mix1.inc +++ b/mysql-test/include/mix1.inc @@ -917,5 +917,29 @@ unlock tables; select * from t1; drop tables t1; +# +# Bug#29310: An InnoDB table was updated when the data wasn't actually changed. +# +create table t1(f1 varchar(5) unique, f2 timestamp NOT NULL DEFAULT + CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP); +insert into t1(f1) values(1); +--replace_column 1 # +select @a:=f2 from t1; +--sleep 5 +update t1 set f1=1; +--replace_column 1 # +select @b:=f2 from t1; +select if(@a=@b,"ok","wrong"); +--sleep 5 +insert into t1(f1) values (1) on duplicate key update f1="1"; +--replace_column 1 # +select @b:=f2 from t1; +select if(@a=@b,"ok","wrong"); +--sleep 5 +insert into t1(f1) select f1 from t1 on duplicate key update f1="1"; +--replace_column 1 # +select @b:=f2 from t1; +select if(@a=@b,"ok","wrong"); +drop table t1; --echo End of 5.1 tests diff --git a/mysql-test/include/ndb_master-slave.inc b/mysql-test/include/ndb_master-slave.inc index 81dd63be78a..1568072202b 100644 --- a/mysql-test/include/ndb_master-slave.inc +++ b/mysql-test/include/ndb_master-slave.inc @@ -4,7 +4,12 @@ connect (slave,127.0.0.1,root,,test,$SLAVE_MYPORT,); connect (slave1,127.0.0.1,root,,test,$SLAVE_MYPORT,); connection slave; --- source include/have_ndb.inc +# Check that server is compiled and started with support for NDB +disable_query_log; +--require r/true.require +select (support = 'YES' or support = 'DEFAULT') as `TRUE` from information_schema.engines where engine = 'ndbcluster'; +--source include/ndb_not_readonly.inc +enable_query_log; -- source include/master-slave-reset.inc diff --git a/mysql-test/ndb/ndb_config_2_node.ini b/mysql-test/ndb/ndb_config_2_node.ini index 6bcb148d471..57e4d049ad6 100644 --- a/mysql-test/ndb/ndb_config_2_node.ini +++ b/mysql-test/ndb/ndb_config_2_node.ini @@ -13,7 +13,8 @@ TimeBetweenGlobalCheckpoints= 500 NoOfFragmentLogFiles= 4 FragmentLogFileSize=12M DiskPageBufferMemory= CHOOSE_DiskPageBufferMemory -ODirect= 1 +# O_DIRECT has issues on 2.4 whach have not been handled, Bug #29612 +#ODirect= 1 # the following parametes just function as a small regression # test that the parameter exists InitialNoOfOpenFiles= 27 diff --git a/mysql-test/r/cast.result b/mysql-test/r/cast.result index c538d8d55e1..afd0a5a990e 100644 --- a/mysql-test/r/cast.result +++ b/mysql-test/r/cast.result @@ -403,4 +403,15 @@ hex(cast('a' as binary(2))) select hex(cast('a' as char(2) binary)); hex(cast('a' as char(2) binary)) 61 +CREATE TABLE t1 (d1 datetime); +INSERT INTO t1(d1) VALUES ('2007-07-19 08:30:00'), (NULL), +('2007-07-19 08:34:00'), (NULL), ('2007-07-19 08:36:00'); +SELECT cast(date(d1) as signed) FROM t1; +cast(date(d1) as signed) +20070719 +NULL +20070719 +NULL +20070719 +drop table t1; End of 5.0 tests diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result index cdbb767dd9f..de25fb754e4 100644 --- a/mysql-test/r/create.result +++ b/mysql-test/r/create.result @@ -1516,6 +1516,22 @@ t1 CREATE TABLE `t1` ( `c17` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; + +Bug #26104 Bug on foreign key class constructor + +Check that ref_columns is initalized correctly in the constructor +and semantic checks in mysql_prepare_table work. + +We do not need a storage engine that supports foreign keys +for this test, as the checks are purely syntax-based, and the +syntax is supported for all engines. + +drop table if exists t1,t2; +create table t1(a int not null, b int not null, primary key (a, b)); +create table t2(a int not null, b int not null, c int not null, primary key (a), +foreign key fk_bug26104 (b,c) references t1(a)); +ERROR 42000: Incorrect foreign key definition for 'fk_bug26104': Key reference and table reference don't match +drop table t1; End of 5.0 tests CREATE TABLE t1 (a int, b int); insert into t1 values (1,1),(1,2); diff --git a/mysql-test/r/ctype_big5.result b/mysql-test/r/ctype_big5.result index 3f1a87838cf..6d318a445f5 100644 --- a/mysql-test/r/ctype_big5.result +++ b/mysql-test/r/ctype_big5.result @@ -193,11 +193,13 @@ select hex(convert(_big5 0xC84041 using ucs2)); hex(convert(_big5 0xC84041 using ucs2)) 003F0041 End of 4.1 tests +set names big5; create table t1 (a blob); insert into t1 values (0xEE00); +select * into outfile 'test/t1.txt' from t1; delete from t1; -select hex(load_file('test/t1.txt')); -hex(load_file('test/t1.txt')) +select hex(load_file('MYSQLTEST_VARDIR/master-data/test/t1.txt'));; +hex(load_file('MYSQLTEST_VARDIR/master-data/test/t1.txt')) 5CEE5C300A load data infile 't1.txt' into table t1; select hex(a) from t1; diff --git a/mysql-test/r/ctype_collate.result b/mysql-test/r/ctype_collate.result index 5417c9da47e..f476ec68371 100644 --- a/mysql-test/r/ctype_collate.result +++ b/mysql-test/r/ctype_collate.result @@ -603,3 +603,11 @@ check table t1 extended; Table Op Msg_type Msg_text test.t1 check status OK drop table t1; +create table t1 (a varchar(2) character set latin7 collate latin7_general_ci,key(a)); +insert into t1 set a=0x4c20; +insert into t1 set a=0x6c; +insert into t1 set a=0x4c98; +check table t1 extended; +Table Op Msg_type Msg_text +test.t1 check status OK +drop table t1; diff --git a/mysql-test/r/ctype_latin1.result b/mysql-test/r/ctype_latin1.result index 32871563b64..763acd0fea0 100644 --- a/mysql-test/r/ctype_latin1.result +++ b/mysql-test/r/ctype_latin1.result @@ -405,3 +405,7 @@ i 1 2 DROP TABLE `abcÿdef`; +select hex(cast(_ascii 0x7f as char(1) character set latin1)); +hex(cast(_ascii 0x7f as char(1) character set latin1)) +7F +End of 5.0 tests diff --git a/mysql-test/r/ctype_ucs.result b/mysql-test/r/ctype_ucs.result index 6f1c9d3d52a..3720aa2910b 100644 --- a/mysql-test/r/ctype_ucs.result +++ b/mysql-test/r/ctype_ucs.result @@ -886,4 +886,14 @@ collation(group_concat(a separator ',')) latin1_swedish_ci drop table t1; set names latin1; +create table t1 (s1 char(1) character set ascii, s2 char(1) character set ucs2); +insert into t1 (s1) values (0x7f); +update t1 set s2 = s1; +select hex(s2) from t1; +hex(s2) +007F +select hex(convert(s1 using latin1)) from t1; +hex(convert(s1 using latin1)) +7F +drop table t1; End of 5.0 tests diff --git a/mysql-test/r/func_gconcat.result b/mysql-test/r/func_gconcat.result index 3fd204c84c9..b17c5e5409c 100644 --- a/mysql-test/r/func_gconcat.result +++ b/mysql-test/r/func_gconcat.result @@ -816,4 +816,13 @@ LENGTH( GROUP_CONCAT( a ) ) 65535 SET group_concat_max_len= DEFAULT; DROP TABLE t1, t2, t3; +set names latin1; +create table t1 (id int, name varchar(20)) DEFAULT CHARSET=utf8; +insert into t1 (id, name) values (1, "óra"); +insert into t1 (id, name) values (2, "óra"); +select b.id, group_concat(b.name) from t1 a, t1 b group by b.id; +id group_concat(b.name) +1 óra,óra +2 óra,óra +drop table t1; End of 5.0 tests diff --git a/mysql-test/r/gis-rtree.result b/mysql-test/r/gis-rtree.result index a3955e8c008..6e3aebe8d47 100644 --- a/mysql-test/r/gis-rtree.result +++ b/mysql-test/r/gis-rtree.result @@ -1444,3 +1444,16 @@ OPTIMIZE TABLE t1; Table Op Msg_type Msg_text test.t1 optimize status OK DROP TABLE t1; +CREATE TABLE t1 (a INT, b GEOMETRY NOT NULL, SPATIAL KEY b(b)); +INSERT INTO t1 VALUES (1, GEOMFROMTEXT('LINESTRING(1102218.456 1,2000000 2)')); +INSERT INTO t1 VALUES (2, GEOMFROMTEXT('LINESTRING(1102218.456 1,2000000 2)')); +SELECT COUNT(*) FROM t1 WHERE +MBRINTERSECTS(b, GEOMFROMTEXT('LINESTRING(1 1,1102219 2)') ); +COUNT(*) +2 +SELECT COUNT(*) FROM t1 IGNORE INDEX (b) WHERE +MBRINTERSECTS(b, GEOMFROMTEXT('LINESTRING(1 1,1102219 2)') ); +COUNT(*) +2 +DROP TABLE t1; +End of 5.0 tests. diff --git a/mysql-test/r/im_options.result b/mysql-test/r/im_options.result index 3225db0c8c5..22bd5d5bdf6 100644 --- a/mysql-test/r/im_options.result +++ b/mysql-test/r/im_options.result @@ -37,9 +37,10 @@ log-slow-queries option_value language option_value character-sets-dir option_value basedir option_value +shutdown-delay option_value skip-stack-trace option_value -skip-innodb option_value -skip-ndbcluster option_value +loose-skip-innodb option_value +loose-skip-ndbcluster option_value nonguarded option_value log-output option_value SET mysqld2.server_id = 2; @@ -57,9 +58,10 @@ log-slow-queries option_value language option_value character-sets-dir option_value basedir option_value +shutdown-delay option_value skip-stack-trace option_value -skip-innodb option_value -skip-ndbcluster option_value +loose-skip-innodb option_value +loose-skip-ndbcluster option_value nonguarded option_value log-output option_value server_id option_value diff --git a/mysql-test/r/index_merge_myisam.result b/mysql-test/r/index_merge_myisam.result index f135d849f76..9d7d06f7f1b 100644 --- a/mysql-test/r/index_merge_myisam.result +++ b/mysql-test/r/index_merge_myisam.result @@ -457,6 +457,67 @@ a 1 UNLOCK TABLES; DROP TABLE t1, t2; +CREATE TABLE `t1` ( +`a` int(11) DEFAULT NULL, +`filler` char(200) DEFAULT NULL, +`b` int(11) DEFAULT NULL, +KEY `a` (`a`), +KEY `b` (`b`) +) ENGINE=MEMORY DEFAULT CHARSET=latin1; +insert into t1 values +(0, 'filler', 0), (1, 'filler', 1), (2, 'filler', 2), (3, 'filler', 3), +(4, 'filler', 4), (5, 'filler', 5), (6, 'filler', 6), (7, 'filler', 7), +(8, 'filler', 8), (9, 'filler', 9), (0, 'filler', 0), (1, 'filler', 1), +(2, 'filler', 2), (3, 'filler', 3), (4, 'filler', 4), (5, 'filler', 5), +(6, 'filler', 6), (7, 'filler', 7), (8, 'filler', 8), (9, 'filler', 9), +(10, 'filler', 10), (11, 'filler', 11), (12, 'filler', 12), (13, 'filler', 13), +(14, 'filler', 14), (15, 'filler', 15), (16, 'filler', 16), (17, 'filler', 17), +(18, 'filler', 18), (19, 'filler', 19), (4, '5 ', 0), (5, '4 ', 0), +(4, '4 ', 0), (4, 'qq ', 5), (5, 'qq ', 4), (4, 'zz ', 4); +create table t2( +`a` int(11) DEFAULT NULL, +`filler` char(200) DEFAULT NULL, +`b` int(11) DEFAULT NULL, +KEY USING BTREE (`a`), +KEY USING BTREE (`b`) +) ENGINE=MEMORY DEFAULT CHARSET=latin1; +insert into t2 select * from t1; +must use sort-union rather than union: +explain select * from t1 where a=4 or b=4; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index_merge a,b a,b 5,5 NULL # Using sort_union(a,b); Using where +select * from t1 where a=4 or b=4; +a filler b +4 4 0 +4 5 0 +4 filler 4 +4 filler 4 +4 qq 5 +4 zz 4 +5 qq 4 +select * from t1 ignore index(a,b) where a=4 or b=4; +a filler b +4 4 0 +4 5 0 +4 filler 4 +4 filler 4 +4 qq 5 +4 zz 4 +5 qq 4 +must use union, not sort-union: +explain select * from t2 where a=4 or b=4; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 index_merge a,b a,b 5,5 NULL # Using union(a,b); Using where +select * from t2 where a=4 or b=4; +a filler b +4 4 0 +4 5 0 +4 filler 4 +4 filler 4 +4 qq 5 +4 zz 4 +5 qq 4 +drop table t1, t2; #---------------- ROR-index_merge tests ----------------------- SET SESSION STORAGE_ENGINE = MyISAM; drop table if exists t0,t1,t2; diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result index ad79a2a837a..804c4b81c17 100644 --- a/mysql-test/r/innodb.result +++ b/mysql-test/r/innodb.result @@ -1640,7 +1640,7 @@ t2 CREATE TABLE `t2` ( ) ENGINE=InnoDB DEFAULT CHARSET=latin1 drop table t2; create table t2 (id int(11) not null, id2 int(11) not null, constraint t1_id_fk foreign key (id2,id) references t1 (id)) engine = innodb; -ERROR HY000: Can't create table 'test.t2' (errno: 150) +ERROR 42000: Incorrect foreign key definition for 't1_id_fk': Key reference and table reference don't match create table t2 (a int auto_increment primary key, b int, index(b), foreign key (b) references t1(id), unique(b)) engine=innodb; show create table t2; Table Create Table @@ -3211,3 +3211,14 @@ t1 CREATE TABLE `t1` ( CONSTRAINT `t1_t2` FOREIGN KEY (`id`) REFERENCES `t2` (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=349 DEFAULT CHARSET=latin1 DROP TABLE t1,t2; +CREATE TABLE t1 ( +c01 CHAR(255), c02 CHAR(255), c03 CHAR(255), c04 CHAR(255), +c05 CHAR(255), c06 CHAR(255), c07 CHAR(255), c08 CHAR(255), +c09 CHAR(255), c10 CHAR(255), c11 CHAR(255), c12 CHAR(255), +c13 CHAR(255), c14 CHAR(255), c15 CHAR(255), c16 CHAR(255), +c17 CHAR(255), c18 CHAR(255), c19 CHAR(255), c20 CHAR(255), +c21 CHAR(255), c22 CHAR(255), c23 CHAR(255), c24 CHAR(255), +c25 CHAR(255), c26 CHAR(255), c27 CHAR(255), c28 CHAR(255), +c29 CHAR(255), c30 CHAR(255), c31 CHAR(255), c32 CHAR(255) +) ENGINE = InnoDB; +ERROR 42000: Row size too large. The maximum row size for the used table type, not counting BLOBs, is 8126. You have to change some columns to TEXT or BLOBs diff --git a/mysql-test/r/innodb_mysql.result b/mysql-test/r/innodb_mysql.result index 9494a04f593..3dc134352db 100644 --- a/mysql-test/r/innodb_mysql.result +++ b/mysql-test/r/innodb_mysql.result @@ -918,4 +918,32 @@ NULL 1 Two drop tables t1; +create table t1(f1 varchar(5) unique, f2 timestamp NOT NULL DEFAULT +CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP); +insert into t1(f1) values(1); +select @a:=f2 from t1; +@a:=f2 +# +update t1 set f1=1; +select @b:=f2 from t1; +@b:=f2 +# +select if(@a=@b,"ok","wrong"); +if(@a=@b,"ok","wrong") +ok +insert into t1(f1) values (1) on duplicate key update f1="1"; +select @b:=f2 from t1; +@b:=f2 +# +select if(@a=@b,"ok","wrong"); +if(@a=@b,"ok","wrong") +ok +insert into t1(f1) select f1 from t1 on duplicate key update f1="1"; +select @b:=f2 from t1; +@b:=f2 +# +select if(@a=@b,"ok","wrong"); +if(@a=@b,"ok","wrong") +ok +drop table t1; End of 5.1 tests diff --git a/mysql-test/r/innodb_trx_weight.result b/mysql-test/r/innodb_trx_weight.result new file mode 100644 index 00000000000..195775f74c8 --- /dev/null +++ b/mysql-test/r/innodb_trx_weight.result @@ -0,0 +1 @@ +SET storage_engine=InnoDB; diff --git a/mysql-test/r/join_nested.result b/mysql-test/r/join_nested.result index 2dd9af8719e..2bdac08e7fd 100644 --- a/mysql-test/r/join_nested.result +++ b/mysql-test/r/join_nested.result @@ -1632,4 +1632,115 @@ INSERT INTO t3 VALUES (1,1); SELECT * FROM t1 JOIN (t2 JOIN t3 USING (b)) USING (a); ERROR 23000: Column 'a' in from clause is ambiguous DROP TABLE t1,t2,t3; +CREATE TABLE t1 ( +carrier char(2) default NULL, +id int NOT NULL auto_increment PRIMARY KEY +); +INSERT INTO t1 VALUES +('CO',235371754),('CO',235376554),('CO',235376884),('CO',235377874), +('CO',231060394),('CO',231059224),('CO',231059314),('CO',231060484), +('CO',231060274),('CO',231060124),('CO',231060244),('CO',231058594), +('CO',231058924),('CO',231058504),('CO',231059344),('CO',231060424), +('CO',231059554),('CO',231060304),('CO',231059644),('CO',231059464), +('CO',231059764),('CO',231058294),('CO',231058624),('CO',231058864), +('CO',231059374),('CO',231059584),('CO',231059734),('CO',231059014), +('CO',231059854),('CO',231059494),('CO',231059794),('CO',231058534), +('CO',231058324),('CO',231058684),('CO',231059524),('CO',231059974); +CREATE TABLE t2 ( +scan_date date default NULL, +package_id int default NULL, +INDEX scan_date(scan_date), +INDEX package_id(package_id) +); +INSERT INTO t2 VALUES +('2008-12-29',231062944),('2008-12-29',231065764),('2008-12-29',231066124), +('2008-12-29',231060094),('2008-12-29',231061054),('2008-12-29',231065644), +('2008-12-29',231064384),('2008-12-29',231064444),('2008-12-29',231073774), +('2008-12-29',231058594),('2008-12-29',231059374),('2008-12-29',231066004), +('2008-12-29',231068494),('2008-12-29',231070174),('2008-12-29',231071884), +('2008-12-29',231063274),('2008-12-29',231063754),('2008-12-29',231064144), +('2008-12-29',231069424),('2008-12-29',231073714),('2008-12-29',231058414), +('2008-12-29',231060994),('2008-12-29',231069154),('2008-12-29',231068614), +('2008-12-29',231071464),('2008-12-29',231074014),('2008-12-29',231059614), +('2008-12-29',231059074),('2008-12-29',231059464),('2008-12-29',231069094), +('2008-12-29',231067294),('2008-12-29',231070144),('2008-12-29',231073804), +('2008-12-29',231072634),('2008-12-29',231058294),('2008-12-29',231065344), +('2008-12-29',231066094),('2008-12-29',231069034),('2008-12-29',231058594), +('2008-12-29',231059854),('2008-12-29',231059884),('2008-12-29',231059914), +('2008-12-29',231063664),('2008-12-29',231063814),('2008-12-29',231063904); +CREATE TABLE t3 ( +package_id int default NULL, +INDEX package_id(package_id) +); +INSERT INTO t3 VALUES +(231058294),(231058324),(231058354),(231058384),(231058414),(231058444), +(231058474),(231058504),(231058534),(231058564),(231058594),(231058624), +(231058684),(231058744),(231058804),(231058864),(231058924),(231058954), +(231059014),(231059074),(231059104),(231059134),(231059164),(231059194), +(231059224),(231059254),(231059284),(231059314),(231059344),(231059374), +(231059404),(231059434),(231059464),(231059494),(231059524),(231059554), +(231059584),(231059614),(231059644),(231059674),(231059704),(231059734), +(231059764),(231059794),(231059824),(231059854),(231059884),(231059914), +(231059944),(231059974),(231060004),(231060034),(231060064),(231060094), +(231060124),(231060154),(231060184),(231060214),(231060244),(231060274), +(231060304),(231060334),(231060364),(231060394),(231060424),(231060454), +(231060484),(231060514),(231060544),(231060574),(231060604),(231060634), +(231060664),(231060694),(231060724),(231060754),(231060784),(231060814), +(231060844),(231060874),(231060904),(231060934),(231060964),(231060994), +(231061024),(231061054),(231061084),(231061144),(231061174),(231061204), +(231061234),(231061294),(231061354),(231061384),(231061414),(231061474), +(231061564),(231061594),(231061624),(231061684),(231061714),(231061774), +(231061804),(231061894),(231061984),(231062074),(231062134),(231062224), +(231062254),(231062314),(231062374),(231062434),(231062494),(231062554), +(231062584),(231062614),(231062644),(231062704),(231062734),(231062794), +(231062854),(231062884),(231062944),(231063004),(231063034),(231063064), +(231063124),(231063154),(231063184),(231063214),(231063274),(231063334), +(231063394),(231063424),(231063454),(231063514),(231063574),(231063664); +CREATE TABLE t4 ( +carrier char(2) NOT NULL default '' PRIMARY KEY, +id int(11) default NULL, +INDEX id(id) +); +INSERT INTO t4 VALUES +('99',6),('SK',456),('UA',486),('AI',1081),('OS',1111),('VS',1510); +CREATE TABLE t5 ( +carrier_id int default NULL, +INDEX carrier_id(carrier_id) +); +INSERT INTO t5 VALUES +(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6), +(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6), +(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6), +(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6), +(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6), +(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(456),(456),(456), +(456),(456),(456),(456),(456),(456),(456),(456),(456),(456),(456),(456), +(456),(486),(1081),(1111),(1111),(1111),(1111),(1510); +SELECT COUNT(*) +FROM((t2 JOIN t1 ON t2.package_id = t1.id) +JOIN t3 ON t3.package_id = t1.id); +COUNT(*) +6 +EXPLAIN +SELECT COUNT(*) +FROM ((t2 JOIN t1 ON t2.package_id = t1.id) +JOIN t3 ON t3.package_id = t1.id) +LEFT JOIN +(t5 JOIN t4 ON t5.carrier_id = t4.id) +ON t4.carrier = t1.carrier; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 index package_id package_id 5 NULL 45 Using index +1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.package_id 1 +1 SIMPLE t4 eq_ref PRIMARY,id PRIMARY 2 test.t1.carrier 1 +1 SIMPLE t5 ref carrier_id carrier_id 5 test.t4.id 22 Using index +1 SIMPLE t3 ref package_id package_id 5 test.t1.id 1 Using where; Using index +SELECT COUNT(*) +FROM ((t2 JOIN t1 ON t2.package_id = t1.id) +JOIN t3 ON t3.package_id = t1.id) +LEFT JOIN +(t5 JOIN t4 ON t5.carrier_id = t4.id) +ON t4.carrier = t1.carrier; +COUNT(*) +6 +DROP TABLE t1,t2,t3,t4,t5; End of 5.0 tests diff --git a/mysql-test/r/log_state.result b/mysql-test/r/log_state.result index 946797aeec7..38b3ebd6e98 100644 --- a/mysql-test/r/log_state.result +++ b/mysql-test/r/log_state.result @@ -131,7 +131,7 @@ set global general_log=ON; set global log_output=default; show variables like 'log_output'; Variable_name Value -log_output TABLE +log_output FILE set global general_log=OFF; set global log_output=FILE; truncate table mysql.general_log; diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result index be3eabb47e9..e8c971a41bc 100644 --- a/mysql-test/r/mysqldump.result +++ b/mysql-test/r/mysqldump.result @@ -1890,7 +1890,7 @@ DROP TABLE IF EXISTS `v2`; /*!50001 CREATE TABLE `v2` ( `a` varchar(30) ) */; -/*!50001 DROP TABLE IF EXISTS `v2`*/; +/*!50001 DROP TABLE `v2`*/; /*!50001 DROP VIEW IF EXISTS `v2`*/; /*!50001 SET @saved_cs_client = @@character_set_client */; /*!50001 SET @saved_cs_results = @@character_set_results */; @@ -1981,7 +1981,7 @@ DROP TABLE IF EXISTS `v1`; /*!50001 CREATE TABLE `v1` ( `a` int(11) ) */; -/*!50001 DROP TABLE IF EXISTS `v1`*/; +/*!50001 DROP TABLE `v1`*/; /*!50001 DROP VIEW IF EXISTS `v1`*/; /*!50001 SET @saved_cs_client = @@character_set_client */; /*!50001 SET @saved_cs_results = @@character_set_results */; @@ -2049,7 +2049,7 @@ DROP TABLE IF EXISTS `v2`; /*!50001 CREATE TABLE `v2` ( `a` varchar(30) ) */; -/*!50001 DROP TABLE IF EXISTS `v2`*/; +/*!50001 DROP TABLE `v2`*/; /*!50001 DROP VIEW IF EXISTS `v2`*/; /*!50001 SET @saved_cs_client = @@character_set_client */; /*!50001 SET @saved_cs_results = @@character_set_results */; @@ -2168,7 +2168,7 @@ DROP TABLE IF EXISTS `v3`; `b` int(11), `c` varchar(30) ) */; -/*!50001 DROP TABLE IF EXISTS `v1`*/; +/*!50001 DROP TABLE `v1`*/; /*!50001 DROP VIEW IF EXISTS `v1`*/; /*!50001 SET @saved_cs_client = @@character_set_client */; /*!50001 SET @saved_cs_results = @@character_set_results */; @@ -2182,7 +2182,7 @@ DROP TABLE IF EXISTS `v3`; /*!50001 SET character_set_client = @saved_cs_client */; /*!50001 SET character_set_results = @saved_cs_results */; /*!50001 SET collation_connection = @saved_col_connection */; -/*!50001 DROP TABLE IF EXISTS `v2`*/; +/*!50001 DROP TABLE `v2`*/; /*!50001 DROP VIEW IF EXISTS `v2`*/; /*!50001 SET @saved_cs_client = @@character_set_client */; /*!50001 SET @saved_cs_results = @@character_set_results */; @@ -2196,7 +2196,7 @@ DROP TABLE IF EXISTS `v3`; /*!50001 SET character_set_client = @saved_cs_client */; /*!50001 SET character_set_results = @saved_cs_results */; /*!50001 SET collation_connection = @saved_col_connection */; -/*!50001 DROP TABLE IF EXISTS `v3`*/; +/*!50001 DROP TABLE `v3`*/; /*!50001 DROP VIEW IF EXISTS `v3`*/; /*!50001 SET @saved_cs_client = @@character_set_client */; /*!50001 SET @saved_cs_results = @@character_set_results */; @@ -2888,7 +2888,7 @@ DROP TABLE IF EXISTS `v2`; ) */; USE `test`; -/*!50001 DROP TABLE IF EXISTS `v0`*/; +/*!50001 DROP TABLE `v0`*/; /*!50001 DROP VIEW IF EXISTS `v0`*/; /*!50001 SET @saved_cs_client = @@character_set_client */; /*!50001 SET @saved_cs_results = @@character_set_results */; @@ -2902,7 +2902,7 @@ USE `test`; /*!50001 SET character_set_client = @saved_cs_client */; /*!50001 SET character_set_results = @saved_cs_results */; /*!50001 SET collation_connection = @saved_col_connection */; -/*!50001 DROP TABLE IF EXISTS `v1`*/; +/*!50001 DROP TABLE `v1`*/; /*!50001 DROP VIEW IF EXISTS `v1`*/; /*!50001 SET @saved_cs_client = @@character_set_client */; /*!50001 SET @saved_cs_results = @@character_set_results */; @@ -2916,7 +2916,7 @@ USE `test`; /*!50001 SET character_set_client = @saved_cs_client */; /*!50001 SET character_set_results = @saved_cs_results */; /*!50001 SET collation_connection = @saved_col_connection */; -/*!50001 DROP TABLE IF EXISTS `v2`*/; +/*!50001 DROP TABLE `v2`*/; /*!50001 DROP VIEW IF EXISTS `v2`*/; /*!50001 SET @saved_cs_client = @@character_set_client */; /*!50001 SET @saved_cs_results = @@character_set_results */; @@ -3145,6 +3145,7 @@ insert into t values(5, 51); create view v1 as select qty, price, qty*price as value from t; create view v2 as select qty from v1; mysqldump { +/*!50001 DROP TABLE `v1`*/; /*!50001 SET @saved_cs_client = @@character_set_client */; /*!50001 SET @saved_cs_results = @@character_set_results */; /*!50001 SET @saved_col_connection = @@collation_connection */; @@ -3159,6 +3160,7 @@ mysqldump { /*!50001 SET collation_connection = @saved_col_connection */; } mysqldump { +/*!50001 DROP TABLE `v2`*/; /*!50001 SET @saved_cs_client = @@character_set_client */; /*!50001 SET @saved_cs_results = @@character_set_results */; /*!50001 SET @saved_col_connection = @@collation_connection */; @@ -3251,7 +3253,7 @@ DROP TABLE IF EXISTS `v1`; ) */; USE `mysqldump_test_db`; -/*!50001 DROP TABLE IF EXISTS `v1`*/; +/*!50001 DROP TABLE `v1`*/; /*!50001 DROP VIEW IF EXISTS `v1`*/; /*!50001 SET @saved_cs_client = @@character_set_client */; /*!50001 SET @saved_cs_results = @@character_set_results */; @@ -3307,6 +3309,7 @@ USE `mysqldump_views`; USE `mysqldump_tables`; USE `mysqldump_views`; +/*!50001 DROP TABLE `nasishnasifu`*/; /*!50001 SET @saved_cs_client = @@character_set_client */; /*!50001 SET @saved_cs_results = @@character_set_results */; /*!50001 SET @saved_col_connection = @@collation_connection */; @@ -3560,6 +3563,16 @@ CREATE TABLE `t1` ( INSERT INTO `t1` VALUES (11,0x7171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171); DROP TABLE t1; # +# Bug #28524: mysqldump --skip-add-drop-table is not +# compatible with views +# +CREATE VIEW v1 AS SELECT 1; +DROP VIEW v1; +SELECT * FROM v1; +1 +1 +DROP VIEW v1; +# # End of 5.0 tests # drop table if exists t1; @@ -3862,7 +3875,7 @@ DROP TABLE IF EXISTS `v1`; ) */; USE `mysqldump_test_db`; -/*!50001 DROP TABLE IF EXISTS `v1`*/; +/*!50001 DROP TABLE `v1`*/; /*!50001 DROP VIEW IF EXISTS `v1`*/; /*!50001 SET @saved_cs_client = @@character_set_client */; /*!50001 SET @saved_cs_results = @@character_set_results */; diff --git a/mysql-test/r/mysqltest.result b/mysql-test/r/mysqltest.result index 8cf5f99dca3..55f78d22272 100644 --- a/mysql-test/r/mysqltest.result +++ b/mysql-test/r/mysqltest.result @@ -420,7 +420,7 @@ mysqltest: At line 1: query 'connect con2,localhost,root,,illegal_db' failed: 1 mysqltest: At line 1: Illegal argument for port: 'illegal_port' mysqltest: At line 1: Illegal option to connect: SMTP OK -mysqltest: In included file "MYSQLTEST_VARDIR/tmp/mysqltest.sql": At line 7: Connection limit exhausted, you can have max 128 connections +mysqltest: The test didn't produce any output mysqltest: In included file "MYSQLTEST_VARDIR/tmp/mysqltest.sql": At line 3: connection 'test_con1' not found in connection pool mysqltest: In included file "MYSQLTEST_VARDIR/tmp/mysqltest.sql": At line 2: Connection test_con1 already exists connect(localhost,root,,test,MASTER_PORT,MASTER_SOCKET); diff --git a/mysql-test/r/sp-prelocking.result b/mysql-test/r/sp-prelocking.result index 5eac54803f0..c19bd1abd26 100644 --- a/mysql-test/r/sp-prelocking.result +++ b/mysql-test/r/sp-prelocking.result @@ -267,4 +267,26 @@ drop table bug_27907_logs; insert into bug_27907_t1(a) values (1); ERROR 42S02: Table 'test.bug_27907_logs' doesn't exist drop table bug_27907_t1; + +Bug#22427 create table if not exists + stored function results in +inconsistent behavior + +Add a test case, the bug itself was fixed by the patch for +Bug#20662 + +drop table if exists t1; +drop function if exists f_bug22427; +create table t1 (i int); +insert into t1 values (1); +create function f_bug22427() returns int return (select max(i) from t1); +select f_bug22427(); +f_bug22427() +1 +create table if not exists t1 select f_bug22427() as i; +Warnings: +Note 1050 Table 't1' already exists +create table t1 select f_bug22427() as i; +ERROR 42S01: Table 't1' already exists +drop table t1; +drop function f_bug22427; End of 5.0 tests diff --git a/mysql-test/r/ssl-big.result b/mysql-test/r/ssl-big.result new file mode 100644 index 00000000000..39c4f34e46c --- /dev/null +++ b/mysql-test/r/ssl-big.result @@ -0,0 +1,3 @@ +DROP TABLE IF EXISTS t1, t2; +create table t1 (a int); +drop table t1; diff --git a/mysql-test/r/symlink.result b/mysql-test/r/symlink.result index 8ffe88acfa4..aba60f757c6 100644 --- a/mysql-test/r/symlink.result +++ b/mysql-test/r/symlink.result @@ -133,4 +133,26 @@ a 42 drop table t1; End of 4.1 tests +CREATE DATABASE db1; +CREATE DATABASE db2; +USE db2; +INSERT INTO db2.t1 VALUES (1); +SELECT * FROM db2.t1; +b +1 +RESET QUERY CACHE; +USE db1; +SET SESSION keep_files_on_create = TRUE; +CREATE TABLE t1 (a INT) ENGINE MYISAM; +Got one of the listed errors +CREATE TABLE t3 (a INT) Engine=MyISAM; +INSERT INTO t3 VALUES (1),(2),(3); +TRUNCATE TABLE t3; +SELECT * from t3; +a +SET SESSION keep_files_on_create = DEFAULT; +DROP TABLE db2.t1, db1.t3; +DROP DATABASE db1; +DROP DATABASE db2; +USE test; End of 5.0 tests diff --git a/mysql-test/r/trigger.result b/mysql-test/r/trigger.result index 5d41d60c37a..189722bfe9b 100644 --- a/mysql-test/r/trigger.result +++ b/mysql-test/r/trigger.result @@ -1933,6 +1933,34 @@ Before UPDATE, new=multi-UPDATE, SET for t2, but the trigger is fired, old=multi After UPDATE, new=multi-UPDATE, SET for t2, but the trigger is fired, old=multi-UPDATE drop view v1; drop table t1, t2, t1_op_log; + +Bug#27248 Triggers: error if insert affects temporary table + +The bug was fixed by the fix for Bug#26141 + +drop table if exists t1; +drop temporary table if exists t2; +create table t1 (s1 int); +create temporary table t2 (s1 int); +create trigger t1_bi before insert on t1 for each row insert into t2 values (0); +create trigger t1_bd before delete on t1 for each row delete from t2; +insert into t1 values (0); +insert into t1 values (0); +select * from t1; +s1 +0 +0 +select * from t2; +s1 +0 +0 +delete from t1; +select * from t1; +s1 +select * from t2; +s1 +drop table t1; +drop temporary table t2; End of 5.0 tests drop table if exists table_25411_a; drop table if exists table_25411_b; diff --git a/mysql-test/r/type_enum.result b/mysql-test/r/type_enum.result index 9535e6dd18a..ec72a6eb995 100644 --- a/mysql-test/r/type_enum.result +++ b/mysql-test/r/type_enum.result @@ -1809,4 +1809,24 @@ f1 drop table t1; +CREATE TABLE t1 (c1 ENUM('a', '', 'b')); +INSERT INTO t1 (c1) VALUES ('b'); +INSERT INTO t1 (c1) VALUES (''); +INSERT INTO t1 (c1) VALUES (0); +Warnings: +Warning 1265 Data truncated for column 'c1' at row 1 +INSERT INTO t1 (c1) VALUES (''); +SELECT c1 + 0, COUNT(c1) FROM t1 GROUP BY c1; +c1 + 0 COUNT(c1) +0 1 +2 2 +3 1 +CREATE TABLE t2 SELECT * FROM t1; +SELECT c1 + 0 FROM t2; +c1 + 0 +3 +2 +0 +2 +DROP TABLE t1,t2; End of 5.1 tests diff --git a/mysql-test/r/type_ranges.result b/mysql-test/r/type_ranges.result index ce5bb9ceb2f..22580c155f3 100644 --- a/mysql-test/r/type_ranges.result +++ b/mysql-test/r/type_ranges.result @@ -208,10 +208,6 @@ options flags one one drop table t2; create table t2 select * from t1; -Warnings: -Warning 1265 Data truncated for column 'options' at row 4 -Warning 1265 Data truncated for column 'options' at row 5 -Warning 1265 Data truncated for column 'options' at row 6 update t2 set string="changed" where auto=16; show full columns from t1; Field Type Collation Null Key Default Extra Privileges Comment diff --git a/mysql-test/r/type_time.result b/mysql-test/r/type_time.result index ce820c0cb8e..d80a3973555 100644 --- a/mysql-test/r/type_time.result +++ b/mysql-test/r/type_time.result @@ -85,3 +85,46 @@ sec_to_time(time_to_sec(t)) 13:00:00 09:00:00 drop table t1; +select cast('100:55:50' as time) < cast('24:00:00' as time); +cast('100:55:50' as time) < cast('24:00:00' as time) +0 +select cast('100:55:50' as time) < cast('024:00:00' as time); +cast('100:55:50' as time) < cast('024:00:00' as time) +0 +select cast('300:55:50' as time) < cast('240:00:00' as time); +cast('300:55:50' as time) < cast('240:00:00' as time) +0 +select cast('100:55:50' as time) > cast('24:00:00' as time); +cast('100:55:50' as time) > cast('24:00:00' as time) +1 +select cast('100:55:50' as time) > cast('024:00:00' as time); +cast('100:55:50' as time) > cast('024:00:00' as time) +1 +select cast('300:55:50' as time) > cast('240:00:00' as time); +cast('300:55:50' as time) > cast('240:00:00' as time) +1 +create table t1 (f1 time); +insert into t1 values ('24:00:00'); +select cast('24:00:00' as time) = (select f1 from t1); +cast('24:00:00' as time) = (select f1 from t1) +1 +drop table t1; +create table t1(f1 time, f2 time); +insert into t1 values('20:00:00','150:00:00'); +select 1 from t1 where cast('100:00:00' as time) between f1 and f2; +1 +1 +drop table t1; +CREATE TABLE t1 ( +f2 date NOT NULL, +f3 int(11) unsigned NOT NULL default '0', +PRIMARY KEY (f3, f2) +); +insert into t1 values('2007-07-01', 1); +insert into t1 values('2007-07-01', 2); +insert into t1 values('2007-07-02', 1); +insert into t1 values('2007-07-02', 2); +SELECT sum(f3) FROM t1 where f2='2007-07-01 00:00:00' group by f2; +sum(f3) +3 +drop table t1; diff --git a/mysql-test/suite/binlog/r/binlog_row_binlog.result b/mysql-test/suite/binlog/r/binlog_row_binlog.result index 37fe49e79dc..1d1656889f4 100644 --- a/mysql-test/suite/binlog/r/binlog_row_binlog.result +++ b/mysql-test/suite/binlog/r/binlog_row_binlog.result @@ -258,117 +258,8 @@ master-bin.000001 419 Table_map 1 458 table_id: # (test.t1) master-bin.000001 458 Write_rows 1 492 table_id: # flags: STMT_END_F master-bin.000001 492 Xid 1 519 COMMIT /* XID */ master-bin.000001 519 Query 1 595 use `test`; drop table t1 -set autocommit= 1; -reset master; -create table t1(n int) engine=innodb; -insert into t1 values (1); -insert into t1 values (2); -insert into t1 values (3); -commit; -drop table t1; -show binlog events from 0; -Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 4 Format_desc 1 106 Server version, Binlog ver: 4 -master-bin.000001 106 Query 1 205 use `test`; create table t1(n int) engine=innodb -master-bin.000001 205 Table_map 1 244 table_id: # (test.t1) -master-bin.000001 244 Write_rows 1 278 table_id: # flags: STMT_END_F -master-bin.000001 278 Xid 1 305 COMMIT /* XID */ -master-bin.000001 305 Table_map 1 344 table_id: # (test.t1) -master-bin.000001 344 Write_rows 1 378 table_id: # flags: STMT_END_F -master-bin.000001 378 Xid 1 405 COMMIT /* XID */ -master-bin.000001 405 Table_map 1 444 table_id: # (test.t1) -master-bin.000001 444 Write_rows 1 478 table_id: # flags: STMT_END_F -master-bin.000001 478 Xid 1 505 COMMIT /* XID */ -master-bin.000001 505 Query 1 581 use `test`; drop table t1 -reset master; -create table t1(n int) engine=myisam; -begin; -insert into t1 values (4); -insert into t1 values (5); -insert into t1 values (6); -commit; -drop table t1; -show binlog events from 0; -Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 4 Format_desc 1 106 Server version, Binlog ver: 4 -master-bin.000001 106 Query 1 205 use `test`; create table t1(n int) engine=myisam -master-bin.000001 205 Table_map 1 244 table_id: # (test.t1) -master-bin.000001 244 Write_rows 1 278 table_id: # flags: STMT_END_F -master-bin.000001 278 Table_map 1 317 table_id: # (test.t1) -master-bin.000001 317 Write_rows 1 351 table_id: # flags: STMT_END_F -master-bin.000001 351 Table_map 1 390 table_id: # (test.t1) -master-bin.000001 390 Write_rows 1 424 table_id: # flags: STMT_END_F -master-bin.000001 424 Query 1 500 use `test`; drop table t1 -set autocommit= 1; -reset master; -create table t1(n int) engine=innodb; -show master status; -File Position Binlog_Do_DB Binlog_Ignore_DB -master-bin.000001 205 -insert into t1 values (1); -show master status; -File Position Binlog_Do_DB Binlog_Ignore_DB -master-bin.000001 305 -insert into t1 values (2); -insert into t1 values (3); -show master status; -File Position Binlog_Do_DB Binlog_Ignore_DB -master-bin.000001 505 -commit; -show master status; -File Position Binlog_Do_DB Binlog_Ignore_DB -master-bin.000001 505 -drop table t1; -show binlog events from 0; -Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 4 Format_desc 1 106 Server version, Binlog ver: 4 -master-bin.000001 106 Query 1 205 use `test`; create table t1(n int) engine=innodb -master-bin.000001 205 Table_map 1 244 table_id: # (test.t1) -master-bin.000001 244 Write_rows 1 278 table_id: # flags: STMT_END_F -master-bin.000001 278 Xid 1 305 COMMIT /* XID */ -master-bin.000001 305 Table_map 1 344 table_id: # (test.t1) -master-bin.000001 344 Write_rows 1 378 table_id: # flags: STMT_END_F -master-bin.000001 378 Xid 1 405 COMMIT /* XID */ -master-bin.000001 405 Table_map 1 444 table_id: # (test.t1) -master-bin.000001 444 Write_rows 1 478 table_id: # flags: STMT_END_F -master-bin.000001 478 Xid 1 505 COMMIT /* XID */ -master-bin.000001 505 Query 1 581 use `test`; drop table t1 -set autocommit= 0; -reset master; -create table t1(n int) engine=myisam; -show master status; -File Position Binlog_Do_DB Binlog_Ignore_DB -master-bin.000001 205 -insert into t1 values (4); -show master status; -File Position Binlog_Do_DB Binlog_Ignore_DB -master-bin.000001 278 -insert into t1 values (5); -insert into t1 values (6); -show master status; -File Position Binlog_Do_DB Binlog_Ignore_DB -master-bin.000001 424 -commit; -show master status; -File Position Binlog_Do_DB Binlog_Ignore_DB -master-bin.000001 424 -drop table t1; -show binlog events from 0; -Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 4 Format_desc 1 106 Server version, Binlog ver: 4 -master-bin.000001 106 Query 1 205 use `test`; create table t1(n int) engine=myisam -master-bin.000001 205 Table_map 1 244 table_id: # (test.t1) -master-bin.000001 244 Write_rows 1 278 table_id: # flags: STMT_END_F -master-bin.000001 278 Table_map 1 317 table_id: # (test.t1) -master-bin.000001 317 Write_rows 1 351 table_id: # flags: STMT_END_F -master-bin.000001 351 Table_map 1 390 table_id: # (test.t1) -master-bin.000001 390 Write_rows 1 424 table_id: # flags: STMT_END_F -master-bin.000001 424 Query 1 500 use `test`; drop table t1 -set session autocommit = @ac; set @bcs = @@binlog_cache_size; -set @ac = @@autocommit; set global binlog_cache_size=4096; -set autocommit= 0; reset master; create table t1 (a int) engine=innodb; show binlog events from 0; diff --git a/mysql-test/suite/binlog/r/binlog_row_ctype_cp932.result b/mysql-test/suite/binlog/r/binlog_row_ctype_cp932.result index ca70f98c0e6..ef9f76b7d9c 100644 --- a/mysql-test/suite/binlog/r/binlog_row_ctype_cp932.result +++ b/mysql-test/suite/binlog/r/binlog_row_ctype_cp932.result @@ -11335,6 +11335,22 @@ cp932_bin 6109 cp932_bin 61 cp932_bin 6120 drop table t1; +create table t2 (a char(1)); +insert into t2 values ('0'),('1'),('2'),('3'),('4'),('5'),('6'),('7'); +insert into t2 values ('8'),('9'),('A'),('B'),('C'),('D'),('E'),('F'); +create table t1 ( +a varchar(2) character set cp932 +) engine=myisam; +insert into t1 +select unhex(concat(t24.a, t23.a, t22.a, t21.a)) +from t2 t21, t2 t22, t2 t23, t2 t24; +delete from t1 where a=''; +alter table t1 add key(a); +check table t1; +Table Op Msg_type Msg_text +test.t1 check status OK +drop table t1; +drop table t2; create table t1 (col1 varchar(1)) character set cp932; insert into t1 values ('a'); insert into t1 values ('ab'); diff --git a/mysql-test/suite/binlog/r/binlog_stm_binlog.result b/mysql-test/suite/binlog/r/binlog_stm_binlog.result index 238cafa6f68..80908e6b450 100644 --- a/mysql-test/suite/binlog/r/binlog_stm_binlog.result +++ b/mysql-test/suite/binlog/r/binlog_stm_binlog.result @@ -165,105 +165,8 @@ master-bin.000001 361 Query 1 449 use `test`; insert into t1 values (2) master-bin.000001 449 Query 1 537 use `test`; insert into t1 values (3) master-bin.000001 537 Xid 1 564 COMMIT /* XID */ master-bin.000001 564 Query 1 640 use `test`; drop table t1 -set autocommit= 1; -reset master; -create table t1(n int) engine=innodb; -insert into t1 values (1); -insert into t1 values (2); -insert into t1 values (3); -commit; -drop table t1; -show binlog events from 0; -Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 4 Format_desc 1 106 Server version, Binlog ver: 4 -master-bin.000001 106 Query 1 205 use `test`; create table t1(n int) engine=innodb -master-bin.000001 205 Query 1 293 use `test`; insert into t1 values (1) -master-bin.000001 293 Xid 1 320 COMMIT /* XID */ -master-bin.000001 320 Query 1 408 use `test`; insert into t1 values (2) -master-bin.000001 408 Xid 1 435 COMMIT /* XID */ -master-bin.000001 435 Query 1 523 use `test`; insert into t1 values (3) -master-bin.000001 523 Xid 1 550 COMMIT /* XID */ -master-bin.000001 550 Query 1 626 use `test`; drop table t1 -reset master; -create table t1(n int) engine=myisam; -begin; -insert into t1 values (4); -insert into t1 values (5); -insert into t1 values (6); -commit; -drop table t1; -show binlog events from 0; -Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 4 Format_desc 1 106 Server version, Binlog ver: 4 -master-bin.000001 106 Query 1 205 use `test`; create table t1(n int) engine=myisam -master-bin.000001 205 Query 1 293 use `test`; insert into t1 values (4) -master-bin.000001 293 Query 1 381 use `test`; insert into t1 values (5) -master-bin.000001 381 Query 1 469 use `test`; insert into t1 values (6) -master-bin.000001 469 Query 1 545 use `test`; drop table t1 -set autocommit= 1; -reset master; -create table t1(n int) engine=innodb; -show master status; -File Position Binlog_Do_DB Binlog_Ignore_DB -master-bin.000001 205 -insert into t1 values (1); -show master status; -File Position Binlog_Do_DB Binlog_Ignore_DB -master-bin.000001 320 -insert into t1 values (2); -insert into t1 values (3); -show master status; -File Position Binlog_Do_DB Binlog_Ignore_DB -master-bin.000001 550 -commit; -show master status; -File Position Binlog_Do_DB Binlog_Ignore_DB -master-bin.000001 550 -drop table t1; -show binlog events from 0; -Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 4 Format_desc 1 106 Server version, Binlog ver: 4 -master-bin.000001 106 Query 1 205 use `test`; create table t1(n int) engine=innodb -master-bin.000001 205 Query 1 293 use `test`; insert into t1 values (1) -master-bin.000001 293 Xid 1 320 COMMIT /* XID */ -master-bin.000001 320 Query 1 408 use `test`; insert into t1 values (2) -master-bin.000001 408 Xid 1 435 COMMIT /* XID */ -master-bin.000001 435 Query 1 523 use `test`; insert into t1 values (3) -master-bin.000001 523 Xid 1 550 COMMIT /* XID */ -master-bin.000001 550 Query 1 626 use `test`; drop table t1 -set autocommit= 0; -reset master; -create table t1(n int) engine=myisam; -show master status; -File Position Binlog_Do_DB Binlog_Ignore_DB -master-bin.000001 205 -insert into t1 values (4); -show master status; -File Position Binlog_Do_DB Binlog_Ignore_DB -master-bin.000001 293 -insert into t1 values (5); -insert into t1 values (6); -show master status; -File Position Binlog_Do_DB Binlog_Ignore_DB -master-bin.000001 469 -commit; -show master status; -File Position Binlog_Do_DB Binlog_Ignore_DB -master-bin.000001 469 -drop table t1; -show binlog events from 0; -Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 4 Format_desc 1 106 Server version, Binlog ver: 4 -master-bin.000001 106 Query 1 205 use `test`; create table t1(n int) engine=myisam -master-bin.000001 205 Query 1 293 use `test`; insert into t1 values (4) -master-bin.000001 293 Query 1 381 use `test`; insert into t1 values (5) -master-bin.000001 381 Query 1 469 use `test`; insert into t1 values (6) -master-bin.000001 469 Query 1 545 use `test`; drop table t1 -set session autocommit = @ac; set @bcs = @@binlog_cache_size; -set @ac = @@autocommit; set global binlog_cache_size=4096; -set autocommit= 0; reset master; create table t1 (a int) engine=innodb; show binlog events from 0; diff --git a/mysql-test/suite/binlog/r/binlog_stm_ctype_cp932.result b/mysql-test/suite/binlog/r/binlog_stm_ctype_cp932.result index ca70f98c0e6..ef9f76b7d9c 100755 --- a/mysql-test/suite/binlog/r/binlog_stm_ctype_cp932.result +++ b/mysql-test/suite/binlog/r/binlog_stm_ctype_cp932.result @@ -11335,6 +11335,22 @@ cp932_bin 6109 cp932_bin 61 cp932_bin 6120 drop table t1; +create table t2 (a char(1)); +insert into t2 values ('0'),('1'),('2'),('3'),('4'),('5'),('6'),('7'); +insert into t2 values ('8'),('9'),('A'),('B'),('C'),('D'),('E'),('F'); +create table t1 ( +a varchar(2) character set cp932 +) engine=myisam; +insert into t1 +select unhex(concat(t24.a, t23.a, t22.a, t21.a)) +from t2 t21, t2 t22, t2 t23, t2 t24; +delete from t1 where a=''; +alter table t1 add key(a); +check table t1; +Table Op Msg_type Msg_text +test.t1 check status OK +drop table t1; +drop table t2; create table t1 (col1 varchar(1)) character set cp932; insert into t1 values ('a'); insert into t1 values ('ab'); diff --git a/mysql-test/r/ndb_binlog_format.result b/mysql-test/suite/ndb/r/ndb_binlog_format.result index ed26060e2a4..ed26060e2a4 100644 --- a/mysql-test/r/ndb_binlog_format.result +++ b/mysql-test/suite/ndb/r/ndb_binlog_format.result diff --git a/mysql-test/t/ndb_binlog_format.test b/mysql-test/suite/ndb/t/ndb_binlog_format.test index acb34bb388c..acb34bb388c 100644 --- a/mysql-test/t/ndb_binlog_format.test +++ b/mysql-test/suite/ndb/t/ndb_binlog_format.test diff --git a/mysql-test/suite/ndb/t/ndb_multi.test b/mysql-test/suite/ndb/t/ndb_multi.test index 3482db1d1b2..b8e052d606b 100644 --- a/mysql-test/suite/ndb/t/ndb_multi.test +++ b/mysql-test/suite/ndb/t/ndb_multi.test @@ -1,4 +1,3 @@ --- source include/have_ndb.inc -- source include/have_multi_ndb.inc -- source include/not_embedded.inc diff --git a/mysql-test/suite/ndb/t/ndb_multi_row.test b/mysql-test/suite/ndb/t/ndb_multi_row.test index 632a9fda89a..543e282b900 100644 --- a/mysql-test/suite/ndb/t/ndb_multi_row.test +++ b/mysql-test/suite/ndb/t/ndb_multi_row.test @@ -1,4 +1,3 @@ --- source include/have_ndb.inc -- source include/have_multi_ndb.inc -- source include/not_embedded.inc -- source include/have_binlog_format_row.inc diff --git a/mysql-test/suite/rpl/include/rpl_mixed_ddl.inc b/mysql-test/suite/rpl/include/rpl_mixed_ddl.inc index 7ea92a5cc1e..0b13116300e 100644 --- a/mysql-test/suite/rpl/include/rpl_mixed_ddl.inc +++ b/mysql-test/suite/rpl/include/rpl_mixed_ddl.inc @@ -67,7 +67,7 @@ ALTER TABLE t2 DROP COLUMN d; --echo --echo ******************** SHOW BINLOG EVENTS ******************** --replace_column 2 # 5 # ---replace_regex /table_id: [0-9]+/table_id: #/ +--replace_regex /Server ver: .+/Server ver: #/ /table_id: [0-9]+/table_id: #/ show binlog events from 1; sync_slave_with_master; # as we're using UUID we don't SELECT but use "diff" like in rpl_row_UUID diff --git a/mysql-test/suite/rpl/include/rpl_mixed_dml.inc b/mysql-test/suite/rpl/include/rpl_mixed_dml.inc index c79eb756c7f..cc225d1bb28 100644 --- a/mysql-test/suite/rpl/include/rpl_mixed_dml.inc +++ b/mysql-test/suite/rpl/include/rpl_mixed_dml.inc @@ -326,8 +326,8 @@ DROP VIEW v2; --echo --echo ******************** SHOW BINLOG EVENTS ******************** --replace_column 2 # 5 # ---replace_regex /table_id: [0-9]+/table_id: #/ /COMMIT.+xid=[0-9]+.+/#/ -show binlog events from 102; +--replace_regex /Server ver: .+/Server ver: #/ /table_id: [0-9]+/table_id: #/ /COMMIT.+xid=[0-9]+.+/#/ +show binlog events from 1; sync_slave_with_master; # as we're using UUID we don't SELECT but use "diff" like in rpl_row_UUID --exec $MYSQL_DUMP --compact --order-by-primary --skip-extended-insert --no-create-info test_rpl > $MYSQLTEST_VARDIR/tmp/rpl_switch_stm_row_mixed_master.sql diff --git a/mysql-test/suite/rpl/r/rpl_innodb_mixed_ddl.result b/mysql-test/suite/rpl/r/rpl_innodb_mixed_ddl.result index db75a2c5b4d..85308442fd8 100644 --- a/mysql-test/suite/rpl/r/rpl_innodb_mixed_ddl.result +++ b/mysql-test/suite/rpl/r/rpl_innodb_mixed_ddl.result @@ -138,7 +138,7 @@ ALTER TABLE t2 DROP COLUMN d; ******************** SHOW BINLOG EVENTS ******************** show binlog events from 1; Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 # Format_desc 1 # Server ver: 5.1.16-beta-debug-log, Binlog ver: 4 +master-bin.000001 # Format_desc 1 # Server ver: # master-bin.000001 # Query 1 # DROP DATABASE IF EXISTS test_rpl master-bin.000001 # Query 1 # DROP DATABASE IF EXISTS test_rpl_1 master-bin.000001 # Query 1 # CREATE DATABASE test_rpl_1 CHARACTER SET utf8 COLLATE utf8_general_ci diff --git a/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result b/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result index 8c625dc70a4..7100e5cbe9c 100644 --- a/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result +++ b/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result @@ -684,11 +684,12 @@ CREATE EVENT e1 ON SCHEDULE EVERY '1' SECOND COMMENT 'e_second_comment' DO DELET ==========MASTER========== SHOW EVENTS; Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator -test_rpl e1 root@localhost RECURRING NULL 1 SECOND # # ENABLED +test_rpl e1 root@localhost SYSTEM RECURRING NULL 1 # # NULL ENABLED 1 ==========SLAVE=========== USE test_rpl; SHOW EVENTS; Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator +test_rpl e1 @ SYSTEM RECURRING NULL 1 # # NULL SLAVESIDE_DISABLED 1 ==========MASTER========== SELECT COUNT(*) FROM t1; COUNT(*) @@ -743,11 +744,12 @@ ALTER EVENT e1 RENAME TO e2; ==========MASTER========== SHOW EVENTS; Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator -test_rpl e2 root@localhost RECURRING NULL 1 SECOND # # ENABLED +test_rpl e2 root@localhost SYSTEM RECURRING NULL 1 # # NULL ENABLED 1 ==========SLAVE=========== USE test_rpl; SHOW EVENTS; Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator +test_rpl e2 @ SYSTEM RECURRING NULL 1 # # NULL SLAVESIDE_DISABLED 1 ==========MASTER========== SELECT COUNT(*) FROM t1; COUNT(*) @@ -827,8 +829,9 @@ DELETE FROM t2; ******************** SHOW BINLOG EVENTS ******************** -show binlog events from 102; +show binlog events from 1; Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Format_desc 1 # Server ver: # master-bin.000001 # Query 1 # CREATE DATABASE test_rpl master-bin.000001 # Query 1 # use `test_rpl`; CREATE TABLE t1 (a int auto_increment not null, b char(254), PRIMARY KEY(a)) ENGINE=innodb master-bin.000001 # Query 1 # use `test_rpl`; CREATE TABLE t2 (a int auto_increment not null, b char(254), PRIMARY KEY(a)) ENGINE=innodb @@ -1011,6 +1014,9 @@ master-bin.000001 # Query 1 # use `test_rpl`; DROP TRIGGER tr1 master-bin.000001 # Query 1 # use `test_rpl`; GRANT EVENT ON *.* TO 'root'@'localhost' master-bin.000001 # Query 1 # use `test_rpl`; INSERT INTO t1 VALUES(1, 'test1') master-bin.000001 # Xid 1 # # +master-bin.000001 # Query 1 # use `test_rpl`; CREATE EVENT e1 ON SCHEDULE EVERY '1' SECOND COMMENT 'e_second_comment' DO DELETE FROM t1 +master-bin.000001 # Query 1 # use `test_rpl`; ALTER EVENT e1 RENAME TO e2 +master-bin.000001 # Query 1 # use `test_rpl`; DROP EVENT e2 master-bin.000001 # Query 1 # use `test_rpl`; DELETE FROM t1 master-bin.000001 # Xid 1 # # master-bin.000001 # Query 1 # use `test_rpl`; DELETE FROM t2 diff --git a/mysql-test/suite/rpl/t/rpl_innodb_mixed_ddl.test b/mysql-test/suite/rpl/t/rpl_innodb_mixed_ddl.test index 1d4709bb548..6eb9c7075e4 100644 --- a/mysql-test/suite/rpl/t/rpl_innodb_mixed_ddl.test +++ b/mysql-test/suite/rpl/t/rpl_innodb_mixed_ddl.test @@ -5,9 +5,10 @@ # Requirements: define binlog format for mysqld as in example below: # ./mysql-test-run.pl --mysqld=--binlog-format=mixed ######################################### - +--source include/have_binlog_format_mixed.inc --source include/have_innodb.inc let $engine_type= innodb; --source suite/rpl/include/rpl_mixed_ddl.inc +# End 5.1 Test Case diff --git a/mysql-test/suite/rpl/t/rpl_innodb_mixed_dml.test b/mysql-test/suite/rpl/t/rpl_innodb_mixed_dml.test index f6b21c4af1c..d48e847a6c8 100644 --- a/mysql-test/suite/rpl/t/rpl_innodb_mixed_dml.test +++ b/mysql-test/suite/rpl/t/rpl_innodb_mixed_dml.test @@ -5,9 +5,10 @@ # Requirements: define binlog format for mysqld as in example below: # ./mysql-test-run.pl --mysqld=--binlog-format=mixed ######################################### - +--source include/have_binlog_format_mixed.inc --source include/have_innodb.inc let $engine_type= innodb; --source suite/rpl/include/rpl_mixed_dml.inc +# End 5.1 Test Case diff --git a/mysql-test/suite/rpl_ndb/t/disabled.def b/mysql-test/suite/rpl_ndb/t/disabled.def index 8392c39331e..a1e6cef6fca 100644 --- a/mysql-test/suite/rpl_ndb/t/disabled.def +++ b/mysql-test/suite/rpl_ndb/t/disabled.def @@ -15,9 +15,8 @@ rpl_ndb_circular_simplex : BUG#27972 2007-04-20 mats Slave cannot start where it rpl_ndb_2innodb : BUG#19227 2006-04-20 pekka pk delete apparently not replicated rpl_ndb_2myisam : BUG#19227 Seems to pass currently rpl_ndb_dd_partitions : BUG#19259 2006-04-21 rpl_ndb_dd_partitions fails on s/AMD -rpl_ndb_innodb2ndb : Bug #19710 Cluster replication to partition table fails on DELETE FROM statement -rpl_ndb_myisam2ndb : Bug #19710 Cluster replication to partition table fails on DELETE FROM statement -#rpl_row_blob_innodb : BUG#18980 2006-04-10 kent Test fails randomly +rpl_ndb_innodb2ndb : Bug#29549 rpl_ndb_myisam2ndb,rpl_ndb_innodb2ndb failed on Solaris for pack_length issue +rpl_ndb_myisam2ndb : Bug#29549 rpl_ndb_myisam2ndb,rpl_ndb_innodb2ndb failed on Solaris for pack_length issue rpl_ndb_ddl : BUG#28798 2007-05-31 lars Valgrind failure in NDB rpl_ndb_mix_innodb : BUG#28123 rpl_ndb_mix_innodb.test casue slave to core on sol10-sparc-a rpl_ndb_ctype_ucs2_def : BUG#27404 util thd mysql_parse sig11 when mysqld default multibyte charset diff --git a/mysql-test/suite/stress/include/ddl.cln b/mysql-test/suite/stress/include/ddl.cln new file mode 100644 index 00000000000..7d021a8c912 --- /dev/null +++ b/mysql-test/suite/stress/include/ddl.cln @@ -0,0 +1,4 @@ +######## include/ddl.cln ######## +disconnect con2; +DEALLOCATE PREPARE stmt_start; +DEALLOCATE PREPARE stmt_break; diff --git a/mysql-test/suite/stress/include/ddl.pre b/mysql-test/suite/stress/include/ddl.pre new file mode 100644 index 00000000000..52de4a3665b --- /dev/null +++ b/mysql-test/suite/stress/include/ddl.pre @@ -0,0 +1,21 @@ +######## include/ddl.pre ######## +# The variable +# $runtime -- rough intended runtime per subtest variant +# must be set within the routine sourcing this script. +# +# Please look for more details within include/ddl1.inc. +# +# Creation of this test: +# 2007-07-11 mleich +# +SET @@session.sql_mode = 'NO_ENGINE_SUBSTITUTION'; +PREPARE stmt_start FROM "SELECT UNIX_TIMESTAMP() INTO @start"; +--replace_result $runtime <intended_runtime> +eval SET @runtime = $runtime; +eval PREPARE stmt_break FROM "SELECT UNIX_TIMESTAMP() - @start > @runtime - 1"; +connect (con2,localhost,root,,); +connection default; + +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings diff --git a/mysql-test/suite/stress/include/ddl1.inc b/mysql-test/suite/stress/include/ddl1.inc new file mode 100644 index 00000000000..96adadc5af5 --- /dev/null +++ b/mysql-test/suite/stress/include/ddl1.inc @@ -0,0 +1,277 @@ +######## include/ddl1.inc ###### +# +# Purpose of include/ddl1.inc - include/ddl8.inc: +# +# Stress storage engines with rapid CREATE/DROP TABLE/INDEX +# and following SELECT/INSERT/SHOW etc. +# +# The variables +# $loop_size -- number of rounds till we look at the clock again +# $runtime -- rough intended runtime per subtest variant +# Real runtime without server restarts and comparison is: +# - >= $runtime +# - > runtime needed for $loop_size execution loops +# $engine_type -- storage engine to be used in CREATE TABLE +# must be set within the routine sourcing this script. +# +# Other stuff which must already exist: +# - connection con2 +# - stmt_start and stmt_break prepared by the default connection +# +# Attention: +# The test does suppress the writing of most statements, server error +# messages and result sets. +# This is needed because their number is usual not deterministic. +# The test is partially self checking. That means is prints some +# helpful hints into the protocol and aborts if something is wrong. +# +# Creation of this test: +# 2007-07-04 mleich +# +############################################################################ +# +# Some details: +# +# 1. Base question of the test: +# There was just a create or drop of some object (TABLE/INDEX). +# +# Could it happen that the next statement referring to this +# object gets a somehow wrong server response (result set, +# error message, warning) because the creation or removal of +# the object is in an incomplete state? +# +# Thinkable reasons for incomplete state of creation or removal: +# The server performs the creation or removal +# - all time incomplete. +# Example: +# Bug#28309 First insert violates unique constraint +# - was "memory" table empty ? +# - asynchronous +# In that case the next statement has probably to wait till +# completion. +# +# 2. Why do we use in some scripts "--error 0,<expected error>" followed +# a check of $mysql_errno? +# +# System reactions when running with "--error 0,<expected error>": +# - RC=0 --> no error message +# - RC=<expected error> --> no error message +# - RC not in (0,<expected error>) --> error message + abort of script +# execution +# +# Requirements and tricky solution for statements which are expected +# to fail: +# 1. RC=<expected error> +# - no abort of script execution +# --> add "--error <expected error>" +# - no error message into the protocol, because the number of +# executions is NOT deterministic +# --> use "--error 0,<expected error>" +# 2. RC=0 = failure +# - abort of script execution +# "--error 0,<expected error>" prevents the automatic abort of +# execution. Therefore we do not need to code the abort. +# --> Check $mysql_errno and do an explicit abort if $mysql_errno = 0. +# 3. RC not in (0,<expected error>) +# - abort of script execution +# "--error 0,<expected error>" causes an automatic abort. +# +# 3. We do not check the correctness of the SHOW CREATE TABLE output +# in detail. This must be done within other tests. +# We only check here that +# - same CREATE TABLE/INDEX statements lead to the same +# - different CREATE TABLE/INDEX statements lead to different +# SHOW CREATE TABLE output +# (Applies to ddl4.inc. and ddl8.inc.) +# +# 4. It could be assumed that running this test with +# - PS-PROTOCOL +# There are already subtests using prepared statements contained. +# - SP/CURSOR/VIEW-PROTOCOL +# These protocol variants transform SELECTs to hopefully much +# stressing statement sequencies using SP/CURSOR/VIEW. +# The SELECTs within include/ddl*.inc are very simple. +# does not increase the coverage. +# Therefore we skip runs with these protocols. +# +# 5. The test consumes significant runtime when running on a non RAM +# based filesystem (run without "--mem"). +# Therefore we adjust $runtime and $loop_size depending on "--big-test" +# option. +# $runtime and $loop_size do not influence the expected results. +# Rough runtime in seconds reported by mysql-test-run.pl: +# (engine_type = MEMORY) +# option set -> $runtime $loop_size real runtime in seconds +# 1 20 68 +# --mem 1 20 32 +# --big-test 5 100 200 +# --mem --big-test 5 100 400 +# I assume that runs with slow filesystems are as much valuable +# as runs with extreme fast filesystems. +# +# 6. Hints for analysis of test failures: +# 1. Look into the protocol and check in which ddl*.inc +# script the difference to the expected result occured. +# 2. Comment the sourcing of all other ddl*.inc scripts +# out. +# 3. Edit the ddl*.inc script where the error occured and +# remove all +# - "--disable_query_log", "--disable_result_log" +# - successful passed subtests. +# 4. Alternative: +# Have a look into VARDIR/master-data/mysql/general_log.CSV +# and construct a new testcase from that. +# 5. If the problem is not deterministic, please try the following +# - increase $runtime (important), $loop_size (most probably +# less important) within the "t/ddl_<engine>.test" and +# maybe the "--testcase-timeout" assigned to mysqltest-run.pl +# - vary the I/O performance of the testing machine by using +# a RAM or disk based filesystem for VARDIR +# + + +#---------------------------------------------------------------------- +# Settings for Subtest 1 variants +# Scenario: CREATE with UNIQUE KEY/INSERT/DROP TABLE like in Bug#28309 +let $create_table= CREATE TABLE t1 (f1 BIGINT,f2 BIGINT,UNIQUE(f1),UNIQUE(f2)) +ENGINE = $engine_type; +let $insert_into= INSERT INTO t1 VALUES (1,1), (2,2), (3,3); +let $drop_table= DROP TABLE t1; +#---------------------------------------------------------------------- + +# +--echo # Subtest 1A (one connection, no PREPARE/EXECUTE) +--echo # connection action +--echo # default: $create_table +--echo # default: $insert_into +--echo # default: $drop_table +--disable_query_log +connection default; +let $run= 1; +# Determine the current time. +EXECUTE stmt_start; +# Run execution loops till the planned runtime is reached +while ($run) +{ + let $loop_run= $loop_size; + while ($loop_run) + { + eval $create_table; + eval $insert_into; + eval $drop_table; + dec $loop_run; + } + if (`EXECUTE stmt_break`) + { + let $run= 0; + } +} +--enable_query_log +# +--echo # Subtest 1B (one connection, use PREPARE/EXECUTE) +--echo # connection action +--echo # default: $create_table +--echo # default: $insert_into +--echo # default: $drop_table +--disable_query_log +connection default; +eval PREPARE create_table FROM "$create_table"; +EXECUTE create_table; +eval PREPARE insert_into FROM "$insert_into"; +eval PREPARE drop_table FROM "$drop_table"; +EXECUTE drop_table; +let $run= 1; +# Determine the current time. +EXECUTE stmt_start; +# Run execution loops till the planned runtime is reached +while ($run) +{ + let $loop_run= $loop_size; + while ($loop_run) + { + EXECUTE create_table; + EXECUTE insert_into; + EXECUTE drop_table; + dec $loop_run; + } + if (`EXECUTE stmt_break`) + { + let $run= 0; + } +} +DEALLOCATE PREPARE create_table; +DEALLOCATE PREPARE insert_into; +DEALLOCATE PREPARE drop_table; +--enable_query_log +# +--echo # Subtest 1C (two connections, no PREPARE/EXECUTE) +--echo # connection action +--echo # default: $create_table +--echo # con2: $insert_into +--echo # con2: $drop_table +--disable_query_log +connection default; +let $run= 1; +# Determine the current time. +EXECUTE stmt_start; +# Run execution loops till the planned runtime is reached +while ($run) +{ + let $loop_run= $loop_size; + while ($loop_run) + { + eval $create_table; + connection con2; + eval $insert_into; + eval $drop_table; + connection default; + dec $loop_run; + } + if (`EXECUTE stmt_break`) + { + let $run= 0; + } +} +--enable_query_log +# +--echo # Subtest 1D (two connections, use PREPARE/EXECUTE) +--echo # connection action +--echo # default: $create_table +--echo # con2: $insert_into +--echo # con2: $drop_table +--disable_query_log +connection default; +eval PREPARE create_table FROM "$create_table"; +EXECUTE create_table; +connection con2; +eval PREPARE insert_into FROM "$insert_into"; +eval PREPARE drop_table FROM "$drop_table"; +EXECUTE drop_table; +connection default; +let $run= 1; +# Determine the current time. +EXECUTE stmt_start; +# Run execution loops till the planned runtime is reached +while ($run) +{ + let $loop_run= $loop_size; + while ($loop_run) + { + EXECUTE create_table; + connection con2; + EXECUTE insert_into; + EXECUTE drop_table; + connection default; + dec $loop_run; + } + if (`EXECUTE stmt_break`) + { + let $run= 0; + } +} +DEALLOCATE PREPARE create_table; +connection con2; +DEALLOCATE PREPARE insert_into; +DEALLOCATE PREPARE drop_table; +connection default; +--enable_query_log diff --git a/mysql-test/suite/stress/include/ddl2.inc b/mysql-test/suite/stress/include/ddl2.inc new file mode 100644 index 00000000000..dd2ec0fd804 --- /dev/null +++ b/mysql-test/suite/stress/include/ddl2.inc @@ -0,0 +1,259 @@ +######## include/ddl2.inc ###### +# +# Stress the storage engine with rapid CREATE/DROP TABLE/INDEX +# and following SELECT/INSERT/SHOW etc. +# Subtest 2 variants (2A - 2D) +# +# The variables +# $loop_size -- number of rounds till we look at the clock again +# $runtime -- rough intended runtime per subtest variant +# $engine_type -- storage engine to be used in CREATE TABLE +# must be set within the routine sourcing this script. +# +# Other stuff which must already exist: +# - connection con2 +# - stmt_start and stmt_break prepared by the default connection +# +# Please look for more details within include/ddl1.inc. +# +# Creation of this test: +# 2007-07-04 mleich +# + + +#---------------------------------------------------------------------- +# Settings for Subtest 2 variants +# Scenario: CREATE TABLE AS SELECT/SELECT/DROP/SELECT(F) +let $create_table= CREATE TABLE t1 ENGINE = $engine_type AS SELECT 1 AS f1; +let $select_record= SELECT COUNT(*) <> 1 FROM t1 WHERE f1 = 1; +let $drop_table= DROP TABLE t1; +#---------------------------------------------------------------------- + +# +--echo # Subtest 2A (one connection, no PREPARE/EXECUTE) +--echo # connection action +--echo # default: $create_table +--echo # default: $select_record +--echo # default: $drop_table +--echo # default: $select_record (expect to get ER_NO_SUCH_TABLE) +--disable_query_log +--disable_result_log +connection default; +let $run= 1; +# Determine the current time. +EXECUTE stmt_start; +# Run execution loops till the planned runtime is reached +while ($run) +{ + let $loop_run= $loop_size; + while ($loop_run) + { + eval $create_table; + if (`$select_record`) + { + --enable_result_log + --enable_query_log + --echo # Error: Unexpected content within t1. + --echo # Expected: 0 + --echo # Got: + eval $select_record; + SELECT * FROM t1; + --echo # abort + exit; + } + eval $drop_table; + --error 0,ER_NO_SUCH_TABLE + eval $select_record; + if (!$mysql_errno) + { + --echo # Error: SELECT was successful though we expected ER_NO_SUCH_TABLE + --echo # abort + exit; + } + dec $loop_run; + } + if (`EXECUTE stmt_break`) + { + let $run= 0; + } +} +--enable_result_log +--enable_query_log +# +--echo # Subtest 2B (one connection, use PREPARE/EXECUTE) +--echo # connection action +--echo # default: $create_table +--echo # default: $select_record +--echo # default: $drop_table +--echo # default: $select_record (expect to get ER_NO_SUCH_TABLE) +--disable_query_log +--disable_result_log +connection default; +eval PREPARE create_table FROM "$create_table"; +EXECUTE create_table; +eval PREPARE select_record FROM "$select_record"; +eval PREPARE drop_table FROM "$drop_table"; +EXECUTE drop_table; +let $run= 1; +# Determine the current time. +EXECUTE stmt_start; +# Run execution loops till the planned runtime is reached +while ($run) +{ + let $loop_run= $loop_size; + while ($loop_run) + { + EXECUTE create_table; + if (`EXECUTE select_record`) + { + --enable_result_log + --enable_query_log + --echo # Error: Unexpected content within t1. + --echo # Expected: 0 + --echo # Got: + EXECUTE select_record; + SELECT * FROM t1; + --echo # abort + exit; + } + EXECUTE drop_table; + --error 0,ER_NO_SUCH_TABLE + EXECUTE select_record; + if (!$mysql_errno) + { + --echo # Error: SELECT was successful though we expected ER_NO_SUCH_TABLE + --echo # abort + exit; + } + dec $loop_run; + } + if (`EXECUTE stmt_break`) + { + let $run= 0; + } +} +DEALLOCATE PREPARE create_table; +DEALLOCATE PREPARE select_record; +DEALLOCATE PREPARE drop_table; +--enable_result_log +--enable_query_log +# +--echo # Subtest 2C (two connections, no PREPARE/EXECUTE) +--echo # connection action +--echo # default: $create_table +--echo # con2: $select_record +--echo # default: $drop_table +--echo # con2: $select_record (expect to get ER_NO_SUCH_TABLE) +--disable_query_log +--disable_result_log +connection default; +let $run= 1; +# Determine the current time. +EXECUTE stmt_start; +# Run execution loops till the planned runtime is reached +while ($run) +{ + let $loop_run= $loop_size; + while ($loop_run) + { + eval $create_table; + connection con2; + if (`$select_record`) + { + --enable_result_log + --enable_query_log + --echo # Error: Unexpected content within t1. + --echo # Expected: 0 + --echo # Got: + eval $select_record; + SELECT * FROM t1; + --echo # abort + exit; + } + connection default; + eval $drop_table; + connection con2; + --error 0,ER_NO_SUCH_TABLE + eval $select_record; + if (!$mysql_errno) + { + --echo # Error: SELECT was successful though we expected ER_NO_SUCH_TABLE + --echo # abort + exit; + } + connection default; + dec $loop_run; + } + if (`EXECUTE stmt_break`) + { + let $run= 0; + } +} +--enable_result_log +--enable_query_log +# +--echo # Subtest 2D (two connections, use PREPARE/EXECUTE) +--echo # connection action +--echo # default: $create_table +--echo # con2: $select_record +--echo # default: $drop_table +--echo # con2: $select_record (expect to get ER_NO_SUCH_TABLE) +--disable_query_log +--disable_result_log +connection default; +eval PREPARE create_table FROM "$create_table"; +eval PREPARE drop_table FROM "$drop_table"; +EXECUTE create_table; +connection con2; +eval PREPARE select_record FROM "$select_record"; +connection default; +EXECUTE drop_table; +let $run= 1; +# Determine the current time. +EXECUTE stmt_start; +# Run execution loops till the planned runtime is reached +while ($run) +{ + let $loop_run= $loop_size; + while ($loop_run) + { + EXECUTE create_table; + connection con2; + if (`EXECUTE select_record`) + { + --enable_result_log + --enable_query_log + --echo # Error: Unexpected content within t1. + --echo # Expected: 0 + --echo # Got: + EXECUTE select_record; + SELECT * FROM t1; + --echo # abort + exit; + } + connection default; + EXECUTE drop_table; + connection con2; + --error 0,ER_NO_SUCH_TABLE + EXECUTE select_record; + if (!$mysql_errno) + { + --echo # Error: SELECT was successful though we expected ER_NO_SUCH_TABLE + --echo # abort + exit; + } + connection default; + dec $loop_run; + } + if (`EXECUTE stmt_break`) + { + let $run= 0; + } +} +DEALLOCATE PREPARE create_table; +DEALLOCATE PREPARE drop_table; +connection con2; +DEALLOCATE PREPARE select_record; +connection default; +--enable_result_log +--enable_query_log diff --git a/mysql-test/suite/stress/include/ddl3.inc b/mysql-test/suite/stress/include/ddl3.inc new file mode 100644 index 00000000000..aacf09f9428 --- /dev/null +++ b/mysql-test/suite/stress/include/ddl3.inc @@ -0,0 +1,242 @@ +######## include/ddl3.inc ###### +# +# Stress the storage engine with rapid CREATE/DROP TABLE/INDEX +# and following SELECT/INSERT/SHOW etc. +# Subtest 3 variants (3A - 3D) +# +# The variables +# $loop_size -- number of rounds till we look at the clock again +# $runtime -- rough intended runtime per subtest variant +# $engine_type -- storage engine to be used in CREATE TABLE +# must be set within the routine sourcing this script. +# +# Other stuff which must already exist: +# - connection con2 +# - stmt_start and stmt_break prepared by the default connection +# +# Please look for more details within include/ddl2.inc. +# +# Creation of this test: +# 2007-07-04 mleich +# + + +#---------------------------------------------------------------------- +# Settings for Subtest 3 variants +# Scenario: CREATE TABLE/CREATE TABLE(F)/DROP TABLE/DROP TABLE(F) +let $create_table= CREATE TABLE t1 (f1 BIGINT) ENGINE=$engine_type; +let $drop_table= DROP TABLE t1; +#---------------------------------------------------------------------- + +# +--echo # Subtest 3A (one connection, no PREPARE/EXECUTE) +--echo # connection action +--echo # default: $create_table +--echo # default: $create_table (expect to get ER_TABLE_EXISTS_ERROR) +--echo # default: $drop_table +--echo # default: $drop_table (expect to get ER_BAD_TABLE_ERROR) +--disable_query_log +--disable_result_log +connection default; +let $run= 1; +# Determine the current time. +EXECUTE stmt_start; +# Run execution loops till the planned runtime is reached +while ($run) +{ + let $loop_run= $loop_size; + while ($loop_run) + { + eval $create_table; + --error 0,ER_TABLE_EXISTS_ERROR + eval $create_table; + if (!$mysql_errno) + { + --echo # Error: CREATE TABLE was successful though we expected ER_TABLE_EXISTS_ERROR + --echo # abort + exit; + } + eval $drop_table; + --error 0,ER_BAD_TABLE_ERROR + eval $drop_table; + if (!$mysql_errno) + { + --echo # Error: DROP TABLE was successful though we expected ER_BAD_TABLE_ERROR) + --echo # abort + exit; + } + dec $loop_run; + } + if (`EXECUTE stmt_break`) + { + let $run= 0; + } +} +--enable_result_log +--enable_query_log +# +--echo # Subtest 3B (one connection, use PREPARE/EXECUTE) +--echo # connection action +--echo # default: $create_table +--echo # default: $create_table (expect to get ER_TABLE_EXISTS_ERROR) +--echo # default: $drop_table +--echo # default: $drop_table (expect to get ER_BAD_TABLE_ERROR) +--disable_query_log +--disable_result_log +connection default; +eval PREPARE create_table FROM "$create_table"; +EXECUTE create_table; +eval PREPARE drop_table FROM "$drop_table"; +EXECUTE drop_table; +let $run= 1; +# Determine the current time. +EXECUTE stmt_start; +# Run execution loops till the planned runtime is reached +while ($run) +{ + let $loop_run= $loop_size; + while ($loop_run) + { + EXECUTE create_table; + --error 0,ER_TABLE_EXISTS_ERROR + EXECUTE create_table; + if (!$mysql_errno) + { + --echo # Error: CREATE TABLE was successful though we expected ER_TABLE_EXISTS_ERROR + --echo # abort + exit; + } + EXECUTE drop_table; + --error 0,ER_BAD_TABLE_ERROR + EXECUTE drop_table; + if (!$mysql_errno) + { + --echo # Error: DROP TABLE was successful though we expected ER_BAD_TABLE_ERROR) + --echo # abort + exit; + } + dec $loop_run; + } + if (`EXECUTE stmt_break`) + { + let $run= 0; + } +} +DEALLOCATE PREPARE create_table; +DEALLOCATE PREPARE drop_table; +--enable_result_log +--enable_query_log +# +--echo # Subtest 3C (two connections, no PREPARE/EXECUTE) +--echo # connection action +--echo # default: $create_table +--echo # con2: $create_table (expect to get ER_TABLE_EXISTS_ERROR) +--echo # default: $drop_table +--echo # con2: $drop_table (expect to get ER_BAD_TABLE_ERROR) +--disable_query_log +--disable_result_log +connection default; +let $run= 1; +# Determine the current time. +EXECUTE stmt_start; +# Run execution loops till the planned runtime is reached +while ($run) +{ + let $loop_run= $loop_size; + while ($loop_run) + { + eval $create_table; + connection con2; + --error 0,ER_TABLE_EXISTS_ERROR + eval $create_table; + if (!$mysql_errno) + { + --echo # Error: CREATE TABLE was successful though we expected ER_TABLE_EXISTS_ERROR + --echo # abort + exit; + } + connection default; + eval $drop_table; + connection con2; + --error 0,ER_BAD_TABLE_ERROR + eval $drop_table; + if (!$mysql_errno) + { + --echo # Error: DROP TABLE was successful though we expected ER_BAD_TABLE_ERROR) + --echo # abort + exit; + } + connection default; + dec $loop_run; + } + if (`EXECUTE stmt_break`) + { + let $run= 0; + } +} +--enable_result_log +--enable_query_log +# +--echo # Subtest 3D (two connections, use PREPARE/EXECUTE) +--echo # connection action +--echo # default: $create_table +--echo # con2: $create_table (expect to get ER_TABLE_EXISTS_ERROR) +--echo # default: $drop_table +--echo # con2: $drop_table (expect to get ER_BAD_TABLE_ERROR) +--disable_query_log +--disable_result_log +connection default; +eval PREPARE create_table FROM "$create_table"; +eval PREPARE drop_table FROM "$drop_table"; +EXECUTE create_table; +connection con2; +eval PREPARE create_table FROM "$create_table"; +eval PREPARE drop_table FROM "$drop_table"; +EXECUTE drop_table; +connection default; +let $run= 1; +# Determine the current time. +EXECUTE stmt_start; +# Run execution loops till the planned runtime is reached +while ($run) +{ + let $loop_run= $loop_size; + while ($loop_run) + { + EXECUTE create_table; + connection con2; + --error 0,ER_TABLE_EXISTS_ERROR + EXECUTE create_table; + if (!$mysql_errno) + { + --echo # Error: CREATE TABLE was successful though we expected ER_TABLE_EXISTS_ERROR + --echo # abort + exit; + } + connection default; + EXECUTE drop_table; + connection con2; + --error 0,ER_BAD_TABLE_ERROR + EXECUTE drop_table; + if (!$mysql_errno) + { + --echo # Error: DROP TABLE was successful though we expected ER_BAD_TABLE_ERROR) + --echo # abort + exit; + } + connection default; + dec $loop_run; + } + if (`EXECUTE stmt_break`) + { + let $run= 0; + } +} +DEALLOCATE PREPARE create_table; +DEALLOCATE PREPARE drop_table; +connection con2; +DEALLOCATE PREPARE create_table; +DEALLOCATE PREPARE drop_table; +connection default; +--enable_result_log +--enable_query_log diff --git a/mysql-test/suite/stress/include/ddl4.inc b/mysql-test/suite/stress/include/ddl4.inc new file mode 100644 index 00000000000..10452a453a5 --- /dev/null +++ b/mysql-test/suite/stress/include/ddl4.inc @@ -0,0 +1,339 @@ +######## include/ddl4.inc ###### +# +# Stress the storage engine with rapid CREATE/DROP TABLE/INDEX +# and following SELECT/INSERT/SHOW etc. +# Subtest 4 variants (4A - 4D) +# +# The variables +# $loop_size -- number of rounds till we look at the clock again +# $runtime -- rough intended runtime per subtest variant +# $engine_type -- storage engine to be used in CREATE TABLE +# must be set within the routine sourcing this script. +# +# Other stuff which must already exist: +# - connection con2 +# - stmt_start and stmt_break prepared by the default connection +# +# Please look for more details within include/ddl1.inc. +# +# Creation of this test: +# 2007-07-04 mleich +# + + +#---------------------------------------------------------------------- +# Settings for Subtest 4 variants +# Scenario: CREATE TABLE variant1/SHOW/DROP TABLE/SHOW(F)/ +# CREATE TABLE variant2/SHOW/DROP TABLE +let $create_table1= CREATE TABLE t1 (f1 BIGINT, f2 BIGINT, UNIQUE(f1), UNIQUE (f2)) ENGINE=$engine_type; +let $create_table2= CREATE TABLE t1 (f1 BIGINT) ENGINE=$engine_type; +let $show_table= SHOW CREATE TABLE t1; +let $drop_table= DROP TABLE t1; +# +eval $create_table1; +let $cr_value1= INITIALIZED; +let $cr_value1= query_get_value($show_table, Create Table, 1); +eval $drop_table; +eval $create_table2; +let $cr_value2= INITIALIZED; +let $cr_value2= query_get_value($show_table, Create Table, 1); +eval $drop_table; +if (`SELECT '$cr_value1' = '$cr_value2'`) +{ + --echo # Error during generation of prerequisites. + --echo # cr_value1 equals cr_value2 + --echo # cr_value1: $cr_value1 + --echo # cr_value2: $cr_value2 + --echo # abort + exit; +} +#---------------------------------------------------------------------- + +# +--echo # Subtest 4A (one connection, no PREPARE/EXECUTE) +--echo # connection action +--echo # default: $create_table1 +--echo # default: $show_table +--echo # default: $drop_table +--echo # default: $show_table (expect to get ER_NO_SUCH_TABLE) +--echo # default: $create_table2 +--echo # default: $show_table +--echo # default: $drop_table +--disable_query_log +--disable_result_log +connection default; +let $run= 1; +# Determine the current time. +EXECUTE stmt_start; +# Run execution loops till the planned runtime is reached +while ($run) +{ + let $loop_run= $loop_size; + while ($loop_run) + { + eval $create_table1; + let $value= INITIALIZED; + let $value= query_get_value($show_table, Create Table, 1); + if (`SELECT '$value' <> '$cr_value1'`) + { + --echo # Error: Unexpected SHOW CREATE TABLE output + --echo # Got: $value + --echo # Expected: $cr_value1 + --echo # abort + exit; + } + eval $drop_table; + --error 0,ER_NO_SUCH_TABLE + eval $show_table; + if (!$mysql_errno) + { + --echo # Error: SHOW CREATE TABLE was successful though we expected ER_NO_SUCH_TABLE) + --echo # abort + exit; + } + eval $create_table2; + let $value= INITIALIZED; + let $value= query_get_value($show_table, Create Table, 1); + if (`SELECT '$value' <> '$cr_value2'`) + { + --echo # Error: Unexpected SHOW CREATE TABLE output + --echo # Got: $value + --echo # Expected: $cr_value2 + --echo # abort + exit; + } + eval $drop_table; + dec $loop_run; + } + if (`EXECUTE stmt_break`) + { + let $run= 0; + } +} +--enable_result_log +--enable_query_log +# +--echo # Subtest 4B (one connection, use PREPARE/EXECUTE) +--echo # connection action +--echo # default: $create_table1 +--echo # default: $show_table +--echo # default: $drop_table +--echo # default: $show_table (expect to get ER_NO_SUCH_TABLE) +--echo # default: $create_table2 +--echo # default: $show_table +--echo # default: $drop_table +--disable_query_log +--disable_result_log +connection default; +eval PREPARE create_table1 FROM "$create_table1"; +eval PREPARE create_table2 FROM "$create_table2"; +EXECUTE create_table1; +eval PREPARE show_table FROM "$show_table"; +eval PREPARE drop_table FROM "$drop_table"; +EXECUTE drop_table; +let $run= 1; +# Determine the current time. +EXECUTE stmt_start; +# Run execution loops till the planned runtime is reached +while ($run) +{ + let $loop_run= $loop_size; + while ($loop_run) + { + EXECUTE create_table1; + let $value= INITIALIZED; + let $value= query_get_value(EXECUTE show_table, Create Table, 1); + if (`SELECT '$value' <> '$cr_value1'`) + { + --echo # Error: Unexpected SHOW CREATE TABLE output + --echo # Got: $value + --echo # Expected: $cr_value1 + --echo # abort + exit; + } + EXECUTE drop_table; + --error 0,ER_NO_SUCH_TABLE + EXECUTE show_table; + if (!$mysql_errno) + { + --echo # Error: SHOW CREATE TABLE was successful though we expected ER_NO_SUCH_TABLE) + --echo # abort + exit; + } + EXECUTE create_table2; + let $value= INITIALIZED; + let $value= query_get_value(EXECUTE show_table, Create Table, 1); + if (`SELECT '$value' <> '$cr_value2'`) + { + --echo # Error: Unexpected SHOW CREATE TABLE output + --echo # Got: $value + --echo # Expected: $cr_value2 + --echo # abort + exit; + } + EXECUTE drop_table; + dec $loop_run; + } + if (`EXECUTE stmt_break`) + { + let $run= 0; + } +} +DEALLOCATE PREPARE create_table1; +DEALLOCATE PREPARE create_table2; +DEALLOCATE PREPARE show_table; +DEALLOCATE PREPARE drop_table; +--enable_result_log +--enable_query_log +# +--echo # Subtest 4C (two connections, no PREPARE/EXECUTE) +--echo # connection action +--echo # default: $create_table1 +--echo # con2: $show_table +--echo # default: $drop_table +--echo # con2: $show_table (expect to get ER_NO_SUCH_TABLE) +--echo # default: $create_table2 +--echo # con2: $show_table +--echo # default: $drop_table +--disable_query_log +--disable_result_log +connection default; +let $run= 1; +# Determine the current time. +EXECUTE stmt_start; +# Run execution loops till the planned runtime is reached +while ($run) +{ + let $loop_run= $loop_size; + while ($loop_run) + { + eval $create_table1; + connection con2; + let $value= INITIALIZED; + let $value= query_get_value($show_table, Create Table, 1); + if (`SELECT '$value' <> '$cr_value1'`) + { + --echo # Error: Unexpected SHOW CREATE TABLE output + --echo # Got: $value + --echo # Expected: $cr_value1 + --echo # abort + exit; + } + connection default; + eval $drop_table; + connection con2; + --error 0,ER_NO_SUCH_TABLE + eval $show_table; + if (!$mysql_errno) + { + --echo # Error: SHOW CREATE TABLE was successful though we expected ER_NO_SUCH_TABLE) + --echo # abort + exit; + } + connection default; + eval $create_table2; + connection con2; + let $value= INITIALIZED; + let $value= query_get_value($show_table, Create Table, 1); + if (`SELECT '$value' <> '$cr_value2'`) + { + --echo # Error: Unexpected SHOW CREATE TABLE output + --echo # Got: $value + --echo # Expected: $cr_value2 + --echo # abort + exit; + } + connection default; + eval $drop_table; + dec $loop_run; + } + if (`EXECUTE stmt_break`) + { + let $run= 0; + } +} +--enable_result_log +--enable_query_log +# +--echo # Subtest 4D (two connections, use PREPARE/EXECUTE) +--echo # connection action +--echo # default: $create_table1 +--echo # con2: $show_table +--echo # default: $drop_table +--echo # con2: $show_table (expect to get ER_NO_SUCH_TABLE) +--echo # default: $create_table2 +--echo # con2: $show_table +--echo # default: $drop_table +--disable_query_log +--disable_result_log +connection default; +eval PREPARE create_table1 FROM "$create_table1"; +eval PREPARE create_table2 FROM "$create_table2"; +eval PREPARE drop_table FROM "$drop_table"; +EXECUTE create_table1; +connection con2; +eval PREPARE show_table FROM "$show_table"; +connection default; +EXECUTE drop_table; +let $run= 1; +# Determine the current time. +EXECUTE stmt_start; +# Run execution loops till the planned runtime is reached +while ($run) +{ + let $loop_run= $loop_size; + while ($loop_run) + { + EXECUTE create_table1; + connection con2; + let $value= INITIALIZED; + let $value= query_get_value(EXECUTE show_table, Create Table, 1); + if (`SELECT '$value' <> '$cr_value1'`) + { + --echo # Error: Unexpected SHOW CREATE TABLE output + --echo # Got: $value + --echo # Expected: $cr_value1 + --echo # abort + exit; + } + connection default; + EXECUTE drop_table; + connection con2; + --error 0,ER_NO_SUCH_TABLE + EXECUTE show_table; + if (!$mysql_errno) + { + --echo # Error: SHOW CREATE TABLE was successful though we expected ER_NO_SUCH_TABLE) + --echo # abort + exit; + } + connection default; + EXECUTE create_table2; + connection con2; + let $value= INITIALIZED; + let $value= query_get_value(EXECUTE show_table, Create Table, 1); + if (`SELECT '$value' <> '$cr_value2'`) + { + --echo # Error: Unexpected SHOW CREATE TABLE output + --echo # Got: $value + --echo # Expected: $cr_value2 + --echo # abort + exit; + } + connection default; + EXECUTE drop_table; + dec $loop_run; + } + if (`EXECUTE stmt_break`) + { + let $run= 0; + } +} +DEALLOCATE PREPARE create_table1; +DEALLOCATE PREPARE create_table2; +DEALLOCATE PREPARE drop_table; +connection con2; +DEALLOCATE PREPARE show_table; +connection default; +--enable_result_log +--enable_query_log diff --git a/mysql-test/suite/stress/include/ddl5.inc b/mysql-test/suite/stress/include/ddl5.inc new file mode 100644 index 00000000000..5a6c2fa0e96 --- /dev/null +++ b/mysql-test/suite/stress/include/ddl5.inc @@ -0,0 +1,227 @@ +######## include/ddl5.inc ###### +# +# Stress the storage engine with rapid CREATE/DROP TABLE/INDEX +# and following SELECT/INSERT/SHOW etc. +# Subtest 5 variants (5A - 5D) +# +# The variables +# $loop_size -- number of rounds till we look at the clock again +# $runtime -- rough intended runtime per subtest variant +# $engine_type -- storage engine to be used in CREATE TABLE +# must be set within the routine sourcing this script. +# +# Other stuff which must already exist: +# - connection con2 +# - stmt_start and stmt_break prepared by the default connection +# +# Please look for more details within include/ddl1.inc. +# +# Creation of this test: +# 2007-07-04 mleich +# + +#---------------------------------------------------------------------- +# Settings for Subtest 5 variants +# Scenario: CREATE TABLE with AUTOINC/INSERT/SELECT/DROP TABLE +let $create_table= CREATE TABLE t1 (f1 MEDIUMINT NOT NULL AUTO_INCREMENT,f2 BIGINT, UNIQUE(f1)) ENGINE = $engine_type; +let $insert_into= INSERT INTO t1 SET f2 = 9; +let $select_record= SELECT f1 <> 1 OR f1 IS NULL FROM t1 WHERE f2 = 9; +let $drop_table= DROP TABLE t1; +#---------------------------------------------------------------------- + +# +--echo # Subtest 5A (one connection, no PREPARE/EXECUTE) +--echo # connection action +--echo # default: $create_table +--echo # default: $insert_into +--echo # default: $select_record +--echo # default: $drop_table +--disable_query_log +connection default; +let $run= 1; +# Determine the current time. +EXECUTE stmt_start; +# Run execution loops till the planned runtime is reached +while ($run) +{ + let $loop_run= $loop_size; + while ($loop_run) + { + eval $create_table; + eval $insert_into; + if (`$select_record`) + { + --enable_result_log + --enable_query_log + --echo # Error: Unexpected content within t1. + --echo # Expected: 0 + --echo # Got: + eval $select_record; + SELECT * FROM t1; + --echo # abort + exit; + } + eval $drop_table; + dec $loop_run; + } + if (`EXECUTE stmt_break`) + { + let $run= 0; + } +} +--enable_query_log +# +--echo # Subtest 5B (one connection, use PREPARE/EXECUTE) +--echo # connection action +--echo # default: $create_table +--echo # default: $insert_into +--echo # default: $select_record +--echo # default: $drop_table +--disable_query_log +connection default; +eval PREPARE create_table FROM "$create_table"; +EXECUTE create_table; +eval PREPARE insert_into FROM "$insert_into"; +eval PREPARE select_record FROM "$select_record"; +eval PREPARE drop_table FROM "$drop_table"; +EXECUTE drop_table; +let $run= 1; +# Determine the current time. +EXECUTE stmt_start; +# Run execution loops till the planned runtime is reached +while ($run) +{ + let $loop_run= $loop_size; + while ($loop_run) + { + EXECUTE create_table; + EXECUTE insert_into; + if (`EXECUTE select_record`) + { + --enable_result_log + --enable_query_log + --echo # Error: Unexpected content within t1. + --echo # Expected: 0 + --echo # Got: + EXECUTE select_record; + SELECT * FROM t1; + --echo # abort + exit; + } + EXECUTE drop_table; + dec $loop_run; + } + if (`EXECUTE stmt_break`) + { + let $run= 0; + } +} +DEALLOCATE PREPARE create_table; +DEALLOCATE PREPARE insert_into; +DEALLOCATE PREPARE select_record; +DEALLOCATE PREPARE drop_table; +--enable_query_log +# +--echo # Subtest 5C (two connections, no PREPARE/EXECUTE) +--echo # connection action +--echo # default: $create_table +--echo # con2: $insert_into +--echo # default: $select_record +--echo # con2: $drop_table +--disable_query_log +connection default; +let $run= 1; +# Determine the current time. +EXECUTE stmt_start; +# Run execution loops till the planned runtime is reached +while ($run) +{ + let $loop_run= $loop_size; + while ($loop_run) + { + eval $create_table; + connection con2; + eval $insert_into; + connection default; + if (`$select_record`) + { + --enable_result_log + --enable_query_log + --echo # Error: Unexpected content within t1. + --echo # Expected: 0 + --echo # Got: + eval $select_record; + SELECT * FROM t1; + --echo # abort + exit; + } + connection con2; + eval $drop_table; + connection default; + dec $loop_run; + } + if (`EXECUTE stmt_break`) + { + let $run= 0; + } +} +--enable_query_log +# +--echo # Subtest 5D (two connections, use PREPARE/EXECUTE) +--echo # connection action +--echo # default: $create_table +--echo # con2: $insert_into +--echo # default: $select_record +--echo # con2: $drop_table +--disable_query_log +connection default; +eval PREPARE create_table FROM "$create_table"; +EXECUTE create_table; +eval PREPARE select_record FROM "$select_record"; +connection con2; +eval PREPARE insert_into FROM "$insert_into"; +eval PREPARE drop_table FROM "$drop_table"; +EXECUTE drop_table; +connection default; +let $run= 1; +# Determine the current time. +EXECUTE stmt_start; +# Run execution loops till the planned runtime is reached +while ($run) +{ + let $loop_run= $loop_size; + while ($loop_run) + { + EXECUTE create_table; + connection con2; + EXECUTE insert_into; + connection default; + if (`EXECUTE select_record`) + { + --enable_result_log + --enable_query_log + --echo # Error: Unexpected content within t1. + --echo # Expected: 0 + --echo # Got: + EXECUTE select_record; + SELECT * FROM t1; + --echo # abort + exit; + } + connection con2; + EXECUTE drop_table; + connection default; + dec $loop_run; + } + if (`EXECUTE stmt_break`) + { + let $run= 0; + } +} +DEALLOCATE PREPARE create_table; +DEALLOCATE PREPARE select_record; +connection con2; +DEALLOCATE PREPARE insert_into; +DEALLOCATE PREPARE drop_table; +connection default; +--enable_query_log diff --git a/mysql-test/suite/stress/include/ddl6.inc b/mysql-test/suite/stress/include/ddl6.inc new file mode 100644 index 00000000000..7bbfe300eaa --- /dev/null +++ b/mysql-test/suite/stress/include/ddl6.inc @@ -0,0 +1,266 @@ +######## include/ddl6.inc ###### +# +# Stress the storage engine with rapid CREATE/DROP TABLE/INDEX +# and following SELECT/INSERT/SHOW etc. +# Subtest 6 variants (6A - 6D) +# +# The variables +# $loop_size -- number of rounds till we look at the clock again +# $runtime -- rough intended runtime per subtest variant +# $engine_type -- storage engine to be used in CREATE TABLE +# must be set within the routine sourcing this script. +# +# Other stuff which must already exist: +# - connection con2 +# - stmt_start and stmt_break prepared by the default connection +# +# Please look for more details within include/ddl1.inc. +# +# Creation of this test: +# 2007-07-04 mleich +# + + +#---------------------------------------------------------------------- +# Settings for Subtest 6 variants +# Scenario: CREATE INDEX/CREATE INDEX(F)/DROP INDEX/DROP INDEX(F) +let $create_index= CREATE INDEX IDX1 ON t1 (f2); +let $drop_index= DROP INDEX IDX1 ON t1; +eval CREATE TABLE t1 (f1 BIGINT, f2 BIGINT, UNIQUE(f1)) ENGINE=$engine_type; +#---------------------------------------------------------------------- + + +# +--echo # Subtest 6A (one connection, no PREPARE/EXECUTE) +--echo # connection action +--echo # default: $create_index +--echo # default: $create_index (expect to get ER_DUP_KEYNAME) +--echo # default: $drop_index +--echo # default: $drop_index (expect to get ER_CANT_DROP_FIELD_OR_KEY) +--echo # default: $create_index +--echo # default: $drop_index +--disable_query_log +--disable_result_log +connection default; +let $run= 1; +# Determine the current time. +EXECUTE stmt_start; +# Run execution loops till the planned runtime is reached +while ($run) +{ + let $loop_run= $loop_size; + while ($loop_run) + { + eval $create_index; + --error 0,ER_DUP_KEYNAME + eval $create_index; + if (!$mysql_errno) + { + --echo # Error: CREATE INDEX was successful though we expected ER_DUP_KEYNAME + --echo # abort + exit; + } + eval $drop_index; + --error 0,ER_CANT_DROP_FIELD_OR_KEY + eval $drop_index; + if (!$mysql_errno) + { + --echo # Error: DROP INDEX was successful though we expected ER_CANT_DROP_FIELD_OR_KEY + --echo # abort + exit; + } + eval $create_index; + eval $drop_index; + dec $loop_run; + } + if (`EXECUTE stmt_break`) + { + let $run= 0; + } +} +--enable_result_log +--enable_query_log +# +--echo # Subtest 6B (one connection, use PREPARE/EXECUTE) +--echo # connection action +--echo # default: $create_index +--echo # default: $create_index (expect to get ER_DUP_KEYNAME) +--echo # default: $drop_index +--echo # default: $drop_index (expect to get ER_CANT_DROP_FIELD_OR_KEY) +--echo # default: $create_index +--echo # default: $drop_index +--disable_query_log +--disable_result_log +connection default; +eval PREPARE create_index FROM "$create_index"; +EXECUTE create_index; +eval PREPARE drop_index FROM "$drop_index"; +EXECUTE drop_index; +let $run= 1; +# Determine the current time. +EXECUTE stmt_start; +# Run execution loops till the planned runtime is reached +while ($run) +{ + let $loop_run= $loop_size; + while ($loop_run) + { + EXECUTE create_index; + --error 0,ER_DUP_KEYNAME + EXECUTE create_index; + if (!$mysql_errno) + { + --echo # Error: CREATE INDEX was successful though we expected ER_DUP_KEYNAME + --echo # abort + exit; + } + EXECUTE drop_index; + --error 0,ER_CANT_DROP_FIELD_OR_KEY + EXECUTE drop_index; + if (!$mysql_errno) + { + --echo # Error: DROP INDEX was successful though we expected ER_CANT_DROP_FIELD_OR_KEY + --echo # abort + exit; + } + EXECUTE create_index; + EXECUTE drop_index; + dec $loop_run; + } + if (`EXECUTE stmt_break`) + { + let $run= 0; + } +} +DEALLOCATE PREPARE create_index; +DEALLOCATE PREPARE drop_index; +--enable_result_log +--enable_query_log +# +--echo # Subtest 6C (two connections, no PREPARE/EXECUTE) +--echo # connection action +--echo # default: $create_index +--echo # con2: $create_index (expect to get ER_DUP_KEYNAME) +--echo # default: $drop_index +--echo # con2: $drop_index (expect to get ER_CANT_DROP_FIELD_OR_KEY) +--echo # default: $create_index +--echo # con2: $drop_index +--disable_query_log +--disable_result_log +connection default; +let $run= 1; +# Determine the current time. +EXECUTE stmt_start; +# Run execution loops till the planned runtime is reached +while ($run) +{ + let $loop_run= $loop_size; + while ($loop_run) + { + eval $create_index; + connection con2; + --error 0,ER_DUP_KEYNAME + eval $create_index; + if (!$mysql_errno) + { + --echo # Error: CREATE INDEX was successful though we expected ER_DUP_KEYNAME + --echo # abort + exit; + } + connection default; + eval $drop_index; + connection con2; + --error 0,ER_CANT_DROP_FIELD_OR_KEY + eval $drop_index; + if (!$mysql_errno) + { + --echo # Error: DROP INDEX was successful though we expected ER_CANT_DROP_FIELD_OR_KEY + --echo # abort + exit; + } + connection default; + eval $create_index; + connection con2; + eval $drop_index; + connection default; + dec $loop_run; + } + if (`EXECUTE stmt_break`) + { + let $run= 0; + } +} +--enable_result_log +--enable_query_log +# +--echo # Subtest 6D (two connections, use PREPARE/EXECUTE) +--echo # connection action +--echo # default: $create_index +--echo # con2: $create_index (expect to get ER_DUP_KEYNAME) +--echo # default: $drop_index +--echo # con2: $drop_index (expect to get ER_CANT_DROP_FIELD_OR_KEY) +--echo # default: $create_index +--echo # con2: $drop_index +--disable_query_log +--disable_result_log +connection default; +eval PREPARE create_index FROM "$create_index"; +eval PREPARE drop_index FROM "$drop_index"; +EXECUTE create_index; +connection con2; +eval PREPARE create_index FROM "$create_index"; +eval PREPARE drop_index FROM "$drop_index"; +EXECUTE drop_index; +connection default; +let $run= 1; +# Determine the current time. +EXECUTE stmt_start; +# Run execution loops till the planned runtime is reached +while ($run) +{ + let $loop_run= $loop_size; + while ($loop_run) + { + EXECUTE create_index; + connection con2; + --error 0,ER_DUP_KEYNAME + EXECUTE create_index; + if (!$mysql_errno) + { + --echo # Error: CREATE INDEX was successful though we expected ER_DUP_KEYNAME + --echo # abort + exit; + } + connection default; + EXECUTE drop_index; + connection con2; + --error 0,ER_CANT_DROP_FIELD_OR_KEY + EXECUTE drop_index; + if (!$mysql_errno) + { + --echo # Error: DROP INDEX was successful though we expected ER_CANT_DROP_FIELD_OR_KEY + --echo # abort + exit; + } + connection default; + EXECUTE create_index; + connection con2; + EXECUTE drop_index; + connection default; + dec $loop_run; + } + if (`EXECUTE stmt_break`) + { + let $run= 0; + } +} +DEALLOCATE PREPARE create_index; +DEALLOCATE PREPARE drop_index; +connection con2; +DEALLOCATE PREPARE create_index; +DEALLOCATE PREPARE drop_index; +connection default; +--enable_result_log +--enable_query_log + +DROP TABLE t1; diff --git a/mysql-test/suite/stress/include/ddl7.inc b/mysql-test/suite/stress/include/ddl7.inc new file mode 100644 index 00000000000..76ba8066c66 --- /dev/null +++ b/mysql-test/suite/stress/include/ddl7.inc @@ -0,0 +1,274 @@ +######## include/ddl7.inc ###### +# +# Stress the storage engine with rapid CREATE/DROP TABLE/INDEX +# and following SELECT/INSERT/SHOW etc. +# Subtest 7 variants (7A - 7D) +# +# The variables +# $loop_size -- number of rounds till we look at the clock again +# $runtime -- rough intended runtime per subtest variant +# $engine_type -- storage engine to be used in CREATE TABLE +# must be set within the routine sourcing this script. +# +# Other stuff which must already exist: +# - connection con2 +# - stmt_start and stmt_break prepared by the default connection +# +# Please look for more details within include/ddl1.inc. +# +# Creation of this test: +# 2007-07-04 mleich +# + + +#---------------------------------------------------------------------- +# Settings for Subtest 7 variants +# Scenario: CREATE INDEX/INSERT(F)/DROP INDEX/INSERT/CREATE INDEX(F)/DELETE +let $create_index= CREATE UNIQUE INDEX IDX1 ON t1 (f2); +let $insert_record= INSERT INTO t1 VALUES(1,1); +let $drop_index= DROP INDEX IDX1 ON t1; +let $delete_record= DELETE FROM t1 WHERE f1 = 1; +eval CREATE TABLE t1 (f1 BIGINT, f2 BIGINT, PRIMARY KEY(f1)) ENGINE=$engine_type; +INSERT INTO t1 VALUES(0,1); +#---------------------------------------------------------------------- + +# +--echo # Subtest 7A (one connection, no PREPARE/EXECUTE) +--echo # connection action +--echo # default: $create_index +--echo # default: $insert_record (expect to get ER_DUP_ENTRY) +--echo # default: $drop_index +--echo # default: $insert_record +--echo # default: $create_index (expect to get ER_DUP_ENTRY) +--echo # default: $delete_record +--disable_query_log +--disable_result_log +connection default; +let $run= 1; +let $counter= 1; +# Determine the current time. +EXECUTE stmt_start; +# Run execution loops till the planned runtime is reached +while ($run) +{ + let $loop_run= $loop_size; + while ($loop_run) + { + eval $create_index; + --error 0,ER_DUP_ENTRY + eval $insert_record; + if (!$mysql_errno) + { + --echo # Error: INSERT was successful though we expected ER_DUP_ENTRY + --echo # abort + exit; + } + eval $drop_index; + eval $insert_record; + # NDB: ER_DUP_UNIQUE, others: ER_DUP_ENTRY + --error 0,ER_DUP_ENTRY,ER_DUP_UNIQUE + eval $create_index; + if (!$mysql_errno) + { + --echo # Error: CREATE INDEX was successful though we expected ER_DUP_ENTRY + --echo # Error: or ER_DUP_UNIQUE (NDB only) + --echo # abort + exit; + } + eval $delete_record; + dec $loop_run; + } + if (`EXECUTE stmt_break`) + { + let $run= 0; + } +} +--enable_result_log +--enable_query_log +# +--echo # Subtest 7B (one connection, use PREPARE/EXECUTE) +--echo # connection action +--echo # default: $create_index +--echo # default: $insert_record (expect to get ER_DUP_ENTRY) +--echo # default: $drop_index +--echo # default: $insert_record +--echo # default: $create_index (expect to get ER_DUP_ENTRY) +--echo # default: $delete_record +--disable_query_log +--disable_result_log +connection default; +eval PREPARE create_index FROM "$create_index"; +eval PREPARE insert_record FROM "$insert_record"; +eval PREPARE delete_record FROM "$delete_record"; +eval PREPARE drop_index FROM "$drop_index"; +let $run= 1; +let $counter= 1; +# Determine the current time. +EXECUTE stmt_start; +# Run execution loops till the planned runtime is reached +while ($run) +{ + let $loop_run= $loop_size; + while ($loop_run) + { + EXECUTE create_index; + --error 0,ER_DUP_ENTRY + EXECUTE insert_record; + if (!$mysql_errno) + { + --echo # Error: INSERT was successful though we expected ER_DUP_ENTRY + --echo # abort + exit; + } + EXECUTE drop_index; + EXECUTE insert_record; + --error 0,ER_DUP_ENTRY + EXECUTE create_index; + if (!$mysql_errno) + { + --echo # Error: CREATE INDEX was successful though we expected ER_DUP_ENTRY + --echo # abort + exit; + } + EXECUTE delete_record; + dec $loop_run; + } + if (`EXECUTE stmt_break`) + { + let $run= 0; + } +} +DEALLOCATE PREPARE create_index; +DEALLOCATE PREPARE insert_record; +DEALLOCATE PREPARE delete_record; +DEALLOCATE PREPARE drop_index; +--enable_result_log +--enable_query_log +# +--echo # Subtest 7C (two connections, no PREPARE/EXECUTE) +--echo # connection action +--echo # default: $create_index +--echo # default: $insert_record (expect to get ER_DUP_ENTRY) +--echo # con2: $drop_index +--echo # default: $insert_record +--echo # con2: $create_index (expect to get ER_DUP_ENTRY) +--echo # con2: $delete_record +--disable_query_log +--disable_result_log +connection default; +let $run= 1; +let $counter= 1; +# Determine the current time. +EXECUTE stmt_start; +# Run execution loops till the planned runtime is reached +while ($run) +{ + let $loop_run= $loop_size; + while ($loop_run) + { + eval $create_index; + --error 0,ER_DUP_ENTRY + eval $insert_record; + if (!$mysql_errno) + { + --echo # Error: INSERT was successful though we expected ER_DUP_ENTRY + --echo # abort + exit; + } + connection con2; + eval $drop_index; + connection default; + eval $insert_record; + connection con2; + --error 0,ER_DUP_ENTRY + eval $create_index; + if (!$mysql_errno) + { + --echo # Error: CREATE INDEX was successful though we expected ER_DUP_ENTRY + --echo # abort + exit; + } + eval $delete_record; + connection default; + dec $loop_run; + } + if (`EXECUTE stmt_break`) + { + let $run= 0; + } +} +--enable_result_log +--enable_query_log +# +--echo # Subtest 7D (two connections, use PREPARE/EXECUTE) +--echo # connection action +--echo # default: $create_index +--echo # default: $insert_record (expect to get ER_DUP_ENTRY) +--echo # con2: $drop_index +--echo # default: $insert_record +--echo # con2: $create_index (expect to get ER_DUP_ENTRY) +--echo # con2: $delete_record +--disable_query_log +--disable_result_log +connection default; +eval PREPARE create_index FROM "$create_index"; +eval PREPARE insert_record FROM "$insert_record"; +EXECUTE create_index; +connection con2; +eval PREPARE create_index FROM "$create_index"; +eval PREPARE drop_index FROM "$drop_index"; +eval PREPARE delete_record FROM "$delete_record"; +EXECUTE drop_index; +connection default; +let $run= 1; +let $counter= 1; +# Determine the current time. +EXECUTE stmt_start; +# Run execution loops till the planned runtime is reached +while ($run) +{ + let $loop_run= $loop_size; + while ($loop_run) + { + EXECUTE create_index; + --error 0,ER_DUP_ENTRY + EXECUTE insert_record; + if (!$mysql_errno) + { + --echo # Error: INSERT was successful though we expected ER_DUP_ENTRY + --echo # abort + exit; + } + connection con2; + EXECUTE drop_index; + connection default; + EXECUTE insert_record; + connection con2; + --error 0,ER_DUP_ENTRY + EXECUTE create_index; + if (!$mysql_errno) + { + --echo # Error: CREATE INDEX was successful though we expected ER_DUP_ENTRY + --echo # abort + exit; + } + EXECUTE delete_record; + connection default; + dec $loop_run; + } + if (`EXECUTE stmt_break`) + { + let $run= 0; + } +} +DEALLOCATE PREPARE create_index; +DEALLOCATE PREPARE insert_record; +connection con2; +DEALLOCATE PREPARE create_index; +DEALLOCATE PREPARE drop_index; +DEALLOCATE PREPARE delete_record; +connection default; +--enable_result_log +--enable_query_log + +DROP TABLE t1; diff --git a/mysql-test/suite/stress/include/ddl8.inc b/mysql-test/suite/stress/include/ddl8.inc new file mode 100644 index 00000000000..85a70770a56 --- /dev/null +++ b/mysql-test/suite/stress/include/ddl8.inc @@ -0,0 +1,302 @@ +######## include/ddl8.inc ###### +# +# Stress the storage engine with rapid CREATE/DROP TABLE/INDEX +# and following SELECT/INSERT/SHOW etc. +# Subtest 8 variants (8A - 8D) +# +# The variables +# $loop_size -- number of rounds till we look at the clock again +# $runtime -- rough intended runtime per subtest variant +# $engine_type -- storage engine to be used in CREATE TABLE +# must be set within the routine sourcing this script. +# +# Other stuff which must already exist: +# - connection con2 +# - stmt_start and stmt_break prepared by the default connection +# +# Please look for more details within include/ddl1.inc. +# +# Creation of this test: +# 2007-07-04 mleich +# + + +#---------------------------------------------------------------------- +# Settings for Subtest 8 variants +# Scenario: CREATE INDEX variant1/SHOW/DROP INDEX/ +# CREATE INDEX variant2/SHOW/DROP INDEX +let $create_index1= CREATE INDEX IDX ON t1 (f2); +let $create_index2= CREATE UNIQUE INDEX IDX ON t1 (f2); +let $show_table= SHOW CREATE TABLE t1; +let $drop_index= DROP INDEX IDX ON t1; +eval CREATE TABLE t1 (f1 BIGINT, f2 BIGINT, UNIQUE(f1)) ENGINE=$engine_type; +INSERT INTO t1 VALUES(1,1); +eval $create_index1; +let $cr_value1= INITIALIZED; +let $cr_value1= query_get_value($show_table, Create Table, 1); +eval $drop_index; +eval $create_index2; +let $cr_value2= INITIALIZED; +let $cr_value2= query_get_value($show_table, Create Table, 1); +eval $drop_index; +if (`SELECT '$cr_value1' = '$cr_value2'`) +{ + --echo # Error during generation of prerequisites. + --echo # cr_value1 equals cr_value2 + --echo # cr_value1: $cr_value1 + --echo # cr_value2: $cr_value2 + --echo # abort + exit; +} +#---------------------------------------------------------------------- + +# +--echo # Subtest 8A (one connection, no PREPARE/EXECUTE) +--echo # connection action +--echo # default: $create_index1 +--echo # default: $show_table +--echo # default: $drop_index +--echo # default: $create_index2 +--echo # default: $show_table +--echo # default: $drop_index +--disable_query_log +--disable_result_log +connection default; +let $run= 1; +# Determine the current time. +EXECUTE stmt_start; +# Run execution loops till the planned runtime is reached +while ($run) +{ + let $loop_run= $loop_size; + while ($loop_run) + { + eval $create_index1; + let $value= INITIALIZED; + let $value= query_get_value($show_table, Create Table, 1); + if (`SELECT '$value' <> '$cr_value1'`) + { + --echo # Error: Unexpected SHOW CREATE TABLE output + --echo # Got: $value + --echo # Expected: $cr_value1 + --echo # abort + exit; + } + eval $drop_index; + eval $create_index2; + let $value= INITIALIZED; + let $value= query_get_value($show_table, Create Table, 1); + if (`SELECT '$value' <> '$cr_value2'`) + { + --echo # Error: Unexpected SHOW CREATE TABLE output + --echo # Got: $value + --echo # Expected: $cr_value2 + --echo # abort + exit; + } + eval $drop_index; + dec $loop_run; + } + if (`EXECUTE stmt_break`) + { + let $run= 0; + } +} +--enable_result_log +--enable_query_log +# +--echo # Subtest 8B (one connection, use PREPARE/EXECUTE) +--echo # connection action +--echo # default: $create_index1 +--echo # default: $show_table +--echo # default: $drop_index +--echo # default: $create_index2 +--echo # default: $show_table +--echo # default: $drop_index +--disable_query_log +--disable_result_log +connection default; +eval PREPARE create_index1 FROM "$create_index1"; +eval PREPARE create_index2 FROM "$create_index2"; +EXECUTE create_index1; +eval PREPARE show_table FROM "$show_table"; +eval PREPARE drop_index FROM "$drop_index"; +EXECUTE drop_index; +let $run= 1; +# Determine the current time. +EXECUTE stmt_start; +# Run execution loops till the planned runtime is reached +while ($run) +{ + let $loop_run= $loop_size; + while ($loop_run) + { + EXECUTE create_index1; + let $value= INITIALIZED; + let $value= query_get_value(EXECUTE show_table, Create Table, 1); + if (`SELECT '$value' <> '$cr_value1'`) + { + --echo # Error: Unexpected SHOW CREATE TABLE output + --echo # Got: $value + --echo # Expected: $cr_value1 + --echo # abort + exit; + } + EXECUTE drop_index; + EXECUTE create_index2; + let $value= INITIALIZED; + let $value= query_get_value(EXECUTE show_table, Create Table, 1); + if (`SELECT '$value' <> '$cr_value2'`) + { + --echo # Error: Unexpected SHOW CREATE TABLE output + --echo # Got: $value + --echo # Expected: $cr_value2 + --echo # abort + exit; + } + EXECUTE drop_index; + dec $loop_run; + } + if (`EXECUTE stmt_break`) + { + let $run= 0; + } +} +DEALLOCATE PREPARE create_index1; +DEALLOCATE PREPARE create_index2; +DEALLOCATE PREPARE show_table; +DEALLOCATE PREPARE drop_index; +--enable_result_log +--enable_query_log +# +--echo # Subtest 8C (two connections, no PREPARE/EXECUTE) +--echo # connection action +--echo # default: $create_index1 +--echo # con2: $show_table +--echo # default: $drop_index +--echo # default: $create_index2 +--echo # con2: $show_table +--echo # default: $drop_index +--disable_query_log +--disable_result_log +connection default; +let $run= 1; +# Determine the current time. +EXECUTE stmt_start; +# Run execution loops till the planned runtime is reached +while ($run) +{ + let $loop_run= $loop_size; + while ($loop_run) + { + eval $create_index1; + connection con2; + let $value= INITIALIZED; + let $value= query_get_value($show_table, Create Table, 1); + if (`SELECT '$value' <> '$cr_value1'`) + { + --echo # Error: Unexpected SHOW CREATE TABLE output + --echo # Got: $value + --echo # Expected: $cr_value1 + --echo # abort + exit; + } + connection default; + eval $drop_index; + eval $create_index2; + connection con2; + let $value= INITIALIZED; + let $value= query_get_value($show_table, Create Table, 1); + if (`SELECT '$value' <> '$cr_value2'`) + { + --echo # Error: Unexpected SHOW CREATE TABLE output + --echo # Got: $value + --echo # Expected: $cr_value2 + --echo # abort + exit; + } + connection default; + eval $drop_index; + dec $loop_run; + } + if (`EXECUTE stmt_break`) + { + let $run= 0; + } +} +--enable_result_log +--enable_query_log +# +--echo # Subtest 8D (two connections, use PREPARE/EXECUTE) +--echo # connection action +--echo # default: $create_index1 +--echo # con2: $show_table +--echo # default: $drop_index +--echo # default: $create_index2 +--echo # con2: $show_table +--echo # default: $drop_index +--disable_query_log +--disable_result_log +connection default; +eval PREPARE create_index1 FROM "$create_index1"; +eval PREPARE create_index2 FROM "$create_index2"; +eval PREPARE drop_index FROM "$drop_index"; +EXECUTE create_index1; +connection con2; +eval PREPARE show_table FROM "$show_table"; +connection default; +EXECUTE drop_index; +let $run= 1; +# Determine the current time. +EXECUTE stmt_start; +# Run execution loops till the planned runtime is reached +while ($run) +{ + let $loop_run= $loop_size; + while ($loop_run) + { + EXECUTE create_index1; + connection con2; + let $value= INITIALIZED; + let $value= query_get_value(EXECUTE show_table, Create Table, 1); + if (`SELECT '$value' <> '$cr_value1'`) + { + --echo # Error: Unexpected SHOW CREATE TABLE output + --echo # Got: $value + --echo # Expected: $cr_value1 + --echo # abort + exit; + } + connection default; + EXECUTE drop_index; + EXECUTE create_index2; + connection con2; + let $value= INITIALIZED; + let $value= query_get_value(EXECUTE show_table, Create Table, 1); + if (`SELECT '$value' <> '$cr_value2'`) + { + --echo # Error: Unexpected SHOW CREATE TABLE output + --echo # Got: $value + --echo # Expected: $cr_value2 + --echo # abort + exit; + } + connection default; + EXECUTE drop_index; + dec $loop_run; + } + if (`EXECUTE stmt_break`) + { + let $run= 0; + } +} +DEALLOCATE PREPARE create_index1; +DEALLOCATE PREPARE create_index2; +DEALLOCATE PREPARE drop_index; +connection con2; +DEALLOCATE PREPARE show_table; +connection default; +--enable_result_log +--enable_query_log + +DROP TABLE t1; diff --git a/mysql-test/suite/stress/r/ddl_archive.result b/mysql-test/suite/stress/r/ddl_archive.result new file mode 100644 index 00000000000..47c64a6af94 --- /dev/null +++ b/mysql-test/suite/stress/r/ddl_archive.result @@ -0,0 +1,79 @@ +SET @@session.sql_mode = 'NO_ENGINE_SUBSTITUTION'; +PREPARE stmt_start FROM "SELECT UNIX_TIMESTAMP() INTO @start"; +SET @runtime = <intended_runtime>; +PREPARE stmt_break FROM "SELECT UNIX_TIMESTAMP() - @start > @runtime - 1"; +DROP TABLE IF EXISTS t1; +# Subtest 2A (one connection, no PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 ENGINE = ARCHIVE AS SELECT 1 AS f1 +# default: SELECT COUNT(*) <> 1 FROM t1 WHERE f1 = 1 +# default: DROP TABLE t1 +# default: SELECT COUNT(*) <> 1 FROM t1 WHERE f1 = 1 (expect to get ER_NO_SUCH_TABLE) +# Subtest 2B (one connection, use PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 ENGINE = ARCHIVE AS SELECT 1 AS f1 +# default: SELECT COUNT(*) <> 1 FROM t1 WHERE f1 = 1 +# default: DROP TABLE t1 +# default: SELECT COUNT(*) <> 1 FROM t1 WHERE f1 = 1 (expect to get ER_NO_SUCH_TABLE) +# Subtest 2C (two connections, no PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 ENGINE = ARCHIVE AS SELECT 1 AS f1 +# con2: SELECT COUNT(*) <> 1 FROM t1 WHERE f1 = 1 +# default: DROP TABLE t1 +# con2: SELECT COUNT(*) <> 1 FROM t1 WHERE f1 = 1 (expect to get ER_NO_SUCH_TABLE) +# Subtest 2D (two connections, use PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 ENGINE = ARCHIVE AS SELECT 1 AS f1 +# con2: SELECT COUNT(*) <> 1 FROM t1 WHERE f1 = 1 +# default: DROP TABLE t1 +# con2: SELECT COUNT(*) <> 1 FROM t1 WHERE f1 = 1 (expect to get ER_NO_SUCH_TABLE) +# Subtest 3A (one connection, no PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 BIGINT) ENGINE=ARCHIVE +# default: CREATE TABLE t1 (f1 BIGINT) ENGINE=ARCHIVE (expect to get ER_TABLE_EXISTS_ERROR) +# default: DROP TABLE t1 +# default: DROP TABLE t1 (expect to get ER_BAD_TABLE_ERROR) +# Subtest 3B (one connection, use PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 BIGINT) ENGINE=ARCHIVE +# default: CREATE TABLE t1 (f1 BIGINT) ENGINE=ARCHIVE (expect to get ER_TABLE_EXISTS_ERROR) +# default: DROP TABLE t1 +# default: DROP TABLE t1 (expect to get ER_BAD_TABLE_ERROR) +# Subtest 3C (two connections, no PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 BIGINT) ENGINE=ARCHIVE +# con2: CREATE TABLE t1 (f1 BIGINT) ENGINE=ARCHIVE (expect to get ER_TABLE_EXISTS_ERROR) +# default: DROP TABLE t1 +# con2: DROP TABLE t1 (expect to get ER_BAD_TABLE_ERROR) +# Subtest 3D (two connections, use PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 BIGINT) ENGINE=ARCHIVE +# con2: CREATE TABLE t1 (f1 BIGINT) ENGINE=ARCHIVE (expect to get ER_TABLE_EXISTS_ERROR) +# default: DROP TABLE t1 +# con2: DROP TABLE t1 (expect to get ER_BAD_TABLE_ERROR) +# Subtest 5A (one connection, no PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 MEDIUMINT NOT NULL AUTO_INCREMENT,f2 BIGINT, UNIQUE(f1)) ENGINE = ARCHIVE +# default: INSERT INTO t1 SET f2 = 9 +# default: SELECT f1 <> 1 OR f1 IS NULL FROM t1 WHERE f2 = 9 +# default: DROP TABLE t1 +# Subtest 5B (one connection, use PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 MEDIUMINT NOT NULL AUTO_INCREMENT,f2 BIGINT, UNIQUE(f1)) ENGINE = ARCHIVE +# default: INSERT INTO t1 SET f2 = 9 +# default: SELECT f1 <> 1 OR f1 IS NULL FROM t1 WHERE f2 = 9 +# default: DROP TABLE t1 +# Subtest 5C (two connections, no PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 MEDIUMINT NOT NULL AUTO_INCREMENT,f2 BIGINT, UNIQUE(f1)) ENGINE = ARCHIVE +# con2: INSERT INTO t1 SET f2 = 9 +# default: SELECT f1 <> 1 OR f1 IS NULL FROM t1 WHERE f2 = 9 +# con2: DROP TABLE t1 +# Subtest 5D (two connections, use PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 MEDIUMINT NOT NULL AUTO_INCREMENT,f2 BIGINT, UNIQUE(f1)) ENGINE = ARCHIVE +# con2: INSERT INTO t1 SET f2 = 9 +# default: SELECT f1 <> 1 OR f1 IS NULL FROM t1 WHERE f2 = 9 +# con2: DROP TABLE t1 +DEALLOCATE PREPARE stmt_start; +DEALLOCATE PREPARE stmt_break; diff --git a/mysql-test/suite/stress/r/ddl_csv.result b/mysql-test/suite/stress/r/ddl_csv.result new file mode 100644 index 00000000000..3dfa0c8fd15 --- /dev/null +++ b/mysql-test/suite/stress/r/ddl_csv.result @@ -0,0 +1,55 @@ +SET @@session.sql_mode = 'NO_ENGINE_SUBSTITUTION'; +PREPARE stmt_start FROM "SELECT UNIX_TIMESTAMP() INTO @start"; +SET @runtime = <intended_runtime>; +PREPARE stmt_break FROM "SELECT UNIX_TIMESTAMP() - @start > @runtime - 1"; +DROP TABLE IF EXISTS t1; +# Subtest 2A (one connection, no PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 ENGINE = CSV AS SELECT 1 AS f1 +# default: SELECT COUNT(*) <> 1 FROM t1 WHERE f1 = 1 +# default: DROP TABLE t1 +# default: SELECT COUNT(*) <> 1 FROM t1 WHERE f1 = 1 (expect to get ER_NO_SUCH_TABLE) +# Subtest 2B (one connection, use PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 ENGINE = CSV AS SELECT 1 AS f1 +# default: SELECT COUNT(*) <> 1 FROM t1 WHERE f1 = 1 +# default: DROP TABLE t1 +# default: SELECT COUNT(*) <> 1 FROM t1 WHERE f1 = 1 (expect to get ER_NO_SUCH_TABLE) +# Subtest 2C (two connections, no PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 ENGINE = CSV AS SELECT 1 AS f1 +# con2: SELECT COUNT(*) <> 1 FROM t1 WHERE f1 = 1 +# default: DROP TABLE t1 +# con2: SELECT COUNT(*) <> 1 FROM t1 WHERE f1 = 1 (expect to get ER_NO_SUCH_TABLE) +# Subtest 2D (two connections, use PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 ENGINE = CSV AS SELECT 1 AS f1 +# con2: SELECT COUNT(*) <> 1 FROM t1 WHERE f1 = 1 +# default: DROP TABLE t1 +# con2: SELECT COUNT(*) <> 1 FROM t1 WHERE f1 = 1 (expect to get ER_NO_SUCH_TABLE) +# Subtest 3A (one connection, no PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 BIGINT) ENGINE=CSV +# default: CREATE TABLE t1 (f1 BIGINT) ENGINE=CSV (expect to get ER_TABLE_EXISTS_ERROR) +# default: DROP TABLE t1 +# default: DROP TABLE t1 (expect to get ER_BAD_TABLE_ERROR) +# Subtest 3B (one connection, use PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 BIGINT) ENGINE=CSV +# default: CREATE TABLE t1 (f1 BIGINT) ENGINE=CSV (expect to get ER_TABLE_EXISTS_ERROR) +# default: DROP TABLE t1 +# default: DROP TABLE t1 (expect to get ER_BAD_TABLE_ERROR) +# Subtest 3C (two connections, no PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 BIGINT) ENGINE=CSV +# con2: CREATE TABLE t1 (f1 BIGINT) ENGINE=CSV (expect to get ER_TABLE_EXISTS_ERROR) +# default: DROP TABLE t1 +# con2: DROP TABLE t1 (expect to get ER_BAD_TABLE_ERROR) +# Subtest 3D (two connections, use PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 BIGINT) ENGINE=CSV +# con2: CREATE TABLE t1 (f1 BIGINT) ENGINE=CSV (expect to get ER_TABLE_EXISTS_ERROR) +# default: DROP TABLE t1 +# con2: DROP TABLE t1 (expect to get ER_BAD_TABLE_ERROR) +DEALLOCATE PREPARE stmt_start; +DEALLOCATE PREPARE stmt_break; diff --git a/mysql-test/suite/stress/r/ddl_innodb.result b/mysql-test/suite/stress/r/ddl_innodb.result new file mode 100644 index 00000000000..6417d3e1c5c --- /dev/null +++ b/mysql-test/suite/stress/r/ddl_innodb.result @@ -0,0 +1,251 @@ +SET @@session.sql_mode = 'NO_ENGINE_SUBSTITUTION'; +PREPARE stmt_start FROM "SELECT UNIX_TIMESTAMP() INTO @start"; +SET @runtime = <intended_runtime>; +PREPARE stmt_break FROM "SELECT UNIX_TIMESTAMP() - @start > @runtime - 1"; +DROP TABLE IF EXISTS t1; +# Subtest 1A (one connection, no PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 BIGINT,f2 BIGINT,UNIQUE(f1),UNIQUE(f2)) +ENGINE = InnoDB +# default: INSERT INTO t1 VALUES (1,1), (2,2), (3,3) +# default: DROP TABLE t1 +# Subtest 1B (one connection, use PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 BIGINT,f2 BIGINT,UNIQUE(f1),UNIQUE(f2)) +ENGINE = InnoDB +# default: INSERT INTO t1 VALUES (1,1), (2,2), (3,3) +# default: DROP TABLE t1 +# Subtest 1C (two connections, no PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 BIGINT,f2 BIGINT,UNIQUE(f1),UNIQUE(f2)) +ENGINE = InnoDB +# con2: INSERT INTO t1 VALUES (1,1), (2,2), (3,3) +# con2: DROP TABLE t1 +# Subtest 1D (two connections, use PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 BIGINT,f2 BIGINT,UNIQUE(f1),UNIQUE(f2)) +ENGINE = InnoDB +# con2: INSERT INTO t1 VALUES (1,1), (2,2), (3,3) +# con2: DROP TABLE t1 +# Subtest 2A (one connection, no PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 ENGINE = InnoDB AS SELECT 1 AS f1 +# default: SELECT COUNT(*) <> 1 FROM t1 WHERE f1 = 1 +# default: DROP TABLE t1 +# default: SELECT COUNT(*) <> 1 FROM t1 WHERE f1 = 1 (expect to get ER_NO_SUCH_TABLE) +# Subtest 2B (one connection, use PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 ENGINE = InnoDB AS SELECT 1 AS f1 +# default: SELECT COUNT(*) <> 1 FROM t1 WHERE f1 = 1 +# default: DROP TABLE t1 +# default: SELECT COUNT(*) <> 1 FROM t1 WHERE f1 = 1 (expect to get ER_NO_SUCH_TABLE) +# Subtest 2C (two connections, no PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 ENGINE = InnoDB AS SELECT 1 AS f1 +# con2: SELECT COUNT(*) <> 1 FROM t1 WHERE f1 = 1 +# default: DROP TABLE t1 +# con2: SELECT COUNT(*) <> 1 FROM t1 WHERE f1 = 1 (expect to get ER_NO_SUCH_TABLE) +# Subtest 2D (two connections, use PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 ENGINE = InnoDB AS SELECT 1 AS f1 +# con2: SELECT COUNT(*) <> 1 FROM t1 WHERE f1 = 1 +# default: DROP TABLE t1 +# con2: SELECT COUNT(*) <> 1 FROM t1 WHERE f1 = 1 (expect to get ER_NO_SUCH_TABLE) +# Subtest 3A (one connection, no PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 BIGINT) ENGINE=InnoDB +# default: CREATE TABLE t1 (f1 BIGINT) ENGINE=InnoDB (expect to get ER_TABLE_EXISTS_ERROR) +# default: DROP TABLE t1 +# default: DROP TABLE t1 (expect to get ER_BAD_TABLE_ERROR) +# Subtest 3B (one connection, use PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 BIGINT) ENGINE=InnoDB +# default: CREATE TABLE t1 (f1 BIGINT) ENGINE=InnoDB (expect to get ER_TABLE_EXISTS_ERROR) +# default: DROP TABLE t1 +# default: DROP TABLE t1 (expect to get ER_BAD_TABLE_ERROR) +# Subtest 3C (two connections, no PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 BIGINT) ENGINE=InnoDB +# con2: CREATE TABLE t1 (f1 BIGINT) ENGINE=InnoDB (expect to get ER_TABLE_EXISTS_ERROR) +# default: DROP TABLE t1 +# con2: DROP TABLE t1 (expect to get ER_BAD_TABLE_ERROR) +# Subtest 3D (two connections, use PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 BIGINT) ENGINE=InnoDB +# con2: CREATE TABLE t1 (f1 BIGINT) ENGINE=InnoDB (expect to get ER_TABLE_EXISTS_ERROR) +# default: DROP TABLE t1 +# con2: DROP TABLE t1 (expect to get ER_BAD_TABLE_ERROR) +CREATE TABLE t1 (f1 BIGINT, f2 BIGINT, UNIQUE(f1), UNIQUE (f2)) ENGINE=InnoDB; +DROP TABLE t1; +CREATE TABLE t1 (f1 BIGINT) ENGINE=InnoDB; +DROP TABLE t1; +# Subtest 4A (one connection, no PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 BIGINT, f2 BIGINT, UNIQUE(f1), UNIQUE (f2)) ENGINE=InnoDB +# default: SHOW CREATE TABLE t1 +# default: DROP TABLE t1 +# default: SHOW CREATE TABLE t1 (expect to get ER_NO_SUCH_TABLE) +# default: CREATE TABLE t1 (f1 BIGINT) ENGINE=InnoDB +# default: SHOW CREATE TABLE t1 +# default: DROP TABLE t1 +# Subtest 4B (one connection, use PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 BIGINT, f2 BIGINT, UNIQUE(f1), UNIQUE (f2)) ENGINE=InnoDB +# default: SHOW CREATE TABLE t1 +# default: DROP TABLE t1 +# default: SHOW CREATE TABLE t1 (expect to get ER_NO_SUCH_TABLE) +# default: CREATE TABLE t1 (f1 BIGINT) ENGINE=InnoDB +# default: SHOW CREATE TABLE t1 +# default: DROP TABLE t1 +# Subtest 4C (two connections, no PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 BIGINT, f2 BIGINT, UNIQUE(f1), UNIQUE (f2)) ENGINE=InnoDB +# con2: SHOW CREATE TABLE t1 +# default: DROP TABLE t1 +# con2: SHOW CREATE TABLE t1 (expect to get ER_NO_SUCH_TABLE) +# default: CREATE TABLE t1 (f1 BIGINT) ENGINE=InnoDB +# con2: SHOW CREATE TABLE t1 +# default: DROP TABLE t1 +# Subtest 4D (two connections, use PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 BIGINT, f2 BIGINT, UNIQUE(f1), UNIQUE (f2)) ENGINE=InnoDB +# con2: SHOW CREATE TABLE t1 +# default: DROP TABLE t1 +# con2: SHOW CREATE TABLE t1 (expect to get ER_NO_SUCH_TABLE) +# default: CREATE TABLE t1 (f1 BIGINT) ENGINE=InnoDB +# con2: SHOW CREATE TABLE t1 +# default: DROP TABLE t1 +# Subtest 5A (one connection, no PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 MEDIUMINT NOT NULL AUTO_INCREMENT,f2 BIGINT, UNIQUE(f1)) ENGINE = InnoDB +# default: INSERT INTO t1 SET f2 = 9 +# default: SELECT f1 <> 1 OR f1 IS NULL FROM t1 WHERE f2 = 9 +# default: DROP TABLE t1 +# Subtest 5B (one connection, use PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 MEDIUMINT NOT NULL AUTO_INCREMENT,f2 BIGINT, UNIQUE(f1)) ENGINE = InnoDB +# default: INSERT INTO t1 SET f2 = 9 +# default: SELECT f1 <> 1 OR f1 IS NULL FROM t1 WHERE f2 = 9 +# default: DROP TABLE t1 +# Subtest 5C (two connections, no PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 MEDIUMINT NOT NULL AUTO_INCREMENT,f2 BIGINT, UNIQUE(f1)) ENGINE = InnoDB +# con2: INSERT INTO t1 SET f2 = 9 +# default: SELECT f1 <> 1 OR f1 IS NULL FROM t1 WHERE f2 = 9 +# con2: DROP TABLE t1 +# Subtest 5D (two connections, use PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 MEDIUMINT NOT NULL AUTO_INCREMENT,f2 BIGINT, UNIQUE(f1)) ENGINE = InnoDB +# con2: INSERT INTO t1 SET f2 = 9 +# default: SELECT f1 <> 1 OR f1 IS NULL FROM t1 WHERE f2 = 9 +# con2: DROP TABLE t1 +CREATE TABLE t1 (f1 BIGINT, f2 BIGINT, UNIQUE(f1)) ENGINE=InnoDB; +# Subtest 6A (one connection, no PREPARE/EXECUTE) +# connection action +# default: CREATE INDEX IDX1 ON t1 (f2) +# default: CREATE INDEX IDX1 ON t1 (f2) (expect to get ER_DUP_KEYNAME) +# default: DROP INDEX IDX1 ON t1 +# default: DROP INDEX IDX1 ON t1 (expect to get ER_CANT_DROP_FIELD_OR_KEY) +# default: CREATE INDEX IDX1 ON t1 (f2) +# default: DROP INDEX IDX1 ON t1 +# Subtest 6B (one connection, use PREPARE/EXECUTE) +# connection action +# default: CREATE INDEX IDX1 ON t1 (f2) +# default: CREATE INDEX IDX1 ON t1 (f2) (expect to get ER_DUP_KEYNAME) +# default: DROP INDEX IDX1 ON t1 +# default: DROP INDEX IDX1 ON t1 (expect to get ER_CANT_DROP_FIELD_OR_KEY) +# default: CREATE INDEX IDX1 ON t1 (f2) +# default: DROP INDEX IDX1 ON t1 +# Subtest 6C (two connections, no PREPARE/EXECUTE) +# connection action +# default: CREATE INDEX IDX1 ON t1 (f2) +# con2: CREATE INDEX IDX1 ON t1 (f2) (expect to get ER_DUP_KEYNAME) +# default: DROP INDEX IDX1 ON t1 +# con2: DROP INDEX IDX1 ON t1 (expect to get ER_CANT_DROP_FIELD_OR_KEY) +# default: CREATE INDEX IDX1 ON t1 (f2) +# con2: DROP INDEX IDX1 ON t1 +# Subtest 6D (two connections, use PREPARE/EXECUTE) +# connection action +# default: CREATE INDEX IDX1 ON t1 (f2) +# con2: CREATE INDEX IDX1 ON t1 (f2) (expect to get ER_DUP_KEYNAME) +# default: DROP INDEX IDX1 ON t1 +# con2: DROP INDEX IDX1 ON t1 (expect to get ER_CANT_DROP_FIELD_OR_KEY) +# default: CREATE INDEX IDX1 ON t1 (f2) +# con2: DROP INDEX IDX1 ON t1 +DROP TABLE t1; +CREATE TABLE t1 (f1 BIGINT, f2 BIGINT, PRIMARY KEY(f1)) ENGINE=InnoDB; +INSERT INTO t1 VALUES(0,1); +# Subtest 7A (one connection, no PREPARE/EXECUTE) +# connection action +# default: CREATE UNIQUE INDEX IDX1 ON t1 (f2) +# default: INSERT INTO t1 VALUES(1,1) (expect to get ER_DUP_ENTRY) +# default: DROP INDEX IDX1 ON t1 +# default: INSERT INTO t1 VALUES(1,1) +# default: CREATE UNIQUE INDEX IDX1 ON t1 (f2) (expect to get ER_DUP_ENTRY) +# default: DELETE FROM t1 WHERE f1 = 1 +# Subtest 7B (one connection, use PREPARE/EXECUTE) +# connection action +# default: CREATE UNIQUE INDEX IDX1 ON t1 (f2) +# default: INSERT INTO t1 VALUES(1,1) (expect to get ER_DUP_ENTRY) +# default: DROP INDEX IDX1 ON t1 +# default: INSERT INTO t1 VALUES(1,1) +# default: CREATE UNIQUE INDEX IDX1 ON t1 (f2) (expect to get ER_DUP_ENTRY) +# default: DELETE FROM t1 WHERE f1 = 1 +# Subtest 7C (two connections, no PREPARE/EXECUTE) +# connection action +# default: CREATE UNIQUE INDEX IDX1 ON t1 (f2) +# default: INSERT INTO t1 VALUES(1,1) (expect to get ER_DUP_ENTRY) +# con2: DROP INDEX IDX1 ON t1 +# default: INSERT INTO t1 VALUES(1,1) +# con2: CREATE UNIQUE INDEX IDX1 ON t1 (f2) (expect to get ER_DUP_ENTRY) +# con2: DELETE FROM t1 WHERE f1 = 1 +# Subtest 7D (two connections, use PREPARE/EXECUTE) +# connection action +# default: CREATE UNIQUE INDEX IDX1 ON t1 (f2) +# default: INSERT INTO t1 VALUES(1,1) (expect to get ER_DUP_ENTRY) +# con2: DROP INDEX IDX1 ON t1 +# default: INSERT INTO t1 VALUES(1,1) +# con2: CREATE UNIQUE INDEX IDX1 ON t1 (f2) (expect to get ER_DUP_ENTRY) +# con2: DELETE FROM t1 WHERE f1 = 1 +DROP TABLE t1; +CREATE TABLE t1 (f1 BIGINT, f2 BIGINT, UNIQUE(f1)) ENGINE=InnoDB; +INSERT INTO t1 VALUES(1,1); +CREATE INDEX IDX ON t1 (f2); +DROP INDEX IDX ON t1; +CREATE UNIQUE INDEX IDX ON t1 (f2); +DROP INDEX IDX ON t1; +# Subtest 8A (one connection, no PREPARE/EXECUTE) +# connection action +# default: CREATE INDEX IDX ON t1 (f2) +# default: SHOW CREATE TABLE t1 +# default: DROP INDEX IDX ON t1 +# default: CREATE UNIQUE INDEX IDX ON t1 (f2) +# default: SHOW CREATE TABLE t1 +# default: DROP INDEX IDX ON t1 +# Subtest 8B (one connection, use PREPARE/EXECUTE) +# connection action +# default: CREATE INDEX IDX ON t1 (f2) +# default: SHOW CREATE TABLE t1 +# default: DROP INDEX IDX ON t1 +# default: CREATE UNIQUE INDEX IDX ON t1 (f2) +# default: SHOW CREATE TABLE t1 +# default: DROP INDEX IDX ON t1 +# Subtest 8C (two connections, no PREPARE/EXECUTE) +# connection action +# default: CREATE INDEX IDX ON t1 (f2) +# con2: SHOW CREATE TABLE t1 +# default: DROP INDEX IDX ON t1 +# default: CREATE UNIQUE INDEX IDX ON t1 (f2) +# con2: SHOW CREATE TABLE t1 +# default: DROP INDEX IDX ON t1 +# Subtest 8D (two connections, use PREPARE/EXECUTE) +# connection action +# default: CREATE INDEX IDX ON t1 (f2) +# con2: SHOW CREATE TABLE t1 +# default: DROP INDEX IDX ON t1 +# default: CREATE UNIQUE INDEX IDX ON t1 (f2) +# con2: SHOW CREATE TABLE t1 +# default: DROP INDEX IDX ON t1 +DROP TABLE t1; +DEALLOCATE PREPARE stmt_start; +DEALLOCATE PREPARE stmt_break; diff --git a/mysql-test/suite/stress/r/ddl_memory.result b/mysql-test/suite/stress/r/ddl_memory.result new file mode 100644 index 00000000000..1700fbc2745 --- /dev/null +++ b/mysql-test/suite/stress/r/ddl_memory.result @@ -0,0 +1,251 @@ +SET @@session.sql_mode = 'NO_ENGINE_SUBSTITUTION'; +PREPARE stmt_start FROM "SELECT UNIX_TIMESTAMP() INTO @start"; +SET @runtime = <intended_runtime>; +PREPARE stmt_break FROM "SELECT UNIX_TIMESTAMP() - @start > @runtime - 1"; +DROP TABLE IF EXISTS t1; +# Subtest 1A (one connection, no PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 BIGINT,f2 BIGINT,UNIQUE(f1),UNIQUE(f2)) +ENGINE = MEMORY +# default: INSERT INTO t1 VALUES (1,1), (2,2), (3,3) +# default: DROP TABLE t1 +# Subtest 1B (one connection, use PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 BIGINT,f2 BIGINT,UNIQUE(f1),UNIQUE(f2)) +ENGINE = MEMORY +# default: INSERT INTO t1 VALUES (1,1), (2,2), (3,3) +# default: DROP TABLE t1 +# Subtest 1C (two connections, no PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 BIGINT,f2 BIGINT,UNIQUE(f1),UNIQUE(f2)) +ENGINE = MEMORY +# con2: INSERT INTO t1 VALUES (1,1), (2,2), (3,3) +# con2: DROP TABLE t1 +# Subtest 1D (two connections, use PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 BIGINT,f2 BIGINT,UNIQUE(f1),UNIQUE(f2)) +ENGINE = MEMORY +# con2: INSERT INTO t1 VALUES (1,1), (2,2), (3,3) +# con2: DROP TABLE t1 +# Subtest 2A (one connection, no PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 ENGINE = MEMORY AS SELECT 1 AS f1 +# default: SELECT COUNT(*) <> 1 FROM t1 WHERE f1 = 1 +# default: DROP TABLE t1 +# default: SELECT COUNT(*) <> 1 FROM t1 WHERE f1 = 1 (expect to get ER_NO_SUCH_TABLE) +# Subtest 2B (one connection, use PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 ENGINE = MEMORY AS SELECT 1 AS f1 +# default: SELECT COUNT(*) <> 1 FROM t1 WHERE f1 = 1 +# default: DROP TABLE t1 +# default: SELECT COUNT(*) <> 1 FROM t1 WHERE f1 = 1 (expect to get ER_NO_SUCH_TABLE) +# Subtest 2C (two connections, no PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 ENGINE = MEMORY AS SELECT 1 AS f1 +# con2: SELECT COUNT(*) <> 1 FROM t1 WHERE f1 = 1 +# default: DROP TABLE t1 +# con2: SELECT COUNT(*) <> 1 FROM t1 WHERE f1 = 1 (expect to get ER_NO_SUCH_TABLE) +# Subtest 2D (two connections, use PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 ENGINE = MEMORY AS SELECT 1 AS f1 +# con2: SELECT COUNT(*) <> 1 FROM t1 WHERE f1 = 1 +# default: DROP TABLE t1 +# con2: SELECT COUNT(*) <> 1 FROM t1 WHERE f1 = 1 (expect to get ER_NO_SUCH_TABLE) +# Subtest 3A (one connection, no PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 BIGINT) ENGINE=MEMORY +# default: CREATE TABLE t1 (f1 BIGINT) ENGINE=MEMORY (expect to get ER_TABLE_EXISTS_ERROR) +# default: DROP TABLE t1 +# default: DROP TABLE t1 (expect to get ER_BAD_TABLE_ERROR) +# Subtest 3B (one connection, use PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 BIGINT) ENGINE=MEMORY +# default: CREATE TABLE t1 (f1 BIGINT) ENGINE=MEMORY (expect to get ER_TABLE_EXISTS_ERROR) +# default: DROP TABLE t1 +# default: DROP TABLE t1 (expect to get ER_BAD_TABLE_ERROR) +# Subtest 3C (two connections, no PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 BIGINT) ENGINE=MEMORY +# con2: CREATE TABLE t1 (f1 BIGINT) ENGINE=MEMORY (expect to get ER_TABLE_EXISTS_ERROR) +# default: DROP TABLE t1 +# con2: DROP TABLE t1 (expect to get ER_BAD_TABLE_ERROR) +# Subtest 3D (two connections, use PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 BIGINT) ENGINE=MEMORY +# con2: CREATE TABLE t1 (f1 BIGINT) ENGINE=MEMORY (expect to get ER_TABLE_EXISTS_ERROR) +# default: DROP TABLE t1 +# con2: DROP TABLE t1 (expect to get ER_BAD_TABLE_ERROR) +CREATE TABLE t1 (f1 BIGINT, f2 BIGINT, UNIQUE(f1), UNIQUE (f2)) ENGINE=MEMORY; +DROP TABLE t1; +CREATE TABLE t1 (f1 BIGINT) ENGINE=MEMORY; +DROP TABLE t1; +# Subtest 4A (one connection, no PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 BIGINT, f2 BIGINT, UNIQUE(f1), UNIQUE (f2)) ENGINE=MEMORY +# default: SHOW CREATE TABLE t1 +# default: DROP TABLE t1 +# default: SHOW CREATE TABLE t1 (expect to get ER_NO_SUCH_TABLE) +# default: CREATE TABLE t1 (f1 BIGINT) ENGINE=MEMORY +# default: SHOW CREATE TABLE t1 +# default: DROP TABLE t1 +# Subtest 4B (one connection, use PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 BIGINT, f2 BIGINT, UNIQUE(f1), UNIQUE (f2)) ENGINE=MEMORY +# default: SHOW CREATE TABLE t1 +# default: DROP TABLE t1 +# default: SHOW CREATE TABLE t1 (expect to get ER_NO_SUCH_TABLE) +# default: CREATE TABLE t1 (f1 BIGINT) ENGINE=MEMORY +# default: SHOW CREATE TABLE t1 +# default: DROP TABLE t1 +# Subtest 4C (two connections, no PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 BIGINT, f2 BIGINT, UNIQUE(f1), UNIQUE (f2)) ENGINE=MEMORY +# con2: SHOW CREATE TABLE t1 +# default: DROP TABLE t1 +# con2: SHOW CREATE TABLE t1 (expect to get ER_NO_SUCH_TABLE) +# default: CREATE TABLE t1 (f1 BIGINT) ENGINE=MEMORY +# con2: SHOW CREATE TABLE t1 +# default: DROP TABLE t1 +# Subtest 4D (two connections, use PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 BIGINT, f2 BIGINT, UNIQUE(f1), UNIQUE (f2)) ENGINE=MEMORY +# con2: SHOW CREATE TABLE t1 +# default: DROP TABLE t1 +# con2: SHOW CREATE TABLE t1 (expect to get ER_NO_SUCH_TABLE) +# default: CREATE TABLE t1 (f1 BIGINT) ENGINE=MEMORY +# con2: SHOW CREATE TABLE t1 +# default: DROP TABLE t1 +# Subtest 5A (one connection, no PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 MEDIUMINT NOT NULL AUTO_INCREMENT,f2 BIGINT, UNIQUE(f1)) ENGINE = MEMORY +# default: INSERT INTO t1 SET f2 = 9 +# default: SELECT f1 <> 1 OR f1 IS NULL FROM t1 WHERE f2 = 9 +# default: DROP TABLE t1 +# Subtest 5B (one connection, use PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 MEDIUMINT NOT NULL AUTO_INCREMENT,f2 BIGINT, UNIQUE(f1)) ENGINE = MEMORY +# default: INSERT INTO t1 SET f2 = 9 +# default: SELECT f1 <> 1 OR f1 IS NULL FROM t1 WHERE f2 = 9 +# default: DROP TABLE t1 +# Subtest 5C (two connections, no PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 MEDIUMINT NOT NULL AUTO_INCREMENT,f2 BIGINT, UNIQUE(f1)) ENGINE = MEMORY +# con2: INSERT INTO t1 SET f2 = 9 +# default: SELECT f1 <> 1 OR f1 IS NULL FROM t1 WHERE f2 = 9 +# con2: DROP TABLE t1 +# Subtest 5D (two connections, use PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 MEDIUMINT NOT NULL AUTO_INCREMENT,f2 BIGINT, UNIQUE(f1)) ENGINE = MEMORY +# con2: INSERT INTO t1 SET f2 = 9 +# default: SELECT f1 <> 1 OR f1 IS NULL FROM t1 WHERE f2 = 9 +# con2: DROP TABLE t1 +CREATE TABLE t1 (f1 BIGINT, f2 BIGINT, UNIQUE(f1)) ENGINE=MEMORY; +# Subtest 6A (one connection, no PREPARE/EXECUTE) +# connection action +# default: CREATE INDEX IDX1 ON t1 (f2) +# default: CREATE INDEX IDX1 ON t1 (f2) (expect to get ER_DUP_KEYNAME) +# default: DROP INDEX IDX1 ON t1 +# default: DROP INDEX IDX1 ON t1 (expect to get ER_CANT_DROP_FIELD_OR_KEY) +# default: CREATE INDEX IDX1 ON t1 (f2) +# default: DROP INDEX IDX1 ON t1 +# Subtest 6B (one connection, use PREPARE/EXECUTE) +# connection action +# default: CREATE INDEX IDX1 ON t1 (f2) +# default: CREATE INDEX IDX1 ON t1 (f2) (expect to get ER_DUP_KEYNAME) +# default: DROP INDEX IDX1 ON t1 +# default: DROP INDEX IDX1 ON t1 (expect to get ER_CANT_DROP_FIELD_OR_KEY) +# default: CREATE INDEX IDX1 ON t1 (f2) +# default: DROP INDEX IDX1 ON t1 +# Subtest 6C (two connections, no PREPARE/EXECUTE) +# connection action +# default: CREATE INDEX IDX1 ON t1 (f2) +# con2: CREATE INDEX IDX1 ON t1 (f2) (expect to get ER_DUP_KEYNAME) +# default: DROP INDEX IDX1 ON t1 +# con2: DROP INDEX IDX1 ON t1 (expect to get ER_CANT_DROP_FIELD_OR_KEY) +# default: CREATE INDEX IDX1 ON t1 (f2) +# con2: DROP INDEX IDX1 ON t1 +# Subtest 6D (two connections, use PREPARE/EXECUTE) +# connection action +# default: CREATE INDEX IDX1 ON t1 (f2) +# con2: CREATE INDEX IDX1 ON t1 (f2) (expect to get ER_DUP_KEYNAME) +# default: DROP INDEX IDX1 ON t1 +# con2: DROP INDEX IDX1 ON t1 (expect to get ER_CANT_DROP_FIELD_OR_KEY) +# default: CREATE INDEX IDX1 ON t1 (f2) +# con2: DROP INDEX IDX1 ON t1 +DROP TABLE t1; +CREATE TABLE t1 (f1 BIGINT, f2 BIGINT, PRIMARY KEY(f1)) ENGINE=MEMORY; +INSERT INTO t1 VALUES(0,1); +# Subtest 7A (one connection, no PREPARE/EXECUTE) +# connection action +# default: CREATE UNIQUE INDEX IDX1 ON t1 (f2) +# default: INSERT INTO t1 VALUES(1,1) (expect to get ER_DUP_ENTRY) +# default: DROP INDEX IDX1 ON t1 +# default: INSERT INTO t1 VALUES(1,1) +# default: CREATE UNIQUE INDEX IDX1 ON t1 (f2) (expect to get ER_DUP_ENTRY) +# default: DELETE FROM t1 WHERE f1 = 1 +# Subtest 7B (one connection, use PREPARE/EXECUTE) +# connection action +# default: CREATE UNIQUE INDEX IDX1 ON t1 (f2) +# default: INSERT INTO t1 VALUES(1,1) (expect to get ER_DUP_ENTRY) +# default: DROP INDEX IDX1 ON t1 +# default: INSERT INTO t1 VALUES(1,1) +# default: CREATE UNIQUE INDEX IDX1 ON t1 (f2) (expect to get ER_DUP_ENTRY) +# default: DELETE FROM t1 WHERE f1 = 1 +# Subtest 7C (two connections, no PREPARE/EXECUTE) +# connection action +# default: CREATE UNIQUE INDEX IDX1 ON t1 (f2) +# default: INSERT INTO t1 VALUES(1,1) (expect to get ER_DUP_ENTRY) +# con2: DROP INDEX IDX1 ON t1 +# default: INSERT INTO t1 VALUES(1,1) +# con2: CREATE UNIQUE INDEX IDX1 ON t1 (f2) (expect to get ER_DUP_ENTRY) +# con2: DELETE FROM t1 WHERE f1 = 1 +# Subtest 7D (two connections, use PREPARE/EXECUTE) +# connection action +# default: CREATE UNIQUE INDEX IDX1 ON t1 (f2) +# default: INSERT INTO t1 VALUES(1,1) (expect to get ER_DUP_ENTRY) +# con2: DROP INDEX IDX1 ON t1 +# default: INSERT INTO t1 VALUES(1,1) +# con2: CREATE UNIQUE INDEX IDX1 ON t1 (f2) (expect to get ER_DUP_ENTRY) +# con2: DELETE FROM t1 WHERE f1 = 1 +DROP TABLE t1; +CREATE TABLE t1 (f1 BIGINT, f2 BIGINT, UNIQUE(f1)) ENGINE=MEMORY; +INSERT INTO t1 VALUES(1,1); +CREATE INDEX IDX ON t1 (f2); +DROP INDEX IDX ON t1; +CREATE UNIQUE INDEX IDX ON t1 (f2); +DROP INDEX IDX ON t1; +# Subtest 8A (one connection, no PREPARE/EXECUTE) +# connection action +# default: CREATE INDEX IDX ON t1 (f2) +# default: SHOW CREATE TABLE t1 +# default: DROP INDEX IDX ON t1 +# default: CREATE UNIQUE INDEX IDX ON t1 (f2) +# default: SHOW CREATE TABLE t1 +# default: DROP INDEX IDX ON t1 +# Subtest 8B (one connection, use PREPARE/EXECUTE) +# connection action +# default: CREATE INDEX IDX ON t1 (f2) +# default: SHOW CREATE TABLE t1 +# default: DROP INDEX IDX ON t1 +# default: CREATE UNIQUE INDEX IDX ON t1 (f2) +# default: SHOW CREATE TABLE t1 +# default: DROP INDEX IDX ON t1 +# Subtest 8C (two connections, no PREPARE/EXECUTE) +# connection action +# default: CREATE INDEX IDX ON t1 (f2) +# con2: SHOW CREATE TABLE t1 +# default: DROP INDEX IDX ON t1 +# default: CREATE UNIQUE INDEX IDX ON t1 (f2) +# con2: SHOW CREATE TABLE t1 +# default: DROP INDEX IDX ON t1 +# Subtest 8D (two connections, use PREPARE/EXECUTE) +# connection action +# default: CREATE INDEX IDX ON t1 (f2) +# con2: SHOW CREATE TABLE t1 +# default: DROP INDEX IDX ON t1 +# default: CREATE UNIQUE INDEX IDX ON t1 (f2) +# con2: SHOW CREATE TABLE t1 +# default: DROP INDEX IDX ON t1 +DROP TABLE t1; +DEALLOCATE PREPARE stmt_start; +DEALLOCATE PREPARE stmt_break; diff --git a/mysql-test/suite/stress/r/ddl_myisam.result b/mysql-test/suite/stress/r/ddl_myisam.result new file mode 100644 index 00000000000..82be55b8371 --- /dev/null +++ b/mysql-test/suite/stress/r/ddl_myisam.result @@ -0,0 +1,251 @@ +SET @@session.sql_mode = 'NO_ENGINE_SUBSTITUTION'; +PREPARE stmt_start FROM "SELECT UNIX_TIMESTAMP() INTO @start"; +SET @runtime = <intended_runtime>; +PREPARE stmt_break FROM "SELECT UNIX_TIMESTAMP() - @start > @runtime - 1"; +DROP TABLE IF EXISTS t1; +# Subtest 1A (one connection, no PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 BIGINT,f2 BIGINT,UNIQUE(f1),UNIQUE(f2)) +ENGINE = MyISAM +# default: INSERT INTO t1 VALUES (1,1), (2,2), (3,3) +# default: DROP TABLE t1 +# Subtest 1B (one connection, use PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 BIGINT,f2 BIGINT,UNIQUE(f1),UNIQUE(f2)) +ENGINE = MyISAM +# default: INSERT INTO t1 VALUES (1,1), (2,2), (3,3) +# default: DROP TABLE t1 +# Subtest 1C (two connections, no PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 BIGINT,f2 BIGINT,UNIQUE(f1),UNIQUE(f2)) +ENGINE = MyISAM +# con2: INSERT INTO t1 VALUES (1,1), (2,2), (3,3) +# con2: DROP TABLE t1 +# Subtest 1D (two connections, use PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 BIGINT,f2 BIGINT,UNIQUE(f1),UNIQUE(f2)) +ENGINE = MyISAM +# con2: INSERT INTO t1 VALUES (1,1), (2,2), (3,3) +# con2: DROP TABLE t1 +# Subtest 2A (one connection, no PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 ENGINE = MyISAM AS SELECT 1 AS f1 +# default: SELECT COUNT(*) <> 1 FROM t1 WHERE f1 = 1 +# default: DROP TABLE t1 +# default: SELECT COUNT(*) <> 1 FROM t1 WHERE f1 = 1 (expect to get ER_NO_SUCH_TABLE) +# Subtest 2B (one connection, use PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 ENGINE = MyISAM AS SELECT 1 AS f1 +# default: SELECT COUNT(*) <> 1 FROM t1 WHERE f1 = 1 +# default: DROP TABLE t1 +# default: SELECT COUNT(*) <> 1 FROM t1 WHERE f1 = 1 (expect to get ER_NO_SUCH_TABLE) +# Subtest 2C (two connections, no PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 ENGINE = MyISAM AS SELECT 1 AS f1 +# con2: SELECT COUNT(*) <> 1 FROM t1 WHERE f1 = 1 +# default: DROP TABLE t1 +# con2: SELECT COUNT(*) <> 1 FROM t1 WHERE f1 = 1 (expect to get ER_NO_SUCH_TABLE) +# Subtest 2D (two connections, use PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 ENGINE = MyISAM AS SELECT 1 AS f1 +# con2: SELECT COUNT(*) <> 1 FROM t1 WHERE f1 = 1 +# default: DROP TABLE t1 +# con2: SELECT COUNT(*) <> 1 FROM t1 WHERE f1 = 1 (expect to get ER_NO_SUCH_TABLE) +# Subtest 3A (one connection, no PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 BIGINT) ENGINE=MyISAM +# default: CREATE TABLE t1 (f1 BIGINT) ENGINE=MyISAM (expect to get ER_TABLE_EXISTS_ERROR) +# default: DROP TABLE t1 +# default: DROP TABLE t1 (expect to get ER_BAD_TABLE_ERROR) +# Subtest 3B (one connection, use PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 BIGINT) ENGINE=MyISAM +# default: CREATE TABLE t1 (f1 BIGINT) ENGINE=MyISAM (expect to get ER_TABLE_EXISTS_ERROR) +# default: DROP TABLE t1 +# default: DROP TABLE t1 (expect to get ER_BAD_TABLE_ERROR) +# Subtest 3C (two connections, no PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 BIGINT) ENGINE=MyISAM +# con2: CREATE TABLE t1 (f1 BIGINT) ENGINE=MyISAM (expect to get ER_TABLE_EXISTS_ERROR) +# default: DROP TABLE t1 +# con2: DROP TABLE t1 (expect to get ER_BAD_TABLE_ERROR) +# Subtest 3D (two connections, use PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 BIGINT) ENGINE=MyISAM +# con2: CREATE TABLE t1 (f1 BIGINT) ENGINE=MyISAM (expect to get ER_TABLE_EXISTS_ERROR) +# default: DROP TABLE t1 +# con2: DROP TABLE t1 (expect to get ER_BAD_TABLE_ERROR) +CREATE TABLE t1 (f1 BIGINT, f2 BIGINT, UNIQUE(f1), UNIQUE (f2)) ENGINE=MyISAM; +DROP TABLE t1; +CREATE TABLE t1 (f1 BIGINT) ENGINE=MyISAM; +DROP TABLE t1; +# Subtest 4A (one connection, no PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 BIGINT, f2 BIGINT, UNIQUE(f1), UNIQUE (f2)) ENGINE=MyISAM +# default: SHOW CREATE TABLE t1 +# default: DROP TABLE t1 +# default: SHOW CREATE TABLE t1 (expect to get ER_NO_SUCH_TABLE) +# default: CREATE TABLE t1 (f1 BIGINT) ENGINE=MyISAM +# default: SHOW CREATE TABLE t1 +# default: DROP TABLE t1 +# Subtest 4B (one connection, use PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 BIGINT, f2 BIGINT, UNIQUE(f1), UNIQUE (f2)) ENGINE=MyISAM +# default: SHOW CREATE TABLE t1 +# default: DROP TABLE t1 +# default: SHOW CREATE TABLE t1 (expect to get ER_NO_SUCH_TABLE) +# default: CREATE TABLE t1 (f1 BIGINT) ENGINE=MyISAM +# default: SHOW CREATE TABLE t1 +# default: DROP TABLE t1 +# Subtest 4C (two connections, no PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 BIGINT, f2 BIGINT, UNIQUE(f1), UNIQUE (f2)) ENGINE=MyISAM +# con2: SHOW CREATE TABLE t1 +# default: DROP TABLE t1 +# con2: SHOW CREATE TABLE t1 (expect to get ER_NO_SUCH_TABLE) +# default: CREATE TABLE t1 (f1 BIGINT) ENGINE=MyISAM +# con2: SHOW CREATE TABLE t1 +# default: DROP TABLE t1 +# Subtest 4D (two connections, use PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 BIGINT, f2 BIGINT, UNIQUE(f1), UNIQUE (f2)) ENGINE=MyISAM +# con2: SHOW CREATE TABLE t1 +# default: DROP TABLE t1 +# con2: SHOW CREATE TABLE t1 (expect to get ER_NO_SUCH_TABLE) +# default: CREATE TABLE t1 (f1 BIGINT) ENGINE=MyISAM +# con2: SHOW CREATE TABLE t1 +# default: DROP TABLE t1 +# Subtest 5A (one connection, no PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 MEDIUMINT NOT NULL AUTO_INCREMENT,f2 BIGINT, UNIQUE(f1)) ENGINE = MyISAM +# default: INSERT INTO t1 SET f2 = 9 +# default: SELECT f1 <> 1 OR f1 IS NULL FROM t1 WHERE f2 = 9 +# default: DROP TABLE t1 +# Subtest 5B (one connection, use PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 MEDIUMINT NOT NULL AUTO_INCREMENT,f2 BIGINT, UNIQUE(f1)) ENGINE = MyISAM +# default: INSERT INTO t1 SET f2 = 9 +# default: SELECT f1 <> 1 OR f1 IS NULL FROM t1 WHERE f2 = 9 +# default: DROP TABLE t1 +# Subtest 5C (two connections, no PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 MEDIUMINT NOT NULL AUTO_INCREMENT,f2 BIGINT, UNIQUE(f1)) ENGINE = MyISAM +# con2: INSERT INTO t1 SET f2 = 9 +# default: SELECT f1 <> 1 OR f1 IS NULL FROM t1 WHERE f2 = 9 +# con2: DROP TABLE t1 +# Subtest 5D (two connections, use PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 MEDIUMINT NOT NULL AUTO_INCREMENT,f2 BIGINT, UNIQUE(f1)) ENGINE = MyISAM +# con2: INSERT INTO t1 SET f2 = 9 +# default: SELECT f1 <> 1 OR f1 IS NULL FROM t1 WHERE f2 = 9 +# con2: DROP TABLE t1 +CREATE TABLE t1 (f1 BIGINT, f2 BIGINT, UNIQUE(f1)) ENGINE=MyISAM; +# Subtest 6A (one connection, no PREPARE/EXECUTE) +# connection action +# default: CREATE INDEX IDX1 ON t1 (f2) +# default: CREATE INDEX IDX1 ON t1 (f2) (expect to get ER_DUP_KEYNAME) +# default: DROP INDEX IDX1 ON t1 +# default: DROP INDEX IDX1 ON t1 (expect to get ER_CANT_DROP_FIELD_OR_KEY) +# default: CREATE INDEX IDX1 ON t1 (f2) +# default: DROP INDEX IDX1 ON t1 +# Subtest 6B (one connection, use PREPARE/EXECUTE) +# connection action +# default: CREATE INDEX IDX1 ON t1 (f2) +# default: CREATE INDEX IDX1 ON t1 (f2) (expect to get ER_DUP_KEYNAME) +# default: DROP INDEX IDX1 ON t1 +# default: DROP INDEX IDX1 ON t1 (expect to get ER_CANT_DROP_FIELD_OR_KEY) +# default: CREATE INDEX IDX1 ON t1 (f2) +# default: DROP INDEX IDX1 ON t1 +# Subtest 6C (two connections, no PREPARE/EXECUTE) +# connection action +# default: CREATE INDEX IDX1 ON t1 (f2) +# con2: CREATE INDEX IDX1 ON t1 (f2) (expect to get ER_DUP_KEYNAME) +# default: DROP INDEX IDX1 ON t1 +# con2: DROP INDEX IDX1 ON t1 (expect to get ER_CANT_DROP_FIELD_OR_KEY) +# default: CREATE INDEX IDX1 ON t1 (f2) +# con2: DROP INDEX IDX1 ON t1 +# Subtest 6D (two connections, use PREPARE/EXECUTE) +# connection action +# default: CREATE INDEX IDX1 ON t1 (f2) +# con2: CREATE INDEX IDX1 ON t1 (f2) (expect to get ER_DUP_KEYNAME) +# default: DROP INDEX IDX1 ON t1 +# con2: DROP INDEX IDX1 ON t1 (expect to get ER_CANT_DROP_FIELD_OR_KEY) +# default: CREATE INDEX IDX1 ON t1 (f2) +# con2: DROP INDEX IDX1 ON t1 +DROP TABLE t1; +CREATE TABLE t1 (f1 BIGINT, f2 BIGINT, PRIMARY KEY(f1)) ENGINE=MyISAM; +INSERT INTO t1 VALUES(0,1); +# Subtest 7A (one connection, no PREPARE/EXECUTE) +# connection action +# default: CREATE UNIQUE INDEX IDX1 ON t1 (f2) +# default: INSERT INTO t1 VALUES(1,1) (expect to get ER_DUP_ENTRY) +# default: DROP INDEX IDX1 ON t1 +# default: INSERT INTO t1 VALUES(1,1) +# default: CREATE UNIQUE INDEX IDX1 ON t1 (f2) (expect to get ER_DUP_ENTRY) +# default: DELETE FROM t1 WHERE f1 = 1 +# Subtest 7B (one connection, use PREPARE/EXECUTE) +# connection action +# default: CREATE UNIQUE INDEX IDX1 ON t1 (f2) +# default: INSERT INTO t1 VALUES(1,1) (expect to get ER_DUP_ENTRY) +# default: DROP INDEX IDX1 ON t1 +# default: INSERT INTO t1 VALUES(1,1) +# default: CREATE UNIQUE INDEX IDX1 ON t1 (f2) (expect to get ER_DUP_ENTRY) +# default: DELETE FROM t1 WHERE f1 = 1 +# Subtest 7C (two connections, no PREPARE/EXECUTE) +# connection action +# default: CREATE UNIQUE INDEX IDX1 ON t1 (f2) +# default: INSERT INTO t1 VALUES(1,1) (expect to get ER_DUP_ENTRY) +# con2: DROP INDEX IDX1 ON t1 +# default: INSERT INTO t1 VALUES(1,1) +# con2: CREATE UNIQUE INDEX IDX1 ON t1 (f2) (expect to get ER_DUP_ENTRY) +# con2: DELETE FROM t1 WHERE f1 = 1 +# Subtest 7D (two connections, use PREPARE/EXECUTE) +# connection action +# default: CREATE UNIQUE INDEX IDX1 ON t1 (f2) +# default: INSERT INTO t1 VALUES(1,1) (expect to get ER_DUP_ENTRY) +# con2: DROP INDEX IDX1 ON t1 +# default: INSERT INTO t1 VALUES(1,1) +# con2: CREATE UNIQUE INDEX IDX1 ON t1 (f2) (expect to get ER_DUP_ENTRY) +# con2: DELETE FROM t1 WHERE f1 = 1 +DROP TABLE t1; +CREATE TABLE t1 (f1 BIGINT, f2 BIGINT, UNIQUE(f1)) ENGINE=MyISAM; +INSERT INTO t1 VALUES(1,1); +CREATE INDEX IDX ON t1 (f2); +DROP INDEX IDX ON t1; +CREATE UNIQUE INDEX IDX ON t1 (f2); +DROP INDEX IDX ON t1; +# Subtest 8A (one connection, no PREPARE/EXECUTE) +# connection action +# default: CREATE INDEX IDX ON t1 (f2) +# default: SHOW CREATE TABLE t1 +# default: DROP INDEX IDX ON t1 +# default: CREATE UNIQUE INDEX IDX ON t1 (f2) +# default: SHOW CREATE TABLE t1 +# default: DROP INDEX IDX ON t1 +# Subtest 8B (one connection, use PREPARE/EXECUTE) +# connection action +# default: CREATE INDEX IDX ON t1 (f2) +# default: SHOW CREATE TABLE t1 +# default: DROP INDEX IDX ON t1 +# default: CREATE UNIQUE INDEX IDX ON t1 (f2) +# default: SHOW CREATE TABLE t1 +# default: DROP INDEX IDX ON t1 +# Subtest 8C (two connections, no PREPARE/EXECUTE) +# connection action +# default: CREATE INDEX IDX ON t1 (f2) +# con2: SHOW CREATE TABLE t1 +# default: DROP INDEX IDX ON t1 +# default: CREATE UNIQUE INDEX IDX ON t1 (f2) +# con2: SHOW CREATE TABLE t1 +# default: DROP INDEX IDX ON t1 +# Subtest 8D (two connections, use PREPARE/EXECUTE) +# connection action +# default: CREATE INDEX IDX ON t1 (f2) +# con2: SHOW CREATE TABLE t1 +# default: DROP INDEX IDX ON t1 +# default: CREATE UNIQUE INDEX IDX ON t1 (f2) +# con2: SHOW CREATE TABLE t1 +# default: DROP INDEX IDX ON t1 +DROP TABLE t1; +DEALLOCATE PREPARE stmt_start; +DEALLOCATE PREPARE stmt_break; diff --git a/mysql-test/suite/stress/r/ddl_ndb.result b/mysql-test/suite/stress/r/ddl_ndb.result new file mode 100644 index 00000000000..39146e65fb0 --- /dev/null +++ b/mysql-test/suite/stress/r/ddl_ndb.result @@ -0,0 +1,216 @@ +SET @@session.sql_mode = 'NO_ENGINE_SUBSTITUTION'; +PREPARE stmt_start FROM "SELECT UNIX_TIMESTAMP() INTO @start"; +SET @runtime = <intended_runtime>; +PREPARE stmt_break FROM "SELECT UNIX_TIMESTAMP() - @start > @runtime - 1"; +DROP TABLE IF EXISTS t1; +# Subtest 1A (one connection, no PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 BIGINT,f2 BIGINT,UNIQUE(f1),UNIQUE(f2)) +ENGINE = NDB +# default: INSERT INTO t1 VALUES (1,1), (2,2), (3,3) +# default: DROP TABLE t1 +# Subtest 1B (one connection, use PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 BIGINT,f2 BIGINT,UNIQUE(f1),UNIQUE(f2)) +ENGINE = NDB +# default: INSERT INTO t1 VALUES (1,1), (2,2), (3,3) +# default: DROP TABLE t1 +# Subtest 1C (two connections, no PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 BIGINT,f2 BIGINT,UNIQUE(f1),UNIQUE(f2)) +ENGINE = NDB +# con2: INSERT INTO t1 VALUES (1,1), (2,2), (3,3) +# con2: DROP TABLE t1 +# Subtest 1D (two connections, use PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 BIGINT,f2 BIGINT,UNIQUE(f1),UNIQUE(f2)) +ENGINE = NDB +# con2: INSERT INTO t1 VALUES (1,1), (2,2), (3,3) +# con2: DROP TABLE t1 +# Subtest 2A (one connection, no PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 ENGINE = NDB AS SELECT 1 AS f1 +# default: SELECT COUNT(*) <> 1 FROM t1 WHERE f1 = 1 +# default: DROP TABLE t1 +# default: SELECT COUNT(*) <> 1 FROM t1 WHERE f1 = 1 (expect to get ER_NO_SUCH_TABLE) +# Subtest 2B (one connection, use PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 ENGINE = NDB AS SELECT 1 AS f1 +# default: SELECT COUNT(*) <> 1 FROM t1 WHERE f1 = 1 +# default: DROP TABLE t1 +# default: SELECT COUNT(*) <> 1 FROM t1 WHERE f1 = 1 (expect to get ER_NO_SUCH_TABLE) +# Subtest 2C (two connections, no PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 ENGINE = NDB AS SELECT 1 AS f1 +# con2: SELECT COUNT(*) <> 1 FROM t1 WHERE f1 = 1 +# default: DROP TABLE t1 +# con2: SELECT COUNT(*) <> 1 FROM t1 WHERE f1 = 1 (expect to get ER_NO_SUCH_TABLE) +# Subtest 2D (two connections, use PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 ENGINE = NDB AS SELECT 1 AS f1 +# con2: SELECT COUNT(*) <> 1 FROM t1 WHERE f1 = 1 +# default: DROP TABLE t1 +# con2: SELECT COUNT(*) <> 1 FROM t1 WHERE f1 = 1 (expect to get ER_NO_SUCH_TABLE) +# Subtest 3A (one connection, no PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 BIGINT) ENGINE=NDB +# default: CREATE TABLE t1 (f1 BIGINT) ENGINE=NDB (expect to get ER_TABLE_EXISTS_ERROR) +# default: DROP TABLE t1 +# default: DROP TABLE t1 (expect to get ER_BAD_TABLE_ERROR) +# Subtest 3B (one connection, use PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 BIGINT) ENGINE=NDB +# default: CREATE TABLE t1 (f1 BIGINT) ENGINE=NDB (expect to get ER_TABLE_EXISTS_ERROR) +# default: DROP TABLE t1 +# default: DROP TABLE t1 (expect to get ER_BAD_TABLE_ERROR) +# Subtest 3C (two connections, no PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 BIGINT) ENGINE=NDB +# con2: CREATE TABLE t1 (f1 BIGINT) ENGINE=NDB (expect to get ER_TABLE_EXISTS_ERROR) +# default: DROP TABLE t1 +# con2: DROP TABLE t1 (expect to get ER_BAD_TABLE_ERROR) +# Subtest 3D (two connections, use PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 BIGINT) ENGINE=NDB +# con2: CREATE TABLE t1 (f1 BIGINT) ENGINE=NDB (expect to get ER_TABLE_EXISTS_ERROR) +# default: DROP TABLE t1 +# con2: DROP TABLE t1 (expect to get ER_BAD_TABLE_ERROR) +CREATE TABLE t1 (f1 BIGINT, f2 BIGINT, UNIQUE(f1), UNIQUE (f2)) ENGINE=NDB; +DROP TABLE t1; +CREATE TABLE t1 (f1 BIGINT) ENGINE=NDB; +DROP TABLE t1; +# Subtest 4A (one connection, no PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 BIGINT, f2 BIGINT, UNIQUE(f1), UNIQUE (f2)) ENGINE=NDB +# default: SHOW CREATE TABLE t1 +# default: DROP TABLE t1 +# default: SHOW CREATE TABLE t1 (expect to get ER_NO_SUCH_TABLE) +# default: CREATE TABLE t1 (f1 BIGINT) ENGINE=NDB +# default: SHOW CREATE TABLE t1 +# default: DROP TABLE t1 +# Subtest 4B (one connection, use PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 BIGINT, f2 BIGINT, UNIQUE(f1), UNIQUE (f2)) ENGINE=NDB +# default: SHOW CREATE TABLE t1 +# default: DROP TABLE t1 +# default: SHOW CREATE TABLE t1 (expect to get ER_NO_SUCH_TABLE) +# default: CREATE TABLE t1 (f1 BIGINT) ENGINE=NDB +# default: SHOW CREATE TABLE t1 +# default: DROP TABLE t1 +# Subtest 4C (two connections, no PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 BIGINT, f2 BIGINT, UNIQUE(f1), UNIQUE (f2)) ENGINE=NDB +# con2: SHOW CREATE TABLE t1 +# default: DROP TABLE t1 +# con2: SHOW CREATE TABLE t1 (expect to get ER_NO_SUCH_TABLE) +# default: CREATE TABLE t1 (f1 BIGINT) ENGINE=NDB +# con2: SHOW CREATE TABLE t1 +# default: DROP TABLE t1 +# Subtest 4D (two connections, use PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 BIGINT, f2 BIGINT, UNIQUE(f1), UNIQUE (f2)) ENGINE=NDB +# con2: SHOW CREATE TABLE t1 +# default: DROP TABLE t1 +# con2: SHOW CREATE TABLE t1 (expect to get ER_NO_SUCH_TABLE) +# default: CREATE TABLE t1 (f1 BIGINT) ENGINE=NDB +# con2: SHOW CREATE TABLE t1 +# default: DROP TABLE t1 +# Subtest 5A (one connection, no PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 MEDIUMINT NOT NULL AUTO_INCREMENT,f2 BIGINT, UNIQUE(f1)) ENGINE = NDB +# default: INSERT INTO t1 SET f2 = 9 +# default: SELECT f1 <> 1 OR f1 IS NULL FROM t1 WHERE f2 = 9 +# default: DROP TABLE t1 +# Subtest 5B (one connection, use PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 MEDIUMINT NOT NULL AUTO_INCREMENT,f2 BIGINT, UNIQUE(f1)) ENGINE = NDB +# default: INSERT INTO t1 SET f2 = 9 +# default: SELECT f1 <> 1 OR f1 IS NULL FROM t1 WHERE f2 = 9 +# default: DROP TABLE t1 +# Subtest 5C (two connections, no PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 MEDIUMINT NOT NULL AUTO_INCREMENT,f2 BIGINT, UNIQUE(f1)) ENGINE = NDB +# con2: INSERT INTO t1 SET f2 = 9 +# default: SELECT f1 <> 1 OR f1 IS NULL FROM t1 WHERE f2 = 9 +# con2: DROP TABLE t1 +# Subtest 5D (two connections, use PREPARE/EXECUTE) +# connection action +# default: CREATE TABLE t1 (f1 MEDIUMINT NOT NULL AUTO_INCREMENT,f2 BIGINT, UNIQUE(f1)) ENGINE = NDB +# con2: INSERT INTO t1 SET f2 = 9 +# default: SELECT f1 <> 1 OR f1 IS NULL FROM t1 WHERE f2 = 9 +# con2: DROP TABLE t1 +CREATE TABLE t1 (f1 BIGINT, f2 BIGINT, UNIQUE(f1)) ENGINE=NDB; +# Subtest 6A (one connection, no PREPARE/EXECUTE) +# connection action +# default: CREATE INDEX IDX1 ON t1 (f2) +# default: CREATE INDEX IDX1 ON t1 (f2) (expect to get ER_DUP_KEYNAME) +# default: DROP INDEX IDX1 ON t1 +# default: DROP INDEX IDX1 ON t1 (expect to get ER_CANT_DROP_FIELD_OR_KEY) +# default: CREATE INDEX IDX1 ON t1 (f2) +# default: DROP INDEX IDX1 ON t1 +# Subtest 6B (one connection, use PREPARE/EXECUTE) +# connection action +# default: CREATE INDEX IDX1 ON t1 (f2) +# default: CREATE INDEX IDX1 ON t1 (f2) (expect to get ER_DUP_KEYNAME) +# default: DROP INDEX IDX1 ON t1 +# default: DROP INDEX IDX1 ON t1 (expect to get ER_CANT_DROP_FIELD_OR_KEY) +# default: CREATE INDEX IDX1 ON t1 (f2) +# default: DROP INDEX IDX1 ON t1 +# Subtest 6C (two connections, no PREPARE/EXECUTE) +# connection action +# default: CREATE INDEX IDX1 ON t1 (f2) +# con2: CREATE INDEX IDX1 ON t1 (f2) (expect to get ER_DUP_KEYNAME) +# default: DROP INDEX IDX1 ON t1 +# con2: DROP INDEX IDX1 ON t1 (expect to get ER_CANT_DROP_FIELD_OR_KEY) +# default: CREATE INDEX IDX1 ON t1 (f2) +# con2: DROP INDEX IDX1 ON t1 +# Subtest 6D (two connections, use PREPARE/EXECUTE) +# connection action +# default: CREATE INDEX IDX1 ON t1 (f2) +# con2: CREATE INDEX IDX1 ON t1 (f2) (expect to get ER_DUP_KEYNAME) +# default: DROP INDEX IDX1 ON t1 +# con2: DROP INDEX IDX1 ON t1 (expect to get ER_CANT_DROP_FIELD_OR_KEY) +# default: CREATE INDEX IDX1 ON t1 (f2) +# con2: DROP INDEX IDX1 ON t1 +DROP TABLE t1; +CREATE TABLE t1 (f1 BIGINT, f2 BIGINT, UNIQUE(f1)) ENGINE=NDB; +INSERT INTO t1 VALUES(1,1); +CREATE INDEX IDX ON t1 (f2); +DROP INDEX IDX ON t1; +CREATE UNIQUE INDEX IDX ON t1 (f2); +DROP INDEX IDX ON t1; +# Subtest 8A (one connection, no PREPARE/EXECUTE) +# connection action +# default: CREATE INDEX IDX ON t1 (f2) +# default: SHOW CREATE TABLE t1 +# default: DROP INDEX IDX ON t1 +# default: CREATE UNIQUE INDEX IDX ON t1 (f2) +# default: SHOW CREATE TABLE t1 +# default: DROP INDEX IDX ON t1 +# Subtest 8B (one connection, use PREPARE/EXECUTE) +# connection action +# default: CREATE INDEX IDX ON t1 (f2) +# default: SHOW CREATE TABLE t1 +# default: DROP INDEX IDX ON t1 +# default: CREATE UNIQUE INDEX IDX ON t1 (f2) +# default: SHOW CREATE TABLE t1 +# default: DROP INDEX IDX ON t1 +# Subtest 8C (two connections, no PREPARE/EXECUTE) +# connection action +# default: CREATE INDEX IDX ON t1 (f2) +# con2: SHOW CREATE TABLE t1 +# default: DROP INDEX IDX ON t1 +# default: CREATE UNIQUE INDEX IDX ON t1 (f2) +# con2: SHOW CREATE TABLE t1 +# default: DROP INDEX IDX ON t1 +# Subtest 8D (two connections, use PREPARE/EXECUTE) +# connection action +# default: CREATE INDEX IDX ON t1 (f2) +# con2: SHOW CREATE TABLE t1 +# default: DROP INDEX IDX ON t1 +# default: CREATE UNIQUE INDEX IDX ON t1 (f2) +# con2: SHOW CREATE TABLE t1 +# default: DROP INDEX IDX ON t1 +DROP TABLE t1; +DEALLOCATE PREPARE stmt_start; +DEALLOCATE PREPARE stmt_break; diff --git a/mysql-test/suite/stress/t/ddl_archive.test b/mysql-test/suite/stress/t/ddl_archive.test new file mode 100644 index 00000000000..0c47b5fcdd5 --- /dev/null +++ b/mysql-test/suite/stress/t/ddl_archive.test @@ -0,0 +1,51 @@ +######## t/ddl_archive.test ###### +# +# Stress the storage engine ARCHIVE with CREATE/DROP TABLE/INDEX +# +# Please look for details within include/ddl1.inc. +# +# Creation of this test: +# 2007-07-04 mleich +# + +# Storage engine to be used in CREATE TABLE +--source include/have_archive.inc +let $engine_type= ARCHIVE; + + +if (`SELECT $PS_PROTOCOL + $SP_PROTOCOL + $CURSOR_PROTOCOL + $VIEW_PROTOCOL > 0`) +{ + --skip Test requires: ps-protocol/sp-protocol/cursor-protocol/view-protocol disabled +} +let $run= `SELECT '$BIG_TEST' = '1'`; +if ($run) +{ + # A run started with "--big-test" should be allowed to consume more time. + # Rough intended runtime per subtest variant in seconds + let $runtime = 5; + # number of rounds till we look at the clock again + let $loop_size= 100; +} +if (!$run) +{ + let $runtime = 1; + let $loop_size= 20; +} + + +##### Some preparations needed for the ddl*.inc scripts +--source suite/stress/include/ddl.pre + +# Tests set to comment fail because of CSV limitations +# (limited number of keys, NULL within index not supported) +# --source suite/stress/include/ddl1.inc +--source suite/stress/include/ddl2.inc +--source suite/stress/include/ddl3.inc +# --source suite/stress/include/ddl4.inc +--source suite/stress/include/ddl5.inc +# --source suite/stress/include/ddl6.inc +# --source suite/stress/include/ddl7.inc +# --source suite/stress/include/ddl8.inc + +##### Cleanup +--source suite/stress/include/ddl.cln diff --git a/mysql-test/suite/stress/t/ddl_csv.test b/mysql-test/suite/stress/t/ddl_csv.test new file mode 100644 index 00000000000..9f6185c76be --- /dev/null +++ b/mysql-test/suite/stress/t/ddl_csv.test @@ -0,0 +1,51 @@ +######## t/ddl_csv.test ###### +# +# Stress the storage engine CSV with CREATE/DROP TABLE/INDEX +# +# Please look for details within include/ddl1.inc. +# +# Creation of this test: +# 2007-07-04 mleich +# + +# Storage engine to be used in CREATE TABLE +--source include/have_csv.inc +let $engine_type= CSV; + + +if (`SELECT $PS_PROTOCOL + $SP_PROTOCOL + $CURSOR_PROTOCOL + $VIEW_PROTOCOL > 0`) +{ + --skip Test requires: ps-protocol/sp-protocol/cursor-protocol/view-protocol disabled +} +let $run= `SELECT '$BIG_TEST' = '1'`; +if ($run) +{ + # A run started with "--big-test" should be allowed to consume more time. + # Rough intended runtime per subtest variant in seconds + let $runtime = 5; + # number of rounds till we look at the clock again + let $loop_size= 100; +} +if (!$run) +{ + let $runtime = 1; + let $loop_size= 20; +} + + +##### Some preparations needed for the ddl*.inc scripts +--source suite/stress/include/ddl.pre + +# Tests set to comment fail because of CSV limitations +# (limited number of keys, AUTOINC not supported) +# --source suite/stress/include/ddl1.inc +--source suite/stress/include/ddl2.inc +--source suite/stress/include/ddl3.inc +# --source suite/stress/include/ddl4.inc +# --source suite/stress/include/ddl5.inc +# --source suite/stress/include/ddl6.inc +# --source suite/stress/include/ddl7.inc +# --source suite/stress/include/ddl8.inc + +##### Cleanup +--source suite/stress/include/ddl.cln diff --git a/mysql-test/suite/stress/t/ddl_innodb.test b/mysql-test/suite/stress/t/ddl_innodb.test new file mode 100644 index 00000000000..784ba8ff003 --- /dev/null +++ b/mysql-test/suite/stress/t/ddl_innodb.test @@ -0,0 +1,49 @@ +######## t/ddl_innodb.test ###### +# +# Stress the storage engine InnoDB with CREATE/DROP TABLE/INDEX +# +# Please look for details within include/ddl1.inc. +# +# Creation of this test: +# 2007-07-04 mleich +# + +# Storage engine to be used in CREATE TABLE +--source include/have_innodb.inc +let $engine_type= InnoDB; + + +if (`SELECT $PS_PROTOCOL + $SP_PROTOCOL + $CURSOR_PROTOCOL + $VIEW_PROTOCOL > 0`) +{ + --skip Test requires: ps-protocol/sp-protocol/cursor-protocol/view-protocol disabled +} +let $run= `SELECT '$BIG_TEST' = '1'`; +if ($run) +{ + # A run started with "--big-test" should be allowed to consume more time. + # Rough intended runtime per subtest variant in seconds + let $runtime = 5; + # number of rounds till we look at the clock again + let $loop_size= 100; +} +if (!$run) +{ + let $runtime = 1; + let $loop_size= 20; +} + + +##### Some preparations needed for the ddl*.inc scripts +--source suite/stress/include/ddl.pre + +--source suite/stress/include/ddl1.inc +--source suite/stress/include/ddl2.inc +--source suite/stress/include/ddl3.inc +--source suite/stress/include/ddl4.inc +--source suite/stress/include/ddl5.inc +--source suite/stress/include/ddl6.inc +--source suite/stress/include/ddl7.inc +--source suite/stress/include/ddl8.inc + +##### Cleanup +--source suite/stress/include/ddl.cln diff --git a/mysql-test/suite/stress/t/ddl_memory.test b/mysql-test/suite/stress/t/ddl_memory.test new file mode 100644 index 00000000000..5178439bff1 --- /dev/null +++ b/mysql-test/suite/stress/t/ddl_memory.test @@ -0,0 +1,48 @@ +######## t/ddl_memory.test ###### +# +# Stress the storage engine MEMORY with CREATE/DROP TABLE/INDEX +# +# Please look for details within include/ddl1.inc. +# +# Creation of this test: +# 2007-07-04 mleich +# + +# Storage engine to be used in CREATE TABLE +let $engine_type= MEMORY; + + +if (`SELECT $PS_PROTOCOL + $SP_PROTOCOL + $CURSOR_PROTOCOL + $VIEW_PROTOCOL > 0`) +{ + --skip Test requires: ps-protocol/sp-protocol/cursor-protocol/view-protocol disabled +} +let $run= `SELECT '$BIG_TEST' = '1'`; +if ($run) +{ + # A run started with "--big-test" should be allowed to consume more time. + # Rough intended runtime per subtest variant in seconds + let $runtime = 5; + # number of rounds till we look at the clock again + let $loop_size= 100; +} +if (!$run) +{ + let $runtime = 1; + let $loop_size= 20; +} + + +##### Some preparations needed for the ddl*.inc scripts +--source suite/stress/include/ddl.pre + +--source suite/stress/include/ddl1.inc +--source suite/stress/include/ddl2.inc +--source suite/stress/include/ddl3.inc +--source suite/stress/include/ddl4.inc +--source suite/stress/include/ddl5.inc +--source suite/stress/include/ddl6.inc +--source suite/stress/include/ddl7.inc +--source suite/stress/include/ddl8.inc + +##### Cleanup +--source suite/stress/include/ddl.cln diff --git a/mysql-test/suite/stress/t/ddl_myisam.test b/mysql-test/suite/stress/t/ddl_myisam.test new file mode 100644 index 00000000000..8d6226e573b --- /dev/null +++ b/mysql-test/suite/stress/t/ddl_myisam.test @@ -0,0 +1,48 @@ +######## t/ddl_myisam.test ###### +# +# Stress the storage engine MyISAM with CREATE/DROP TABLE/INDEX +# +# Please look for details within include/ddl1.inc. +# +# Creation of this test: +# 2007-07-04 mleich +# + +# Storage engine to be used in CREATE TABLE +let $engine_type= MyISAM; + + +if (`SELECT $PS_PROTOCOL + $SP_PROTOCOL + $CURSOR_PROTOCOL + $VIEW_PROTOCOL > 0`) +{ + --skip Test requires: ps-protocol/sp-protocol/cursor-protocol/view-protocol disabled +} +let $run= `SELECT '$BIG_TEST' = '1'`; +if ($run) +{ + # A run started with "--big-test" should be allowed to consume more time. + # Rough intended runtime per subtest variant in seconds + let $runtime = 5; + # number of rounds till we look at the clock again + let $loop_size= 100; +} +if (!$run) +{ + let $runtime = 1; + let $loop_size= 20; +} + + +##### Some preparations needed for the ddl*.inc scripts +--source suite/stress/include/ddl.pre + +--source suite/stress/include/ddl1.inc +--source suite/stress/include/ddl2.inc +--source suite/stress/include/ddl3.inc +--source suite/stress/include/ddl4.inc +--source suite/stress/include/ddl5.inc +--source suite/stress/include/ddl6.inc +--source suite/stress/include/ddl7.inc +--source suite/stress/include/ddl8.inc + +##### Cleanup +--source suite/stress/include/ddl.cln diff --git a/mysql-test/suite/stress/t/ddl_ndb.test b/mysql-test/suite/stress/t/ddl_ndb.test new file mode 100644 index 00000000000..7eb45da8739 --- /dev/null +++ b/mysql-test/suite/stress/t/ddl_ndb.test @@ -0,0 +1,56 @@ +######## t/ddl_ndb.test ###### +# +# Stress the storage engine NDB with CREATE/DROP TABLE/INDEX +# +# Please look for details within include/ddl1.inc. +# +# Creation of this test: +# 2007-07-04 mleich +# + +# Storage engine to be used in CREATE TABLE +--source include/have_ndb.inc +let $engine_type= NDB; + + +if (`SELECT $PS_PROTOCOL + $SP_PROTOCOL + $CURSOR_PROTOCOL + $VIEW_PROTOCOL > 0`) +{ + --skip Test requires: ps-protocol/sp-protocol/cursor-protocol/view-protocol disabled +} +# Attention: We set here much smaller values for $runtime and $loop_size compared +# to the other storage engines. +# The reason is that NDB is extreme slow and should not exceed +# the "testcase-timeout". +let $run= `SELECT '$BIG_TEST' = '1'`; +if ($run) +{ + # A run started with "--big-test" should be allowed to consume more time. + # Rough intended runtime per subtest variant in seconds + let $runtime = 5; + # number of rounds till we look at the clock again + let $loop_size= 3; +} +if (!$run) +{ + let $runtime = 1; + let $loop_size= 1; +} + + +##### Some preparations needed for the ddl*.inc scripts +--source suite/stress/include/ddl.pre + +--source suite/stress/include/ddl1.inc +--source suite/stress/include/ddl2.inc +--source suite/stress/include/ddl3.inc +--source suite/stress/include/ddl4.inc +--source suite/stress/include/ddl5.inc +--source suite/stress/include/ddl6.inc +# The following test suffers from +# Bug#26043 UNIQUE INDEX create always fails after constraint violation +# and is therefore set to comment. +# --source suite/stress/include/ddl7.inc +--source suite/stress/include/ddl8.inc + +##### Cleanup +--source suite/stress/include/ddl.cln diff --git a/mysql-test/t/cast.test b/mysql-test/t/cast.test index ab2859a5346..5563e260a06 100644 --- a/mysql-test/t/cast.test +++ b/mysql-test/t/cast.test @@ -237,4 +237,13 @@ select hex(cast('a' as char(2) binary)); select hex(cast('a' as binary(2))); select hex(cast('a' as char(2) binary)); +# +# Bug#29898: Item_date_typecast::val_int doesn't reset the null_value flag. +# +CREATE TABLE t1 (d1 datetime); +INSERT INTO t1(d1) VALUES ('2007-07-19 08:30:00'), (NULL), + ('2007-07-19 08:34:00'), (NULL), ('2007-07-19 08:36:00'); +SELECT cast(date(d1) as signed) FROM t1; +drop table t1; + --echo End of 5.0 tests diff --git a/mysql-test/t/create.test b/mysql-test/t/create.test index dd3037ce88d..8b1de227ab8 100644 --- a/mysql-test/t/create.test +++ b/mysql-test/t/create.test @@ -1122,6 +1122,25 @@ show create table t1; drop table t1; +--echo +--echo Bug #26104 Bug on foreign key class constructor +--echo +--echo Check that ref_columns is initalized correctly in the constructor +--echo and semantic checks in mysql_prepare_table work. +--echo +--echo We do not need a storage engine that supports foreign keys +--echo for this test, as the checks are purely syntax-based, and the +--echo syntax is supported for all engines. +--echo +--disable_warnings +drop table if exists t1,t2; +--enable_warnings + +create table t1(a int not null, b int not null, primary key (a, b)); +--error ER_WRONG_FK_DEF +create table t2(a int not null, b int not null, c int not null, primary key (a), +foreign key fk_bug26104 (b,c) references t1(a)); +drop table t1; --echo End of 5.0 tests diff --git a/mysql-test/t/create_not_windows.test b/mysql-test/t/create_not_windows.test index 2c1700d9e49..56b4002106d 100644 --- a/mysql-test/t/create_not_windows.test +++ b/mysql-test/t/create_not_windows.test @@ -17,6 +17,7 @@ primary key (_id) show create table `about:text`; drop table `about:text`; + # End of 5.0 tests # diff --git a/mysql-test/t/ctype_big5.test b/mysql-test/t/ctype_big5.test index 8e17a27c550..5f3357e0406 100644 --- a/mysql-test/t/ctype_big5.test +++ b/mysql-test/t/ctype_big5.test @@ -68,15 +68,16 @@ select hex(convert(_big5 0xC84041 using ucs2)); # # Bug#26711 "binary content 0x00 sometimes becomes 0x5C 0x00 after dump/load" # +set names big5; create table t1 (a blob); insert into t1 values (0xEE00); ---exec $MYSQL_DUMP --default-character-set=big5 -T $MYSQLTEST_VARDIR/master-data/test test t1 +select * into outfile 'test/t1.txt' from t1; delete from t1; -select hex(load_file('test/t1.txt')); +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +--eval select hex(load_file('$MYSQLTEST_VARDIR/master-data/test/t1.txt')); load data infile 't1.txt' into table t1; select hex(a) from t1; --exec rm $MYSQLTEST_VARDIR/master-data/test/t1.txt ---exec rm $MYSQLTEST_VARDIR/master-data/test/t1.sql drop table t1; --echo End of 5.0 tests diff --git a/mysql-test/t/ctype_collate.test b/mysql-test/t/ctype_collate.test index 4bbae42559a..cfef8dfe81a 100644 --- a/mysql-test/t/ctype_collate.test +++ b/mysql-test/t/ctype_collate.test @@ -218,3 +218,14 @@ insert into t1 set f1=0x3F3F1E563F; insert into t1 set f1=0x3F3F; check table t1 extended; drop table t1; + +# +# Bug#29461: Sort order of the collation wasn't used when comparing characters +# with the space character. +# +create table t1 (a varchar(2) character set latin7 collate latin7_general_ci,key(a)); +insert into t1 set a=0x4c20; +insert into t1 set a=0x6c; +insert into t1 set a=0x4c98; +check table t1 extended; +drop table t1; diff --git a/mysql-test/t/ctype_latin1.test b/mysql-test/t/ctype_latin1.test index 0a112233ffb..b12436f77ba 100644 --- a/mysql-test/t/ctype_latin1.test +++ b/mysql-test/t/ctype_latin1.test @@ -121,3 +121,9 @@ INSERT INTO abcÿdef VALUES (2); SELECT * FROM `abcÿdef`; SELECT * FROM abcÿdef; DROP TABLE `abcÿdef`; +# +# Bug#29499 Converting 'del' from ascii to Unicode results in 'question mark' +# +select hex(cast(_ascii 0x7f as char(1) character set latin1)); + +--echo End of 5.0 tests diff --git a/mysql-test/t/ctype_ucs.test b/mysql-test/t/ctype_ucs.test index 8828cd10eec..18a18d6c632 100644 --- a/mysql-test/t/ctype_ucs.test +++ b/mysql-test/t/ctype_ucs.test @@ -612,4 +612,14 @@ select collation(group_concat(a separator ',')) from t1; drop table t1; set names latin1; +# +# Bug#29499 Converting 'del' from ascii to Unicode results in 'question mark' +# +create table t1 (s1 char(1) character set ascii, s2 char(1) character set ucs2); +insert into t1 (s1) values (0x7f); +update t1 set s2 = s1; +select hex(s2) from t1; +select hex(convert(s1 using latin1)) from t1; +drop table t1; + --echo End of 5.0 tests diff --git a/mysql-test/t/ddl_i18n_koi8r.test b/mysql-test/t/ddl_i18n_koi8r.test index e636d801b07..1d16adbad55 100644 --- a/mysql-test/t/ddl_i18n_koi8r.test +++ b/mysql-test/t/ddl_i18n_koi8r.test @@ -30,6 +30,8 @@ # ########################################################################### +# Test requires server to accept client connections (for mysqldump portions) +--source include/not_embedded.inc --source include/have_utf8.inc --source include/have_cp866.inc --source include/have_cp1251.inc diff --git a/mysql-test/t/ddl_i18n_utf8.test b/mysql-test/t/ddl_i18n_utf8.test index 5f032232e56..c80137a58b5 100644 --- a/mysql-test/t/ddl_i18n_utf8.test +++ b/mysql-test/t/ddl_i18n_utf8.test @@ -30,6 +30,8 @@ # ########################################################################### +# Test requires server to accept client connections (for mysqldump portions) +--source include/not_embedded.inc --source include/have_utf8.inc --source include/have_cp866.inc --source include/have_cp1251.inc diff --git a/mysql-test/t/func_gconcat.test b/mysql-test/t/func_gconcat.test index b24015ebb99..6f9b5399b7b 100644 --- a/mysql-test/t/func_gconcat.test +++ b/mysql-test/t/func_gconcat.test @@ -551,4 +551,15 @@ SELECT LENGTH( GROUP_CONCAT( a ) ) FROM t3 WHERE b = 3; SET group_concat_max_len= DEFAULT; DROP TABLE t1, t2, t3; +# +# Bug#29850: Wrong charset of the GROUP_CONCAT result when the select employs +# a temporary table. +# +set names latin1; +create table t1 (id int, name varchar(20)) DEFAULT CHARSET=utf8; +insert into t1 (id, name) values (1, "óra"); +insert into t1 (id, name) values (2, "óra"); +select b.id, group_concat(b.name) from t1 a, t1 b group by b.id; +drop table t1; + --echo End of 5.0 tests diff --git a/mysql-test/t/gis-rtree.test b/mysql-test/t/gis-rtree.test index 579ec65f149..88f31143d93 100644 --- a/mysql-test/t/gis-rtree.test +++ b/mysql-test/t/gis-rtree.test @@ -827,3 +827,22 @@ INSERT INTO t1 (b) SELECT b FROM t1; OPTIMIZE TABLE t1; DROP TABLE t1; + + +# +# Bug #29070: Error in spatial index +# + +CREATE TABLE t1 (a INT, b GEOMETRY NOT NULL, SPATIAL KEY b(b)); +INSERT INTO t1 VALUES (1, GEOMFROMTEXT('LINESTRING(1102218.456 1,2000000 2)')); +INSERT INTO t1 VALUES (2, GEOMFROMTEXT('LINESTRING(1102218.456 1,2000000 2)')); + +# must return the same number as the next select +SELECT COUNT(*) FROM t1 WHERE + MBRINTERSECTS(b, GEOMFROMTEXT('LINESTRING(1 1,1102219 2)') ); +SELECT COUNT(*) FROM t1 IGNORE INDEX (b) WHERE + MBRINTERSECTS(b, GEOMFROMTEXT('LINESTRING(1 1,1102219 2)') ); + +DROP TABLE t1; + +--echo End of 5.0 tests. diff --git a/mysql-test/t/innodb.test b/mysql-test/t/innodb.test index 321a1f4763a..140aac3b9c3 100644 --- a/mysql-test/t/innodb.test +++ b/mysql-test/t/innodb.test @@ -1178,7 +1178,7 @@ drop table t2; # Clean up filename -- embedded server reports whole path without .frm, # regular server reports relative path with .frm (argh!) --replace_result \\ / $MYSQL_TEST_DIR . /var/master-data/ / t2.frm t2 ---error 1005 +--error ER_WRONG_FK_DEF create table t2 (id int(11) not null, id2 int(11) not null, constraint t1_id_fk foreign key (id2,id) references t1 (id)) engine = innodb; # bug#3749 @@ -2349,6 +2349,21 @@ SHOW CREATE TABLE t1; DROP TABLE t1,t2; +# +# Bug #21101 (Prints wrong error message if max row size is too large) +# +--error 1118 +CREATE TABLE t1 ( + c01 CHAR(255), c02 CHAR(255), c03 CHAR(255), c04 CHAR(255), + c05 CHAR(255), c06 CHAR(255), c07 CHAR(255), c08 CHAR(255), + c09 CHAR(255), c10 CHAR(255), c11 CHAR(255), c12 CHAR(255), + c13 CHAR(255), c14 CHAR(255), c15 CHAR(255), c16 CHAR(255), + c17 CHAR(255), c18 CHAR(255), c19 CHAR(255), c20 CHAR(255), + c21 CHAR(255), c22 CHAR(255), c23 CHAR(255), c24 CHAR(255), + c25 CHAR(255), c26 CHAR(255), c27 CHAR(255), c28 CHAR(255), + c29 CHAR(255), c30 CHAR(255), c31 CHAR(255), c32 CHAR(255) + ) ENGINE = InnoDB; + ####################################################################### # # # Please, DO NOT TOUCH this file as well as the innodb.result file. # diff --git a/mysql-test/t/innodb_trx_weight.test b/mysql-test/t/innodb_trx_weight.test new file mode 100644 index 00000000000..b72eaad345f --- /dev/null +++ b/mysql-test/t/innodb_trx_weight.test @@ -0,0 +1,108 @@ +# +# Ensure that the number of locks (SELECT FOR UPDATE for example) is +# added to the number of altered rows when choosing the smallest +# transaction to kill as a victim when a deadlock is detected. +# Also transactions what had edited non-transactional tables should +# be heavier than ones that had not. +# + +-- source include/have_innodb.inc + +SET storage_engine=InnoDB; + +# we do not really care about what gets printed, we are only +# interested in getting the deadlock resolved according to our +# expectations +-- disable_query_log +-- disable_result_log + +# we want to use "-- eval statement1; statement2" which does not work with +# prepared statements. Because this test should not behave differently with +# or without prepared statements we disable them so the test does not fail +# if someone runs ./mysql-test-run.pl --ps-protocol +-- disable_ps_protocol + +-- disable_warnings +DROP TABLE IF EXISTS t1, t2, t3, t4, t5_nontrans; +-- enable_warnings + +# we will create a simple deadlock with t1, t2 and two connections +CREATE TABLE t1 (a INT); +CREATE TABLE t2 (a INT); + +# auxiliary table with a bulk of rows which will be locked by a +# transaction to increase its weight +CREATE TABLE t3 (a INT); + +# auxiliary empty table which will be inserted by a +# transaction to increase its weight +CREATE TABLE t4 (a INT); + +# auxiliary non-transactional table which will be edited by a +# transaction to tremendously increase its weight +CREATE TABLE t5_nontrans (a INT) ENGINE=MyISAM; + +INSERT INTO t1 VALUES (1); +INSERT INTO t2 VALUES (1); +# insert a lot of rows in t3 +INSERT INTO t3 VALUES (1); +INSERT INTO t3 SELECT * FROM t3; +INSERT INTO t3 SELECT * FROM t3; +INSERT INTO t3 SELECT * FROM t3; +INSERT INTO t3 SELECT * FROM t3; +INSERT INTO t3 SELECT * FROM t3; +INSERT INTO t3 SELECT * FROM t3; +INSERT INTO t3 SELECT * FROM t3; +INSERT INTO t3 SELECT * FROM t3; +INSERT INTO t3 SELECT * FROM t3; +INSERT INTO t3 SELECT * FROM t3; +INSERT INTO t3 SELECT * FROM t3; + +# test locking weight + +-- let $con1_extra_sql = +-- let $con1_extra_sql_present = 0 +-- let $con2_extra_sql = SELECT * FROM t3 FOR UPDATE +-- let $con2_extra_sql_present = 1 +-- let $con1_should_be_rolledback = 1 +-- source include/innodb_trx_weight.inc + +-- let $con1_extra_sql = INSERT INTO t4 VALUES (1), (1) +-- let $con1_extra_sql_present = 1 +-- let $con2_extra_sql = SELECT * FROM t3 FOR UPDATE +-- let $con2_extra_sql_present = 1 +-- let $con1_should_be_rolledback = 1 +-- source include/innodb_trx_weight.inc + +-- let $con1_extra_sql = INSERT INTO t4 VALUES (1), (1), (1), (1), (1), (1) +-- let $con1_extra_sql_present = 1 +-- let $con2_extra_sql = SELECT * FROM t3 FOR UPDATE +-- let $con2_extra_sql_present = 1 +-- let $con1_should_be_rolledback = 0 +-- source include/innodb_trx_weight.inc + +# test weight when non-transactional tables are edited + +-- let $con1_extra_sql = INSERT INTO t4 VALUES (1), (1), (1) +-- let $con1_extra_sql_present = 1 +-- let $con2_extra_sql = +-- let $con2_extra_sql_present = 0 +-- let $con1_should_be_rolledback = 0 +-- source include/innodb_trx_weight.inc + +-- let $con1_extra_sql = INSERT INTO t4 VALUES (1), (1), (1) +-- let $con1_extra_sql_present = 1 +-- let $con2_extra_sql = INSERT INTO t5_nontrans VALUES (1) +-- let $con2_extra_sql_present = 1 +-- let $con1_should_be_rolledback = 1 +-- source include/innodb_trx_weight.inc + +-- let $con1_extra_sql = INSERT INTO t4 VALUES (1), (1), (1) +-- let $con1_extra_sql = $con1_extra_sql; INSERT INTO t5_nontrans VALUES (1) +-- let $con1_extra_sql_present = 1 +-- let $con2_extra_sql = INSERT INTO t5_nontrans VALUES (1) +-- let $con2_extra_sql_present = 1 +-- let $con1_should_be_rolledback = 0 +-- source include/innodb_trx_weight.inc + +DROP TABLE t1, t2, t3, t4, t5_nontrans; diff --git a/mysql-test/t/join_nested.test b/mysql-test/t/join_nested.test index f29366797f6..5b07d8966f1 100644 --- a/mysql-test/t/join_nested.test +++ b/mysql-test/t/join_nested.test @@ -1083,4 +1083,118 @@ SELECT * FROM t1 JOIN (t2 JOIN t3 USING (b)) USING (a); DROP TABLE t1,t2,t3; +# +# BUG#29604: inner nest of left join interleaves with outer tables +# + +CREATE TABLE t1 ( + carrier char(2) default NULL, + id int NOT NULL auto_increment PRIMARY KEY +); +INSERT INTO t1 VALUES + ('CO',235371754),('CO',235376554),('CO',235376884),('CO',235377874), + ('CO',231060394),('CO',231059224),('CO',231059314),('CO',231060484), + ('CO',231060274),('CO',231060124),('CO',231060244),('CO',231058594), + ('CO',231058924),('CO',231058504),('CO',231059344),('CO',231060424), + ('CO',231059554),('CO',231060304),('CO',231059644),('CO',231059464), + ('CO',231059764),('CO',231058294),('CO',231058624),('CO',231058864), + ('CO',231059374),('CO',231059584),('CO',231059734),('CO',231059014), + ('CO',231059854),('CO',231059494),('CO',231059794),('CO',231058534), + ('CO',231058324),('CO',231058684),('CO',231059524),('CO',231059974); + +CREATE TABLE t2 ( + scan_date date default NULL, + package_id int default NULL, + INDEX scan_date(scan_date), + INDEX package_id(package_id) +); +INSERT INTO t2 VALUES + ('2008-12-29',231062944),('2008-12-29',231065764),('2008-12-29',231066124), + ('2008-12-29',231060094),('2008-12-29',231061054),('2008-12-29',231065644), + ('2008-12-29',231064384),('2008-12-29',231064444),('2008-12-29',231073774), + ('2008-12-29',231058594),('2008-12-29',231059374),('2008-12-29',231066004), + ('2008-12-29',231068494),('2008-12-29',231070174),('2008-12-29',231071884), + ('2008-12-29',231063274),('2008-12-29',231063754),('2008-12-29',231064144), + ('2008-12-29',231069424),('2008-12-29',231073714),('2008-12-29',231058414), + ('2008-12-29',231060994),('2008-12-29',231069154),('2008-12-29',231068614), + ('2008-12-29',231071464),('2008-12-29',231074014),('2008-12-29',231059614), + ('2008-12-29',231059074),('2008-12-29',231059464),('2008-12-29',231069094), + ('2008-12-29',231067294),('2008-12-29',231070144),('2008-12-29',231073804), + ('2008-12-29',231072634),('2008-12-29',231058294),('2008-12-29',231065344), + ('2008-12-29',231066094),('2008-12-29',231069034),('2008-12-29',231058594), + ('2008-12-29',231059854),('2008-12-29',231059884),('2008-12-29',231059914), + ('2008-12-29',231063664),('2008-12-29',231063814),('2008-12-29',231063904); + +CREATE TABLE t3 ( + package_id int default NULL, + INDEX package_id(package_id) +); +INSERT INTO t3 VALUES + (231058294),(231058324),(231058354),(231058384),(231058414),(231058444), + (231058474),(231058504),(231058534),(231058564),(231058594),(231058624), + (231058684),(231058744),(231058804),(231058864),(231058924),(231058954), + (231059014),(231059074),(231059104),(231059134),(231059164),(231059194), + (231059224),(231059254),(231059284),(231059314),(231059344),(231059374), + (231059404),(231059434),(231059464),(231059494),(231059524),(231059554), + (231059584),(231059614),(231059644),(231059674),(231059704),(231059734), + (231059764),(231059794),(231059824),(231059854),(231059884),(231059914), + (231059944),(231059974),(231060004),(231060034),(231060064),(231060094), + (231060124),(231060154),(231060184),(231060214),(231060244),(231060274), + (231060304),(231060334),(231060364),(231060394),(231060424),(231060454), + (231060484),(231060514),(231060544),(231060574),(231060604),(231060634), + (231060664),(231060694),(231060724),(231060754),(231060784),(231060814), + (231060844),(231060874),(231060904),(231060934),(231060964),(231060994), + (231061024),(231061054),(231061084),(231061144),(231061174),(231061204), + (231061234),(231061294),(231061354),(231061384),(231061414),(231061474), + (231061564),(231061594),(231061624),(231061684),(231061714),(231061774), + (231061804),(231061894),(231061984),(231062074),(231062134),(231062224), + (231062254),(231062314),(231062374),(231062434),(231062494),(231062554), + (231062584),(231062614),(231062644),(231062704),(231062734),(231062794), + (231062854),(231062884),(231062944),(231063004),(231063034),(231063064), + (231063124),(231063154),(231063184),(231063214),(231063274),(231063334), + (231063394),(231063424),(231063454),(231063514),(231063574),(231063664); + +CREATE TABLE t4 ( + carrier char(2) NOT NULL default '' PRIMARY KEY, + id int(11) default NULL, + INDEX id(id) +); +INSERT INTO t4 VALUES + ('99',6),('SK',456),('UA',486),('AI',1081),('OS',1111),('VS',1510); + +CREATE TABLE t5 ( + carrier_id int default NULL, + INDEX carrier_id(carrier_id) +); +INSERT INTO t5 VALUES + (6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6), + (6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6), + (6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6), + (6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6), + (6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6), + (6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(456),(456),(456), + (456),(456),(456),(456),(456),(456),(456),(456),(456),(456),(456),(456), + (456),(486),(1081),(1111),(1111),(1111),(1111),(1510); + +SELECT COUNT(*) + FROM((t2 JOIN t1 ON t2.package_id = t1.id) + JOIN t3 ON t3.package_id = t1.id); + +EXPLAIN +SELECT COUNT(*) + FROM ((t2 JOIN t1 ON t2.package_id = t1.id) + JOIN t3 ON t3.package_id = t1.id) + LEFT JOIN + (t5 JOIN t4 ON t5.carrier_id = t4.id) + ON t4.carrier = t1.carrier; +SELECT COUNT(*) + FROM ((t2 JOIN t1 ON t2.package_id = t1.id) + JOIN t3 ON t3.package_id = t1.id) + LEFT JOIN + (t5 JOIN t4 ON t5.carrier_id = t4.id) + ON t4.carrier = t1.carrier; + +DROP TABLE t1,t2,t3,t4,t5; + --echo End of 5.0 tests + diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test index 0f1fee453a5..38d8a07fe48 100644 --- a/mysql-test/t/mysqldump.test +++ b/mysql-test/t/mysqldump.test @@ -1542,6 +1542,19 @@ INSERT INTO t1 SET c1=11, c2=REPEAT('q',509); DROP TABLE t1; --echo # +--echo # Bug #28524: mysqldump --skip-add-drop-table is not +--echo # compatible with views +--echo # + +CREATE VIEW v1 AS SELECT 1; +--exec $MYSQL_DUMP --skip-add-drop-table test > $MYSQLTEST_VARDIR/tmp/bug28524.sql +DROP VIEW v1; + +--exec $MYSQL test < $MYSQLTEST_VARDIR/tmp/bug28524.sql +SELECT * FROM v1; +DROP VIEW v1; + +--echo # --echo # End of 5.0 tests --echo # diff --git a/mysql-test/t/mysqltest.test b/mysql-test/t/mysqltest.test index aa0e2f89382..b01579dce53 100644 --- a/mysql-test/t/mysqltest.test +++ b/mysql-test/t/mysqltest.test @@ -1263,7 +1263,7 @@ while ($i) EOF --exec echo "source $MYSQLTEST_VARDIR/tmp/mysqltest.sql; echo OK;" | $MYSQL_TEST 2>&1 -# Repeat connect/disconnect, exceed max number of connections +# Repeat connect/disconnect --write_file $MYSQLTEST_VARDIR/tmp/mysqltest.sql let $i=200; while ($i) diff --git a/mysql-test/t/sp-prelocking.test b/mysql-test/t/sp-prelocking.test index ec5b7fbad7c..60e97260839 100644 --- a/mysql-test/t/sp-prelocking.test +++ b/mysql-test/t/sp-prelocking.test @@ -333,4 +333,27 @@ insert into bug_27907_t1(a) values (1); drop table bug_27907_t1; +--echo +--echo Bug#22427 create table if not exists + stored function results in +--echo inconsistent behavior +--echo +--echo Add a test case, the bug itself was fixed by the patch for +--echo Bug#20662 +--echo +--disable_warnings +drop table if exists t1; +drop function if exists f_bug22427; +--enable_warnings +create table t1 (i int); +insert into t1 values (1); +create function f_bug22427() returns int return (select max(i) from t1); +select f_bug22427(); +# Until this bug was fixed, the following emitted error +# ERROR 1213: Deadlock found when trying to get lock +create table if not exists t1 select f_bug22427() as i; +--error ER_TABLE_EXISTS_ERROR +create table t1 select f_bug22427() as i; +drop table t1; +drop function f_bug22427; + --echo End of 5.0 tests diff --git a/mysql-test/t/ssl-big.test b/mysql-test/t/ssl-big.test new file mode 100644 index 00000000000..099c64df08f --- /dev/null +++ b/mysql-test/t/ssl-big.test @@ -0,0 +1,56 @@ +# Turn on ssl between the client and server +# and run a number of tests + +-- source include/have_ssl.inc +-- source include/big_test.inc + +--disable_warnings +DROP TABLE IF EXISTS t1, t2; +--enable_warnings + +# +# Bug #29579 Clients using SSL can hang the server +# + +connect (ssl_con,localhost,root,,,,,SSL); + +create table t1 (a int); + +disconnect ssl_con; + + +--disable_query_log +--disable_result_log + +let $count= 2000; +while ($count) +{ + connect (ssl_con,localhost,root,,,,,SSL); + + eval insert into t1 values ($count); + dec $count; + + # This select causes the net buffer to fill as the server sends the results + # but the client doesn't reap the results. The results are larger each time + # through the loop, so that eventually the buffer is completely full + # at the exact moment the server attempts to the close the connection with + # the lock held. + send select * from t1; + + # now send the quit the command so the server will initiate the shutdown. + send_quit ssl_con; + + # if the server is hung, this will hang too: + connect (ssl_con2,localhost,root,,,,,SSL); + + # no hang if we get here, close and retry + disconnect ssl_con2; + disconnect ssl_con; +} +--enable_query_log +--enable_result_log + +connect (ssl_con,localhost,root,,,,,SSL); + +drop table t1; + diff --git a/mysql-test/t/status.test b/mysql-test/t/status.test index b3d167a9341..1208393aa09 100644 --- a/mysql-test/t/status.test +++ b/mysql-test/t/status.test @@ -22,11 +22,14 @@ connection con2; lock tables t1 read; unlock tables; lock tables t1 read; +let $ID= `select connection_id()`; connection con1; --send update t1 set n = 3; connection con2; -sleep 1; +# wait for the other query to start executing +let $wait_condition= select 1 from INFORMATION_SCHEMA.PROCESSLIST where ID = $ID and STATE = 0; +--source include/wait_condition.inc unlock tables; connection con1; reap; diff --git a/mysql-test/t/symlink.test b/mysql-test/t/symlink.test index 981206ca54c..15f50b11e73 100644 --- a/mysql-test/t/symlink.test +++ b/mysql-test/t/symlink.test @@ -174,4 +174,43 @@ drop table t1; --echo End of 4.1 tests +# +# Bug #29325: create table overwrites .MYD file of other table (datadir) +# + +CREATE DATABASE db1; +CREATE DATABASE db2; + +USE db2; +--disable_query_log +eval CREATE TABLE t1 (b INT) ENGINE MYISAM +DATA DIRECTORY = '$MYSQLTEST_VARDIR/master-data/db1/'; +--enable_query_log + +INSERT INTO db2.t1 VALUES (1); +SELECT * FROM db2.t1; +RESET QUERY CACHE; + +USE db1; + +#no warning from create table +SET SESSION keep_files_on_create = TRUE; +--disable_abort_on_error +--error 1,1 +CREATE TABLE t1 (a INT) ENGINE MYISAM; +--enable_abort_on_error + +CREATE TABLE t3 (a INT) Engine=MyISAM; +INSERT INTO t3 VALUES (1),(2),(3); +TRUNCATE TABLE t3; +SELECT * from t3; + +SET SESSION keep_files_on_create = DEFAULT; + +DROP TABLE db2.t1, db1.t3; +DROP DATABASE db1; +DROP DATABASE db2; +USE test; + + --echo End of 5.0 tests diff --git a/mysql-test/t/trigger.test b/mysql-test/t/trigger.test index 8db432b27c3..c7251040544 100644 --- a/mysql-test/t/trigger.test +++ b/mysql-test/t/trigger.test @@ -2194,6 +2194,29 @@ drop table t1, t2, t1_op_log; # # TODO: test LOAD DATA INFILE +# +--echo +--echo Bug#27248 Triggers: error if insert affects temporary table +--echo +--echo The bug was fixed by the fix for Bug#26141 +--echo +--disable_warnings +drop table if exists t1; +drop temporary table if exists t2; +--enable_warnings +create table t1 (s1 int); +create temporary table t2 (s1 int); +create trigger t1_bi before insert on t1 for each row insert into t2 values (0); +create trigger t1_bd before delete on t1 for each row delete from t2; +insert into t1 values (0); +insert into t1 values (0); +select * from t1; +select * from t2; +delete from t1; +select * from t1; +select * from t2; +drop table t1; +drop temporary table t2; --echo End of 5.0 tests # diff --git a/mysql-test/t/type_enum.test b/mysql-test/t/type_enum.test index 1e5b53a2c6e..4d5d5ec8a86 100644 --- a/mysql-test/t/type_enum.test +++ b/mysql-test/t/type_enum.test @@ -183,4 +183,21 @@ insert into t1 values(''),(''),('a'),('b'); select * from t1 where f1=''; drop table t1; +# +# Bug#29360: Confluence of the special 0 enum value with the normal empty string +# value during field to field copy. +# + +CREATE TABLE t1 (c1 ENUM('a', '', 'b')); +INSERT INTO t1 (c1) VALUES ('b'); +INSERT INTO t1 (c1) VALUES (''); +INSERT INTO t1 (c1) VALUES (0); +INSERT INTO t1 (c1) VALUES (''); + +SELECT c1 + 0, COUNT(c1) FROM t1 GROUP BY c1; + +CREATE TABLE t2 SELECT * FROM t1; +SELECT c1 + 0 FROM t2; + +DROP TABLE t1,t2; --echo End of 5.1 tests diff --git a/mysql-test/t/type_time.test b/mysql-test/t/type_time.test index cb7e4f85ad1..5fc763be7fe 100644 --- a/mysql-test/t/type_time.test +++ b/mysql-test/t/type_time.test @@ -40,3 +40,40 @@ drop table t1; # ########################################################## # End of 4.1 tests + +# +# Bug#29555: Comparing time values as strings may lead to a wrong result. +# +select cast('100:55:50' as time) < cast('24:00:00' as time); +select cast('100:55:50' as time) < cast('024:00:00' as time); +select cast('300:55:50' as time) < cast('240:00:00' as time); +select cast('100:55:50' as time) > cast('24:00:00' as time); +select cast('100:55:50' as time) > cast('024:00:00' as time); +select cast('300:55:50' as time) > cast('240:00:00' as time); +create table t1 (f1 time); +insert into t1 values ('24:00:00'); +select cast('24:00:00' as time) = (select f1 from t1); +drop table t1; + +# +# Bug#29739: Incorrect time comparison in BETWEEN. +# +create table t1(f1 time, f2 time); +insert into t1 values('20:00:00','150:00:00'); +select 1 from t1 where cast('100:00:00' as time) between f1 and f2; +drop table t1; + +# +# Bug#29729: Wrong conversion error led to an empty result set. +# +CREATE TABLE t1 ( + f2 date NOT NULL, + f3 int(11) unsigned NOT NULL default '0', + PRIMARY KEY (f3, f2) +); +insert into t1 values('2007-07-01', 1); +insert into t1 values('2007-07-01', 2); +insert into t1 values('2007-07-02', 1); +insert into t1 values('2007-07-02', 2); +SELECT sum(f3) FROM t1 where f2='2007-07-01 00:00:00' group by f2; +drop table t1; diff --git a/mysys/md5.c b/mysys/md5.c index a88fb279a0b..0945f9ce5f4 100644 --- a/mysys/md5.c +++ b/mysys/md5.c @@ -45,7 +45,7 @@ documentation and/or software. #include <my_global.h> #include <m_string.h> -#include "md5.h" +#include "my_md5.h" /* Constants for MD5Transform routine. */ diff --git a/mysys/my_conio.c b/mysys/my_conio.c index 1ea1f7a820a..b78966446ee 100644 --- a/mysys/my_conio.c +++ b/mysys/my_conio.c @@ -187,15 +187,19 @@ char* my_cgets(char *buffer, size_t clen, size_t* plen) while (GetLastError() == ERROR_NOT_ENOUGH_MEMORY); *plen= plen_res; + /* We go here on error reading the string (Ctrl-C for example) */ + if (!*plen) + result= NULL; /* purecov: inspected */ + if (result != NULL) { - if (buffer[*plen - 2] == '\r') + if (*plen > 1 && buffer[*plen - 2] == '\r') { *plen= *plen - 2; } else { - if (buffer[*plen - 1] == '\r') + if (*plen > 0 && buffer[*plen - 1] == '\r') { char tmp[3]; int tmplen= sizeof(tmp); diff --git a/mysys/my_symlink2.c b/mysys/my_symlink2.c index 6ea22790998..2a46fb3abea 100644 --- a/mysys/my_symlink2.c +++ b/mysys/my_symlink2.c @@ -56,11 +56,13 @@ File my_create_with_symlink(const char *linkname, const char *filename, { if (!access(filename,F_OK)) { + my_errno= errno= EEXIST; my_error(EE_CANTCREATEFILE, MYF(0), filename, EEXIST); DBUG_RETURN(-1); } if (create_link && !access(linkname,F_OK)) { + my_errno= errno= EEXIST; my_error(EE_CANTCREATEFILE, MYF(0), linkname, EEXIST); DBUG_RETURN(-1); } diff --git a/scripts/make_binary_distribution.sh b/scripts/make_binary_distribution.sh index 201a922ee68..e7084d86f9c 100644 --- a/scripts/make_binary_distribution.sh +++ b/scripts/make_binary_distribution.sh @@ -301,7 +301,8 @@ rm -f $MYSQL_SHARE/Makefile* $MYSQL_SHARE/*/*.OLD copyfileto $BASE/mysql-test \ mysql-test/mysql-test-run mysql-test/install_test_db \ mysql-test/mysql-test-run.pl mysql-test/README \ - mysql-test/valgrind.supp \ + mysql-test/mysql-stress-test.pl \ + mysql-test/valgrind.supp \ netware/mysql_test_run.nlm netware/install_test_db.ncf MCP mysql-test/lib/*.pl $BASE/mysql-test/lib @@ -312,6 +313,7 @@ MCP mysql-test/t/*.def $BASE/mysql-test/t MCP mysql-test/std_data/*.dat mysql-test/std_data/*.frm \ mysql-test/std_data/*.MYD mysql-test/std_data/*.MYI \ mysql-test/std_data/*.pem mysql-test/std_data/Moscow_leap \ + mysql-test/std_data/Index.xml \ mysql-test/std_data/des_key_file mysql-test/std_data/*.*001 \ mysql-test/std_data/*.cnf mysql-test/std_data/*.MY* \ $BASE/mysql-test/std_data diff --git a/server-tools/instance-manager/instance.cc b/server-tools/instance-manager/instance.cc index edc9c88fe9f..80e7e99214b 100644 --- a/server-tools/instance-manager/instance.cc +++ b/server-tools/instance-manager/instance.cc @@ -524,24 +524,17 @@ bool Instance::init(const LEX_STRING *name_arg) /** - Complete instance options initialization. + @brief Complete instance options initialization. - SYNOPSIS - complete_initialization() - - RETURN - FALSE - ok - TRUE - error + @return Error status. + @retval FALSE ok + @retval TRUE error */ bool Instance::complete_initialization() { configured= ! options.complete_initialization(); - return FALSE; - /* - TODO: return actual status (from - Instance_options::complete_initialization()) here. - */ + return !configured; } /************************************************************************** @@ -644,25 +637,24 @@ bool Instance::is_mysqld_running() /** - Start mysqld. + @brief Start mysqld. - SYNOPSIS - start_mysqld() - - DESCRIPTION - Reset flags and start Instance Monitor thread, which will start mysqld. + Reset flags and start Instance Monitor thread, which will start mysqld. - MT-NOTE: instance must be locked before calling the operation. + @note Instance must be locked before calling the operation. - RETURN - FALSE - ok - TRUE - could not start instance + @return Error status code + @retval FALSE Ok + @retval TRUE Could not start instance */ bool Instance::start_mysqld() { Instance_monitor *instance_monitor; + if (!configured) + return TRUE; + /* Prepare instance to start Instance Monitor thread. diff --git a/server-tools/instance-manager/instance_options.cc b/server-tools/instance-manager/instance_options.cc index 5665c6f8670..8b96d6f0f96 100644 --- a/server-tools/instance-manager/instance_options.cc +++ b/server-tools/instance-manager/instance_options.cc @@ -156,7 +156,8 @@ int Instance_options::get_default_option(char *result, size_t result_len, goto err; /* +2 eats first "--" from the option string (E.g. "--datadir") */ - rc= parse_output_and_get_value((char*) cmd.buffer, option_name + 2, + rc= parse_output_and_get_value((char*) cmd.buffer, + option_name + 2, strlen(option_name + 2), result, result_len, GET_VALUE); err: return rc; @@ -194,8 +195,8 @@ bool Instance_options::fill_instance_version() bzero(result, MAX_VERSION_LENGTH); - if (parse_output_and_get_value((char*) cmd.buffer, "Ver", result, - MAX_VERSION_LENGTH, GET_LINE)) + if (parse_output_and_get_value((char*) cmd.buffer, STRING_WITH_LEN("Ver"), + result, MAX_VERSION_LENGTH, GET_LINE)) { log_error("Failed to get version of '%s': unexpected output.", (const char *) mysqld_path.str); @@ -206,8 +207,7 @@ bool Instance_options::fill_instance_version() { char *start; - /* chop the newline from the end of the version string */ - result[strlen(result) - NEWLINE_LEN]= '\0'; + /* trim leading whitespaces */ start= result; while (my_isspace(default_charset_info, *start)) @@ -255,7 +255,8 @@ bool Instance_options::fill_mysqld_real_path() bzero(result, FN_REFLEN); - if (parse_output_and_get_value((char*) cmd.buffer, "Usage: ", + if (parse_output_and_get_value((char*) cmd.buffer, + STRING_WITH_LEN("Usage: "), result, FN_REFLEN, GET_LINE)) { diff --git a/server-tools/instance-manager/parse_output.cc b/server-tools/instance-manager/parse_output.cc index 36eb5185f6b..4dc67657512 100644 --- a/server-tools/instance-manager/parse_output.cc +++ b/server-tools/instance-manager/parse_output.cc @@ -24,6 +24,13 @@ #include "parse.h" #include "portability.h" +/************************************************************************** + Private module implementation. +**************************************************************************/ + +namespace { /* no-indent */ + +/*************************************************************************/ void trim_space(const char **text, uint *word_len) { @@ -39,90 +46,362 @@ void trim_space(const char **text, uint *word_len) *word_len= (end - start)+1; } -/* - Parse output of the given command +/*************************************************************************/ - SYNOPSIS - parse_output_and_get_value() +/** + @brief A facade to the internal workings of optaining the output from an + executed system process. +*/ - command the command to execue with popen. - word the word to look for (usually an option name) - result the buffer to store the next word (option value) - input_buffer_len self-explanatory - flag this equals to GET_LINE if we want to get all the line after - the matched word and GET_VALUE otherwise. +class Mysqld_output_parser +{ +public: + Mysqld_output_parser() + { } - DESCRIPTION + virtual ~Mysqld_output_parser() + { } - Parse output of the "command". Find the "word" and return the next one - if flag is GET_VALUE. Return the rest of the parsed string otherwise. +public: + bool parse(const char *command, + const char *option_name_str, + uint option_name_length, + char *option_value_buf, + size_t option_value_buf_size, + enum_option_type option_type); - RETURN - 0 - ok, the word has been found - 1 - error occured or the word is not found -*/ +protected: + /** + @brief Run a process and attach stdout- and stdin-pipes to it. -int parse_output_and_get_value(const char *command, const char *word, - char *result, size_t input_buffer_len, - uint flag) -{ - FILE *output; - uint wordlen; - /* should be enough to store the string from the output */ - enum { MAX_LINE_LEN= 512 }; - char linebuf[MAX_LINE_LEN]; - int rc= 1; + @param command The path to the process to be executed - wordlen= strlen(word); + @return Error status. + @retval TRUE An error occurred + @retval FALSE Operation was a success + */ - /* - Successful return of popen does not tell us whether the command has been - executed successfully: if the command was not found, we'll get EOF - when reading the output buffer below. + virtual bool run_command(const char *command)= 0; + + + /** + @brief Read a sequence of bytes from the executed process' stdout pipe. + + The sequence is terminated by either '\0', LF or CRLF tokens. The + terminating token is excluded from the result. + + @param line_buffer A pointer to a character buffer + @param line_buffer_size The size of the buffer in bytes + + @return Error status. + @retval TRUE An error occured + @retval FALSE Operation was a success */ - if (!(output= popen(command, "r"))) - goto err; - /* - We want fully buffered stream. We also want system to - allocate appropriate buffer. + virtual bool read_line(char *line_buffer, + uint line_buffer_size)= 0; + + + /** + @brief Release any resources needed after a execution and parsing. */ - setvbuf(output, NULL, _IOFBF, 0); - while (fgets(linebuf, sizeof(linebuf) - 1, output)) + virtual bool cleanup()= 0; +}; + +/*************************************************************************/ + +bool Mysqld_output_parser::parse(const char *command, + const char *option_name_str, + uint option_name_length, + char *option_value_buf, + size_t option_value_buf_size, + enum_option_type option_type) +{ + /* should be enough to store the string from the output */ + const int LINE_BUFFER_SIZE= 512; + char line_buffer[LINE_BUFFER_SIZE]; + + if (run_command(command)) + return TRUE; + + while (true) { + if (read_line(line_buffer, LINE_BUFFER_SIZE)) + { + cleanup(); + return TRUE; + } + uint found_word_len= 0; - char *linep= linebuf; + char *linep= line_buffer; + + line_buffer[sizeof(line_buffer) - 1]= '\0'; /* safety */ + + /* Find the word(s) we are looking for in the line. */ - linebuf[sizeof(linebuf) - 1]= '\0'; /* safety */ + linep= strstr(linep, option_name_str); - /* - Find the word(s) we are looking for in the line - */ - if ((linep= strstr(linep, word))) + if (!linep) + continue; + + linep+= option_name_length; + + switch (option_type) { - /* - If we have found our word(s), then move linep past the word(s) - */ - linep+= wordlen; - if (flag & GET_VALUE) + case GET_VALUE: + trim_space((const char**) &linep, &found_word_len); + + if (option_value_buf_size <= found_word_len) { - trim_space((const char**) &linep, &found_word_len); - if (input_buffer_len <= found_word_len) - goto err; - strmake(result, linep, found_word_len); + cleanup(); + return TRUE; } - else /* currently there are only two options */ - strmake(result, linep, input_buffer_len - 1); - rc= 0; + + strmake(option_value_buf, linep, found_word_len); + + break; + + case GET_LINE: + strmake(option_value_buf, linep, option_value_buf_size - 1); + break; } + + cleanup(); + + return FALSE; } +} + +/************************************************************************** + Platform-specific implementation: UNIX. +**************************************************************************/ + +#ifndef __WIN__ + +class Mysqld_output_parser_unix : public Mysqld_output_parser +{ +public: + Mysqld_output_parser_unix() : + m_stdout(NULL) + { } + +protected: + virtual bool run_command(const char *command); + + virtual bool read_line(char *line_buffer, + uint line_buffer_size); + + virtual bool cleanup(); + +private: + FILE *m_stdout; +}; + +bool Mysqld_output_parser_unix::run_command(const char *command) +{ + if (!(m_stdout= popen(command, "r"))) + return TRUE; - /* we are not interested in the termination status */ - pclose(output); + /* + We want fully buffered stream. We also want system to allocate + appropriate buffer. + */ -err: - return rc; + setvbuf(m_stdout, NULL, _IOFBF, 0); + + return FALSE; } +bool Mysqld_output_parser_unix::read_line(char *line_buffer, + uint line_buffer_size) +{ + char *retbuff = fgets(line_buffer, line_buffer_size, m_stdout); + /* Remove any tailing new line charaters */ + if (line_buffer[line_buffer_size-1] == LF) + line_buffer[line_buffer_size-1]= '\0'; + return (retbuff == NULL); +} + +bool Mysqld_output_parser_unix::cleanup() +{ + if (m_stdout) + pclose(m_stdout); + + return FALSE; +} + +#else /* Windows */ + +/************************************************************************** + Platform-specific implementation: Windows. +**************************************************************************/ + +class Mysqld_output_parser_win : public Mysqld_output_parser +{ +public: + Mysqld_output_parser_win() : + m_internal_buffer(NULL), + m_internal_buffer_offset(0), + m_internal_buffer_size(0) + { } + +protected: + virtual bool run_command(const char *command); + virtual bool read_line(char *line_buffer, + uint line_buffer_size); + virtual bool cleanup(); + +private: + HANDLE m_h_child_stdout_wr; + HANDLE m_h_child_stdout_rd; + uint m_internal_buffer_offset; + uint m_internal_buffer_size; + char *m_internal_buffer; +}; + +bool Mysqld_output_parser_win::run_command(const char *command) +{ + BOOL op_status; + + SECURITY_ATTRIBUTES sa_attr; + sa_attr.nLength= sizeof(SECURITY_ATTRIBUTES); + sa_attr.bInheritHandle= TRUE; + sa_attr.lpSecurityDescriptor= NULL; + + op_status= CreatePipe(&m_h_child_stdout_rd, + &m_h_child_stdout_wr, + &sa_attr, + 0 /* Use system-default buffer size. */); + + if (!op_status) + return TRUE; + + SetHandleInformation(m_h_child_stdout_rd, HANDLE_FLAG_INHERIT, 0); + + STARTUPINFO si_start_info; + ZeroMemory(&si_start_info, sizeof(STARTUPINFO)); + si_start_info.cb= sizeof(STARTUPINFO); + si_start_info.hStdError= m_h_child_stdout_wr; + si_start_info.hStdOutput= m_h_child_stdout_wr; + si_start_info.dwFlags|= STARTF_USESTDHANDLES; + + PROCESS_INFORMATION pi_proc_info; + + op_status= CreateProcess(NULL, /* Application name. */ + (char*)command, /* Command line. */ + NULL, /* Process security attributes. */ + NULL, /* Primary thread security attr.*/ + TRUE, /* Handles are inherited. */ + 0, /* Creation flags. */ + NULL, /* Use parent's environment. */ + NULL, /* Use parent's curr. directory. */ + &si_start_info, /* STARTUPINFO pointer. */ + &pi_proc_info); /* Rec. PROCESS_INFORMATION. */ + + if (!retval) + { + CloseHandle(m_h_child_stdout_rd); + CloseHandle(m_h_child_stdout_wr); + + return TRUE; + } + + /* Close unnessary handles. */ + + CloseHandle(pi_proc_info.hProcess); + CloseHandle(pi_proc_info.hThread); + + return FALSE; +} + +bool Mysqld_output_parser_win::read_line(char *line_buffer, + uint line_buffer_size) +{ + DWORD dw_read_count= m_internal_buffer_size; + bzero(line_buffer,line_buffer_size); + char *buff_ptr= line_buffer; + char ch; + + while (buff_ptr - line_buffer < line_buffer_size) + { + do + { + ReadFile(m_h_child_stdout_rd, &ch, + 1, &dw_read_count, NULL); + } while ((ch == CR || ch == LF) && buff_ptr == line_buffer); + + if (dw_read_count == 0) + return TRUE; + + if (ch == CR || ch == LF) + break; + + *buff_ptr++ = ch; + } + + return FALSE; +} + +bool Mysqld_output_parser_win::cleanup() +{ + /* Close all handles. */ + + CloseHandle(m_h_child_stdout_wr); + CloseHandle(m_h_child_stdout_rd); + + return FALSE; +} +#endif + +/*************************************************************************/ + +} /* End of private module implementation. */ + +/*************************************************************************/ + +/** + @brief Parse output of the given command + + @param command The command to execute. + @param option_name_str Option name. + @param option_name_length Length of the option name. + @param[out] option_value_buf The buffer to store option value. + @param option_value_buf_size Size of the option value buffer. + @param option_type Type of the option: + - GET_LINE if we want to get all the + line after the option name; + - GET_VALUE otherwise. + + Execute the process by running "command". Find the "option name" and + return the next word if "option_type" is GET_VALUE. Return the rest of + the parsed string otherwise. + + @note This function has a separate windows implementation. + + @return The error status. + @retval FALSE Ok, the option name has been found. + @retval TRUE Error occured or the option name is not found. +*/ + +bool parse_output_and_get_value(const char *command, + const char *option_name_str, + uint option_name_length, + char *option_value_buf, + size_t option_value_buf_size, + enum_option_type option_type) +{ +#ifndef __WIN__ + Mysqld_output_parser_unix parser; +#else /* __WIN__ */ + Mysqld_output_parser_win parser; +#endif + + return parser.parse(command, + option_name_str, + option_name_length, + option_value_buf, + option_value_buf_size, + option_type); +} diff --git a/server-tools/instance-manager/parse_output.h b/server-tools/instance-manager/parse_output.h index 8851934f230..41618f643a3 100644 --- a/server-tools/instance-manager/parse_output.h +++ b/server-tools/instance-manager/parse_output.h @@ -17,11 +17,17 @@ #include <my_global.h> -#define GET_VALUE 1 -#define GET_LINE 2 +enum enum_option_type +{ + GET_VALUE = 1, + GET_LINE +}; -int parse_output_and_get_value(const char *command, const char *word, - char *result, size_t input_buffer_len, - uint flag); +bool parse_output_and_get_value(const char *command, + const char *option_name_str, + uint option_name_length, + char *option_value_buf, + size_t option_value_buf_size, + enum_option_type option_type); #endif /* INCLUDES_MYSQL_INSTANCE_MANAGER_PARSE_OUTPUT_H */ diff --git a/server-tools/instance-manager/portability.h b/server-tools/instance-manager/portability.h index eb677a0135c..990e6140a9e 100644 --- a/server-tools/instance-manager/portability.h +++ b/server-tools/instance-manager/portability.h @@ -48,11 +48,16 @@ typedef int pid_t; #define NEWLINE "\r\n" #define NEWLINE_LEN 2 +const char CR = '\r'; +const char LF = '\n'; + #else /* ! __WIN__ */ #define NEWLINE "\n" #define NEWLINE_LEN 1 +const char LF = '\n'; + #endif /* __WIN__ */ #endif /* INCLUDES_MYSQL_INSTANCE_MANAGER_PORTABILITY_H */ diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt index 85c2013d8e7..a8aa7d70586 100644 --- a/sql/CMakeLists.txt +++ b/sql/CMakeLists.txt @@ -15,9 +15,10 @@ INCLUDE("${PROJECT_SOURCE_DIR}/win/mysql_manifest.cmake") SET(CMAKE_CXX_FLAGS_DEBUG - "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX -DUSE_SYMDIR") + "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX -DUSE_SYMDIR /Zi") SET(CMAKE_C_FLAGS_DEBUG - "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX -DUSE_SYMDIR") + "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX -DUSE_SYMDIR /Zi") +SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} /MAP /MAPINFO:EXPORTS") INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/extra/yassl/include @@ -40,7 +41,8 @@ SET_SOURCE_FILES_PROPERTIES(${CMAKE_SOURCE_DIR}/sql/message.rc ADD_DEFINITIONS(-DMYSQL_SERVER -D_CONSOLE -DHAVE_DLOPEN) -ADD_EXECUTABLE(mysqld ../sql-common/client.c derror.cc des_key_file.cc +ADD_EXECUTABLE(mysqld${MYSQLD_EXE_SUFFIX} + ../sql-common/client.c derror.cc des_key_file.cc discover.cc ../libmysql/errmsg.c field.cc field_conv.cc filesort.cc gstream.cc ha_partition.cc @@ -81,7 +83,8 @@ ADD_EXECUTABLE(mysqld ../sql-common/client.c derror.cc des_key_file.cc ${PROJECT_SOURCE_DIR}/include/mysql_version.h ${PROJECT_SOURCE_DIR}/sql/sql_builtin.cc ${PROJECT_SOURCE_DIR}/sql/lex_hash.h) -TARGET_LINK_LIBRARIES(mysqld heap myisam myisammrg mysys yassl zlib dbug yassl +TARGET_LINK_LIBRARIES(mysqld${MYSQLD_EXE_SUFFIX} + heap myisam myisammrg mysys yassl zlib dbug yassl taocrypt strings vio regex wsock32 ws2_32) IF(EMBED_MANIFESTS) @@ -97,16 +100,16 @@ IF(WITH_CSV_STORAGE_ENGINE) TARGET_LINK_LIBRARIES(mysqld csv) ENDIF(WITH_CSV_STORAGE_ENGINE) IF(WITH_EXAMPLE_STORAGE_ENGINE) - TARGET_LINK_LIBRARIES(mysqld example) + TARGET_LINK_LIBRARIES(mysqld${MYSQLD_EXE_SUFFIX} example) ENDIF(WITH_EXAMPLE_STORAGE_ENGINE) IF(WITH_FEDERATED_STORAGE_ENGINE) TARGET_LINK_LIBRARIES(mysqld federated) ENDIF(WITH_FEDERATED_STORAGE_ENGINE) IF(WITH_INNOBASE_STORAGE_ENGINE) - TARGET_LINK_LIBRARIES(mysqld innobase) + TARGET_LINK_LIBRARIES(mysqld${MYSQLD_EXE_SUFFIX} innobase) ENDIF(WITH_INNOBASE_STORAGE_ENGINE) -ADD_DEPENDENCIES(mysqld GenError) +ADD_DEPENDENCIES(mysqld${MYSQLD_EXE_SUFFIX} GenError) # Sql Parser custom command ADD_CUSTOM_COMMAND( @@ -138,8 +141,7 @@ ADD_CUSTOM_COMMAND( COMMAND ${GEN_LEX_HASH_EXE} ARGS > lex_hash.h DEPENDS ${GEN_LEX_HASH_EXE} ) - -ADD_DEPENDENCIES(mysqld gen_lex_hash) +ADD_DEPENDENCIES(mysqld${MYSQLD_EXE_SUFFIX} gen_lex_hash) ADD_LIBRARY(udf_example MODULE udf_example.c udf_example.def) ADD_DEPENDENCIES(udf_example strings) diff --git a/sql/field.cc b/sql/field.cc index 2cd81afca49..a970a6e4318 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -5406,7 +5406,8 @@ int Field_newdate::store(const char *from,uint len,CHARSET_INFO *cs) else { tmp= l_time.day + l_time.month*32 + l_time.year*16*32; - if (!error && (ret != MYSQL_TIMESTAMP_DATE)) + if (!error && (ret != MYSQL_TIMESTAMP_DATE) && + thd->count_cuted_fields != CHECK_FIELD_IGNORE) error= 3; // Datetime was cut (note) } diff --git a/sql/field_conv.cc b/sql/field_conv.cc index 44aea9acee0..33c7897c3db 100644 --- a/sql/field_conv.cc +++ b/sql/field_conv.cc @@ -795,11 +795,18 @@ int field_conv(Field *to,Field *from) blob->value.copy(); return blob->store(blob->value.ptr(),blob->value.length(),from->charset()); } - if ((from->result_type() == STRING_RESULT && - (to->result_type() == STRING_RESULT || - (from->real_type() != MYSQL_TYPE_ENUM && - from->real_type() != MYSQL_TYPE_SET))) || - to->type() == MYSQL_TYPE_DECIMAL) + if (from->real_type() == MYSQL_TYPE_ENUM && + to->real_type() == MYSQL_TYPE_ENUM && + from->val_int() == 0) + { + ((Field_enum *)(to))->store_type(0); + return 0; + } + else if ((from->result_type() == STRING_RESULT && + (to->result_type() == STRING_RESULT || + (from->real_type() != MYSQL_TYPE_ENUM && + from->real_type() != MYSQL_TYPE_SET))) || + to->type() == MYSQL_TYPE_DECIMAL) { char buff[MAX_FIELD_WIDTH]; String result(buff,sizeof(buff),from->charset()); diff --git a/sql/filesort.cc b/sql/filesort.cc index e547940797b..b6a5d844eac 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -1120,7 +1120,8 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file, int flag) { int error; - uint rec_length,sort_length,res_length,offset; + uint rec_length,res_length,offset; + size_t sort_length; ulong maxcount; ha_rows max_rows,org_max_rows; my_off_t to_start_filepos; diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 3477ce84b21..755e711e383 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -719,6 +719,67 @@ Arg_comparator::can_compare_as_dates(Item *a, Item *b, ulonglong *const_value) } +/* + Retrieves correct TIME value from the given item. + + SYNOPSIS + get_time_value() + thd thread handle + item_arg [in/out] item to retrieve TIME value from + cache_arg [in/out] pointer to place to store the cache item to + warn_item [in] unused + is_null [out] TRUE <=> the item_arg is null + + DESCRIPTION + Retrieves the correct TIME value from given item for comparison by the + compare_datetime() function. + If item's result can be compared as longlong then its int value is used + and a value returned by get_time function is used otherwise. + If an item is a constant one then its value is cached and it isn't + get parsed again. An Item_cache_int object is used for for cached values. + It seamlessly substitutes the original item. The cache item is marked as + non-constant to prevent re-caching it again. + + RETURN + obtained value +*/ + +ulonglong +get_time_value(THD *thd, Item ***item_arg, Item **cache_arg, + Item *warn_item, bool *is_null) +{ + ulonglong value; + Item *item= **item_arg; + MYSQL_TIME ltime; + + if (item->result_as_longlong()) + { + value= item->val_int(); + *is_null= item->null_value; + } + else + { + *is_null= item->get_time(<ime); + value= !*is_null ? TIME_to_ulonglong_datetime(<ime) : 0; + } + /* + Do not cache GET_USER_VAR() function as its const_item() may return TRUE + for the current thread but it still may change during the execution. + */ + if (item->const_item() && cache_arg && (item->type() != Item::FUNC_ITEM || + ((Item_func*)item)->functype() != Item_func::GUSERVAR_FUNC)) + { + Item_cache_int *cache= new Item_cache_int(); + /* Mark the cache as non-const to prevent re-caching. */ + cache->set_used_tables(1); + cache->store(item, value); + *cache_arg= cache; + *item_arg= cache_arg; + } + return value; +} + + int Arg_comparator::set_cmp_func(Item_bool_func2 *owner_arg, Item **a1, Item **a2, Item_result type) @@ -757,8 +818,23 @@ int Arg_comparator::set_cmp_func(Item_bool_func2 *owner_arg, } is_nulls_eq= test(owner && owner->functype() == Item_func::EQUAL_FUNC); func= &Arg_comparator::compare_datetime; + get_value_func= &get_datetime_value; return 0; } + else if (type == STRING_RESULT && (*a)->field_type() == MYSQL_TYPE_TIME && + (*b)->field_type() == MYSQL_TYPE_TIME) + { + /* Compare TIME values as integers. */ + thd= current_thd; + owner= owner_arg; + a_cache= 0; + b_cache= 0; + is_nulls_eq= test(owner && owner->functype() == Item_func::EQUAL_FUNC); + func= &Arg_comparator::compare_datetime; + get_value_func= &get_time_value; + return 0; + } + return set_compare_func(owner_arg, type); } @@ -776,8 +852,10 @@ void Arg_comparator::set_datetime_cmp_func(Item **a1, Item **b1) b_cache= 0; is_nulls_eq= FALSE; func= &Arg_comparator::compare_datetime; + get_value_func= &get_datetime_value; } + /* Retrieves correct DATETIME value from given item. @@ -891,8 +969,8 @@ int Arg_comparator::compare_datetime() bool is_null= FALSE; ulonglong a_value, b_value; - /* Get DATE/DATETIME value of the 'a' item. */ - a_value= get_datetime_value(thd, &a, &a_cache, *b, &is_null); + /* Get DATE/DATETIME/TIME value of the 'a' item. */ + a_value= (*get_value_func)(thd, &a, &a_cache, *b, &is_null); if (!is_nulls_eq && is_null) { if (owner) @@ -900,8 +978,8 @@ int Arg_comparator::compare_datetime() return -1; } - /* Get DATE/DATETIME value of the 'b' item. */ - b_value= get_datetime_value(thd, &b, &b_cache, *a, &is_null); + /* Get DATE/DATETIME/TIME value of the 'b' item. */ + b_value= (*get_value_func)(thd, &b, &b_cache, *a, &is_null); if (is_null) { if (owner) @@ -1771,6 +1849,7 @@ void Item_func_between::fix_length_and_dec() max_length= 1; int i; bool datetime_found= FALSE; + int time_items_found= 0; compare_as_dates= TRUE; THD *thd= current_thd; @@ -1791,17 +1870,19 @@ void Item_func_between::fix_length_and_dec() At least one of items should be a DATE/DATETIME item and other items should return the STRING result. */ - for (i= 0; i < 3; i++) + if (cmp_type == STRING_RESULT) { - if (args[i]->is_datetime()) + for (i= 0; i < 3; i++) { - datetime_found= TRUE; - continue; + if (args[i]->is_datetime()) + { + datetime_found= TRUE; + continue; + } + if (args[i]->field_type() == MYSQL_TYPE_TIME && + args[i]->result_as_longlong()) + time_items_found++; } - if (args[i]->result_type() == STRING_RESULT) - continue; - compare_as_dates= FALSE; - break; } if (!datetime_found) compare_as_dates= FALSE; @@ -1811,6 +1892,11 @@ void Item_func_between::fix_length_and_dec() ge_cmp.set_datetime_cmp_func(args, args + 1); le_cmp.set_datetime_cmp_func(args, args + 2); } + else if (time_items_found == 3) + { + /* Compare TIME items as integers. */ + cmp_type= INT_RESULT; + } else if (args[0]->real_item()->type() == FIELD_ITEM && thd->lex->sql_command != SQLCOM_CREATE_VIEW && thd->lex->sql_command != SQLCOM_SHOW_CREATE) diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index ee36aca069d..fcbacc32d88 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -42,6 +42,8 @@ class Arg_comparator: public Sql_alloc bool is_nulls_eq; // TRUE <=> compare for the EQUAL_FUNC enum enum_date_cmp_type { CMP_DATE_DFLT= 0, CMP_DATE_WITH_DATE, CMP_DATE_WITH_STR, CMP_STR_WITH_DATE }; + ulonglong (*get_value_func)(THD *thd, Item ***item_arg, Item **cache_arg, + Item *warn_item, bool *is_null); public: DTCollation cmp_collation; diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index a376504512f..d54b9961562 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -25,7 +25,7 @@ #include "mysql_priv.h" #include <m_ctype.h> -#include "md5.h" +#include "my_md5.h" #include "sha1.h" #include "my_aes.h" #include <zlib.h> diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 0fa46d231a9..8fe843a2a2d 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -3089,6 +3089,7 @@ Item_func_group_concat::Item_func_group_concat(THD *thd, original(item) { quick_group= item->quick_group; + result.set_charset(collation.collation); } diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 95ff7dfd336..a87efa9e68c 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -2534,11 +2534,8 @@ longlong Item_date_typecast::val_int() { DBUG_ASSERT(fixed == 1); MYSQL_TIME ltime; - if (args[0]->get_date(<ime, TIME_FUZZY_DATE)) - { - null_value= 1; + if ((null_value= args[0]->get_date(<ime, TIME_FUZZY_DATE))) return 0; - } return (longlong) (ltime.year * 10000L + ltime.month * 100 + ltime.day); } diff --git a/sql/log.cc b/sql/log.cc index cd1acb35ece..0bf77d68410 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -3942,7 +3942,7 @@ int MYSQL_BIN_LOG::write_cache(IO_CACHE *cache, bool lock_log, bool sync_log) if (reinit_io_cache(cache, READ_CACHE, 0, 0, 0)) return ER_ERROR_ON_WRITE; - uint bytes= my_b_bytes_in_cache(cache), group, carry, hdr_offs; + uint length= my_b_bytes_in_cache(cache), group, carry, hdr_offs; long val; uchar header[LOG_EVENT_HEADER_LEN]; @@ -3999,7 +3999,7 @@ int MYSQL_BIN_LOG::write_cache(IO_CACHE *cache, bool lock_log, bool sync_log) /* if there is anything to write, process it. */ - if (likely(bytes > 0)) + if (likely(length > 0)) { /* process all event-headers in this (partial) cache. @@ -4008,18 +4008,18 @@ int MYSQL_BIN_LOG::write_cache(IO_CACHE *cache, bool lock_log, bool sync_log) very next iteration, just "eventually"). */ - while (hdr_offs < bytes) + while (hdr_offs < length) { /* partial header only? save what we can get, process once we get the rest. */ - if (hdr_offs + LOG_EVENT_HEADER_LEN > bytes) + if (hdr_offs + LOG_EVENT_HEADER_LEN > length) { - carry= bytes - hdr_offs; + carry= length - hdr_offs; memcpy(header, (char *)cache->read_pos + hdr_offs, carry); - bytes= hdr_offs; + length= hdr_offs; } else { @@ -4039,21 +4039,23 @@ int MYSQL_BIN_LOG::write_cache(IO_CACHE *cache, bool lock_log, bool sync_log) } /* - Adjust hdr_offs. Note that this doesn't mean it will necessarily - be valid in the next iteration; if the current event is very long, - it may take a couple of read-iterations (and subsequent fixings - of hdr_offs) for it to become valid again. - if we had a split header, hdr_offs was already fixed above. + Adjust hdr_offs. Note that it may still point beyond the segment + read in the next iteration; if the current event is very long, + it may take a couple of read-iterations (and subsequent adjustments + of hdr_offs) for it to point into the then-current segment. + If we have a split header (!carry), hdr_offs will be set at the + beginning of the next iteration, overwriting the value we set here: */ - if (carry == 0) - hdr_offs -= bytes; + hdr_offs -= length; } /* Write data to the binary log file */ - if (my_b_write(&log_file, cache->read_pos, bytes)) + if (my_b_write(&log_file, cache->read_pos, length)) return ER_ERROR_ON_WRITE; cache->read_pos=cache->read_end; // Mark buffer used up - } while ((bytes=my_b_fill(cache))); + } while ((length= my_b_fill(cache))); + + DBUG_ASSERT(carry == 0); if (sync_log) flush_and_sync(); diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 40bb2f9509d..7b7bc81957e 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -719,6 +719,26 @@ bool end_active_trans(THD *thd); int end_trans(THD *thd, enum enum_mysql_completiontype completion); Item *negate_expression(THD *thd, Item *expr); + +/* log.cc */ +int vprint_msg_to_log(enum loglevel level, const char *format, va_list args); +void sql_print_error(const char *format, ...) ATTRIBUTE_FORMAT(printf, 1, 2); +void sql_print_warning(const char *format, ...) ATTRIBUTE_FORMAT(printf, 1, 2); +void sql_print_information(const char *format, ...) + ATTRIBUTE_FORMAT(printf, 1, 2); +typedef void (*sql_print_message_func)(const char *format, ...) + ATTRIBUTE_FORMAT(printf, 1, 2); +extern sql_print_message_func sql_print_message_handlers[]; + +int error_log_print(enum loglevel level, const char *format, + va_list args); + +bool slow_log_print(THD *thd, const char *query, uint query_length, + time_t query_start_arg); + +bool general_log_print(THD *thd, enum enum_server_command command, + const char *format,...); + #include "sql_class.h" #include "sql_acl.h" #include "tztime.h" @@ -1617,25 +1637,6 @@ bool init_errmessage(void); #endif /* MYSQL_SERVER */ void sql_perror(const char *message); - -int vprint_msg_to_log(enum loglevel level, const char *format, va_list args); -void sql_print_error(const char *format, ...) ATTRIBUTE_FORMAT(printf, 1, 2); -void sql_print_warning(const char *format, ...) ATTRIBUTE_FORMAT(printf, 1, 2); -void sql_print_information(const char *format, ...) - ATTRIBUTE_FORMAT(printf, 1, 2); -typedef void (*sql_print_message_func)(const char *format, ...) - ATTRIBUTE_FORMAT(printf, 1, 2); -extern sql_print_message_func sql_print_message_handlers[]; - -int error_log_print(enum loglevel level, const char *format, - va_list args); - -bool slow_log_print(THD *thd, const char *query, uint query_length, - time_t query_start_arg); - -bool general_log_print(THD *thd, enum enum_server_command command, - const char *format,...); - bool fn_format_relative_to_data_home(char * to, const char *name, const char *dir, const char *extension); #ifdef MYSQL_SERVER diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 4944c994d3d..948b268d9a3 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -1264,8 +1264,16 @@ int QUICK_RANGE_SELECT::init_ror_merged_scan(bool reuse_handler) thd= head->in_use; if (!(file= head->file->clone(thd->mem_root))) { + /* + Manually set the error flag. Note: there seems to be quite a few + places where a failure could cause the server to "hang" the client by + sending no response to a query. ATM those are not real errors because + the storage engine calls in question happen to never fail with the + existing storage engines. + */ + thd->net.report_error= 1; /* purecov: inspected */ /* Caller will free the memory */ - goto failure; + goto failure; /* purecov: inspected */ } head->column_bitmaps_set(&column_bitmap, &column_bitmap); @@ -7244,6 +7252,11 @@ check_quick_select(PARAM *param,uint idx,SEL_ARG *tree, bool update_tbl_stats) param->is_ror_scan is cleared if the function detects that the key scan is not a Rowid-Ordered Retrieval scan ( see comments for is_key_scan_ror function for description of which key scans are ROR scans) + + RETURN + #records E(#records) for given subtree + HA_POS_ERROR if subtree cannot be used for record retrieval + */ static ha_rows @@ -7445,27 +7458,24 @@ check_quick_keys(PARAM *param, uint idx, SEL_ARG *key_tree, ROR (Rowid Ordered Retrieval) key scan is a key scan that produces ordered sequence of rowids (ha_xxx::cmp_ref is the comparison function) - An index scan is a ROR scan if it is done using a condition in form + This function is needed to handle a practically-important special case: + an index scan is a ROR scan if it is done using a condition in form - "key1_1=c_1 AND ... AND key1_n=c_n" (1) + "key1_1=c_1 AND ... AND key1_n=c_n" where the index is defined on (key1_1, ..., key1_N [,a_1, ..., a_n]) - and the table has a clustered Primary Key - - PRIMARY KEY(a_1, ..., a_n, b1, ..., b_k) with first key parts being - identical to uncovered parts ot the key being scanned (2) - - Scans on HASH indexes are not ROR scans, - any range scan on clustered primary key is ROR scan (3) + and the table has a clustered Primary Key defined as - Check (1) is made in check_quick_keys() - Check (3) is made check_quick_select() - Check (2) is made by this function. + PRIMARY KEY(a_1, ..., a_n, b1, ..., b_k) + + i.e. the first key parts of it are identical to uncovered parts ot the + key being scanned. This function assumes that the index flags do not + include HA_KEY_SCAN_NOT_ROR flag (that is checked elsewhere). RETURN - TRUE If the scan is ROR-scan - FALSE otherwise + TRUE The scan is ROR-scan + FALSE Otherwise */ static bool is_key_scan_ror(PARAM *param, uint keynr, uint8 nparts) diff --git a/sql/set_var.cc b/sql/set_var.cc index d9869ce6809..7f3e808090d 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -616,6 +616,8 @@ sys_var_thd_time_zone sys_time_zone(&vars, "time_zone"); /* Global read-only variable containing hostname */ static sys_var_const_str sys_hostname(&vars, "hostname", glob_hostname); +sys_var_thd_bool sys_keep_files_on_create(&vars, "keep_files_on_create", + &SV::keep_files_on_create); /* Read only variables */ static sys_var_have_variable sys_have_compress(&vars, "have_compress", &have_compress); @@ -2218,9 +2220,9 @@ void sys_var_log_output::set_default(THD *thd, enum_var_type type) { pthread_mutex_lock(&LOCK_global_system_variables); logger.lock(); - logger.init_slow_log(LOG_TABLE); - logger.init_general_log(LOG_TABLE); - *value= LOG_TABLE; + logger.init_slow_log(LOG_FILE); + logger.init_general_log(LOG_FILE); + *value= LOG_FILE; logger.unlock(); pthread_mutex_unlock(&LOCK_global_system_variables); } diff --git a/sql/share/charsets/ascii.xml b/sql/share/charsets/ascii.xml index 97006c53680..068fb84eeae 100644 --- a/sql/share/charsets/ascii.xml +++ b/sql/share/charsets/ascii.xml @@ -97,7 +97,7 @@ 0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 004A 004B 004C 004D 004E 004F 0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 005A 005B 005C 005D 005E 005F 0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 006A 006B 006C 006D 006E 006F -0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007A 007B 007C 007D 007E 0000 +0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007A 007B 007C 007D 007E 007F 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 diff --git a/sql/slave.cc b/sql/slave.cc index d2c5b4fd254..2e8e3f582de 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -27,6 +27,7 @@ #include <my_dir.h> #include <sql_common.h> #include <errmsg.h> +#include <mysys_err.h> #ifdef HAVE_REPLICATION @@ -2204,20 +2205,23 @@ reading event")) if (event_len == packet_error) { uint mysql_error_number= mysql_errno(mysql); - if (mysql_error_number == CR_NET_PACKET_TOO_LARGE) - { + switch (mysql_error_number) { + case CR_NET_PACKET_TOO_LARGE: sql_print_error("\ Log entry on master is longer than max_allowed_packet (%ld) on \ slave. If the entry is correct, restart the server with a higher value of \ max_allowed_packet", thd->variables.max_allowed_packet); goto err; - } - if (mysql_error_number == ER_MASTER_FATAL_ERROR_READING_BINLOG) - { + case ER_MASTER_FATAL_ERROR_READING_BINLOG: sql_print_error(ER(mysql_error_number), mysql_error_number, mysql_error(mysql)); goto err; + case EE_OUTOFMEMORY: + case ER_OUTOFMEMORY: + sql_print_error("\ +Stopping slave I/O thread due to out-of-memory error from master"); + goto err; } if (try_to_reconnect(thd, mysql, mi, &retry_count, suppress_warnings, reconnect_messages[SLAVE_RECON_ACT_EVENT])) diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 6fd57c5a428..0cd46a7c6fb 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -64,11 +64,11 @@ Prelock_error_handler::handle_error(uint sql_errno, if (sql_errno == ER_NO_SUCH_TABLE) { m_handled_errors++; - return TRUE; // 'TRUE', as per coding style + return TRUE; } m_unhandled_errors++; - return FALSE; // 'FALSE', as per coding style + return FALSE; } @@ -3533,7 +3533,7 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags) */ for (tables= *start; tables ;tables= tables->next_global) { - safe_to_ignore_table= FALSE; // 'FALSE', as per coding style + safe_to_ignore_table= FALSE; if (tables->lock_type == TL_WRITE_DEFAULT) { diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 61ed471ea8f..da975ee3103 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -2576,7 +2576,7 @@ extern "C" int thd_non_transactional_update(const MYSQL_THD thd) return(thd->no_trans_update.all); } -extern "C" int thd_binlog_format(const THD *thd) +extern "C" int thd_binlog_format(const MYSQL_THD thd) { return (int) thd->variables.binlog_format; } diff --git a/sql/sql_class.h b/sql/sql_class.h index 7466ab69ed8..71c13e001ee 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -65,11 +65,23 @@ typedef struct st_user_var_events #define RP_LOCK_LOG_IS_ALREADY_LOCKED 1 #define RP_FORCE_ROTATE 2 +/* + The COPY_INFO structure is used by INSERT/REPLACE code. + The schema of the row counting by the INSERT/INSERT ... ON DUPLICATE KEY + UPDATE code: + If a row is inserted then the copied variable is incremented. + If a row is updated by the INSERT ... ON DUPLICATE KEY UPDATE and the + new data differs from the old one then the copied and the updated + variables are incremented. + The touched variable is incremented if a row was touched by the update part + of the INSERT ... ON DUPLICATE KEY UPDATE no matter whether the row + was actually changed or not. +*/ typedef struct st_copy_info { - ha_rows records; - ha_rows deleted; - ha_rows updated; - ha_rows copied; + ha_rows records; /* Number of processed records */ + ha_rows deleted; /* Number of deleted records */ + ha_rows updated; /* Number of updated records */ + ha_rows copied; /* Number of copied records */ ha_rows error_count; ha_rows touched; /* Number of touched records */ enum enum_duplicates handle_duplicates; @@ -177,7 +189,7 @@ public: Table_ident *table, List<Key_part_spec> &ref_cols, uint delete_opt_arg, uint update_opt_arg, uint match_opt_arg) :Key(FOREIGN_KEY, name_arg, &default_key_create_info, 0, cols), - ref_table(table), ref_columns(cols), + ref_table(table), ref_columns(ref_cols), delete_opt(delete_opt_arg), update_opt(update_opt_arg), match_opt(match_opt_arg) {} @@ -303,6 +315,7 @@ struct system_variables my_bool old_mode; my_bool query_cache_wlock_invalidate; my_bool engine_condition_pushdown; + my_bool keep_files_on_create; my_bool ndb_force_send; my_bool ndb_use_copying_alter_table; my_bool ndb_use_exact_count; @@ -1557,11 +1570,27 @@ public: proc_info = old_msg; pthread_mutex_unlock(&mysys_var->mutex); } + + static inline void safe_time(time_t *t) + { + /** + Wrapper around time() which retries on error (-1) + + @details + This is needed because, despite the documentation, time() may fail + in some circumstances. Here we retry time() until it succeeds, and + log the failure so that performance problems related to this can be + identified. + */ + while(unlikely(time(t) == ((time_t) -1))) + sql_print_information("time() failed with %d", errno); + } + inline time_t query_start() { query_start_used=1; return start_time; } - inline void set_time() { if (user_time) start_time=time_after_lock=user_time; else time_after_lock=time(&start_time); } - inline void end_time() { time(&start_time); } + inline void set_time() { if (user_time) start_time=time_after_lock=user_time; else { safe_time(&start_time); time_after_lock= start_time; }} + inline void end_time() { safe_time(&start_time); } inline void set_time(time_t t) { time_after_lock=start_time=user_time=t; } - inline void lock_time() { time(&time_after_lock); } + inline void lock_time() { safe_time(&time_after_lock); } inline ulonglong found_rows(void) { return limit_found_rows; diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 11db88d8f5e..b747c706f75 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -661,7 +661,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, /* Fill in the given fields and dump it to the table file */ - info.records= info.deleted= info.copied= info.updated= 0; + bzero((char*) &info,sizeof(info)); info.ignore= ignore; info.handle_duplicates=duplic; info.update_fields= &update_fields; @@ -1421,7 +1421,12 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) goto before_trg_err; table->file->restore_auto_increment(prev_insert_id); - if ((table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ) || + if (table->next_number_field) + table->file->adjust_next_insert_id_after_explicit_value( + table->next_number_field->val_int()); + info->touched++; + if ((table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ && + !bitmap_is_subset(table->write_set, table->read_set)) || compare_record(table)) { if ((error=table->file->ha_update_row(table->record[1], @@ -1448,9 +1453,6 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) handled separately by THD::arg_of_last_insert_id_function. */ insert_id_for_cur_row= table->file->insert_id_for_cur_row= 0; - if (table->next_number_field) - table->file->adjust_next_insert_id_after_explicit_value( - table->next_number_field->val_int()); trg_error= (table->triggers && table->triggers->process_triggers(thd, TRG_EVENT_UPDATE, TRG_ACTION_AFTER, TRUE)); @@ -1761,18 +1763,18 @@ Delayed_insert *find_handler(THD *thd, TABLE_LIST *table_list) thd->proc_info="waiting for delay_list"; pthread_mutex_lock(&LOCK_delayed_insert); // Protect master list I_List_iterator<Delayed_insert> it(delayed_threads); - Delayed_insert *tmp; - while ((tmp=it++)) + Delayed_insert *di; + while ((di= it++)) { - if (!strcmp(tmp->thd.db, table_list->db) && - !strcmp(table_list->table_name, tmp->table->s->table_name.str)) + if (!strcmp(table_list->db, di->table_list.db) && + !strcmp(table_list->table_name, di->table_list.table_name)) { - tmp->lock(); + di->lock(); break; } } pthread_mutex_unlock(&LOCK_delayed_insert); // For unlink from list - return tmp; + return di; } @@ -1798,21 +1800,41 @@ Delayed_insert *find_handler(THD *thd, TABLE_LIST *table_list) Two latter cases indicate a request for lock upgrade. XXX: why do we regard INSERT DELAYED into a view as an error and - do not simply a lock upgrade? + do not simply perform a lock upgrade? + + TODO: The approach with using two mutexes to work with the + delayed thread list -- LOCK_delayed_insert and + LOCK_delayed_create -- is redundant, and we only need one of + them to protect the list. The reason we have two locks is that + we do not want to block look-ups in the list while we're waiting + for the newly created thread to open the delayed table. However, + this wait itself is redundant -- we always call get_local_table + later on, and there wait again until the created thread acquires + a table lock. + + As is redundant the concept of locks_in_memory, since we already + have another counter with similar semantics - tables_in_use, + both of them are devoted to counting the number of producers for + a given consumer (delayed insert thread), only at different + stages of producer-consumer relationship. + + 'dead' and 'status' variables in Delayed_insert are redundant + too, since there is already 'di->thd.killed' and + di->stacked_inserts. */ static bool delayed_get_table(THD *thd, TABLE_LIST *table_list) { int error; - Delayed_insert *tmp; + Delayed_insert *di; DBUG_ENTER("delayed_get_table"); /* Must be set in the parser */ DBUG_ASSERT(table_list->db); /* Find the thread which handles this table. */ - if (!(tmp=find_handler(thd,table_list))) + if (!(di= find_handler(thd, table_list))) { /* No match. Create a new thread to handle the table, but @@ -1826,9 +1848,9 @@ bool delayed_get_table(THD *thd, TABLE_LIST *table_list) The first search above was done without LOCK_delayed_create. Another thread might have created the handler in between. Search again. */ - if (! (tmp= find_handler(thd, table_list))) + if (! (di= find_handler(thd, table_list))) { - if (!(tmp=new Delayed_insert())) + if (!(di= new Delayed_insert())) { my_error(ER_OUTOFMEMORY,MYF(0),sizeof(Delayed_insert)); thd->fatal_error(); @@ -1837,28 +1859,30 @@ bool delayed_get_table(THD *thd, TABLE_LIST *table_list) pthread_mutex_lock(&LOCK_thread_count); thread_count++; pthread_mutex_unlock(&LOCK_thread_count); - tmp->thd.set_db(table_list->db, strlen(table_list->db)); - tmp->thd.query= my_strdup(table_list->table_name,MYF(MY_WME)); - if (tmp->thd.db == NULL || tmp->thd.query == NULL) + di->thd.set_db(table_list->db, strlen(table_list->db)); + di->thd.query= my_strdup(table_list->table_name, MYF(MY_WME)); + if (di->thd.db == NULL || di->thd.query == NULL) { /* The error is reported */ - delete tmp; + delete di; thd->fatal_error(); goto end_create; } - tmp->table_list= *table_list; // Needed to open table - tmp->table_list.alias= tmp->table_list.table_name= tmp->thd.query; - tmp->lock(); - pthread_mutex_lock(&tmp->mutex); - if ((error=pthread_create(&tmp->thd.real_id,&connection_attrib, - handle_delayed_insert,(void*) tmp))) + di->table_list= *table_list; // Needed to open table + /* Replace volatile strings with local copies */ + di->table_list.alias= di->table_list.table_name= di->thd.query; + di->table_list.db= di->thd.db; + di->lock(); + pthread_mutex_lock(&di->mutex); + if ((error= pthread_create(&di->thd.real_id, &connection_attrib, + handle_delayed_insert, (void*) di))) { DBUG_PRINT("error", ("Can't create thread to handle delayed insert (error %d)", error)); - pthread_mutex_unlock(&tmp->mutex); - tmp->unlock(); - delete tmp; + pthread_mutex_unlock(&di->mutex); + di->unlock(); + delete di; my_error(ER_CANT_CREATE_THREAD, MYF(0), error); thd->fatal_error(); goto end_create; @@ -1866,15 +1890,15 @@ bool delayed_get_table(THD *thd, TABLE_LIST *table_list) /* Wait until table is open */ thd->proc_info="waiting for handler open"; - while (!tmp->thd.killed && !tmp->table && !thd->killed) + while (!di->thd.killed && !di->table && !thd->killed) { - pthread_cond_wait(&tmp->cond_client,&tmp->mutex); + pthread_cond_wait(&di->cond_client, &di->mutex); } - pthread_mutex_unlock(&tmp->mutex); + pthread_mutex_unlock(&di->mutex); thd->proc_info="got old table"; - if (tmp->thd.killed) + if (di->thd.killed) { - if (tmp->thd.net.report_error) + if (di->thd.net.report_error) { /* Copy the error message. Note that we don't treat fatal @@ -1882,31 +1906,34 @@ bool delayed_get_table(THD *thd, TABLE_LIST *table_list) main thread. Use of my_message will enable stored procedures continue handlers. */ - my_message(tmp->thd.net.last_errno, tmp->thd.net.last_error, + my_message(di->thd.net.last_errno, di->thd.net.last_error, MYF(0)); } - tmp->unlock(); + di->unlock(); goto end_create; } if (thd->killed) { - tmp->unlock(); + di->unlock(); goto end_create; } + pthread_mutex_lock(&LOCK_delayed_insert); + delayed_threads.append(di); + pthread_mutex_unlock(&LOCK_delayed_insert); } pthread_mutex_unlock(&LOCK_delayed_create); } - pthread_mutex_lock(&tmp->mutex); - table_list->table= tmp->get_local_table(thd); - pthread_mutex_unlock(&tmp->mutex); + pthread_mutex_lock(&di->mutex); + table_list->table= di->get_local_table(thd); + pthread_mutex_unlock(&di->mutex); if (table_list->table) { DBUG_ASSERT(thd->net.report_error == 0); - thd->di=tmp; + thd->di= di; } /* Unlock the delayed insert object after its last access. */ - tmp->unlock(); + di->unlock(); DBUG_RETURN((table_list->table == NULL)); end_create: @@ -1936,7 +1963,7 @@ TABLE *Delayed_insert::get_local_table(THD* client_thd) my_ptrdiff_t adjust_ptrs; Field **field,**org_field, *found_next_number_field; TABLE *copy; - TABLE_SHARE *share= table->s; + TABLE_SHARE *share; uchar *bitmap; DBUG_ENTER("Delayed_insert::get_local_table"); @@ -1960,6 +1987,7 @@ TABLE *Delayed_insert::get_local_table(THD* client_thd) goto error; } } + share= table->s; /* Allocate memory for the TABLE object, the field pointers array, and @@ -2155,26 +2183,26 @@ void kill_delayed_threads(void) VOID(pthread_mutex_lock(&LOCK_delayed_insert)); // For unlink from list I_List_iterator<Delayed_insert> it(delayed_threads); - Delayed_insert *tmp; - while ((tmp=it++)) + Delayed_insert *di; + while ((di= it++)) { - tmp->thd.killed= THD::KILL_CONNECTION; - if (tmp->thd.mysys_var) + di->thd.killed= THD::KILL_CONNECTION; + if (di->thd.mysys_var) { - pthread_mutex_lock(&tmp->thd.mysys_var->mutex); - if (tmp->thd.mysys_var->current_cond) + pthread_mutex_lock(&di->thd.mysys_var->mutex); + if (di->thd.mysys_var->current_cond) { /* We need the following test because the main mutex may be locked in handle_delayed_insert() */ - if (&tmp->mutex != tmp->thd.mysys_var->current_mutex) - pthread_mutex_lock(tmp->thd.mysys_var->current_mutex); - pthread_cond_broadcast(tmp->thd.mysys_var->current_cond); - if (&tmp->mutex != tmp->thd.mysys_var->current_mutex) - pthread_mutex_unlock(tmp->thd.mysys_var->current_mutex); + if (&di->mutex != di->thd.mysys_var->current_mutex) + pthread_mutex_lock(di->thd.mysys_var->current_mutex); + pthread_cond_broadcast(di->thd.mysys_var->current_cond); + if (&di->mutex != di->thd.mysys_var->current_mutex) + pthread_mutex_unlock(di->thd.mysys_var->current_mutex); } - pthread_mutex_unlock(&tmp->thd.mysys_var->mutex); + pthread_mutex_unlock(&di->thd.mysys_var->mutex); } } VOID(pthread_mutex_unlock(&LOCK_delayed_insert)); // For unlink from list @@ -2248,11 +2276,6 @@ pthread_handler_t handle_delayed_insert(void *arg) } di->table->copy_blobs=1; - /* One can now use this */ - pthread_mutex_lock(&LOCK_delayed_insert); - delayed_threads.append(di); - pthread_mutex_unlock(&LOCK_delayed_insert); - /* Tell client that the thread is initialized */ pthread_cond_signal(&di->cond_client); diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 9f69e7dee05..e493dc05047 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -124,7 +124,7 @@ Lex_input_stream::Lex_input_stream(THD *thd, m_tok_start_prev(NULL), m_buf(buffer), m_buf_length(length), - m_echo(true), + m_echo(TRUE), m_cpp_tok_start(NULL), m_cpp_tok_start_prev(NULL), m_cpp_tok_end(NULL), @@ -1200,7 +1200,7 @@ int MYSQLlex(void *arg, void *yythd) { lip->in_comment= DISCARD_COMMENT; /* Accept '/' '*' '!', but do not keep this marker. */ - lip->set_echo(false); + lip->set_echo(FALSE); lip->yySkip(); lip->yySkip(); lip->yySkip(); @@ -1233,7 +1233,7 @@ int MYSQLlex(void *arg, void *yythd) if (version <= MYSQL_VERSION_ID) { /* Expand the content of the special comment as real code */ - lip->set_echo(true); + lip->set_echo(TRUE); state=MY_LEX_START; break; } @@ -1241,7 +1241,7 @@ int MYSQLlex(void *arg, void *yythd) else { state=MY_LEX_START; - lip->set_echo(true); + lip->set_echo(TRUE); break; } } @@ -1261,7 +1261,7 @@ int MYSQLlex(void *arg, void *yythd) if (! lip->eof()) lip->yySkip(); // remove last '/' state = MY_LEX_START; // Try again - lip->set_echo(true); + lip->set_echo(TRUE); break; case MY_LEX_END_LONG_COMMENT: if ((lip->in_comment != NO_COMMENT) && lip->yyPeek() == '/') @@ -1272,7 +1272,7 @@ int MYSQLlex(void *arg, void *yythd) lip->set_echo(lip->in_comment == PRESERVE_COMMENT); lip->yySkipn(2); /* And start recording the tokens again */ - lip->set_echo(true); + lip->set_echo(TRUE); lip->in_comment=NO_COMMENT; state=MY_LEX_START; } @@ -1297,7 +1297,7 @@ int MYSQLlex(void *arg, void *yythd) lip->found_semicolon= lip->get_ptr(); thd->server_status|= SERVER_MORE_RESULTS_EXISTS; lip->next_state= MY_LEX_END; - lip->set_echo(true); + lip->set_echo(TRUE); return (END_OF_INPUT); } state= MY_LEX_CHAR; // Return ';' @@ -1309,9 +1309,9 @@ int MYSQLlex(void *arg, void *yythd) if (lip->eof()) { lip->yyUnget(); // Reject the last '\0' - lip->set_echo(false); + lip->set_echo(FALSE); lip->yySkip(); - lip->set_echo(true); + lip->set_echo(TRUE); lip->next_state=MY_LEX_END; // Mark for next loop return(END_OF_INPUT); } diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 4ac59fbacde..9ac7f2835f0 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -1239,19 +1239,19 @@ public: } /** Get the raw query buffer. */ - const char* get_buf() + const char *get_buf() { return m_buf; } /** Get the pre-processed query buffer. */ - const char* get_cpp_buf() + const char *get_cpp_buf() { return m_cpp_buf; } /** Get the end of the raw query buffer. */ - const char* get_end_of_query() + const char *get_end_of_query() { return m_end_of_query; } @@ -1279,43 +1279,43 @@ public: } /** Get the token start position, in the raw buffer. */ - const char* get_tok_start() + const char *get_tok_start() { return m_tok_start; } /** Get the token start position, in the pre-processed buffer. */ - const char* get_cpp_tok_start() + const char *get_cpp_tok_start() { return m_cpp_tok_start; } /** Get the token end position, in the raw buffer. */ - const char* get_tok_end() + const char *get_tok_end() { return m_tok_end; } /** Get the token end position, in the pre-processed buffer. */ - const char* get_cpp_tok_end() + const char *get_cpp_tok_end() { return m_cpp_tok_end; } /** Get the previous token start position, in the raw buffer. */ - const char* get_tok_start_prev() + const char *get_tok_start_prev() { return m_tok_start_prev; } /** Get the current stream pointer, in the raw buffer. */ - const char* get_ptr() + const char *get_ptr() { return m_ptr; } /** Get the current stream pointer, in the pre-processed buffer. */ - const char* get_cpp_ptr() + const char *get_cpp_ptr() { return m_cpp_ptr; } @@ -1365,22 +1365,22 @@ public: private: /** Pointer to the current position in the raw input stream. */ - const char* m_ptr; + const char *m_ptr; /** Starting position of the last token parsed, in the raw buffer. */ - const char* m_tok_start; + const char *m_tok_start; /** Ending position of the previous token parsed, in the raw buffer. */ - const char* m_tok_end; + const char *m_tok_end; /** End of the query text in the input stream, in the raw buffer. */ - const char* m_end_of_query; + const char *m_end_of_query; /** Starting position of the previous token parsed, in the raw buffer. */ - const char* m_tok_start_prev; + const char *m_tok_start_prev; /** Begining of the query text in the input stream, in the raw buffer. */ - const char* m_buf; + const char *m_buf; /** Length of the raw buffer. */ uint m_buf_length; @@ -1389,28 +1389,28 @@ private: bool m_echo; /** Pre-processed buffer. */ - char* m_cpp_buf; + char *m_cpp_buf; /** Pointer to the current position in the pre-processed input stream. */ - char* m_cpp_ptr; + char *m_cpp_ptr; /** Starting position of the last token parsed, in the pre-processed buffer. */ - const char* m_cpp_tok_start; + const char *m_cpp_tok_start; /** Starting position of the previous token parsed, in the pre-procedded buffer. */ - const char* m_cpp_tok_start_prev; + const char *m_cpp_tok_start_prev; /** Ending position of the previous token parsed, in the pre-processed buffer. */ - const char* m_cpp_tok_end; + const char *m_cpp_tok_end; /** UTF8-body buffer created during parsing. */ char *m_body_utf8; @@ -1433,7 +1433,7 @@ public: Position of ';' in the stream, to delimit multiple queries. This delimiter is in the raw buffer. */ - const char* found_semicolon; + const char *found_semicolon; /** SQL_MODE = IGNORE_SPACE. */ bool ignore_space; diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index 0584bb12b9e..5cfb46a99ab 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -36,7 +36,7 @@ #include "mysql_priv.h" #include <errno.h> #include <m_ctype.h> -#include "md5.h" +#include "my_md5.h" #ifdef WITH_PARTITION_STORAGE_ENGINE #include "ha_partition.h" diff --git a/sql/sql_select.cc b/sql/sql_select.cc index dc8a10a013f..be6d1f74852 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -8703,9 +8703,15 @@ static void restore_prev_nj_state(JOIN_TAB *last) { TABLE_LIST *last_emb= last->table->pos_in_table_list->embedding; JOIN *join= last->join; - while (last_emb && !(--last_emb->nested_join->counter)) + while (last_emb) { - join->cur_embedding_map &= last_emb->nested_join->nj_map; + if (!(--last_emb->nested_join->counter)) + join->cur_embedding_map&= ~last_emb->nested_join->nj_map; + else if (last_emb->nested_join->join_list.elements-1 == + last_emb->nested_join->counter) + join->cur_embedding_map|= last_emb->nested_join->nj_map; + else + break; last_emb= last_emb->embedding; } } diff --git a/sql/sql_show.cc b/sql/sql_show.cc index c6bf816b290..5b8cb93baab 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -5905,12 +5905,17 @@ int initialize_schema_table(st_plugin_int *plugin) schema_table->idx_field1= -1, schema_table->idx_field2= -1; + /* Make the name available to the init() function. */ + schema_table->table_name= plugin->name.str; + if (plugin->plugin->init(schema_table)) { sql_print_error("Plugin '%s' init function returned error.", plugin->name.str); goto err; } + + /* Make sure the plugin name is not set inside the init() function. */ schema_table->table_name= plugin->name.str; } diff --git a/sql/sql_table.cc b/sql/sql_table.cc index c603f1ad77f..dc3e72554fa 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -4655,8 +4655,11 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table, DBUG_EXECUTE_IF("sleep_create_like_before_ha_create", my_sleep(6000000);); dst_path[dst_path_length - reg_ext_length]= '\0'; // Remove .frm + if (thd->variables.keep_files_on_create) + create_info->options|= HA_CREATE_KEEP_FILES; err= ha_create_table(thd, dst_path, db, table_name, create_info, 1); VOID(pthread_mutex_unlock(&LOCK_open)); + if (create_info->options & HA_LEX_CREATE_TMP_TABLE) { if (err || !open_temporary_table(thd, dst_path, db, table_name, 1)) diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 873aa6cfbeb..1016a23b5ae 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -300,6 +300,17 @@ int mysql_update(THD *thd, if (cond_value == Item::COND_FALSE) limit= 0; // Impossible WHERE } + + /* + If a timestamp field settable on UPDATE is present then to avoid wrong + update force the table handler to retrieve write-only fields to be able + to compare records and detect data change. + */ + if (table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ && + table->timestamp_field && + (table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_UPDATE || + table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_BOTH)) + bitmap_union(table->read_set, table->write_set); // Don't count on usage of 'only index' when calculating which key to use table->covering_keys.clear_all(); diff --git a/sql/table.cc b/sql/table.cc index 5ac43343934..a58f59d3a75 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -19,7 +19,7 @@ #include "mysql_priv.h" #include "sql_trigger.h" #include <m_ctype.h> -#include "md5.h" +#include "my_md5.h" /* Functions defined in this file */ diff --git a/sql/unireg.cc b/sql/unireg.cc index 57847bc70c6..f9e8e54439a 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -355,6 +355,8 @@ int rea_create_table(THD *thd, const char *path, // Make sure mysql_create_frm din't remove extension DBUG_ASSERT(*fn_rext(frm_name)); + if (thd->variables.keep_files_on_create) + create_info->options|= HA_CREATE_KEEP_FILES; if (file->create_handler_files(path, NULL, CHF_CREATE_FLAG, create_info)) goto err_handler; if (!create_info->frm_only && ha_create_table(thd, path, db, table_name, diff --git a/storage/csv/ha_tina.cc b/storage/csv/ha_tina.cc index 07bd28f8e65..34c1fcde58d 100644 --- a/storage/csv/ha_tina.cc +++ b/storage/csv/ha_tina.cc @@ -163,6 +163,7 @@ static TINA_SHARE *get_share(const char *table_name, TABLE *table) share->rows_recorded= 0; share->update_file_opened= FALSE; share->tina_write_opened= FALSE; + share->data_file_version= 0; strmov(share->table_name, table_name); fn_format(share->data_file_name, table_name, "", CSV_EXT, MY_REPLACE_EXT|MY_UNPACK_FILENAME); @@ -440,7 +441,7 @@ ha_tina::ha_tina(handlerton *hton, TABLE_SHARE *table_arg) */ current_position(0), next_position(0), local_saved_data_file_length(0), file_buff(0), chain_alloced(0), chain_size(DEFAULT_CHAIN_LENGTH), - records_is_known(0) + local_data_file_version(0), records_is_known(0) { /* Set our original buffers from pre-allocated memory */ buffer.set((char*)byte_buffer, IO_SIZE, &my_charset_bin); @@ -815,6 +816,7 @@ int ha_tina::open(const char *name, int mode, uint open_options) DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE); } + local_data_file_version= share->data_file_version; if ((data_file= my_open(share->data_file_name, O_RDONLY, MYF(0))) == -1) DBUG_RETURN(0); @@ -985,6 +987,33 @@ int ha_tina::delete_row(const uchar * buf) } +/** + @brief Initialize the data file. + + @details Compare the local version of the data file with the shared one. + If they differ, there are some changes behind and we have to reopen + the data file to make the changes visible. + Call @c file_buff->init_buff() at the end to read the beginning of the + data file into buffer. + + @retval 0 OK. + @retval 1 There was an error. +*/ + +int ha_tina::init_data_file() +{ + if (local_data_file_version != share->data_file_version) + { + local_data_file_version= share->data_file_version; + if (my_close(data_file, MYF(0)) || + (data_file= my_open(share->data_file_name, O_RDONLY, MYF(0))) == -1) + return 1; + } + file_buff->init_buff(data_file); + return 0; +} + + /* All table scans call this first. The order of a table scan is: @@ -1021,9 +1050,8 @@ int ha_tina::rnd_init(bool scan) DBUG_ENTER("ha_tina::rnd_init"); /* set buffer to the beginning of the file */ - file_buff->init_buff(data_file); - if (share->crashed) - DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE); + if (share->crashed || init_data_file()) + DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE); current_position= next_position= 0; stats.records= 0; @@ -1247,6 +1275,16 @@ int ha_tina::rnd_end() if (((data_file= my_open(share->data_file_name, O_RDONLY, MYF(0))) == -1)) DBUG_RETURN(-1); /* + As we reopened the data file, increase share->data_file_version + in order to force other threads waiting on a table lock and + have already opened the table to reopen the data file. + That makes the latest changes become visible to them. + Update local_data_file_version as no need to reopen it in the + current thread. + */ + share->data_file_version++; + local_data_file_version= share->data_file_version; + /* The datafile is consistent at this point and the write filedes is closed, so nothing worrying will happen to it in case of a crash. Here we record this fact to the meta-file. @@ -1308,7 +1346,8 @@ int ha_tina::repair(THD* thd, HA_CHECK_OPT* check_opt) DBUG_RETURN(HA_ERR_OUT_OF_MEM); /* position buffer to the start of the file */ - file_buff->init_buff(data_file); + if (init_data_file()) + DBUG_RETURN(HA_ERR_CRASHED_ON_REPAIR); /* Local_saved_data_file_length is initialized during the lock phase. @@ -1480,7 +1519,8 @@ int ha_tina::check(THD* thd, HA_CHECK_OPT* check_opt) DBUG_RETURN(HA_ERR_OUT_OF_MEM); /* position buffer to the start of the file */ - file_buff->init_buff(data_file); + if (init_data_file()) + DBUG_RETURN(HA_ERR_CRASHED); /* Local_saved_data_file_length is initialized during the lock phase. diff --git a/storage/csv/ha_tina.h b/storage/csv/ha_tina.h index 2e43f1a2307..5bb3e9a79a0 100644 --- a/storage/csv/ha_tina.h +++ b/storage/csv/ha_tina.h @@ -49,6 +49,7 @@ typedef struct st_tina_share { File tina_write_filedes; /* File handler for readers */ bool crashed; /* Meta file is crashed */ ha_rows rows_recorded; /* Number of rows in tables */ + uint data_file_version; /* Version of the data file used */ } TINA_SHARE; struct tina_set { @@ -79,12 +80,14 @@ class ha_tina: public handler tina_set *chain_ptr; uchar chain_alloced; uint32 chain_size; + uint local_data_file_version; /* Saved version of the data file used */ bool records_is_known; private: bool get_write_pos(off_t *end_pos, tina_set *closest_hole); int open_update_temp_file_if_needed(); int init_tina_writer(); + int init_data_file(); public: ha_tina(handlerton *hton, TABLE_SHARE *table_arg); diff --git a/storage/heap/ha_heap.cc b/storage/heap/ha_heap.cc index 86bc2cc516e..f2b67f20c57 100644 --- a/storage/heap/ha_heap.cc +++ b/storage/heap/ha_heap.cc @@ -125,6 +125,26 @@ int ha_heap::close(void) /* + Create a copy of this table + + DESCRIPTION + Do same as default implementation but use file->s->name instead of + table->s->path. This is needed by Windows where the clone() call sees + '/'-delimited path in table->s->path, while ha_peap::open() was called + with '\'-delimited path. +*/ + +handler *ha_heap::clone(MEM_ROOT *mem_root) +{ + handler *new_handler= get_new_handler(table->s, mem_root, table->s->db_type()); + if (new_handler && !new_handler->ha_open(table, file->s->name, table->db_stat, + HA_OPEN_IGNORE_IF_LOCKED)) + return new_handler; + return NULL; /* purecov: inspected */ +} + + +/* Compute which keys to use for scanning SYNOPSIS diff --git a/storage/heap/ha_heap.h b/storage/heap/ha_heap.h index f41c710716d..c414383a4aa 100644 --- a/storage/heap/ha_heap.h +++ b/storage/heap/ha_heap.h @@ -32,6 +32,7 @@ class ha_heap: public handler public: ha_heap(handlerton *hton, TABLE_SHARE *table); ~ha_heap() {} + handler *clone(MEM_ROOT *mem_root); const char *table_type() const { return (table->in_use->variables.sql_mode & MODE_MYSQL323) ? @@ -55,8 +56,8 @@ public: ulong index_flags(uint inx, uint part, bool all_parts) const { return ((table_share->key_info[inx].algorithm == HA_KEY_ALG_BTREE) ? - HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER | HA_READ_RANGE : - HA_ONLY_WHOLE_INDEX); + HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER | HA_READ_RANGE : + HA_ONLY_WHOLE_INDEX | HA_KEY_SCAN_NOT_ROR); } const key_map *keys_to_use_for_scanning() { return &btree_keys; } uint max_supported_keys() const { return MAX_KEY; } @@ -108,9 +109,7 @@ public: enum thr_lock_type lock_type); int cmp_ref(const uchar *ref1, const uchar *ref2) { - HEAP_PTR ptr1=*(HEAP_PTR*)ref1; - HEAP_PTR ptr2=*(HEAP_PTR*)ref2; - return ptr1 < ptr2? -1 : (ptr1 > ptr2? 1 : 0); + return memcmp(ref1, ref2, sizeof(HEAP_PTR)); } bool check_if_incompatible_data(HA_CREATE_INFO *info, uint table_changes); private: diff --git a/storage/innobase/Makefile.am b/storage/innobase/Makefile.am index 62c0f8e817c..0b23ae74f9e 100644 --- a/storage/innobase/Makefile.am +++ b/storage/innobase/Makefile.am @@ -25,102 +25,146 @@ INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/include \ -I$(top_srcdir)/sql \ -I$(srcdir) -AUTOMAKE_OPTIONS = foreign -TAR = gtar +DEFS = @DEFS@ -noinst_HEADERS = -SUBDIRS = os ut btr buf data dict dyn eval fil fsp fut \ - ha ibuf lock log mach mem mtr page \ - handler \ - pars que read rem row srv sync thr trx usr +noinst_HEADERS = include/btr0btr.h include/btr0btr.ic \ + include/btr0cur.h include/btr0cur.ic \ + include/btr0pcur.h include/btr0pcur.ic \ + include/btr0sea.h include/btr0sea.ic \ + include/btr0types.h include/buf0buf.h \ + include/buf0buf.ic include/buf0flu.h \ + include/buf0flu.ic include/buf0lru.h \ + include/buf0lru.ic include/buf0rea.h \ + include/buf0types.h include/data0data.h \ + include/data0data.ic include/data0type.h \ + include/data0type.ic include/data0types.h \ + include/db0err.h include/dict0boot.h \ + include/dict0boot.ic include/dict0crea.h \ + include/dict0crea.ic include/dict0dict.h \ + include/dict0dict.ic include/dict0load.h \ + include/dict0load.ic include/dict0mem.h \ + include/dict0mem.ic include/dict0types.h \ + include/dyn0dyn.h include/dyn0dyn.ic \ + include/eval0eval.h include/eval0eval.ic \ + include/eval0proc.h include/eval0proc.ic \ + include/fil0fil.h include/fsp0fsp.h \ + include/fsp0fsp.ic include/fut0fut.h \ + include/fut0fut.ic include/fut0lst.h \ + include/fut0lst.ic include/ha0ha.h \ + include/ha0ha.ic include/hash0hash.h \ + include/hash0hash.ic include/ibuf0ibuf.h \ + include/ibuf0ibuf.ic include/ibuf0types.h \ + include/lock0lock.h include/lock0lock.ic \ + include/lock0types.h include/log0log.h \ + include/log0log.ic include/log0recv.h \ + include/log0recv.ic include/mach0data.h \ + include/mach0data.ic include/mem0dbg.h \ + include/mem0dbg.ic mem/mem0dbg.c \ + include/mem0mem.h include/mem0mem.ic \ + include/mem0pool.h include/mem0pool.ic \ + include/mtr0log.h include/mtr0log.ic \ + include/mtr0mtr.h include/mtr0mtr.ic \ + include/mtr0types.h include/os0file.h \ + include/os0proc.h include/os0proc.ic \ + include/os0sync.h include/os0sync.ic \ + include/os0thread.h include/os0thread.ic \ + include/page0cur.h include/page0cur.ic \ + include/page0page.h include/page0page.ic \ + include/page0types.h include/pars0grm.h \ + include/pars0opt.h include/pars0opt.ic \ + include/pars0pars.h include/pars0pars.ic \ + include/pars0sym.h include/pars0sym.ic \ + include/pars0types.h include/que0que.h \ + include/que0que.ic include/que0types.h \ + include/read0read.h include/read0read.ic \ + include/read0types.h include/rem0cmp.h \ + include/rem0cmp.ic include/rem0rec.h \ + include/rem0rec.ic include/rem0types.h \ + include/row0ins.h include/row0ins.ic \ + include/row0mysql.h include/row0mysql.ic \ + include/row0purge.h include/row0purge.ic \ + include/row0row.h include/row0row.ic \ + include/row0sel.h include/row0sel.ic \ + include/row0types.h include/row0uins.h \ + include/row0uins.ic include/row0umod.h \ + include/row0umod.ic include/row0undo.h \ + include/row0undo.ic include/row0upd.h \ + include/row0upd.ic include/row0vers.h \ + include/row0vers.ic include/srv0que.h \ + include/srv0srv.h include/srv0srv.ic \ + include/srv0start.h include/sync0arr.h \ + include/sync0arr.ic include/sync0rw.h \ + include/sync0rw.ic include/sync0sync.h \ + include/sync0sync.ic include/sync0types.h \ + include/thr0loc.h include/thr0loc.ic \ + include/trx0purge.h include/trx0purge.ic \ + include/trx0rec.h include/trx0rec.ic \ + include/trx0roll.h include/trx0roll.ic \ + include/trx0rseg.h include/trx0rseg.ic \ + include/trx0sys.h include/trx0sys.ic \ + include/trx0trx.h include/trx0trx.ic \ + include/trx0types.h include/trx0undo.h \ + include/trx0undo.ic include/trx0xa.h \ + include/univ.i include/usr0sess.h \ + include/usr0sess.ic include/usr0types.h \ + include/ut0byte.h include/ut0byte.ic \ + include/ut0dbg.h include/ut0lst.h \ + include/ut0mem.h include/ut0mem.ic \ + include/ut0rnd.h include/ut0rnd.ic \ + include/ut0sort.h include/ut0ut.h \ + include/ut0ut.ic include/ut0vec.h \ + include/ut0vec.ic include/ut0list.h \ + include/ut0list.ic include/ut0wqueue.h \ + include/ha_prototypes.h handler/ha_innodb.h -EXTRA_DIST = include/btr0btr.h include/btr0btr.ic include/btr0cur.h include/btr0cur.ic \ - include/btr0pcur.h include/btr0pcur.ic include/btr0sea.h include/btr0sea.ic \ - include/btr0types.h \ - include/buf0buf.h include/buf0buf.ic include/buf0flu.h include/buf0flu.ic \ - include/buf0lru.h include/buf0lru.ic include/buf0rea.h include/buf0types.h \ - include/data0data.h include/data0data.ic include/data0type.h include/data0type.ic \ - include/data0types.h include/db0err.h \ - include/dict0boot.h include/dict0boot.ic include/dict0crea.h include/dict0crea.ic \ - include/dict0dict.h include/dict0dict.ic include/dict0load.h include/dict0load.ic \ - include/dict0mem.h include/dict0mem.ic include/dict0types.h \ - include/dyn0dyn.h include/dyn0dyn.ic \ - include/eval0eval.h include/eval0eval.ic include/eval0proc.h include/eval0proc.ic \ - include/fil0fil.h include/fsp0fsp.h include/fsp0fsp.ic \ - include/fut0fut.h include/fut0fut.ic include/fut0lst.h include/fut0lst.ic \ - include/ha0ha.h include/ha0ha.ic include/hash0hash.h include/hash0hash.ic \ - include/ibuf0ibuf.h include/ibuf0ibuf.ic include/ibuf0types.h \ - include/lock0lock.h include/lock0lock.ic include/lock0types.h \ - include/log0log.h include/log0log.ic include/log0recv.h include/log0recv.ic \ - include/mach0data.h include/mach0data.ic include/mem0dbg.h include/mem0dbg.ic \ - include/mem0mem.h include/mem0mem.ic include/mem0pool.h include/mem0pool.ic \ - include/mtr0log.h include/mtr0log.ic include/mtr0mtr.h include/mtr0mtr.ic \ - include/mtr0types.h include/os0file.h \ - include/os0proc.h include/os0proc.ic include/os0sync.h include/os0sync.ic \ - include/os0thread.h include/os0thread.ic \ - include/page0cur.h include/page0cur.ic include/page0page.h include/page0page.ic \ - include/page0types.h \ - include/pars0grm.h include/pars0opt.h include/pars0opt.ic \ - include/pars0pars.h include/pars0pars.ic include/pars0sym.h include/pars0sym.ic \ - include/pars0types.h \ - include/que0que.h include/que0que.ic include/que0types.h \ - include/read0read.h include/read0read.ic include/read0types.h \ - include/rem0cmp.h include/rem0cmp.ic include/rem0rec.h include/rem0rec.ic \ - include/rem0types.h \ - include/row0ins.h include/row0ins.ic include/row0mysql.h include/row0mysql.ic \ - include/row0purge.h include/row0purge.ic include/row0row.h include/row0row.ic \ - include/row0sel.h include/row0sel.ic include/row0types.h \ - include/row0uins.h include/row0uins.ic include/row0umod.h include/row0umod.ic \ - include/row0undo.h include/row0undo.ic include/row0upd.h include/row0upd.ic \ - include/row0vers.h include/row0vers.ic \ - include/srv0que.h include/srv0srv.h include/srv0srv.ic include/srv0start.h \ - include/sync0arr.h include/sync0arr.ic include/sync0rw.h include/sync0rw.ic \ - include/sync0sync.h include/sync0sync.ic include/sync0types.h \ - include/thr0loc.h include/thr0loc.ic \ - include/trx0purge.h include/trx0purge.ic include/trx0rec.h include/trx0rec.ic \ - include/trx0roll.h include/trx0roll.ic include/trx0rseg.h include/trx0rseg.ic \ - include/trx0sys.h include/trx0sys.ic include/trx0trx.h include/trx0trx.ic \ - include/trx0types.h include/trx0undo.h include/trx0undo.ic include/trx0xa.h \ - include/univ.i include/usr0sess.h include/usr0sess.ic include/usr0types.h \ - include/ut0byte.h include/ut0byte.ic include/ut0dbg.h include/ut0lst.h \ - include/ut0mem.h include/ut0mem.ic include/ut0rnd.h include/ut0rnd.ic \ - handler/ha_innodb.h \ - include/ut0sort.h include/ut0ut.h include/ut0ut.ic include/ut0vec.h include/ut0vec.ic include/ha_prototypes.h \ - include/ut0list.h include/ut0list.ic \ - include/ut0wqueue.h \ - pars/make_bison.sh pars/make_flex.sh \ - pars/pars0grm.y pars/pars0lex.l \ - CMakeLists.txt plug.in +EXTRA_LIBRARIES = libinnobase.a +noinst_LIBRARIES = @plugin_innobase_static_target@ +libinnobase_a_SOURCES = btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c \ + btr/btr0sea.c buf/buf0buf.c buf/buf0flu.c \ + buf/buf0lru.c buf/buf0rea.c data/data0data.c \ + data/data0type.c dict/dict0boot.c \ + dict/dict0crea.c dict/dict0dict.c \ + dict/dict0load.c dict/dict0mem.c dyn/dyn0dyn.c \ + eval/eval0eval.c eval/eval0proc.c \ + fil/fil0fil.c fsp/fsp0fsp.c fut/fut0fut.c \ + fut/fut0lst.c ha/ha0ha.c ha/hash0hash.c \ + ibuf/ibuf0ibuf.c lock/lock0lock.c \ + log/log0log.c log/log0recv.c mach/mach0data.c \ + mem/mem0mem.c mem/mem0pool.c mtr/mtr0log.c \ + mtr/mtr0mtr.c os/os0file.c os/os0proc.c \ + os/os0sync.c os/os0thread.c page/page0cur.c \ + page/page0page.c pars/lexyy.c pars/pars0grm.c \ + pars/pars0opt.c pars/pars0pars.c \ + pars/pars0sym.c que/que0que.c read/read0read.c \ + rem/rem0cmp.c rem/rem0rec.c row/row0ins.c \ + row/row0mysql.c row/row0purge.c row/row0row.c \ + row/row0sel.c row/row0uins.c row/row0umod.c \ + row/row0undo.c row/row0upd.c row/row0vers.c \ + srv/srv0que.c srv/srv0srv.c srv/srv0start.c \ + sync/sync0arr.c sync/sync0rw.c \ + sync/sync0sync.c thr/thr0loc.c trx/trx0purge.c \ + trx/trx0rec.c trx/trx0roll.c trx/trx0rseg.c \ + trx/trx0sys.c trx/trx0trx.c trx/trx0undo.c \ + usr/usr0sess.c ut/ut0byte.c ut/ut0dbg.c \ + ut/ut0list.c ut/ut0mem.c ut/ut0rnd.c \ + ut/ut0ut.c ut/ut0vec.c ut/ut0wqueue.c \ + handler/ha_innodb.cc -noinst_LIBRARIES = libinnobase.a -libinnobase_a_LIBADD = usr/libusr.a srv/libsrv.a dict/libdict.a \ - que/libque.a srv/libsrv.a ibuf/libibuf.a \ - row/librow.a pars/libpars.a btr/libbtr.a \ - trx/libtrx.a read/libread.a usr/libusr.a \ - buf/libbuf.a ibuf/libibuf.a eval/libeval.a \ - log/liblog.a fsp/libfsp.a fut/libfut.a \ - fil/libfil.a lock/liblock.a mtr/libmtr.a \ - page/libpage.a rem/librem.a thr/libthr.a \ - sync/libsync.a data/libdata.a mach/libmach.a \ - ha/libha.a dyn/libdyn.a mem/libmem.a \ - handler/libhandler.a \ - ut/libut.a os/libos.a ut/libut.a -libinnobase_a_SOURCES = +libinnobase_a_CXXFLAGS= $(AM_CFLAGS) +libinnobase_a_CFLAGS = $(AM_CFLAGS) +EXTRA_LTLIBRARIES = ha_innodb.la +pkglib_LTLIBRARIES = @plugin_innobase_shared_target@ -libinnobase.a: $(libinnobase_a_LIBADD) - -rm -f $@ - if test "$(host_os)" = "netware" ; \ - then \ - $(libinnobase_a_AR) $@ $(libinnobase_a_LIBADD) ; \ - else \ - for arc in $(libinnobase_a_LIBADD); do \ - arpath=`echo $$arc|sed 's|[^/]*$$||'`; \ - $(AR) t $$arc|sed "s|^|$$arpath|"; \ - done | sort -u | xargs $(AR) cq $@ ; \ - $(RANLIB) $@ ; \ - fi +ha_innodb_la_LDFLAGS = -module -rpath $(MYSQLLIBdir) +ha_innodb_la_CXXFLAGS= $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN +ha_innodb_la_CFLAGS = $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN +ha_innodb_la_SOURCES = $(libinnobase_a_SOURCES) + +EXTRA_DIST = CMakeLists.txt plug.in \ + pars/make_bison.sh pars/make_flex.sh \ + pars/pars0grm.y pars/pars0lex.l # Don't update the files from bitkeeper %::SCCS/s.% diff --git a/storage/innobase/btr/Makefile.am b/storage/innobase/btr/Makefile.am deleted file mode 100644 index 6b09b289cdc..00000000000 --- a/storage/innobase/btr/Makefile.am +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (C) 2001, 2003 MySQL AB & Innobase Oy -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -include ../include/Makefile.i - -noinst_LIBRARIES = libbtr.a - -libbtr_a_SOURCES = btr0btr.c btr0cur.c btr0pcur.c btr0sea.c - -EXTRA_PROGRAMS = - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/storage/innobase/btr/btr0btr.c b/storage/innobase/btr/btr0btr.c index 50a349e78d6..6e8b43aeb8d 100644 --- a/storage/innobase/btr/btr0btr.c +++ b/storage/innobase/btr/btr0btr.c @@ -2606,8 +2606,11 @@ btr_index_rec_validate( rec_get_nth_field(rec, offsets, i, &len); - /* Note that prefix indexes are not fixed size even when - their type is CHAR. */ + /* Note that if fixed_size != 0, it equals the + length of a fixed-size column in the clustered index. + A prefix index of the column is of fixed, but different + length. When fixed_size == 0, prefix_len is the maximum + length of the prefix index column. */ if ((dict_index_get_nth_field(index, i)->prefix_len == 0 && len != UNIV_SQL_NULL && fixed_size diff --git a/storage/innobase/buf/Makefile.am b/storage/innobase/buf/Makefile.am deleted file mode 100644 index 946d5a2e5c2..00000000000 --- a/storage/innobase/buf/Makefile.am +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (C) 2001, 2003 MySQL AB & Innobase Oy -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -include ../include/Makefile.i - -noinst_LIBRARIES = libbuf.a - -libbuf_a_SOURCES = buf0buf.c buf0flu.c buf0lru.c buf0rea.c - -EXTRA_PROGRAMS = - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/storage/innobase/data/Makefile.am b/storage/innobase/data/Makefile.am deleted file mode 100644 index 6f9407d40e5..00000000000 --- a/storage/innobase/data/Makefile.am +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (C) 2001, 2003 MySQL AB & Innobase Oy -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -include ../include/Makefile.i - -noinst_LIBRARIES = libdata.a - -libdata_a_SOURCES = data0data.c data0type.c - -EXTRA_PROGRAMS = - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/storage/innobase/data/data0data.c b/storage/innobase/data/data0data.c index fc4494d991a..0f03de4ca9d 100644 --- a/storage/innobase/data/data0data.c +++ b/storage/innobase/data/data0data.c @@ -18,6 +18,8 @@ Created 5/30/1994 Heikki Tuuri #include "dict0dict.h" #include "btr0cur.h" +#include <ctype.h> + #ifdef UNIV_DEBUG byte data_error; /* data pointers of tuple fields are initialized to point here for error checking */ diff --git a/storage/innobase/data/data0type.c b/storage/innobase/data/data0type.c index 77779d185cf..305000d7c0a 100644 --- a/storage/innobase/data/data0type.c +++ b/storage/innobase/data/data0type.c @@ -190,7 +190,8 @@ dtype_validate( dtype_t* type) /* in: type struct to validate */ { ut_a(type); - ut_a((type->mtype >= DATA_VARCHAR) && (type->mtype <= DATA_MYSQL)); + ut_a(type->mtype >= DATA_VARCHAR); + ut_a(type->mtype <= DATA_MYSQL); if (type->mtype == DATA_SYS) { ut_a((type->prtype & DATA_MYSQL_TYPE_MASK) < DATA_N_SYS_COLS); diff --git a/storage/innobase/dict/Makefile.am b/storage/innobase/dict/Makefile.am deleted file mode 100644 index 15cacca6f58..00000000000 --- a/storage/innobase/dict/Makefile.am +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright (C) 2001, 2003 MySQL AB & Innobase Oy -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -include ../include/Makefile.i - -noinst_LIBRARIES = libdict.a - -libdict_a_SOURCES = dict0boot.c dict0crea.c dict0dict.c dict0load.c\ - dict0mem.c - -EXTRA_PROGRAMS = - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/storage/innobase/dict/dict0crea.c b/storage/innobase/dict/dict0crea.c index e060d45768e..51146c3c24c 100644 --- a/storage/innobase/dict/dict0crea.c +++ b/storage/innobase/dict/dict0crea.c @@ -1195,7 +1195,8 @@ dict_create_or_check_foreign_constraint_tables(void) fprintf(stderr, "InnoDB: error %lu in creation\n", (ulong) error); - ut_a(error == DB_OUT_OF_FILE_SPACE); + ut_a(error == DB_OUT_OF_FILE_SPACE + || error == DB_TOO_MANY_CONCURRENT_TRXS); fprintf(stderr, "InnoDB: creation failed\n" diff --git a/storage/innobase/dict/dict0dict.c b/storage/innobase/dict/dict0dict.c index f450d3553eb..e2a9535dc8b 100644 --- a/storage/innobase/dict/dict0dict.c +++ b/storage/innobase/dict/dict0dict.c @@ -30,6 +30,8 @@ Created 1/8/1996 Heikki Tuuri # include "m_ctype.h" /* my_isspace() */ #endif /* !UNIV_HOTBACKUP */ +#include <ctype.h> + dict_sys_t* dict_sys = NULL; /* the dictionary system */ rw_lock_t dict_operation_lock; /* table create, drop, etc. reserve @@ -1529,6 +1531,12 @@ dict_index_add_col( if (field->fixed_len > DICT_MAX_INDEX_COL_LEN) { field->fixed_len = 0; } +#if DICT_MAX_INDEX_COL_LEN != 768 + /* The comparison limit above must be constant. If it were + changed, the disk format of some fixed-length columns would + change, which would be a disaster. */ +# error "DICT_MAX_INDEX_COL_LEN != 768" +#endif if (!(col->prtype & DATA_NOT_NULL)) { index->n_nullable++; @@ -1585,9 +1593,6 @@ dict_index_copy_types( ifield = dict_index_get_nth_field(index, i); dfield_type = dfield_get_type(dtuple_get_nth_field(tuple, i)); dict_col_copy_type(dict_field_get_col(ifield), dfield_type); - if (UNIV_UNLIKELY(ifield->prefix_len)) { - dfield_type->len = ifield->prefix_len; - } } } @@ -3361,7 +3366,8 @@ dict_create_foreign_constraints( ulint err; mem_heap_t* heap; - ut_a(trx && trx->mysql_thd); + ut_a(trx); + ut_a(trx->mysql_thd); str = dict_strip_comments(sql_string); heap = mem_heap_create(10000); @@ -3403,7 +3409,8 @@ dict_foreign_parse_drop_constraints( FILE* ef = dict_foreign_err_file; struct charset_info_st* cs; - ut_a(trx && trx->mysql_thd); + ut_a(trx); + ut_a(trx->mysql_thd); cs = innobase_get_charset(trx->mysql_thd); @@ -3712,7 +3719,7 @@ dict_index_calc_min_rec_len( } /* round the NULL flags up to full bytes */ - sum += (nullable + 7) / 8; + sum += UT_BITS_IN_BYTES(nullable); return(sum); } diff --git a/storage/innobase/dyn/Makefile.am b/storage/innobase/dyn/Makefile.am deleted file mode 100644 index 57d9a25e481..00000000000 --- a/storage/innobase/dyn/Makefile.am +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (C) 2001, 2003 MySQL AB & Innobase Oy -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -include ../include/Makefile.i - -noinst_LIBRARIES = libdyn.a - -libdyn_a_SOURCES = dyn0dyn.c - -EXTRA_PROGRAMS = - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/storage/innobase/eval/Makefile.am b/storage/innobase/eval/Makefile.am deleted file mode 100644 index 6c2b05d8b7a..00000000000 --- a/storage/innobase/eval/Makefile.am +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (C) 2001, 2003 MySQL AB & Innobase Oy -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -include ../include/Makefile.i - -noinst_LIBRARIES = libeval.a - -libeval_a_SOURCES = eval0eval.c eval0proc.c - -EXTRA_PROGRAMS = - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/storage/innobase/fil/Makefile.am b/storage/innobase/fil/Makefile.am deleted file mode 100644 index 0a85ceb5b86..00000000000 --- a/storage/innobase/fil/Makefile.am +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (C) 2001, 2003 MySQL AB & Innobase Oy -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -include ../include/Makefile.i - -noinst_LIBRARIES = libfil.a - -libfil_a_SOURCES = fil0fil.c - -EXTRA_PROGRAMS = - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/storage/innobase/fsp/Makefile.am b/storage/innobase/fsp/Makefile.am deleted file mode 100644 index 7818cdafc1b..00000000000 --- a/storage/innobase/fsp/Makefile.am +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright (C) 2001, 2003 MySQL AB & Innobase Oy -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - -include ../include/Makefile.i - -noinst_LIBRARIES = libfsp.a - -libfsp_a_SOURCES = fsp0fsp.c - -EXTRA_PROGRAMS = - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/storage/innobase/fsp/fsp0fsp.c b/storage/innobase/fsp/fsp0fsp.c index b5662fd24a4..78fb55e4ef3 100644 --- a/storage/innobase/fsp/fsp0fsp.c +++ b/storage/innobase/fsp/fsp0fsp.c @@ -205,10 +205,9 @@ the extent are free and which contain old tuple version to clean. */ space */ #define XDES_FSEG 4 /* extent belongs to a segment */ -/* File extent data structure size in bytes. The "+ 7 ) / 8" part in the -definition rounds the number of bytes upward. */ +/* File extent data structure size in bytes. */ #define XDES_SIZE \ - (XDES_BITMAP + (FSP_EXTENT_SIZE * XDES_BITS_PER_PAGE + 7) / 8) + (XDES_BITMAP + UT_BITS_IN_BYTES(FSP_EXTENT_SIZE * XDES_BITS_PER_PAGE)) /* Offset of the descriptor array on a descriptor page */ #define XDES_ARR_OFFSET (FSP_HEADER_OFFSET + FSP_HEADER_SIZE) @@ -3649,7 +3648,11 @@ fsp_validate( n_full_frag_pages = FSP_EXTENT_SIZE * flst_get_len(header + FSP_FULL_FRAG, &mtr); - ut_a(free_limit <= size || (space != 0 && size < FSP_EXTENT_SIZE)); + if (UNIV_UNLIKELY(free_limit > size)) { + + ut_a(space != 0); + ut_a(size < FSP_EXTENT_SIZE); + } flst_validate(header + FSP_FREE, &mtr); flst_validate(header + FSP_FREE_FRAG, &mtr); diff --git a/storage/innobase/fut/Makefile.am b/storage/innobase/fut/Makefile.am deleted file mode 100644 index ffe9835a023..00000000000 --- a/storage/innobase/fut/Makefile.am +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (C) 2001, 2003 MySQL AB & Innobase Oy -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -include ../include/Makefile.i - -noinst_LIBRARIES = libfut.a - -libfut_a_SOURCES = fut0fut.c fut0lst.c - -EXTRA_PROGRAMS = - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/storage/innobase/ha/Makefile.am b/storage/innobase/ha/Makefile.am deleted file mode 100644 index 696cad0b203..00000000000 --- a/storage/innobase/ha/Makefile.am +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (C) 2001, 2003 MySQL AB & Innobase Oy -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -include ../include/Makefile.i - -noinst_LIBRARIES = libha.a - -libha_a_SOURCES = ha0ha.c hash0hash.c - -EXTRA_PROGRAMS = - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/storage/innobase/handler/Makefile.am b/storage/innobase/handler/Makefile.am deleted file mode 100644 index 0d34212bdd4..00000000000 --- a/storage/innobase/handler/Makefile.am +++ /dev/null @@ -1,28 +0,0 @@ -# Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB -# & Innobase Oy -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -include ../include/Makefile.i - -DEFS = -DMYSQL_SERVER @DEFS@ - -noinst_LIBRARIES = libhandler.a - -libhandler_a_SOURCES = ha_innodb.cc - -EXTRA_PROGRAMS = - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index c6319d977f7..b7d0c4417c3 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -15,11 +15,10 @@ /* This file defines the InnoDB handler: the interface between MySQL and InnoDB NOTE: You can only use noninlined InnoDB functions in this file, because we -have disables the InnoDB inlining in this file. */ +have disabled the InnoDB inlining in this file. */ /* TODO list for the InnoDB handler in 5.0: - - Remove the flag trx->active_trans and look at the InnoDB - trx struct state field + - Remove the flag trx->active_trans and look at trx->conc_state - fix savepoint functions to use savepoint storage area - Find out what kind of problems the OS X case-insensitivity causes to table and database names; should we 'normalize' the names like we do @@ -31,8 +30,7 @@ have disables the InnoDB inlining in this file. */ #endif #include <mysql_priv.h> - -#ifdef WITH_INNOBASE_STORAGE_ENGINE +#include <mysqld_error.h> #include <m_ctype.h> #include <hash.h> @@ -40,15 +38,23 @@ have disables the InnoDB inlining in this file. */ #include <mysys_err.h> #include <my_sys.h> #include "ha_innodb.h" - -pthread_mutex_t innobase_share_mutex, /* to protect innobase_open_files */ - prepare_commit_mutex; /* to force correct commit order in - binlog */ -ulong commit_threads= 0; -pthread_mutex_t commit_threads_m; -pthread_cond_t commit_cond; -pthread_mutex_t commit_cond_m; -bool innodb_inited= 0; +#include <mysql/plugin.h> + +#ifndef MYSQL_SERVER +/* This is needed because of Bug #3596. Let us hope that pthread_mutex_t +is defined the same in both builds: the MySQL server and the InnoDB plugin. */ +extern pthread_mutex_t LOCK_thread_count; +#endif /* MYSQL_SERVER */ + +/** to protect innobase_open_files */ +static pthread_mutex_t innobase_share_mutex; +/** to force correct commit order in binlog */ +static pthread_mutex_t prepare_commit_mutex; +static ulong commit_threads = 0; +static pthread_mutex_t commit_threads_m; +static pthread_cond_t commit_cond; +static pthread_mutex_t commit_cond_m; +static bool innodb_inited = 0; /* This needs to exist until the query cache callback is removed @@ -92,55 +98,41 @@ extern "C" { #include "../storage/innobase/include/ha_prototypes.h" } - -/* The default values for the following, type long or longlong, start-up -parameters are declared in mysqld.cc: */ - -long innobase_mirrored_log_groups, innobase_log_files_in_group, +static long innobase_mirrored_log_groups, innobase_log_files_in_group, innobase_log_buffer_size, innobase_buffer_pool_awe_mem_mb, innobase_additional_mem_pool_size, innobase_file_io_threads, innobase_lock_wait_timeout, innobase_force_recovery, innobase_open_files; -long long innobase_buffer_pool_size, innobase_log_file_size; +static long long innobase_buffer_pool_size, innobase_log_file_size; /* The default values for the following char* start-up parameters are determined in innobase_init below: */ -char* innobase_data_home_dir = NULL; -char* innobase_data_file_path = NULL; -char* innobase_log_group_home_dir = NULL; -char* innobase_log_arch_dir = NULL;/* unused */ +static char* innobase_data_home_dir = NULL; +static char* innobase_data_file_path = NULL; +static char* innobase_log_group_home_dir = NULL; /* The following has a misleading name: starting from 4.0.5, this also affects Windows: */ -char* innobase_unix_file_flush_method = NULL; +static char* innobase_unix_file_flush_method = NULL; /* Below we have boolean-valued start-up parameters, and their default values */ -static -ulong innobase_fast_shutdown = 1; +static ulong innobase_fast_shutdown = 1; #ifdef UNIV_LOG_ARCHIVE -static -my_bool innobase_log_archive = FALSE;/* unused */ -#endif /* UNIG_LOG_ARCHIVE */ -static -my_bool innobase_use_doublewrite = TRUE; -static -my_bool innobase_use_checksums = TRUE; -static -my_bool innobase_file_per_table = FALSE; -static -my_bool innobase_locks_unsafe_for_binlog = FALSE; -static -my_bool innobase_rollback_on_timeout = FALSE; -static -my_bool innobase_create_status_file = FALSE; -static -my_bool innobase_stats_on_metadata = TRUE; +static my_bool innobase_log_archive = FALSE; +static char* innobase_log_arch_dir = NULL; +#endif /* UNIV_LOG_ARCHIVE */ +static my_bool innobase_use_doublewrite = TRUE; +static my_bool innobase_use_checksums = TRUE; +static my_bool innobase_file_per_table = FALSE; +static my_bool innobase_locks_unsafe_for_binlog = FALSE; +static my_bool innobase_rollback_on_timeout = FALSE; +static my_bool innobase_create_status_file = FALSE; +static my_bool innobase_stats_on_metadata = TRUE; -static -char* internal_innobase_data_file_path = NULL; +static char* internal_innobase_data_file_path = NULL; /* The following counter is used to convey information to InnoDB about server activity: in selects it is not sensible to call @@ -427,6 +419,22 @@ static SHOW_VAR innodb_status_variables[]= { /* General functions */ /********************************************************************** +Returns true if the thread is the replication thread on the slave +server. Used in srv_conc_enter_innodb() to determine if the thread +should be allowed to enter InnoDB - the replication thread is treated +differently than other threads. Also used in +srv_conc_force_exit_innodb(). */ +extern "C" +ibool +thd_is_replication_slave_thread( +/*============================*/ + /* out: true if thd is the replication thread */ + void* thd) /* in: thread handle (THD*) */ +{ + return((ibool) thd_slave_thread((THD*) thd)); +} + +/********************************************************************** Save some CPU by testing the value of srv_thread_concurrency in inline functions. */ inline @@ -482,14 +490,30 @@ innobase_release_stat_resources( } } +/********************************************************************** +Returns true if the transaction this thread is processing has edited +non-transactional tables. Used by the deadlock detector when deciding +which transaction to rollback in case of a deadlock - we try to avoid +rolling back transactions that have edited non-transactional tables. */ +extern "C" +ibool +thd_has_edited_nontrans_tables( +/*===========================*/ + /* out: true if non-transactional tables have + been edited */ + void* thd) /* in: thread handle (THD*) */ +{ + return((ibool) thd_non_transactional_update((THD*) thd)); +} + /************************************************************************ Obtain the InnoDB transaction of a MySQL thread. */ inline trx_t*& thd_to_trx( /*=======*/ - /* out: reference to transaction pointer */ - THD* thd) /* in: MySQL thread */ + /* out: reference to transaction pointer */ + THD* thd) /* in: MySQL thread */ { return(*(trx_t**) thd_ha_data(thd, innodb_hton_ptr)); } @@ -502,11 +526,14 @@ static int innobase_release_temporary_latches( /*===============================*/ - handlerton *hton, - THD *thd) + /* out: 0 */ + handlerton* hton, /* in: handlerton */ + THD* thd) /* in: MySQL thread */ { trx_t* trx; + DBUG_ASSERT(hton == innodb_hton_ptr); + if (!innodb_inited) { return 0; @@ -645,6 +672,20 @@ convert_error_code_to_mysql( } return(HA_ERR_LOCK_TABLE_FULL); + } else if (error == DB_TOO_MANY_CONCURRENT_TRXS) { + + /* Once MySQL add the appropriate code to errmsg.txt then + we can get rid of this #ifdef. NOTE: The code checked by + the #ifdef is the suggested name for the error condition + and the actual error code name could very well be different. + This will require some monitoring, ie. the status + of this request on our part.*/ +#ifdef ER_TOO_MANY_CONCURRENT_TRXS + return(ER_TOO_MANY_CONCURRENT_TRXS); +#else + return(HA_ERR_RECORD_FILE_FULL); +#endif + } else { return(-1); // Unknown error } @@ -693,19 +734,19 @@ innobase_mysql_print_thd( use the default max length */ { THD* thd; - char buffer[1024]; + char buffer[1024]; - thd = (THD*) input_thd; - fputs(thd_security_context(thd, buffer, sizeof(buffer), + thd = (THD*) input_thd; + fputs(thd_security_context(thd, buffer, sizeof(buffer), max_query_len), f); - putc('\n', f); + putc('\n', f); } /********************************************************************** Get the variable length bounds of the given character set. NOTE that the exact prototype of this function has to be in -/innobase/data/data0type.ic! */ +/innobase/include/data0type.ic! */ extern "C" void innobase_get_cset_width( @@ -744,7 +785,7 @@ innobase_convert_from_table_id( { uint errors; - strconvert(current_thd->charset(), from, + strconvert(thd_charset(current_thd), from, &my_charset_filename, to, (uint) len, &errors); } @@ -763,7 +804,7 @@ innobase_convert_from_id( { uint errors; - strconvert(current_thd->charset(), from, + strconvert(thd_charset(current_thd), from, system_charset_info, to, (uint) len, &errors); } @@ -826,7 +867,7 @@ innobase_get_charset( /* out: connection character set */ void* mysql_thd) /* in: MySQL thread handle */ { - return(((THD*) mysql_thd)->charset()); + return(thd_charset((THD*) mysql_thd)); } /************************************************************************* @@ -837,22 +878,9 @@ innobase_mysql_tmpfile(void) /*========================*/ /* out: temporary file descriptor, or < 0 on error */ { - char filename[FN_REFLEN]; int fd2 = -1; - File fd = create_temp_file(filename, mysql_tmpdir, "ib", -#ifdef __WIN__ - O_BINARY | O_TRUNC | O_SEQUENTIAL | - O_TEMPORARY | O_SHORT_LIVED | -#endif /* __WIN__ */ - O_CREAT | O_EXCL | O_RDWR, - MYF(MY_WME)); + File fd = mysql_tmpfile("ib"); if (fd >= 0) { -#ifndef __WIN__ - /* On Windows, open files cannot be removed, but files can be - created with the O_TEMPORARY flag to the same effect - ("delete on close"). */ - unlink(filename); -#endif /* !__WIN__ */ /* Copy the file descriptor, so that the additional resources allocated by create_temp_file() can be freed by invoking my_close(). @@ -867,7 +895,7 @@ innobase_mysql_tmpfile(void) my_errno=errno; my_error(EE_OUT_OF_FILERESOURCES, MYF(ME_BELL+ME_WAITTANG), - filename, my_errno); + "ib*", my_errno); } my_close(fd, MYF(MY_WME)); } @@ -903,7 +931,6 @@ trx_t* check_trx_exists( /*=============*/ /* out: InnoDB transaction handle */ - handlerton* hton, /* in: handlerton for innodb */ THD* thd) /* in: user thread handle */ { trx_t*& trx = thd_to_trx(thd); @@ -915,8 +942,7 @@ check_trx_exists( trx = trx_allocate_for_mysql(); trx->mysql_thd = thd; - trx->mysql_query_str = &(thd->query); - trx->active_trans = 0; + trx->mysql_query_str = thd_query(thd); /* Update the info whether we should skip XA steps that eat CPU time */ @@ -927,7 +953,7 @@ check_trx_exists( if (trx->magic_n != TRX_MAGIC_N) { mem_analyze_corruption(trx); - ut_a(0); + ut_error; } } @@ -958,7 +984,7 @@ ha_innobase::ha_innobase(handlerton *hton, TABLE_SHARE *table_arg) HA_CAN_SQL_HANDLER | HA_PRIMARY_KEY_REQUIRED_FOR_POSITION | HA_PRIMARY_KEY_IN_READ_INDEX | - HA_BINLOG_ROW_CAPABLE | + HA_BINLOG_ROW_CAPABLE | HA_CAN_GEOMETRY | HA_PARTIAL_COLUMN_READ | HA_TABLE_SCAN_ON_INDEX), start_of_scan(0), @@ -978,7 +1004,7 @@ ha_innobase::update_thd( { trx_t* trx; - trx = check_trx_exists(ht, thd); + trx = check_trx_exists(thd); if (prebuilt->trx != trx) { @@ -1117,7 +1143,7 @@ innobase_query_caching_of_table_permitted( ut_a(full_name_len < 999); - trx = check_trx_exists(innodb_hton_ptr, thd); + trx = check_trx_exists(thd); if (trx->isolation_level == TRX_ISO_SERIALIZABLE) { /* In the SERIALIZABLE mode we add LOCK IN SHARE MODE to every @@ -1222,10 +1248,10 @@ innobase_invalidate_query_cache( /* Argument TRUE below means we are using transactions */ #ifdef HAVE_QUERY_CACHE - query_cache.invalidate((THD*)(trx->mysql_thd), - (const char*)full_name, - (uint32)full_name_len, - TRUE); + mysql_query_cache_invalidate4((THD*) trx->mysql_thd, + (const char*) full_name, + (uint32) full_name_len, + TRUE); #endif } @@ -1305,7 +1331,20 @@ trx_is_interrupted( /* out: TRUE if interrupted */ trx_t* trx) /* in: transaction */ { - return(trx && trx->mysql_thd && ((THD*) trx->mysql_thd)->killed); + return(trx && trx->mysql_thd && thd_killed((THD*) trx->mysql_thd)); +} + +/****************************************************************** +Resets some fields of a prebuilt struct. The template is used in fast +retrieval of just those column values MySQL needs in its processing. */ +static +void +reset_template( +/*===========*/ + row_prebuilt_t* prebuilt) /* in/out: prebuilt struct */ +{ + prebuilt->keep_other_fields_on_keyread = 0; + prebuilt->read_just_key = 0; } /********************************************************************* @@ -1343,7 +1382,7 @@ ha_innobase::init_table_handle_for_HANDLER(void) if (prebuilt->trx->active_trans == 0) { - innobase_register_trx_and_stmt(ht, ha_thd()); + innobase_register_trx_and_stmt(ht, user_thd); prebuilt->trx->active_trans = 1; } @@ -1366,19 +1405,18 @@ ha_innobase::init_table_handle_for_HANDLER(void) /* We want always to fetch all columns in the whole row? Or do we???? */ - prebuilt->read_just_key = FALSE; - prebuilt->used_in_HANDLER = TRUE; - - prebuilt->keep_other_fields_on_keyread = FALSE; + reset_template(prebuilt); } /************************************************************************* Opens an InnoDB database. */ static int -innobase_init(void *p) -/*===============*/ +innobase_init( +/*==========*/ + /* out: 0 on success, error code on failure */ + void *p) /* in: InnoDB handlerton */ { static char current_dir[3]; /* Set if using current lib */ int err; @@ -1387,9 +1425,9 @@ innobase_init(void *p) DBUG_ENTER("innobase_init"); handlerton *innobase_hton= (handlerton *)p; - innodb_hton_ptr= innobase_hton; + innodb_hton_ptr = innobase_hton; - innobase_hton->state= SHOW_OPTION_YES; + innobase_hton->state = SHOW_OPTION_YES; innobase_hton->db_type= DB_TYPE_INNODB; innobase_hton->savepoint_offset=sizeof(trx_named_savept_t); innobase_hton->close_connection=innobase_close_connection; @@ -1569,10 +1607,7 @@ innobase_init(void *p) changes the value so that it becomes the number of database pages. */ if (innobase_buffer_pool_awe_mem_mb == 0) { - /* Careful here: we first convert the signed long int to ulint - and only after that divide */ - - srv_pool_size = ((ulint) innobase_buffer_pool_size) / 1024; + srv_pool_size = (ulint)(innobase_buffer_pool_size / 1024); } else { srv_use_awe = TRUE; srv_pool_size = (ulint) @@ -1751,7 +1786,7 @@ innobase_start_trx_and_assign_read_view( /* Create a new trx struct for thd, if it does not yet have one */ - trx = check_trx_exists(hton, thd); + trx = check_trx_exists(thd); /* This is just to play safe: release a possible FIFO ticket and search latch. Since we will reserve the kernel mutex, we have to @@ -1796,7 +1831,7 @@ innobase_commit( DBUG_ENTER("innobase_commit"); DBUG_PRINT("trans", ("ending transaction")); - trx = check_trx_exists(hton, thd); + trx = check_trx_exists(thd); /* Update the info whether we should skip XA steps that eat CPU time */ trx->support_xa = THDVAR(thd, support_xa); @@ -1855,9 +1890,8 @@ retry: } } - trx->mysql_log_file_name = mysql_bin_log.get_log_fname(); - trx->mysql_log_offset = - (ib_longlong)mysql_bin_log.get_log_file()->pos_in_file; + trx->mysql_log_file_name = mysql_bin_log_file_name(); + trx->mysql_log_offset = (ib_longlong) mysql_bin_log_file_pos(); innobase_commit_low(trx); @@ -1987,7 +2021,6 @@ int innobase_commit_complete( /*=====================*/ /* out: 0 */ - handlerton *hton, /* in: Innodb handlerton */ THD* thd) /* in: user thread */ { trx_t* trx; @@ -2012,8 +2045,8 @@ innobase_commit_complete( /********************************************************************* Rolls back a transaction or the latest SQL statement. */ - -static int +static +int innobase_rollback( /*==============*/ /* out: 0 or error number */ @@ -2029,7 +2062,7 @@ innobase_rollback( DBUG_ENTER("innobase_rollback"); DBUG_PRINT("trans", ("aborting transaction")); - trx = check_trx_exists(hton, thd); + trx = check_trx_exists(thd); /* Update the info whether we should skip XA steps that eat CPU time */ trx->support_xa = THDVAR(thd, support_xa); @@ -2095,8 +2128,8 @@ innobase_rollback_trx( /********************************************************************* Rolls back a transaction to a savepoint. */ - -static int +static +int innobase_rollback_to_savepoint( /*===========================*/ /* out: 0 if success, HA_ERR_NO_SAVEPOINT if @@ -2113,7 +2146,7 @@ innobase_rollback_to_savepoint( DBUG_ENTER("innobase_rollback_to_savepoint"); - trx = check_trx_exists(hton, thd); + trx = check_trx_exists(thd); /* Release a possible FIFO ticket and search latch. Since we will reserve the kernel mutex, we have to release the search system latch @@ -2149,7 +2182,7 @@ innobase_release_savepoint( DBUG_ENTER("innobase_release_savepoint"); - trx = check_trx_exists(hton, thd); + trx = check_trx_exists(thd); /* TODO: use provided savepoint data area to store savepoint data */ @@ -2181,10 +2214,12 @@ innobase_savepoint( (unless we are in sub-statement), so SQL layer ensures that this method is never called in such situation. */ +#ifdef MYSQL_SERVER /* plugins cannot access thd->in_sub_stmt */ DBUG_ASSERT(thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN) || thd->in_sub_stmt); +#endif /* MYSQL_SERVER */ - trx = check_trx_exists(hton, thd); + trx = check_trx_exists(thd); /* Release a possible FIFO ticket and search latch. Since we will reserve the kernel mutex, we have to release the search system latch @@ -2217,6 +2252,8 @@ innobase_close_connection( { trx_t* trx; + DBUG_ENTER("innobase_close_connection"); + DBUG_ASSERT(hton == innodb_hton_ptr); trx = thd_to_trx(thd); ut_a(trx); @@ -2243,7 +2280,7 @@ innobase_close_connection( thr_local_free(trx->mysql_thread_id); trx_free_for_mysql(trx); - return(0); + DBUG_RETURN(0); } @@ -2523,8 +2560,15 @@ ha_innobase::close(void) /*====================*/ /* out: 0 */ { + THD* thd; + DBUG_ENTER("ha_innobase::close"); + thd = current_thd; // avoid calling current_thd twice, it may be slow + if (thd != NULL) { + innobase_release_temporary_latches(ht, thd); + } + row_prebuilt_free(prebuilt); my_free(upd_buff, MYF(0)); @@ -3099,7 +3143,7 @@ static void build_template( /*===========*/ - row_prebuilt_t* prebuilt, /* in: prebuilt struct */ + row_prebuilt_t* prebuilt, /* in/out: prebuilt struct */ THD* thd, /* in: current user thread, used only if templ_type is ROW_MYSQL_REC_FIELDS */ @@ -3319,8 +3363,8 @@ ha_innobase::write_row( longlong auto_inc; longlong dummy; ibool auto_inc_used= FALSE; - THD *thd= ha_thd(); - trx_t* trx = thd_to_trx(thd); + ulint sql_command; + trx_t* trx = thd_to_trx(user_thd); DBUG_ENTER("ha_innobase::write_row"); @@ -3344,11 +3388,13 @@ ha_innobase::write_row( if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT) table->timestamp_field->set_time(); - if ((thd_sql_command(thd) == SQLCOM_ALTER_TABLE - || thd_sql_command(thd) == SQLCOM_OPTIMIZE - || thd_sql_command(thd) == SQLCOM_CREATE_INDEX - || thd_sql_command(thd) == SQLCOM_DROP_INDEX) - && num_write_row >= 10000) { + sql_command = thd_sql_command(user_thd); + + if ((sql_command == SQLCOM_ALTER_TABLE + || sql_command == SQLCOM_OPTIMIZE + || sql_command == SQLCOM_CREATE_INDEX + || sql_command == SQLCOM_DROP_INDEX) + && num_write_row >= 10000) { /* ALTER TABLE is COMMITted at every 10000 copied rows. The IX table lock for the original table has to be re-issued. As this method will be called on a temporary table where the @@ -3490,30 +3536,32 @@ no_commit: /* This call will update the counter according to the value that was inserted in the table */ - dict_table_autoinc_update(prebuilt->table, auto_inc); - } - } + dict_table_autoinc_update(prebuilt->table, auto_inc); + } + } - /* A REPLACE command and LOAD DATA INFILE REPLACE handle a duplicate - key error themselves, and we must update the autoinc counter if we are - performing those statements. */ + /* A REPLACE command and LOAD DATA INFILE REPLACE handle a duplicate + key error themselves, and we must update the autoinc counter if we are + performing those statements. */ - if (error == DB_DUPLICATE_KEY && auto_inc_used - && (thd_sql_command(user_thd) == SQLCOM_REPLACE - || thd_sql_command(user_thd) == SQLCOM_REPLACE_SELECT - || (thd_sql_command(user_thd) == SQLCOM_INSERT - && prebuilt->trx->allow_duplicates - && !prebuilt->trx->replace_duplicates) - || (thd_sql_command(user_thd) == SQLCOM_LOAD - && prebuilt->trx->allow_duplicates - && prebuilt->trx->replace_duplicates))) { + if (error == DB_DUPLICATE_KEY && auto_inc_used + && (sql_command == SQLCOM_REPLACE + || sql_command == SQLCOM_REPLACE_SELECT + || (sql_command == SQLCOM_INSERT + && ((trx->duplicates + & (TRX_DUP_IGNORE | TRX_DUP_REPLACE)) + == TRX_DUP_IGNORE)) + || (sql_command == SQLCOM_LOAD + && ((trx->duplicates + & (TRX_DUP_IGNORE | TRX_DUP_REPLACE)) + == (TRX_DUP_IGNORE | TRX_DUP_REPLACE))))) { - auto_inc = table->next_number_field->val_int(); + auto_inc = table->next_number_field->val_int(); - if (auto_inc != 0) { - dict_table_autoinc_update(prebuilt->table, auto_inc); - } - } + if (auto_inc != 0) { + dict_table_autoinc_update(prebuilt->table, auto_inc); + } + } innodb_srv_conc_exit_innodb(prebuilt->trx); @@ -3694,7 +3742,7 @@ ha_innobase::update_row( { upd_t* uvect; int error = 0; - trx_t* trx = thd_to_trx(ha_thd()); + trx_t* trx = thd_to_trx(user_thd); DBUG_ENTER("ha_innobase::update_row"); @@ -3747,7 +3795,7 @@ ha_innobase::delete_row( const mysql_byte* record) /* in: a row in MySQL format */ { int error = 0; - trx_t* trx = thd_to_trx(ha_thd()); + trx_t* trx = thd_to_trx(user_thd); DBUG_ENTER("ha_innobase::delete_row"); @@ -3833,7 +3881,8 @@ ha_innobase::try_semi_consistent_read(bool yes) option is used or this session is using READ COMMITTED isolation level. */ - if (yes && (srv_locks_unsafe_for_binlog + if (yes + && (srv_locks_unsafe_for_binlog || prebuilt->trx->isolation_level == TRX_ISO_READ_COMMITTED)) { prebuilt->row_read_type = ROW_READ_TRY_SEMI_CONSISTENT; } else { @@ -3991,7 +4040,7 @@ ha_innobase::index_read( DBUG_ENTER("index_read"); - ut_a(prebuilt->trx == thd_to_trx(ha_thd())); + ut_a(prebuilt->trx == thd_to_trx(user_thd)); ha_statistic_increment(&SSV::ha_read_key_count); @@ -4183,7 +4232,7 @@ ha_innobase::general_fetch( DBUG_ENTER("general_fetch"); - ut_a(prebuilt->trx == thd_to_trx(ha_thd())); + ut_a(prebuilt->trx == thd_to_trx(user_thd)); innodb_srv_conc_enter_innodb(prebuilt->trx); @@ -4482,6 +4531,25 @@ ha_innobase::position( } /********************************************************************* +If it's a DB_TOO_BIG_RECORD error then set a suitable message to +return to the client.*/ +static +void +innodb_check_for_record_too_big_error( +/*==================================*/ + dict_table_t* table, /* in: table to check */ + int error) /* in: error code to check */ +{ + if (error == (int)DB_TOO_BIG_RECORD) { + ulint max_row_size; + + max_row_size = page_get_free_space_of_empty_noninline(table); + + my_error(ER_TOO_BIG_ROWSIZE, MYF(0), max_row_size); + } +} + +/********************************************************************* Creates a table definition to an InnoDB database. */ static int @@ -4589,6 +4657,10 @@ create_table_def( error = row_create_table_for_mysql(table, trx); + /* We need access to the table and so we do the error checking + and set the error message here, before the error translation.*/ + innodb_check_for_record_too_big_error(table, error); + error = convert_error_code_to_mysql(error, NULL); DBUG_RETURN(error); @@ -4711,6 +4783,10 @@ create_index( sure we don't create too long indexes. */ error = row_create_index_for_mysql(index, trx, field_lengths); + /* We need access to the table and so we do the error checking + and set the error message here, before the error translation.*/ + innodb_check_for_record_too_big_error(index->table, error); + error = convert_error_code_to_mysql(error, NULL); my_free(field_lengths, MYF(0)); @@ -4738,6 +4814,10 @@ create_clustered_index_when_no_primary( (char*) "GEN_CLUST_INDEX", 0, DICT_CLUSTERED, 0); error = row_create_index_for_mysql(index, trx, NULL); + /* We need access to the table and so we do the error checking + and set the error message here, before the error translation.*/ + innodb_check_for_record_too_big_error(index->table, error); + error = convert_error_code_to_mysql(error, NULL); return(error); @@ -4779,7 +4859,7 @@ ha_innobase::create( uint i; char name2[FN_REFLEN]; char norm_name[FN_REFLEN]; - THD *thd= ha_thd(); + THD* thd = ha_thd(); ib_longlong auto_inc_value; ulint flags; @@ -4797,7 +4877,7 @@ ha_innobase::create( /* Get the transaction associated with the current thd, or create one if not yet created */ - parent_trx = check_trx_exists(ht, thd); + parent_trx = check_trx_exists(thd); /* In case MySQL calls this in the middle of a SELECT query, release possible adaptive hash latch to avoid deadlocks of threads */ @@ -4807,7 +4887,7 @@ ha_innobase::create( trx = trx_allocate_for_mysql(); trx->mysql_thd = thd; - trx->mysql_query_str = &((*thd).query); + trx->mysql_query_str = thd_query(thd); if (thd_test_options(thd, OPTION_NO_FOREIGN_KEY_CHECKS)) { trx->check_foreigns = FALSE; @@ -4893,9 +4973,9 @@ ha_innobase::create( } } - if (thd->query != NULL) { + if (*trx->mysql_query_str) { error = row_table_add_foreign_constraints(trx, - thd->query, norm_name, + *trx->mysql_query_str, norm_name, create_info->options & HA_LEX_CREATE_TMP_TABLE); error = convert_error_code_to_mysql(error, NULL); @@ -4994,33 +5074,32 @@ ha_innobase::delete_all_rows(void) /* out: error number */ { int error; - THD* thd = ha_thd(); DBUG_ENTER("ha_innobase::delete_all_rows"); /* Get the transaction associated with the current thd, or create one if not yet created, and update prebuilt->trx */ - update_thd(thd); - - if (thd_sql_command(thd) == SQLCOM_TRUNCATE) { - /* Truncate the table in InnoDB */ + update_thd(ha_thd()); - error = row_truncate_table_for_mysql(prebuilt->table, prebuilt->trx); - if (error == DB_ERROR) { - /* Cannot truncate; resort to ha_innobase::delete_row() */ - goto fallback; - } + if (thd_sql_command(user_thd) != SQLCOM_TRUNCATE) { + fallback: + /* We only handle TRUNCATE TABLE t as a special case. + DELETE FROM t will have to use ha_innobase::delete_row(). */ + DBUG_RETURN(my_errno=HA_ERR_WRONG_COMMAND); + } - error = convert_error_code_to_mysql(error, NULL); + /* Truncate the table in InnoDB */ - DBUG_RETURN(error); + error = row_truncate_table_for_mysql(prebuilt->table, prebuilt->trx); + if (error == DB_ERROR) { + /* Cannot truncate; resort to ha_innobase::delete_row() */ + goto fallback; } -fallback: - /* We only handle TRUNCATE TABLE t as a special case. - DELETE FROM t will have to use ha_innobase::delete_row(). */ - DBUG_RETURN(my_errno=HA_ERR_WRONG_COMMAND); + error = convert_error_code_to_mysql(error, NULL); + + DBUG_RETURN(error); } /********************************************************************* @@ -5040,7 +5119,7 @@ ha_innobase::delete_table( int error; trx_t* parent_trx; trx_t* trx; - THD *thd= ha_thd(); + THD *thd = ha_thd(); char norm_name[1000]; DBUG_ENTER("ha_innobase::delete_table"); @@ -5048,7 +5127,7 @@ ha_innobase::delete_table( /* Get the transaction associated with the current thd, or create one if not yet created */ - parent_trx = check_trx_exists(ht, thd); + parent_trx = check_trx_exists(thd); /* In case MySQL calls this in the middle of a SELECT query, release possible adaptive hash latch to avoid deadlocks of threads */ @@ -5063,75 +5142,77 @@ ha_innobase::delete_table( trx = trx_allocate_for_mysql(); - trx->mysql_thd = ha_thd(); - trx->mysql_query_str = &(ha_thd()->query); + trx->mysql_thd = thd; + trx->mysql_query_str = thd_query(thd); - if (thd_test_options(thd, OPTION_NO_FOREIGN_KEY_CHECKS)) { - trx->check_foreigns = FALSE; - } + if (thd_test_options(thd, OPTION_NO_FOREIGN_KEY_CHECKS)) { + trx->check_foreigns = FALSE; + } - if (thd_test_options(thd, OPTION_RELAXED_UNIQUE_CHECKS)) { - trx->check_unique_secondary = FALSE; - } + if (thd_test_options(thd, OPTION_RELAXED_UNIQUE_CHECKS)) { + trx->check_unique_secondary = FALSE; + } - name_len = strlen(name); + name_len = strlen(name); - assert(name_len < 1000); + assert(name_len < 1000); - /* Strangely, MySQL passes the table name without the '.frm' - extension, in contrast to ::create */ + /* Strangely, MySQL passes the table name without the '.frm' + extension, in contrast to ::create */ - normalize_table_name(norm_name, name); + normalize_table_name(norm_name, name); - /* Drop the table in InnoDB */ + /* Drop the table in InnoDB */ - error = row_drop_table_for_mysql(norm_name, trx, - thd_sql_command(thd) == SQLCOM_DROP_DB); + error = row_drop_table_for_mysql(norm_name, trx, + thd_sql_command(thd) + == SQLCOM_DROP_DB); - /* Flush the log to reduce probability that the .frm files and - the InnoDB data dictionary get out-of-sync if the user runs - with innodb_flush_log_at_trx_commit = 0 */ + /* Flush the log to reduce probability that the .frm files and + the InnoDB data dictionary get out-of-sync if the user runs + with innodb_flush_log_at_trx_commit = 0 */ - log_buffer_flush_to_disk(); + log_buffer_flush_to_disk(); - /* Tell the InnoDB server that there might be work for - utility threads: */ + /* Tell the InnoDB server that there might be work for + utility threads: */ - srv_active_wake_master_thread(); + srv_active_wake_master_thread(); - innobase_commit_low(trx); + innobase_commit_low(trx); - trx_free_for_mysql(trx); + trx_free_for_mysql(trx); - error = convert_error_code_to_mysql(error, NULL); + error = convert_error_code_to_mysql(error, NULL); - DBUG_RETURN(error); + DBUG_RETURN(error); } /********************************************************************* - Removes all tables in the named database inside InnoDB. */ +Removes all tables in the named database inside InnoDB. */ static void innobase_drop_database( - /*===================*/ - /* out: error number */ - handlerton *hton, /* in: handlerton of Innodb */ - char* path) /* in: database path; inside InnoDB the name - of the last directory in the path is used as - the database name: for example, in 'mysql/data/test' - the database name is 'test' */ -{ - ulint len = 0; - trx_t* parent_trx; - trx_t* trx; - char* ptr; - int error; - char* namebuf; - - /* Get the transaction associated with the current thd, or create one - if not yet created */ - - parent_trx = check_trx_exists(hton, current_thd); +/*===================*/ + /* out: error number */ + handlerton *hton, /* in: handlerton of Innodb */ + char* path) /* in: database path; inside InnoDB the name + of the last directory in the path is used as + the database name: for example, in 'mysql/data/test' + the database name is 'test' */ +{ + ulint len = 0; + trx_t* parent_trx; + trx_t* trx; + char* ptr; + int error; + char* namebuf; + THD* thd = current_thd; + + /* Get the transaction associated with the current thd, or create one + if not yet created */ + + parent_trx = check_trx_exists(thd); /* In case MySQL calls this in the middle of a SELECT query, release possible adaptive hash latch to avoid deadlocks of threads */ @@ -5155,10 +5236,10 @@ innobase_drop_database( innobase_casedn_str(namebuf); #endif trx = trx_allocate_for_mysql(); - trx->mysql_thd = current_thd; - trx->mysql_query_str = &((*current_thd).query); + trx->mysql_thd = thd; + trx->mysql_query_str = thd_query(thd); - if (thd_test_options(current_thd, OPTION_NO_FOREIGN_KEY_CHECKS)) { + if (thd_test_options(thd, OPTION_NO_FOREIGN_KEY_CHECKS)) { trx->check_foreigns = FALSE; } @@ -5204,13 +5285,14 @@ ha_innobase::rename_table( trx_t* trx; char norm_from[1000]; char norm_to[1000]; + THD* thd = ha_thd(); DBUG_ENTER("ha_innobase::rename_table"); /* Get the transaction associated with the current thd, or create one if not yet created */ - parent_trx = check_trx_exists(ht, ha_thd()); + parent_trx = check_trx_exists(thd); /* In case MySQL calls this in the middle of a SELECT query, release possible adaptive hash latch to avoid deadlocks of threads */ @@ -5224,10 +5306,10 @@ ha_innobase::rename_table( } trx = trx_allocate_for_mysql(); - trx->mysql_thd = ha_thd(); - trx->mysql_query_str = &((*ha_thd()).query); + trx->mysql_thd = thd; + trx->mysql_query_str = thd_query(thd); - if (thd_test_options(ha_thd(), OPTION_NO_FOREIGN_KEY_CHECKS)) { + if (thd_test_options(thd, OPTION_NO_FOREIGN_KEY_CHECKS)) { trx->check_foreigns = FALSE; } @@ -5489,7 +5571,12 @@ ha_innobase::info( if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) { - DBUG_RETURN(HA_ERR_CRASHED); + /* We return success (0) instead of HA_ERR_CRASHED, + because we want MySQL to process this query and not + stop, like it would do if it received the error code + HA_ERR_CRASHED. */ + + DBUG_RETURN(0); } /* We do not know if MySQL can call this function before calling @@ -5509,15 +5596,14 @@ ha_innobase::info( if (flag & HA_STATUS_TIME) { if (srv_stats_on_metadata) { - /* In sql_show we call with this flag: update then statistics - so that they are up-to-date */ + /* In sql_show we call with this flag: update + then statistics so that they are up-to-date */ - prebuilt->trx->op_info = (char*)"updating table statistics"; + prebuilt->trx->op_info = "updating table statistics"; dict_update_statistics(ib_table); - prebuilt->trx->op_info = (char*) - "returning various info to MySQL"; + prebuilt->trx->op_info = "returning various info to MySQL"; } my_snprintf(path, sizeof(path), "%s/%s%s", @@ -5642,7 +5728,8 @@ ha_innobase::info( } if (flag & HA_STATUS_ERRKEY) { - ut_a(prebuilt->trx && prebuilt->trx->magic_n == TRX_MAGIC_N); + ut_a(prebuilt->trx); + ut_a(prebuilt->trx->magic_n == TRX_MAGIC_N); errkey = (unsigned int) row_get_mysql_key_number_for_index( (dict_index_t*) trx_get_error_info(prebuilt->trx)); @@ -5726,8 +5813,10 @@ ha_innobase::check( { ulint ret; - ut_a(prebuilt->trx && prebuilt->trx->magic_n == TRX_MAGIC_N); - ut_a(prebuilt->trx == thd_to_trx(ha_thd())); + DBUG_ASSERT(thd == ha_thd()); + ut_a(prebuilt->trx); + ut_a(prebuilt->trx->magic_n == TRX_MAGIC_N); + ut_a(prebuilt->trx == thd_to_trx(thd)); if (prebuilt->mysql_template == NULL) { /* Build the template; we will use a dummy template @@ -6000,9 +6089,8 @@ ha_innobase::get_foreign_key_list(THD *thd, List<FOREIGN_KEY_INFO> *f_key_list) strlen(foreign->referenced_index->name), 1); } - FOREIGN_KEY_INFO *pf_key_info= ((FOREIGN_KEY_INFO *) - thd->memdup(&f_key_info, - sizeof(FOREIGN_KEY_INFO))); + FOREIGN_KEY_INFO *pf_key_info = (FOREIGN_KEY_INFO *) + thd_memdup(thd, &f_key_info, sizeof(FOREIGN_KEY_INFO)); f_key_list->push_back(pf_key_info); foreign = UT_LIST_GET_NEXT(foreign_list, foreign); } @@ -6094,8 +6182,7 @@ ha_innobase::extra( } break; case HA_EXTRA_RESET_STATE: - prebuilt->keep_other_fields_on_keyread = 0; - prebuilt->read_just_key = 0; + reset_template(prebuilt); break; case HA_EXTRA_NO_KEYREAD: prebuilt->read_just_key = 0; @@ -6106,18 +6193,25 @@ ha_innobase::extra( case HA_EXTRA_KEYREAD_PRESERVE_FIELDS: prebuilt->keep_other_fields_on_keyread = 1; break; + + /* IMPORTANT: prebuilt->trx can be obsolete in + this method, because it is not sure that MySQL + calls external_lock before this method with the + parameters below. We must not invoke update_thd() + either, because the calling threads may change. + CAREFUL HERE, OR MEMORY CORRUPTION MAY OCCUR! */ case HA_EXTRA_IGNORE_DUP_KEY: - prebuilt->trx->allow_duplicates= TRUE; + thd_to_trx(ha_thd())->duplicates |= TRX_DUP_IGNORE; break; case HA_EXTRA_WRITE_CAN_REPLACE: - prebuilt->trx->replace_duplicates= TRUE; + thd_to_trx(ha_thd())->duplicates |= TRX_DUP_REPLACE; break; case HA_EXTRA_WRITE_CANNOT_REPLACE: - prebuilt->trx->replace_duplicates= FALSE; + thd_to_trx(ha_thd())->duplicates &= ~TRX_DUP_REPLACE; break; case HA_EXTRA_NO_IGNORE_DUP_KEY: - prebuilt->trx->allow_duplicates= FALSE; - prebuilt->trx->replace_duplicates= FALSE; + thd_to_trx(ha_thd())->duplicates &= + ~(TRX_DUP_IGNORE | TRX_DUP_REPLACE); break; default:/* Do nothing */ ; @@ -6131,8 +6225,7 @@ int ha_innobase::reset() if (prebuilt->blob_heap) { row_mysql_prebuilt_free_blob_heap(prebuilt); } - prebuilt->keep_other_fields_on_keyread = 0; - prebuilt->read_just_key = 0; + reset_template(prebuilt); return 0; } @@ -6173,8 +6266,7 @@ ha_innobase::start_stmt( prebuilt->sql_stat_start = TRUE; prebuilt->hint_need_to_fetch_extra_cols = 0; - prebuilt->read_just_key = 0; - prebuilt->keep_other_fields_on_keyread = FALSE; + reset_template(prebuilt); if (!prebuilt->mysql_has_locked) { /* This handle is for a temporary table created inside @@ -6261,27 +6353,27 @@ ha_innobase::external_lock( update_thd(thd); - /* Statement based binlogging does not work in isolation level - READ UNCOMMITTED and READ COMMITTED since the necessary - locks cannot be taken. In this case, we print an - informative error message and return with an error. */ - if (lock_type == F_WRLCK) - { - ulong const binlog_format= thd->variables.binlog_format; - ulong const tx_isolation = thd_tx_isolation(current_thd); - if (tx_isolation <= ISO_READ_COMMITTED && - binlog_format == BINLOG_FORMAT_STMT) - { - char buf[256]; - my_snprintf(buf, sizeof(buf), - "Transaction level '%s' in" - " InnoDB is not safe for binlog mode '%s'", - tx_isolation_names[tx_isolation], - binlog_format_names[binlog_format]); - my_error(ER_BINLOG_LOGGING_IMPOSSIBLE, MYF(0), buf); - DBUG_RETURN(HA_ERR_LOGGING_IMPOSSIBLE); - } - } + /* Statement based binlogging does not work in isolation level + READ UNCOMMITTED and READ COMMITTED since the necessary + locks cannot be taken. In this case, we print an + informative error message and return with an error. */ + if (lock_type == F_WRLCK) + { + ulong const binlog_format= thd_binlog_format(thd); + ulong const tx_isolation = thd_tx_isolation(current_thd); + if (tx_isolation <= ISO_READ_COMMITTED && + binlog_format == BINLOG_FORMAT_STMT) + { + char buf[256]; + my_snprintf(buf, sizeof(buf), + "Transaction level '%s' in" + " InnoDB is not safe for binlog mode '%s'", + tx_isolation_names[tx_isolation], + binlog_format_names[binlog_format]); + my_error(ER_BINLOG_LOGGING_IMPOSSIBLE, MYF(0), buf); + DBUG_RETURN(HA_ERR_LOGGING_IMPOSSIBLE); + } + } trx = prebuilt->trx; @@ -6289,8 +6381,7 @@ ha_innobase::external_lock( prebuilt->sql_stat_start = TRUE; prebuilt->hint_need_to_fetch_extra_cols = 0; - prebuilt->read_just_key = 0; - prebuilt->keep_other_fields_on_keyread = FALSE; + reset_template(prebuilt); if (lock_type == F_WRLCK) { @@ -6348,17 +6439,17 @@ ha_innobase::external_lock( if (prebuilt->select_lock_type != LOCK_NONE) { - if (thd_in_lock_tables(thd) && - thd_sql_command(thd) == SQLCOM_LOCK_TABLES && - THDVAR(thd, table_locks) && - thd_test_options(thd, OPTION_NOT_AUTOCOMMIT)) { + if (thd_sql_command(thd) == SQLCOM_LOCK_TABLES + && THDVAR(thd, table_locks) + && thd_test_options(thd, OPTION_NOT_AUTOCOMMIT) + && thd_in_lock_tables(thd)) { ulint error = row_lock_table_for_mysql( prebuilt, NULL, 0); if (error != DB_SUCCESS) { error = convert_error_code_to_mysql( - (int) error, user_thd); + (int) error, thd); DBUG_RETURN((int) error); } } @@ -6374,6 +6465,12 @@ ha_innobase::external_lock( trx->n_mysql_tables_in_use--; prebuilt->mysql_has_locked = FALSE; + /* Release a possible FIFO ticket and search latch. Since we + may reserve the kernel mutex, we have to release the search + system latch first to obey the latching order. */ + + innobase_release_stat_resources(trx); + /* If the MySQL lock count drops to zero we know that the current SQL statement has ended */ @@ -6382,12 +6479,6 @@ ha_innobase::external_lock( trx->mysql_n_tables_locked = 0; prebuilt->used_in_HANDLER = FALSE; - /* Release a possible FIFO ticket and search latch. Since we - may reserve the kernel mutex, we have to release the search - system latch first to obey the latching order. */ - - innobase_release_stat_resources(trx); - if (!thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) { if (trx->active_trans != 0) { innobase_commit(ht, thd, TRUE); @@ -6429,8 +6520,7 @@ ha_innobase::transactional_table_lock( update_thd(thd); - if (prebuilt->table->ibd_file_missing - && !thd_tablespace_op(ha_thd())) { + if (prebuilt->table->ibd_file_missing && !thd_tablespace_op(thd)) { ut_print_timestamp(stderr); fprintf(stderr, " InnoDB error:\n" "MySQL is trying to use a table handle but the .ibd file for\n" @@ -6448,8 +6538,7 @@ ha_innobase::transactional_table_lock( prebuilt->sql_stat_start = TRUE; prebuilt->hint_need_to_fetch_extra_cols = 0; - prebuilt->read_just_key = 0; - prebuilt->keep_other_fields_on_keyread = FALSE; + reset_template(prebuilt); if (lock_type == F_WRLCK) { prebuilt->select_lock_type = LOCK_X; @@ -6475,13 +6564,13 @@ ha_innobase::transactional_table_lock( trx->active_trans = 1; } - if (thd_in_lock_tables(thd) && THDVAR(thd, table_locks)) { + if (THDVAR(thd, table_locks) && thd_in_lock_tables(thd)) { ulint error = DB_SUCCESS; error = row_lock_table_for_mysql(prebuilt, NULL, 0); if (error != DB_SUCCESS) { - error = convert_error_code_to_mysql((int) error, user_thd); + error = convert_error_code_to_mysql((int) error, thd); DBUG_RETURN((int) error); } @@ -6531,7 +6620,7 @@ innodb_show_status( DBUG_ENTER("innodb_show_status"); - trx = check_trx_exists(hton, thd); + trx = check_trx_exists(thd); innobase_release_stat_resources(trx); @@ -6809,7 +6898,7 @@ ha_innobase::store_lock( because we call update_thd() later, in ::external_lock()! Failure to understand this caused a serious memory corruption bug in 5.1.11. */ - trx = check_trx_exists(ht, thd); + trx = check_trx_exists(thd); /* NOTE: MySQL can call this function with lock 'type' TL_IGNORE! Be careful to ignore TL_IGNORE if we are going to do something with @@ -6819,9 +6908,9 @@ ha_innobase::store_lock( of the transaction. */ if (lock_type != TL_IGNORE - && trx->n_mysql_tables_in_use == 0) { + && trx->n_mysql_tables_in_use == 0) { trx->isolation_level = innobase_map_isolation_level( - (enum_tx_isolation)thd_tx_isolation(thd)); + (enum_tx_isolation) thd_tx_isolation(thd)); if (trx->isolation_level <= TRX_ISO_READ_COMMITTED && trx->global_read_view) { @@ -6843,12 +6932,12 @@ ha_innobase::store_lock( handle may belong to another thd that is running a query. Let us in that case skip any changes to the prebuilt struct. */ - } else if ((lock_type == TL_READ && in_lock_tables) || - (lock_type == TL_READ_HIGH_PRIORITY && in_lock_tables) || - lock_type == TL_READ_WITH_SHARED_LOCKS || - lock_type == TL_READ_NO_INSERT || - (sql_command != SQLCOM_SELECT - && lock_type != TL_IGNORE)) { + } else if ((lock_type == TL_READ && in_lock_tables) + || (lock_type == TL_READ_HIGH_PRIORITY && in_lock_tables) + || lock_type == TL_READ_WITH_SHARED_LOCKS + || lock_type == TL_READ_NO_INSERT + || (lock_type != TL_IGNORE + && sql_command != SQLCOM_SELECT)) { /* The OR cases above are in this order: 1) MySQL is doing LOCK TABLES ... READ LOCAL, or we @@ -6873,10 +6962,10 @@ ha_innobase::store_lock( isolation_level = trx->isolation_level; if ((srv_locks_unsafe_for_binlog - || isolation_level == TRX_ISO_READ_COMMITTED) - && isolation_level != TRX_ISO_SERIALIZABLE - && (lock_type == TL_READ || lock_type == TL_READ_NO_INSERT) - && (sql_command == SQLCOM_INSERT_SELECT + || isolation_level == TRX_ISO_READ_COMMITTED) + && isolation_level != TRX_ISO_SERIALIZABLE + && (lock_type == TL_READ || lock_type == TL_READ_NO_INSERT) + && (sql_command == SQLCOM_INSERT_SELECT || sql_command == SQLCOM_UPDATE || sql_command == SQLCOM_CREATE_TABLE)) { @@ -6947,24 +7036,25 @@ ha_innobase::store_lock( TRUE there). */ if ((lock_type >= TL_WRITE_CONCURRENT_INSERT - && lock_type <= TL_WRITE) - && !(in_lock_tables - && sql_command == SQLCOM_LOCK_TABLES) - && !thd_tablespace_op(thd) - && sql_command != SQLCOM_TRUNCATE - && sql_command != SQLCOM_OPTIMIZE + && lock_type <= TL_WRITE) + && !(in_lock_tables + && sql_command == SQLCOM_LOCK_TABLES) + && !thd_tablespace_op(thd) + && sql_command != SQLCOM_TRUNCATE + && sql_command != SQLCOM_OPTIMIZE #ifdef __WIN__ - /* For alter table on win32 for succesful operation - completion it is used TL_WRITE(=10) lock instead of - TL_WRITE_ALLOW_READ(=6), however here in innodb handler - TL_WRITE is lifted to TL_WRITE_ALLOW_WRITE, which causes - race condition when several clients do alter table - simultaneously (bug #17264). This fix avoids the problem. */ - && sql_command != SQLCOM_ALTER_TABLE + /* For alter table on win32 for successful + operation completion it is used TL_WRITE(=10) lock + instead of TL_WRITE_ALLOW_READ(=6), however here + in innodb handler TL_WRITE is lifted to + TL_WRITE_ALLOW_WRITE, which causes race condition + when several clients do alter table simultaneously + (bug #17264). This fix avoids the problem. */ + && sql_command != SQLCOM_ALTER_TABLE #endif - && sql_command != SQLCOM_CREATE_TABLE) { + && sql_command != SQLCOM_CREATE_TABLE) { lock_type = TL_WRITE_ALLOW_WRITE; } @@ -7009,11 +7099,16 @@ ha_innobase::innobase_read_and_init_auto_inc( longlong auto_inc; ulint old_select_lock_type; ibool trx_was_not_started = FALSE; + ibool stmt_start; int error; ut_a(prebuilt); ut_a(prebuilt->table); + /* Remember if we are in the beginning of an SQL statement. + This function must not change that flag. */ + stmt_start = prebuilt->sql_stat_start; + /* Prepare prebuilt->trx in the table handle */ update_thd(ha_thd()); @@ -7135,6 +7230,8 @@ func_exit_early: innobase_commit_low(prebuilt->trx); } + prebuilt->sql_stat_start = stmt_start; + return(error); } @@ -7206,7 +7303,7 @@ ha_innobase::reset_auto_increment(ulonglong value) bool ha_innobase::get_error_message(int error, String *buf) { - trx_t* trx = check_trx_exists(ht, ha_thd()); + trx_t* trx = check_trx_exists(ha_thd()); buf->copy(trx->detailed_error, strlen(trx->detailed_error), system_charset_info); @@ -7328,7 +7425,6 @@ ha_innobase::get_mysql_bin_log_pos() return(trx_sys_mysql_bin_log_pos); } -extern "C" { /********************************************************************** This function is used to find the storage length in bytes of the first n characters for prefix indexes using a multibyte character set. The function @@ -7337,7 +7433,7 @@ index field in bytes. NOTE: the prototype of this function is copied to data0type.c! If you change this function, you MUST change also data0type.c! */ - +extern "C" ulint innobase_get_at_most_n_mbchars( /*===========================*/ @@ -7402,39 +7498,6 @@ innobase_get_at_most_n_mbchars( return(char_length); } -} - -/********************************************************************** -This function returns true if - -1) SQL-query in the current thread -is either REPLACE or LOAD DATA INFILE REPLACE. - -2) SQL-query in the current thread -is INSERT ON DUPLICATE KEY UPDATE. - -NOTE that storage/innobase/row/row0ins.c must contain the -prototype for this function ! */ -extern "C" -ibool -innobase_query_is_update(void) -/*==========================*/ -{ - THD* thd = current_thd; - trx_t* trx; - - if (!thd) { - /* InnoDB's internal threads may run InnoDB stored procedures - that call this function. Then current_thd is not defined - (it is probably NULL). */ - - return(FALSE); - } - - trx = check_trx_exists(innodb_hton_ptr, thd); - - return(trx->allow_duplicates); -} /*********************************************************************** This function is used to prepare X/Open XA distributed transaction */ @@ -7450,7 +7513,7 @@ innobase_xa_prepare( FALSE - the current SQL statement ended */ { int error = 0; - trx_t* trx = check_trx_exists(hton, thd); + trx_t* trx = check_trx_exists(thd); if (thd_sql_command(thd) != SQLCOM_XA_PREPARE && (all || !thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) @@ -7484,7 +7547,7 @@ innobase_xa_prepare( return(0); } - trx->xid=thd->transaction.xid_state.xid; + thd_get_xid(thd, (MYSQL_XID*) &trx->xid); /* Release a possible FIFO ticket and search latch. Since we will reserve the kernel mutex, we have to release the search system latch @@ -7611,8 +7674,7 @@ innobase_create_cursor_view( handlerton *hton, /* in: innobase hton */ THD* thd) /* in: user thread handle */ { - return(read_cursor_view_create_for_mysql( - check_trx_exists(hton, thd))); + return(read_cursor_view_create_for_mysql(check_trx_exists(thd))); } /*********************************************************************** @@ -7627,8 +7689,8 @@ innobase_close_cursor_view( THD* thd, /* in: user thread handle */ void* curview)/* in: Consistent read view to be closed */ { - read_cursor_view_close_for_mysql(check_trx_exists(hton, current_thd), - (cursor_view_t*) curview); + read_cursor_view_close_for_mysql(check_trx_exists(thd), + (cursor_view_t*) curview); } /*********************************************************************** @@ -7644,8 +7706,8 @@ innobase_set_cursor_view( THD* thd, /* in: user thread handle */ void* curview)/* in: Consistent cursor view to be set */ { - read_cursor_set_for_mysql(check_trx_exists(hton, current_thd), - (cursor_view_t*) curview); + read_cursor_set_for_mysql(check_trx_exists(thd), + (cursor_view_t*) curview); } @@ -7728,8 +7790,9 @@ static MYSQL_SYSVAR_BOOL(file_per_table, innobase_file_per_table, static MYSQL_SYSVAR_ULONG(flush_log_at_trx_commit, srv_flush_log_at_trx_commit, PLUGIN_VAR_OPCMDARG, - "Set to 0 (write and flush once per second), 1 (write and flush at each commit)" - " or 2 (write at commit, flush once per second).", + "Set to 0 (write and flush once per second)," + " 1 (write and flush at each commit)" + " or 2 (write at commit, flush once per second).", NULL, NULL, 1, 0, 2, 0); static MYSQL_SYSVAR_STR(flush_method, innobase_unix_file_flush_method, @@ -7741,11 +7804,11 @@ static MYSQL_SYSVAR_BOOL(locks_unsafe_for_binlog, innobase_locks_unsafe_for_binl "Force InnoDB to not use next-key locking, to use only row-level locking.", NULL, NULL, FALSE); +#ifdef UNIV_LOG_ARCHIVE static MYSQL_SYSVAR_STR(log_arch_dir, innobase_log_arch_dir, PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, "Where full logs should be archived.", NULL, NULL, NULL); -#ifdef UNIV_LOG_ARCHIVE static MYSQL_SYSVAR_BOOL(log_archive, innobase_log_archive, PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_READONLY, "Set to 1 if you want to have logs archived.", NULL, NULL, FALSE); @@ -7883,8 +7946,8 @@ static struct st_mysql_sys_var* innobase_system_variables[]= { MYSQL_SYSVAR(force_recovery), MYSQL_SYSVAR(locks_unsafe_for_binlog), MYSQL_SYSVAR(lock_wait_timeout), - MYSQL_SYSVAR(log_arch_dir), #ifdef UNIV_LOG_ARCHIVE + MYSQL_SYSVAR(log_arch_dir), MYSQL_SYSVAR(log_archive), #endif /* UNIV_LOG_ARCHIVE */ MYSQL_SYSVAR(log_buffer_size), @@ -7922,5 +7985,3 @@ mysql_declare_plugin(innobase) NULL /* reserved */ } mysql_declare_plugin_end; - -#endif diff --git a/storage/innobase/handler/ha_innodb.h b/storage/innobase/handler/ha_innodb.h index c727243bfd3..b10cccded18 100644 --- a/storage/innobase/handler/ha_innodb.h +++ b/storage/innobase/handler/ha_innodb.h @@ -190,27 +190,50 @@ class ha_innobase: public handler uint table_changes); }; -extern long innobase_mirrored_log_groups, innobase_log_files_in_group; -extern long long innobase_buffer_pool_size, innobase_log_file_size; -extern long innobase_log_buffer_size; -extern long innobase_additional_mem_pool_size; -extern long innobase_buffer_pool_awe_mem_mb; -extern long innobase_file_io_threads, innobase_lock_wait_timeout; -extern long innobase_force_recovery; -extern long innobase_open_files; -extern char *innobase_data_home_dir, *innobase_data_file_path; -extern char *innobase_log_group_home_dir, *innobase_log_arch_dir; -extern char *innobase_unix_file_flush_method; +/* Some accessor functions which the InnoDB plugin needs, but which +can not be added to mysql/plugin.h as part of the public interface; +the definitions are bracketed with #ifdef INNODB_COMPATIBILITY_HOOKS */ + +#ifndef INNODB_COMPATIBILITY_HOOKS +#error InnoDB needs MySQL to be built with #define INNODB_COMPATIBILITY_HOOKS +#endif + extern "C" { -extern ulong srv_max_buf_pool_modified_pct; -extern ulong srv_max_purge_lag; -extern ulong srv_auto_extend_increment; -extern ulong srv_n_spin_wait_rounds; -extern ulong srv_n_free_tickets_to_enter; -extern ulong srv_thread_sleep_delay; -extern ulong srv_thread_concurrency; -extern ulong srv_commit_concurrency; -extern ulong srv_flush_log_at_trx_commit; +struct charset_info_st *thd_charset(MYSQL_THD thd); +char **thd_query(MYSQL_THD thd); + +/** Get the file name of the MySQL binlog. + * @return the name of the binlog file + */ +const char* mysql_bin_log_file_name(void); + +/** Get the current position of the MySQL binlog. + * @return byte offset from the beginning of the binlog + */ +ulonglong mysql_bin_log_file_pos(void); + +/** + Check if a user thread is a replication slave thread + @param thd user thread + @retval 0 the user thread is not a replication slave thread + @retval 1 the user thread is a replication slave thread +*/ +int thd_slave_thread(const MYSQL_THD thd); + +/** + Check if a user thread is running a non-transactional update + @param thd user thread + @retval 0 the user thread is not running a non-transactional update + @retval 1 the user thread is running a non-transactional update +*/ +int thd_non_transactional_update(const MYSQL_THD thd); + +/** + Get the user thread's binary logging format + @param thd user thread + @return Value to be used as index into the binlog_format_names array +*/ +int thd_binlog_format(const MYSQL_THD thd); } /* diff --git a/storage/innobase/ibuf/Makefile.am b/storage/innobase/ibuf/Makefile.am deleted file mode 100644 index 42adda9a4ef..00000000000 --- a/storage/innobase/ibuf/Makefile.am +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (C) 2001, 2003 MySQL AB & Innobase Oy -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -include ../include/Makefile.i - -noinst_LIBRARIES = libibuf.a - -libibuf_a_SOURCES = ibuf0ibuf.c - -EXTRA_PROGRAMS = - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/storage/innobase/ibuf/ibuf0ibuf.c b/storage/innobase/ibuf/ibuf0ibuf.c index 1cbb6003cfc..4e291924e0e 100644 --- a/storage/innobase/ibuf/ibuf0ibuf.c +++ b/storage/innobase/ibuf/ibuf0ibuf.c @@ -150,9 +150,30 @@ ulint ibuf_flush_count = 0; #define IBUF_COUNT_N_PAGES 2000 /* Buffered entry counts for file pages, used in debugging */ -static ulint* ibuf_counts[IBUF_COUNT_N_SPACES]; +static ulint ibuf_counts[IBUF_COUNT_N_SPACES][IBUF_COUNT_N_PAGES]; -static ibool ibuf_counts_inited = FALSE; +/********************************************************************** +Checks that the indexes to ibuf_counts[][] are within limits. */ +UNIV_INLINE +void +ibuf_count_check( +/*=============*/ + ulint space_id, /* in: space identifier */ + ulint page_no) /* in: page number */ +{ + if (space_id < IBUF_COUNT_N_SPACES && page_no < IBUF_COUNT_N_PAGES) { + return; + } + + fprintf(stderr, + "InnoDB: UNIV_IBUF_DEBUG limits space_id and page_no\n" + "InnoDB: and breaks crash recovery.\n" + "InnoDB: space_id=%lu, should be 0<=space_id<%lu\n" + "InnoDB: page_no=%lu, should be 0<=page_no<%lu\n", + (ulint) space_id, (ulint) IBUF_COUNT_N_SPACES, + (ulint) page_no, (ulint) IBUF_COUNT_N_PAGES); + ut_error; +} #endif /* The start address for an insert buffer bitmap page bitmap */ @@ -328,15 +349,9 @@ ibuf_count_get( ulint space, /* in: space id */ ulint page_no)/* in: page number */ { - ut_ad(space < IBUF_COUNT_N_SPACES); - ut_ad(page_no < IBUF_COUNT_N_PAGES); - - if (!ibuf_counts_inited) { - - return(0); - } + ibuf_count_check(space, page_no); - return(*(ibuf_counts[space] + page_no)); + return(ibuf_counts[space][page_no]); } /********************************************************************** @@ -349,11 +364,10 @@ ibuf_count_set( ulint page_no,/* in: page number */ ulint val) /* in: value to set */ { - ut_a(space < IBUF_COUNT_N_SPACES); - ut_a(page_no < IBUF_COUNT_N_PAGES); + ibuf_count_check(space, page_no); ut_a(val < UNIV_PAGE_SIZE); - *(ibuf_counts[space] + page_no) = val; + ibuf_counts[space][page_no] = val; } #endif @@ -378,22 +392,6 @@ ibuf_init_at_db_start(void) ibuf->size = 0; -#ifdef UNIV_IBUF_DEBUG - { - ulint i, j; - - for (i = 0; i < IBUF_COUNT_N_SPACES; i++) { - - ibuf_counts[i] = mem_alloc(sizeof(ulint) - * IBUF_COUNT_N_PAGES); - for (j = 0; j < IBUF_COUNT_N_PAGES; j++) { - ibuf_count_set(i, j, 0); - } - } - - ibuf_counts_inited = TRUE; - } -#endif mutex_create(&ibuf_pessimistic_insert_mutex, SYNC_IBUF_PESS_INSERT_MUTEX); @@ -567,7 +565,8 @@ ibuf_bitmap_page_init( bit_offset = XDES_DESCRIBED_PER_PAGE * IBUF_BITS_PER_PAGE; - byte_offset = bit_offset / 8 + 1; /* better: (bit_offset + 7) / 8 */ + byte_offset = bit_offset / 8 + 1; + /* better: byte_offset = UT_BITS_IN_BYTES(bit_offset); */ fil_page_set_type(page, FIL_PAGE_IBUF_BITMAP); @@ -1441,6 +1440,9 @@ ibuf_entry_build( *buf2++ = 0; /* write the compact format indicator */ } for (i = 0; i < n_fields; i++) { + ulint fixed_len; + const dict_field_t* ifield; + /* We add 4 below because we have the 4 extra fields at the start of an ibuf record */ @@ -1448,10 +1450,30 @@ ibuf_entry_build( entry_field = dtuple_get_nth_field(entry, i); dfield_copy(field, entry_field); + ifield = dict_index_get_nth_field(index, i); + /* Prefix index columns of fixed-length columns are of + fixed length. However, in the function call below, + dfield_get_type(entry_field) contains the fixed length + of the column in the clustered index. Replace it with + the fixed length of the secondary index column. */ + fixed_len = ifield->fixed_len; + +#ifdef UNIV_DEBUG + if (fixed_len) { + /* dict_index_add_col() should guarantee these */ + ut_ad(fixed_len <= (ulint) entry_field->type.len); + if (ifield->prefix_len) { + ut_ad(ifield->prefix_len == fixed_len); + } else { + ut_ad(fixed_len + == (ulint) entry_field->type.len); + } + } +#endif /* UNIV_DEBUG */ + dtype_new_store_for_order_and_null_size( buf2 + i * DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE, - dfield_get_type(entry_field), - dict_index_get_nth_field(index, i)->prefix_len); + dfield_get_type(entry_field), fixed_len); } /* Store the type info in buf2 to field 3 of tuple */ diff --git a/storage/innobase/include/Makefile.i b/storage/innobase/include/Makefile.i deleted file mode 100644 index db436c702ff..00000000000 --- a/storage/innobase/include/Makefile.i +++ /dev/null @@ -1,10 +0,0 @@ -# Makefile included in Makefile.am in every subdirectory - -INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/include \ - -I$(top_srcdir)/regex \ - -I$(top_srcdir)/storage/innobase/include \ - -I$(top_srcdir)/sql \ - -I$(srcdir) - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/storage/innobase/include/db0err.h b/storage/innobase/include/db0err.h index 843c70af577..0aa1b87e470 100644 --- a/storage/innobase/include/db0err.h +++ b/storage/innobase/include/db0err.h @@ -62,6 +62,11 @@ Created 5/24/1996 Heikki Tuuri lead to a duplicate key in some table */ +#define DB_TOO_MANY_CONCURRENT_TRXS 47 /* when InnoDB runs out of the + preconfigured undo slots, this can + only happen when there are too many + concurrent transactions */ + /* The following are partial failure codes */ #define DB_FAIL 1000 #define DB_OVERFLOW 1001 diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h index 836a6290498..eb31043ecc3 100644 --- a/storage/innobase/include/dict0dict.h +++ b/storage/innobase/include/dict0dict.h @@ -92,6 +92,17 @@ dict_col_copy_type_noninline( /*=========================*/ const dict_col_t* col, /* in: column */ dtype_t* type); /* out: data type */ +#ifdef UNIV_DEBUG +/************************************************************************* +Assert that a column and a data type match. */ +UNIV_INLINE +ibool +dict_col_type_assert_equal( +/*=======================*/ + /* out: TRUE */ + const dict_col_t* col, /* in: column */ + const dtype_t* type); /* in: data type */ +#endif /* UNIV_DEBUG */ /*************************************************************************** Returns the minimum size of the column. */ UNIV_INLINE diff --git a/storage/innobase/include/dict0dict.ic b/storage/innobase/include/dict0dict.ic index 4a9afd2f3f5..7d38cbcd1fa 100644 --- a/storage/innobase/include/dict0dict.ic +++ b/storage/innobase/include/dict0dict.ic @@ -30,6 +30,30 @@ dict_col_copy_type( type->mbmaxlen = col->mbmaxlen; } +#ifdef UNIV_DEBUG +/************************************************************************* +Assert that a column and a data type match. */ +UNIV_INLINE +ibool +dict_col_type_assert_equal( +/*=======================*/ + /* out: TRUE */ + const dict_col_t* col, /* in: column */ + const dtype_t* type) /* in: data type */ +{ + ut_ad(col); + ut_ad(type); + + ut_ad(col->mtype == type->mtype); + ut_ad(col->prtype == type->prtype); + ut_ad(col->len == type->len); + ut_ad(col->mbminlen == type->mbminlen); + ut_ad(col->mbmaxlen == type->mbmaxlen); + + return(TRUE); +} +#endif /* UNIV_DEBUG */ + /*************************************************************************** Returns the minimum size of the column. */ UNIV_INLINE diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h index a23f89954a4..647035c2fff 100644 --- a/storage/innobase/include/dict0mem.h +++ b/storage/innobase/include/dict0mem.h @@ -158,10 +158,13 @@ struct dict_col_struct{ of an index */ }; -/* DICT_MAX_INDEX_COL_LEN is measured in bytes and is the max index column -length + 1. Starting from 4.1.6, we set it to < 3 * 256, so that one can -create a column prefix index on 255 characters of a TEXT field also in the -UTF-8 charset. In that charset, a character may take at most 3 bytes. */ +/* DICT_MAX_INDEX_COL_LEN is measured in bytes and is the maximum +indexed column length (or indexed prefix length). It is set to 3*256, +so that one can create a column prefix index on 256 characters of a +TEXT or VARCHAR column also in the UTF-8 charset. In that charset, +a character may take at most 3 bytes. +This constant MUST NOT BE CHANGED, or the compatibility of InnoDB data +files would be at risk! */ #define DICT_MAX_INDEX_COL_LEN 768 diff --git a/storage/innobase/include/ha_prototypes.h b/storage/innobase/include/ha_prototypes.h index 2d27034fdfe..7fb50988941 100644 --- a/storage/innobase/include/ha_prototypes.h +++ b/storage/innobase/include/ha_prototypes.h @@ -1,6 +1,9 @@ #ifndef HA_INNODB_PROTOTYPES_H #define HA_INNODB_PROTOTYPES_H +#include "univ.i" /* ulint, uint */ +#include "m_ctype.h" /* CHARSET_INFO */ + /* Prototypes for global functions in ha_innodb.cc that are called by InnoDB's C-code. */ @@ -19,4 +22,30 @@ innobase_convert_string( CHARSET_INFO* from_cs, uint* errors); +/********************************************************************** +Returns true if the thread is the replication thread on the slave +server. Used in srv_conc_enter_innodb() to determine if the thread +should be allowed to enter InnoDB - the replication thread is treated +differently than other threads. Also used in +srv_conc_force_exit_innodb(). */ + +ibool +thd_is_replication_slave_thread( +/*============================*/ + /* out: true if thd is the replication thread */ + void* thd); /* in: thread handle (THD*) */ + +/********************************************************************** +Returns true if the transaction this thread is processing has edited +non-transactional tables. Used by the deadlock detector when deciding +which transaction to rollback in case of a deadlock - we try to avoid +rolling back transactions that have edited non-transactional tables. */ + +ibool +thd_has_edited_nontrans_tables( +/*===========================*/ + /* out: true if non-transactional tables have + been edited */ + void* thd); /* in: thread handle (THD*) */ + #endif diff --git a/storage/innobase/include/os0file.h b/storage/innobase/include/os0file.h index 5ffcdf7e58c..9eb44d3f4a8 100644 --- a/storage/innobase/include/os0file.h +++ b/storage/innobase/include/os0file.h @@ -94,7 +94,8 @@ log. */ #define OS_FILE_PATH_ERROR 74 #define OS_FILE_AIO_RESOURCES_RESERVED 75 /* wait for OS aio resources to become available again */ -#define OS_FILE_ERROR_NOT_SPECIFIED 76 +#define OS_FILE_SHARING_VIOLATION 76 +#define OS_FILE_ERROR_NOT_SPECIFIED 77 /* Types for aio operations */ #define OS_FILE_READ 10 diff --git a/storage/innobase/include/rem0rec.ic b/storage/innobase/include/rem0rec.ic index 90a35af74dc..95aa65fabba 100644 --- a/storage/innobase/include/rem0rec.ic +++ b/storage/innobase/include/rem0rec.ic @@ -795,7 +795,8 @@ UNIV_INLINE void rec_offs_set_n_alloc( /*=================*/ - ulint* offsets, /* in: array for rec_get_offsets() */ + ulint* offsets, /* out: array for rec_get_offsets(), + must be allocated */ ulint n_alloc) /* in: number of elements */ { ut_ad(offsets); @@ -1282,7 +1283,8 @@ UNIV_INLINE void rec_offs_set_n_fields( /*==================*/ - ulint* offsets, /* in: array returned by rec_get_offsets() */ + ulint* offsets, /* in/out: array returned by + rec_get_offsets() */ ulint n_fields) /* in: number of fields */ { ut_ad(offsets); diff --git a/storage/innobase/include/row0mysql.h b/storage/innobase/include/row0mysql.h index 1448efe94fe..bda3494073f 100644 --- a/storage/innobase/include/row0mysql.h +++ b/storage/innobase/include/row0mysql.h @@ -460,6 +460,19 @@ row_check_table_for_mysql( /* out: DB_ERROR or DB_SUCCESS */ row_prebuilt_t* prebuilt); /* in: prebuilt struct in MySQL handle */ +/************************************************************************* +Get the min of the maximum possible row sizes. */ + +ulint +page_get_free_space_of_empty_noninline( +/*===================================*/ + /* out: The (approx) maximum size + of a row, this is a conservative + estimate, since the size can be + slightly larger depending upon + the ROW_FORMAT setting.*/ + dict_table_t* table); /* in: table for which max record + size required.*/ /* A struct describing a place for an individual column in the MySQL row format which is presented to the table handler in ha_innobase. diff --git a/storage/innobase/include/trx0trx.h b/storage/innobase/include/trx0trx.h index e75c200cc3a..eeda2a7a52c 100644 --- a/storage/innobase/include/trx0trx.h +++ b/storage/innobase/include/trx0trx.h @@ -371,6 +371,18 @@ trx_is_interrupted( #define trx_is_interrupted(trx) FALSE #endif /* !UNIV_HOTBACKUP */ +/*********************************************************************** +Compares the "weight" (or size) of two transactions. The weight of one +transaction is estimated as the number of altered rows + the number of +locked rows. Transactions that have edited non-transactional tables are +considered heavier than ones that have not. */ + +int +trx_weight_cmp( +/*===========*/ + /* out: <0, 0 or >0; similar to strcmp(3) */ + trx_t* a, /* in: the first transaction to be compared */ + trx_t* b); /* in: the second transaction to be compared */ /* Signal to a transaction */ struct trx_sig_struct{ @@ -453,7 +465,8 @@ struct trx_struct{ dulint table_id; /* table id if the preceding field is TRUE */ /*------------------------------*/ - int active_trans; /* 1 - if a transaction in MySQL + unsigned duplicates:2; /* TRX_DUP_IGNORE | TRX_DUP_REPLACE */ + unsigned active_trans:2; /* 1 - if a transaction in MySQL is active. 2 - if prepare_commit_mutex was taken */ void* mysql_thd; /* MySQL thread handle corresponding @@ -610,7 +623,7 @@ struct trx_struct{ NULL */ ibool was_chosen_as_deadlock_victim; /* when the transaction decides to wait - for a lock, this it sets this to FALSE; + for a lock, it sets this to FALSE; if another transaction chooses this transaction as a victim in deadlock resolution, it sets this to TRUE */ @@ -651,7 +664,12 @@ struct trx_struct{ cannot be any activity in the undo logs! */ dulint undo_no; /* next undo log record number to - assign */ + assign; since the undo log is + private for a transaction, this + is a simple ascending sequence + with no gaps; thus it represents + the number of modified/inserted + rows in a transaction */ trx_savept_t last_sql_stat_start; /* undo_no when the last sql statement was started: in case of an error, trx @@ -681,19 +699,19 @@ struct trx_struct{ single operation of a transaction, e.g., a parallel query */ -/* Transaction concurrency states */ +/* Transaction concurrency states (trx->conc_state) */ #define TRX_NOT_STARTED 1 #define TRX_ACTIVE 2 #define TRX_COMMITTED_IN_MEMORY 3 #define TRX_PREPARED 4 /* Support for 2PC/XA */ -/* Transaction execution states when trx state is TRX_ACTIVE */ +/* Transaction execution states when trx->conc_state == TRX_ACTIVE */ #define TRX_QUE_RUNNING 1 /* transaction is running */ #define TRX_QUE_LOCK_WAIT 2 /* transaction is waiting for a lock */ #define TRX_QUE_ROLLING_BACK 3 /* transaction is rolling back */ #define TRX_QUE_COMMITTING 4 /* transaction is committing */ -/* Transaction isolation levels */ +/* Transaction isolation levels (trx->isolation_level) */ #define TRX_ISO_READ_UNCOMMITTED 1 /* dirty read: non-locking SELECTs are performed so that we do not look at a possible @@ -728,6 +746,12 @@ struct trx_struct{ converted to LOCK IN SHARE MODE reads */ +/* Treatment of duplicate values (trx->duplicates; for example, in inserts). +Multiple flags can be combined with bitwise OR. */ +#define TRX_DUP_IGNORE 1 /* duplicate rows are to be updated */ +#define TRX_DUP_REPLACE 2 /* duplicate rows are to be replaced */ + + /* Types of a trx signal */ #define TRX_SIG_NO_SIGNAL 100 #define TRX_SIG_TOTAL_ROLLBACK 1 diff --git a/storage/innobase/include/trx0undo.h b/storage/innobase/include/trx0undo.h index 87849ab42c3..f53c6b01be4 100644 --- a/storage/innobase/include/trx0undo.h +++ b/storage/innobase/include/trx0undo.h @@ -222,13 +222,16 @@ trx_undo_lists_init( Assigns an undo log for a transaction. A new undo log is created or a cached undo log reused. */ -trx_undo_t* +ulint trx_undo_assign_undo( /*=================*/ - /* out: the undo log, NULL if did not succeed: out of - space */ - trx_t* trx, /* in: transaction */ - ulint type); /* in: TRX_UNDO_INSERT or TRX_UNDO_UPDATE */ + /* out: DB_SUCCESS if undo log assign + * successful, possible error codes are: + * ER_TOO_MANY_CONCURRENT_TRXS + * DB_OUT_OF_FILE_SPAC + * DB_OUT_OF_MEMORY */ + trx_t* trx, /* in: transaction */ + ulint type); /* in: TRX_UNDO_INSERT or TRX_UNDO_UPDATE */ /********************************************************************** Sets the state of the undo log segment at a transaction finish. */ diff --git a/storage/innobase/include/ut0ut.h b/storage/innobase/include/ut0ut.h index 8bfc1edd323..825c10d5f11 100644 --- a/storage/innobase/include/ut0ut.h +++ b/storage/innobase/include/ut0ut.h @@ -121,6 +121,11 @@ ut_2_power_up( /* out: first power of 2 which is >= n */ ulint n) /* in: number != 0 */ __attribute__((const)); + +/* Determine how many bytes (groups of 8 bits) are needed to +store the given number of bits. */ +#define UT_BITS_IN_BYTES(b) (((b) + 7) / 8) + /**************************************************************** Sort function for ulint arrays. */ diff --git a/storage/innobase/lock/Makefile.am b/storage/innobase/lock/Makefile.am deleted file mode 100644 index 4c6caa49853..00000000000 --- a/storage/innobase/lock/Makefile.am +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (C) 2001, 2003 MySQL AB & Innobase Oy -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -include ../include/Makefile.i - -noinst_LIBRARIES = liblock.a - -liblock_a_SOURCES = lock0lock.c - -EXTRA_PROGRAMS = - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/storage/innobase/lock/lock0lock.c b/storage/innobase/lock/lock0lock.c index 93a43d9a30f..6f5390145b5 100644 --- a/storage/innobase/lock/lock0lock.c +++ b/storage/innobase/lock/lock0lock.c @@ -3174,7 +3174,8 @@ lock_deadlock_occurs( ulint ret; ulint cost = 0; - ut_ad(trx && lock); + ut_ad(trx); + ut_ad(lock); ut_ad(mutex_own(&kernel_mutex)); retry: /* We check that adding this trx to the waits-for graph @@ -3246,7 +3247,9 @@ lock_deadlock_recursive( trx_t* lock_trx; ulint ret; - ut_a(trx && start && wait_lock); + ut_a(trx); + ut_a(start); + ut_a(wait_lock); ut_ad(mutex_own(&kernel_mutex)); if (trx->deadlock_mark == 1) { @@ -3357,8 +3360,8 @@ lock_deadlock_recursive( return(LOCK_VICTIM_IS_START); } - if (ut_dulint_cmp(wait_lock->trx->undo_no, - start->undo_no) >= 0) { + if (trx_weight_cmp(wait_lock->trx, + start) >= 0) { /* Our recursion starting point transaction is 'smaller', let us choose 'start' as the victim and roll @@ -4423,12 +4426,9 @@ lock_table_queue_validate( dict_table_t* table) /* in: table */ { lock_t* lock; - ibool is_waiting; ut_ad(mutex_own(&kernel_mutex)); - is_waiting = FALSE; - lock = UT_LIST_GET_FIRST(table->locks); while (lock) { @@ -4438,13 +4438,10 @@ lock_table_queue_validate( if (!lock_get_wait(lock)) { - ut_a(!is_waiting); - ut_a(!lock_table_other_has_incompatible( lock->trx, 0, table, lock_get_mode(lock))); } else { - is_waiting = TRUE; ut_a(lock_table_has_to_wait_in_queue(lock)); } diff --git a/storage/innobase/log/Makefile.am b/storage/innobase/log/Makefile.am deleted file mode 100644 index a40572a64da..00000000000 --- a/storage/innobase/log/Makefile.am +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (C) 2001, 2003 MySQL AB & Innobase Oy -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -include ../include/Makefile.i - -noinst_LIBRARIES = liblog.a - -liblog_a_SOURCES = log0log.c log0recv.c - -EXTRA_PROGRAMS = - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/storage/innobase/log/log0log.c b/storage/innobase/log/log0log.c index e9dedf6aac4..b10c348b24d 100644 --- a/storage/innobase/log/log0log.c +++ b/storage/innobase/log/log0log.c @@ -3039,10 +3039,22 @@ loop: mutex_enter(&kernel_mutex); - /* Check that there are no longer transactions. We need this wait - even for the 'very fast' shutdown, because the InnoDB layer may have - committed or prepared transactions and we don't want to lose - them. */ + /* We need the monitor threads to stop before we proceed with a + normal shutdown. In case of very fast shutdown, however, we can + proceed without waiting for monitor threads. */ + + if (srv_fast_shutdown < 2 + && (srv_error_monitor_active + || srv_lock_timeout_and_monitor_active)) { + + mutex_exit(&kernel_mutex); + + goto loop; + } + + /* Check that there are no longer transactions. We need this wait even + for the 'very fast' shutdown, because the InnoDB layer may have + committed or prepared transactions and we don't want to lose them. */ if (trx_n_mysql_transactions > 0 || UT_LIST_GET_LEN(trx_sys->trx_list) > 0) { @@ -3163,22 +3175,8 @@ loop: goto loop; } - /* The lock timeout thread should now have exited */ - - if (srv_lock_timeout_and_monitor_active) { - - goto loop; - } - - /* We now let also the InnoDB error monitor thread to exit */ - srv_shutdown_state = SRV_SHUTDOWN_LAST_PHASE; - if (srv_error_monitor_active) { - - goto loop; - } - /* Make some checks that the server really is quiet */ ut_a(srv_n_threads_active[SRV_MASTER] == 0); ut_a(buf_all_freed()); diff --git a/storage/innobase/mach/Makefile.am b/storage/innobase/mach/Makefile.am deleted file mode 100644 index 1a59cb3e4d7..00000000000 --- a/storage/innobase/mach/Makefile.am +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (C) 2001, 2003 MySQL AB & Innobase Oy -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -include ../include/Makefile.i - -noinst_LIBRARIES = libmach.a - -libmach_a_SOURCES = mach0data.c - -EXTRA_PROGRAMS = - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/storage/innobase/mem/Makefile.am b/storage/innobase/mem/Makefile.am deleted file mode 100644 index 598dbb96124..00000000000 --- a/storage/innobase/mem/Makefile.am +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright (C) 2001, 2003 MySQL AB & Innobase Oy -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -include ../include/Makefile.i - -noinst_LIBRARIES = libmem.a - -libmem_a_SOURCES = mem0mem.c mem0pool.c - -EXTRA_DIST = mem0dbg.c - -EXTRA_PROGRAMS = - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/storage/innobase/mtr/Makefile.am b/storage/innobase/mtr/Makefile.am deleted file mode 100644 index 80eb7c907be..00000000000 --- a/storage/innobase/mtr/Makefile.am +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (C) 2001, 2003 MySQL AB & Innobase Oy -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -include ../include/Makefile.i - -noinst_LIBRARIES = libmtr.a - -libmtr_a_SOURCES = mtr0mtr.c mtr0log.c - -EXTRA_PROGRAMS = - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/storage/innobase/os/Makefile.am b/storage/innobase/os/Makefile.am deleted file mode 100644 index d5c45eba54e..00000000000 --- a/storage/innobase/os/Makefile.am +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (C) 2001, 2003-2004 MySQL AB & Innobase Oy -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -include ../include/Makefile.i - -noinst_LIBRARIES = libos.a - -libos_a_SOURCES = os0proc.c os0sync.c os0thread.c os0file.c - -EXTRA_PROGRAMS = - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/storage/innobase/os/os0file.c b/storage/innobase/os/os0file.c index c18ba047d4e..f496e1127ce 100644 --- a/storage/innobase/os/os0file.c +++ b/storage/innobase/os/os0file.c @@ -250,6 +250,15 @@ os_file_get_last_error( "InnoDB: the directory. It may also be" " you have created a subdirectory\n" "InnoDB: of the same name as a data file.\n"); + } else if (err == ERROR_SHARING_VIOLATION + || err == ERROR_LOCK_VIOLATION) { + fprintf(stderr, + "InnoDB: The error means that another program" + " is using InnoDB's files.\n" + "InnoDB: This might be a backup or antivirus" + " software or another instance\n" + "InnoDB: of MySQL." + " Please close it to get rid of this error.\n"); } else { fprintf(stderr, "InnoDB: Some operating system error numbers" @@ -268,6 +277,9 @@ os_file_get_last_error( return(OS_FILE_DISK_FULL); } else if (err == ERROR_FILE_EXISTS) { return(OS_FILE_ALREADY_EXISTS); + } else if (err == ERROR_SHARING_VIOLATION + || err == ERROR_LOCK_VIOLATION) { + return(OS_FILE_SHARING_VIOLATION); } else { return(100 + err); } @@ -388,6 +400,10 @@ os_file_handle_error_cond_exit( || err == OS_FILE_PATH_ERROR) { return(FALSE); + } else if (err == OS_FILE_SHARING_VIOLATION) { + + os_thread_sleep(10000000); /* 10 sec */ + return(TRUE); } else { if (name) { fprintf(stderr, "InnoDB: File name %s\n", name); diff --git a/storage/innobase/page/Makefile.am b/storage/innobase/page/Makefile.am deleted file mode 100644 index 1a5b202a2c9..00000000000 --- a/storage/innobase/page/Makefile.am +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (C) 2001, 2003 MySQL AB & Innobase Oy -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -include ../include/Makefile.i - -noinst_LIBRARIES = libpage.a - -libpage_a_SOURCES = page0page.c page0cur.c - -EXTRA_PROGRAMS = - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/storage/innobase/pars/Makefile.am b/storage/innobase/pars/Makefile.am deleted file mode 100644 index b10796c3d5e..00000000000 --- a/storage/innobase/pars/Makefile.am +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright (C) 2001, 2003 MySQL AB & Innobase Oy -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -include ../include/Makefile.i - -noinst_LIBRARIES = libpars.a - -noinst_HEADERS = pars0grm.h - -libpars_a_SOURCES = pars0grm.c lexyy.c pars0opt.c pars0pars.c pars0sym.c - -EXTRA_PROGRAMS = - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/storage/innobase/plug.in b/storage/innobase/plug.in index 59634523399..6e26a7d3376 100644 --- a/storage/innobase/plug.in +++ b/storage/innobase/plug.in @@ -2,6 +2,7 @@ MYSQL_STORAGE_ENGINE(innobase, innodb, [InnoDB Storage Engine], [Transactional Tables using InnoDB], [max,max-no-ndb]) MYSQL_PLUGIN_DIRECTORY(innobase, [storage/innobase]) MYSQL_PLUGIN_STATIC(innobase, [libinnobase.a]) +MYSQL_PLUGIN_DYNAMIC(innobase, [ha_innodb.la]) MYSQL_PLUGIN_ACTIONS(innobase, [ AC_CHECK_LIB(rt, aio_read, [innodb_system_libs="-lrt"]) AC_SUBST(innodb_system_libs) @@ -38,37 +39,5 @@ MYSQL_PLUGIN_ACTIONS(innobase, [ openbsd*) CFLAGS="$CFLAGS -DUNIV_MUST_NOT_INLINE";; esac - AC_CONFIG_FILES( - storage/innobase/ut/Makefile - storage/innobase/btr/Makefile - storage/innobase/buf/Makefile - storage/innobase/data/Makefile - storage/innobase/dict/Makefile - storage/innobase/dyn/Makefile - storage/innobase/eval/Makefile - storage/innobase/fil/Makefile - storage/innobase/fsp/Makefile - storage/innobase/fut/Makefile - storage/innobase/ha/Makefile - storage/innobase/ibuf/Makefile - storage/innobase/lock/Makefile - storage/innobase/log/Makefile - storage/innobase/mach/Makefile - storage/innobase/mem/Makefile - storage/innobase/mtr/Makefile - storage/innobase/os/Makefile - storage/innobase/page/Makefile - storage/innobase/pars/Makefile - storage/innobase/que/Makefile - storage/innobase/read/Makefile - storage/innobase/rem/Makefile - storage/innobase/row/Makefile - storage/innobase/srv/Makefile - storage/innobase/sync/Makefile - storage/innobase/thr/Makefile - storage/innobase/trx/Makefile - storage/innobase/handler/Makefile - storage/innobase/usr/Makefile) ]) -MYSQL_PLUGIN_DEPENDS_ON_MYSQL_INTERNALS(innobase, [handler/ha_innodb.cc]) diff --git a/storage/innobase/que/Makefile.am b/storage/innobase/que/Makefile.am deleted file mode 100644 index 73f3fb07af4..00000000000 --- a/storage/innobase/que/Makefile.am +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (C) 2001, 2003 MySQL AB & Innobase Oy -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -include ../include/Makefile.i - -noinst_LIBRARIES = libque.a - -libque_a_SOURCES = que0que.c - -EXTRA_PROGRAMS = - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/storage/innobase/read/Makefile.am b/storage/innobase/read/Makefile.am deleted file mode 100644 index 1e56a9716c3..00000000000 --- a/storage/innobase/read/Makefile.am +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (C) 2001, 2003 MySQL AB & Innobase Oy -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -include ../include/Makefile.i - -noinst_LIBRARIES = libread.a - -libread_a_SOURCES = read0read.c - -EXTRA_PROGRAMS = - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/storage/innobase/rem/Makefile.am b/storage/innobase/rem/Makefile.am deleted file mode 100644 index 1026172b815..00000000000 --- a/storage/innobase/rem/Makefile.am +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (C) 2001, 2003 MySQL AB & Innobase Oy -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -include ../include/Makefile.i - -noinst_LIBRARIES = librem.a - -librem_a_SOURCES = rem0rec.c rem0cmp.c - -EXTRA_PROGRAMS = - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/storage/innobase/rem/rem0rec.c b/storage/innobase/rem/rem0rec.c index 549b5ee8b28..3bc73eca9ea 100644 --- a/storage/innobase/rem/rem0rec.c +++ b/storage/innobase/rem/rem0rec.c @@ -153,7 +153,6 @@ static void rec_init_offsets( /*=============*/ - /* out: the offsets */ rec_t* rec, /* in: physical record */ dict_index_t* index, /* in: record descriptor */ ulint* offsets)/* in/out: array of offsets; @@ -189,7 +188,7 @@ rec_init_offsets( } nulls = rec - (REC_N_NEW_EXTRA_BYTES + 1); - lens = nulls - (index->n_nullable + 7) / 8; + lens = nulls - UT_BITS_IN_BYTES(index->n_nullable); offs = 0; null_mask = 1; @@ -304,7 +303,7 @@ rec_get_offsets_func( /* out: the new offsets */ rec_t* rec, /* in: physical record */ dict_index_t* index, /* in: record descriptor */ - ulint* offsets,/* in: array consisting of offsets[0] + ulint* offsets,/* in/out: array consisting of offsets[0] allocated elements, or an array from rec_get_offsets(), or NULL */ ulint n_fields,/* in: maximum number of initialized fields @@ -440,7 +439,7 @@ rec_get_converted_size_new( dtuple_t* dtuple) /* in: data tuple */ { ulint size = REC_N_NEW_EXTRA_BYTES - + (index->n_nullable + 7) / 8; + + UT_BITS_IN_BYTES(index->n_nullable); ulint i; ulint n_fields; ut_ad(index && dtuple); @@ -459,10 +458,10 @@ rec_get_converted_size_new( break; case REC_STATUS_INFIMUM: case REC_STATUS_SUPREMUM: - /* infimum or supremum record, 8 bytes */ - return(size + 8); /* no extra data needed */ + /* infimum or supremum record, 8 data bytes */ + return(REC_N_NEW_EXTRA_BYTES + 8); default: - ut_a(0); + ut_error; return(ULINT_UNDEFINED); } @@ -476,21 +475,31 @@ rec_get_converted_size_new( len = dtuple_get_nth_field(dtuple, i)->len; col = dict_field_get_col(field); - ut_ad(len != UNIV_SQL_NULL || !(col->prtype & DATA_NOT_NULL)); + ut_ad(dict_col_type_assert_equal( + col, dfield_get_type(dtuple_get_nth_field( + dtuple, i)))); if (len == UNIV_SQL_NULL) { /* No length is stored for NULL fields. */ + ut_ad(!(col->prtype & DATA_NOT_NULL)); continue; } ut_ad(len <= col->len || col->mtype == DATA_BLOB); - ut_ad(!field->fixed_len || len == field->fixed_len); if (field->fixed_len) { + ut_ad(len == field->fixed_len); + /* dict_index_add_col() should guarantee this */ + ut_ad(!field->prefix_len + || field->fixed_len == field->prefix_len); } else if (len < 128 || (col->len < 256 && col->mtype != DATA_BLOB)) { size++; } else { + /* For variable-length columns, we look up the + maximum length from the column itself. If this + is a prefix index column shorter than 256 bytes, + this will waste one byte. */ size += 2; } size += len; @@ -586,7 +595,7 @@ rec_set_nth_field_extern_bit_new( we do not write to log about the change */ { byte* nulls = rec - (REC_N_NEW_EXTRA_BYTES + 1); - byte* lens = nulls - (index->n_nullable + 7) / 8; + byte* lens = nulls - UT_BITS_IN_BYTES(index->n_nullable); ulint i; ulint n_fields; ulint null_mask = 1; @@ -875,7 +884,7 @@ rec_convert_dtuple_to_rec_new( /* Calculate the offset of the origin in the physical record. We must loop over all fields to do this. */ - rec += (index->n_nullable + 7) / 8; + rec += UT_BITS_IN_BYTES(index->n_nullable); for (i = 0; i < n_fields; i++) { if (UNIV_UNLIKELY(i == n_node_ptr_field)) { @@ -892,6 +901,11 @@ rec_convert_dtuple_to_rec_new( len = dfield_get_len(field); fixed_len = dict_index_get_nth_field(index, i)->fixed_len; + ut_ad(dict_col_type_assert_equal( + dict_field_get_col(dict_index_get_nth_field( + index, i)), + dfield_get_type(field))); + if (!(dtype_get_prtype(type) & DATA_NOT_NULL)) { if (len == UNIV_SQL_NULL) continue; @@ -915,7 +929,7 @@ rec_convert_dtuple_to_rec_new( init: end = rec; nulls = rec - (REC_N_NEW_EXTRA_BYTES + 1); - lens = nulls - (index->n_nullable + 7) / 8; + lens = nulls - UT_BITS_IN_BYTES(index->n_nullable); /* clear the SQL-null flags */ memset (lens + 1, 0, nulls - lens); @@ -1172,7 +1186,7 @@ rec_copy_prefix_to_buf( } nulls = rec - (REC_N_NEW_EXTRA_BYTES + 1); - lens = nulls - (index->n_nullable + 7) / 8; + lens = nulls - UT_BITS_IN_BYTES(index->n_nullable); UNIV_PREFETCH_R(lens); prefix_len = 0; null_mask = 1; diff --git a/storage/innobase/row/Makefile.am b/storage/innobase/row/Makefile.am deleted file mode 100644 index 6c1f960055d..00000000000 --- a/storage/innobase/row/Makefile.am +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright (C) 2001, 2003 MySQL AB & Innobase Oy -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -include ../include/Makefile.i - -noinst_LIBRARIES = librow.a - -librow_a_SOURCES = row0ins.c row0mysql.c row0purge.c row0row.c row0sel.c\ - row0uins.c row0umod.c row0undo.c row0upd.c row0vers.c - -EXTRA_PROGRAMS = - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/storage/innobase/row/row0ins.c b/storage/innobase/row/row0ins.c index 1fba0abcdaf..ad14b927170 100644 --- a/storage/innobase/row/row0ins.c +++ b/storage/innobase/row/row0ins.c @@ -51,21 +51,6 @@ innobase_invalidate_query_cache( ulint full_name_len); /* in: full name length where also the null chars count */ -/********************************************************************** -This function returns true if - -1) SQL-query in the current thread -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 -prototype for this function ! */ - -ibool -innobase_query_is_update(void); - /************************************************************************* Creates an insert node struct. */ @@ -448,7 +433,11 @@ row_ins_cascade_calc_update_vec( ulint i; ulint j; - ut_a(node && foreign && cascade && table && index); + ut_a(node); + ut_a(foreign); + ut_a(cascade); + ut_a(table); + ut_a(index); /* Calculate the appropriate update vector which will set the fields in the child index record to the same value (possibly padded with @@ -791,7 +780,10 @@ row_ins_foreign_check_on_constraint( trx_t* trx; mem_heap_t* tmp_heap = NULL; - ut_a(thr && foreign && pcur && mtr); + ut_a(thr); + ut_a(foreign); + ut_a(pcur); + ut_a(mtr); trx = thr_get_trx(thr); @@ -1308,7 +1300,8 @@ run_again: goto exit_func; } - ut_a(check_table && check_index); + ut_a(check_table); + ut_a(check_index); if (check_table != table) { /* We already have a LOCK_IX on table, but not necessarily @@ -1336,11 +1329,9 @@ run_again: /* Scan index records and check if there is a matching record */ for (;;) { - page_t* page; rec = btr_pcur_get_rec(&pcur); - page = buf_frame_align(rec); - if (rec == page_get_infimum_rec(page)) { + if (page_rec_is_infimum(rec)) { goto next_rec; } @@ -1348,7 +1339,7 @@ run_again: offsets = rec_get_offsets(rec, check_index, offsets, ULINT_UNDEFINED, &heap); - if (rec == page_get_supremum_rec(page)) { + if (page_rec_is_supremum(rec)) { err = row_ins_set_shared_rec_lock( LOCK_ORDINARY, rec, check_index, offsets, thr); @@ -1654,6 +1645,7 @@ row_ins_scan_sec_index_for_duplicate( btr_pcur_t pcur; ulint err = DB_SUCCESS; ibool moved; + unsigned allow_duplicates; mtr_t mtr; mem_heap_t* heap = NULL; ulint offsets_[REC_OFFS_NORMAL_SIZE]; @@ -1684,12 +1676,14 @@ row_ins_scan_sec_index_for_duplicate( btr_pcur_open(index, entry, PAGE_CUR_GE, BTR_SEARCH_LEAF, &pcur, &mtr); + allow_duplicates = thr_get_trx(thr)->duplicates & TRX_DUP_IGNORE; + /* Scan index records and check if there is a duplicate */ for (;;) { rec = btr_pcur_get_rec(&pcur); - if (rec == page_get_infimum_rec(buf_frame_align(rec))) { + if (page_rec_is_infimum(rec)) { goto next_rec; } @@ -1697,7 +1691,7 @@ row_ins_scan_sec_index_for_duplicate( offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap); - if (innobase_query_is_update()) { + if (allow_duplicates) { /* If the SQL-query will update or replace duplicate key we will take X-lock for @@ -1826,7 +1820,7 @@ row_ins_duplicate_error_in_clust( sure that in roll-forward we get the same duplicate errors as in original execution */ - if (innobase_query_is_update()) { + if (trx->duplicates & TRX_DUP_IGNORE) { /* If the SQL-query will update or replace duplicate key we will take X-lock for @@ -1864,7 +1858,7 @@ row_ins_duplicate_error_in_clust( offsets = rec_get_offsets(rec, cursor->index, offsets, ULINT_UNDEFINED, &heap); - if (innobase_query_is_update()) { + if (trx->duplicates & TRX_DUP_IGNORE) { /* If the SQL-query will update or replace duplicate key we will take X-lock for diff --git a/storage/innobase/row/row0mysql.c b/storage/innobase/row/row0mysql.c index 7c9427db0d2..9f88fd8040b 100644 --- a/storage/innobase/row/row0mysql.c +++ b/storage/innobase/row/row0mysql.c @@ -476,7 +476,8 @@ handle_new_error: /* MySQL will roll back the latest SQL statement */ } else if (err == DB_ROW_IS_REFERENCED || err == DB_NO_REFERENCED_ROW - || err == DB_CANNOT_ADD_CONSTRAINT) { + || err == DB_CANNOT_ADD_CONSTRAINT + || err == DB_TOO_MANY_CONCURRENT_TRXS) { if (savept) { /* Roll back the latest, possibly incomplete insertion or update */ @@ -4058,3 +4059,25 @@ row_check_table_for_mysql( return(ret); } + +/************************************************************************* +Get the maximum row size. */ + +ulint +page_get_free_space_of_empty_noninline( +/*===================================*/ + /* out: The (approx) maximum size + of a row, this is a conservative + estimate, since the size can be + slightly larger depending upon + the ROW_FORMAT setting.*/ + dict_table_t* table) /* in: table for which max record + size is required.*/ +{ + ibool compact; + + compact = dict_table_is_comp(table); + + return(page_get_free_space_of_empty(compact) / 2); +} + diff --git a/storage/innobase/row/row0row.c b/storage/innobase/row/row0row.c index efa129d6211..08e50817db9 100644 --- a/storage/innobase/row/row0row.c +++ b/storage/innobase/row/row0row.c @@ -142,20 +142,15 @@ row_build_index_entry( dfield_copy(dfield, dfield2); /* If a column prefix index, take only the prefix */ - if (ind_field->prefix_len) { - if (dfield_get_len(dfield2) != UNIV_SQL_NULL) { + if (ind_field->prefix_len > 0 + && dfield_get_len(dfield2) != UNIV_SQL_NULL) { - storage_len = dtype_get_at_most_n_mbchars( - col->prtype, - col->mbminlen, col->mbmaxlen, - ind_field->prefix_len, - dfield_get_len(dfield2), - dfield2->data); - - dfield_set_len(dfield, storage_len); - } + storage_len = dtype_get_at_most_n_mbchars( + col->prtype, col->mbminlen, col->mbmaxlen, + ind_field->prefix_len, + dfield_get_len(dfield2), dfield2->data); - dfield_get_type(dfield)->len = ind_field->prefix_len; + dfield_set_len(dfield, storage_len); } } @@ -478,7 +473,9 @@ row_build_row_ref_in_tuple( ulint* offsets = offsets_; *offsets_ = (sizeof offsets_) / sizeof *offsets_; - ut_a(ref && index && rec); + ut_a(ref); + ut_a(index); + ut_a(rec); if (UNIV_UNLIKELY(!index->table)) { fputs("InnoDB: table ", stderr); diff --git a/storage/innobase/row/row0sel.c b/storage/innobase/row/row0sel.c index a3199055b54..e70b3b8671f 100644 --- a/storage/innobase/row/row0sel.c +++ b/storage/innobase/row/row0sel.c @@ -3619,6 +3619,32 @@ shortcut_fails_too_big_rec: pcur, 0, &mtr); pcur->trx_if_known = trx; + + rec = btr_pcur_get_rec(pcur); + + if (!moves_up + && !page_rec_is_supremum(rec) + && set_also_gap_locks + && !(srv_locks_unsafe_for_binlog + || trx->isolation_level == TRX_ISO_READ_COMMITTED) + && prebuilt->select_lock_type != LOCK_NONE) { + + /* Try to place a gap lock on the next index record + to prevent phantoms in ORDER BY ... DESC queries */ + + offsets = rec_get_offsets(page_rec_get_next(rec), + index, offsets, + ULINT_UNDEFINED, &heap); + err = sel_set_rec_lock(page_rec_get_next(rec), + index, offsets, + prebuilt->select_lock_type, + LOCK_GAP, thr); + + if (err != DB_SUCCESS) { + + goto lock_wait_or_error; + } + } } else { if (mode == PAGE_CUR_G) { btr_pcur_open_at_index_side( diff --git a/storage/innobase/srv/Makefile.am b/storage/innobase/srv/Makefile.am deleted file mode 100644 index e0b5b911b04..00000000000 --- a/storage/innobase/srv/Makefile.am +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (C) 2001, 2003-2004 MySQL AB & Innobase Oy -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -include ../include/Makefile.i - -noinst_LIBRARIES = libsrv.a - -libsrv_a_SOURCES = srv0srv.c srv0que.c srv0start.c - -EXTRA_PROGRAMS = - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c index 72e8fe751d0..8f8c9386f41 100644 --- a/storage/innobase/srv/srv0srv.c +++ b/storage/innobase/srv/srv0srv.c @@ -47,6 +47,7 @@ Created 10/8/1995 Heikki Tuuri #include "dict0boot.h" #include "srv0start.h" #include "row0mysql.h" +#include "ha_prototypes.h" /* This is set to TRUE if the MySQL user has set it in MySQL; currently affects only FOREIGN KEY definition parsing */ @@ -180,6 +181,16 @@ dulint srv_archive_recovery_limit_lsn; ulint srv_lock_wait_timeout = 1024 * 1024 * 1024; +/* This parameter is used to throttle the number of insert buffers that are +merged in a batch. By increasing this parameter on a faster disk you can +possibly reduce the number of I/O operations performed to complete the +merge operation. The value of this parameter is used as is by the +background loop when the system is idle (low load), on a busy system +the parameter is scaled down by a factor of 4, this is to avoid putting +a heavier load on the I/O sub system. */ + +ulong srv_insert_buffer_batch_size = 20; + char* srv_file_flush_method_str = NULL; ulint srv_unix_file_flush_method = SRV_UNIX_FDATASYNC; ulint srv_win_file_flush_method = SRV_WIN_IO_UNBUFFERED; @@ -977,6 +988,17 @@ srv_conc_enter_innodb( srv_conc_slot_t* slot = NULL; ulint i; + if (trx->mysql_thd != NULL + && thd_is_replication_slave_thread(trx->mysql_thd)) { + + /* TODO Do something more interesting (based on a config + parameter). Some users what to give the replication + thread very low priority, see http://bugs.mysql.com/25078 + This can be done by introducing + innodb_replication_delay(ms) config parameter */ + return; + } + /* If trx has 'free tickets' to enter the engine left, then use one such ticket */ @@ -1017,7 +1039,7 @@ retry: if (!has_slept && !trx->has_search_latch && NULL == UT_LIST_GET_FIRST(trx->trx_locks)) { - has_slept = TRUE; /* We let is sleep only once to avoid + has_slept = TRUE; /* We let it sleep only once to avoid starvation */ srv_conc_n_waiting_threads++; @@ -1130,7 +1152,7 @@ srv_conc_force_enter_innodb( srv_conc_n_threads++; trx->declared_to_be_inside_innodb = TRUE; - trx->n_tickets_to_enter_innodb = 0; + trx->n_tickets_to_enter_innodb = 1; os_fast_mutex_unlock(&srv_conc_mutex); } @@ -1152,6 +1174,12 @@ srv_conc_force_exit_innodb( return; } + if (trx->mysql_thd != NULL + && thd_is_replication_slave_thread(trx->mysql_thd)) { + + return; + } + if (trx->declared_to_be_inside_innodb == FALSE) { return; @@ -1853,6 +1881,7 @@ srv_lock_timeout_and_monitor_thread( double time_elapsed; time_t current_time; time_t last_table_monitor_time; + time_t last_tablespace_monitor_time; time_t last_monitor_time; ibool some_waits; double wait_time; @@ -1865,6 +1894,7 @@ srv_lock_timeout_and_monitor_thread( UT_NOT_USED(arg); srv_last_monitor_time = time(NULL); last_table_monitor_time = time(NULL); + last_tablespace_monitor_time = time(NULL); last_monitor_time = time(NULL); loop: srv_lock_timeout_and_monitor_active = TRUE; @@ -1901,9 +1931,9 @@ loop: } if (srv_print_innodb_tablespace_monitor - && difftime(current_time, last_table_monitor_time) > 60) { - - last_table_monitor_time = time(NULL); + && difftime(current_time, + last_tablespace_monitor_time) > 60) { + last_tablespace_monitor_time = time(NULL); fputs("========================" "========================\n", @@ -2100,7 +2130,7 @@ loop: os_thread_sleep(2000000); - if (srv_shutdown_state < SRV_SHUTDOWN_LAST_PHASE) { + if (srv_shutdown_state < SRV_SHUTDOWN_CLEANUP) { goto loop; } @@ -2270,7 +2300,8 @@ loop: + buf_pool->n_pages_written; if (n_pend_ios < 3 && (n_ios - n_ios_old < 5)) { srv_main_thread_op_info = "doing insert buffer merge"; - ibuf_contract_for_n_pages(TRUE, 5); + ibuf_contract_for_n_pages( + TRUE, srv_insert_buffer_batch_size / 4); srv_main_thread_op_info = "flushing log"; @@ -2331,7 +2362,7 @@ loop: even if the server were active */ srv_main_thread_op_info = "doing insert buffer merge"; - ibuf_contract_for_n_pages(TRUE, 5); + ibuf_contract_for_n_pages(TRUE, srv_insert_buffer_batch_size / 4); srv_main_thread_op_info = "flushing log"; log_buffer_flush_to_disk(); @@ -2469,7 +2500,8 @@ background_loop: if (srv_fast_shutdown && srv_shutdown_state > 0) { n_bytes_merged = 0; } else { - n_bytes_merged = ibuf_contract_for_n_pages(TRUE, 20); + n_bytes_merged = ibuf_contract_for_n_pages( + TRUE, srv_insert_buffer_batch_size); } srv_main_thread_op_info = "reserving kernel mutex"; diff --git a/storage/innobase/srv/srv0start.c b/storage/innobase/srv/srv0start.c index 25f6f05e878..dac84e1410d 100644 --- a/storage/innobase/srv/srv0start.c +++ b/storage/innobase/srv/srv0start.c @@ -1025,6 +1025,12 @@ innobase_start_or_create_for_mysql(void) "InnoDB: !!!!!!!! UNIV_DEBUG switched on !!!!!!!!!\n"); #endif +#ifdef UNIV_IBUF_DEBUG + fprintf(stderr, + "InnoDB: !!!!!!!! UNIV_IBUF_DEBUG switched on !!!!!!!!!\n" + "InnoDB: Crash recovery will fail with UNIV_IBUF_DEBUG\n"); +#endif + #ifdef UNIV_SYNC_DEBUG fprintf(stderr, "InnoDB: !!!!!!!! UNIV_SYNC_DEBUG switched on !!!!!!!!!\n"); diff --git a/storage/innobase/sync/Makefile.am b/storage/innobase/sync/Makefile.am deleted file mode 100644 index 7cf274b64e8..00000000000 --- a/storage/innobase/sync/Makefile.am +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (C) 2001, 2003-2004 MySQL AB & Innobase Oy -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -include ../include/Makefile.i - -noinst_LIBRARIES = libsync.a - -libsync_a_SOURCES = sync0arr.c sync0rw.c sync0sync.c - -EXTRA_PROGRAMS = - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/storage/innobase/sync/sync0arr.c b/storage/innobase/sync/sync0arr.c index e45cd48a6b4..82b08a890e0 100644 --- a/storage/innobase/sync/sync0arr.c +++ b/storage/innobase/sync/sync0arr.c @@ -670,7 +670,9 @@ sync_array_detect_deadlock( ibool ret; rw_lock_debug_t*debug; - ut_a(arr && start && cell); + ut_a(arr); + ut_a(start); + ut_a(cell); ut_ad(cell->wait_object); ut_ad(os_thread_get_curr_id() == start->thread); ut_ad(depth < 100); diff --git a/storage/innobase/thr/Makefile.am b/storage/innobase/thr/Makefile.am deleted file mode 100644 index febcdf3e1a3..00000000000 --- a/storage/innobase/thr/Makefile.am +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (C) 2001, 2003 MySQL AB & Innobase Oy -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -include ../include/Makefile.i - -noinst_LIBRARIES = libthr.a - -libthr_a_SOURCES = thr0loc.c - -EXTRA_PROGRAMS = - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/storage/innobase/trx/Makefile.am b/storage/innobase/trx/Makefile.am deleted file mode 100644 index f9722454ef5..00000000000 --- a/storage/innobase/trx/Makefile.am +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright (C) 2001, 2003 MySQL AB & Innobase Oy -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -include ../include/Makefile.i - -noinst_LIBRARIES = libtrx.a - -libtrx_a_SOURCES = trx0purge.c trx0rec.c trx0roll.c trx0rseg.c\ - trx0sys.c trx0trx.c trx0undo.c - -EXTRA_PROGRAMS = - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/storage/innobase/trx/trx0rec.c b/storage/innobase/trx/trx0rec.c index 69e858fe71d..50f8b011463 100644 --- a/storage/innobase/trx/trx0rec.c +++ b/storage/innobase/trx/trx0rec.c @@ -1024,6 +1024,7 @@ trx_undo_report_row_operation( ibool is_insert; trx_rseg_t* rseg; mtr_t mtr; + ulint err = DB_SUCCESS; mem_heap_t* heap = NULL; ulint offsets_[REC_OFFS_NORMAL_SIZE]; ulint* offsets = offsets_; @@ -1035,7 +1036,7 @@ trx_undo_report_row_operation( *roll_ptr = ut_dulint_zero; - return(DB_SUCCESS); + return(err); } ut_ad(thr); @@ -1053,7 +1054,7 @@ trx_undo_report_row_operation( if (trx->insert_undo == NULL) { - trx_undo_assign_undo(trx, TRX_UNDO_INSERT); + err = trx_undo_assign_undo(trx, TRX_UNDO_INSERT); } undo = trx->insert_undo; @@ -1063,7 +1064,7 @@ trx_undo_report_row_operation( if (trx->update_undo == NULL) { - trx_undo_assign_undo(trx, TRX_UNDO_UPDATE); + err = trx_undo_assign_undo(trx, TRX_UNDO_UPDATE); } @@ -1071,11 +1072,11 @@ trx_undo_report_row_operation( is_insert = FALSE; } - if (undo == NULL) { - /* Did not succeed: out of space */ + if (err != DB_SUCCESS) { + /* Did not succeed: return the error encountered */ mutex_exit(&(trx->undo_mutex)); - return(DB_OUT_OF_FILE_SPACE); + return(err); } page_no = undo->last_page_no; @@ -1107,7 +1108,9 @@ trx_undo_report_row_operation( if (offset == 0) { /* The record did not fit on the page. We erase the end segment of the undo log page and write a log - record of it to to ensure deterministic contents. */ + record of it: this is to ensure that in the debug + version the replicate page constructed using the log + records stays identical to the original page */ trx_undo_erase_page_end(undo_page, &mtr); } @@ -1163,7 +1166,7 @@ trx_undo_report_row_operation( if (UNIV_LIKELY_NULL(heap)) { mem_heap_free(heap); } - return(DB_SUCCESS); + return(err); } /*============== BUILDING PREVIOUS VERSION OF A RECORD ===============*/ diff --git a/storage/innobase/trx/trx0trx.c b/storage/innobase/trx/trx0trx.c index cdea3e9c477..2d5ce0e1c61 100644 --- a/storage/innobase/trx/trx0trx.c +++ b/storage/innobase/trx/trx0trx.c @@ -25,6 +25,7 @@ Created 3/26/1996 Heikki Tuuri #include "btr0sea.h" #include "os0proc.h" #include "trx0xa.h" +#include "ha_prototypes.h" /* Copy of the prototype for innobase_mysql_print_thd: this copy MUST be equal to the one in mysql/sql/ha_innodb.cc ! */ @@ -130,6 +131,8 @@ trx_create( trx->mysql_thd = NULL; trx->mysql_query_str = NULL; + trx->active_trans = 0; + trx->duplicates = 0; trx->n_mysql_tables_in_use = 0; trx->mysql_n_tables_locked = 0; @@ -1771,6 +1774,61 @@ trx_print( } } +/*********************************************************************** +Compares the "weight" (or size) of two transactions. The weight of one +transaction is estimated as the number of altered rows + the number of +locked rows. Transactions that have edited non-transactional tables are +considered heavier than ones that have not. */ + +int +trx_weight_cmp( +/*===========*/ + /* out: <0, 0 or >0; similar to strcmp(3) */ + trx_t* a, /* in: the first transaction to be compared */ + trx_t* b) /* in: the second transaction to be compared */ +{ + ibool a_notrans_edit; + ibool b_notrans_edit; + + /* If mysql_thd is NULL for a transaction we assume that it has + not edited non-transactional tables. */ + + a_notrans_edit = a->mysql_thd != NULL + && thd_has_edited_nontrans_tables(a->mysql_thd); + + b_notrans_edit = b->mysql_thd != NULL + && thd_has_edited_nontrans_tables(b->mysql_thd); + + if (a_notrans_edit && !b_notrans_edit) { + + return(1); + } + + if (!a_notrans_edit && b_notrans_edit) { + + return(-1); + } + + /* Either both had edited non-transactional tables or both had + not, we fall back to comparing the number of altered/locked + rows. */ + +#if 0 + fprintf(stderr, + "%s TRX_WEIGHT(a): %lld+%lu, TRX_WEIGHT(b): %lld+%lu\n", + __func__, + ut_conv_dulint_to_longlong(a->undo_no), + UT_LIST_GET_LEN(a->trx_locks), + ut_conv_dulint_to_longlong(b->undo_no), + UT_LIST_GET_LEN(b->trx_locks)); +#endif + +#define TRX_WEIGHT(t) \ + ut_dulint_add((t)->undo_no, UT_LIST_GET_LEN((t)->trx_locks)) + + return(ut_dulint_cmp(TRX_WEIGHT(a), TRX_WEIGHT(b))); +} + /******************************************************************** Prepares a transaction. */ @@ -1889,7 +1947,7 @@ Does the transaction prepare for MySQL. */ ulint trx_prepare_for_mysql( -/*====-=============*/ +/*==================*/ /* out: 0 or error number */ trx_t* trx) /* in: trx handle */ { diff --git a/storage/innobase/trx/trx0undo.c b/storage/innobase/trx/trx0undo.c index 831e337f513..64e5ad3c9a8 100644 --- a/storage/innobase/trx/trx0undo.c +++ b/storage/innobase/trx/trx0undo.c @@ -373,26 +373,31 @@ trx_undo_page_init( /******************************************************************* Creates a new undo log segment in file. */ static -page_t* +ulint trx_undo_seg_create( /*================*/ - /* out: segment header page x-latched, NULL - if no space left */ + /* out: DB_SUCCESS if page creation OK + possible error codes are: + DB_TOO_MANY_CONCURRENT_TRXS + DB_OUT_OF_FILE_SPACE */ trx_rseg_t* rseg __attribute__((unused)),/* in: rollback segment */ trx_rsegf_t* rseg_hdr,/* in: rollback segment header, page x-latched */ ulint type, /* in: type of the segment: TRX_UNDO_INSERT or TRX_UNDO_UPDATE */ ulint* id, /* out: slot index within rseg header */ + page_t** undo_page, + /* out: segment header page x-latched, NULL + if there was an error */ mtr_t* mtr) /* in: mtr */ { ulint slot_no; ulint space; - page_t* undo_page; trx_upagef_t* page_hdr; trx_usegf_t* seg_hdr; ulint n_reserved; ibool success; + ulint err = DB_SUCCESS; ut_ad(mtr && id && rseg_hdr); ut_ad(mutex_own(&(rseg->mutex))); @@ -410,7 +415,7 @@ trx_undo_seg_create( "InnoDB: many active transactions" " running concurrently?\n"); - return(NULL); + return(DB_TOO_MANY_CONCURRENT_TRXS); } space = buf_frame_get_space_id(rseg_hdr); @@ -419,30 +424,30 @@ trx_undo_seg_create( mtr); if (!success) { - return(NULL); + return(DB_OUT_OF_FILE_SPACE); } /* Allocate a new file segment for the undo log */ - undo_page = fseg_create_general(space, 0, + *undo_page = fseg_create_general(space, 0, TRX_UNDO_SEG_HDR + TRX_UNDO_FSEG_HEADER, TRUE, mtr); fil_space_release_free_extents(space, n_reserved); - if (undo_page == NULL) { + if (*undo_page == NULL) { /* No space left */ - return(NULL); + return(DB_OUT_OF_FILE_SPACE); } #ifdef UNIV_SYNC_DEBUG - buf_page_dbg_add_level(undo_page, SYNC_TRX_UNDO_PAGE); + buf_page_dbg_add_level(*undo_page, SYNC_TRX_UNDO_PAGE); #endif /* UNIV_SYNC_DEBUG */ - page_hdr = undo_page + TRX_UNDO_PAGE_HDR; - seg_hdr = undo_page + TRX_UNDO_SEG_HDR; + page_hdr = *undo_page + TRX_UNDO_PAGE_HDR; + seg_hdr = *undo_page + TRX_UNDO_SEG_HDR; - trx_undo_page_init(undo_page, type, mtr); + trx_undo_page_init(*undo_page, type, mtr); mlog_write_ulint(page_hdr + TRX_UNDO_PAGE_FREE, TRX_UNDO_SEG_HDR + TRX_UNDO_SEG_HDR_SIZE, @@ -456,10 +461,11 @@ trx_undo_seg_create( page_hdr + TRX_UNDO_PAGE_NODE, mtr); trx_rsegf_set_nth_undo(rseg_hdr, slot_no, - buf_frame_get_page_no(undo_page), mtr); + buf_frame_get_page_no(*undo_page), mtr); + *id = slot_no; - return(undo_page); + return(err); } /************************************************************************** @@ -1387,6 +1393,11 @@ trx_undo_mem_create( undo = mem_alloc(sizeof(trx_undo_t)); + if (undo == NULL) { + + return NULL; + } + undo->id = id; undo->type = type; undo->state = TRX_UNDO_ACTIVE; @@ -1464,11 +1475,15 @@ trx_undo_mem_free( /************************************************************************** Creates a new undo log. */ static -trx_undo_t* +ulint trx_undo_create( /*============*/ - /* out: undo log object, NULL if did not - succeed: out of space */ + /* out: DB_SUCCESS if successful in creating + the new undo lob object, possible error + codes are: + DB_TOO_MANY_CONCURRENT_TRXS + DB_OUT_OF_FILE_SPACE + DB_OUT_OF_MEMORY*/ trx_t* trx, /* in: transaction */ trx_rseg_t* rseg, /* in: rollback segment memory copy */ ulint type, /* in: type of the log: TRX_UNDO_INSERT or @@ -1476,34 +1491,37 @@ trx_undo_create( dulint trx_id, /* in: id of the trx for which the undo log is created */ XID* xid, /* in: X/Open transaction identification*/ + trx_undo_t** undo, /* out: the new undo log object, undefined + * if did not succeed */ mtr_t* mtr) /* in: mtr */ { trx_rsegf_t* rseg_header; ulint page_no; ulint offset; ulint id; - trx_undo_t* undo; page_t* undo_page; + ulint err; ut_ad(mutex_own(&(rseg->mutex))); if (rseg->curr_size == rseg->max_size) { - return(NULL); + return(DB_OUT_OF_FILE_SPACE); } rseg->curr_size++; rseg_header = trx_rsegf_get(rseg->space, rseg->page_no, mtr); - undo_page = trx_undo_seg_create(rseg, rseg_header, type, &id, mtr); + err = trx_undo_seg_create(rseg, rseg_header, type, &id, + &undo_page, mtr); - if (undo_page == NULL) { + if (err != DB_SUCCESS) { /* Did not succeed */ rseg->curr_size--; - return(NULL); + return(err); } page_no = buf_frame_get_page_no(undo_page); @@ -1515,9 +1533,14 @@ trx_undo_create( undo_page + offset, mtr); } - undo = trx_undo_mem_create(rseg, id, type, trx_id, xid, + *undo = trx_undo_mem_create(rseg, id, type, trx_id, xid, page_no, offset); - return(undo); + if (*undo == NULL) { + + err = DB_OUT_OF_MEMORY; + } + + return(err); } /*================ UNDO LOG ASSIGNMENT AND CLEANUP =====================*/ @@ -1634,17 +1657,20 @@ trx_undo_mark_as_dict_operation( Assigns an undo log for a transaction. A new undo log is created or a cached undo log reused. */ -trx_undo_t* +ulint trx_undo_assign_undo( /*=================*/ - /* out: the undo log, NULL if did not succeed: out of - space */ - trx_t* trx, /* in: transaction */ - ulint type) /* in: TRX_UNDO_INSERT or TRX_UNDO_UPDATE */ + /* out: DB_SUCCESS if undo log assign + successful, possible error codes are: + DD_TOO_MANY_CONCURRENT_TRXS + DB_OUT_OF_FILE_SPACE DB_OUT_OF_MEMORY*/ + trx_t* trx, /* in: transaction */ + ulint type) /* in: TRX_UNDO_INSERT or TRX_UNDO_UPDATE */ { trx_rseg_t* rseg; trx_undo_t* undo; mtr_t mtr; + ulint err = DB_SUCCESS; ut_ad(trx); ut_ad(trx->rseg); @@ -1662,15 +1688,11 @@ trx_undo_assign_undo( undo = trx_undo_reuse_cached(trx, rseg, type, trx->id, &trx->xid, &mtr); if (undo == NULL) { - undo = trx_undo_create(trx, rseg, type, trx->id, &trx->xid, - &mtr); - if (undo == NULL) { - /* Did not succeed */ + err = trx_undo_create(trx, rseg, type, trx->id, &trx->xid, + &undo, &mtr); + if (err != DB_SUCCESS) { - mutex_exit(&(rseg->mutex)); - mtr_commit(&mtr); - - return(NULL); + goto func_exit; } } @@ -1688,10 +1710,11 @@ trx_undo_assign_undo( trx_undo_mark_as_dict_operation(trx, undo, &mtr); } +func_exit: mutex_exit(&(rseg->mutex)); mtr_commit(&mtr); - return(undo); + return err; } /********************************************************************** diff --git a/storage/innobase/usr/Makefile.am b/storage/innobase/usr/Makefile.am deleted file mode 100644 index ea485022f71..00000000000 --- a/storage/innobase/usr/Makefile.am +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (C) 2001, 2003 MySQL AB & Innobase Oy -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -include ../include/Makefile.i - -noinst_LIBRARIES = libusr.a - -libusr_a_SOURCES = usr0sess.c - -EXTRA_PROGRAMS = - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/storage/innobase/ut/Makefile.am b/storage/innobase/ut/Makefile.am deleted file mode 100644 index d79184759c1..00000000000 --- a/storage/innobase/ut/Makefile.am +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (C) 2001, 2003 MySQL AB & Innobase Oy -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -include ../include/Makefile.i - -noinst_LIBRARIES = libut.a - -libut_a_SOURCES = ut0byte.c ut0dbg.c ut0mem.c ut0rnd.c ut0ut.c ut0vec.c ut0list.c ut0wqueue.c - -EXTRA_PROGRAMS = - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/storage/innobase/ut/ut0ut.c b/storage/innobase/ut/ut0ut.c index bc6778f4c2f..389063ad821 100644 --- a/storage/innobase/ut/ut0ut.c +++ b/storage/innobase/ut/ut0ut.c @@ -14,6 +14,7 @@ Created 5/11/1994 Heikki Tuuri #include <stdarg.h> #include <string.h> +#include <ctype.h> #include "ut0sort.h" #include "trx0trx.h" diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc index 20f55545282..c86459ae0a7 100644 --- a/storage/myisam/ha_myisam.cc +++ b/storage/myisam/ha_myisam.cc @@ -1889,6 +1889,8 @@ int ha_myisam::create(const char *name, register TABLE *table_arg, if (ha_create_info->options & HA_LEX_CREATE_TMP_TABLE) create_flags|= HA_CREATE_TMP_TABLE; + if (ha_create_info->options & HA_CREATE_KEEP_FILES) + create_flags|= HA_CREATE_KEEP_FILES; if (options & HA_OPTION_PACK_RECORD) create_flags|= HA_PACK_RECORD; if (options & HA_OPTION_CHECKSUM) diff --git a/storage/myisam/mi_create.c b/storage/myisam/mi_create.c index c177aa8d987..0cac5f08b3b 100644 --- a/storage/myisam/mi_create.c +++ b/storage/myisam/mi_create.c @@ -615,7 +615,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, (have_iext ? MY_REPLACE_EXT : MY_APPEND_EXT)); linkname_ptr=0; /* Replace the current file */ - create_flag=MY_DELETE_OLD; + create_flag=(flags & HA_CREATE_KEEP_FILES) ? 0 : MY_DELETE_OLD; } /* @@ -689,7 +689,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, fn_format(filename,name,"", MI_NAME_DEXT, MY_UNPACK_FILENAME | MY_APPEND_EXT); linkname_ptr=0; - create_flag=MY_DELETE_OLD; + create_flag=(flags & HA_CREATE_KEEP_FILES) ? 0 : MY_DELETE_OLD; } if ((dfile= my_create_with_symlink(linkname_ptr, filename, 0, create_mode, diff --git a/storage/myisam/sp_key.c b/storage/myisam/sp_key.c index be4021935c4..3748a38ff81 100644 --- a/storage/myisam/sp_key.c +++ b/storage/myisam/sp_key.c @@ -31,11 +31,6 @@ static int sp_get_geometry_mbr(uchar *(*wkb), uchar *end, uint n_dims, double *mbr, int top); static int sp_mbr_from_wkb(uchar (*wkb), uint size, uint n_dims, double *mbr); -static void get_double(double *d, const uchar *pos) -{ - float8get(*d, pos); -} - uint sp_make_key(register MI_INFO *info, uint keynr, uchar *key, const uchar *record, my_off_t filepos) { @@ -62,48 +57,40 @@ uint sp_make_key(register MI_INFO *info, uint keynr, uchar *key, for (i = 0, keyseg = keyinfo->seg; keyseg->type; keyseg++, i++) { - uint length = keyseg->length; + uint length = keyseg->length, start= keyseg->start; + double val; + + DBUG_ASSERT(length == sizeof(double)); + DBUG_ASSERT(!(start % sizeof(double))); + DBUG_ASSERT(start < sizeof(mbr)); + DBUG_ASSERT(keyseg->type == HA_KEYTYPE_DOUBLE); - pos = ((uchar*)mbr) + keyseg->start; - if (keyseg->flag & HA_SWAP_KEY) - { + val= mbr[start / sizeof (double)]; #ifdef HAVE_ISNAN - if (keyseg->type == HA_KEYTYPE_FLOAT) - { - float nr; - float4get(nr, pos); - if (isnan(nr)) - { - /* Replace NAN with zero */ - bzero(key, length); - key+= length; - continue; - } - } - else if (keyseg->type == HA_KEYTYPE_DOUBLE) - { - double nr; - get_double(&nr, pos); - if (isnan(nr)) - { - bzero(key, length); - key+= length; - continue; - } - } + if (isnan(val)) + { + bzero(key, length); + key+= length; + len+= length; + continue; + } #endif - pos += length; - while (length--) - { + + if (keyseg->flag & HA_SWAP_KEY) + { + uchar buf[sizeof(double)]; + + float8store(buf, val); + pos= &buf[length]; + while (pos > buf) *key++ = *--pos; - } } else { - memcpy((uchar*)key, pos, length); - key += keyseg->length; + float8store((uchar *)key, val); + key += length; } - len += keyseg->length; + len+= length; } _mi_dpointer(info, key, filepos); return len; @@ -141,13 +128,13 @@ static int sp_add_point_to_mbr(uchar *(*wkb), uchar *end, uint n_dims, { if ((*wkb) > end - 8) return -1; - get_double(&ord, (const uchar*) *wkb); + float8get(ord, (const uchar*) *wkb); (*wkb)+= 8; if (ord < *mbr) - float8store((char*) mbr, ord); + *mbr= ord; mbr++; if (ord > *mbr) - float8store((char*) mbr, ord); + *mbr= ord; mbr++; } return 0; diff --git a/storage/ndb/include/ndb_version.h.in b/storage/ndb/include/ndb_version.h.in index 9e1edeecd1e..5405ad4d7aa 100644 --- a/storage/ndb/include/ndb_version.h.in +++ b/storage/ndb/include/ndb_version.h.in @@ -16,8 +16,7 @@ #ifndef NDB_VERSION_H #define NDB_VERSION_H -#include <ndb_global.h> -#include <version.h> +#include <ndb_types.h> /* NDB build version */ #define NDB_VERSION_BUILD @NDB_VERSION_BUILD@ @@ -32,19 +31,35 @@ #define NDB_VERSION_STATUS "@NDB_VERSION_STATUS@" -#define MAKE_VERSION(A,B,C) (((A) << 16) | ((B) << 8) | ((C) << 0)) +#define NDB_MAKE_VERSION(A,B,C) (((A) << 16) | ((B) << 8) | ((C) << 0)) -#define NDB_VERSION_D MAKE_VERSION(NDB_VERSION_MAJOR, NDB_VERSION_MINOR, NDB_VERSION_BUILD) +#define NDB_VERSION_D NDB_MAKE_VERSION(NDB_VERSION_MAJOR, NDB_VERSION_MINOR, NDB_VERSION_BUILD) #define NDB_VERSION_STRING_BUF_SZ 100 #ifdef __cplusplus -extern "C" -#else -extern +extern "C" { #endif -char ndb_version_string_buf[NDB_VERSION_STRING_BUF_SZ]; -#define NDB_VERSION_STRING (getVersionString(NDB_VERSION, NDB_VERSION_STATUS, \ - ndb_version_string_buf, \ - sizeof(ndb_version_string_buf))) + +void ndbPrintVersion(); + +Uint32 ndbMakeVersion(Uint32 major, Uint32 minor, Uint32 build); + +Uint32 ndbGetMajor(Uint32 version); + +Uint32 ndbGetMinor(Uint32 version); + +Uint32 ndbGetBuild(Uint32 version); + +const char* ndbGetVersionString(Uint32 version, const char * status, + char *buf, unsigned sz); +const char* ndbGetOwnVersionString(); + +Uint32 ndbGetOwnVersion(); + +#ifdef __cplusplus +} +#endif + +#define NDB_VERSION_STRING ndbGetOwnVersionString() #define NDB_VERSION ndbGetOwnVersion() @@ -59,19 +74,19 @@ char ndb_version_string_buf[NDB_VERSION_STRING_BUF_SZ]; /** * From which version do we support rowid */ -#define NDBD_ROWID_VERSION (MAKE_VERSION(5,1,6)) -#define NDBD_INCL_NODECONF_VERSION_4 MAKE_VERSION(4,1,17) -#define NDBD_INCL_NODECONF_VERSION_5 MAKE_VERSION(5,0,18) -#define NDBD_FRAGID_VERSION (MAKE_VERSION(5,1,6)) -#define NDBD_DICT_LOCK_VERSION_5 MAKE_VERSION(5,0,23) -#define NDBD_DICT_LOCK_VERSION_5_1 MAKE_VERSION(5,1,12) +#define NDBD_ROWID_VERSION (NDB_MAKE_VERSION(5,1,6)) +#define NDBD_INCL_NODECONF_VERSION_4 NDB_MAKE_VERSION(4,1,17) +#define NDBD_INCL_NODECONF_VERSION_5 NDB_MAKE_VERSION(5,0,18) +#define NDBD_FRAGID_VERSION (NDB_MAKE_VERSION(5,1,6)) +#define NDBD_DICT_LOCK_VERSION_5 NDB_MAKE_VERSION(5,0,23) +#define NDBD_DICT_LOCK_VERSION_5_1 NDB_MAKE_VERSION(5,1,12) -#define NDBD_UPDATE_FRAG_DIST_KEY_50 MAKE_VERSION(5,0,26) -#define NDBD_UPDATE_FRAG_DIST_KEY_51 MAKE_VERSION(5,1,12) +#define NDBD_UPDATE_FRAG_DIST_KEY_50 NDB_MAKE_VERSION(5,0,26) +#define NDBD_UPDATE_FRAG_DIST_KEY_51 NDB_MAKE_VERSION(5,1,12) -#define NDBD_QMGR_SINGLEUSER_VERSION_5 MAKE_VERSION(5,0,25) +#define NDBD_QMGR_SINGLEUSER_VERSION_5 NDB_MAKE_VERSION(5,0,25) -#define NDBD_NODE_VERSION_REP MAKE_VERSION(6,1,1) +#define NDBD_NODE_VERSION_REP NDB_MAKE_VERSION(6,1,1) #endif diff --git a/storage/ndb/include/util/version.h b/storage/ndb/include/util/version.h index 42513d00442..9ea18ecd9d9 100644 --- a/storage/ndb/include/util/version.h +++ b/storage/ndb/include/util/version.h @@ -16,25 +16,18 @@ #ifndef VERSION_H #define VERSION_H -#include <ndb_types.h> +#include <ndb_version.h> + +/* some backwards compatible macros */ +#define MAKE_VERSION(A,B,C) NDB_MAKE_VERSION(A,B,C) +#define getMajor(a) ndbGetMajor(a) +#define getMinor(a) ndbGetMinor(a) +#define getBuild(a) ndbGetBuild(a) + #ifdef __cplusplus extern "C" { #endif - Uint32 getMajor(Uint32 version); - - Uint32 getMinor(Uint32 version); - - Uint32 getBuild(Uint32 version); - - Uint32 makeVersion(Uint32 major, Uint32 minor, Uint32 build); - - const char* getVersionString(Uint32 version, const char * status, - char *buf, unsigned sz); - - void ndbPrintVersion(); - Uint32 ndbGetOwnVersion(); - int ndbCompatible_mgmt_ndb(Uint32 ownVersion, Uint32 otherVersion); int ndbCompatible_ndb_mgmt(Uint32 ownVersion, Uint32 otherVersion); int ndbCompatible_mgmt_api(Uint32 ownVersion, Uint32 otherVersion); diff --git a/storage/ndb/ndbapi-examples/ndbapi_simple/ndbapi_simple.cpp b/storage/ndb/ndbapi-examples/ndbapi_simple/ndbapi_simple.cpp index 0a4f6d92f2c..4e82fc3e42b 100644 --- a/storage/ndb/ndbapi-examples/ndbapi_simple/ndbapi_simple.cpp +++ b/storage/ndb/ndbapi-examples/ndbapi_simple/ndbapi_simple.cpp @@ -281,12 +281,14 @@ static void do_read(Ndb &myNdb) if (myRecAttr == NULL) APIERROR(myTransaction->getNdbError()); if(myTransaction->execute( NdbTransaction::Commit ) == -1) - if (i == 3) { - std::cout << "Detected that deleted tuple doesn't exist!" << std::endl; - } else { - APIERROR(myTransaction->getNdbError()); - } + APIERROR(myTransaction->getNdbError()); + if (myTransaction->getNdbError().classification == NdbError::NoDataFound) + if (i == 3) + std::cout << "Detected that deleted tuple doesn't exist!" << std::endl; + else + APIERROR(myTransaction->getNdbError()); + if (i != 3) { printf(" %2d %2d\n", i, myRecAttr->u_32_value()); } diff --git a/storage/ndb/src/common/util/version.c b/storage/ndb/src/common/util/version.c index f309a3d4ad5..56a92489131 100644 --- a/storage/ndb/src/common/util/version.c +++ b/storage/ndb/src/common/util/version.c @@ -20,26 +20,33 @@ #include <NdbEnv.h> #include <NdbOut.hpp> -Uint32 getMajor(Uint32 version) { +Uint32 ndbGetMajor(Uint32 version) { return (version >> 16) & 0xFF; } -Uint32 getMinor(Uint32 version) { +Uint32 ndbGetMinor(Uint32 version) { return (version >> 8) & 0xFF; } -Uint32 getBuild(Uint32 version) { +Uint32 ndbGetBuild(Uint32 version) { return (version >> 0) & 0xFF; } -Uint32 makeVersion(Uint32 major, Uint32 minor, Uint32 build) { - return MAKE_VERSION(major, minor, build); +Uint32 ndbMakeVersion(Uint32 major, Uint32 minor, Uint32 build) { + return NDB_MAKE_VERSION(major, minor, build); } -char ndb_version_string_buf[NDB_VERSION_STRING_BUF_SZ]; -const char * getVersionString(Uint32 version, const char * status, - char *buf, unsigned sz) +const char * ndbGetOwnVersionString() +{ + static char ndb_version_string_buf[NDB_VERSION_STRING_BUF_SZ]; + return ndbGetVersionString(NDB_VERSION, NDB_VERSION_STATUS, + ndb_version_string_buf, + sizeof(ndb_version_string_buf)); +} + +const char * ndbGetVersionString(Uint32 version, const char * status, + char *buf, unsigned sz) { if (status && status[0] != 0) basestring_snprintf(buf, sz, diff --git a/storage/ndb/src/kernel/blocks/dbdict/printSchemaFile.cpp b/storage/ndb/src/kernel/blocks/dbdict/printSchemaFile.cpp index 602881095c3..44326e213d0 100644 --- a/storage/ndb/src/kernel/blocks/dbdict/printSchemaFile.cpp +++ b/storage/ndb/src/kernel/blocks/dbdict/printSchemaFile.cpp @@ -15,7 +15,7 @@ #include <ndb_global.h> -#include <ndb_version.h> +#include <util/version.h> #include <NdbMain.h> #include <NdbOut.hpp> diff --git a/storage/ndb/src/kernel/blocks/diskpage.cpp b/storage/ndb/src/kernel/blocks/diskpage.cpp index 3f98e078746..50e9b6e53cb 100644 --- a/storage/ndb/src/kernel/blocks/diskpage.cpp +++ b/storage/ndb/src/kernel/blocks/diskpage.cpp @@ -49,7 +49,7 @@ operator<<(NdbOut& out, const File_formats::Zero_page_header& obj) char buf[256]; out << "page size: " << obj.m_page_size << endl; out << "ndb version: " << obj.m_ndb_version << ", " << - getVersionString(obj.m_ndb_version, 0, buf, sizeof(buf)) << endl; + ndbGetVersionString(obj.m_ndb_version, 0, buf, sizeof(buf)) << endl; out << "ndb node id: " << obj.m_node_id << endl; out << "file type: " << obj.m_file_type << endl; out << "time: " << obj.m_time << ", " diff --git a/storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp b/storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp index 52045fd63cd..1fba4d62e17 100644 --- a/storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp +++ b/storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp @@ -2793,7 +2793,7 @@ void Qmgr::execAPI_REGREQ(Signal* signal) "incompatible with %s", type == NodeInfo::API ? "api or mysqld" : "management server", apiNodePtr.i, - getVersionString(version,"",buf,sizeof(buf)), + ndbGetVersionString(version,"",buf,sizeof(buf)), NDB_VERSION_STRING); apiNodePtr.p->phase = ZAPI_INACTIVE; sendApiRegRef(signal, ref, ApiRegRef::UnsupportedVersion); diff --git a/storage/ndb/src/kernel/blocks/restore.cpp b/storage/ndb/src/kernel/blocks/restore.cpp index 2d40cd79daa..efc4bc1948a 100644 --- a/storage/ndb/src/kernel/blocks/restore.cpp +++ b/storage/ndb/src/kernel/blocks/restore.cpp @@ -1271,7 +1271,7 @@ Restore::check_file_version(Signal* signal, Uint32 file_version) { char buf[255]; char verbuf[255]; - getVersionString(file_version, 0, verbuf, sizeof(verbuf)); + ndbGetVersionString(file_version, 0, verbuf, sizeof(verbuf)); BaseString::snprintf(buf, sizeof(buf), "Unsupported version of LCP files found on disk, " " found: %s", verbuf); diff --git a/storage/ndb/src/kernel/vm/SimulatedBlock.hpp b/storage/ndb/src/kernel/vm/SimulatedBlock.hpp index a78ee21fb8f..31f219718e5 100644 --- a/storage/ndb/src/kernel/vm/SimulatedBlock.hpp +++ b/storage/ndb/src/kernel/vm/SimulatedBlock.hpp @@ -18,7 +18,7 @@ #include <NdbTick.h> #include <kernel_types.h> -#include <ndb_version.h> +#include <util/version.h> #include <ndb_limits.h> #include "VMSignal.hpp" diff --git a/storage/ndb/src/mgmsrv/ConfigInfo.cpp b/storage/ndb/src/mgmsrv/ConfigInfo.cpp index 69907224b7f..9cbb7d93ceb 100644 --- a/storage/ndb/src/mgmsrv/ConfigInfo.cpp +++ b/storage/ndb/src/mgmsrv/ConfigInfo.cpp @@ -3806,16 +3806,16 @@ check_node_vs_replicas(Vector<ConfigInfo::ConfigRuleSection>§ions, } } if (db_host_count > 1 && node_group_warning.length() > 0) - ndbout_c("Cluster configuration warning:\n%s",node_group_warning.c_str()); + ctx.reportWarning("Cluster configuration warning:\n%s",node_group_warning.c_str()); if (!with_arbitration_rank) { - ndbout_c("Cluster configuration warning:" + ctx.reportWarning("Cluster configuration warning:" "\n Neither %s nor %s nodes are configured with arbitrator," "\n may cause complete cluster shutdown in case of host failure.", MGM_TOKEN, API_TOKEN); } if (db_host_count > 1 && arbitration_warning.length() > 0) - ndbout_c("Cluster configuration warning:%s%s",arbitration_warning.c_str(), + ctx.reportWarning("Cluster configuration warning:%s%s",arbitration_warning.c_str(), "\n Running arbitrator on the same host as a database node may" "\n cause complete cluster shutdown in case of host failure."); } diff --git a/storage/ndb/src/mgmsrv/Services.cpp b/storage/ndb/src/mgmsrv/Services.cpp index f260ff7e3ec..9272b5ab532 100644 --- a/storage/ndb/src/mgmsrv/Services.cpp +++ b/storage/ndb/src/mgmsrv/Services.cpp @@ -18,7 +18,7 @@ #include <uucode.h> #include <socket_io.h> -#include <ndb_version.h> +#include <util/version.h> #include <mgmapi.h> #include <EventLogger.hpp> #include <signaldata/SetLogLevelOrd.hpp> diff --git a/storage/ndb/src/ndbapi/ClusterMgr.cpp b/storage/ndb/src/ndbapi/ClusterMgr.cpp index f51a5098c53..448bc1025e8 100644 --- a/storage/ndb/src/ndbapi/ClusterMgr.cpp +++ b/storage/ndb/src/ndbapi/ClusterMgr.cpp @@ -16,7 +16,7 @@ #include <ndb_global.h> #include <my_pthread.h> #include <ndb_limits.h> -#include <ndb_version.h> +#include <util/version.h> #include "TransporterFacade.hpp" #include "ClusterMgr.hpp" diff --git a/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp b/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp index 63d36bf012f..ab6d90ad59e 100644 --- a/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp +++ b/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp @@ -42,7 +42,7 @@ #include <my_sys.h> #include <NdbEnv.h> #include <NdbMem.h> -#include <ndb_version.h> +#include <util/version.h> #define DEBUG_PRINT 0 #define INCOMPATIBLE_VERSION -2 diff --git a/storage/ndb/tools/restore/restore_main.cpp b/storage/ndb/tools/restore/restore_main.cpp index ec2550118d3..c12dc4dd0e8 100644 --- a/storage/ndb/tools/restore/restore_main.cpp +++ b/storage/ndb/tools/restore/restore_main.cpp @@ -684,7 +684,7 @@ main(int argc, char** argv) char buf[NDB_VERSION_STRING_BUF_SZ]; info.setLevel(254); info << "Ndb version in backup files: " - << getVersionString(version, 0, buf, sizeof(buf)) << endl; + << ndbGetVersionString(version, 0, buf, sizeof(buf)) << endl; /** * check wheater we can restore the backup (right version). @@ -694,9 +694,9 @@ main(int argc, char** argv) if (version >= MAKE_VERSION(5,1,3) && version <= MAKE_VERSION(5,1,9)) { err << "Restore program incompatible with backup versions between " - << getVersionString(MAKE_VERSION(5,1,3), 0, buf, sizeof(buf)) + << ndbGetVersionString(MAKE_VERSION(5,1,3), 0, buf, sizeof(buf)) << " and " - << getVersionString(MAKE_VERSION(5,1,9), 0, buf, sizeof(buf)) + << ndbGetVersionString(MAKE_VERSION(5,1,9), 0, buf, sizeof(buf)) << endl; exitHandler(NDBT_FAILED); } diff --git a/strings/conf_to_src.c b/strings/conf_to_src.c index e2ac9846c85..75776d5e6d0 100644 --- a/strings/conf_to_src.c +++ b/strings/conf_to_src.c @@ -243,6 +243,28 @@ void dispcset(FILE *f,CHARSET_INFO *cs) } +static void +fprint_copyright(FILE *file) +{ + fprintf(file, +"/* Copyright (C) 2000-2007 MySQL AB\n" +"\n" +" This program is free software; you can redistribute it and/or modify\n" +" it under the terms of the GNU General Public License as published by\n" +" the Free Software Foundation; version 2 of the License.\n" +"\n" +" This program is distributed in the hope that it will be useful,\n" +" but WITHOUT ANY WARRANTY; without even the implied warranty of\n" +" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" +" GNU General Public License for more details.\n" +"\n" +" You should have received a copy of the GNU General Public License\n" +" along with this program; if not, write to the Free Software\n" +" Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */\n" +"\n"); +} + + int main(int argc, char **argv __attribute__((unused))) { @@ -283,6 +305,7 @@ main(int argc, char **argv __attribute__((unused))) "directory:\n"); fprintf(f, " ./conf_to_src ../sql/share/charsets/ > FILE\n"); fprintf(f, "*/\n\n"); + fprint_copyright(f); fprintf(f,"#include <my_global.h>\n"); fprintf(f,"#include <m_ctype.h>\n\n"); diff --git a/strings/ctype-cp932.c b/strings/ctype-cp932.c index 72b00679e1c..a0ff0314246 100644 --- a/strings/ctype-cp932.c +++ b/strings/ctype-cp932.c @@ -250,9 +250,16 @@ static int my_strnncollsp_cp932(CHARSET_INFO *cs __attribute__((unused)), const uchar *a_end= a + a_length; const uchar *b_end= b + b_length; int res= my_strnncoll_cp932_internal(cs, &a, a_length, &b, b_length); + +#ifndef VARCHAR_WITH_DIFF_ENDSPACE_ARE_DIFFERENT_FOR_UNIQUE + diff_if_only_endspace_difference= 0; +#endif + if (!res && (a != a_end || b != b_end)) { - int swap= 0; + int swap= 1; + if (diff_if_only_endspace_difference) + res= 1; /* Assume 'a' is bigger */ /* Check the next not space character of the longer key. If it's < ' ', then it's smaller than the other key. @@ -263,11 +270,12 @@ static int my_strnncollsp_cp932(CHARSET_INFO *cs __attribute__((unused)), a_end= b_end; a= b; swap= -1; /* swap sign of result */ + res= -res; } for (; a < a_end ; a++) { - if (*a != ' ') - return ((int) *a - (int) ' ') ^ swap; + if (*a != (uchar) ' ') + return (*a < (uchar) ' ') ? -swap : swap; } } return res; diff --git a/strings/ctype-extra.c b/strings/ctype-extra.c index 2b66989ed3e..6d595af51ae 100644 --- a/strings/ctype-extra.c +++ b/strings/ctype-extra.c @@ -6,6 +6,21 @@ ./conf_to_src ../sql/share/charsets/ > FILE */ +/* Copyright (C) 2000-2007 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + #include <my_global.h> #include <m_ctype.h> @@ -908,7 +923,7 @@ uint16 to_uni_ascii_general_ci[] = { 0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067, 0x0068,0x0069,0x006A,0x006B,0x006C,0x006D,0x006E,0x006F, 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077, -0x0078,0x0079,0x007A,0x007B,0x007C,0x007D,0x007E,0x0000, +0x0078,0x0079,0x007A,0x007B,0x007C,0x007D,0x007E,0x007F, 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, @@ -4589,7 +4604,7 @@ uint16 to_uni_ascii_bin[] = { 0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067, 0x0068,0x0069,0x006A,0x006B,0x006C,0x006D,0x006E,0x006F, 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077, -0x0078,0x0079,0x007A,0x007B,0x007C,0x007D,0x007E,0x0000, +0x0078,0x0079,0x007A,0x007B,0x007C,0x007D,0x007E,0x007F, 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, diff --git a/strings/ctype-simple.c b/strings/ctype-simple.c index 9a80b932d20..6b71f29f0d2 100644 --- a/strings/ctype-simple.c +++ b/strings/ctype-simple.c @@ -185,7 +185,7 @@ int my_strnncollsp_simple(CHARSET_INFO * cs, const uchar *a, size_t a_length, } for (end= a + a_length-length; a < end ; a++) { - if (*a != ' ') + if (map[*a] != ' ') return (map[*a] < ' ') ? -swap : swap; } } diff --git a/strings/ctype-utf8.c b/strings/ctype-utf8.c index 851cef54b5b..2b248f1eed5 100644 --- a/strings/ctype-utf8.c +++ b/strings/ctype-utf8.c @@ -2812,16 +2812,19 @@ static int my_strnncoll_utf8_cs(CHARSET_INFO *cs, static int my_strnncollsp_utf8_cs(CHARSET_INFO *cs, const uchar *s, size_t slen, const uchar *t, size_t tlen, - my_bool diff_if_only_endspace_difference - __attribute__((unused))) + my_bool diff_if_only_endspace_difference) { - int s_res,t_res; - my_wc_t s_wc,t_wc; - const uchar *se= s+slen; - const uchar *te= t+tlen; - int save_diff = 0; + int s_res, t_res, res; + my_wc_t s_wc, t_wc; + const uchar *se= s + slen; + const uchar *te= t + tlen; + int save_diff= 0; MY_UNICASE_INFO **uni_plane= cs->caseinfo; - + +#ifndef VARCHAR_WITH_DIFF_ENDSPACE_ARE_DIFFERENT_FOR_UNIQUE + diff_if_only_endspace_difference= 0; +#endif + while ( s < se && t < te ) { int plane; @@ -2853,16 +2856,20 @@ static int my_strnncollsp_utf8_cs(CHARSET_INFO *cs, slen= se-s; tlen= te-t; + res= 0; if (slen != tlen) { - int swap= 0; + int swap= 1; + if (diff_if_only_endspace_difference) + res= 1; /* Assume 'a' is bigger */ if (slen < tlen) { slen= tlen; s= t; se= te; swap= -1; + res= -res; } /* This following loop uses the fact that in UTF-8 @@ -2876,8 +2883,8 @@ static int my_strnncollsp_utf8_cs(CHARSET_INFO *cs, */ for ( ; s < se; s++) { - if (*s != ' ') - return ((int)*s - (int) ' ') ^ swap; + if (*s != (uchar) ' ') + return (*s < (uchar) ' ') ? -swap : swap; } } return save_diff; diff --git a/support-files/Makefile.am b/support-files/Makefile.am index b3581d65eb0..36dcd36e25b 100644 --- a/support-files/Makefile.am +++ b/support-files/Makefile.am @@ -25,6 +25,7 @@ EXTRA_DIST = mysql.spec.sh \ my-innodb-heavy-4G.cnf.sh \ mysql-log-rotate.sh \ mysql.server.sh \ + mysqld_multi.server.sh \ binary-configure.sh \ magic mysql.m4 \ MySQL-shared-compat.spec.sh \ @@ -42,7 +43,8 @@ pkgdata_DATA = my-small.cnf \ binary-configure \ ndb-config-2-node.ini -pkgdata_SCRIPTS = mysql.server +pkgdata_SCRIPTS = mysql.server \ + mysqld_multi.server aclocaldir = $(datadir)/aclocal aclocal_DATA = mysql.m4 @@ -59,6 +61,7 @@ CLEANFILES = my-small.cnf \ mysql-@VERSION@.spec \ mysql-log-rotate \ mysql.server \ + mysqld_multi.server \ binary-configure \ MySQL-shared-compat.spec \ ndb-config-2-node.ini diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index cb1561ad6f5..eac1ad413ea 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -16271,6 +16271,70 @@ static void test_bug27592() } + +/* + Bug#29687 mysql_stmt_store_result memory leak in libmysqld +*/ + +static void test_bug29687() +{ + const int NUM_ITERATIONS= 40; + int i; + int rc; + MYSQL_STMT *stmt= NULL; + + DBUG_ENTER("test_bug29687"); + myheader("test_bug29687"); + + stmt= mysql_simple_prepare(mysql, "SELECT 1 FROM dual WHERE 0=2"); + DIE_UNLESS(stmt); + + for (i= 0; i < NUM_ITERATIONS; i++) + { + rc= mysql_stmt_execute(stmt); + check_execute(stmt, rc); + mysql_stmt_store_result(stmt); + while (mysql_stmt_fetch(stmt)==0); + mysql_stmt_free_result(stmt); + } + + mysql_stmt_close(stmt); + DBUG_VOID_RETURN; +} + + +/* + Bug #29692 Single row inserts can incorrectly report a huge number of + row insertions +*/ + +static void test_bug29692() +{ + MYSQL* conn; + + if (!(conn= mysql_init(NULL))) + { + myerror("test_bug29692 init failed"); + exit(1); + } + + if (!(mysql_real_connect(conn, opt_host, opt_user, + opt_password, opt_db ? opt_db:"test", opt_port, + opt_unix_socket, CLIENT_FOUND_ROWS))) + { + myerror("test_bug29692 connection failed"); + mysql_close(mysql); + exit(1); + } + myquery(mysql_query(conn, "drop table if exists t1")); + myquery(mysql_query(conn, "create table t1(f1 int)")); + myquery(mysql_query(conn, "insert into t1 values(1)")); + DIE_UNLESS(1 == mysql_affected_rows(conn)); + myquery(mysql_query(conn, "drop table t1")); + mysql_close(conn); +} + + /* Read and parse arguments and MySQL options from my.cnf */ @@ -16560,6 +16624,8 @@ static struct my_tests_st my_tests[]= { { "test_bug28505", test_bug28505 }, { "test_bug28934", test_bug28934 }, { "test_bug27592", test_bug27592 }, + { "test_bug29687", test_bug29687 }, + { "test_bug29692", test_bug29692 }, { 0, 0 } }; diff --git a/vio/viossl.c b/vio/viossl.c index 32cfecdb9c8..2c74efb1bef 100644 --- a/vio/viossl.c +++ b/vio/viossl.c @@ -124,6 +124,16 @@ int vio_ssl_close(Vio *vio) if (ssl) { + /* + THE SSL standard says that SSL sockets must send and receive a close_notify + alert on socket shutdown to avoid truncation attacks. However, this can + cause problems since we often hold a lock during shutdown and this IO can + take an unbounded amount of time to complete. Since our packets are self + describing with length, we aren't vunerable to these attacks. Therefore, + we just shutdown by closing the socket (quiet shutdown). + */ + SSL_set_quiet_shutdown(ssl, 1); + switch ((r= SSL_shutdown(ssl))) { case 1: /* Shutdown successful */ diff --git a/win/configure.js b/win/configure.js index 06c2fe56a51..2b0e2bbcc37 100644 --- a/win/configure.js +++ b/win/configure.js @@ -51,6 +51,7 @@ try configfile.WriteLine("SET (" + args.Item(i) + " TRUE)"); break; case "MYSQL_SERVER_SUFFIX": + case "MYSQLD_EXE_SUFFIX": configfile.WriteLine("SET (" + parts[0] + " \"" + parts[1] + "\")"); break; |