From ccb9f673b48ffa17103e628f34804ee1f2748b37 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Mon, 3 Aug 2020 13:23:38 +0200 Subject: [PATCH 01/26] MDEV-23348 vio_shutdown does not prevent later ReadFile on named pipe Introduce st_vio::shutdown_flag to be checked prior to Read/WriteFile and during wait for async.io to finish. --- include/violite.h | 1 + vio/vio.c | 1 + vio/viopipe.c | 17 +++++++++++++---- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/include/violite.h b/include/violite.h index 5bc6359b153..bb3fd8f6b6c 100644 --- a/include/violite.h +++ b/include/violite.h @@ -281,6 +281,7 @@ struct st_vio OVERLAPPED overlapped; DWORD read_timeout_ms; DWORD write_timeout_ms; + int shutdown_flag; #endif }; #endif /* vio_violite_h_ */ diff --git a/vio/vio.c b/vio/vio.c index 52a5387a852..694d2f7b7ff 100644 --- a/vio/vio.c +++ b/vio/vio.c @@ -68,6 +68,7 @@ int vio_shared_memory_shutdown(Vio *vio, int how) int vio_pipe_shutdown(Vio *vio, int how) { + vio->shutdown_flag= how; return CancelIoEx(vio->hPipe, NULL); } #endif diff --git a/vio/viopipe.c b/vio/viopipe.c index 5007599aa17..aeaad311b7e 100644 --- a/vio/viopipe.c +++ b/vio/viopipe.c @@ -75,6 +75,9 @@ size_t vio_read_pipe(Vio *vio, uchar *buf, size_t count) size_t ret= (size_t) -1; DBUG_ENTER("vio_read_pipe"); + if (vio->shutdown_flag) + return ret; + disable_iocp_notification(&vio->overlapped); /* Attempt to read from the pipe (overlapped I/O). */ @@ -85,8 +88,11 @@ size_t vio_read_pipe(Vio *vio, uchar *buf, size_t count) } /* Read operation is pending completion asynchronously? */ else if (GetLastError() == ERROR_IO_PENDING) + { + if (vio->shutdown_flag) + CancelIo(vio->hPipe); ret= wait_overlapped_result(vio, vio->read_timeout); - + } enable_iocp_notification(&vio->overlapped); DBUG_RETURN(ret); @@ -99,6 +105,8 @@ size_t vio_write_pipe(Vio *vio, const uchar *buf, size_t count) size_t ret= (size_t) -1; DBUG_ENTER("vio_write_pipe"); + if (vio->shutdown_flag == SHUT_RDWR) + return ret; disable_iocp_notification(&vio->overlapped); /* Attempt to write to the pipe (overlapped I/O). */ if (WriteFile(vio->hPipe, buf, (DWORD)count, &transferred, &vio->overlapped)) @@ -108,8 +116,11 @@ size_t vio_write_pipe(Vio *vio, const uchar *buf, size_t count) } /* Write operation is pending completion asynchronously? */ else if (GetLastError() == ERROR_IO_PENDING) + { + if (vio->shutdown_flag == SHUT_RDWR) + CancelIo(vio->hPipe); ret= wait_overlapped_result(vio, vio->write_timeout); - + } enable_iocp_notification(&vio->overlapped); DBUG_RETURN(ret); } @@ -129,9 +140,7 @@ int vio_close_pipe(Vio *vio) BOOL ret; DBUG_ENTER("vio_close_pipe"); - CancelIo(vio->hPipe); CloseHandle(vio->overlapped.hEvent); - DisconnectNamedPipe(vio->hPipe); ret= CloseHandle(vio->hPipe); vio->type= VIO_CLOSED; From b3e9798ff3fe4dcdda841dc72bd5d9a26db9eaa1 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Mon, 3 Aug 2020 13:35:53 +0200 Subject: [PATCH 02/26] Fix named_pipe test so it can be used with --repeat Remove the error log of the mysqld instance that was attempted to start in the test. --- mysql-test/main/named_pipe.test | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/main/named_pipe.test b/mysql-test/main/named_pipe.test index 8503907b808..2fe6f1cc5c0 100644 --- a/mysql-test/main/named_pipe.test +++ b/mysql-test/main/named_pipe.test @@ -30,3 +30,4 @@ let $MYSQLD_DATADIR= `select @@datadir`; let SEARCH_FILE=$MYSQLD_DATADIR/second-mysqld.err; let SEARCH_PATTERN=\[ERROR\] Create named pipe failed; source include/search_pattern_in_file.inc; +remove_file $SEARCH_FILE; From a8ec45863b958757da61af3b2ce0a38b0a79d92c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Mon, 3 Aug 2020 15:15:40 +0300 Subject: [PATCH 03/26] MDEV-23101: SIGSEGV in lock_rec_unlock() when Galera is enabled lock_rec_has_to_wait wsrep_kill_victim lock_rec_create_low lock_rec_add_to_queue DeadlockChecker::select_victim() THD can't change from normal transaction to BF (brute force) transaction here, thus there is no need to syncronize access in wsrep_thd_is_BF function. lock_rec_has_to_wait_in_queue Add condition that lock is not NULL and add assertions if we are in strong state. --- storage/innobase/lock/lock0lock.cc | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc index c4c045ffba3..1e7d9b031d7 100644 --- a/storage/innobase/lock/lock0lock.cc +++ b/storage/innobase/lock/lock0lock.cc @@ -754,7 +754,7 @@ lock_rec_has_to_wait( /* if BF thread is locking and has conflict with another BF thread, we need to look at trx ordering and lock types */ if (wsrep_thd_is_BF(trx->mysql_thd, FALSE) && - wsrep_thd_is_BF(lock2->trx->mysql_thd, TRUE)) { + wsrep_thd_is_BF(lock2->trx->mysql_thd, FALSE)) { mtr_t mtr; if (UNIV_UNLIKELY(wsrep_debug)) { @@ -1104,7 +1104,7 @@ wsrep_kill_victim( if (!trx->is_wsrep()) return; my_bool bf_this = wsrep_thd_is_BF(trx->mysql_thd, FALSE); - my_bool bf_other = wsrep_thd_is_BF(lock->trx->mysql_thd, TRUE); + my_bool bf_other = wsrep_thd_is_BF(lock->trx->mysql_thd, FALSE); mtr_t mtr; if ((bf_this && !bf_other) || @@ -1483,7 +1483,7 @@ lock_rec_create_low( lock_t *hash = (lock_t *)c_lock->hash; lock_t *prev = NULL; - while (hash && wsrep_thd_is_BF(hash->trx->mysql_thd, TRUE) + while (hash && wsrep_thd_is_BF(hash->trx->mysql_thd, FALSE) && wsrep_trx_order_before(hash->trx->mysql_thd, trx->mysql_thd)) { prev = hash; @@ -1877,11 +1877,9 @@ lock_rec_add_to_queue( = lock_rec_other_has_expl_req( mode, block, false, heap_no, trx); #ifdef WITH_WSREP - //ut_a(!other_lock || (wsrep_thd_is_BF(trx->mysql_thd, FALSE) && - // wsrep_thd_is_BF(other_lock->trx->mysql_thd, TRUE))); if (other_lock && trx->is_wsrep() && !wsrep_thd_is_BF(trx->mysql_thd, FALSE) && - !wsrep_thd_is_BF(other_lock->trx->mysql_thd, TRUE)) { + !wsrep_thd_is_BF(other_lock->trx->mysql_thd, FALSE)) { ib::info() << "WSREP BF lock conflict for my lock:\n BF:" << ((wsrep_thd_is_BF(trx->mysql_thd, FALSE)) ? "BF" : "normal") << " exec: " << @@ -2190,6 +2188,7 @@ lock_rec_has_to_wait_in_queue( ulint bit_offset; hash_table_t* hash; + ut_ad(wait_lock); ut_ad(lock_mutex_own()); ut_ad(lock_get_wait(wait_lock)); ut_ad(lock_get_type_low(wait_lock) == LOCK_REC); @@ -2204,9 +2203,10 @@ lock_rec_has_to_wait_in_queue( hash = lock_hash_get(wait_lock->type_mode); for (lock = lock_rec_get_first_on_page_addr(hash, space, page_no); - lock != wait_lock; + lock && lock != wait_lock; lock = lock_rec_get_next_on_page_const(lock)) { + ut_ad(lock); const byte* p = (const byte*) &lock[1]; if (heap_no < lock_rec_get_n_bits(lock) @@ -2214,7 +2214,8 @@ lock_rec_has_to_wait_in_queue( && lock_has_to_wait(wait_lock, lock)) { #ifdef WITH_WSREP if (wsrep_thd_is_BF(wait_lock->trx->mysql_thd, FALSE) && - wsrep_thd_is_BF(lock->trx->mysql_thd, TRUE)) { + wsrep_thd_is_BF(lock->trx->mysql_thd, FALSE)) { + if (UNIV_UNLIKELY(wsrep_debug)) { mtr_t mtr; ib::info() << "WSREP: waiting BF trx: " << ib::hex(wait_lock->trx->id) @@ -7038,7 +7039,7 @@ DeadlockChecker::select_victim() const /* The joining transaction is 'smaller', choose it as the victim and roll it back. */ #ifdef WITH_WSREP - if (wsrep_thd_is_BF(m_start->mysql_thd, TRUE)) { + if (wsrep_thd_is_BF(m_start->mysql_thd, FALSE)) { return(m_wait_lock->trx); } #endif /* WITH_WSREP */ @@ -7046,7 +7047,7 @@ DeadlockChecker::select_victim() const } #ifdef WITH_WSREP - if (wsrep_thd_is_BF(m_wait_lock->trx->mysql_thd, TRUE)) { + if (wsrep_thd_is_BF(m_wait_lock->trx->mysql_thd, FALSE)) { return(m_start); } #endif /* WITH_WSREP */ From 6a2ee9c8bbec437e7eb50b1a273a017cdefc6e15 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Mon, 3 Aug 2020 13:56:10 +0400 Subject: [PATCH 04/26] MDEV-23032 FLOOR()/CEIL() incorrectly calculate the precision of a DECIMAL(M,D) column The code in Item_func_int_val::fix_length_and_dec_int_or_decimal() calculated badly the result data type for FLOOR()/CEIL(), so for example the decimal(38,10) input created a decimal(28,0) result. That was not correct, because one extra integer digit is needed. floor(-9.9) -> -10 ceil(9.9) -> 10 Rewritting the code in a more straightforward way. Additional changes: - FLOOR() now takes into account the presence of the UNSIGNED flag of the argument: FLOOR(unsigned decimal) does not need an extra digits. - FLOOR()/CEILING() now preserve the unsigned flag in the result data type is decimal. These changes give nicer data types. --- mysql-test/include/ctype_numconv.inc | 4 +- mysql-test/main/ctype_binary.result | 10 +- mysql-test/main/ctype_cp1251.result | 10 +- mysql-test/main/ctype_latin1.result | 10 +- mysql-test/main/ctype_ucs.result | 10 +- mysql-test/main/ctype_utf8.result | 10 +- mysql-test/main/func_math.result | 232 ++++++++++---------- mysql-test/main/type_newdecimal.result | 289 +++++++++++++++++++++++++ mysql-test/main/type_newdecimal.test | 48 ++++ sql/item_func.cc | 65 ++++-- sql/item_func.h | 3 + 11 files changed, 535 insertions(+), 156 deletions(-) diff --git a/mysql-test/include/ctype_numconv.inc b/mysql-test/include/ctype_numconv.inc index 07298b1d47b..889c80cc477 100644 --- a/mysql-test/include/ctype_numconv.inc +++ b/mysql-test/include/ctype_numconv.inc @@ -194,12 +194,12 @@ show create table t1; drop table t1; select hex(concat(ceiling(0.5))); -create table t1 as select concat(ceiling(0.5)) as c1; +create table t1 as select ceiling(0.5) as c0, concat(ceiling(0.5)) as c1; show create table t1; drop table t1; select hex(concat(floor(0.5))); -create table t1 as select concat(floor(0.5)) as c1; +create table t1 as select floor(0.5) as c0, concat(floor(0.5)) as c1; show create table t1; drop table t1; diff --git a/mysql-test/main/ctype_binary.result b/mysql-test/main/ctype_binary.result index 931d295ec4a..97f970a9e49 100644 --- a/mysql-test/main/ctype_binary.result +++ b/mysql-test/main/ctype_binary.result @@ -348,21 +348,23 @@ drop table t1; select hex(concat(ceiling(0.5))); hex(concat(ceiling(0.5))) 31 -create table t1 as select concat(ceiling(0.5)) as c1; +create table t1 as select ceiling(0.5) as c0, concat(ceiling(0.5)) as c1; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( - `c1` varbinary(4) DEFAULT NULL + `c0` int(3) NOT NULL, + `c1` varbinary(3) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; select hex(concat(floor(0.5))); hex(concat(floor(0.5))) 30 -create table t1 as select concat(floor(0.5)) as c1; +create table t1 as select floor(0.5) as c0, concat(floor(0.5)) as c1; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( - `c1` varbinary(4) DEFAULT NULL + `c0` int(3) NOT NULL, + `c1` varbinary(3) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; select hex(concat(round(0.5))); diff --git a/mysql-test/main/ctype_cp1251.result b/mysql-test/main/ctype_cp1251.result index 03a0d413023..b0e6e1e6506 100644 --- a/mysql-test/main/ctype_cp1251.result +++ b/mysql-test/main/ctype_cp1251.result @@ -757,21 +757,23 @@ drop table t1; select hex(concat(ceiling(0.5))); hex(concat(ceiling(0.5))) 31 -create table t1 as select concat(ceiling(0.5)) as c1; +create table t1 as select ceiling(0.5) as c0, concat(ceiling(0.5)) as c1; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( - `c1` varchar(4) CHARACTER SET cp1251 DEFAULT NULL + `c0` int(3) NOT NULL, + `c1` varchar(3) CHARACTER SET cp1251 DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; select hex(concat(floor(0.5))); hex(concat(floor(0.5))) 30 -create table t1 as select concat(floor(0.5)) as c1; +create table t1 as select floor(0.5) as c0, concat(floor(0.5)) as c1; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( - `c1` varchar(4) CHARACTER SET cp1251 DEFAULT NULL + `c0` int(3) NOT NULL, + `c1` varchar(3) CHARACTER SET cp1251 DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; select hex(concat(round(0.5))); diff --git a/mysql-test/main/ctype_latin1.result b/mysql-test/main/ctype_latin1.result index a4925af69ae..b4005a4a73b 100644 --- a/mysql-test/main/ctype_latin1.result +++ b/mysql-test/main/ctype_latin1.result @@ -1066,21 +1066,23 @@ drop table t1; select hex(concat(ceiling(0.5))); hex(concat(ceiling(0.5))) 31 -create table t1 as select concat(ceiling(0.5)) as c1; +create table t1 as select ceiling(0.5) as c0, concat(ceiling(0.5)) as c1; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( - `c1` varchar(4) DEFAULT NULL + `c0` int(3) NOT NULL, + `c1` varchar(3) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; select hex(concat(floor(0.5))); hex(concat(floor(0.5))) 30 -create table t1 as select concat(floor(0.5)) as c1; +create table t1 as select floor(0.5) as c0, concat(floor(0.5)) as c1; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( - `c1` varchar(4) DEFAULT NULL + `c0` int(3) NOT NULL, + `c1` varchar(3) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; select hex(concat(round(0.5))); diff --git a/mysql-test/main/ctype_ucs.result b/mysql-test/main/ctype_ucs.result index fba779f5881..6292ad2591e 100644 --- a/mysql-test/main/ctype_ucs.result +++ b/mysql-test/main/ctype_ucs.result @@ -1950,21 +1950,23 @@ drop table t1; select hex(concat(ceiling(0.5))); hex(concat(ceiling(0.5))) 0031 -create table t1 as select concat(ceiling(0.5)) as c1; +create table t1 as select ceiling(0.5) as c0, concat(ceiling(0.5)) as c1; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( - `c1` varchar(4) CHARACTER SET ucs2 DEFAULT NULL + `c0` int(3) NOT NULL, + `c1` varchar(3) CHARACTER SET ucs2 DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; select hex(concat(floor(0.5))); hex(concat(floor(0.5))) 0030 -create table t1 as select concat(floor(0.5)) as c1; +create table t1 as select floor(0.5) as c0, concat(floor(0.5)) as c1; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( - `c1` varchar(4) CHARACTER SET ucs2 DEFAULT NULL + `c0` int(3) NOT NULL, + `c1` varchar(3) CHARACTER SET ucs2 DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; select hex(concat(round(0.5))); diff --git a/mysql-test/main/ctype_utf8.result b/mysql-test/main/ctype_utf8.result index 9585931584b..bd35fd10f19 100644 --- a/mysql-test/main/ctype_utf8.result +++ b/mysql-test/main/ctype_utf8.result @@ -2817,21 +2817,23 @@ drop table t1; select hex(concat(ceiling(0.5))); hex(concat(ceiling(0.5))) 31 -create table t1 as select concat(ceiling(0.5)) as c1; +create table t1 as select ceiling(0.5) as c0, concat(ceiling(0.5)) as c1; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( - `c1` varchar(4) CHARACTER SET utf8 DEFAULT NULL + `c0` int(3) NOT NULL, + `c1` varchar(3) CHARACTER SET utf8 DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; select hex(concat(floor(0.5))); hex(concat(floor(0.5))) 30 -create table t1 as select concat(floor(0.5)) as c1; +create table t1 as select floor(0.5) as c0, concat(floor(0.5)) as c1; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( - `c1` varchar(4) CHARACTER SET utf8 DEFAULT NULL + `c0` int(3) NOT NULL, + `c1` varchar(3) CHARACTER SET utf8 DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; select hex(concat(round(0.5))); diff --git a/mysql-test/main/func_math.result b/mysql-test/main/func_math.result index 163478f330c..a397f927265 100644 --- a/mysql-test/main/func_math.result +++ b/mysql-test/main/func_math.result @@ -1080,7 +1080,7 @@ Create Table CREATE TABLE `t2` ( `a` decimal(38,0) DEFAULT NULL, `b` decimal(38,0) unsigned DEFAULT NULL, `fa` decimal(38,0) DEFAULT NULL, - `fb` decimal(38,0) DEFAULT NULL + `fb` decimal(38,0) unsigned DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 a 99999999999999999999999999999999999999 b 99999999999999999999999999999999999999 @@ -1090,8 +1090,8 @@ Table t2 Create Table CREATE TABLE `t2` ( `a` decimal(38,1) DEFAULT NULL, `b` decimal(38,1) unsigned DEFAULT NULL, - `fa` decimal(37,0) DEFAULT NULL, - `fb` decimal(37,0) DEFAULT NULL + `fa` decimal(38,0) DEFAULT NULL, + `fb` decimal(37,0) unsigned DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 a 9999999999999999999999999999999999999.9 b 9999999999999999999999999999999999999.9 @@ -1101,8 +1101,8 @@ Table t2 Create Table CREATE TABLE `t2` ( `a` decimal(38,2) DEFAULT NULL, `b` decimal(38,2) unsigned DEFAULT NULL, - `fa` decimal(36,0) DEFAULT NULL, - `fb` decimal(36,0) DEFAULT NULL + `fa` decimal(37,0) DEFAULT NULL, + `fb` decimal(36,0) unsigned DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 a 999999999999999999999999999999999999.99 b 999999999999999999999999999999999999.99 @@ -1112,8 +1112,8 @@ Table t2 Create Table CREATE TABLE `t2` ( `a` decimal(38,3) DEFAULT NULL, `b` decimal(38,3) unsigned DEFAULT NULL, - `fa` decimal(35,0) DEFAULT NULL, - `fb` decimal(35,0) DEFAULT NULL + `fa` decimal(36,0) DEFAULT NULL, + `fb` decimal(35,0) unsigned DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 a 99999999999999999999999999999999999.999 b 99999999999999999999999999999999999.999 @@ -1123,8 +1123,8 @@ Table t2 Create Table CREATE TABLE `t2` ( `a` decimal(38,4) DEFAULT NULL, `b` decimal(38,4) unsigned DEFAULT NULL, - `fa` decimal(34,0) DEFAULT NULL, - `fb` decimal(34,0) DEFAULT NULL + `fa` decimal(35,0) DEFAULT NULL, + `fb` decimal(34,0) unsigned DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 a 9999999999999999999999999999999999.9999 b 9999999999999999999999999999999999.9999 @@ -1134,8 +1134,8 @@ Table t2 Create Table CREATE TABLE `t2` ( `a` decimal(38,5) DEFAULT NULL, `b` decimal(38,5) unsigned DEFAULT NULL, - `fa` decimal(33,0) DEFAULT NULL, - `fb` decimal(33,0) DEFAULT NULL + `fa` decimal(34,0) DEFAULT NULL, + `fb` decimal(33,0) unsigned DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 a 999999999999999999999999999999999.99999 b 999999999999999999999999999999999.99999 @@ -1145,8 +1145,8 @@ Table t2 Create Table CREATE TABLE `t2` ( `a` decimal(38,6) DEFAULT NULL, `b` decimal(38,6) unsigned DEFAULT NULL, - `fa` decimal(32,0) DEFAULT NULL, - `fb` decimal(32,0) DEFAULT NULL + `fa` decimal(33,0) DEFAULT NULL, + `fb` decimal(32,0) unsigned DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 a 99999999999999999999999999999999.999999 b 99999999999999999999999999999999.999999 @@ -1156,8 +1156,8 @@ Table t2 Create Table CREATE TABLE `t2` ( `a` decimal(38,7) DEFAULT NULL, `b` decimal(38,7) unsigned DEFAULT NULL, - `fa` decimal(31,0) DEFAULT NULL, - `fb` decimal(31,0) DEFAULT NULL + `fa` decimal(32,0) DEFAULT NULL, + `fb` decimal(31,0) unsigned DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 a 9999999999999999999999999999999.9999999 b 9999999999999999999999999999999.9999999 @@ -1167,8 +1167,8 @@ Table t2 Create Table CREATE TABLE `t2` ( `a` decimal(38,8) DEFAULT NULL, `b` decimal(38,8) unsigned DEFAULT NULL, - `fa` decimal(30,0) DEFAULT NULL, - `fb` decimal(30,0) DEFAULT NULL + `fa` decimal(31,0) DEFAULT NULL, + `fb` decimal(30,0) unsigned DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 a 999999999999999999999999999999.99999999 b 999999999999999999999999999999.99999999 @@ -1178,8 +1178,8 @@ Table t2 Create Table CREATE TABLE `t2` ( `a` decimal(38,9) DEFAULT NULL, `b` decimal(38,9) unsigned DEFAULT NULL, - `fa` decimal(29,0) DEFAULT NULL, - `fb` decimal(29,0) DEFAULT NULL + `fa` decimal(30,0) DEFAULT NULL, + `fb` decimal(29,0) unsigned DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 a 99999999999999999999999999999.999999999 b 99999999999999999999999999999.999999999 @@ -1189,8 +1189,8 @@ Table t2 Create Table CREATE TABLE `t2` ( `a` decimal(38,10) DEFAULT NULL, `b` decimal(38,10) unsigned DEFAULT NULL, - `fa` decimal(28,0) DEFAULT NULL, - `fb` decimal(28,0) DEFAULT NULL + `fa` decimal(29,0) DEFAULT NULL, + `fb` decimal(28,0) unsigned DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 a 9999999999999999999999999999.9999999999 b 9999999999999999999999999999.9999999999 @@ -1200,8 +1200,8 @@ Table t2 Create Table CREATE TABLE `t2` ( `a` decimal(38,11) DEFAULT NULL, `b` decimal(38,11) unsigned DEFAULT NULL, - `fa` decimal(27,0) DEFAULT NULL, - `fb` decimal(27,0) DEFAULT NULL + `fa` decimal(28,0) DEFAULT NULL, + `fb` decimal(27,0) unsigned DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 a 999999999999999999999999999.99999999999 b 999999999999999999999999999.99999999999 @@ -1211,8 +1211,8 @@ Table t2 Create Table CREATE TABLE `t2` ( `a` decimal(38,12) DEFAULT NULL, `b` decimal(38,12) unsigned DEFAULT NULL, - `fa` decimal(26,0) DEFAULT NULL, - `fb` decimal(26,0) DEFAULT NULL + `fa` decimal(27,0) DEFAULT NULL, + `fb` decimal(26,0) unsigned DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 a 99999999999999999999999999.999999999999 b 99999999999999999999999999.999999999999 @@ -1222,8 +1222,8 @@ Table t2 Create Table CREATE TABLE `t2` ( `a` decimal(38,13) DEFAULT NULL, `b` decimal(38,13) unsigned DEFAULT NULL, - `fa` decimal(25,0) DEFAULT NULL, - `fb` decimal(25,0) DEFAULT NULL + `fa` decimal(26,0) DEFAULT NULL, + `fb` decimal(25,0) unsigned DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 a 9999999999999999999999999.9999999999999 b 9999999999999999999999999.9999999999999 @@ -1233,8 +1233,8 @@ Table t2 Create Table CREATE TABLE `t2` ( `a` decimal(38,14) DEFAULT NULL, `b` decimal(38,14) unsigned DEFAULT NULL, - `fa` decimal(24,0) DEFAULT NULL, - `fb` decimal(24,0) DEFAULT NULL + `fa` decimal(25,0) DEFAULT NULL, + `fb` decimal(24,0) unsigned DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 a 999999999999999999999999.99999999999999 b 999999999999999999999999.99999999999999 @@ -1244,8 +1244,8 @@ Table t2 Create Table CREATE TABLE `t2` ( `a` decimal(38,15) DEFAULT NULL, `b` decimal(38,15) unsigned DEFAULT NULL, - `fa` decimal(23,0) DEFAULT NULL, - `fb` decimal(23,0) DEFAULT NULL + `fa` decimal(24,0) DEFAULT NULL, + `fb` decimal(23,0) unsigned DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 a 99999999999999999999999.999999999999999 b 99999999999999999999999.999999999999999 @@ -1255,8 +1255,8 @@ Table t2 Create Table CREATE TABLE `t2` ( `a` decimal(38,16) DEFAULT NULL, `b` decimal(38,16) unsigned DEFAULT NULL, - `fa` decimal(22,0) DEFAULT NULL, - `fb` decimal(22,0) DEFAULT NULL + `fa` decimal(23,0) DEFAULT NULL, + `fb` decimal(22,0) unsigned DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 a 9999999999999999999999.9999999999999999 b 9999999999999999999999.9999999999999999 @@ -1266,8 +1266,8 @@ Table t2 Create Table CREATE TABLE `t2` ( `a` decimal(38,17) DEFAULT NULL, `b` decimal(38,17) unsigned DEFAULT NULL, - `fa` decimal(21,0) DEFAULT NULL, - `fb` decimal(21,0) DEFAULT NULL + `fa` decimal(22,0) DEFAULT NULL, + `fb` decimal(21,0) unsigned DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 a 999999999999999999999.99999999999999999 b 999999999999999999999.99999999999999999 @@ -1277,8 +1277,8 @@ Table t2 Create Table CREATE TABLE `t2` ( `a` decimal(38,18) DEFAULT NULL, `b` decimal(38,18) unsigned DEFAULT NULL, - `fa` decimal(20,0) DEFAULT NULL, - `fb` decimal(20,0) DEFAULT NULL + `fa` decimal(21,0) DEFAULT NULL, + `fb` decimal(20,0) unsigned DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 a 99999999999999999999.999999999999999999 b 99999999999999999999.999999999999999999 @@ -1288,8 +1288,8 @@ Table t2 Create Table CREATE TABLE `t2` ( `a` decimal(38,19) DEFAULT NULL, `b` decimal(38,19) unsigned DEFAULT NULL, - `fa` decimal(19,0) DEFAULT NULL, - `fb` decimal(19,0) DEFAULT NULL + `fa` decimal(20,0) DEFAULT NULL, + `fb` decimal(19,0) unsigned DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 a 9999999999999999999.9999999999999999999 b 9999999999999999999.9999999999999999999 @@ -1299,8 +1299,8 @@ Table t2 Create Table CREATE TABLE `t2` ( `a` decimal(38,20) DEFAULT NULL, `b` decimal(38,20) unsigned DEFAULT NULL, - `fa` decimal(18,0) DEFAULT NULL, - `fb` bigint(17) unsigned DEFAULT NULL + `fa` decimal(19,0) DEFAULT NULL, + `fb` bigint(18) unsigned DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 a 999999999999999999.99999999999999999999 b 999999999999999999.99999999999999999999 @@ -1310,7 +1310,7 @@ Table t2 Create Table CREATE TABLE `t2` ( `a` decimal(38,21) DEFAULT NULL, `b` decimal(38,21) unsigned DEFAULT NULL, - `fa` bigint(17) DEFAULT NULL, + `fa` bigint(19) DEFAULT NULL, `fb` bigint(17) unsigned DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 a 99999999999999999.999999999999999999999 @@ -1321,8 +1321,8 @@ Table t2 Create Table CREATE TABLE `t2` ( `a` decimal(38,22) DEFAULT NULL, `b` decimal(38,22) unsigned DEFAULT NULL, - `fa` bigint(17) DEFAULT NULL, - `fb` bigint(17) unsigned DEFAULT NULL + `fa` bigint(18) DEFAULT NULL, + `fb` bigint(16) unsigned DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 a 9999999999999999.9999999999999999999999 b 9999999999999999.9999999999999999999999 @@ -1333,7 +1333,7 @@ Create Table CREATE TABLE `t2` ( `a` decimal(38,23) DEFAULT NULL, `b` decimal(38,23) unsigned DEFAULT NULL, `fa` bigint(17) DEFAULT NULL, - `fb` bigint(17) unsigned DEFAULT NULL + `fb` bigint(15) unsigned DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 a 999999999999999.99999999999999999999999 b 999999999999999.99999999999999999999999 @@ -1343,8 +1343,8 @@ Table t2 Create Table CREATE TABLE `t2` ( `a` decimal(38,24) DEFAULT NULL, `b` decimal(38,24) unsigned DEFAULT NULL, - `fa` bigint(17) DEFAULT NULL, - `fb` bigint(16) unsigned DEFAULT NULL + `fa` bigint(16) DEFAULT NULL, + `fb` bigint(14) unsigned DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 a 99999999999999.999999999999999999999999 b 99999999999999.999999999999999999999999 @@ -1354,8 +1354,8 @@ Table t2 Create Table CREATE TABLE `t2` ( `a` decimal(38,25) DEFAULT NULL, `b` decimal(38,25) unsigned DEFAULT NULL, - `fa` bigint(16) DEFAULT NULL, - `fb` bigint(15) unsigned DEFAULT NULL + `fa` bigint(15) DEFAULT NULL, + `fb` bigint(13) unsigned DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 a 9999999999999.9999999999999999999999999 b 9999999999999.9999999999999999999999999 @@ -1365,8 +1365,8 @@ Table t2 Create Table CREATE TABLE `t2` ( `a` decimal(38,26) DEFAULT NULL, `b` decimal(38,26) unsigned DEFAULT NULL, - `fa` bigint(15) DEFAULT NULL, - `fb` bigint(14) unsigned DEFAULT NULL + `fa` bigint(14) DEFAULT NULL, + `fb` bigint(12) unsigned DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 a 999999999999.99999999999999999999999999 b 999999999999.99999999999999999999999999 @@ -1376,8 +1376,8 @@ Table t2 Create Table CREATE TABLE `t2` ( `a` decimal(38,27) DEFAULT NULL, `b` decimal(38,27) unsigned DEFAULT NULL, - `fa` bigint(14) DEFAULT NULL, - `fb` bigint(13) unsigned DEFAULT NULL + `fa` bigint(13) DEFAULT NULL, + `fb` bigint(11) unsigned DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 a 99999999999.999999999999999999999999999 b 99999999999.999999999999999999999999999 @@ -1387,8 +1387,8 @@ Table t2 Create Table CREATE TABLE `t2` ( `a` decimal(38,28) DEFAULT NULL, `b` decimal(38,28) unsigned DEFAULT NULL, - `fa` bigint(13) DEFAULT NULL, - `fb` bigint(12) unsigned DEFAULT NULL + `fa` bigint(12) DEFAULT NULL, + `fb` bigint(10) unsigned DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 a 9999999999.9999999999999999999999999999 b 9999999999.9999999999999999999999999999 @@ -1398,8 +1398,8 @@ Table t2 Create Table CREATE TABLE `t2` ( `a` decimal(38,29) DEFAULT NULL, `b` decimal(38,29) unsigned DEFAULT NULL, - `fa` bigint(12) DEFAULT NULL, - `fb` bigint(11) unsigned DEFAULT NULL + `fa` bigint(11) DEFAULT NULL, + `fb` int(9) unsigned DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 a 999999999.99999999999999999999999999999 b 999999999.99999999999999999999999999999 @@ -1409,8 +1409,8 @@ Table t2 Create Table CREATE TABLE `t2` ( `a` decimal(38,30) DEFAULT NULL, `b` decimal(38,30) unsigned DEFAULT NULL, - `fa` bigint(11) DEFAULT NULL, - `fb` bigint(10) unsigned DEFAULT NULL + `fa` int(10) DEFAULT NULL, + `fb` int(8) unsigned DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 a 99999999.999999999999999999999999999999 b 99999999.999999999999999999999999999999 @@ -1422,7 +1422,7 @@ Create Table CREATE TABLE `t2` ( `a` decimal(30,0) DEFAULT NULL, `b` decimal(30,0) unsigned DEFAULT NULL, `fa` decimal(30,0) DEFAULT NULL, - `fb` decimal(31,0) unsigned DEFAULT NULL + `fb` decimal(30,0) unsigned DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 a 999999999999999999999999999999 b 999999999999999999999999999999 @@ -1432,8 +1432,8 @@ Table t2 Create Table CREATE TABLE `t2` ( `a` decimal(30,1) DEFAULT NULL, `b` decimal(30,1) unsigned DEFAULT NULL, - `fa` decimal(29,0) DEFAULT NULL, - `fb` decimal(30,0) unsigned DEFAULT NULL + `fa` decimal(30,0) DEFAULT NULL, + `fb` decimal(29,0) unsigned DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 a 99999999999999999999999999999.9 b 99999999999999999999999999999.9 @@ -1443,8 +1443,8 @@ Table t2 Create Table CREATE TABLE `t2` ( `a` decimal(30,2) DEFAULT NULL, `b` decimal(30,2) unsigned DEFAULT NULL, - `fa` decimal(28,0) DEFAULT NULL, - `fb` decimal(29,0) unsigned DEFAULT NULL + `fa` decimal(29,0) DEFAULT NULL, + `fb` decimal(28,0) unsigned DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 a 9999999999999999999999999999.99 b 9999999999999999999999999999.99 @@ -1454,8 +1454,8 @@ Table t2 Create Table CREATE TABLE `t2` ( `a` decimal(30,3) DEFAULT NULL, `b` decimal(30,3) unsigned DEFAULT NULL, - `fa` decimal(27,0) DEFAULT NULL, - `fb` decimal(28,0) unsigned DEFAULT NULL + `fa` decimal(28,0) DEFAULT NULL, + `fb` decimal(27,0) unsigned DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 a 999999999999999999999999999.999 b 999999999999999999999999999.999 @@ -1465,8 +1465,8 @@ Table t2 Create Table CREATE TABLE `t2` ( `a` decimal(30,4) DEFAULT NULL, `b` decimal(30,4) unsigned DEFAULT NULL, - `fa` decimal(26,0) DEFAULT NULL, - `fb` decimal(27,0) unsigned DEFAULT NULL + `fa` decimal(27,0) DEFAULT NULL, + `fb` decimal(26,0) unsigned DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 a 99999999999999999999999999.9999 b 99999999999999999999999999.9999 @@ -1476,8 +1476,8 @@ Table t2 Create Table CREATE TABLE `t2` ( `a` decimal(30,5) DEFAULT NULL, `b` decimal(30,5) unsigned DEFAULT NULL, - `fa` decimal(25,0) DEFAULT NULL, - `fb` decimal(26,0) unsigned DEFAULT NULL + `fa` decimal(26,0) DEFAULT NULL, + `fb` decimal(25,0) unsigned DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 a 9999999999999999999999999.99999 b 9999999999999999999999999.99999 @@ -1487,8 +1487,8 @@ Table t2 Create Table CREATE TABLE `t2` ( `a` decimal(30,6) DEFAULT NULL, `b` decimal(30,6) unsigned DEFAULT NULL, - `fa` decimal(24,0) DEFAULT NULL, - `fb` decimal(25,0) unsigned DEFAULT NULL + `fa` decimal(25,0) DEFAULT NULL, + `fb` decimal(24,0) unsigned DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 a 999999999999999999999999.999999 b 999999999999999999999999.999999 @@ -1498,8 +1498,8 @@ Table t2 Create Table CREATE TABLE `t2` ( `a` decimal(30,7) DEFAULT NULL, `b` decimal(30,7) unsigned DEFAULT NULL, - `fa` decimal(23,0) DEFAULT NULL, - `fb` decimal(24,0) unsigned DEFAULT NULL + `fa` decimal(24,0) DEFAULT NULL, + `fb` decimal(23,0) unsigned DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 a 99999999999999999999999.9999999 b 99999999999999999999999.9999999 @@ -1509,8 +1509,8 @@ Table t2 Create Table CREATE TABLE `t2` ( `a` decimal(30,8) DEFAULT NULL, `b` decimal(30,8) unsigned DEFAULT NULL, - `fa` decimal(22,0) DEFAULT NULL, - `fb` decimal(23,0) unsigned DEFAULT NULL + `fa` decimal(23,0) DEFAULT NULL, + `fb` decimal(22,0) unsigned DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 a 9999999999999999999999.99999999 b 9999999999999999999999.99999999 @@ -1520,8 +1520,8 @@ Table t2 Create Table CREATE TABLE `t2` ( `a` decimal(30,9) DEFAULT NULL, `b` decimal(30,9) unsigned DEFAULT NULL, - `fa` decimal(21,0) DEFAULT NULL, - `fb` decimal(22,0) unsigned DEFAULT NULL + `fa` decimal(22,0) DEFAULT NULL, + `fb` decimal(21,0) unsigned DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 a 999999999999999999999.999999999 b 999999999999999999999.999999999 @@ -1531,8 +1531,8 @@ Table t2 Create Table CREATE TABLE `t2` ( `a` decimal(30,10) DEFAULT NULL, `b` decimal(30,10) unsigned DEFAULT NULL, - `fa` decimal(20,0) DEFAULT NULL, - `fb` decimal(21,0) unsigned DEFAULT NULL + `fa` decimal(21,0) DEFAULT NULL, + `fb` decimal(20,0) unsigned DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 a 99999999999999999999.9999999999 b 99999999999999999999.9999999999 @@ -1542,8 +1542,8 @@ Table t2 Create Table CREATE TABLE `t2` ( `a` decimal(30,11) DEFAULT NULL, `b` decimal(30,11) unsigned DEFAULT NULL, - `fa` decimal(19,0) DEFAULT NULL, - `fb` decimal(20,0) unsigned DEFAULT NULL + `fa` decimal(20,0) DEFAULT NULL, + `fb` decimal(19,0) unsigned DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 a 9999999999999999999.99999999999 b 9999999999999999999.99999999999 @@ -1553,8 +1553,8 @@ Table t2 Create Table CREATE TABLE `t2` ( `a` decimal(30,12) DEFAULT NULL, `b` decimal(30,12) unsigned DEFAULT NULL, - `fa` decimal(18,0) DEFAULT NULL, - `fb` bigint(17) unsigned DEFAULT NULL + `fa` decimal(19,0) DEFAULT NULL, + `fb` bigint(18) unsigned DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 a 999999999999999999.999999999999 b 999999999999999999.999999999999 @@ -1564,7 +1564,7 @@ Table t2 Create Table CREATE TABLE `t2` ( `a` decimal(30,13) DEFAULT NULL, `b` decimal(30,13) unsigned DEFAULT NULL, - `fa` bigint(17) DEFAULT NULL, + `fa` bigint(19) DEFAULT NULL, `fb` bigint(17) unsigned DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 a 99999999999999999.9999999999999 @@ -1575,8 +1575,8 @@ Table t2 Create Table CREATE TABLE `t2` ( `a` decimal(30,14) DEFAULT NULL, `b` decimal(30,14) unsigned DEFAULT NULL, - `fa` bigint(17) DEFAULT NULL, - `fb` bigint(17) unsigned DEFAULT NULL + `fa` bigint(18) DEFAULT NULL, + `fb` bigint(16) unsigned DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 a 9999999999999999.99999999999999 b 9999999999999999.99999999999999 @@ -1587,7 +1587,7 @@ Create Table CREATE TABLE `t2` ( `a` decimal(30,15) DEFAULT NULL, `b` decimal(30,15) unsigned DEFAULT NULL, `fa` bigint(17) DEFAULT NULL, - `fb` bigint(17) unsigned DEFAULT NULL + `fb` bigint(15) unsigned DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 a 999999999999999.999999999999999 b 999999999999999.999999999999999 @@ -1597,8 +1597,8 @@ Table t2 Create Table CREATE TABLE `t2` ( `a` decimal(30,16) DEFAULT NULL, `b` decimal(30,16) unsigned DEFAULT NULL, - `fa` bigint(17) DEFAULT NULL, - `fb` bigint(16) unsigned DEFAULT NULL + `fa` bigint(16) DEFAULT NULL, + `fb` bigint(14) unsigned DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 a 99999999999999.9999999999999999 b 99999999999999.9999999999999999 @@ -1608,8 +1608,8 @@ Table t2 Create Table CREATE TABLE `t2` ( `a` decimal(30,17) DEFAULT NULL, `b` decimal(30,17) unsigned DEFAULT NULL, - `fa` bigint(16) DEFAULT NULL, - `fb` bigint(15) unsigned DEFAULT NULL + `fa` bigint(15) DEFAULT NULL, + `fb` bigint(13) unsigned DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 a 9999999999999.99999999999999999 b 9999999999999.99999999999999999 @@ -1619,8 +1619,8 @@ Table t2 Create Table CREATE TABLE `t2` ( `a` decimal(30,18) DEFAULT NULL, `b` decimal(30,18) unsigned DEFAULT NULL, - `fa` bigint(15) DEFAULT NULL, - `fb` bigint(14) unsigned DEFAULT NULL + `fa` bigint(14) DEFAULT NULL, + `fb` bigint(12) unsigned DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 a 999999999999.999999999999999999 b 999999999999.999999999999999999 @@ -1630,8 +1630,8 @@ Table t2 Create Table CREATE TABLE `t2` ( `a` decimal(30,19) DEFAULT NULL, `b` decimal(30,19) unsigned DEFAULT NULL, - `fa` bigint(14) DEFAULT NULL, - `fb` bigint(13) unsigned DEFAULT NULL + `fa` bigint(13) DEFAULT NULL, + `fb` bigint(11) unsigned DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 a 99999999999.9999999999999999999 b 99999999999.9999999999999999999 @@ -1641,8 +1641,8 @@ Table t2 Create Table CREATE TABLE `t2` ( `a` decimal(30,20) DEFAULT NULL, `b` decimal(30,20) unsigned DEFAULT NULL, - `fa` bigint(13) DEFAULT NULL, - `fb` bigint(12) unsigned DEFAULT NULL + `fa` bigint(12) DEFAULT NULL, + `fb` bigint(10) unsigned DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 a 9999999999.99999999999999999999 b 9999999999.99999999999999999999 @@ -1652,8 +1652,8 @@ Table t2 Create Table CREATE TABLE `t2` ( `a` decimal(30,21) DEFAULT NULL, `b` decimal(30,21) unsigned DEFAULT NULL, - `fa` bigint(12) DEFAULT NULL, - `fb` bigint(11) unsigned DEFAULT NULL + `fa` bigint(11) DEFAULT NULL, + `fb` int(9) unsigned DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 a 999999999.999999999999999999999 b 999999999.999999999999999999999 @@ -1663,8 +1663,8 @@ Table t2 Create Table CREATE TABLE `t2` ( `a` decimal(30,22) DEFAULT NULL, `b` decimal(30,22) unsigned DEFAULT NULL, - `fa` bigint(11) DEFAULT NULL, - `fb` bigint(10) unsigned DEFAULT NULL + `fa` int(10) DEFAULT NULL, + `fb` int(8) unsigned DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 a 99999999.9999999999999999999999 b 99999999.9999999999999999999999 @@ -1674,8 +1674,8 @@ Table t2 Create Table CREATE TABLE `t2` ( `a` decimal(30,23) DEFAULT NULL, `b` decimal(30,23) unsigned DEFAULT NULL, - `fa` bigint(10) DEFAULT NULL, - `fb` int(9) unsigned DEFAULT NULL + `fa` int(9) DEFAULT NULL, + `fb` int(7) unsigned DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 a 9999999.99999999999999999999999 b 9999999.99999999999999999999999 @@ -1685,8 +1685,8 @@ Table t2 Create Table CREATE TABLE `t2` ( `a` decimal(30,24) DEFAULT NULL, `b` decimal(30,24) unsigned DEFAULT NULL, - `fa` int(9) DEFAULT NULL, - `fb` int(8) unsigned DEFAULT NULL + `fa` int(8) DEFAULT NULL, + `fb` int(6) unsigned DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 a 999999.999999999999999999999999 b 999999.999999999999999999999999 @@ -1696,8 +1696,8 @@ Table t2 Create Table CREATE TABLE `t2` ( `a` decimal(30,25) DEFAULT NULL, `b` decimal(30,25) unsigned DEFAULT NULL, - `fa` int(8) DEFAULT NULL, - `fb` int(7) unsigned DEFAULT NULL + `fa` int(7) DEFAULT NULL, + `fb` int(5) unsigned DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 a 99999.9999999999999999999999999 b 99999.9999999999999999999999999 @@ -1707,8 +1707,8 @@ Table t2 Create Table CREATE TABLE `t2` ( `a` decimal(30,26) DEFAULT NULL, `b` decimal(30,26) unsigned DEFAULT NULL, - `fa` int(7) DEFAULT NULL, - `fb` int(6) unsigned DEFAULT NULL + `fa` int(6) DEFAULT NULL, + `fb` int(4) unsigned DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 a 9999.99999999999999999999999999 b 9999.99999999999999999999999999 @@ -1718,8 +1718,8 @@ Table t2 Create Table CREATE TABLE `t2` ( `a` decimal(30,27) DEFAULT NULL, `b` decimal(30,27) unsigned DEFAULT NULL, - `fa` int(6) DEFAULT NULL, - `fb` int(5) unsigned DEFAULT NULL + `fa` int(5) DEFAULT NULL, + `fb` int(3) unsigned DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 a 999.999999999999999999999999999 b 999.999999999999999999999999999 @@ -1729,8 +1729,8 @@ Table t2 Create Table CREATE TABLE `t2` ( `a` decimal(30,28) DEFAULT NULL, `b` decimal(30,28) unsigned DEFAULT NULL, - `fa` int(5) DEFAULT NULL, - `fb` int(4) unsigned DEFAULT NULL + `fa` int(4) DEFAULT NULL, + `fb` int(2) unsigned DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 a 99.9999999999999999999999999999 b 99.9999999999999999999999999999 @@ -1740,8 +1740,8 @@ Table t2 Create Table CREATE TABLE `t2` ( `a` decimal(30,29) DEFAULT NULL, `b` decimal(30,29) unsigned DEFAULT NULL, - `fa` int(4) DEFAULT NULL, - `fb` int(3) unsigned DEFAULT NULL + `fa` int(3) DEFAULT NULL, + `fb` int(1) unsigned DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 a 9.99999999999999999999999999999 b 9.99999999999999999999999999999 diff --git a/mysql-test/main/type_newdecimal.result b/mysql-test/main/type_newdecimal.result index d5fc6db107b..0a631521d49 100644 --- a/mysql-test/main/type_newdecimal.result +++ b/mysql-test/main/type_newdecimal.result @@ -2411,3 +2411,292 @@ drop table t1; # # End of 10.2 tests # +# +# Start of 10.4 tests +# +# +# MDEV-23032 FLOOR()/CEIL() incorrectly calculate the precision of a DECIMAL(M,D) column. +# +CREATE PROCEDURE p1(prec INT, scale INT, suffix VARCHAR(32)) +BEGIN +EXECUTE IMMEDIATE CONCAT('CREATE TABLE t1 (a decimal(',prec,',',scale,')',suffix,')'); +INSERT IGNORE INTO t1 VALUES (-1e100), (+1e100); +CREATE TABLE t2 AS SELECT +a, +FLOOR(a) AS fa, +CEILING(a) AS ca, +LENGTH(FLOOR(a)), +LENGTH(CEILING(a)) +FROM t1 ORDER BY a; +SHOW CREATE TABLE t2; +SELECT * FROM t2; +DROP TABLE t2, t1; +END; +$$ +CALL p1(38,10,''); +Table t2 +Create Table CREATE TABLE `t2` ( + `a` decimal(38,10) DEFAULT NULL, + `fa` decimal(29,0) DEFAULT NULL, + `ca` decimal(29,0) DEFAULT NULL, + `LENGTH(FLOOR(a))` int(10) DEFAULT NULL, + `LENGTH(CEILING(a))` int(10) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +a -9999999999999999999999999999.9999999999 +fa -10000000000000000000000000000 +ca -9999999999999999999999999999 +LENGTH(FLOOR(a)) 30 +LENGTH(CEILING(a)) 29 +a 9999999999999999999999999999.9999999999 +fa 9999999999999999999999999999 +ca 10000000000000000000000000000 +LENGTH(FLOOR(a)) 28 +LENGTH(CEILING(a)) 29 +CALL p1(28,10,''); +Table t2 +Create Table CREATE TABLE `t2` ( + `a` decimal(28,10) DEFAULT NULL, + `fa` decimal(19,0) DEFAULT NULL, + `ca` decimal(19,0) DEFAULT NULL, + `LENGTH(FLOOR(a))` int(10) DEFAULT NULL, + `LENGTH(CEILING(a))` int(10) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +a -999999999999999999.9999999999 +fa -1000000000000000000 +ca -999999999999999999 +LENGTH(FLOOR(a)) 20 +LENGTH(CEILING(a)) 19 +a 999999999999999999.9999999999 +fa 999999999999999999 +ca 1000000000000000000 +LENGTH(FLOOR(a)) 18 +LENGTH(CEILING(a)) 19 +CALL p1(27,10,''); +Table t2 +Create Table CREATE TABLE `t2` ( + `a` decimal(27,10) DEFAULT NULL, + `fa` bigint(19) DEFAULT NULL, + `ca` bigint(19) DEFAULT NULL, + `LENGTH(FLOOR(a))` int(10) DEFAULT NULL, + `LENGTH(CEILING(a))` int(10) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +a -99999999999999999.9999999999 +fa -100000000000000000 +ca -99999999999999999 +LENGTH(FLOOR(a)) 19 +LENGTH(CEILING(a)) 18 +a 99999999999999999.9999999999 +fa 99999999999999999 +ca 100000000000000000 +LENGTH(FLOOR(a)) 17 +LENGTH(CEILING(a)) 18 +CALL p1(20,10,''); +Table t2 +Create Table CREATE TABLE `t2` ( + `a` decimal(20,10) DEFAULT NULL, + `fa` bigint(12) DEFAULT NULL, + `ca` bigint(12) DEFAULT NULL, + `LENGTH(FLOOR(a))` int(10) DEFAULT NULL, + `LENGTH(CEILING(a))` int(10) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +a -9999999999.9999999999 +fa -10000000000 +ca -9999999999 +LENGTH(FLOOR(a)) 12 +LENGTH(CEILING(a)) 11 +a 9999999999.9999999999 +fa 9999999999 +ca 10000000000 +LENGTH(FLOOR(a)) 10 +LENGTH(CEILING(a)) 11 +CALL p1(19,10,''); +Table t2 +Create Table CREATE TABLE `t2` ( + `a` decimal(19,10) DEFAULT NULL, + `fa` bigint(11) DEFAULT NULL, + `ca` bigint(11) DEFAULT NULL, + `LENGTH(FLOOR(a))` int(10) DEFAULT NULL, + `LENGTH(CEILING(a))` int(10) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +a -999999999.9999999999 +fa -1000000000 +ca -999999999 +LENGTH(FLOOR(a)) 11 +LENGTH(CEILING(a)) 10 +a 999999999.9999999999 +fa 999999999 +ca 1000000000 +LENGTH(FLOOR(a)) 9 +LENGTH(CEILING(a)) 10 +CALL p1(18,10,''); +Table t2 +Create Table CREATE TABLE `t2` ( + `a` decimal(18,10) DEFAULT NULL, + `fa` int(10) DEFAULT NULL, + `ca` int(10) DEFAULT NULL, + `LENGTH(FLOOR(a))` int(10) DEFAULT NULL, + `LENGTH(CEILING(a))` int(10) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +a -99999999.9999999999 +fa -100000000 +ca -99999999 +LENGTH(FLOOR(a)) 10 +LENGTH(CEILING(a)) 9 +a 99999999.9999999999 +fa 99999999 +ca 100000000 +LENGTH(FLOOR(a)) 8 +LENGTH(CEILING(a)) 9 +CALL p1(10,10,''); +Table t2 +Create Table CREATE TABLE `t2` ( + `a` decimal(10,10) DEFAULT NULL, + `fa` int(2) DEFAULT NULL, + `ca` int(2) DEFAULT NULL, + `LENGTH(FLOOR(a))` int(10) DEFAULT NULL, + `LENGTH(CEILING(a))` int(10) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +a -0.9999999999 +fa -1 +ca 0 +LENGTH(FLOOR(a)) 2 +LENGTH(CEILING(a)) 1 +a 0.9999999999 +fa 0 +ca 1 +LENGTH(FLOOR(a)) 1 +LENGTH(CEILING(a)) 1 +CALL p1(38,10,' UNSIGNED'); +Table t2 +Create Table CREATE TABLE `t2` ( + `a` decimal(38,10) unsigned DEFAULT NULL, + `fa` decimal(28,0) unsigned DEFAULT NULL, + `ca` decimal(29,0) unsigned DEFAULT NULL, + `LENGTH(FLOOR(a))` int(10) DEFAULT NULL, + `LENGTH(CEILING(a))` int(10) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +a 0.0000000000 +fa 0 +ca 0 +LENGTH(FLOOR(a)) 1 +LENGTH(CEILING(a)) 1 +a 9999999999999999999999999999.9999999999 +fa 9999999999999999999999999999 +ca 10000000000000000000000000000 +LENGTH(FLOOR(a)) 28 +LENGTH(CEILING(a)) 29 +CALL p1(28,10,' UNSIGNED'); +Table t2 +Create Table CREATE TABLE `t2` ( + `a` decimal(28,10) unsigned DEFAULT NULL, + `fa` bigint(18) unsigned DEFAULT NULL, + `ca` decimal(19,0) unsigned DEFAULT NULL, + `LENGTH(FLOOR(a))` int(10) DEFAULT NULL, + `LENGTH(CEILING(a))` int(10) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +a 0.0000000000 +fa 0 +ca 0 +LENGTH(FLOOR(a)) 1 +LENGTH(CEILING(a)) 1 +a 999999999999999999.9999999999 +fa 999999999999999999 +ca 1000000000000000000 +LENGTH(FLOOR(a)) 18 +LENGTH(CEILING(a)) 19 +CALL p1(27,10,' UNSIGNED'); +Table t2 +Create Table CREATE TABLE `t2` ( + `a` decimal(27,10) unsigned DEFAULT NULL, + `fa` bigint(17) unsigned DEFAULT NULL, + `ca` bigint(18) unsigned DEFAULT NULL, + `LENGTH(FLOOR(a))` int(10) DEFAULT NULL, + `LENGTH(CEILING(a))` int(10) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +a 0.0000000000 +fa 0 +ca 0 +LENGTH(FLOOR(a)) 1 +LENGTH(CEILING(a)) 1 +a 99999999999999999.9999999999 +fa 99999999999999999 +ca 100000000000000000 +LENGTH(FLOOR(a)) 17 +LENGTH(CEILING(a)) 18 +CALL p1(20,10,' UNSIGNED'); +Table t2 +Create Table CREATE TABLE `t2` ( + `a` decimal(20,10) unsigned DEFAULT NULL, + `fa` bigint(10) unsigned DEFAULT NULL, + `ca` bigint(11) unsigned DEFAULT NULL, + `LENGTH(FLOOR(a))` int(10) DEFAULT NULL, + `LENGTH(CEILING(a))` int(10) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +a 0.0000000000 +fa 0 +ca 0 +LENGTH(FLOOR(a)) 1 +LENGTH(CEILING(a)) 1 +a 9999999999.9999999999 +fa 9999999999 +ca 10000000000 +LENGTH(FLOOR(a)) 10 +LENGTH(CEILING(a)) 11 +CALL p1(19,10,' UNSIGNED'); +Table t2 +Create Table CREATE TABLE `t2` ( + `a` decimal(19,10) unsigned DEFAULT NULL, + `fa` int(9) unsigned DEFAULT NULL, + `ca` bigint(10) unsigned DEFAULT NULL, + `LENGTH(FLOOR(a))` int(10) DEFAULT NULL, + `LENGTH(CEILING(a))` int(10) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +a 0.0000000000 +fa 0 +ca 0 +LENGTH(FLOOR(a)) 1 +LENGTH(CEILING(a)) 1 +a 999999999.9999999999 +fa 999999999 +ca 1000000000 +LENGTH(FLOOR(a)) 9 +LENGTH(CEILING(a)) 10 +CALL p1(18,10,' UNSIGNED'); +Table t2 +Create Table CREATE TABLE `t2` ( + `a` decimal(18,10) unsigned DEFAULT NULL, + `fa` int(8) unsigned DEFAULT NULL, + `ca` int(9) unsigned DEFAULT NULL, + `LENGTH(FLOOR(a))` int(10) DEFAULT NULL, + `LENGTH(CEILING(a))` int(10) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +a 0.0000000000 +fa 0 +ca 0 +LENGTH(FLOOR(a)) 1 +LENGTH(CEILING(a)) 1 +a 99999999.9999999999 +fa 99999999 +ca 100000000 +LENGTH(FLOOR(a)) 8 +LENGTH(CEILING(a)) 9 +CALL p1(10,10,' UNSIGNED'); +Table t2 +Create Table CREATE TABLE `t2` ( + `a` decimal(10,10) unsigned DEFAULT NULL, + `fa` int(1) unsigned DEFAULT NULL, + `ca` int(1) unsigned DEFAULT NULL, + `LENGTH(FLOOR(a))` int(10) DEFAULT NULL, + `LENGTH(CEILING(a))` int(10) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +a 0.0000000000 +fa 0 +ca 0 +LENGTH(FLOOR(a)) 1 +LENGTH(CEILING(a)) 1 +a 0.9999999999 +fa 0 +ca 1 +LENGTH(FLOOR(a)) 1 +LENGTH(CEILING(a)) 1 +DROP PROCEDURE p1; diff --git a/mysql-test/main/type_newdecimal.test b/mysql-test/main/type_newdecimal.test index 2f3409f56e9..7cf0a486268 100644 --- a/mysql-test/main/type_newdecimal.test +++ b/mysql-test/main/type_newdecimal.test @@ -1871,3 +1871,51 @@ drop table t1; --echo # --echo # End of 10.2 tests --echo # + +--echo # +--echo # Start of 10.4 tests +--echo # + +--echo # +--echo # MDEV-23032 FLOOR()/CEIL() incorrectly calculate the precision of a DECIMAL(M,D) column. +--echo # + +DELIMITER $$; +CREATE PROCEDURE p1(prec INT, scale INT, suffix VARCHAR(32)) +BEGIN + EXECUTE IMMEDIATE CONCAT('CREATE TABLE t1 (a decimal(',prec,',',scale,')',suffix,')'); + INSERT IGNORE INTO t1 VALUES (-1e100), (+1e100); + CREATE TABLE t2 AS SELECT + a, + FLOOR(a) AS fa, + CEILING(a) AS ca, + LENGTH(FLOOR(a)), + LENGTH(CEILING(a)) + FROM t1 ORDER BY a; + SHOW CREATE TABLE t2; + SELECT * FROM t2; + DROP TABLE t2, t1; +END; +$$ +DELIMITER ;$$ + +--vertical_results +CALL p1(38,10,''); +CALL p1(28,10,''); +CALL p1(27,10,''); +CALL p1(20,10,''); +CALL p1(19,10,''); +CALL p1(18,10,''); +CALL p1(10,10,''); + +CALL p1(38,10,' UNSIGNED'); +CALL p1(28,10,' UNSIGNED'); +CALL p1(27,10,' UNSIGNED'); +CALL p1(20,10,' UNSIGNED'); +CALL p1(19,10,' UNSIGNED'); +CALL p1(18,10,' UNSIGNED'); +CALL p1(10,10,' UNSIGNED'); + +--horizontal_results + +DROP PROCEDURE p1; diff --git a/sql/item_func.cc b/sql/item_func.cc index 8000d7f6a1d..e4f9e8f164a 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -2173,35 +2173,64 @@ longlong Item_func_bit_neg::val_int() void Item_func_int_val::fix_length_and_dec_int_or_decimal() { + DBUG_ASSERT(args[0]->cmp_type() == DECIMAL_RESULT); + DBUG_ASSERT(args[0]->max_length <= DECIMAL_MAX_STR_LENGTH); /* - The INT branch of this code should be revised. - It creates too large data types, e.g. - CREATE OR REPLACE TABLE t2 AS SELECT FLOOR(9999999.999) AS fa; - results in a BININT(10) column, while INT(7) should probably be enough. + FLOOR() for negative numbers can increase length: floor(-9.9) -> -10 + CEILING() for positive numbers can increase length: ceil(9.9) -> 10 */ - ulonglong tmp_max_length= (ulonglong ) args[0]->max_length - - (args[0]->decimals ? args[0]->decimals + 1 : 0) + 2; - max_length= tmp_max_length > (ulonglong) UINT_MAX32 ? - (uint32) UINT_MAX32 : (uint32) tmp_max_length; - uint tmp= float_length(decimals); - set_if_smaller(max_length,tmp); - decimals= 0; + decimal_round_mode mode= round_mode(); + uint length_increase= args[0]->decimals > 0 && + (mode == CEILING || + (mode == FLOOR && !args[0]->unsigned_flag)) ? 1 : 0; + uint precision= args[0]->decimal_int_part() + length_increase; + set_if_bigger(precision, 1); /* - -2 because in most high position can't be used any digit for longlong - and one position for increasing value during operation + The BIGINT data type can store: + UNSIGNED BIGINT: 0..18446744073709551615 - up to 19 digits + SIGNED BIGINT: -9223372036854775808..9223372036854775807 - up to 18 digits + + The INT data type can store: + UNSIGNED INT: 0..4294967295 - up to 9 digits + SIGNED INT: -2147483648..2147483647 - up to 9 digits */ - if (args[0]->max_length - args[0]->decimals >= DECIMAL_LONGLONG_DIGITS - 2) + if (precision > 18) { + unsigned_flag= args[0]->unsigned_flag; fix_char_length( - my_decimal_precision_to_length_no_truncation( - args[0]->decimal_int_part(), 0, false)); + my_decimal_precision_to_length_no_truncation(precision, 0, + unsigned_flag)); set_handler(&type_handler_newdecimal); } else { - unsigned_flag= args[0]->unsigned_flag; - set_handler(type_handler_long_or_longlong()); + uint sign_length= (unsigned_flag= args[0]->unsigned_flag) ? 0 : 1; + fix_char_length(precision + sign_length); + if (precision > 9) + { +#if MYSQL_VERSION_ID > 100500 +#error Remove the '#else' branch and the conditional compilation + if (unsigned_flag) + set_handler(&type_handler_ulonglong); + else + set_handler(&type_handler_slonglong); +#else + set_handler(&type_handler_longlong); +#endif + } + else + { +#if MYSQL_VERSION_ID > 100500 +#error Remove the '#else' branch and the conditional compilation + if (unsigned_flag) + set_handler(&type_handler_ulong); + else + set_handler(&type_handler_slong); +#else + set_handler(&type_handler_long); +#endif + } } } diff --git a/sql/item_func.h b/sql/item_func.h index 24601983f86..d1292c3e07a 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -1695,6 +1695,7 @@ public: Item_func_int_val(THD *thd, Item *a): Item_func_hybrid_field_type(thd, a) {} bool check_partition_func_processor(void *int_arg) { return FALSE; } bool check_vcol_func_processor(void *arg) { return FALSE; } + virtual decimal_round_mode round_mode() const= 0; void fix_length_and_dec_double(); void fix_length_and_dec_int_or_decimal(); void fix_length_and_dec_time() @@ -1723,6 +1724,7 @@ class Item_func_ceiling :public Item_func_int_val public: Item_func_ceiling(THD *thd, Item *a): Item_func_int_val(thd, a) {} const char *func_name() const { return "ceiling"; } + decimal_round_mode round_mode() const { return CEILING; } longlong int_op(); double real_op(); my_decimal *decimal_op(my_decimal *); @@ -1738,6 +1740,7 @@ class Item_func_floor :public Item_func_int_val public: Item_func_floor(THD *thd, Item *a): Item_func_int_val(thd, a) {} const char *func_name() const { return "floor"; } + decimal_round_mode round_mode() const { return FLOOR; } longlong int_op(); double real_op(); my_decimal *decimal_op(my_decimal *); From 100f0c965cbbcf5a0f665bd233fdfab33544c774 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Tue, 4 Aug 2020 08:31:03 +0400 Subject: [PATCH 05/26] MDEV-23388 Assertion `args[0]->decimals == 0' failed in Item_func_round::fix_arg_int Type_handler_temporal_result::Item_func_min_max_fix_attributes() in an expression GREATEST(string,date), e.g: SELECT GREATEST('1', CAST('2020-12-12' AS DATE)); incorrectly evaluated decimals as 6 (like for DATETIME). Adding a separate virtual implementation: Type_handler_date_common::Item_func_min_max_fix_attributes() This makes the code simpler. --- mysql-test/main/type_date.result | 30 ++++++++++++++++++++++++++++++ mysql-test/main/type_date.test | 22 ++++++++++++++++++++++ sql/sql_type.cc | 29 +++++++++++++++++++++++++---- sql/sql_type.h | 2 ++ 4 files changed, 79 insertions(+), 4 deletions(-) diff --git a/mysql-test/main/type_date.result b/mysql-test/main/type_date.result index f40a27e5f5c..1724b7ae605 100644 --- a/mysql-test/main/type_date.result +++ b/mysql-test/main/type_date.result @@ -1103,5 +1103,35 @@ t2 CREATE TABLE `t2` ( ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t2,t1; # +# MDEV-23388 Assertion `args[0]->decimals == 0' failed in Item_func_round::fix_arg_int +# +SELECT ROUND(GREATEST('1', CAST('2020-12-12' AS DATE))); +ROUND(GREATEST('1', CAST('2020-12-12' AS DATE))) +20201212 +Warnings: +Warning 1292 Truncated incorrect datetime value: '1' +SELECT GREATEST('1', CAST('2020-12-12' AS DATE)); +Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr +def GREATEST('1', CAST('2020-12-12' AS DATE)) 10 10 10 Y 128 0 63 +GREATEST('1', CAST('2020-12-12' AS DATE)) +2020-12-12 +Warnings: +Warning 1292 Truncated incorrect datetime value: '1' +CREATE TABLE t1 (c_date DATE NOT NULL, c_int INT NOT NULL); +CREATE TABLE t2 AS SELECT +GREATEST(c_date,c_date), +GREATEST(c_date,c_int), +GREATEST(c_int,c_date) +FROM t1; +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `GREATEST(c_date,c_date)` date NOT NULL, + `GREATEST(c_date,c_int)` date DEFAULT NULL, + `GREATEST(c_int,c_date)` date DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TABLE t2; +DROP TABLE t1; +# # End of 10.4 tests # diff --git a/mysql-test/main/type_date.test b/mysql-test/main/type_date.test index 33598846504..a29f78a679b 100644 --- a/mysql-test/main/type_date.test +++ b/mysql-test/main/type_date.test @@ -749,6 +749,28 @@ CREATE TABLE t2 AS SELECT FLOOR(a), CEIL(a),ROUND(a),TRUNCATE(a,0) FROM t1; SHOW CREATE TABLE t2; DROP TABLE t2,t1; +--echo # +--echo # MDEV-23388 Assertion `args[0]->decimals == 0' failed in Item_func_round::fix_arg_int +--echo # + +SELECT ROUND(GREATEST('1', CAST('2020-12-12' AS DATE))); + +--disable_ps_protocol +--enable_metadata +SELECT GREATEST('1', CAST('2020-12-12' AS DATE)); +--disable_metadata +--enable_ps_protocol + +CREATE TABLE t1 (c_date DATE NOT NULL, c_int INT NOT NULL); +CREATE TABLE t2 AS SELECT + GREATEST(c_date,c_date), + GREATEST(c_date,c_int), + GREATEST(c_int,c_date) +FROM t1; +SHOW CREATE TABLE t2; +DROP TABLE t2; +DROP TABLE t1; + --echo # --echo # End of 10.4 tests --echo # diff --git a/sql/sql_type.cc b/sql/sql_type.cc index 0b333d44b77..eb284302613 100644 --- a/sql/sql_type.cc +++ b/sql/sql_type.cc @@ -4120,6 +4120,7 @@ bool Type_handler_temporal_result:: Item_func_min_max_fix_attributes(THD *thd, Item_func_min_max *func, Item **items, uint nitems) const { + DBUG_ASSERT(func->field_type() != MYSQL_TYPE_DATE); bool rc= Type_handler::Item_func_min_max_fix_attributes(thd, func, items, nitems); bool is_time= func->field_type() == MYSQL_TYPE_TIME; @@ -4174,7 +4175,6 @@ bool Type_handler_temporal_result:: DATETIME DATETIME no conversion DATETIME TIMESTAMP safe conversion DATETIME DATE safe conversion - DATE DATE no conversion TIME TIME no conversion Note, a function cannot return TIMESTAMP if it has non-TIMESTAMP @@ -4191,9 +4191,6 @@ bool Type_handler_temporal_result:: -------------------- ------------- ------- TIMESTAMP TIME Not possible DATETIME TIME depends on OLD_MODE_ZERO_DATE_TIME_CAST - DATE TIMESTAMP Not possible - DATE DATETIME Not possible - DATE TIME Not possible TIME TIMESTAMP Not possible TIME DATETIME Not possible TIME DATE Not possible @@ -4216,6 +4213,30 @@ bool Type_handler_temporal_result:: } +bool Type_handler_date_common:: + Item_func_min_max_fix_attributes(THD *thd, Item_func_min_max *func, + Item **items, uint nitems) const +{ + func->fix_attributes_date(); + if (func->maybe_null) + return false; + /* + We cannot trust the generic maybe_null value calculated during fix_fields(). + If a conversion from non-temoral types to DATE happens, + then the result can be NULL (even if all arguments are not NULL). + */ + for (uint i= 0; i < nitems; i++) + { + if (items[i]->type_handler()->cmp_type() != TIME_RESULT) + { + func->maybe_null= true; + break; + } + } + return false; +} + + bool Type_handler_real_result:: Item_func_min_max_fix_attributes(THD *thd, Item_func_min_max *func, Item **items, uint nitems) const diff --git a/sql/sql_type.h b/sql/sql_type.h index badd8d2f7f5..30618df82ab 100644 --- a/sql/sql_type.h +++ b/sql/sql_type.h @@ -5508,6 +5508,8 @@ public: Type_handler_hybrid_field_type *, Type_all_attributes *atrr, Item **items, uint nitems) const; + bool Item_func_min_max_fix_attributes(THD *thd, Item_func_min_max *func, + Item **items, uint nitems) const; void Item_param_set_param_func(Item_param *param, uchar **pos, ulong len) const; }; From 87b1625b5ccb3e0e7f15a32e15892227463c7796 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Tue, 4 Aug 2020 07:53:13 +0300 Subject: [PATCH 06/26] Test case MW-328A still fails, thus disable it until it is really fixed. --- mysql-test/suite/galera/disabled.def | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/suite/galera/disabled.def b/mysql-test/suite/galera/disabled.def index 453bbb139f5..02f1bb5eb1f 100644 --- a/mysql-test/suite/galera/disabled.def +++ b/mysql-test/suite/galera/disabled.def @@ -11,6 +11,7 @@ ############################################################################## MW-286 : MDEV-18464 Killing thread can cause mutex deadlock if done concurrently with Galera/replication victim kill +MW-328A : MDEV-22666 galera.MW-328A MTR failed: "Semaphore wait has lasted > 600 seconds" and do not release port 16002 MW-329 : MDEV-19962 Galera test failure on MW-329 galera.galera_defaults : MDEV-21494 Galera test sporadic failure on galera.galera_defaults galera_as_slave_replication_bundle : MDEV-15785 OPTION_GTID_BEGIN is set in Gtid_log_event::do_apply_event() From 745fa255ba73ab8b703481c4c420bfec7d11f6b3 Mon Sep 17 00:00:00 2001 From: Rucha Deodhar Date: Thu, 16 Jul 2020 22:15:55 +0530 Subject: [PATCH 07/26] MDEV-14836: Assertion `m_status == DA_ERROR' failed in Diagnostics_area::sql_errno upon query from I_S with LIMIT ROWS EXAMINED open_normal_and_derived_table() fails because the query was already killed as rows examined by the query are more than the limit. However, this isn't a real error. Fix: Check if there is actually an error before calling thd->sql_errno() and later send a warning in handle_select() if no real error. --- mysql-test/r/information_schema.result | 13 +++++++++++++ mysql-test/t/information_schema.test | 13 +++++++++++++ sql/sql_show.cc | 18 ++++++++++++------ 3 files changed, 38 insertions(+), 6 deletions(-) diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result index 2d404aff6bc..7644ff4e7a2 100644 --- a/mysql-test/r/information_schema.result +++ b/mysql-test/r/information_schema.result @@ -2184,3 +2184,16 @@ SCHEMA_NAME # # End of 10.1 tests # +# +# Start of 10.2 Test +# +# MDEV-14836: Assertion `m_status == DA_ERROR' failed in +# Diagnostics_area::sql_errno upon query from I_S with LIMIT ROWS EXAMINED +# +SELECT * FROM INFORMATION_SCHEMA.`COLUMNS` LIMIT ROWS EXAMINED 10; +TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE COLUMN_KEY EXTRA PRIVILEGES COLUMN_COMMENT IS_GENERATED GENERATION_EXPRESSION +Warnings: +Warning 1931 Query execution was interrupted. The query examined at least 666 rows, which exceeds LIMIT ROWS EXAMINED (10). The query result may be incomplete +# +# End of 10.2 Test +# diff --git a/mysql-test/t/information_schema.test b/mysql-test/t/information_schema.test index 2df105d4653..df00ff26908 100644 --- a/mysql-test/t/information_schema.test +++ b/mysql-test/t/information_schema.test @@ -1906,3 +1906,16 @@ SELECT SCHEMA_NAME from information_schema.schemata where schema_name=REPEAT('a' --echo # --echo # End of 10.1 tests --echo # + +--echo # +--echo # Start of 10.2 Test +--echo # +--echo # MDEV-14836: Assertion `m_status == DA_ERROR' failed in +--echo # Diagnostics_area::sql_errno upon query from I_S with LIMIT ROWS EXAMINED +--echo # + +SELECT * FROM INFORMATION_SCHEMA.`COLUMNS` LIMIT ROWS EXAMINED 10; + +--echo # +--echo # End of 10.2 Test +--echo # diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 18b7e92bca5..5544c765775 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -4430,7 +4430,7 @@ fill_schema_table_by_open(THD *thd, bool is_show_fields_or_keys, Again we don't do this for SHOW COLUMNS/KEYS because of backward compatibility. */ - if (!is_show_fields_or_keys && result && + if (!is_show_fields_or_keys && result && thd->is_error() && (thd->get_stmt_da()->sql_errno() == ER_NO_SUCH_TABLE || thd->get_stmt_da()->sql_errno() == ER_WRONG_OBJECT)) { @@ -5614,15 +5614,21 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables, I.e. we are in SELECT FROM INFORMATION_SCHEMA.COLUMS rather than in SHOW COLUMNS */ - push_warning(thd, Sql_condition::WARN_LEVEL_WARN, - thd->get_stmt_da()->sql_errno(), - thd->get_stmt_da()->message()); - thd->clear_error(); + if (thd->is_error()) + { + /* + The the query was aborted because examined rows exceeded limit. + Don't send the warning here. It is done later, in handle_select(). + */ + push_warning(thd, Sql_condition::WARN_LEVEL_WARN, + thd->get_stmt_da()->sql_errno(), + thd->get_stmt_da()->message()); + thd->clear_error(); + } res= 0; } DBUG_RETURN(res); } - show_table= tables->table; count= 0; ptr= show_table->field; From 5fb07d22f175f9c343d0299340eb3bebcaf6c838 Mon Sep 17 00:00:00 2001 From: Rucha Deodhar Date: Mon, 27 Jul 2020 19:07:08 +0530 Subject: [PATCH 08/26] MDEV-23082: ER_TABLEACCESS_DENIED_ERROR error message is truncated, and inaccurately Analysis: The list of all privileges is 118 characters wide. However, the format of error message was: "%-.32s command denied to user...". get_length() sets the maximum width to 32 characters. As a result, only first 32 characters of list of privilege are stored. Fix: Changing the format to "%-.100T..." so that get_length() sets width to 100. Hence, first 100 characters of the list of privilege are stored and the type specifier 'T' appends '...' so that truncation can be seen. --- mysql-test/r/grant.result | 18 ++++++++++++++++++ mysql-test/t/grant.test | 25 +++++++++++++++++++++++++ sql/share/errmsg-utf8.txt | 38 +++++++++++++++++++------------------- 3 files changed, 62 insertions(+), 19 deletions(-) diff --git a/mysql-test/r/grant.result b/mysql-test/r/grant.result index e7edaacdc9b..bd24c5bf380 100644 --- a/mysql-test/r/grant.result +++ b/mysql-test/r/grant.result @@ -2767,5 +2767,23 @@ root@localhost DROP TABLE t1; DROP USER dummy@localhost; # +# MDEV-23082: ER_TABLEACCESS_DENIED_ERROR error message is truncated, and +# inaccurately +# +CREATE USER foo; +CREATE DATABASE db; +CREATE TABLE db.t (a INT); +connect con1,localhost,foo,,; +GRANT ALL ON db.t TO foo; +ERROR 42000: SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, GRANT, REFERENCES, INDEX, ALTER, CREATE VIEW, SHOW ... command denied to user 'foo'@'localhost' for table 't' +GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, GRANT OPTION, REFERENCES, +INDEX, ALTER, CREATE VIEW, SHOW VIEW, TRIGGER ON db.t TO foo; +ERROR 42000: SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, GRANT, REFERENCES, INDEX, ALTER, CREATE VIEW, SHOW ... command denied to user 'foo'@'localhost' for table 't' +connection default; +disconnect con1; +DROP USER foo; +DROP TABLE db.t; +DROP DATABASE db; +# # End of 10.2 tests # diff --git a/mysql-test/t/grant.test b/mysql-test/t/grant.test index 11281811f02..fa3a690a2ee 100644 --- a/mysql-test/t/grant.test +++ b/mysql-test/t/grant.test @@ -2267,6 +2267,31 @@ SELECT * FROM t1; DROP TABLE t1; DROP USER dummy@localhost; +--echo # +--echo # MDEV-23082: ER_TABLEACCESS_DENIED_ERROR error message is truncated, and +--echo # inaccurately +--echo # + +CREATE USER foo; +CREATE DATABASE db; +CREATE TABLE db.t (a INT); + +--connect (con1,localhost,foo,,) + +--error ER_TABLEACCESS_DENIED_ERROR +GRANT ALL ON db.t TO foo; + +--error ER_TABLEACCESS_DENIED_ERROR +GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, GRANT OPTION, REFERENCES, +INDEX, ALTER, CREATE VIEW, SHOW VIEW, TRIGGER ON db.t TO foo; + +--connection default +--disconnect con1 + +DROP USER foo; +DROP TABLE db.t; +DROP DATABASE db; + --echo # --echo # End of 10.2 tests --echo # diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt index 8db992c7501..a4465ae0083 100644 --- a/sql/share/errmsg-utf8.txt +++ b/sql/share/errmsg-utf8.txt @@ -3244,25 +3244,25 @@ ER_NONEXISTING_GRANT 42000 swe "Det finns inget privilegium definierat för användare '%-.48s' på '%-.64s'" ukr "Повноважень не визначено для користувача '%-.48s' з хосту '%-.64s'" ER_TABLEACCESS_DENIED_ERROR 42000 - cze "%-.32s příkaz nepřístupný pro uživatele: '%s'@'%s' pro tabulku '%-.192s'" - dan "%-.32s-kommandoen er ikke tilladt for brugeren '%s'@'%s' for tabellen '%-.192s'" - nla "%-.32s commando geweigerd voor gebruiker: '%s'@'%s' voor tabel '%-.192s'" - eng "%-.32s command denied to user '%s'@'%s' for table '%-.192s'" - jps "コマンド %-.32s は ユーザー '%s'@'%s' ,テーブル '%-.192s' に対して許可されていません", - est "%-.32s käsk ei ole lubatud kasutajale '%s'@'%s' tabelis '%-.192s'" - fre "La commande '%-.32s' est interdite à l'utilisateur: '%s'@'%s' sur la table '%-.192s'" - ger "%-.32s Befehl nicht erlaubt für Benutzer '%s'@'%s' auf Tabelle '%-.192s'" - hun "%-.32s parancs a '%s'@'%s' felhasznalo szamara nem engedelyezett a '%-.192s' tablaban" - ita "Comando %-.32s negato per l'utente: '%s'@'%s' sulla tabella '%-.192s'" - jpn "コマンド %-.32s は ユーザー '%s'@'%s' ,テーブル '%-.192s' に対して許可されていません" - kor "'%-.32s' 명령은 다음 사용자에게 거부되었습니다. : '%s'@'%s' for 테이블 '%-.192s'" - por "Comando '%-.32s' negado para o usuário '%s'@'%s' na tabela '%-.192s'" - rum "Comanda %-.32s interzisa utilizatorului: '%s'@'%s' pentru tabela '%-.192s'" - rus "Команда %-.32s запрещена пользователю '%s'@'%s' для таблицы '%-.192s'" - serbian "%-.32s komanda zabranjena za korisnika '%s'@'%s' za tabelu '%-.192s'" - spa "%-.32s comando negado para usuario: '%s'@'%s' para tabla '%-.192s'" - swe "%-.32s ej tillåtet för '%s'@'%s' för tabell '%-.192s'" - ukr "%-.32s команда заборонена користувачу: '%s'@'%s' у таблиці '%-.192s'" + cze "%-.100T příkaz nepřístupný pro uživatele: '%s'@'%s' pro tabulku '%-.192s'" + dan "%-.100T-kommandoen er ikke tilladt for brugeren '%s'@'%s' for tabellen '%-.192s'" + nla "%-.100T commando geweigerd voor gebruiker: '%s'@'%s' voor tabel '%-.192s'" + eng "%-.100T command denied to user '%s'@'%s' for table '%-.192s'" + jps "コマンド %-.100T は ユーザー '%s'@'%s' ,テーブル '%-.192s' に対して許可されていません", + est "%-.100T käsk ei ole lubatud kasutajale '%s'@'%s' tabelis '%-.192s'" + fre "La commande '%-.100T' est interdite à l'utilisateur: '%s'@'%s' sur la table '%-.192s'" + ger "%-.100T Befehl nicht erlaubt für Benutzer '%s'@'%s' auf Tabelle '%-.192s'" + hun "%-.100T parancs a '%s'@'%s' felhasznalo szamara nem engedelyezett a '%-.192s' tablaban" + ita "Comando %-.100T negato per l'utente: '%s'@'%s' sulla tabella '%-.192s'" + jpn "コマンド %-.100T は ユーザー '%s'@'%s' ,テーブル '%-.192s' に対して許可されていません" + kor "'%-.100T' 명령은 다음 사용자에게 거부되었습니다. : '%s'@'%s' for 테이블 '%-.192s'" + por "Comando '%-.100T' negado para o usuário '%s'@'%s' na tabela '%-.192s'" + rum "Comanda %-.100T interzisa utilizatorului: '%s'@'%s' pentru tabela '%-.192s'" + rus "Команда %-.100T запрещена пользователю '%s'@'%s' для таблицы '%-.192s'" + serbian "%-.100T komanda zabranjena za korisnika '%s'@'%s' za tabelu '%-.192s'" + spa "%-.100T comando negado para usuario: '%s'@'%s' para tabla '%-.192s'" + swe "%-.100T ej tillåtet för '%s'@'%s' för tabell '%-.192s'" + ukr "%-.100T команда заборонена користувачу: '%s'@'%s' у таблиці '%-.192s'" ER_COLUMNACCESS_DENIED_ERROR 42000 cze "%-.32s příkaz nepřístupný pro uživatele: '%s'@'%s' pro sloupec '%-.192s' v tabulce '%-.192s'" dan "%-.32s-kommandoen er ikke tilladt for brugeren '%s'@'%s' for kolonne '%-.192s' in tabellen '%-.192s'" From d4967659032b18a5504198b41dd3d0a1813d79ef Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Tue, 4 Aug 2020 09:49:44 +0400 Subject: [PATCH 09/26] MDEV-22022 Various mangled SQL statements will crash 10.3 to 10.5 debug builds Lex_input_stream::scan_ident_delimited() could go beyond the end of the input when a starting backtick (`) delimiter did not have a corresponding ending backtick. Fix: catch the case when yyGet() returns 0, which means either eof-of-query or straight 0x00 byte inside backticks, and make the parser fail on syntax error, displaying the left backtick as the syntax error place. In case of filename in a script like this: SET CHARACTER_SET_CLIENT=17; -- 17 is 'filename' SELECT doc.`Children`.0 FROM t1; the ending backtick was not recognized as such because my_charlen() returns 0 for a straight backtick (backticks must normally be encoded as @0060 in filename). The same fix works for 'filename': the execution skips the backtick and reaches the end of the query, then yyGet() returns 0. This fix is OK for now. But eventually 'filename' should either be disallowed as a parser character set, or fixed to handle encoded punctuation properly. --- mysql-test/main/ctype_filename.result | 7 +++++++ mysql-test/main/ctype_filename.test | 10 ++++++++++ mysql-test/main/parser.result | 7 +++++++ mysql-test/main/parser.test | 9 +++++++++ sql/sql_lex.cc | 11 ++++++++++- 5 files changed, 43 insertions(+), 1 deletion(-) diff --git a/mysql-test/main/ctype_filename.result b/mysql-test/main/ctype_filename.result index c6d7d1e39b9..7536ea97fb1 100644 --- a/mysql-test/main/ctype_filename.result +++ b/mysql-test/main/ctype_filename.result @@ -21,3 +21,10 @@ SET NAMES utf8; SELECT @a:=CONVERT('aя' USING filename) AS `@a`, BINARY @a, REVERSE(@a), HEX(@a), HEX(REVERSE(@a)); @a BINARY @a REVERSE(@a) HEX(@a) HEX(REVERSE(@a)) aя a@r1 яa 61407231 40723161 +# +# MDEV-22022 Various mangled SQL statements will crash 10.3 to 10.5 debug builds +# +SET CHARACTER_SET_CLIENT=17; +SELECT doc.`Children`.0 FROM t1; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '?Children??0?FROM?t1' at line 1 +SET NAMES latin1; diff --git a/mysql-test/main/ctype_filename.test b/mysql-test/main/ctype_filename.test index 7ec07293a2b..6f77a6c5a3a 100644 --- a/mysql-test/main/ctype_filename.test +++ b/mysql-test/main/ctype_filename.test @@ -27,3 +27,13 @@ select convert(convert(',' using filename) using binary); --echo # SET NAMES utf8; SELECT @a:=CONVERT('aя' USING filename) AS `@a`, BINARY @a, REVERSE(@a), HEX(@a), HEX(REVERSE(@a)); + + +--echo # +--echo # MDEV-22022 Various mangled SQL statements will crash 10.3 to 10.5 debug builds +--echo # + +SET CHARACTER_SET_CLIENT=17; +--error ER_PARSE_ERROR +SELECT doc.`Children`.0 FROM t1; +SET NAMES latin1; diff --git a/mysql-test/main/parser.result b/mysql-test/main/parser.result index 002993eb128..f66fa7c457f 100644 --- a/mysql-test/main/parser.result +++ b/mysql-test/main/parser.result @@ -1760,4 +1760,11 @@ SELECT @@GLOBAL.password; ERROR HY000: Unknown system variable 'password' SELECT @@GLOBAL.role; ERROR HY000: Unknown system variable 'role' +# +# MDEV-22022 Various mangled SQL statements will crash 10.3 to 10.5 debug builds +# +EXECUTE IMMEDIATE 'if(`systeminfo /FO LIST'; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '`systeminfo /FO LIST' at line 1 +EXECUTE IMMEDIATE 'if(`systeminfo'; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '`systeminfo' at line 1 End of 10.3 tests diff --git a/mysql-test/main/parser.test b/mysql-test/main/parser.test index 4ee335dbbb4..5a2d0294171 100644 --- a/mysql-test/main/parser.test +++ b/mysql-test/main/parser.test @@ -1538,4 +1538,13 @@ SELECT @@GLOBAL.password; --error ER_UNKNOWN_SYSTEM_VARIABLE SELECT @@GLOBAL.role; +--echo # +--echo # MDEV-22022 Various mangled SQL statements will crash 10.3 to 10.5 debug builds +--echo # + +--error ER_PARSE_ERROR +EXECUTE IMMEDIATE 'if(`systeminfo /FO LIST'; +--error ER_PARSE_ERROR +EXECUTE IMMEDIATE 'if(`systeminfo'; + --echo End of 10.3 tests diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 89f74b6537b..1ef917f6964 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -2206,8 +2206,17 @@ int Lex_input_stream::scan_ident_delimited(THD *thd, uchar c, quote_char= m_tok_start[0]; DBUG_ASSERT(m_ptr == m_tok_start + 1); - while ((c= yyGet())) + for ( ; ; ) { + if (!(c= yyGet())) + { + /* + End-of-query or straight 0x00 inside a delimited identifier. + Return the quote character, to have the parser fail on syntax error. + */ + m_ptr= (char *) m_tok_start + 1; + return quote_char; + } int var_length= my_charlen(cs, get_ptr() - 1, get_end_of_query()); if (var_length == 1) { From 91caf130b71ac7532b5f1a387b7cf506ea2b09e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 4 Aug 2020 09:56:09 +0300 Subject: [PATCH 10/26] MDEV-23101 fixup: Remove redundant code lock_rec_has_to_wait_in_queue(): Remove an obviously redundant assertion that was added in commit a8ec45863b958757da61af3b2ce0a38b0a79d92c and also enclose a Galera-specific condition in #ifdef WITH_WSREP. --- storage/innobase/lock/lock0lock.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc index 1e7d9b031d7..4730ae53133 100644 --- a/storage/innobase/lock/lock0lock.cc +++ b/storage/innobase/lock/lock0lock.cc @@ -2203,10 +2203,11 @@ lock_rec_has_to_wait_in_queue( hash = lock_hash_get(wait_lock->type_mode); for (lock = lock_rec_get_first_on_page_addr(hash, space, page_no); - lock && lock != wait_lock; +#ifdef WITH_WSREP + lock && +#endif + lock != wait_lock; lock = lock_rec_get_next_on_page_const(lock)) { - - ut_ad(lock); const byte* p = (const byte*) &lock[1]; if (heap_no < lock_rec_get_n_bits(lock) From 14a5f73cdaf43ea40b990ab0dd6eb1553a5c86ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Tue, 4 Aug 2020 14:15:06 +0300 Subject: [PATCH 11/26] Add wait conditions for cluster size. --- .../galera_3nodes/r/galera_pc_bootstrap.result | 3 +++ .../galera_3nodes/t/galera_pc_bootstrap.test | 16 ++++++++++++---- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/mysql-test/suite/galera_3nodes/r/galera_pc_bootstrap.result b/mysql-test/suite/galera_3nodes/r/galera_pc_bootstrap.result index ee49330e892..3f29c7419eb 100644 --- a/mysql-test/suite/galera_3nodes/r/galera_pc_bootstrap.result +++ b/mysql-test/suite/galera_3nodes/r/galera_pc_bootstrap.result @@ -1,12 +1,15 @@ connection node_2; connection node_1; +call mtr.add_suppression("WSREP: gcs/src/gcs_core.cpp:core_handle_uuid_msg\\(\\).*"); CREATE TABLE t1 (f1 INTEGER); connection node_1; SET GLOBAL wsrep_provider_options = 'gmcast.isolate=1'; connection node_2; +SET SESSION wsrep_sync_wait=0; SET GLOBAL wsrep_provider_options = 'gmcast.isolate=1'; connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3; connection node_3; +SET SESSION wsrep_sync_wait=0; SET GLOBAL wsrep_provider_options = 'gmcast.isolate=1'; SET SESSION wsrep_sync_wait = 0; connection node_2; diff --git a/mysql-test/suite/galera_3nodes/t/galera_pc_bootstrap.test b/mysql-test/suite/galera_3nodes/t/galera_pc_bootstrap.test index f8381a3324b..ef5bc7dd923 100644 --- a/mysql-test/suite/galera_3nodes/t/galera_pc_bootstrap.test +++ b/mysql-test/suite/galera_3nodes/t/galera_pc_bootstrap.test @@ -6,6 +6,8 @@ --source include/galera_cluster.inc --source include/have_innodb.inc +call mtr.add_suppression("WSREP: gcs/src/gcs_core.cpp:core_handle_uuid_msg\\(\\).*"); + CREATE TABLE t1 (f1 INTEGER); # Force all nodes to become non-primary @@ -13,13 +15,19 @@ CREATE TABLE t1 (f1 INTEGER); SET GLOBAL wsrep_provider_options = 'gmcast.isolate=1'; --connection node_2 +SET SESSION wsrep_sync_wait=0; +--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size' +--source include/wait_condition.inc + SET GLOBAL wsrep_provider_options = 'gmcast.isolate=1'; --connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3 --connection node_3 -SET GLOBAL wsrep_provider_options = 'gmcast.isolate=1'; +SET SESSION wsrep_sync_wait=0; +--let $wait_condition = SELECT VARIABLE_VALUE = 1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size' +--source include/wait_condition.inc ---sleep 10 +SET GLOBAL wsrep_provider_options = 'gmcast.isolate=1'; # Node #2 should be non-primary SET SESSION wsrep_sync_wait = 0; @@ -44,7 +52,7 @@ INSERT INTO t1 VALUES (1); # Reconnect all nodes --connection node_2 SET GLOBAL wsrep_provider_options = 'gmcast.isolate=0'; ---sleep 10 + --source include/wait_until_connected_again.inc --let $wait_condition = SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; --source include/wait_condition.inc @@ -67,7 +75,7 @@ SET GLOBAL wsrep_provider_options = 'gmcast.isolate=0'; --connection node_3 SET GLOBAL wsrep_provider_options = 'gmcast.isolate=0'; ---sleep 10 + --source include/wait_until_connected_again.inc --let $wait_condition = SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; --source include/wait_condition.inc From 0e80f5a6934692dd7a47b6d31104fa194bbf18ec Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Wed, 5 Aug 2020 08:14:49 +0400 Subject: [PATCH 12/26] MDEV-23105 Cast number string with many leading zeros to decimal gives unexpected result Skip leading zeros when converting a string to decimal_t. --- mysql-test/r/type_newdecimal.result | 44 +++++++++++++++++++++++++++++ mysql-test/t/type_newdecimal.test | 22 +++++++++++++++ strings/decimal.c | 18 ++++++++++++ 3 files changed, 84 insertions(+) diff --git a/mysql-test/r/type_newdecimal.result b/mysql-test/r/type_newdecimal.result index 7b6629bc7b2..0c8f4f55442 100644 --- a/mysql-test/r/type_newdecimal.result +++ b/mysql-test/r/type_newdecimal.result @@ -2342,6 +2342,50 @@ t1 CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t1; # +# MDEV-23105 Cast number string with many leading zeros to decimal gives unexpected result +# +SELECT CAST(0000000000000000000000000000000000000000000000000000000000000000000000000000000020.01 AS DECIMAL(15,2)) as val; +val +20.01 +SET sql_mode=''; +CREATE TABLE t1 (a TEXT); +INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1)); +INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1,'.0')); +INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1,'.9')); +INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1,'.99')); +INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1,'.994')); +INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1,'.995')); +INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1,'.999')); +CREATE TABLE t2 (a TEXT, d DECIMAL(15,2)); +INSERT IGNORE INTO t2 (a,d) SELECT a, a FROM t1; +Warnings: +Note 1265 Data truncated for column 'd' at row 5 +Note 1265 Data truncated for column 'd' at row 6 +Note 1265 Data truncated for column 'd' at row 7 +INSERT IGNORE INTO t2 (a,d) SELECT CONCAT('-',a), CONCAT('-',a) FROM t1; +Warnings: +Note 1265 Data truncated for column 'd' at row 5 +Note 1265 Data truncated for column 'd' at row 6 +Note 1265 Data truncated for column 'd' at row 7 +SELECT d, a FROM t2 ORDER BY d,a; +d a +-2.00 -00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.995 +-2.00 -00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.999 +-1.99 -00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.99 +-1.99 -00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.994 +-1.90 -00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.9 +-1.00 -00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 +-1.00 -00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.0 +1.00 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 +1.00 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.0 +1.90 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.9 +1.99 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.99 +1.99 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.994 +2.00 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.995 +2.00 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.999 +DROP TABLE t1, t2; +SET sql_mode=DEFAULT; +# # End of 10.1 tests # # diff --git a/mysql-test/t/type_newdecimal.test b/mysql-test/t/type_newdecimal.test index 9b1beeb3f51..7338780c616 100644 --- a/mysql-test/t/type_newdecimal.test +++ b/mysql-test/t/type_newdecimal.test @@ -1821,6 +1821,28 @@ CREATE TABLE t1 (a DECIMAL(2,1) DEFAULT 0.10001e0); SHOW CREATE TABLE t1; DROP TABLE t1; +--echo # +--echo # MDEV-23105 Cast number string with many leading zeros to decimal gives unexpected result +--echo # + +SELECT CAST(0000000000000000000000000000000000000000000000000000000000000000000000000000000020.01 AS DECIMAL(15,2)) as val; + +SET sql_mode=''; +CREATE TABLE t1 (a TEXT); +INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1)); +INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1,'.0')); +INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1,'.9')); +INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1,'.99')); +INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1,'.994')); +INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1,'.995')); +INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1,'.999')); +CREATE TABLE t2 (a TEXT, d DECIMAL(15,2)); +INSERT IGNORE INTO t2 (a,d) SELECT a, a FROM t1; +INSERT IGNORE INTO t2 (a,d) SELECT CONCAT('-',a), CONCAT('-',a) FROM t1; +SELECT d, a FROM t2 ORDER BY d,a; +DROP TABLE t1, t2; +SET sql_mode=DEFAULT; + --echo # --echo # End of 10.1 tests --echo # diff --git a/strings/decimal.c b/strings/decimal.c index 56d09e8f303..dd2e1236489 100644 --- a/strings/decimal.c +++ b/strings/decimal.c @@ -812,6 +812,24 @@ internal_str2dec(const char *from, decimal_t *to, char **end, my_bool fixed) while (s < end_of_string && my_isdigit(&my_charset_latin1, *s)) s++; intg= (int) (s-s1); + /* + If the integer part is long enough and it has multiple leading zeros, + let's trim them, so this expression can return 1 without overflowing: + CAST(CONCAT(REPEAT('0',90),'1') AS DECIMAL(10)) + */ + if (intg > DIG_PER_DEC1 && s1[0] == '0' && s1[1] == '0') + { + /* + Keep at least one digit, to avoid an empty string. + So we trim '0000' to '0' rather than to ''. + Otherwise the below code (converting digits to to->buf) + would fail on a fatal error. + */ + const char *iend= s - 1; + for ( ; s1 < iend && *s1 == '0'; s1++) + { } + intg= (int) (s-s1); + } if (s < end_of_string && *s=='.') { endp= s+1; From 0041dacc1b8e85e1958355d1cfdc36055b05a884 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Wed, 5 Aug 2020 08:56:12 +0400 Subject: [PATCH 13/26] MDEV-23118 FORMAT(d1,dec) where dec=0/38 and d1 is DECIMAL(38,38) gives incorrect results FORMAT() can print more integer digits (than the argument has) if rounding happens: FORMAT(9.9,0) -> '10' The old code did not take this into account. Fix: 1. One extra digit is needed in case of rounding - If args[1] is a not-NULL constant, then reserve space for one extra integer digit if the requested number of decimals is less than args[0]->decimals. - Otherwise, reserve space for one extra integer digit if args[0]->decimals is not 0, because rounding can potentially happen (depending on the exact data in arguments). 2. One extra digit is also needed if the argument has no integer digits, e.g. in a data type like DECIMAL(38,38). The conditions 1 and 2 are ORed. 3. Fixing FORMAT_MAX_DECIMALS from 30 to 38. This was forgotten in 10.2.1 (when the limit for the number of fractional digits in DECIMAL was extended). --- mysql-test/main/func_math.result | 8 +++---- mysql-test/main/func_str.result | 2 +- mysql-test/main/type_newdecimal.result | 31 ++++++++++++++++++++++++++ mysql-test/main/type_newdecimal.test | 19 ++++++++++++++++ sql/item_strfunc.cc | 30 ++++++++++++++++++++++--- 5 files changed, 82 insertions(+), 8 deletions(-) diff --git a/mysql-test/main/func_math.result b/mysql-test/main/func_math.result index a397f927265..c0072641d3b 100644 --- a/mysql-test/main/func_math.result +++ b/mysql-test/main/func_math.result @@ -2295,7 +2295,7 @@ FORMAT(-1e308,2) SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( - `FORMAT(-1e308,2)` varchar(416) DEFAULT NULL + `FORMAT(-1e308,2)` varchar(417) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t1; CREATE OR REPLACE TABLE t1 AS SELECT FORMAT('-1e308',2); @@ -2305,7 +2305,7 @@ FORMAT('-1e308',2) SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( - `FORMAT('-1e308',2)` varchar(416) DEFAULT NULL + `FORMAT('-1e308',2)` varchar(417) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t1; CREATE OR REPLACE TABLE t1 AS SELECT FORMAT(DATE'20191231',0),FORMAT(TIME'99:05:00',0),FORMAT(TIMESTAMP'2019-12-31 23:59:59.123456',0); @@ -2317,7 +2317,7 @@ Table Create Table t1 CREATE TABLE `t1` ( `FORMAT(DATE'20191231',0)` varchar(11) DEFAULT NULL, `FORMAT(TIME'99:05:00',0)` varchar(10) DEFAULT NULL, - `FORMAT(TIMESTAMP'2019-12-31 23:59:59.123456',0)` varchar(19) DEFAULT NULL + `FORMAT(TIMESTAMP'2019-12-31 23:59:59.123456',0)` varchar(21) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t1; CREATE OR REPLACE TABLE t1 (y YEAR); @@ -3549,7 +3549,7 @@ FORMAT(f,0) SHOW CREATE TABLE t2; Table Create Table t2 CREATE TABLE `t2` ( - `FORMAT(f,0)` varchar(53) DEFAULT NULL + `FORMAT(f,0)` varchar(54) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t1,t2; # diff --git a/mysql-test/main/func_str.result b/mysql-test/main/func_str.result index 4a01935785c..7a6af68b1d8 100644 --- a/mysql-test/main/func_str.result +++ b/mysql-test/main/func_str.result @@ -2708,7 +2708,7 @@ create table t1(a float); insert into t1 values (1.33); select format(a, 2) from t1; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def format(a, 2) 253 56 4 Y 0 39 8 +def format(a, 2) 253 57 4 Y 0 39 8 format(a, 2) 1.33 drop table t1; diff --git a/mysql-test/main/type_newdecimal.result b/mysql-test/main/type_newdecimal.result index 0a631521d49..dd55d230450 100644 --- a/mysql-test/main/type_newdecimal.result +++ b/mysql-test/main/type_newdecimal.result @@ -2700,3 +2700,34 @@ ca 1 LENGTH(FLOOR(a)) 1 LENGTH(CEILING(a)) 1 DROP PROCEDURE p1; +# +# MDEV-23118 FORMAT(d1,dec) where dec=0/38 and d1 is DECIMAL(38,38) gives incorrect results +# +CREATE OR REPLACE TABLE t1 (a DECIMAL(38,38)); +INSERT INTO t1 VALUES (-0.9999999999999999999999999999999999999), (0.9999999999999999999999999999999999999); +SELECT a, FORMAT(a,0), FORMAT(a,38) FROM t1; +a -0.99999999999999999999999999999999999990 +FORMAT(a,0) -1 +FORMAT(a,38) -0.99999999999999999999999999999999999990 +a 0.99999999999999999999999999999999999990 +FORMAT(a,0) 1 +FORMAT(a,38) 0.99999999999999999999999999999999999990 +CREATE OR REPLACE TABLE t2 AS SELECT a, FORMAT(a,0), FORMAT(a,38) FROM t1; +SELECT * FROM t2; +a -0.99999999999999999999999999999999999990 +FORMAT(a,0) -1 +FORMAT(a,38) -0.99999999999999999999999999999999999990 +a 0.99999999999999999999999999999999999990 +FORMAT(a,0) 1 +FORMAT(a,38) 0.99999999999999999999999999999999999990 +SHOW CREATE TABLE t2; +Table t2 +Create Table CREATE TABLE `t2` ( + `a` decimal(38,38) DEFAULT NULL, + `FORMAT(a,0)` varchar(2) DEFAULT NULL, + `FORMAT(a,38)` varchar(41) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TABLE t2,t1; +# +# End of 10.4 tests +# diff --git a/mysql-test/main/type_newdecimal.test b/mysql-test/main/type_newdecimal.test index 7cf0a486268..c2b3dc44b37 100644 --- a/mysql-test/main/type_newdecimal.test +++ b/mysql-test/main/type_newdecimal.test @@ -1919,3 +1919,22 @@ CALL p1(10,10,' UNSIGNED'); --horizontal_results DROP PROCEDURE p1; + + +--echo # +--echo # MDEV-23118 FORMAT(d1,dec) where dec=0/38 and d1 is DECIMAL(38,38) gives incorrect results +--echo # + +--vertical_results +CREATE OR REPLACE TABLE t1 (a DECIMAL(38,38)); +INSERT INTO t1 VALUES (-0.9999999999999999999999999999999999999), (0.9999999999999999999999999999999999999); +SELECT a, FORMAT(a,0), FORMAT(a,38) FROM t1; +CREATE OR REPLACE TABLE t2 AS SELECT a, FORMAT(a,0), FORMAT(a,38) FROM t1; +SELECT * FROM t2; +SHOW CREATE TABLE t2; +DROP TABLE t2,t1; +--horizontal_results + +--echo # +--echo # End of 10.4 tests +--echo # diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 0baa762d25f..ca196acaff3 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -2661,18 +2661,42 @@ String *Item_func_soundex::val_str(String *str) This should be 'internationalized' sometimes. */ -const int FORMAT_MAX_DECIMALS= 30; +/* + The maximum supported decimal scale: + 38 - starting from 10.2.1 + 30 - before 10.2.1 +*/ +const int FORMAT_MAX_DECIMALS= 38; bool Item_func_format::fix_length_and_dec() { uint32 char_length= args[0]->type_handler()->Item_decimal_notation_int_digits(args[0]); uint dec= FORMAT_MAX_DECIMALS; - if (args[1]->const_item() && !args[1]->is_expensive() && !args[1]->null_value) + /* + Format can require one more integer digit if rounding happens: + FORMAT(9.9,0) -> '10' + Set need_extra_digit_for_rounding to true by default + if args[0] has some decimals: if args[1] is not + a constant, then format can potentially reduce + the number of decimals and round to the next integer. + */ + bool need_extra_digit_for_rounding= args[0]->decimals > 0; + if (args[1]->const_item() && !args[1]->is_expensive()) { Longlong_hybrid tmp= args[1]->to_longlong_hybrid(); - dec= tmp.to_uint(FORMAT_MAX_DECIMALS); + if (!args[1]->null_value) + { + dec= tmp.to_uint(FORMAT_MAX_DECIMALS); + need_extra_digit_for_rounding= (dec < args[0]->decimals); + } } + /* + In case of a data type with zero integer digits, e.g. DECIMAL(4,4), + we'll print at least one integer digit. + */ + if (need_extra_digit_for_rounding || !char_length) + char_length++; uint32 max_sep_count= (char_length / 3) + (dec ? 1 : 0) + /*sign*/1; collation.set(default_charset()); fix_char_length(char_length + max_sep_count + dec); From 1e31d74833d56609f8711022394c1eb2eb25a19a Mon Sep 17 00:00:00 2001 From: Varun Gupta Date: Thu, 23 Jul 2020 14:17:05 +0530 Subject: [PATCH 14/26] MDEV-17066: Bytes lost or Assertion `status_var.local_memory_used == 0 after DELETE with subquery with ROLLUP The issue here is when records are read from the temporary file (filesort result in this case) via a cache(rr_from_cache). The cache is initialized with init_rr_cache. For correlated subquery the cache allocation is happening at each execution of the subquery but the deallocation happens only once and that was when the query execution was done. So generally for subqueries we do two types of cleanup 1) Full cleanup: we should free all resources of the query(like temp tables). This is done generally when the query execution is complete or the subquery re-execution is not needed (case with uncorrelated subquery) 2) Partial cleanup: Minor cleanup that is required if the subquery needs recalculation. This is done for all the structures that need to be allocated for each execution (example SORT_INFO for filesort is allocated for each execution of the correlated subquery). The fix here would be free the cache used by rr_from_cache in the partial cleanup phase. --- mysql-test/r/subselect4.result | 25 ++++++++++++++++ mysql-test/t/subselect4.test | 23 +++++++++++++++ sql/records.cc | 20 +++++++++---- sql/records.h | 1 + sql/sql_select.cc | 53 ++++++++++++++++++++++------------ sql/sql_select.h | 2 +- 6 files changed, 99 insertions(+), 25 deletions(-) diff --git a/mysql-test/r/subselect4.result b/mysql-test/r/subselect4.result index a21b4174aae..ad8df9f9836 100644 --- a/mysql-test/r/subselect4.result +++ b/mysql-test/r/subselect4.result @@ -2620,4 +2620,29 @@ SELECT (SELECT DISTINCT t1i.b FROM t1 t1i GROUP BY t1i.a ORDER BY MAX(t1o.b)) FR 0 SET @@optimizer_switch= @save_optimizer_switch; DROP TABLE t1; +# +# MDEV-17066: Bytes lost or Assertion `status_var.local_memory_used == 0 after DELETE +# with subquery with ROLLUP +# +CREATE TABLE t1 (i INT DEFAULT 0, c VARCHAR(2048)); +INSERT INTO t1 SELECT 0, seq FROM seq_1_to_6000; +CREATE TABLE t2 (f VARCHAR(2048) DEFAULT ''); +INSERT INTO t2 VALUES ('1'),('bar'); +EXPLAIN +SELECT * FROM t2 WHERE f IN ( SELECT MAX(c) FROM t1 GROUP BY c WITH ROLLUP); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 6000 Using filesort +SELECT * FROM t2 WHERE f IN ( SELECT MAX(c) FROM t1 GROUP BY c WITH ROLLUP); +f +1 +SELECT * FROM t2; +f +1 +bar +DELETE FROM t2 WHERE f IN ( SELECT MAX(c) FROM t1 GROUP BY c WITH ROLLUP ); +SELECT * FROM t2; +f +bar +DROP TABLE t1, t2; # End of 10.2 tests diff --git a/mysql-test/t/subselect4.test b/mysql-test/t/subselect4.test index c33fe15bdcc..f35df5b6967 100644 --- a/mysql-test/t/subselect4.test +++ b/mysql-test/t/subselect4.test @@ -7,6 +7,8 @@ drop table if exists t0,t1,t2,t3,t4,t5,t6; drop view if exists v1, v2; --enable_warnings +--source include/have_sequence.inc + set @subselect4_tmp= @@optimizer_switch; set optimizer_switch='semijoin=on,firstmatch=on,loosescan=on'; set optimizer_switch='semijoin_with_cache=on'; @@ -2153,4 +2155,25 @@ SELECT (SELECT DISTINCT t1i.b FROM t1 t1i GROUP BY t1i.a ORDER BY MAX(t1o.b)) FR SET @@optimizer_switch= @save_optimizer_switch; DROP TABLE t1; +--echo # +--echo # MDEV-17066: Bytes lost or Assertion `status_var.local_memory_used == 0 after DELETE +--echo # with subquery with ROLLUP +--echo # + +CREATE TABLE t1 (i INT DEFAULT 0, c VARCHAR(2048)); +INSERT INTO t1 SELECT 0, seq FROM seq_1_to_6000; + +CREATE TABLE t2 (f VARCHAR(2048) DEFAULT ''); +INSERT INTO t2 VALUES ('1'),('bar'); + +EXPLAIN +SELECT * FROM t2 WHERE f IN ( SELECT MAX(c) FROM t1 GROUP BY c WITH ROLLUP); +SELECT * FROM t2 WHERE f IN ( SELECT MAX(c) FROM t1 GROUP BY c WITH ROLLUP); + +SELECT * FROM t2; +DELETE FROM t2 WHERE f IN ( SELECT MAX(c) FROM t1 GROUP BY c WITH ROLLUP ); +SELECT * FROM t2; + +DROP TABLE t1, t2; + --echo # End of 10.2 tests diff --git a/sql/records.cc b/sql/records.cc index 6a611d46ca4..8a152cda4c2 100644 --- a/sql/records.cc +++ b/sql/records.cc @@ -320,12 +320,9 @@ bool init_read_record(READ_RECORD *info,THD *thd, TABLE *table, void end_read_record(READ_RECORD *info) -{ /* free cache if used */ - if (info->cache) - { - my_free_lock(info->cache); - info->cache=0; - } +{ + /* free cache if used */ + free_cache(info); if (info->table) { if (info->table->is_created()) @@ -336,6 +333,17 @@ void end_read_record(READ_RECORD *info) } } + +void free_cache(READ_RECORD *info) +{ + if (info->cache) + { + my_free_lock(info->cache); + info->cache=0; + } +} + + static int rr_handle_error(READ_RECORD *info, int error) { if (info->thd->killed) diff --git a/sql/records.h b/sql/records.h index b5f04dbd161..dd63d3608bb 100644 --- a/sql/records.h +++ b/sql/records.h @@ -30,6 +30,7 @@ class SORT_INFO; struct READ_RECORD; void end_read_record(READ_RECORD *info); +void free_cache(READ_RECORD *info); /** A context for reading through a single table using a chosen access method: diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 379a109c57c..96e9602d77d 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -12391,24 +12391,7 @@ void JOIN::cleanup(bool full) for (tab= first_linear_tab(this, WITH_BUSH_ROOTS, WITH_CONST_TABLES); tab; tab= next_linear_tab(this, tab, WITH_BUSH_ROOTS)) { - if (!tab->table) - continue; - DBUG_PRINT("info", ("close index: %s.%s alias: %s", - tab->table->s->db.str, - tab->table->s->table_name.str, - tab->table->alias.c_ptr())); - if (tab->table->is_created()) - { - tab->table->file->ha_index_or_rnd_end(); - if (tab->aggr) - { - int tmp= 0; - if ((tmp= tab->table->file->extra(HA_EXTRA_NO_CACHE))) - tab->table->file->print_error(tmp, MYF(0)); - } - } - delete tab->filesort_result; - tab->filesort_result= NULL; + tab->partial_cleanup(); } } } @@ -26982,6 +26965,40 @@ void JOIN::handle_implicit_grouping_with_window_funcs() } } + +/* + @brief + Perform a partial cleanup for the JOIN_TAB structure + + @note + this is used to cleanup resources for the re-execution of correlated + subqueries. +*/ +void JOIN_TAB::partial_cleanup() +{ + if (!table) + return; + + if (table->is_created()) + { + table->file->ha_index_or_rnd_end(); + DBUG_PRINT("info", ("close index: %s.%s alias: %s", + table->s->db.str, + table->s->table_name.str, + table->alias.c_ptr())); + if (aggr) + { + int tmp= 0; + if ((tmp= table->file->extra(HA_EXTRA_NO_CACHE))) + table->file->print_error(tmp, MYF(0)); + } + } + delete filesort_result; + filesort_result= NULL; + free_cache(&read_record); +} + + /** @} (end of group Query_Optimizer) */ diff --git a/sql/sql_select.h b/sql/sql_select.h index 92da1355be0..4584460ca3f 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -613,7 +613,7 @@ typedef struct st_join_table { bool use_order() const; ///< Use ordering provided by chosen index? bool sort_table(); bool remove_duplicates(); - + void partial_cleanup(); } JOIN_TAB; From ab578bdf453c3cb0e9ca561cf373f64c96b22fda Mon Sep 17 00:00:00 2001 From: Varun Gupta Date: Tue, 4 Aug 2020 14:36:01 +0530 Subject: [PATCH 15/26] MDEV-9513: Assertion `join->group_list || !join->is_in_subquery()' failed in create_sort_index Removing the ORDER BY clause from the UNION when UNION is inside an IN/ALL/ANY/EXISTS subquery. The rewrites are done for subqueries but this rewrite is not done for the fake_select of the UNION. --- mysql-test/r/subselect4.result | 41 ++++++++++++++++++++++++++++++++++ mysql-test/t/subselect4.test | 25 +++++++++++++++++++++ sql/item_subselect.h | 4 ++++ sql/sql_union.cc | 19 ++++++++++++++++ 4 files changed, 89 insertions(+) diff --git a/mysql-test/r/subselect4.result b/mysql-test/r/subselect4.result index 606ab847028..e7655131fcf 100644 --- a/mysql-test/r/subselect4.result +++ b/mysql-test/r/subselect4.result @@ -2608,3 +2608,44 @@ region area population Central America and the Caribbean 442 66422 SET @@optimizer_switch= @save_optimizer_switch; DROP TABLE t1; +# +# MDEV-9513: Assertion `join->group_list || !join->is_in_subquery()' failed in create_sort_index +# +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1),(2); +CREATE TABLE t2 (a INT); +INSERT INTO t2 VALUES (2),(3); +EXPLAIN +SELECT t1.a FROM t1 WHERE t1.a IN ( SELECT A.a FROM t1 A UNION SELECT B.a FROM t2 B ORDER BY 1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where +2 DEPENDENT SUBQUERY A ALL NULL NULL NULL NULL 2 Using where +3 DEPENDENT UNION B ALL NULL NULL NULL NULL 2 Using where +NULL UNION RESULT ALL NULL NULL NULL NULL NULL +SELECT t1.a FROM t1 WHERE t1.a IN ( SELECT A.a FROM t1 A UNION SELECT B.a FROM t2 B ORDER BY 1); +a +1 +2 +EXPLAIN +SELECT t1.a FROM t1 WHERE EXISTS (SELECT A.a FROM t1 A UNION SELECT B.a FROM t2 B ORDER BY 1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 +2 SUBQUERY A ALL NULL NULL NULL NULL 2 +3 UNION B ALL NULL NULL NULL NULL 2 +NULL UNION RESULT ALL NULL NULL NULL NULL NULL +SELECT t1.a FROM t1 WHERE EXISTS (SELECT A.a FROM t1 A UNION SELECT B.a FROM t2 B ORDER BY 1); +a +1 +2 +EXPLAIN +SELECT t1.a FROM t1 WHERE t1.a IN ( SELECT A.a FROM t1 A UNION ALL SELECT B.a FROM t2 B ORDER BY 1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where +2 DEPENDENT SUBQUERY A ALL NULL NULL NULL NULL 2 Using where +3 DEPENDENT UNION B ALL NULL NULL NULL NULL 2 Using where +SELECT t1.a FROM t1 WHERE t1.a IN ( SELECT A.a FROM t1 A UNION ALL SELECT B.a FROM t2 B ORDER BY 1); +a +1 +2 +DROP TABLE t1,t2; +# end of 10.1 tests diff --git a/mysql-test/t/subselect4.test b/mysql-test/t/subselect4.test index 21ec28b1c03..8f1ad51ca50 100644 --- a/mysql-test/t/subselect4.test +++ b/mysql-test/t/subselect4.test @@ -2138,3 +2138,28 @@ WHERE population/area = (SELECT MAX(population/area) from t1 B where A.region = SET @@optimizer_switch= @save_optimizer_switch; DROP TABLE t1; + +--echo # +--echo # MDEV-9513: Assertion `join->group_list || !join->is_in_subquery()' failed in create_sort_index +--echo # + +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1),(2); + +CREATE TABLE t2 (a INT); +INSERT INTO t2 VALUES (2),(3); +EXPLAIN +SELECT t1.a FROM t1 WHERE t1.a IN ( SELECT A.a FROM t1 A UNION SELECT B.a FROM t2 B ORDER BY 1); +SELECT t1.a FROM t1 WHERE t1.a IN ( SELECT A.a FROM t1 A UNION SELECT B.a FROM t2 B ORDER BY 1); + +EXPLAIN +SELECT t1.a FROM t1 WHERE EXISTS (SELECT A.a FROM t1 A UNION SELECT B.a FROM t2 B ORDER BY 1); +SELECT t1.a FROM t1 WHERE EXISTS (SELECT A.a FROM t1 A UNION SELECT B.a FROM t2 B ORDER BY 1); + +EXPLAIN +SELECT t1.a FROM t1 WHERE t1.a IN ( SELECT A.a FROM t1 A UNION ALL SELECT B.a FROM t2 B ORDER BY 1); +SELECT t1.a FROM t1 WHERE t1.a IN ( SELECT A.a FROM t1 A UNION ALL SELECT B.a FROM t2 B ORDER BY 1); + +DROP TABLE t1,t2; + +--echo # end of 10.1 tests diff --git a/sql/item_subselect.h b/sql/item_subselect.h index ee8b31f4f17..9771b067ac4 100644 --- a/sql/item_subselect.h +++ b/sql/item_subselect.h @@ -131,6 +131,10 @@ public: Item_subselect(THD *thd); virtual subs_type substype() { return UNKNOWN_SUBS; } + bool is_exists_predicate() + { + return substype() == Item_subselect::EXISTS_SUBS; + } bool is_in_predicate() { return (substype() == Item_subselect::IN_SUBS || diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 38de2d592ed..0e623777ef0 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -388,6 +388,25 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, found_rows_for_union= first_sl->options & OPTION_FOUND_ROWS; is_union_select= is_union() || fake_select_lex; + /* + If we are reading UNION output and the UNION is in the + IN/ANY/ALL/EXISTS subquery, then ORDER BY is redundant and hence should + be removed. + Example: + select ... col IN (select col2 FROM t1 union select col3 from t2 ORDER BY 1) + + (as for ORDER BY ... LIMIT, it currently not supported inside + IN/ALL/ANY subqueries) + (For non-UNION this removal of ORDER BY clause is done in + check_and_do_in_subquery_rewrites()) + */ + if (is_union() && item && + (item->is_in_predicate() || item->is_exists_predicate())) + { + global_parameters()->order_list.first= NULL; + global_parameters()->order_list.elements= 0; + } + /* Global option */ if (is_union_select) From 85bd5314c56c150d756066806d4a6cb5b682383f Mon Sep 17 00:00:00 2001 From: Sergei Petrunia Date: Thu, 6 Aug 2020 13:39:10 +0300 Subject: [PATCH 16/26] Better comment about TABLE::maybe_null --- sql/table.h | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/sql/table.h b/sql/table.h index 93795113fab..2ea9b514df4 100644 --- a/sql/table.h +++ b/sql/table.h @@ -1291,9 +1291,16 @@ public: /* number of select if it is derived table */ uint derived_select_number; /* - 0 or JOIN_TYPE_{LEFT|RIGHT}. Currently this is only compared to 0. - If maybe_null !=0, this table is inner w.r.t. some outer join operation, - and null_row may be true. + Possible values: + - 0 by default + - JOIN_TYPE_{LEFT|RIGHT} if the table is inner w.r.t an outer join + operation + - 1 if the SELECT has mixed_implicit_grouping=1. example: + select max(col1), col2 from t1. In this case, the query produces + one row with all columns having NULL values. + + Interpetation: If maybe_null!=0, all fields of the table are considered + NULLable (and have NULL values when null_row=true) */ uint maybe_null; int current_lock; /* Type of lock on table */ From caa474f8e3139b1d8d00be7bedf337af7fd304a3 Mon Sep 17 00:00:00 2001 From: Varun Gupta Date: Thu, 6 Aug 2020 17:50:20 +0530 Subject: [PATCH 17/26] MDEV-15180: server crashed with NTH_VALUE() fix_fields for the arguments of the NTH_VALUE function was updating the same reference, so for the second argument (or after the first argument) the items were not resolved to their corresponding field from the view as they were updating the reference to the first argument. --- mysql-test/r/win.result | 16 ++++++++++++++++ mysql-test/t/win.test | 16 ++++++++++++++++ sql/item_windowfunc.cc | 2 +- 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/win.result b/mysql-test/r/win.result index 081aaedd323..3023a86eaad 100644 --- a/mysql-test/r/win.result +++ b/mysql-test/r/win.result @@ -3850,5 +3850,21 @@ ERROR 42000: Too big scale 56 specified for 'rank() over w1'. Maximum is 38 SELECT cast((rank() over w1) as decimal (53,30)); ERROR HY000: Window specification with name 'w1' is not defined # +# MDEV-15180: server crashed with NTH_VALUE() +# +CREATE TABLE t1 (i1 int, a int); +INSERT INTO t1 VALUES (1, 1), (2, 2),(3, 3); +CREATE TABLE t2 (i2 int); +INSERT INTO t2 VALUES (1),(2),(5),(1),(7),(4),(3); +CREATE VIEW v1 AS (SELECT * FROM t1,t2 WHERE t1.i1=t2.i2) ; +SELECT NTH_VALUE(i1, i1) OVER (PARTITION BY i1) FROM v1; +NTH_VALUE(i1, i1) OVER (PARTITION BY i1) +1 +1 +NULL +NULL +DROP VIEW v1; +DROP TABLE t1,t2; +# # End of 10.2 tests # diff --git a/mysql-test/t/win.test b/mysql-test/t/win.test index b749b235082..c7e3dac598b 100644 --- a/mysql-test/t/win.test +++ b/mysql-test/t/win.test @@ -2506,6 +2506,22 @@ SELECT cast((rank() over w1) as decimal (53,56)); --error ER_WRONG_WINDOW_SPEC_NAME SELECT cast((rank() over w1) as decimal (53,30)); +--echo # +--echo # MDEV-15180: server crashed with NTH_VALUE() +--echo # + +CREATE TABLE t1 (i1 int, a int); +INSERT INTO t1 VALUES (1, 1), (2, 2),(3, 3); + +CREATE TABLE t2 (i2 int); +INSERT INTO t2 VALUES (1),(2),(5),(1),(7),(4),(3); + +CREATE VIEW v1 AS (SELECT * FROM t1,t2 WHERE t1.i1=t2.i2) ; +SELECT NTH_VALUE(i1, i1) OVER (PARTITION BY i1) FROM v1; + +DROP VIEW v1; +DROP TABLE t1,t2; + --echo # --echo # End of 10.2 tests --echo # diff --git a/sql/item_windowfunc.cc b/sql/item_windowfunc.cc index 87dddbfb439..bb4a8a9f3af 100644 --- a/sql/item_windowfunc.cc +++ b/sql/item_windowfunc.cc @@ -234,7 +234,7 @@ bool Item_sum_hybrid_simple::fix_fields(THD *thd, Item **ref) { Item *item= args[i]; // 'item' can be changed during fix_fields - if ((!item->fixed && item->fix_fields(thd, args)) || + if ((!item->fixed && item->fix_fields(thd, args + i)) || (item= args[i])->check_cols(1)) return TRUE; with_window_func|= item->with_window_func; From 1dec60c79508f338572a69ef5e21b0535a13d064 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Fri, 7 Aug 2020 09:06:13 +0300 Subject: [PATCH 18/26] MDEV-22626: mysql_tzinfo_to_sql not replicates timezone to galeranodes if only 1 timezone will be loaded. Move alter to InnoDB earlier to more correct place to handle also if only a one timezone file is loaded. --- .../r/mysql_tzinfo_to_sql_symlink.result | 18 ++++++++++++++++++ .../r/mysql_tzinfo_to_sql_symlink.result | 18 ++++++++++++++++++ sql/tztime.cc | 19 ++++++++++--------- 3 files changed, 46 insertions(+), 9 deletions(-) diff --git a/mysql-test/r/mysql_tzinfo_to_sql_symlink.result b/mysql-test/r/mysql_tzinfo_to_sql_symlink.result index fc9ddce08b1..06e21beace1 100644 --- a/mysql-test/r/mysql_tzinfo_to_sql_symlink.result +++ b/mysql-test/r/mysql_tzinfo_to_sql_symlink.result @@ -85,6 +85,15 @@ END IF| # # Testing with explicit timezonefile # +\d | +IF (select count(*) from information_schema.global_variables where +variable_name='wsrep_on' and variable_value='ON') = 1 THEN +ALTER TABLE time_zone ENGINE=InnoDB; +ALTER TABLE time_zone_name ENGINE=InnoDB; +ALTER TABLE time_zone_transition ENGINE=InnoDB; +ALTER TABLE time_zone_transition_type ENGINE=InnoDB; +END IF| +\d ; INSERT INTO time_zone (Use_leap_seconds) VALUES ('N'); SET @time_zone_id= LAST_INSERT_ID(); INSERT INTO time_zone_name (Name, Time_zone_id) VALUES ('XXX', @time_zone_id); @@ -106,6 +115,15 @@ END IF| \d | IF (select count(*) from information_schema.global_variables where variable_name='wsrep_on' and variable_value='ON') = 1 THEN +ALTER TABLE time_zone ENGINE=InnoDB; +ALTER TABLE time_zone_name ENGINE=InnoDB; +ALTER TABLE time_zone_transition ENGINE=InnoDB; +ALTER TABLE time_zone_transition_type ENGINE=InnoDB; +END IF| +\d ; +\d | +IF (select count(*) from information_schema.global_variables where +variable_name='wsrep_on' and variable_value='ON') = 1 THEN ALTER TABLE time_zone_leap_second ENGINE=InnoDB; END IF| \d ; diff --git a/mysql-test/suite/wsrep/r/mysql_tzinfo_to_sql_symlink.result b/mysql-test/suite/wsrep/r/mysql_tzinfo_to_sql_symlink.result index 1e6ebbbd34d..51c2e204b78 100644 --- a/mysql-test/suite/wsrep/r/mysql_tzinfo_to_sql_symlink.result +++ b/mysql-test/suite/wsrep/r/mysql_tzinfo_to_sql_symlink.result @@ -85,6 +85,15 @@ END IF| # # Testing with explicit timezonefile # +\d | +IF (select count(*) from information_schema.global_variables where +variable_name='wsrep_on' and variable_value='ON') = 1 THEN +ALTER TABLE time_zone ENGINE=InnoDB; +ALTER TABLE time_zone_name ENGINE=InnoDB; +ALTER TABLE time_zone_transition ENGINE=InnoDB; +ALTER TABLE time_zone_transition_type ENGINE=InnoDB; +END IF| +\d ; INSERT INTO time_zone (Use_leap_seconds) VALUES ('N'); SET @time_zone_id= LAST_INSERT_ID(); INSERT INTO time_zone_name (Name, Time_zone_id) VALUES ('XXX', @time_zone_id); @@ -106,6 +115,15 @@ END IF| \d | IF (select count(*) from information_schema.global_variables where variable_name='wsrep_on' and variable_value='ON') = 1 THEN +ALTER TABLE time_zone ENGINE=InnoDB; +ALTER TABLE time_zone_name ENGINE=InnoDB; +ALTER TABLE time_zone_transition ENGINE=InnoDB; +ALTER TABLE time_zone_transition_type ENGINE=InnoDB; +END IF| +\d ; +\d | +IF (select count(*) from information_schema.global_variables where +variable_name='wsrep_on' and variable_value='ON') = 1 THEN ALTER TABLE time_zone_leap_second ENGINE=InnoDB; END IF| \d ; diff --git a/sql/tztime.cc b/sql/tztime.cc index f58801bf4b7..35e18f47629 100644 --- a/sql/tztime.cc +++ b/sql/tztime.cc @@ -2713,6 +2713,7 @@ main(int argc, char **argv) } if (opt_skip_write_binlog) + { /* If skip_write_binlog is set and wsrep is compiled in we disable sql_log_bin and wsrep_on to avoid Galera replicating below truncate table clauses. This will allow user to set different @@ -2720,15 +2721,9 @@ main(int argc, char **argv) printf("set @prep1=if((select count(*) from information_schema.global_variables where variable_name='wsrep_on' and variable_value='ON'), 'SET SESSION SQL_LOG_BIN=?, WSREP_ON=OFF;', 'do ?');\n" "prepare set_wsrep_write_binlog from @prep1;\n" "set @toggle=0; execute set_wsrep_write_binlog using @toggle;\n"); - - if (argc == 1 && !opt_leap) + } + else { - /* Argument is timezonedir */ - - root_name_end= strmake_buf(fullname, argv[0]); - - if(!opt_skip_write_binlog) - { // Alter time zone tables to InnoDB if wsrep_on is enabled // to allow changes to them to replicate with Galera printf("\\d |\n" @@ -2740,7 +2735,13 @@ main(int argc, char **argv) "ALTER TABLE time_zone_transition_type ENGINE=InnoDB;\n" "END IF|\n" "\\d ;\n"); - } + } + + if (argc == 1 && !opt_leap) + { + /* Argument is timezonedir */ + + root_name_end= strmake_buf(fullname, argv[0]); printf("TRUNCATE TABLE time_zone;\n"); printf("TRUNCATE TABLE time_zone_name;\n"); From 845e3c9801d17905bf2392f27cda66669c00f75f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Fri, 7 Aug 2020 10:22:38 +0300 Subject: [PATCH 19/26] Replaced infinite loop in procedure with limited loop to avoid hang. --- .../suite/galera/r/galera_bf_lock_wait.result | 32 +++++++++--- .../suite/galera/t/galera_bf_lock_wait.test | 52 +++++++++++++++---- 2 files changed, 67 insertions(+), 17 deletions(-) diff --git a/mysql-test/suite/galera/r/galera_bf_lock_wait.result b/mysql-test/suite/galera/r/galera_bf_lock_wait.result index 7ec524da888..0b22f963b29 100644 --- a/mysql-test/suite/galera/r/galera_bf_lock_wait.result +++ b/mysql-test/suite/galera/r/galera_bf_lock_wait.result @@ -1,23 +1,41 @@ +connection node_1; CREATE TABLE t1 ENGINE=InnoDB select 1 as a, 1 as b union select 2, 2; ALTER TABLE t1 add primary key(a); -CREATE PROCEDURE p1() +CREATE PROCEDURE p1(repeat_count INT) BEGIN +DECLARE current_num int; DECLARE CONTINUE HANDLER FOR SQLEXCEPTION rollback; -WHILE 1 DO +SET current_num = 0; +WHILE current_num < repeat_count DO start transaction; update t1 set b=connection_id() where a=1; commit; +SET current_num = current_num + 1; END WHILE; END| +connection node_2; connect node_1_p1, 127.0.0.1, root, , test, $NODE_MYPORT_1; -call p1; +SET SESSION wsrep_sync_wait=0; +call p1(1000); connect node_1_p2, 127.0.0.1, root, , test, $NODE_MYPORT_1; -call p1; +SET SESSION wsrep_sync_wait=0; +call p1(1000); connect node_2_p1, 127.0.0.1, root, , test, $NODE_MYPORT_2; -call p1; +SET SESSION wsrep_sync_wait=0; +call p1(1000); connect node_2_p2, 127.0.0.1, root, , test, $NODE_MYPORT_2; -call p1; -connection default; +SET SESSION wsrep_sync_wait=0; +call p1(1000); +connection node_1; checking error log for 'BF lock wait long' message for 10 times every 10 seconds ... +connection node_1_p1; +connection node_1_p2; +connection node_2_p1; +connection node_2_p2; +connection node_1; drop table t1; drop procedure p1; +disconnect node_1_p1; +disconnect node_1_p2; +disconnect node_2_p1; +disconnect node_2_p2; diff --git a/mysql-test/suite/galera/t/galera_bf_lock_wait.test b/mysql-test/suite/galera/t/galera_bf_lock_wait.test index e3a9077a888..c8a31506ffa 100644 --- a/mysql-test/suite/galera/t/galera_bf_lock_wait.test +++ b/mysql-test/suite/galera/t/galera_bf_lock_wait.test @@ -1,34 +1,47 @@ --source include/galera_cluster.inc --source include/big_test.inc - + +--connection node_1 CREATE TABLE t1 ENGINE=InnoDB select 1 as a, 1 as b union select 2, 2; ALTER TABLE t1 add primary key(a); DELIMITER |; -CREATE PROCEDURE p1() +CREATE PROCEDURE p1(repeat_count INT) BEGIN + DECLARE current_num int; DECLARE CONTINUE HANDLER FOR SQLEXCEPTION rollback; - WHILE 1 DO + SET current_num = 0; + + WHILE current_num < repeat_count DO start transaction; update t1 set b=connection_id() where a=1; commit; + SET current_num = current_num + 1; END WHILE; END| DELIMITER ;| - + +--connection node_2 +--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_TYPE = 'PROCEDURE' AND ROUTINE_NAME = 'p1' +--source include/wait_condition.inc + --connect node_1_p1, 127.0.0.1, root, , test, $NODE_MYPORT_1 -send call p1; +SET SESSION wsrep_sync_wait=0; +send call p1(1000); --connect node_1_p2, 127.0.0.1, root, , test, $NODE_MYPORT_1 -send call p1; +SET SESSION wsrep_sync_wait=0; +send call p1(1000); --connect node_2_p1, 127.0.0.1, root, , test, $NODE_MYPORT_2 -send call p1; +SET SESSION wsrep_sync_wait=0; +send call p1(1000); --connect node_2_p2, 127.0.0.1, root, , test, $NODE_MYPORT_2 -send call p1; +SET SESSION wsrep_sync_wait=0; +send call p1(1000); -connection default; +connection node_1; let $counter=10; let $sleep_period=10; @@ -46,7 +59,26 @@ while($counter > 0) exec grep 'BF lock wait long' $MYSQLTEST_VARDIR/log/mysqld.*.err; dec $counter; } - + +--connection node_1_p1 +--error 0,1213 +--reap +--connection node_1_p2 +--error 0,1213 +--reap +--connection node_2_p1 +--error 0,1213 +--reap +--connection node_2_p2 +--error 0,1213 +--reap + +--connection node_1 drop table t1; drop procedure p1; +--disconnect node_1_p1 +--disconnect node_1_p2 +--disconnect node_2_p1 +--disconnect node_2_p2 + From fe555b9c5f110467a991bc5bde1215d7ef014d28 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Sat, 8 Aug 2020 09:44:31 +0400 Subject: [PATCH 20/26] MDEV-23415 Server crash or Assertion `dec_length <= str_length' failed in Item_func_format::val_str_ascii Problem: The crash happened in FORMAT(double, dec>=31, 'de_DE'). The patch for MDEV-23118 (commit 0041dacc1b8e85e1958355d1cfdc36055b05a884) did not take into account that String::set_real() has a limit of 31 (FLOATING_POINT_DECIMALS) fractional digits. So for the range of 31..38 digits, set_real() switches to use: - my_fcvt() - decimal point notation, e.g. 1.9999999999 - my_gcvt() - scientific notation, e.g. 1e22 my_gcvt() returned a shorter string than Item_func_format::val_str_ascii() expected to get after the my_fcvt() call, so it crashed on assert. Solution: We cannot extend set_real() to use the my_fcvt() mode for the range of 31..38 fractional digits, because set_real() is used in a lot of places and such a change will break everything. Introducing String::set_fcvt() which always prints using my_fcvt() for the whole range of decimals 0..38, supported by the FORMAT() function. --- mysql-test/main/type_float.result | 170 ++++++++++++++++++++++++++++++ mysql-test/main/type_float.test | 20 ++++ sql/item_strfunc.cc | 2 +- sql/sql_string.cc | 11 ++ sql/sql_string.h | 6 ++ 5 files changed, 208 insertions(+), 1 deletion(-) diff --git a/mysql-test/main/type_float.result b/mysql-test/main/type_float.result index 167c167ad45..57fba0e8d40 100644 --- a/mysql-test/main/type_float.result +++ b/mysql-test/main/type_float.result @@ -969,5 +969,175 @@ Warnings: Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where 1 DROP TABLE t1; # +# MDEV-23415 Server crash or Assertion `dec_length <= str_length' failed in Item_func_format::val_str_ascii +# +SELECT FORMAT('0', 50, 'de_DE'); +FORMAT('0', 50, 'de_DE') +0,00000000000000000000000000000000000000 +SELECT FORMAT(0e0, 50, 'de_DE'); +FORMAT(0e0, 50, 'de_DE') +0,00000000000000000000000000000000000000 +FOR d IN 0..50 +DO +SELECT +d, +FORMAT(123456789.123456789e0, d, 'de_DE') AS fdbl, +FORMAT(123456789.123456789, d, 'de_DE') AS fdec; +END FOR; +$$ +d 0 +fdbl 123.456.789 +fdec 123.456.789 +d 1 +fdbl 123.456.789,1 +fdec 123.456.789,1 +d 2 +fdbl 123.456.789,12 +fdec 123.456.789,12 +d 3 +fdbl 123.456.789,123 +fdec 123.456.789,123 +d 4 +fdbl 123.456.789,1235 +fdec 123.456.789,1235 +d 5 +fdbl 123.456.789,12346 +fdec 123.456.789,12346 +d 6 +fdbl 123.456.789,123457 +fdec 123.456.789,123457 +d 7 +fdbl 123.456.789,1234568 +fdec 123.456.789,1234568 +d 8 +fdbl 123.456.789,12345680 +fdec 123.456.789,12345679 +d 9 +fdbl 123.456.789,123456790 +fdec 123.456.789,123456789 +d 10 +fdbl 123.456.789,1234567900 +fdec 123.456.789,1234567890 +d 11 +fdbl 123.456.789,12345680000 +fdec 123.456.789,12345678900 +d 12 +fdbl 123.456.789,123456790000 +fdec 123.456.789,123456789000 +d 13 +fdbl 123.456.789,1234568000000 +fdec 123.456.789,1234567890000 +d 14 +fdbl 123.456.789,12345679000000 +fdec 123.456.789,12345678900000 +d 15 +fdbl 123.456.789,123456790000000 +fdec 123.456.789,123456789000000 +d 16 +fdbl 123.456.789,1234567800000000 +fdec 123.456.789,1234567890000000 +d 17 +fdbl 123.456.789,12345679000000000 +fdec 123.456.789,12345678900000000 +d 18 +fdbl 123.456.789,123456790000000000 +fdec 123.456.789,123456789000000000 +d 19 +fdbl 123.456.789,1234567900000000000 +fdec 123.456.789,1234567890000000000 +d 20 +fdbl 123.456.789,12345679000000000000 +fdec 123.456.789,12345678900000000000 +d 21 +fdbl 123.456.789,123456800000000000000 +fdec 123.456.789,123456789000000000000 +d 22 +fdbl 123.456.789,1234567900000000000000 +fdec 123.456.789,1234567890000000000000 +d 23 +fdbl 123.456.789,12345680000000000000000 +fdec 123.456.789,12345678900000000000000 +d 24 +fdbl 123.456.789,123456790000000000000000 +fdec 123.456.789,123456789000000000000000 +d 25 +fdbl 123.456.789,1234567900000000000000000 +fdec 123.456.789,1234567890000000000000000 +d 26 +fdbl 123.456.789,12345679000000000000000000 +fdec 123.456.789,12345678900000000000000000 +d 27 +fdbl 123.456.789,123456780000000000000000000 +fdec 123.456.789,123456789000000000000000000 +d 28 +fdbl 123.456.789,1234567900000000000000000000 +fdec 123.456.789,1234567890000000000000000000 +d 29 +fdbl 123.456.789,12345678000000000000000000000 +fdec 123.456.789,12345678900000000000000000000 +d 30 +fdbl 123.456.789,123456790000000000000000000000 +fdec 123.456.789,123456789000000000000000000000 +d 31 +fdbl 123.456.789,1234567900000000000000000000000 +fdec 123.456.789,1234567890000000000000000000000 +d 32 +fdbl 123.456.789,12345679000000000000000000000000 +fdec 123.456.789,12345678900000000000000000000000 +d 33 +fdbl 123.456.789,123456790000000000000000000000000 +fdec 123.456.789,123456789000000000000000000000000 +d 34 +fdbl 123.456.789,1234567900000000000000000000000000 +fdec 123.456.789,1234567890000000000000000000000000 +d 35 +fdbl 123.456.789,12345679000000000000000000000000000 +fdec 123.456.789,12345678900000000000000000000000000 +d 36 +fdbl 123.456.789,123456790000000000000000000000000000 +fdec 123.456.789,123456789000000000000000000000000000 +d 37 +fdbl 123.456.789,1234567900000000000000000000000000000 +fdec 123.456.789,1234567890000000000000000000000000000 +d 38 +fdbl 123.456.789,12345678000000000000000000000000000000 +fdec 123.456.789,12345678900000000000000000000000000000 +d 39 +fdbl 123.456.789,12345678000000000000000000000000000000 +fdec 123.456.789,12345678900000000000000000000000000000 +d 40 +fdbl 123.456.789,12345678000000000000000000000000000000 +fdec 123.456.789,12345678900000000000000000000000000000 +d 41 +fdbl 123.456.789,12345678000000000000000000000000000000 +fdec 123.456.789,12345678900000000000000000000000000000 +d 42 +fdbl 123.456.789,12345678000000000000000000000000000000 +fdec 123.456.789,12345678900000000000000000000000000000 +d 43 +fdbl 123.456.789,12345678000000000000000000000000000000 +fdec 123.456.789,12345678900000000000000000000000000000 +d 44 +fdbl 123.456.789,12345678000000000000000000000000000000 +fdec 123.456.789,12345678900000000000000000000000000000 +d 45 +fdbl 123.456.789,12345678000000000000000000000000000000 +fdec 123.456.789,12345678900000000000000000000000000000 +d 46 +fdbl 123.456.789,12345678000000000000000000000000000000 +fdec 123.456.789,12345678900000000000000000000000000000 +d 47 +fdbl 123.456.789,12345678000000000000000000000000000000 +fdec 123.456.789,12345678900000000000000000000000000000 +d 48 +fdbl 123.456.789,12345678000000000000000000000000000000 +fdec 123.456.789,12345678900000000000000000000000000000 +d 49 +fdbl 123.456.789,12345678000000000000000000000000000000 +fdec 123.456.789,12345678900000000000000000000000000000 +d 50 +fdbl 123.456.789,12345678000000000000000000000000000000 +fdec 123.456.789,12345678900000000000000000000000000000 +# # End of 10.4 tests # diff --git a/mysql-test/main/type_float.test b/mysql-test/main/type_float.test index 4665c945a76..1c17b6345f3 100644 --- a/mysql-test/main/type_float.test +++ b/mysql-test/main/type_float.test @@ -666,6 +666,26 @@ EXECUTE IMMEDIATE 'EXPLAIN EXTENDED SELECT * FROM t1 WHERE ?+a<=>1e0+a' USING 1e EXECUTE IMMEDIATE 'EXPLAIN EXTENDED SELECT * FROM t1 WHERE 1e0+a<=>?+a' USING 1e0; DROP TABLE t1; +--echo # +--echo # MDEV-23415 Server crash or Assertion `dec_length <= str_length' failed in Item_func_format::val_str_ascii +--echo # + +SELECT FORMAT('0', 50, 'de_DE'); +SELECT FORMAT(0e0, 50, 'de_DE'); + +--vertical_results +DELIMITER $$; +FOR d IN 0..50 +DO + SELECT + d, + FORMAT(123456789.123456789e0, d, 'de_DE') AS fdbl, + FORMAT(123456789.123456789, d, 'de_DE') AS fdec; +END FOR; +$$ +DELIMITER ;$$ +--horizontal_results + --echo # --echo # End of 10.4 tests --echo # diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index ca196acaff3..5ae6fe0c7de 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -2752,7 +2752,7 @@ String *Item_func_format::val_str_ascii(String *str) if ((null_value=args[0]->null_value)) return 0; /* purecov: inspected */ nr= my_double_round(nr, (longlong) dec, FALSE, FALSE); - str->set_real(nr, dec, &my_charset_numeric); + str->set_fcvt(nr, dec); if (!std::isfinite(nr)) return str; str_length=str->length(); diff --git a/sql/sql_string.cc b/sql/sql_string.cc index 483eb4fcbec..4a94087a6ba 100644 --- a/sql/sql_string.cc +++ b/sql/sql_string.cc @@ -183,6 +183,17 @@ bool Binary_string::set_hex(const char *str, uint32 len) } +bool Binary_string::set_fcvt(double num, uint decimals) +{ + // Assert that `decimals` is small enough to fit into FLOATING_POINT_BUFFER + DBUG_ASSERT(decimals < DECIMAL_NOT_SPECIFIED); + if (alloc(FLOATING_POINT_BUFFER)) + return true; + length(my_fcvt(num, decimals, Ptr, NULL)); + return false; +} + + bool String::set_real(double num,uint decimals, CHARSET_INFO *cs) { char buff[FLOATING_POINT_BUFFER]; diff --git a/sql/sql_string.h b/sql/sql_string.h index 3050a5ef464..7d2ce5cecbc 100644 --- a/sql/sql_string.h +++ b/sql/sql_string.h @@ -517,6 +517,7 @@ public: bool set_hex(ulonglong num); bool set_hex(const char *str, uint32 len); + bool set_fcvt(double num, uint decimals); bool copy(); // Alloc string if not alloced bool copy(const Binary_string &s); // Allocate new string @@ -781,6 +782,11 @@ public: bool set(longlong num, CHARSET_INFO *cs) { return set_int(num, false, cs); } bool set(ulonglong num, CHARSET_INFO *cs) { return set_int((longlong)num, true, cs); } bool set_real(double num,uint decimals, CHARSET_INFO *cs); + bool set_fcvt(double num, uint decimals) + { + set_charset(&my_charset_latin1); + return Binary_string::set_fcvt(num, decimals); + } bool set_hex(ulonglong num) { From deb365581b96527c5c96b3f5ed1235e10543f5f1 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Tue, 5 May 2020 19:23:29 +1000 Subject: [PATCH 21/26] MDEV-23386: mtr: main.mysqld--help autosized table{-open,}-cach and max-connections Example of the failure: http://buildbot.askmonty.org/buildbot/builders/bld-p9-rhel7/builds/4417/steps/mtr/logs/stdio ``` main.mysqld--help 'unix' w17 [ fail ] Test ended at 2020-06-20 18:51:45 CURRENT_TEST: main.mysqld--help --- /opt/buildbot-slave/bld-p9-rhel7/build/mysql-test/main/mysqld--help.result 2020-06-20 16:06:49.903604179 +0300 +++ /opt/buildbot-slave/bld-p9-rhel7/build/mysql-test/main/mysqld--help.reject 2020-06-20 18:51:44.886766820 +0300 @@ -1797,10 +1797,10 @@ sync-relay-log-info 10000 sysdate-is-now FALSE system-versioning-alter-history ERROR -table-cache 421 +table-cache 2000 table-definition-cache 400 -table-open-cache 421 -table-open-cache-instances 1 +table-open-cache 2000 +table-open-cache-instances 8 tc-heuristic-recover OFF tcp-keepalive-interval 0 tcp-keepalive-probes 0 mysqltest: Result length mismatch ``` mtr: table_open_cache_basic autosized: Lets assume that >400 are available and that we can set the result back to the start value. All of these system variables are autosized and can generate MTR output differences. Closes #1527 --- mysql-test/r/mysqld--help,win.rdiff | 31 +++++++------------ mysql-test/r/mysqld--help.result | 3 -- .../sys_vars/r/table_open_cache_basic.result | 12 +++---- .../sys_vars/t/table_open_cache_basic.test | 4 +-- mysql-test/t/mysqld--help.test | 3 +- 5 files changed, 22 insertions(+), 31 deletions(-) diff --git a/mysql-test/r/mysqld--help,win.rdiff b/mysql-test/r/mysqld--help,win.rdiff index 128155870b8..b71401bf461 100644 --- a/mysql-test/r/mysqld--help,win.rdiff +++ b/mysql-test/r/mysqld--help,win.rdiff @@ -1,6 +1,6 @@ --- mysqld--help.result +++ mysqld--help,win.reject -@@ -333,7 +333,6 @@ +@@ -337,7 +337,6 @@ The following specify which files/extra groups are read (specified before remain The number of segments in a key cache -L, --language=name Client error messages in given language. May be given as a full path. Deprecated. Use --lc-messages-dir instead. @@ -8,7 +8,7 @@ --lc-messages=name Set the language used for the error messages. -L, --lc-messages-dir=name Directory where error messages are -@@ -533,6 +532,7 @@ +@@ -537,6 +536,7 @@ The following specify which files/extra groups are read (specified before remain Use MySQL-5.6 (instead of MariaDB-5.3) format for TIME, DATETIME, TIMESTAMP columns. (Defaults to on; use --skip-mysql56-temporal-format to disable.) @@ -16,7 +16,7 @@ --net-buffer-length=# Buffer length for TCP/IP and socket communication --net-read-timeout=# -@@ -924,6 +924,9 @@ +@@ -928,6 +928,9 @@ The following specify which files/extra groups are read (specified before remain files within specified directory --server-id=# Uniquely identifies the server instance in the community of replication partners @@ -26,7 +26,7 @@ --show-slave-auth-info Show user and password in SHOW SLAVE HOSTS on this master. -@@ -1034,6 +1037,10 @@ +@@ -1038,6 +1041,10 @@ The following specify which files/extra groups are read (specified before remain Log slow queries to given log file. Defaults logging to 'hostname'-slow.log. Must be enabled to activate other slow log options @@ -37,7 +37,7 @@ --socket=name Socket file to use for connection --sort-buffer-size=# Each thread that needs to do a sort allocates a buffer of -@@ -1052,6 +1059,7 @@ +@@ -1056,6 +1063,7 @@ The following specify which files/extra groups are read (specified before remain NO_ENGINE_SUBSTITUTION, PAD_CHAR_TO_FULL_LENGTH --stack-trace Print a symbolic stack trace on failure (Defaults to on; use --skip-stack-trace to disable.) @@ -45,7 +45,7 @@ --stored-program-cache=# The soft upper limit for number of cached stored routines for one connection. -@@ -1088,25 +1096,11 @@ +@@ -1092,25 +1100,11 @@ The following specify which files/extra groups are read (specified before remain COMMIT, ROLLBACK --thread-cache-size=# How many threads we should keep in a cache for reuse @@ -73,7 +73,7 @@ --thread-stack=# The stack size for each thread --time-format=name The TIME format (ignored) --timed-mutexes Specify whether to time mutexes. Deprecated, has no -@@ -1115,8 +1109,8 @@ +@@ -1119,8 +1113,8 @@ The following specify which files/extra groups are read (specified before remain size, MariaDB will automatically convert it to an on-disk MyISAM or Aria table. -t, --tmpdir=name Path for temporary files. Several paths may be specified, @@ -84,7 +84,7 @@ --transaction-alloc-block-size=# Allocation block size for transactions to be stored in binary log -@@ -1240,7 +1234,6 @@ +@@ -1244,7 +1238,6 @@ key-cache-block-size 1024 key-cache-division-limit 100 key-cache-file-hash-size 512 key-cache-segments 0 @@ -92,7 +92,7 @@ lc-messages en_US lc-messages-dir MYSQL_SHAREDIR/ lc-time-names en_US -@@ -1307,6 +1300,7 @@ +@@ -1310,6 +1303,7 @@ myisam-sort-buffer-size 134216704 myisam-stats-method NULLS_UNEQUAL myisam-use-mmap FALSE mysql56-temporal-format TRUE @@ -100,7 +100,7 @@ net-buffer-length 16384 net-read-timeout 30 net-retry-count 10 -@@ -1403,6 +1397,8 @@ +@@ -1406,6 +1400,8 @@ safe-user-create FALSE secure-auth TRUE secure-file-priv (No default value) server-id 0 @@ -109,7 +109,7 @@ show-slave-auth-info FALSE silent-startup FALSE skip-grant-tables TRUE -@@ -1426,6 +1422,7 @@ +@@ -1429,6 +1425,7 @@ slave-transaction-retries 10 slave-type-conversions slow-launch-time 2 slow-query-log FALSE @@ -117,15 +117,8 @@ sort-buffer-size 2097152 sql-mode NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION stack-trace TRUE -@@ -1438,15 +1435,13 @@ - sync-relay-log 10000 - sync-relay-log-info 10000 - sysdate-is-now FALSE --table-cache 421 -+table-cache 2000 +@@ -1444,10 +1441,8 @@ sysdate-is-now FALSE table-definition-cache 400 --table-open-cache 421 -+table-open-cache 2000 tc-heuristic-recover OFF thread-cache-size 0 -thread-pool-idle-timeout 60 diff --git a/mysql-test/r/mysqld--help.result b/mysql-test/r/mysqld--help.result index c7fb52eeeb6..dce1578adee 100644 --- a/mysql-test/r/mysqld--help.result +++ b/mysql-test/r/mysqld--help.result @@ -1277,7 +1277,6 @@ max-binlog-cache-size 18446744073709547520 max-binlog-size 1073741824 max-binlog-stmt-cache-size 18446744073709547520 max-connect-errors 100 -max-connections 151 max-delayed-threads 20 max-digest-length 1024 max-error-count 64 @@ -1442,9 +1441,7 @@ sync-master-info 10000 sync-relay-log 10000 sync-relay-log-info 10000 sysdate-is-now FALSE -table-cache 421 table-definition-cache 400 -table-open-cache 421 tc-heuristic-recover OFF thread-cache-size 0 thread-pool-idle-timeout 60 diff --git a/mysql-test/suite/sys_vars/r/table_open_cache_basic.result b/mysql-test/suite/sys_vars/r/table_open_cache_basic.result index bc373003e1d..b805eb8f742 100644 --- a/mysql-test/suite/sys_vars/r/table_open_cache_basic.result +++ b/mysql-test/suite/sys_vars/r/table_open_cache_basic.result @@ -1,7 +1,7 @@ SET @start_value = @@global.table_open_cache ; -SELECT @start_value; -@start_value -421 +SELECT @start_value > 400; +@start_value > 400 +1 '#--------------------FN_DYNVARS_001_01------------------------#' SET @@global.table_open_cache = 99; SET @@global.table_open_cache = DeFAULT; @@ -108,6 +108,6 @@ ERROR 42S02: Unknown table 'global' in field list SELECT table_open_cache = @@session.table_open_cache ; ERROR 42S22: Unknown column 'table_open_cache' in 'field list' SET @@global.table_open_cache = @start_value; -SELECT @@global.table_open_cache ; -@@global.table_open_cache -421 +SELECT @@global.table_open_cache = @start_value ; +@@global.table_open_cache = @start_value +1 diff --git a/mysql-test/suite/sys_vars/t/table_open_cache_basic.test b/mysql-test/suite/sys_vars/t/table_open_cache_basic.test index 7d2549cd87f..1b7fbe5cbc5 100644 --- a/mysql-test/suite/sys_vars/t/table_open_cache_basic.test +++ b/mysql-test/suite/sys_vars/t/table_open_cache_basic.test @@ -35,7 +35,7 @@ ########################################################################## SET @start_value = @@global.table_open_cache ; -SELECT @start_value; +SELECT @start_value > 400; --echo '#--------------------FN_DYNVARS_001_01------------------------#' @@ -165,7 +165,7 @@ SELECT table_open_cache = @@session.table_open_cache ; ############################## SET @@global.table_open_cache = @start_value; -SELECT @@global.table_open_cache ; +SELECT @@global.table_open_cache = @start_value ; ################################################################## diff --git a/mysql-test/t/mysqld--help.test b/mysql-test/t/mysqld--help.test index 8924d2c45da..ec6e0f01189 100644 --- a/mysql-test/t/mysqld--help.test +++ b/mysql-test/t/mysqld--help.test @@ -23,7 +23,8 @@ perl; log-slow-queries pid-file slow-query-log-file log-basename datadir slave-load-tmpdir tmpdir socket thread-pool-size large-files-support lower-case-file-system system-time-zone - collation-server character-set-server log-tc-size version.*/; + collation-server character-set-server log-tc-size table-cache + table-open-cache max-connections version.*/; # Plugins which may or may not be there: @plugins=qw/innodb archive blackhole federated partition From 3e3da1642d6d02df00862f69ba64c2c6a8dd9b15 Mon Sep 17 00:00:00 2001 From: Daniel Bartholomew Date: Mon, 10 Aug 2020 10:16:31 -0400 Subject: [PATCH 22/26] bump the VERSION --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 42407f29a37..453e11b3aae 100644 --- a/VERSION +++ b/VERSION @@ -1,3 +1,3 @@ MYSQL_VERSION_MAJOR=10 MYSQL_VERSION_MINOR=1 -MYSQL_VERSION_PATCH=46 +MYSQL_VERSION_PATCH=47 From 7f67ef14852afebf90aaafdfc7295acbf0ad340f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 10 Aug 2020 15:18:53 +0300 Subject: [PATCH 23/26] MDEV-16115 Hang after reducing innodb_encryption_threads The test encryption.create_or_replace would occasionally fail, because some fil_space_t::n_pending_ops would never be decremented. fil_crypt_find_space_to_rotate(): If rotate_thread_t::should_shutdown() holds due to innodb_encryption_threads having been reduced, do release the reference. fil_space_remove_from_keyrotation(), fil_space_next(): Declare the functions static, simplify a little, and define in the same compilation unit with the only caller, fil_crypt_find_space_to_rotate(). fil_crypt_key_mutex: Remove (unused). --- storage/innobase/fil/fil0crypt.cc | 136 +++++++++++++++++++++++------ storage/innobase/fil/fil0fil.cc | 134 ---------------------------- storage/innobase/include/fil0fil.h | 28 ------ storage/xtradb/fil/fil0crypt.cc | 136 +++++++++++++++++++++++------ storage/xtradb/fil/fil0fil.cc | 134 ---------------------------- storage/xtradb/include/fil0fil.h | 28 ------ 6 files changed, 222 insertions(+), 374 deletions(-) diff --git a/storage/innobase/fil/fil0crypt.cc b/storage/innobase/fil/fil0crypt.cc index 901b28c8c62..fc7ef41786e 100644 --- a/storage/innobase/fil/fil0crypt.cc +++ b/storage/innobase/fil/fil0crypt.cc @@ -44,15 +44,8 @@ Modified Jan Lindström jan.lindstrom@mariadb.com #include "ha_prototypes.h" // IB_LOG_ #include -/** Mutex for keys */ -static ib_mutex_t fil_crypt_key_mutex; - static bool fil_crypt_threads_inited = false; -#ifdef UNIV_PFS_MUTEX -static mysql_pfs_key_t fil_crypt_key_mutex_key; -#endif - /** Is encryption enabled/disabled */ UNIV_INTERN ulong srv_encrypt_tables = 0; @@ -133,9 +126,6 @@ UNIV_INTERN void fil_space_crypt_init() { - mutex_create(fil_crypt_key_mutex_key, - &fil_crypt_key_mutex, SYNC_NO_ORDER_CHECK); - fil_crypt_throttle_sleep_event = os_event_create(); mutex_create(fil_crypt_stat_mutex_key, @@ -152,7 +142,6 @@ fil_space_crypt_cleanup() { os_event_free(fil_crypt_throttle_sleep_event); fil_crypt_throttle_sleep_event = NULL; - mutex_free(&fil_crypt_key_mutex); mutex_free(&crypt_stat_mutex); } @@ -1451,6 +1440,109 @@ fil_crypt_return_iops( fil_crypt_update_total_stat(state); } +/** Remove space from key rotation list if there are no pending operations. */ +static void fil_space_remove_from_keyrotation(fil_space_t *space) +{ + ut_ad(mutex_own(&fil_system->mutex)); + + if (space->n_pending_ops == 0 && space->is_in_rotation_list) + { + space->is_in_rotation_list= false; + ut_a(UT_LIST_GET_LEN(fil_system->rotation_list) > 0); + UT_LIST_REMOVE(rotation_list, fil_system->rotation_list, space); + } +} + +/** Return the next tablespace from key rotation list. +@param space previous tablespace (NULL to start from the beginning) +@return pointer to the next tablespace (with n_pending_ops incremented) +@retval NULL if this was the last */ +static fil_space_t *fil_space_keyrotate_next(fil_space_t *space) +{ + ut_ad(mutex_own(&fil_system->mutex)); + + if (UT_LIST_GET_LEN(fil_system->rotation_list) == 0) + { + if (space) + { + space->n_pending_ops--; + fil_space_remove_from_keyrotation(space); + } + + return NULL; + } + + if (!space) + { + space= UT_LIST_GET_FIRST(fil_system->rotation_list); + /* We can trust that space is not NULL because we + checked list length above */ + } + else + { + space->n_pending_ops--; + fil_space_t *old = space; + space= UT_LIST_GET_NEXT(rotation_list, space); + fil_space_remove_from_keyrotation(old); + } + + /* Skip spaces that are being created by fil_ibd_create(), + or dropped. Note that rotation_list contains only + space->purpose == FIL_TABLESPACE. */ + while (space && (!UT_LIST_GET_LEN(space->chain) || space->is_stopping())) + { + fil_space_t *old = space; + space= UT_LIST_GET_NEXT(rotation_list, space); + fil_space_remove_from_keyrotation(old); + } + + if (space) + space->n_pending_ops++; + + return space; +} + +/** Return the next tablespace. +@param space previous tablespace (NULL to start from the beginning) +@return pointer to the next tablespace (with n_pending_ops incremented) +@retval NULL if this was the last */ +static fil_space_t *fil_space_next(fil_space_t *space) +{ + mutex_enter(&fil_system->mutex); + ut_ad(!space || space->n_pending_ops); + + if (!srv_fil_crypt_rotate_key_age) + space= fil_space_keyrotate_next(space); + else if (!space) + { + space= UT_LIST_GET_FIRST(fil_system->space_list); + /* We can trust that space is not NULL because at least the + system tablespace is always present and loaded first. */ + space->n_pending_ops++; + } + else + { + ut_ad(space->n_pending_ops > 0); + /* Move on to the next fil_space_t */ + space->n_pending_ops--; + space= UT_LIST_GET_NEXT(space_list, space); + + /* Skip abnormal tablespaces or those that are being created by + fil_ibd_create(), or being dropped. */ + while (space && + (UT_LIST_GET_LEN(space->chain) == 0 || + space->is_stopping() || space->purpose != FIL_TABLESPACE)) + space= UT_LIST_GET_NEXT(space_list, space); + + if (space) + space->n_pending_ops++; + } + + mutex_exit(&fil_system->mutex); + + return space; +} + /*********************************************************************** Search for a space needing rotation @param[in,out] key_state Key state @@ -1485,14 +1577,7 @@ fil_crypt_find_space_to_rotate( state->space = NULL; } - /* If key rotation is enabled (default) we iterate all tablespaces. - If key rotation is not enabled we iterate only the tablespaces - added to keyrotation list. */ - if (srv_fil_crypt_rotate_key_age) { - state->space = fil_space_next(state->space); - } else { - state->space = fil_space_keyrotate_next(state->space); - } + state->space = fil_space_next(state->space); while (!state->should_shutdown() && state->space) { fil_crypt_read_crypt_data(state->space); @@ -1505,14 +1590,15 @@ fil_crypt_find_space_to_rotate( return true; } - if (srv_fil_crypt_rotate_key_age) { - state->space = fil_space_next(state->space); - } else { - state->space = fil_space_keyrotate_next(state->space); - } + state->space = fil_space_next(state->space); } - /* if we didn't find any space return iops */ + if (state->space) { + fil_space_release(state->space); + state->space = NULL; + } + + /* no work to do; release our allocation of I/O capacity */ fil_crypt_return_iops(state); return false; diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc index 62fb8deaf72..e3ba8dc7dac 100644 --- a/storage/innobase/fil/fil0fil.cc +++ b/storage/innobase/fil/fil0fil.cc @@ -6476,137 +6476,3 @@ fil_space_release_for_io(fil_space_t* space) space->n_pending_ios--; mutex_exit(&fil_system->mutex); } - -/** Return the next fil_space_t. -Once started, the caller must keep calling this until it returns NULL. -fil_space_acquire() and fil_space_release() are invoked here which -blocks a concurrent operation from dropping the tablespace. -@param[in] prev_space Pointer to the previous fil_space_t. -If NULL, use the first fil_space_t on fil_system->space_list. -@return pointer to the next fil_space_t. -@retval NULL if this was the last*/ -UNIV_INTERN -fil_space_t* -fil_space_next(fil_space_t* prev_space) -{ - fil_space_t* space=prev_space; - - mutex_enter(&fil_system->mutex); - - if (prev_space == NULL) { - space = UT_LIST_GET_FIRST(fil_system->space_list); - - /* We can trust that space is not NULL because at least the - system tablespace is always present and loaded first. */ - space->n_pending_ops++; - } else { - ut_ad(space->n_pending_ops > 0); - - /* Move on to the next fil_space_t */ - space->n_pending_ops--; - space = UT_LIST_GET_NEXT(space_list, space); - - /* Skip spaces that are being created by - fil_ibd_create(), or dropped, or !tablespace. */ - while (space != NULL - && (UT_LIST_GET_LEN(space->chain) == 0 - || space->is_stopping() - || space->purpose != FIL_TABLESPACE)) { - space = UT_LIST_GET_NEXT(space_list, space); - } - - if (space != NULL) { - space->n_pending_ops++; - } - } - - mutex_exit(&fil_system->mutex); - - return(space); -} - -/** -Remove space from key rotation list if there are no more -pending operations. -@param[in] space Tablespace */ -static -void -fil_space_remove_from_keyrotation( - fil_space_t* space) -{ - ut_ad(mutex_own(&fil_system->mutex)); - ut_ad(space); - - if (space->n_pending_ops == 0 && space->is_in_rotation_list) { - space->is_in_rotation_list = false; - ut_a(UT_LIST_GET_LEN(fil_system->rotation_list) > 0); - UT_LIST_REMOVE(rotation_list, fil_system->rotation_list, space); - } -} - - -/** Return the next fil_space_t from key rotation list. -Once started, the caller must keep calling this until it returns NULL. -fil_space_acquire() and fil_space_release() are invoked here which -blocks a concurrent operation from dropping the tablespace. -@param[in] prev_space Pointer to the previous fil_space_t. -If NULL, use the first fil_space_t on fil_system->space_list. -@return pointer to the next fil_space_t. -@retval NULL if this was the last*/ -UNIV_INTERN -fil_space_t* -fil_space_keyrotate_next( - fil_space_t* prev_space) -{ - fil_space_t* space = prev_space; - fil_space_t* old = NULL; - - mutex_enter(&fil_system->mutex); - - if (UT_LIST_GET_LEN(fil_system->rotation_list) == 0) { - if (space) { - ut_ad(space->n_pending_ops > 0); - space->n_pending_ops--; - fil_space_remove_from_keyrotation(space); - } - mutex_exit(&fil_system->mutex); - return(NULL); - } - - if (prev_space == NULL) { - space = UT_LIST_GET_FIRST(fil_system->rotation_list); - - /* We can trust that space is not NULL because we - checked list length above */ - } else { - ut_ad(space->n_pending_ops > 0); - - /* Move on to the next fil_space_t */ - space->n_pending_ops--; - - old = space; - space = UT_LIST_GET_NEXT(rotation_list, space); - - fil_space_remove_from_keyrotation(old); - } - - /* Skip spaces that are being created by fil_ibd_create(), - or dropped. Note that rotation_list contains only - space->purpose == FIL_TABLESPACE. */ - while (space != NULL - && (UT_LIST_GET_LEN(space->chain) == 0 - || space->is_stopping())) { - - old = space; - space = UT_LIST_GET_NEXT(rotation_list, space); - fil_space_remove_from_keyrotation(old); - } - - if (space != NULL) { - space->n_pending_ops++; - } - - mutex_exit(&fil_system->mutex); - - return(space); -} diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h index 5b11a026cf9..74d0673ccfc 100644 --- a/storage/innobase/include/fil0fil.h +++ b/storage/innobase/include/fil0fil.h @@ -699,34 +699,6 @@ UNIV_INTERN void fil_space_release_for_io(fil_space_t* space); -/** Return the next fil_space_t. -Once started, the caller must keep calling this until it returns NULL. -fil_space_acquire() and fil_space_release() are invoked here which -blocks a concurrent operation from dropping the tablespace. -@param[in,out] prev_space Pointer to the previous fil_space_t. -If NULL, use the first fil_space_t on fil_system->space_list. -@return pointer to the next fil_space_t. -@retval NULL if this was the last */ -UNIV_INTERN -fil_space_t* -fil_space_next( - fil_space_t* prev_space) - MY_ATTRIBUTE((warn_unused_result)); - -/** Return the next fil_space_t from key rotation list. -Once started, the caller must keep calling this until it returns NULL. -fil_space_acquire() and fil_space_release() are invoked here which -blocks a concurrent operation from dropping the tablespace. -@param[in,out] prev_space Pointer to the previous fil_space_t. -If NULL, use the first fil_space_t on fil_system->space_list. -@return pointer to the next fil_space_t. -@retval NULL if this was the last*/ -UNIV_INTERN -fil_space_t* -fil_space_keyrotate_next( - fil_space_t* prev_space) - MY_ATTRIBUTE((warn_unused_result)); - /** Wrapper with reference-counting for a fil_space_t. */ class FilSpace { diff --git a/storage/xtradb/fil/fil0crypt.cc b/storage/xtradb/fil/fil0crypt.cc index 901b28c8c62..fc7ef41786e 100644 --- a/storage/xtradb/fil/fil0crypt.cc +++ b/storage/xtradb/fil/fil0crypt.cc @@ -44,15 +44,8 @@ Modified Jan Lindström jan.lindstrom@mariadb.com #include "ha_prototypes.h" // IB_LOG_ #include -/** Mutex for keys */ -static ib_mutex_t fil_crypt_key_mutex; - static bool fil_crypt_threads_inited = false; -#ifdef UNIV_PFS_MUTEX -static mysql_pfs_key_t fil_crypt_key_mutex_key; -#endif - /** Is encryption enabled/disabled */ UNIV_INTERN ulong srv_encrypt_tables = 0; @@ -133,9 +126,6 @@ UNIV_INTERN void fil_space_crypt_init() { - mutex_create(fil_crypt_key_mutex_key, - &fil_crypt_key_mutex, SYNC_NO_ORDER_CHECK); - fil_crypt_throttle_sleep_event = os_event_create(); mutex_create(fil_crypt_stat_mutex_key, @@ -152,7 +142,6 @@ fil_space_crypt_cleanup() { os_event_free(fil_crypt_throttle_sleep_event); fil_crypt_throttle_sleep_event = NULL; - mutex_free(&fil_crypt_key_mutex); mutex_free(&crypt_stat_mutex); } @@ -1451,6 +1440,109 @@ fil_crypt_return_iops( fil_crypt_update_total_stat(state); } +/** Remove space from key rotation list if there are no pending operations. */ +static void fil_space_remove_from_keyrotation(fil_space_t *space) +{ + ut_ad(mutex_own(&fil_system->mutex)); + + if (space->n_pending_ops == 0 && space->is_in_rotation_list) + { + space->is_in_rotation_list= false; + ut_a(UT_LIST_GET_LEN(fil_system->rotation_list) > 0); + UT_LIST_REMOVE(rotation_list, fil_system->rotation_list, space); + } +} + +/** Return the next tablespace from key rotation list. +@param space previous tablespace (NULL to start from the beginning) +@return pointer to the next tablespace (with n_pending_ops incremented) +@retval NULL if this was the last */ +static fil_space_t *fil_space_keyrotate_next(fil_space_t *space) +{ + ut_ad(mutex_own(&fil_system->mutex)); + + if (UT_LIST_GET_LEN(fil_system->rotation_list) == 0) + { + if (space) + { + space->n_pending_ops--; + fil_space_remove_from_keyrotation(space); + } + + return NULL; + } + + if (!space) + { + space= UT_LIST_GET_FIRST(fil_system->rotation_list); + /* We can trust that space is not NULL because we + checked list length above */ + } + else + { + space->n_pending_ops--; + fil_space_t *old = space; + space= UT_LIST_GET_NEXT(rotation_list, space); + fil_space_remove_from_keyrotation(old); + } + + /* Skip spaces that are being created by fil_ibd_create(), + or dropped. Note that rotation_list contains only + space->purpose == FIL_TABLESPACE. */ + while (space && (!UT_LIST_GET_LEN(space->chain) || space->is_stopping())) + { + fil_space_t *old = space; + space= UT_LIST_GET_NEXT(rotation_list, space); + fil_space_remove_from_keyrotation(old); + } + + if (space) + space->n_pending_ops++; + + return space; +} + +/** Return the next tablespace. +@param space previous tablespace (NULL to start from the beginning) +@return pointer to the next tablespace (with n_pending_ops incremented) +@retval NULL if this was the last */ +static fil_space_t *fil_space_next(fil_space_t *space) +{ + mutex_enter(&fil_system->mutex); + ut_ad(!space || space->n_pending_ops); + + if (!srv_fil_crypt_rotate_key_age) + space= fil_space_keyrotate_next(space); + else if (!space) + { + space= UT_LIST_GET_FIRST(fil_system->space_list); + /* We can trust that space is not NULL because at least the + system tablespace is always present and loaded first. */ + space->n_pending_ops++; + } + else + { + ut_ad(space->n_pending_ops > 0); + /* Move on to the next fil_space_t */ + space->n_pending_ops--; + space= UT_LIST_GET_NEXT(space_list, space); + + /* Skip abnormal tablespaces or those that are being created by + fil_ibd_create(), or being dropped. */ + while (space && + (UT_LIST_GET_LEN(space->chain) == 0 || + space->is_stopping() || space->purpose != FIL_TABLESPACE)) + space= UT_LIST_GET_NEXT(space_list, space); + + if (space) + space->n_pending_ops++; + } + + mutex_exit(&fil_system->mutex); + + return space; +} + /*********************************************************************** Search for a space needing rotation @param[in,out] key_state Key state @@ -1485,14 +1577,7 @@ fil_crypt_find_space_to_rotate( state->space = NULL; } - /* If key rotation is enabled (default) we iterate all tablespaces. - If key rotation is not enabled we iterate only the tablespaces - added to keyrotation list. */ - if (srv_fil_crypt_rotate_key_age) { - state->space = fil_space_next(state->space); - } else { - state->space = fil_space_keyrotate_next(state->space); - } + state->space = fil_space_next(state->space); while (!state->should_shutdown() && state->space) { fil_crypt_read_crypt_data(state->space); @@ -1505,14 +1590,15 @@ fil_crypt_find_space_to_rotate( return true; } - if (srv_fil_crypt_rotate_key_age) { - state->space = fil_space_next(state->space); - } else { - state->space = fil_space_keyrotate_next(state->space); - } + state->space = fil_space_next(state->space); } - /* if we didn't find any space return iops */ + if (state->space) { + fil_space_release(state->space); + state->space = NULL; + } + + /* no work to do; release our allocation of I/O capacity */ fil_crypt_return_iops(state); return false; diff --git a/storage/xtradb/fil/fil0fil.cc b/storage/xtradb/fil/fil0fil.cc index b5ccb533af8..41bc4cca8a6 100644 --- a/storage/xtradb/fil/fil0fil.cc +++ b/storage/xtradb/fil/fil0fil.cc @@ -6863,137 +6863,3 @@ fil_space_release(fil_space_t* space) space->n_pending_ops--; mutex_exit(&fil_system->mutex); } - -/** Return the next fil_space_t. -Once started, the caller must keep calling this until it returns NULL. -fil_space_acquire() and fil_space_release() are invoked here which -blocks a concurrent operation from dropping the tablespace. -@param[in] prev_space Pointer to the previous fil_space_t. -If NULL, use the first fil_space_t on fil_system->space_list. -@return pointer to the next fil_space_t. -@retval NULL if this was the last*/ -UNIV_INTERN -fil_space_t* -fil_space_next(fil_space_t* prev_space) -{ - fil_space_t* space=prev_space; - - mutex_enter(&fil_system->mutex); - - if (prev_space == NULL) { - space = UT_LIST_GET_FIRST(fil_system->space_list); - - /* We can trust that space is not NULL because at least the - system tablespace is always present and loaded first. */ - space->n_pending_ops++; - } else { - ut_ad(space->n_pending_ops > 0); - - /* Move on to the next fil_space_t */ - space->n_pending_ops--; - space = UT_LIST_GET_NEXT(space_list, space); - - /* Skip spaces that are being created by - fil_ibd_create(), or dropped, or !tablespace. */ - while (space != NULL - && (UT_LIST_GET_LEN(space->chain) == 0 - || space->is_stopping() - || space->purpose != FIL_TABLESPACE)) { - space = UT_LIST_GET_NEXT(space_list, space); - } - - if (space != NULL) { - space->n_pending_ops++; - } - } - - mutex_exit(&fil_system->mutex); - - return(space); -} - -/** -Remove space from key rotation list if there are no more -pending operations. -@param[in] space Tablespace */ -static -void -fil_space_remove_from_keyrotation( - fil_space_t* space) -{ - ut_ad(mutex_own(&fil_system->mutex)); - ut_ad(space); - - if (space->n_pending_ops == 0 && space->is_in_rotation_list) { - space->is_in_rotation_list = false; - ut_a(UT_LIST_GET_LEN(fil_system->rotation_list) > 0); - UT_LIST_REMOVE(rotation_list, fil_system->rotation_list, space); - } -} - - -/** Return the next fil_space_t from key rotation list. -Once started, the caller must keep calling this until it returns NULL. -fil_space_acquire() and fil_space_release() are invoked here which -blocks a concurrent operation from dropping the tablespace. -@param[in] prev_space Pointer to the previous fil_space_t. -If NULL, use the first fil_space_t on fil_system->space_list. -@return pointer to the next fil_space_t. -@retval NULL if this was the last*/ -UNIV_INTERN -fil_space_t* -fil_space_keyrotate_next( - fil_space_t* prev_space) -{ - fil_space_t* space = prev_space; - fil_space_t* old = NULL; - - mutex_enter(&fil_system->mutex); - - if (UT_LIST_GET_LEN(fil_system->rotation_list) == 0) { - if (space) { - ut_ad(space->n_pending_ops > 0); - space->n_pending_ops--; - fil_space_remove_from_keyrotation(space); - } - mutex_exit(&fil_system->mutex); - return(NULL); - } - - if (prev_space == NULL) { - space = UT_LIST_GET_FIRST(fil_system->rotation_list); - - /* We can trust that space is not NULL because we - checked list length above */ - } else { - ut_ad(space->n_pending_ops > 0); - - /* Move on to the next fil_space_t */ - space->n_pending_ops--; - - old = space; - space = UT_LIST_GET_NEXT(rotation_list, space); - - fil_space_remove_from_keyrotation(old); - } - - /* Skip spaces that are being created by fil_ibd_create(), - or dropped. Note that rotation_list contains only - space->purpose == FIL_TABLESPACE. */ - while (space != NULL - && (UT_LIST_GET_LEN(space->chain) == 0 - || space->is_stopping())) { - - old = space; - space = UT_LIST_GET_NEXT(rotation_list, space); - fil_space_remove_from_keyrotation(old); - } - - if (space != NULL) { - space->n_pending_ops++; - } - - mutex_exit(&fil_system->mutex); - - return(space); -} diff --git a/storage/xtradb/include/fil0fil.h b/storage/xtradb/include/fil0fil.h index 6a823e131ac..78878fa75fc 100644 --- a/storage/xtradb/include/fil0fil.h +++ b/storage/xtradb/include/fil0fil.h @@ -705,34 +705,6 @@ UNIV_INTERN void fil_space_release_for_io(fil_space_t* space); -/** Return the next fil_space_t. -Once started, the caller must keep calling this until it returns NULL. -fil_space_acquire() and fil_space_release() are invoked here which -blocks a concurrent operation from dropping the tablespace. -@param[in,out] prev_space Pointer to the previous fil_space_t. -If NULL, use the first fil_space_t on fil_system->space_list. -@return pointer to the next fil_space_t. -@retval NULL if this was the last */ -UNIV_INTERN -fil_space_t* -fil_space_next( - fil_space_t* prev_space) - MY_ATTRIBUTE((warn_unused_result)); - -/** Return the next fil_space_t from key rotation list. -Once started, the caller must keep calling this until it returns NULL. -fil_space_acquire() and fil_space_release() are invoked here which -blocks a concurrent operation from dropping the tablespace. -@param[in,out] prev_space Pointer to the previous fil_space_t. -If NULL, use the first fil_space_t on fil_system->space_list. -@return pointer to the next fil_space_t. -@retval NULL if this was the last*/ -UNIV_INTERN -fil_space_t* -fil_space_keyrotate_next( - fil_space_t* prev_space) - MY_ATTRIBUTE((warn_unused_result)); - /** Wrapper with reference-counting for a fil_space_t. */ class FilSpace { From debd36c880bf088363350a31c580ee0c7ee92e42 Mon Sep 17 00:00:00 2001 From: Daniel Bartholomew Date: Mon, 10 Aug 2020 10:23:10 -0400 Subject: [PATCH 24/26] bump the VERSION --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index ed8554d24d9..d010acbf85d 100644 --- a/VERSION +++ b/VERSION @@ -1,3 +1,3 @@ MYSQL_VERSION_MAJOR=10 MYSQL_VERSION_MINOR=2 -MYSQL_VERSION_PATCH=33 +MYSQL_VERSION_PATCH=34 From c19335ea5359923c918b07ef9892c14408414b4d Mon Sep 17 00:00:00 2001 From: Daniel Bartholomew Date: Mon, 10 Aug 2020 10:26:37 -0400 Subject: [PATCH 25/26] bump the VERSION --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 19a3d95ed2d..5f8bdaf364f 100644 --- a/VERSION +++ b/VERSION @@ -1,4 +1,4 @@ MYSQL_VERSION_MAJOR=10 MYSQL_VERSION_MINOR=3 -MYSQL_VERSION_PATCH=24 +MYSQL_VERSION_PATCH=25 SERVER_MATURITY=stable From 2b9c53102c7c7428279c5fd02f771d335b5c53dc Mon Sep 17 00:00:00 2001 From: Daniel Bartholomew Date: Mon, 10 Aug 2020 10:32:57 -0400 Subject: [PATCH 26/26] bump the VERSION --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index de6b7b10f3f..bbdcc6a4ee3 100644 --- a/VERSION +++ b/VERSION @@ -1,4 +1,4 @@ MYSQL_VERSION_MAJOR=10 MYSQL_VERSION_MINOR=4 -MYSQL_VERSION_PATCH=14 +MYSQL_VERSION_PATCH=15 SERVER_MATURITY=stable