diff options
24 files changed, 295 insertions, 71 deletions
diff --git a/client/mysqladmin.cc b/client/mysqladmin.cc index 35afe06eade..66678f3fd77 100644 --- a/client/mysqladmin.cc +++ b/client/mysqladmin.cc @@ -310,7 +310,6 @@ int main(int argc,char *argv[]) char **commands, **save_argv, **temp_argv; MY_INIT(argv[0]); - mysql_init(&mysql); sf_leaking_memory=1; /* don't report memory leaks on early exits */ load_defaults_or_exit("my", load_default_groups, &argc, &argv); save_argv = argv; /* Save for free_defaults */ @@ -339,6 +338,7 @@ int main(int argc,char *argv[]) sf_leaking_memory=0; /* from now on we cleanup properly */ + mysql_init(&mysql); if (opt_compress) mysql_options(&mysql,MYSQL_OPT_COMPRESS,NullS); if (opt_connect_timeout) diff --git a/dbug/tests.c b/dbug/tests.c index 22a445fdeca..70424046bf4 100644 --- a/dbug/tests.c +++ b/dbug/tests.c @@ -86,3 +86,11 @@ int main (int argc __attribute__((unused)), return 0; #endif /* DBUG_OFF */ } + +#ifdef __SANITIZE_ADDRESS__ +/* Disable LeakSanitizer in this executable */ +const char* __asan_default_options() +{ + return "detect_leaks=0"; +} +#endif diff --git a/include/my_pthread.h b/include/my_pthread.h index 843701ccab9..4d33d1abdd4 100644 --- a/include/my_pthread.h +++ b/include/my_pthread.h @@ -1,5 +1,5 @@ /* Copyright (c) 2000, 2014, Oracle and/or its affiliates. - Copyright (c) 2009, 2017, MariaDB Corporation. + Copyright (c) 2009, 2019, MariaDB Corporation. 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 @@ -703,7 +703,11 @@ extern void my_mutex_end(void); We need to have at least 256K stack to handle calls to myisamchk_init() with the current number of keys and key parts. */ -#define DEFAULT_THREAD_STACK (292*1024L) +#ifdef __SANITIZE_ADDRESS__ +#define DEFAULT_THREAD_STACK (383*1024L) /* 392192 */ +#else +#define DEFAULT_THREAD_STACK (292*1024L) /* 299008 */ +#endif #endif #define MY_PTHREAD_LOCK_READ 0 diff --git a/mysql-test/main/derived_cond_pushdown.result b/mysql-test/main/derived_cond_pushdown.result index dae127b12ea..a13ce8575de 100644 --- a/mysql-test/main/derived_cond_pushdown.result +++ b/mysql-test/main/derived_cond_pushdown.result @@ -10497,6 +10497,27 @@ EXPLAIN } DROP VIEW v1,v2; DROP TABLE t1; +# +# MDEV-18383: pushdown condition with the IF structure +# defined with Item_cond item +# +CREATE TABLE t1(a INT, b INT); +CREATE TABLE t2(c INT, d INT); +INSERT INTO t1 VALUES (1,2),(3,4),(5,6); +INSERT INTO t2 VALUES (1,3),(3,7),(5,1); +SELECT * +FROM t1, +( +SELECT MAX(d) AS max_d,c +FROM t2 +GROUP BY c +) AS tab +WHERE t1.a=tab.c AND +IF(2,t1.a=1 OR t1.b>5,1=1); +a b max_d c +1 2 3 1 +5 6 1 5 +DROP TABLE t1,t2; # End of 10.2 tests # # MDEV-14579: pushdown conditions into materialized views/derived tables diff --git a/mysql-test/main/derived_cond_pushdown.test b/mysql-test/main/derived_cond_pushdown.test index ef28dcf1d97..ebbda849afa 100644 --- a/mysql-test/main/derived_cond_pushdown.test +++ b/mysql-test/main/derived_cond_pushdown.test @@ -2102,6 +2102,28 @@ eval EXPLAIN FORMAT=JSON $q2; DROP VIEW v1,v2; DROP TABLE t1; +--echo # +--echo # MDEV-18383: pushdown condition with the IF structure +--echo # defined with Item_cond item +--echo # + +CREATE TABLE t1(a INT, b INT); +CREATE TABLE t2(c INT, d INT); +INSERT INTO t1 VALUES (1,2),(3,4),(5,6); +INSERT INTO t2 VALUES (1,3),(3,7),(5,1); + +SELECT * +FROM t1, +( + SELECT MAX(d) AS max_d,c + FROM t2 + GROUP BY c +) AS tab +WHERE t1.a=tab.c AND + IF(2,t1.a=1 OR t1.b>5,1=1); + +DROP TABLE t1,t2; + --echo # End of 10.2 tests --echo # diff --git a/mysql-test/main/mysqld--help.test b/mysql-test/main/mysqld--help.test index 27d3286685b..c2b6424599a 100644 --- a/mysql-test/main/mysqld--help.test +++ b/mysql-test/main/mysqld--help.test @@ -57,7 +57,7 @@ perl; # fixes for 32-bit s/\b4294967295\b/18446744073709551615/; s/\b2146435072\b/9223372036853727232/; - s/\b196608\b/262144/; + s/\b392192\b/299008/; s/\b4294963200\b/18446744073709547520/; foreach $var (@env) { s/\Q$ENV{$var}\E/$var/ } next if /use --skip-(use-)?symbolic-links to disable/; # for valgrind, again diff --git a/mysql-test/suite/innodb/r/alter_crash.result b/mysql-test/suite/innodb/r/alter_crash.result index 3c3aaa68b6a..cb9c17e45ea 100644 --- a/mysql-test/suite/innodb/r/alter_crash.result +++ b/mysql-test/suite/innodb/r/alter_crash.result @@ -3,6 +3,9 @@ # CREATE TABLE t1(c1 INT PRIMARY KEY, c2 CHAR(1), c3 INT UNSIGNED) ENGINE=InnoDB; SET @saved_debug_dbug = @@SESSION.debug_dbug; +SET DEBUG_DBUG='+d,create_index_metadata_fail'; +ALTER TABLE t1 ADD INDEX (c2), ADD INDEX (c3); +ERROR HY000: The table 't1' is full SET DEBUG_DBUG='+d,ib_create_table_fail_too_many_trx'; ALTER TABLE t1 ADD INDEX (c2), ADD INDEX (c3); ERROR HY000: Too many active concurrent transactions diff --git a/mysql-test/suite/innodb/r/foreign_key.result b/mysql-test/suite/innodb/r/foreign_key.result index a6322284923..75197099c11 100644 --- a/mysql-test/suite/innodb/r/foreign_key.result +++ b/mysql-test/suite/innodb/r/foreign_key.result @@ -137,6 +137,8 @@ SELECT unique_constraint_name FROM information_schema.referential_constraints WHERE table_name = 't2'; unique_constraint_name PRIMARY +SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency; +SET GLOBAL innodb_purge_rseg_truncate_frequency = 1; SELECT unique_constraint_name FROM information_schema.referential_constraints WHERE table_name = 't2'; unique_constraint_name @@ -194,17 +196,19 @@ DROP DATABASE best; # # MDEV-17541 KILL QUERY during lock wait in FOREIGN KEY check hangs # -connect fk, localhost, root,,; +connect con1, localhost, root,,; INSERT INTO t1 SET a=1; BEGIN; DELETE FROM t1; connection default; INSERT INTO t3 SET a=1; -connection fk; +connection con1; kill query @id; connection default; ERROR 70100: Query execution was interrupted -disconnect fk; +connection con1; +ROLLBACK; +connection default; DROP TABLE t3,t1; # # MDEV-18222 InnoDB: Failing assertion: heap->magic_n == MEM_BLOCK_MAGIC_N @@ -298,7 +302,7 @@ INSERT INTO matchmaking_group_users VALUES (10,1),(11,2); INSERT INTO matchmaking_group_maps VALUES (10,55),(11,66); BEGIN; UPDATE users SET name = 'qux' WHERE id = 1; -connect con1,localhost,root,,; +connection con1; SET innodb_lock_wait_timeout= 1; DELETE FROM matchmaking_groups WHERE id = 10; connection default; @@ -443,6 +447,69 @@ connection con1; kill query @id; connection default; ERROR 70100: Query execution was interrupted -disconnect con1; +connection con1; +ROLLBACK; +connection default; DROP TABLE t2,t1; +# +# MDEV-18272 InnoDB index corruption after failed DELETE CASCADE +# +CREATE TABLE t1 ( +pk TINYINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, +a TINYINT UNSIGNED NOT NULL, b TINYINT UNSIGNED NOT NULL, KEY(b), +CONSTRAINT FOREIGN KEY (a) REFERENCES t1 (b) ON DELETE CASCADE +) ENGINE=InnoDB; +INSERT INTO t1 (a,b) VALUES +(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0), +(0,1),(0,1),(1,0); +connection con1; +START TRANSACTION WITH CONSISTENT SNAPSHOT; +connection default; +DELETE IGNORE FROM t1 WHERE b = 1; +Warnings: +Warning 152 InnoDB: Cannot delete/update rows with cascading foreign key constraints that exceed max depth of 20. Please drop extra constraints and try again +Warning 1296 Got error 193 '`test`.`t1`, CONSTRAINT `t1_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`b`) ON DELETE CASCADE' from InnoDB +Warning 152 InnoDB: Cannot delete/update rows with cascading foreign key constraints that exceed max depth of 20. Please drop extra constraints and try again +Warning 1296 Got error 193 '`test`.`t1`, CONSTRAINT `t1_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`b`) ON DELETE CASCADE' from InnoDB +SELECT a FROM t1 FORCE INDEX(a); +a +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +1 +SELECT * FROM t1; +pk a b +1 0 0 +2 0 0 +3 0 0 +4 0 0 +5 0 0 +6 0 0 +7 0 0 +8 0 0 +9 0 0 +10 0 0 +11 0 0 +12 0 0 +13 0 1 +14 0 1 +15 1 0 +disconnect con1; +InnoDB 0 transactions not purged +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check status OK +DROP TABLE t1; +SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency; # End of 10.2 tests diff --git a/mysql-test/suite/innodb/r/innodb-index-online.result b/mysql-test/suite/innodb/r/innodb-index-online.result index 86c9dd4fbbe..d21dc21c61e 100644 --- a/mysql-test/suite/innodb/r/innodb-index-online.result +++ b/mysql-test/suite/innodb/r/innodb-index-online.result @@ -43,6 +43,10 @@ SET DEBUG_DBUG = '+d,innodb_OOM_inplace_alter'; CREATE UNIQUE INDEX c2 ON t1(c2); ERROR HY000: Out of memory. SET DEBUG_DBUG = @saved_debug_dbug; +SET DEBUG_DBUG = '+d,innodb_OOM_prepare_add_index'; +ALTER TABLE t1 ADD KEY(c2), ADD KEY c3_10(c3(10)), ADD KEY c3_c2(c3(4),c2); +ERROR HY000: Out of memory. +SET DEBUG_DBUG = @saved_debug_dbug; CREATE UNIQUE INDEX c2 ON t1(c2); DROP INDEX c2 ON t1; connection default; diff --git a/mysql-test/suite/innodb/t/alter_crash.test b/mysql-test/suite/innodb/t/alter_crash.test index 101e0fa44c2..c7cd1bcfe66 100644 --- a/mysql-test/suite/innodb/t/alter_crash.test +++ b/mysql-test/suite/innodb/t/alter_crash.test @@ -7,8 +7,6 @@ --source include/not_crashrep.inc --disable_query_log -call mtr.add_suppression('InnoDB: cannot find a free slot for an undo log'); -call mtr.add_suppression('InnoDB: row_merge_rename_index_to_add failed with error 47'); call mtr.add_suppression('InnoDB: Flagged corruption of `c[23]`'); call mtr.add_suppression('InnoDB: Index `c[23]` .*is corrupted'); --enable_query_log @@ -19,6 +17,10 @@ call mtr.add_suppression('InnoDB: Index `c[23]` .*is corrupted'); CREATE TABLE t1(c1 INT PRIMARY KEY, c2 CHAR(1), c3 INT UNSIGNED) ENGINE=InnoDB; SET @saved_debug_dbug = @@SESSION.debug_dbug; +SET DEBUG_DBUG='+d,create_index_metadata_fail'; +--error ER_RECORD_FILE_FULL +ALTER TABLE t1 ADD INDEX (c2), ADD INDEX (c3); + SET DEBUG_DBUG='+d,ib_create_table_fail_too_many_trx'; --error ER_TOO_MANY_CONCURRENT_TRXS ALTER TABLE t1 ADD INDEX (c2), ADD INDEX (c3); diff --git a/mysql-test/suite/innodb/t/foreign_key.test b/mysql-test/suite/innodb/t/foreign_key.test index 4330f807d69..a4e045d4d5e 100644 --- a/mysql-test/suite/innodb/t/foreign_key.test +++ b/mysql-test/suite/innodb/t/foreign_key.test @@ -103,6 +103,9 @@ WHERE table_name = 't2'; --source include/restart_mysqld.inc +SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency; +SET GLOBAL innodb_purge_rseg_truncate_frequency = 1; + SELECT unique_constraint_name FROM information_schema.referential_constraints WHERE table_name = 't2'; @@ -148,6 +151,7 @@ SET FOREIGN_KEY_CHECKS=1; call mtr.add_suppression("InnoDB: Possible reasons:"); call mtr.add_suppression("InnoDB: \\([12]\\) Table "); call mtr.add_suppression("InnoDB: If table `test`\\.`t2` is a temporary table"); +call mtr.add_suppression("InnoDB: Cannot delete/update rows with cascading foreign key constraints that exceed max depth of 15\\."); --enable_query_log CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB; @@ -165,7 +169,7 @@ DROP DATABASE best; --echo # --echo # MDEV-17541 KILL QUERY during lock wait in FOREIGN KEY check hangs --echo # -connect (fk, localhost, root,,); +connect (con1, localhost, root,,); INSERT INTO t1 SET a=1; BEGIN; DELETE FROM t1; @@ -174,7 +178,7 @@ connection default; let $ID= `SELECT @id := CONNECTION_ID()`; send INSERT INTO t3 SET a=1; -connection fk; +connection con1; # Check that the above SELECT is blocked let $wait_condition= select count(*) = 1 from information_schema.processlist @@ -186,7 +190,10 @@ kill query @id; connection default; --error ER_QUERY_INTERRUPTED reap; -disconnect fk; + +connection con1; +ROLLBACK; +connection default; DROP TABLE t3,t1; @@ -286,7 +293,7 @@ INSERT INTO matchmaking_group_maps VALUES (10,55),(11,66); BEGIN; UPDATE users SET name = 'qux' WHERE id = 1; ---connect (con1,localhost,root,,) +--connection con1 SET innodb_lock_wait_timeout= 1; DELETE FROM matchmaking_groups WHERE id = 10; @@ -442,10 +449,44 @@ kill query @id; connection default; --error ER_QUERY_INTERRUPTED reap; -disconnect con1; + +connection con1; +ROLLBACK; +connection default; DROP TABLE t2,t1; +--echo # +--echo # MDEV-18272 InnoDB index corruption after failed DELETE CASCADE +--echo # +CREATE TABLE t1 ( + pk TINYINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, + a TINYINT UNSIGNED NOT NULL, b TINYINT UNSIGNED NOT NULL, KEY(b), + CONSTRAINT FOREIGN KEY (a) REFERENCES t1 (b) ON DELETE CASCADE +) ENGINE=InnoDB; + +INSERT INTO t1 (a,b) VALUES +(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0), +(0,1),(0,1),(1,0); +connection con1; +START TRANSACTION WITH CONSISTENT SNAPSHOT; + +connection default; +DELETE IGNORE FROM t1 WHERE b = 1; + +SELECT a FROM t1 FORCE INDEX(a); +# This would wrongly return the empty result if +# the "goto rollback_to_savept" in row_mysql_handle_errors() is reverted. +SELECT * FROM t1; +# Allow purge to continue by closing the read view. +disconnect con1; + +# Wait for purge. With the fix reverted, the server would crash here. +--source include/wait_all_purged.inc +CHECK TABLE t1; +DROP TABLE t1; +SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency; + --echo # End of 10.2 tests --source include/wait_until_count_sessions.inc diff --git a/mysql-test/suite/innodb/t/innodb-index-online.test b/mysql-test/suite/innodb/t/innodb-index-online.test index 5d92b010e60..4cdbdb7c584 100644 --- a/mysql-test/suite/innodb/t/innodb-index-online.test +++ b/mysql-test/suite/innodb/t/innodb-index-online.test @@ -53,6 +53,10 @@ SET DEBUG_DBUG = '+d,innodb_OOM_inplace_alter'; --error ER_OUT_OF_RESOURCES CREATE UNIQUE INDEX c2 ON t1(c2); SET DEBUG_DBUG = @saved_debug_dbug; +SET DEBUG_DBUG = '+d,innodb_OOM_prepare_add_index'; +--error ER_OUT_OF_RESOURCES +ALTER TABLE t1 ADD KEY(c2), ADD KEY c3_10(c3(10)), ADD KEY c3_c2(c3(4),c2); +SET DEBUG_DBUG = @saved_debug_dbug; CREATE UNIQUE INDEX c2 ON t1(c2); DROP INDEX c2 ON t1; diff --git a/mysql-test/suite/sys_vars/inc/sysvars_server.inc b/mysql-test/suite/sys_vars/inc/sysvars_server.inc index d14e905378c..af1b0ce4563 100644 --- a/mysql-test/suite/sys_vars/inc/sysvars_server.inc +++ b/mysql-test/suite/sys_vars/inc/sysvars_server.inc @@ -13,7 +13,7 @@ set sql_mode=ansi_quotes; set global div_precision_increment=5; --replace_regex /^\/\S+/PATH/ ---replace_result $MASTER_MYPORT MASTER_MYPORT +--replace_result $MASTER_MYPORT MASTER_MYPORT 392192 299008 select * from information_schema.system_variables where variable_name not like 'aria%' and variable_name not like 'debug%' and diff --git a/mysql-test/suite/sys_vars/t/thread_stack_basic.test b/mysql-test/suite/sys_vars/t/thread_stack_basic.test index 2d4d144572d..41015033fe9 100644 --- a/mysql-test/suite/sys_vars/t/thread_stack_basic.test +++ b/mysql-test/suite/sys_vars/t/thread_stack_basic.test @@ -1,17 +1,17 @@ # # only global # ---replace_result 196608 262144 +--replace_result 392192 299008 select @@global.thread_stack; --error ER_INCORRECT_GLOBAL_LOCAL_VAR select @@session.thread_stack; ---replace_result 196608 262144 +--replace_result 392192 299008 show global variables like 'thread_stack'; ---replace_result 196608 262144 +--replace_result 392192 299008 show session variables like 'thread_stack'; ---replace_result 196608 262144 +--replace_result 392192 299008 select * from information_schema.global_variables where variable_name='thread_stack'; ---replace_result 196608 262144 +--replace_result 392192 299008 select * from information_schema.session_variables where variable_name='thread_stack'; # diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index ffb7b60e4de..86725de8ae7 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -5209,6 +5209,23 @@ Item *Item_cond::build_clone(THD *thd) } +bool Item_cond::excl_dep_on_table(table_map tab_map) +{ + if (used_tables() & OUTER_REF_TABLE_BIT) + return false; + if (!(used_tables() & ~tab_map)) + return true; + List_iterator_fast<Item> li(list); + Item *item; + while ((item= li++)) + { + if (!item->excl_dep_on_table(tab_map)) + return false; + } + return true; +} + + bool Item_cond::excl_dep_on_grouping_fields(st_select_lex *sel) { List_iterator_fast<Item> li(list); diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index ed9dc5fb59f..d78977544c7 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -3010,6 +3010,7 @@ public: Item_transformer transformer, uchar *arg_t); bool eval_not_null_tables(void *opt_arg); Item *build_clone(THD *thd); + bool excl_dep_on_table(table_map tab_map); bool excl_dep_on_grouping_fields(st_select_lex *sel); bool excl_dep_on_group_fields_for_having_pushdown(st_select_lex *sel); }; diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc index 78b6d562f13..3ecfd7a096c 100644 --- a/storage/innobase/dict/dict0dict.cc +++ b/storage/innobase/dict/dict0dict.cc @@ -6032,23 +6032,16 @@ dict_ind_free() /** Get an index by name. @param[in] table the table where to look for the index @param[in] name the index name to look for -@param[in] committed true=search for committed, -false=search for uncommitted @return index, NULL if does not exist */ dict_index_t* -dict_table_get_index_on_name( - dict_table_t* table, - const char* name, - bool committed) +dict_table_get_index_on_name(dict_table_t* table, const char* name) { dict_index_t* index; index = dict_table_get_first_index(table); while (index != NULL) { - if (index->is_committed() == committed - && strcmp(index->name, name) == 0) { - + if (index->is_committed() && !strcmp(index->name, name)) { return(index); } diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 57ebde11ece..4e336413abc 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -5935,11 +5935,13 @@ create_index_dict( que_run_threads(thr); + DBUG_ASSERT(trx->error_state != DB_SUCCESS || index != node->index); + DBUG_ASSERT(trx->error_state != DB_SUCCESS || node->index); index = node->index; que_graph_free((que_t*) que_node_get_parent(thr)); - DBUG_RETURN(trx->error_state == DB_SUCCESS ? index : NULL); + DBUG_RETURN(index); } /** Update internal structures with concurrent writes blocked, @@ -6646,18 +6648,23 @@ new_table_failed: } for (ulint a = 0; a < ctx->num_to_add_index; a++) { - dict_index_t*& index = ctx->add_index[a]; + dict_index_t* index = ctx->add_index[a]; const bool has_new_v_col = index->has_new_v_col; index = create_index_dict(ctx->trx, index, add_v); - if (!index) { - error = ctx->trx->error_state; - ut_ad(error != DB_SUCCESS); + error = ctx->trx->error_state; + if (error != DB_SUCCESS) { + if (index) { + dict_mem_index_free(index); + } while (++a < ctx->num_to_add_index) { dict_mem_index_free(ctx->add_index[a]); } goto error_handling; + } else { + DBUG_ASSERT(index != ctx->add_index[a]); } + ctx->add_index[a] = index; index->parser = index_defs[a].parser; index->has_new_v_col = has_new_v_col; /* Note the id of the transaction that created this @@ -6728,18 +6735,33 @@ new_table_failed: ctx->trx->table_id = user_table->id; for (ulint a = 0; a < ctx->num_to_add_index; a++) { - dict_index_t*& index = ctx->add_index[a]; + dict_index_t* index = ctx->add_index[a]; const bool has_new_v_col = index->has_new_v_col; + DBUG_EXECUTE_IF( + "create_index_metadata_fail", + if (a + 1 == ctx->num_to_add_index) { + ctx->trx->error_state = + DB_OUT_OF_FILE_SPACE; + goto index_created; + }); index = create_index_dict(ctx->trx, index, add_v); - if (!index) { - error = ctx->trx->error_state; - ut_ad(error != DB_SUCCESS); +#ifndef DBUG_OFF +index_created: +#endif + error = ctx->trx->error_state; + if (error != DB_SUCCESS) { + if (index) { + dict_mem_index_free(index); + } error_handling_drop_uncached: while (++a < ctx->num_to_add_index) { dict_mem_index_free(ctx->add_index[a]); } goto error_handling; + } else { + DBUG_ASSERT(index != ctx->add_index[a]); } + ctx->add_index[a]= index; index->parser = index_defs[a].parser; index->has_new_v_col = has_new_v_col; @@ -6763,10 +6785,6 @@ error_handling_drop_uncached: /* No need to allocate a modification log. */ DBUG_ASSERT(!index->online_log); } else { - DBUG_EXECUTE_IF( - "innodb_OOM_prepare_inplace_alter", - error = DB_OUT_OF_MEMORY; - goto error_handling_drop_uncached;); rw_lock_x_lock(&ctx->add_index[a]->lock); bool ok = row_log_allocate( @@ -6778,6 +6796,14 @@ error_handling_drop_uncached: rw_lock_x_unlock(&index->lock); + DBUG_EXECUTE_IF( + "innodb_OOM_prepare_add_index", + if (ok && a == 1) { + row_log_free( + index->online_log); + ok = false; + }); + if (!ok) { error = DB_OUT_OF_MEMORY; goto error_handling_drop_uncached; diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h index 202d56365b7..64811372796 100644 --- a/storage/innobase/include/dict0dict.h +++ b/storage/innobase/include/dict0dict.h @@ -1431,31 +1431,21 @@ dict_tables_have_same_db( /** Get an index by name. @param[in] table the table where to look for the index @param[in] name the index name to look for -@param[in] committed true=search for committed, -false=search for uncommitted @return index, NULL if does not exist */ dict_index_t* -dict_table_get_index_on_name( - dict_table_t* table, - const char* name, - bool committed=true) +dict_table_get_index_on_name(dict_table_t* table, const char* name) MY_ATTRIBUTE((warn_unused_result)); /** Get an index by name. @param[in] table the table where to look for the index @param[in] name the index name to look for -@param[in] committed true=search for committed, -false=search for uncommitted @return index, NULL if does not exist */ inline const dict_index_t* -dict_table_get_index_on_name( - const dict_table_t* table, - const char* name, - bool committed=true) +dict_table_get_index_on_name(const dict_table_t* table, const char* name) { - return(dict_table_get_index_on_name( - const_cast<dict_table_t*>(table), name, committed)); + return dict_table_get_index_on_name(const_cast<dict_table_t*>(table), + name); } /*************************************************************** diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index 7ae400c8860..6e05a0c81e7 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -705,8 +705,7 @@ handle_new_error: switch (err) { case DB_LOCK_WAIT_TIMEOUT: if (row_rollback_on_timeout) { - trx_rollback_to_savepoint(trx, NULL); - break; + goto rollback; } /* fall through */ case DB_DUPLICATE_KEY: @@ -725,6 +724,7 @@ handle_new_error: case DB_TABLE_NOT_FOUND: case DB_DECRYPTION_FAILED: case DB_COMPUTE_VALUE_FAILED: + rollback_to_savept: DBUG_EXECUTE_IF("row_mysql_crash_if_error", { log_buffer_flush_to_disk(); DBUG_SUICIDE(); }); @@ -751,6 +751,7 @@ handle_new_error: case DB_DEADLOCK: case DB_LOCK_TABLE_FULL: + rollback: /* Roll back the whole transaction; this resolution was added to version 3.23.43 */ @@ -772,19 +773,19 @@ handle_new_error: " tablespace. If the mysqld server crashes after" " the startup or when you dump the tables. " << FORCE_RECOVERY_MSG; - break; + goto rollback_to_savept; case DB_FOREIGN_EXCEED_MAX_CASCADE: ib::error() << "Cannot delete/update rows with cascading" " foreign key constraints that exceed max depth of " << FK_MAX_CASCADE_DEL << ". Please drop excessive" " foreign constraints and try again"; - break; + goto rollback_to_savept; case DB_UNSUPPORTED: ib::error() << "Cannot delete/update rows with cascading" " foreign key constraints in timestamp-based temporal" " table. Please drop excessive" " foreign constraints and try again"; - break; + goto rollback_to_savept; default: ib::fatal() << "Unknown error code " << err << ": " << ut_strerr(err); diff --git a/storage/mroonga/ha_mroonga.cpp b/storage/mroonga/ha_mroonga.cpp index d300cf001ed..453dd15da47 100644 --- a/storage/mroonga/ha_mroonga.cpp +++ b/storage/mroonga/ha_mroonga.cpp @@ -2600,7 +2600,7 @@ ha_mroonga::~ha_mroonga() } if (blob_buffers) { - delete [] blob_buffers; + ::delete [] blob_buffers; } grn_obj_unlink(ctx, &top_left_point); grn_obj_unlink(ctx, &bottom_right_point); @@ -14541,6 +14541,7 @@ enum_alter_inplace_result ha_mroonga::wrapper_check_if_supported_inplace_alter( ALTER_COLUMN_NULLABLE | ALTER_COLUMN_NOT_NULLABLE | ALTER_COLUMN_STORAGE_TYPE | + ALTER_ADD_STORED_GENERATED_COLUMN | ALTER_COLUMN_COLUMN_FORMAT ) ) @@ -14659,7 +14660,6 @@ enum_alter_inplace_result ha_mroonga::storage_check_if_supported_inplace_alter( ALTER_DROP_UNIQUE_INDEX | MRN_ALTER_INPLACE_INFO_ADD_VIRTUAL_COLUMN | MRN_ALTER_INPLACE_INFO_ADD_STORED_BASE_COLUMN | - MRN_ALTER_INPLACE_INFO_ADD_STORED_GENERATED_COLUMN | ALTER_DROP_COLUMN | ALTER_COLUMN_NAME; if (ha_alter_info->handler_flags & explicitly_unsupported_flags) { diff --git a/storage/mroonga/mysql-test/mroonga/storage/r/column_generated_stored_add_column.result b/storage/mroonga/mysql-test/mroonga/storage/r/column_generated_stored_add_column.result index 20213f0cbf8..924c3134a3e 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/r/column_generated_stored_add_column.result +++ b/storage/mroonga/mysql-test/mroonga/storage/r/column_generated_stored_add_column.result @@ -1,9 +1,10 @@ -DROP TABLE IF EXISTS logs; +set names utf8mb4; CREATE TABLE logs ( id INT, record JSON ) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4; INSERT INTO logs(id, record) VALUES (1, '{"level": "info", "message": "start"}'); +INSERT INTO logs(id, record) VALUES (1, json_object('message', repeat('☹', 253))); ALTER TABLE logs ADD COLUMN message VARCHAR(255) GENERATED ALWAYS AS (json_extract(`record`, '$.message')) STORED; ALTER TABLE logs ADD FULLTEXT INDEX(message) comment 'tokenizer "TokenBigramSplitSymbolAlphaDigit"'; INSERT INTO logs(id, record) VALUES (2, '{"level": "info", "message": "restart"}'); diff --git a/storage/mroonga/mysql-test/mroonga/storage/t/column_generated_stored_add_column.test b/storage/mroonga/mysql-test/mroonga/storage/t/column_generated_stored_add_column.test index 8561688db3a..deae021d540 100644 --- a/storage/mroonga/mysql-test/mroonga/storage/t/column_generated_stored_add_column.test +++ b/storage/mroonga/mysql-test/mroonga/storage/t/column_generated_stored_add_column.test @@ -18,9 +18,7 @@ --source ../../include/mroonga/skip_mariadb_10_1_or_earlier.inc --source ../../include/mroonga/have_mroonga.inc ---disable_warnings -DROP TABLE IF EXISTS logs; ---enable_warnings +set names utf8mb4; CREATE TABLE logs ( id INT, @@ -28,6 +26,7 @@ CREATE TABLE logs ( ) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4; INSERT INTO logs(id, record) VALUES (1, '{"level": "info", "message": "start"}'); +INSERT INTO logs(id, record) VALUES (1, json_object('message', repeat('☹', 253))); ALTER TABLE logs ADD COLUMN message VARCHAR(255) GENERATED ALWAYS AS (json_extract(`record`, '$.message')) STORED; ALTER TABLE logs ADD FULLTEXT INDEX(message) comment 'tokenizer "TokenBigramSplitSymbolAlphaDigit"'; diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 6d17fa74005..cac7c95b280 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -18540,6 +18540,7 @@ static void test_bug42373() DIE_UNLESS(rc == 1); mysql_stmt_close(stmt); + mysql_close(&con); /* Now try with a multi-statement. */ DIE_UNLESS(mysql_client_init(&con)); @@ -19002,8 +19003,6 @@ static void test_progress_reporting() conn= client_connect(CLIENT_PROGRESS_OBSOLETE, MYSQL_PROTOCOL_TCP, 0); - if (!(conn->server_capabilities & CLIENT_PROGRESS_OBSOLETE)) - return; DIE_UNLESS(conn->client_flag & CLIENT_PROGRESS_OBSOLETE); mysql_options(conn, MYSQL_PROGRESS_CALLBACK, (void*) report_progress); @@ -20203,6 +20202,7 @@ static void test_proxy_header_tcp(const char *ipaddr, int port) printf("%.*s %.*s\n", (int)addrlen, row[0], (int)addrlen, normalized_addr); DIE_UNLESS(strncmp(row[0], normalized_addr, addrlen) == 0); DIE_UNLESS(atoi(row[0] + addrlen+1) == port); + mysql_free_result(result); mysql_close(m); } sprintf(query,"DROP USER 'u'@'%s'",normalized_addr); @@ -20241,6 +20241,7 @@ static void test_proxy_header_localhost() mytest(result); row = mysql_fetch_row(result); DIE_UNLESS(strcmp(row[0], "localhost") == 0); + mysql_free_result(result); mysql_close(m); rc = mysql_query(mysql, "DROP USER 'u'@'localhost'"); myquery(rc); @@ -20338,6 +20339,7 @@ static void test_bulk_autoinc() { DIE_IF(atoi(row[0]) != id[i++]); } + mysql_free_result(result); rc= mysql_query(mysql, "DROP TABLE ai_field_value"); myquery(rc); } @@ -20397,6 +20399,7 @@ static void test_bulk_delete() DIE_IF(atoi(row[0]) != 3); } DIE_IF(i != 1); + mysql_free_result(result); rc= mysql_query(mysql, "DROP TABLE t1"); myquery(rc); @@ -20453,6 +20456,7 @@ static void test_explain_meta() mct_close_log(); DIE("num_fields != 1"); } + mysql_free_result(rs_metadata); mysql_stmt_close(stmt); strmov(query, "EXPLAIN SELECT 1"); @@ -20469,6 +20473,7 @@ static void test_explain_meta() DIE("num_fields != 10"); } print_metadata(rs_metadata, num_fields); + mysql_free_result(rs_metadata); mysql_stmt_close(stmt); strmov(query, "EXPLAIN format=json SELECT 1"); @@ -20485,6 +20490,7 @@ static void test_explain_meta() DIE("num_fields != 1"); } print_metadata(rs_metadata, num_fields); + mysql_free_result(rs_metadata); mysql_stmt_close(stmt); @@ -20502,6 +20508,7 @@ static void test_explain_meta() DIE("num_fields != 13"); } print_metadata(rs_metadata, num_fields); + mysql_free_result(rs_metadata); mysql_stmt_close(stmt); strmov(query, "ANALYZE format=json SELECT 1"); @@ -20518,6 +20525,7 @@ static void test_explain_meta() DIE("num_fields != 1"); } print_metadata(rs_metadata, num_fields); + mysql_free_result(rs_metadata); mysql_stmt_close(stmt); rc= mysql_query(mysql, "CREATE TABLE t1 (a int)"); @@ -20537,6 +20545,7 @@ static void test_explain_meta() DIE("num_fields != 10"); } print_metadata(rs_metadata, num_fields); + mysql_free_result(rs_metadata); mysql_stmt_close(stmt); strmov(query, "EXPLAIN format=json INSERT INTO t1 values(1)"); @@ -20553,6 +20562,7 @@ static void test_explain_meta() DIE("num_fields != 1"); } print_metadata(rs_metadata, num_fields); + mysql_free_result(rs_metadata); mysql_stmt_close(stmt); @@ -20570,6 +20580,7 @@ static void test_explain_meta() DIE("num_fields != 13"); } print_metadata(rs_metadata, num_fields); + mysql_free_result(rs_metadata); mysql_stmt_close(stmt); strmov(query, "ANALYZE format=json INSERT INTO t1 values(1)"); @@ -20586,6 +20597,7 @@ static void test_explain_meta() DIE("num_fields != 1"); } print_metadata(rs_metadata, num_fields); + mysql_free_result(rs_metadata); mysql_stmt_close(stmt); @@ -20603,6 +20615,7 @@ static void test_explain_meta() DIE("num_fields != 10"); } print_metadata(rs_metadata, num_fields); + mysql_free_result(rs_metadata); mysql_stmt_close(stmt); strmov(query, "EXPLAIN format=json UPDATE t1 set a=2"); @@ -20619,6 +20632,7 @@ static void test_explain_meta() DIE("num_fields != 1"); } print_metadata(rs_metadata, num_fields); + mysql_free_result(rs_metadata); mysql_stmt_close(stmt); @@ -20636,6 +20650,7 @@ static void test_explain_meta() DIE("num_fields != 13"); } print_metadata(rs_metadata, num_fields); + mysql_free_result(rs_metadata); mysql_stmt_close(stmt); strmov(query, "ANALYZE format=json UPDATE t1 set a=2"); @@ -20652,6 +20667,7 @@ static void test_explain_meta() DIE("num_fields != 1"); } print_metadata(rs_metadata, num_fields); + mysql_free_result(rs_metadata); mysql_stmt_close(stmt); @@ -20669,6 +20685,7 @@ static void test_explain_meta() DIE("num_fields != 10"); } print_metadata(rs_metadata, num_fields); + mysql_free_result(rs_metadata); mysql_stmt_close(stmt); strmov(query, "EXPLAIN format=json DELETE FROM t1"); @@ -20685,6 +20702,7 @@ static void test_explain_meta() DIE("num_fields != 1"); } print_metadata(rs_metadata, num_fields); + mysql_free_result(rs_metadata); mysql_stmt_close(stmt); @@ -20702,6 +20720,7 @@ static void test_explain_meta() DIE("num_fields != 13"); } print_metadata(rs_metadata, num_fields); + mysql_free_result(rs_metadata); mysql_stmt_close(stmt); strmov(query, "ANALYZE format=json DELETE FROM t1"); @@ -20718,6 +20737,7 @@ static void test_explain_meta() DIE("num_fields != 1"); } print_metadata(rs_metadata, num_fields); + mysql_free_result(rs_metadata); mysql_stmt_close(stmt); rc= mysql_query(mysql, "DROP TABLE t1"); |