From 034ababa508615fc4ad1a047703ef21f6926d677 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Fri, 3 May 2024 11:41:58 +1000 Subject: [PATCH 01/31] MDEV-34053 mariadbbackup privilege REPLICA MONITOR issue MariaDB-backup needs to check for SLAVE MONITOR as that is what is returned by SHOW GRANTS. Update test to ensure that warnings about missing privileges do not occur when the backup is successful. Reviewer: Andrew Hutchings Thanks Eugene for reporting the issue. --- extra/mariabackup/xtrabackup.cc | 2 +- .../suite/mariabackup/backup_grants.result | 9 ++++-- .../suite/mariabackup/backup_grants.test | 29 +++++++++++++------ 3 files changed, 28 insertions(+), 12 deletions(-) diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc index 500ae683d80..c126d0b5b7c 100644 --- a/extra/mariabackup/xtrabackup.cc +++ b/extra/mariabackup/xtrabackup.cc @@ -6413,7 +6413,7 @@ static bool check_all_privileges() if (opt_galera_info || opt_slave_info || opt_safe_slave_backup) { check_result |= check_privilege(granted_privileges, - "REPLICA MONITOR", "*", "*", + "SLAVE MONITOR", "*", "*", PRIVILEGE_WARNING); } diff --git a/mysql-test/suite/mariabackup/backup_grants.result b/mysql-test/suite/mariabackup/backup_grants.result index 77cc3dd65d1..1dc3cc332dd 100644 --- a/mysql-test/suite/mariabackup/backup_grants.result +++ b/mysql-test/suite/mariabackup/backup_grants.result @@ -1,15 +1,20 @@ CREATE user backup@localhost IDENTIFIED BY 'xyz'; +NOT FOUND /missing required privilege/ in backup.log FOUND 1 /missing required privilege RELOAD/ in backup.log FOUND 1 /missing required privilege PROCESS/ in backup.log FOUND 1 /GRANT USAGE ON/ in backup.log GRANT RELOAD, PROCESS on *.* to backup@localhost; -FOUND 1 /missing required privilege REPLICA MONITOR/ in backup.log +NOT FOUND /missing required privilege/ in backup.log +FOUND 1 /missing required privilege SLAVE MONITOR/ in backup.log GRANT REPLICA MONITOR ON *.* TO backup@localhost; +NOT FOUND /missing required privilege/ in backup.log REVOKE REPLICA MONITOR ON *.* FROM backup@localhost; FOUND 1 /missing required privilege CONNECTION ADMIN/ in backup.log GRANT CONNECTION ADMIN ON *.* TO backup@localhost; +NOT FOUND /missing required privilege/ in backup.log FOUND 1 /missing required privilege REPLICATION SLAVE ADMIN/ in backup.log -FOUND 1 /missing required privilege REPLICA MONITOR/ in backup.log +FOUND 1 /missing required privilege SLAVE MONITOR/ in backup.log GRANT REPLICATION SLAVE ADMIN ON *.* TO backup@localhost; GRANT REPLICA MONITOR ON *.* TO backup@localhost; +NOT FOUND /missing required privilege/ in backup.log DROP USER backup@localhost; diff --git a/mysql-test/suite/mariabackup/backup_grants.test b/mysql-test/suite/mariabackup/backup_grants.test index 7b8c9b39b57..20a028ebc53 100644 --- a/mysql-test/suite/mariabackup/backup_grants.test +++ b/mysql-test/suite/mariabackup/backup_grants.test @@ -1,10 +1,14 @@ let $targetdir=$MYSQLTEST_VARDIR/tmp/backup; CREATE user backup@localhost IDENTIFIED BY 'xyz'; +let SEARCH_FILE=$MYSQLTEST_VARDIR/tmp/backup.log; # backup possible for unprivileges user, with --no-lock --disable_result_log -exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup -ubackup -pxyz --no-lock --target-dir=$targetdir; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup -ubackup -pxyz --no-lock --target-dir=$targetdir > $MYSQLTEST_VARDIR/tmp/backup.log 2>&1; --enable_result_log + +--let SEARCH_PATTERN= missing required privilege +--source include/search_pattern_in_file.inc rmdir $targetdir; # backup fails without --no-lock, because of FTWRL @@ -13,7 +17,6 @@ error 1; exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup -ubackup -pxyz --target-dir=$targetdir > $MYSQLTEST_VARDIR/tmp/backup.log 2>&1; --enable_result_log -let SEARCH_FILE=$MYSQLTEST_VARDIR/tmp/backup.log; --let SEARCH_PATTERN= missing required privilege RELOAD --source include/search_pattern_in_file.inc --let SEARCH_PATTERN= missing required privilege PROCESS @@ -23,25 +26,29 @@ let SEARCH_FILE=$MYSQLTEST_VARDIR/tmp/backup.log; # backup succeeds with RELOAD privilege GRANT RELOAD, PROCESS on *.* to backup@localhost; --disable_result_log -exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --user=backup --password=xyz --target-dir=$targetdir; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --user=backup --password=xyz --target-dir=$targetdir > $MYSQLTEST_VARDIR/tmp/backup.log 2>&1; --enable_result_log +--let SEARCH_PATTERN= missing required privilege +--source include/search_pattern_in_file.inc rmdir $targetdir; # MDEV-23607 Warning: missing required privilege REPLICATION CLIENT -# --slave-info and galera info require REPLICA MONITOR +# --slave-info and --galera-info require REPLICA MONITOR --disable_result_log error 1; exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --user backup --password xyz --slave-info --target-dir=$targetdir > $MYSQLTEST_VARDIR/tmp/backup.log 2>&1; --enable_result_log rmdir $targetdir; ---let SEARCH_PATTERN= missing required privilege REPLICA MONITOR +--let SEARCH_PATTERN= missing required privilege SLAVE MONITOR --source include/search_pattern_in_file.inc GRANT REPLICA MONITOR ON *.* TO backup@localhost; --disable_result_log -exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup -ubackup -pxyz --slave-info --target-dir=$targetdir; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup -ubackup -pxyz --slave-info --target-dir=$targetdir > $MYSQLTEST_VARDIR/tmp/backup.log 2>&1; --enable_result_log +--let SEARCH_PATTERN= missing required privilege +--source include/search_pattern_in_file.inc rmdir $targetdir; REVOKE REPLICA MONITOR ON *.* FROM backup@localhost; @@ -59,8 +66,10 @@ rmdir $targetdir; GRANT CONNECTION ADMIN ON *.* TO backup@localhost; --disable_result_log -exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --user=backup --password=xyz --kill-long-query-type=all --kill-long-queries-timeout=1 --target-dir=$targetdir; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup -ubackup --password=xyz --kill-long-query-type=all --kill-long-queries-timeout=1 --target-dir=$targetdir > $MYSQLTEST_VARDIR/tmp/backup.log 2>&1; --enable_result_log +--let SEARCH_PATTERN= missing required privilege +--source include/search_pattern_in_file.inc rmdir $targetdir; # --safe-slave-backup requires REPLICATION SLAVE ADMIN, and REPLICA MONITOR @@ -72,14 +81,16 @@ rmdir $targetdir; --let SEARCH_PATTERN= missing required privilege REPLICATION SLAVE ADMIN --source include/search_pattern_in_file.inc ---let SEARCH_PATTERN= missing required privilege REPLICA MONITOR +--let SEARCH_PATTERN= missing required privilege SLAVE MONITOR --source include/search_pattern_in_file.inc GRANT REPLICATION SLAVE ADMIN ON *.* TO backup@localhost; GRANT REPLICA MONITOR ON *.* TO backup@localhost; --disable_result_log -exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup -ubackup -pxyz --safe-slave-backup --target-dir=$targetdir; +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup -ubackup -pxyz --safe-slave-backup --target-dir=$targetdir > $MYSQLTEST_VARDIR/tmp/backup.log 2>&1; --enable_result_log +--let SEARCH_PATTERN= missing required privilege +--source include/search_pattern_in_file.inc rmdir $targetdir; DROP USER backup@localhost; From 867747204afd4a94885fdbdb2a1442ca35001f93 Mon Sep 17 00:00:00 2001 From: He Guohua <3803657@qq.com> Date: Tue, 7 May 2024 13:52:15 +0800 Subject: [PATCH 02/31] MDEV-31566 Fix buffer overrun of column_json function The accounting of the limit variable that represents the amount of space left it the buffer was incorrect. Also there was 1 or 2 bytes left to write that occured without the buffer length being checked. Review: Sanja Byelkin --- mysql-test/main/dyncol.result | 15 ++++++++------- mysql-test/main/dyncol.test | 15 ++++++--------- mysys/ma_dyncol.c | 17 +++++++++-------- 3 files changed, 23 insertions(+), 24 deletions(-) diff --git a/mysql-test/main/dyncol.result b/mysql-test/main/dyncol.result index eb1e0464570..d070ef8f626 100644 --- a/mysql-test/main/dyncol.result +++ b/mysql-test/main/dyncol.result @@ -1950,12 +1950,6 @@ ex # End of 10.4 tests # # -# Start of 10.5 tests -# -# -# Start of 10.5 tests -# -# # MDEV-33788 HEX(COLUMN_CREATE(.. AS CHAR ...)) fails with --view-protocol # SELECT hex(column_create(1,'a' AS CHAR CHARACTER SET utf8mb3 COLLATE utf8mb3_bin)) AS ex; @@ -1967,5 +1961,12 @@ SELECT hex(column_add(column_create( ex 00020001000302001353612162 # -# Start of 10.5 tests +# MDEV-31566 Fix buffer overrun of column_json function # +select column_json(0x0402000A0000000300030023076A736E7375626A6563742E0005006C0027000200290002002B0002002D0002002F0002000C31000C3B000C4B000C51000F62006631663266336634663509E5A79AE8BF9CE6B48B0FE8819AE9809AE98791E6A1A5E5BA970537343530301031313634332F393634352F31313630300C080000000000EFBFBDEFBFBD192E); +column_json(0x0402000A0000000300030023076A736E7375626A6563742E0005006C0027000200290002002B0002002D0002002F0002000C31000C3B000C4B000C51000F62006631663266336634663509E5A79AE8BF9CE6B48B0FE8819AE9809AE98791E6A1A5E5BA970537343530301031313634332F393634352F31313 +{"jsn":"\u0000\u0005\u0000l\u0000'\u0000\u0002\u0000)\u0000\u0002\u0000+\u0000\u0002\u0000-\u0000\u0002\u0000/\u0000\u0002\u0000\u000C1\u0000\u000C;\u0000\u000CK\u0000\u000CQ\u0000\u000Fb\u0000f1f2f3f4f5\u0009姚远洋\u000F聚通金桥店\u000574500\u001011643/9645/11600\u000C\u0008\u0000\u0000\u0000\u0000\u0000��\u0019","subject":""} +select column_json(0x0402000900000003000300740C6A736E766F6C756D652E000900EFBFBD004300020045000200470003004A0004004E00050053000500580005005D000500620005000C67000C6A000C6D000C7000052C00051B00052C000CEFBFBD0007EFBFBD006638663966313070696332626F785F63626F785F67626F785F6B626F785F7666355F696402343402343402333241687474703A2F2F6F73732E68646238382E636F6D2F302F70686F746F2F30373865653765376336343634616236386130343833373333323636613532612E67696608302E303532323732244F1E00030180C106); +column_json(0x0402000900000003000300740C6A736E766F6C756D652E000900EFBFBD004300020045000200470003004A0004004E00050053000500580005005D000500620005000C67000C6A000C6D000C7000052C00051B00052C000CEFBFBD0007EFBFBD006638663966313070696332626F785F63626F785F67626F7 +{"jsn":"\u0000\u0009\u0000�\u0000C\u0000\u0002\u0000E\u0000\u0002\u0000G\u0000\u0003\u0000J\u0000\u0004\u0000N\u0000\u0005\u0000S\u0000\u0005\u0000X\u0000\u0005\u0000]\u0000\u0005\u0000b\u0000\u0005\u0000\u000Cg\u0000\u000Cj\u0000\u000Cm\u0000\u000Cp\u0000\u0005,\u0000\u0005\u001B\u0000\u0005,\u0000\u000C�\u0000\u0007�\u0000f8f9f10pic2box_cbox_gbox_kbox_vf5_id\u000244\u000244\u000232Ahttp://oss.hdb88.com/0/photo/078ee7e7c6464ab68a0483733266a52a.gif\u00080.052272$O\u001E\u0000","volume":193.6} +# End of 10.5 tests diff --git a/mysql-test/main/dyncol.test b/mysql-test/main/dyncol.test index 16cf8a2306d..95121fef1e4 100644 --- a/mysql-test/main/dyncol.test +++ b/mysql-test/main/dyncol.test @@ -1001,14 +1001,6 @@ SELECT HEX(COLUMN_ADD(COLUMN_CREATE(1,10),2,NULL,1,NULL)) as ex; --echo # End of 10.4 tests --echo # ---echo # ---echo # Start of 10.5 tests ---echo # - ---echo # ---echo # Start of 10.5 tests ---echo # - --echo # --echo # MDEV-33788 HEX(COLUMN_CREATE(.. AS CHAR ...)) fails with --view-protocol --echo # @@ -1019,5 +1011,10 @@ SELECT hex(column_add(column_create( 2, 'b' AS CHAR CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci)) AS ex; --echo # ---echo # Start of 10.5 tests +--echo # MDEV-31566 Fix buffer overrun of column_json function --echo # + +select column_json(0x0402000A0000000300030023076A736E7375626A6563742E0005006C0027000200290002002B0002002D0002002F0002000C31000C3B000C4B000C51000F62006631663266336634663509E5A79AE8BF9CE6B48B0FE8819AE9809AE98791E6A1A5E5BA970537343530301031313634332F393634352F31313630300C080000000000EFBFBDEFBFBD192E); +select column_json(0x0402000900000003000300740C6A736E766F6C756D652E000900EFBFBD004300020045000200470003004A0004004E00050053000500580005005D000500620005000C67000C6A000C6D000C7000052C00051B00052C000CEFBFBD0007EFBFBD006638663966313070696332626F785F63626F785F67626F785F6B626F785F7666355F696402343402343402333241687474703A2F2F6F73732E68646238382E636F6D2F302F70686F746F2F30373865653765376336343634616236386130343833373333323636613532612E67696608302E303532323732244F1E00030180C106); + +--echo # End of 10.5 tests diff --git a/mysys/ma_dyncol.c b/mysys/ma_dyncol.c index 5ab7d28f915..013fcc913b4 100644 --- a/mysys/ma_dyncol.c +++ b/mysys/ma_dyncol.c @@ -3848,13 +3848,13 @@ my_bool dynstr_append_json_quoted(DYNAMIC_STRING *str, register char c= append[i]; if (unlikely(((uchar)c) <= 0x1F)) { - if (lim < 5) + if (lim < 6) { if (dynstr_realloc(str, additional)) return TRUE; lim+= additional; } - lim-= 5; + lim -= 6; str->str[str->length++]= '\\'; str->str[str->length++]= 'u'; str->str[str->length++]= '0'; @@ -3865,17 +3865,18 @@ my_bool dynstr_append_json_quoted(DYNAMIC_STRING *str, } else { + if (lim < 2) + { + if (dynstr_realloc(str, additional)) + return TRUE; + lim += additional; + } if (c == '"' || c == '\\') { - if (!lim) - { - if (dynstr_realloc(str, additional)) - return TRUE; - lim= additional; - } lim--; str->str[str->length++]= '\\'; } + lim--; str->str[str->length++]= c; } } From d7d8c2c287f8496091070007950a17e5bd2b5c84 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Fri, 10 May 2024 11:17:46 +1000 Subject: [PATCH 03/31] MDEV-31566: Fix buffer overrun of column_json function (postfix) Test case failed --view protocol. Revert to using table for data in the test. --- mysql-test/main/dyncol.result | 16 ++++++++++------ mysql-test/main/dyncol.test | 12 ++++++++++-- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/mysql-test/main/dyncol.result b/mysql-test/main/dyncol.result index d070ef8f626..4b216e77a66 100644 --- a/mysql-test/main/dyncol.result +++ b/mysql-test/main/dyncol.result @@ -1963,10 +1963,14 @@ ex # # MDEV-31566 Fix buffer overrun of column_json function # -select column_json(0x0402000A0000000300030023076A736E7375626A6563742E0005006C0027000200290002002B0002002D0002002F0002000C31000C3B000C4B000C51000F62006631663266336634663509E5A79AE8BF9CE6B48B0FE8819AE9809AE98791E6A1A5E5BA970537343530301031313634332F393634352F31313630300C080000000000EFBFBDEFBFBD192E); -column_json(0x0402000A0000000300030023076A736E7375626A6563742E0005006C0027000200290002002B0002002D0002002F0002000C31000C3B000C4B000C51000F62006631663266336634663509E5A79AE8BF9CE6B48B0FE8819AE9809AE98791E6A1A5E5BA970537343530301031313634332F393634352F31313 -{"jsn":"\u0000\u0005\u0000l\u0000'\u0000\u0002\u0000)\u0000\u0002\u0000+\u0000\u0002\u0000-\u0000\u0002\u0000/\u0000\u0002\u0000\u000C1\u0000\u000C;\u0000\u000CK\u0000\u000CQ\u0000\u000Fb\u0000f1f2f3f4f5\u0009姚远洋\u000F聚通金桥店\u000574500\u001011643/9645/11600\u000C\u0008\u0000\u0000\u0000\u0000\u0000��\u0019","subject":""} -select column_json(0x0402000900000003000300740C6A736E766F6C756D652E000900EFBFBD004300020045000200470003004A0004004E00050053000500580005005D000500620005000C67000C6A000C6D000C7000052C00051B00052C000CEFBFBD0007EFBFBD006638663966313070696332626F785F63626F785F67626F785F6B626F785F7666355F696402343402343402333241687474703A2F2F6F73732E68646238382E636F6D2F302F70686F746F2F30373865653765376336343634616236386130343833373333323636613532612E67696608302E303532323732244F1E00030180C106); -column_json(0x0402000900000003000300740C6A736E766F6C756D652E000900EFBFBD004300020045000200470003004A0004004E00050053000500580005005D000500620005000C67000C6A000C6D000C7000052C00051B00052C000CEFBFBD0007EFBFBD006638663966313070696332626F785F63626F785F67626F7 -{"jsn":"\u0000\u0009\u0000�\u0000C\u0000\u0002\u0000E\u0000\u0002\u0000G\u0000\u0003\u0000J\u0000\u0004\u0000N\u0000\u0005\u0000S\u0000\u0005\u0000X\u0000\u0005\u0000]\u0000\u0005\u0000b\u0000\u0005\u0000\u000Cg\u0000\u000Cj\u0000\u000Cm\u0000\u000Cp\u0000\u0005,\u0000\u0005\u001B\u0000\u0005,\u0000\u000C�\u0000\u0007�\u0000f8f9f10pic2box_cbox_gbox_kbox_vf5_id\u000244\u000244\u000232Ahttp://oss.hdb88.com/0/photo/078ee7e7c6464ab68a0483733266a52a.gif\u00080.052272$O\u001E\u0000","volume":193.6} +create table t1 ( +c1 varchar(32) primary key, +d1 blob +); +insert into t1 values ('var', 0x0402000A0000000300030023076A736E7375626A6563742E0005006C0027000200290002002B0002002D0002002F0002000C31000C3B000C4B000C51000F62006631663266336634663509E5A79AE8BF9CE6B48B0FE8819AE9809AE98791E6A1A5E5BA970537343530301031313634332F393634352F31313630300C080000000000EFBFBDEFBFBD192E), ('zzz', 0x0402000900000003000300740C6A736E766F6C756D652E000900EFBFBD004300020045000200470003004A0004004E00050053000500580005005D000500620005000C67000C6A000C6D000C7000052C00051B00052C000CEFBFBD0007EFBFBD006638663966313070696332626F785F63626F785F67626F785F6B626F785F7666355F696402343402343402333241687474703A2F2F6F73732E68646238382E636F6D2F302F70686F746F2F30373865653765376336343634616236386130343833373333323636613532612E67696608302E303532323732244F1E00030180C106); +select c1,column_json(d1) as not_crashing from t1 order by c1; +c1 not_crashing +var {"jsn":"\u0000\u0005\u0000l\u0000'\u0000\u0002\u0000)\u0000\u0002\u0000+\u0000\u0002\u0000-\u0000\u0002\u0000/\u0000\u0002\u0000\u000C1\u0000\u000C;\u0000\u000CK\u0000\u000CQ\u0000\u000Fb\u0000f1f2f3f4f5\u0009姚远洋\u000F聚通金桥店\u000574500\u001011643/9645/11600\u000C\u0008\u0000\u0000\u0000\u0000\u0000��\u0019","subject":""} +zzz {"jsn":"\u0000\u0009\u0000�\u0000C\u0000\u0002\u0000E\u0000\u0002\u0000G\u0000\u0003\u0000J\u0000\u0004\u0000N\u0000\u0005\u0000S\u0000\u0005\u0000X\u0000\u0005\u0000]\u0000\u0005\u0000b\u0000\u0005\u0000\u000Cg\u0000\u000Cj\u0000\u000Cm\u0000\u000Cp\u0000\u0005,\u0000\u0005\u001B\u0000\u0005,\u0000\u000C�\u0000\u0007�\u0000f8f9f10pic2box_cbox_gbox_kbox_vf5_id\u000244\u000244\u000232Ahttp://oss.hdb88.com/0/photo/078ee7e7c6464ab68a0483733266a52a.gif\u00080.052272$O\u001E\u0000","volume":193.6} +drop table t1; # End of 10.5 tests diff --git a/mysql-test/main/dyncol.test b/mysql-test/main/dyncol.test index 95121fef1e4..0c1978a8fa0 100644 --- a/mysql-test/main/dyncol.test +++ b/mysql-test/main/dyncol.test @@ -1014,7 +1014,15 @@ SELECT hex(column_add(column_create( --echo # MDEV-31566 Fix buffer overrun of column_json function --echo # -select column_json(0x0402000A0000000300030023076A736E7375626A6563742E0005006C0027000200290002002B0002002D0002002F0002000C31000C3B000C4B000C51000F62006631663266336634663509E5A79AE8BF9CE6B48B0FE8819AE9809AE98791E6A1A5E5BA970537343530301031313634332F393634352F31313630300C080000000000EFBFBDEFBFBD192E); -select column_json(0x0402000900000003000300740C6A736E766F6C756D652E000900EFBFBD004300020045000200470003004A0004004E00050053000500580005005D000500620005000C67000C6A000C6D000C7000052C00051B00052C000CEFBFBD0007EFBFBD006638663966313070696332626F785F63626F785F67626F785F6B626F785F7666355F696402343402343402333241687474703A2F2F6F73732E68646238382E636F6D2F302F70686F746F2F30373865653765376336343634616236386130343833373333323636613532612E67696608302E303532323732244F1E00030180C106); + +create table t1 ( + c1 varchar(32) primary key, + d1 blob +); +insert into t1 values ('var', 0x0402000A0000000300030023076A736E7375626A6563742E0005006C0027000200290002002B0002002D0002002F0002000C31000C3B000C4B000C51000F62006631663266336634663509E5A79AE8BF9CE6B48B0FE8819AE9809AE98791E6A1A5E5BA970537343530301031313634332F393634352F31313630300C080000000000EFBFBDEFBFBD192E), ('zzz', 0x0402000900000003000300740C6A736E766F6C756D652E000900EFBFBD004300020045000200470003004A0004004E00050053000500580005005D000500620005000C67000C6A000C6D000C7000052C00051B00052C000CEFBFBD0007EFBFBD006638663966313070696332626F785F63626F785F67626F785F6B626F785F7666355F696402343402343402333241687474703A2F2F6F73732E68646238382E636F6D2F302F70686F746F2F30373865653765376336343634616236386130343833373333323636613532612E67696608302E303532323732244F1E00030180C106); + +select c1,column_json(d1) as not_crashing from t1 order by c1; + +drop table t1; --echo # End of 10.5 tests From 9ea1f67214ee081388612740507ffe6dd84c1a55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Sun, 12 May 2024 08:04:06 +0300 Subject: [PATCH 04/31] MDEV-33817: Proper intrinsics for vextracti32x4 --- mysys/crc32/crc32c_x86.cc | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/mysys/crc32/crc32c_x86.cc b/mysys/crc32/crc32c_x86.cc index 02dbf2920eb..317b3545c0c 100644 --- a/mysys/crc32/crc32c_x86.cc +++ b/mysys/crc32/crc32c_x86.cc @@ -173,19 +173,11 @@ static inline __m512i combine512(__m512i a, __m512i tab, __m512i b) # define and128(a, b) _mm_and_si128(a, b) template USE_VPCLMULQDQ -/** Pick a 128-bit component of a 512-bit vector */ +/** Pick and zero-extend 128 bits of a 512-bit vector (vextracti32x4) */ static inline __m512i extract512_128(__m512i a) { static_assert(bits <= 3, "usage"); -# if defined __GNUC__ && __GNUC__ >= 11 - /* While technically incorrect, this would seem to translate into a - vextracti32x4 instruction, which actually outputs a ZMM register - (anything above the XMM range is cleared). */ - return _mm512_castsi128_si512(_mm512_extracti64x2_epi64(a, bits)); -# else - /* On clang, this is needed in order to get a correct result. */ - return _mm512_maskz_shuffle_i64x2(3, a, a, bits); -# endif + return _mm512_zextsi128_si512(_mm512_extracti64x2_epi64(a, bits)); } alignas(16) static const uint64_t shuffle128[4] = { From 1e5b0ff9778b16801d5afa08b6433070948f0910 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 12 May 2024 10:13:15 +0200 Subject: [PATCH 05/31] mtr: don't store galera sst logs in /tmp/ --- mysql-test/suite/galera/galera_2nodes.cnf | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mysql-test/suite/galera/galera_2nodes.cnf b/mysql-test/suite/galera/galera_2nodes.cnf index 3532c1f2134..f1697c08149 100644 --- a/mysql-test/suite/galera/galera_2nodes.cnf +++ b/mysql-test/suite/galera/galera_2nodes.cnf @@ -33,6 +33,9 @@ wsrep_node_address='127.0.0.1:@mysqld.2.#galera_port' wsrep_node_incoming_address=127.0.0.1:@mysqld.2.port wsrep_sst_receive_address='127.0.0.1:@mysqld.2.#sst_port' +[sst] +sst-log-archive-dir=@ENV.MYSQLTEST_VARDIR/log + [ENV] NODE_MYPORT_1= @mysqld.1.port NODE_MYSOCK_1= @mysqld.1.socket From a6ae1c2dfb272008666d1f15dc9cb0cc06a5b82a Mon Sep 17 00:00:00 2001 From: Yuchen Pei Date: Mon, 13 May 2024 09:15:14 +1000 Subject: [PATCH 06/31] MDEV-32487 Check plugin is ready when resolving storage engine This handles the situation when one thread is still initiating a storage engine plugin, while another is creating a table using it. --- sql/handler.cc | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/sql/handler.cc b/sql/handler.cc index b12014b55ec..42e1c3e7212 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -291,13 +291,20 @@ redo: } +/* + Resolve the storage engine by name. + + Succeed if the storage engine is found and initialised. Otherwise + fail if the sql mode contains NO_ENGINE_SUBSTITUTION. +*/ bool Storage_engine_name::resolve_storage_engine_with_error(THD *thd, handlerton **ha, bool tmp_table) { - if (plugin_ref plugin= ha_resolve_by_name(thd, &m_storage_engine_name, - tmp_table)) + plugin_ref plugin; + if ((plugin= ha_resolve_by_name(thd, &m_storage_engine_name, tmp_table)) && + (plugin_ref_to_int(plugin)->state == PLUGIN_IS_READY)) { *ha= plugin_hton(plugin); return false; From fd76746234b480ce386e335533eefdab92795022 Mon Sep 17 00:00:00 2001 From: Yuchen Pei Date: Tue, 7 May 2024 13:49:17 +1000 Subject: [PATCH 07/31] MDEV-28105 Return error in ha_spider::write_row() if info(HA_STATUS_AUTO) fails Spider calls info with HA_STATUS_AUTO to update auto increment info, which may attempt to connect the data node. If the connection fails, it may emit an error and return the same error. This error should not be of lower priority than any possible error from the later call to handler::update_auto_increment(). Without this change, certain errors from update_auto_increment() such as HA_ERR_AUTOINC_ERANGE may get ignored, causing my_insert() to call my_ok(), which fails the assertion because the error was emitted in the info() call (Diagnostics_area::is_set() returns true). --- storage/spider/ha_spider.cc | 19 ++++++------------- .../spider/bugfix/r/mdev_28105.result | 10 ++++++++++ .../mysql-test/spider/bugfix/t/mdev_28105.opt | 1 + .../spider/bugfix/t/mdev_28105.test | 8 ++++++++ 4 files changed, 25 insertions(+), 13 deletions(-) create mode 100644 storage/spider/mysql-test/spider/bugfix/r/mdev_28105.result create mode 100644 storage/spider/mysql-test/spider/bugfix/t/mdev_28105.opt create mode 100644 storage/spider/mysql-test/spider/bugfix/t/mdev_28105.test diff --git a/storage/spider/ha_spider.cc b/storage/spider/ha_spider.cc index 997f57ab6c8..31498328535 100644 --- a/storage/spider/ha_spider.cc +++ b/storage/spider/ha_spider.cc @@ -9396,18 +9396,6 @@ int ha_spider::update_auto_increment() DBUG_ENTER("ha_spider::update_auto_increment"); DBUG_PRINT("info",("spider this=%p", this)); force_auto_increment = TRUE; -/* - if ( - next_insert_id >= auto_inc_interval_for_cur_row.maximum() && - wide_handler->trx->thd->auto_inc_intervals_forced.get_current() - ) { - force_auto_increment = TRUE; - DBUG_PRINT("info",("spider force_auto_increment=TRUE")); - } else { - force_auto_increment = FALSE; - DBUG_PRINT("info",("spider force_auto_increment=FALSE")); - } -*/ DBUG_PRINT("info",("spider auto_increment_mode=%d", auto_increment_mode)); DBUG_PRINT("info",("spider next_number_field=%lld", @@ -9662,7 +9650,12 @@ int ha_spider::write_row( pthread_mutex_lock(&share->lgtm_tblhnd_share->auto_increment_mutex); if (!share->lgtm_tblhnd_share->auto_increment_init) { - info(HA_STATUS_AUTO); + if ((error_num= info(HA_STATUS_AUTO))) + { + pthread_mutex_unlock( + &share->lgtm_tblhnd_share->auto_increment_mutex); + DBUG_RETURN(error_num); + } share->lgtm_tblhnd_share->auto_increment_lclval = stats.auto_increment_value; share->lgtm_tblhnd_share->auto_increment_init = TRUE; diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_28105.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_28105.result new file mode 100644 index 00000000000..1932f6b2624 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_28105.result @@ -0,0 +1,10 @@ +install soname 'ha_spider'; +Warnings: +Warning 1105 Cannot enable tc-log at run-time. XA features of SPIDER are disabled +SET @@insert_id=128; +CREATE TABLE t(c TINYINT AUTO_INCREMENT KEY) ENGINE=Spider; +INSERT IGNORE INTO t VALUES(0); +ERROR HY000: Unable to connect to foreign data source: localhost +drop table t; +Warnings: +Warning 1620 Plugin is busy and will be uninstalled on shutdown diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_28105.opt b/storage/spider/mysql-test/spider/bugfix/t/mdev_28105.opt new file mode 100644 index 00000000000..789275fa25e --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_28105.opt @@ -0,0 +1 @@ +--skip-log-bin diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_28105.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_28105.test new file mode 100644 index 00000000000..219835075ba --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_28105.test @@ -0,0 +1,8 @@ +install soname 'ha_spider'; +SET @@insert_id=128; # 127 does not crash +CREATE TABLE t(c TINYINT AUTO_INCREMENT KEY) ENGINE=Spider; +--error ER_CONNECT_TO_FOREIGN_DATA_SOURCE +INSERT IGNORE INTO t VALUES(0); +drop table t; +--disable_query_log +--source ../../include/clean_up_spider.inc From 7e65512ecc04a50cec9f7db7220546180e3e08f9 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 14 May 2024 13:31:53 +0200 Subject: [PATCH 08/31] cleanup: compile with -fno-operator-names in maintainer mode --- cmake/maintainer.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/maintainer.cmake b/cmake/maintainer.cmake index b4936ff57cc..d5ad2867f5b 100644 --- a/cmake/maintainer.cmake +++ b/cmake/maintainer.cmake @@ -43,7 +43,7 @@ FOREACH(F ${MY_WARNING_FLAGS}) MY_CHECK_AND_SET_COMPILER_FLAG(${F} DEBUG RELWITHDEBINFO) ENDFOREACH() -SET(MY_ERROR_FLAGS -Werror) +SET(MY_ERROR_FLAGS -Werror -fno-operator-names) IF(CMAKE_COMPILER_IS_GNUCC AND CMAKE_C_COMPILER_VERSION VERSION_LESS "6.0.0") SET(MY_ERROR_FLAGS ${MY_ERROR_FLAGS} -Wno-error=maybe-uninitialized) From 32ee6670a5c7dd98136989686f23a181110fbf03 Mon Sep 17 00:00:00 2001 From: Daniel Bartholomew Date: Wed, 15 May 2024 10:52:16 -0400 Subject: [PATCH 09/31] bump the VERSION --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 31ae1672cba..05e6832c930 100644 --- a/VERSION +++ b/VERSION @@ -1,4 +1,4 @@ MYSQL_VERSION_MAJOR=10 MYSQL_VERSION_MINOR=5 -MYSQL_VERSION_PATCH=25 +MYSQL_VERSION_PATCH=26 SERVER_MATURITY=stable From 4911ec1a5bc07ef20c9018386a3a2671c59c4dca Mon Sep 17 00:00:00 2001 From: Dave Gosselin Date: Wed, 15 May 2024 09:50:11 -0400 Subject: [PATCH 10/31] mtr on FreeBSD detects core count for --parallel=auto --- mysql-test/lib/My/Platform.pm | 11 ++++++++++- mysql-test/mysql-test-run.pl | 2 +- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/mysql-test/lib/My/Platform.pm b/mysql-test/lib/My/Platform.pm index f33875e14aa..279fea02ffb 100644 --- a/mysql-test/lib/My/Platform.pm +++ b/mysql-test/lib/My/Platform.pm @@ -23,7 +23,7 @@ use File::Path; use Carp; use base qw(Exporter); -our @EXPORT= qw(IS_CYGWIN IS_MSYS IS_WINDOWS IS_WIN32PERL IS_AIX IS_MAC +our @EXPORT= qw(IS_CYGWIN IS_MSYS IS_WINDOWS IS_WIN32PERL IS_AIX IS_MAC IS_FREEBSD native_path posix_path mixed_path check_socket_path_length process_alive open_for_append); @@ -79,6 +79,15 @@ BEGIN { } } +BEGIN { + if ($^O eq "freebsd") { + eval 'sub IS_FREEBSD { 1 }'; + } + else { + eval 'sub IS_FREEBSD { 0 }'; + } +} + # # native_path # Convert from path format used by perl to the underlying diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 117252cb6f0..d1ad3bdea77 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -427,7 +427,7 @@ sub main { { $opt_parallel= $ENV{NUMBER_OF_PROCESSORS} || 1; } - elsif (IS_MAC) + elsif (IS_MAC || IS_FREEBSD) { $opt_parallel= `sysctl -n hw.ncpu`; } From dc38d8ea80e3a8d650478b4407f49b4adede710b Mon Sep 17 00:00:00 2001 From: Robin Newhouse Date: Tue, 25 Jul 2023 20:13:33 +0000 Subject: [PATCH 11/31] Minimize unsafe C functions with safe_strcpy() Similar to #2480. 567b681 introduced safe_strcpy() to minimize the use of C with potentially unsafe memory overflow with strcpy() whose use is discouraged. Replace instances of strcpy() with safe_strcpy() where possible, limited here to files in the `sql/` directory. All new code of the whole pull request, including one or several files that are either new files or modified ones, are contributed under the BSD-new license. I am contributing on behalf of my employer Amazon Web Services, Inc. --- sql/gcalc_slicescan.cc | 2 +- sql/hostname.cc | 18 ++++++++++++------ sql/log.h | 4 ++-- sql/my_json_writer.cc | 14 +++----------- sql/mysql_install_db.cc | 4 ++-- sql/rpl_parallel.cc | 24 ++++++++++++++++-------- sql/rpl_rli.cc | 3 ++- sql/semisync_master.cc | 7 ++++--- sql/sql_connect.cc | 4 ++-- sql/sql_partition.cc | 2 +- sql/sql_plugin.cc | 7 ++++--- sql/sql_repl.cc | 2 +- 12 files changed, 50 insertions(+), 41 deletions(-) diff --git a/sql/gcalc_slicescan.cc b/sql/gcalc_slicescan.cc index b079bd7a714..662783ea4ea 100644 --- a/sql/gcalc_slicescan.cc +++ b/sql/gcalc_slicescan.cc @@ -144,7 +144,7 @@ static void GCALC_DBUG_PRINT_SLICE(const char *header, size_t nbuf; char buf[1024]; nbuf= strlen(header); - strcpy(buf, header); + safe_strcpy(buf, sizeof(buf), header); for (; slice; slice= slice->get_next()) { size_t lnbuf= nbuf; diff --git a/sql/hostname.cc b/sql/hostname.cc index 48677b5ef76..984c1a219ff 100644 --- a/sql/hostname.cc +++ b/sql/hostname.cc @@ -513,42 +513,48 @@ int ip_to_hostname(struct sockaddr_storage *ip_storage, DBUG_EXECUTE_IF("getnameinfo_error_noname", { - strcpy(hostname_buffer, ""); + safe_strcpy(hostname_buffer, sizeof(hostname_buffer), + ""); err_code= EAI_NONAME; } ); DBUG_EXECUTE_IF("getnameinfo_error_again", { - strcpy(hostname_buffer, ""); + safe_strcpy(hostname_buffer, sizeof(hostname_buffer), + ""); err_code= EAI_AGAIN; } ); DBUG_EXECUTE_IF("getnameinfo_fake_ipv4", { - strcpy(hostname_buffer, "santa.claus.ipv4.example.com"); + safe_strcpy(hostname_buffer, sizeof(hostname_buffer), + "santa.claus.ipv4.example.com"); err_code= 0; } ); DBUG_EXECUTE_IF("getnameinfo_fake_ipv6", { - strcpy(hostname_buffer, "santa.claus.ipv6.example.com"); + safe_strcpy(hostname_buffer, sizeof(hostname_buffer), + "santa.claus.ipv6.example.com"); err_code= 0; } ); DBUG_EXECUTE_IF("getnameinfo_format_ipv4", { - strcpy(hostname_buffer, "12.12.12.12"); + safe_strcpy(hostname_buffer, sizeof(hostname_buffer), + "12.12.12.12"); err_code= 0; } ); DBUG_EXECUTE_IF("getnameinfo_format_ipv6", { - strcpy(hostname_buffer, "12:DEAD:BEEF:0"); + safe_strcpy(hostname_buffer, sizeof(hostname_buffer), + "12:DEAD:BEEF:0"); err_code= 0; } ); diff --git a/sql/log.h b/sql/log.h index dd31081c404..454f0ff63b7 100644 --- a/sql/log.h +++ b/sql/log.h @@ -936,7 +936,7 @@ public: mysql_mutex_assert_not_owner(&LOCK_binlog_end_pos); lock_binlog_end_pos(); binlog_end_pos= pos; - strcpy(binlog_end_pos_file, file_name); + safe_strcpy(binlog_end_pos_file, sizeof(binlog_end_pos_file), file_name); signal_bin_log_update(); unlock_binlog_end_pos(); } @@ -949,7 +949,7 @@ public: { mysql_mutex_assert_not_owner(&LOCK_log); mysql_mutex_assert_owner(&LOCK_binlog_end_pos); - strcpy(file_name_buf, binlog_end_pos_file); + safe_strcpy(file_name_buf, FN_REFLEN, binlog_end_pos_file); return binlog_end_pos; } void lock_binlog_end_pos() { mysql_mutex_lock(&LOCK_binlog_end_pos); } diff --git a/sql/my_json_writer.cc b/sql/my_json_writer.cc index 0397f87dd77..e41bad1ed25 100644 --- a/sql/my_json_writer.cc +++ b/sql/my_json_writer.cc @@ -190,7 +190,7 @@ void Json_writer::add_ull(ulonglong val) } -/* Add a memory size, printing in Kb, Kb, Gb if necessary */ +/* Add a memory size, printing in Kb, Mb if necessary */ void Json_writer::add_size(longlong val) { char buf[64]; @@ -198,18 +198,10 @@ void Json_writer::add_size(longlong val) if (val < 1024) len= my_snprintf(buf, sizeof(buf), "%lld", val); else if (val < 1024*1024*16) - { /* Values less than 16MB are specified in KB for precision */ - len= my_snprintf(buf, sizeof(buf), "%lld", val/1024); - strcpy(buf + len, "Kb"); - len+= 2; - } + len= my_snprintf(buf, sizeof(buf), "%lldKb", val/1024); else - { - len= my_snprintf(buf, sizeof(buf), "%lld", val/(1024*1024)); - strcpy(buf + len, "Mb"); - len+= 2; - } + len= my_snprintf(buf, sizeof(buf), "%lldMb", val/(1024*1024)); add_str(buf, len); } diff --git a/sql/mysql_install_db.cc b/sql/mysql_install_db.cc index 8879d7daf5d..d083372bec1 100644 --- a/sql/mysql_install_db.cc +++ b/sql/mysql_install_db.cc @@ -159,7 +159,7 @@ int main(int argc, char **argv) MY_INIT(argv[0]); GetModuleFileName(NULL, self_name, FN_REFLEN); - strcpy(mysqld_path,self_name); + safe_strcpy(mysqld_path, sizeof(mysqld_path), self_name); p= strrchr(mysqld_path, FN_LIBCHAR); if (p) { @@ -174,7 +174,7 @@ int main(int argc, char **argv) Figure out default data directory. It "data" directory, next to "bin" directory, where mysql_install_db.exe resides. */ - strcpy(default_datadir, self_name); + safe_strcpy(default_datadir, sizeof(default_datadir), self_name); p = strrchr(default_datadir, FN_LIBCHAR); if (p) { diff --git a/sql/rpl_parallel.cc b/sql/rpl_parallel.cc index 23ca235c3e9..1cfdf96ee3b 100644 --- a/sql/rpl_parallel.cc +++ b/sql/rpl_parallel.cc @@ -54,11 +54,13 @@ rpt_handle_event(rpl_parallel_thread::queued_event *qev, thd->system_thread_info.rpl_sql_info->rpl_filter = rli->mi->rpl_filter; ev->thd= thd; - strcpy(rgi->event_relay_log_name_buf, qev->event_relay_log_name); + safe_strcpy(rgi->event_relay_log_name_buf, sizeof(rgi->event_relay_log_name_buf), + qev->event_relay_log_name); rgi->event_relay_log_name= rgi->event_relay_log_name_buf; rgi->event_relay_log_pos= qev->event_relay_log_pos; rgi->future_event_relay_log_pos= qev->future_event_relay_log_pos; - strcpy(rgi->future_event_master_log_name, qev->future_event_master_log_name); + safe_strcpy(rgi->future_event_master_log_name, sizeof(rgi->future_event_master_log_name), + qev->future_event_master_log_name); if (event_can_update_last_master_timestamp(ev)) rgi->last_master_timestamp= ev->when + (time_t)ev->exec_time; err= apply_event_and_update_pos_for_parallel(ev, thd, rgi); @@ -115,7 +117,8 @@ handle_queued_pos_update(THD *thd, rpl_parallel_thread::queued_event *qev) cmp= compare_log_name(rli->group_master_log_name, qev->future_event_master_log_name); if (cmp < 0) { - strcpy(rli->group_master_log_name, qev->future_event_master_log_name); + safe_strcpy(rli->group_master_log_name, sizeof(rli->group_master_log_name), + qev->future_event_master_log_name); rli->group_master_log_pos= qev->future_event_master_log_pos; } else if (cmp == 0 @@ -1983,10 +1986,13 @@ rpl_parallel_thread::get_qev(Log_event *ev, ulonglong event_size, queued_event *qev= get_qev_common(ev, event_size); if (!qev) return NULL; - strcpy(qev->event_relay_log_name, rli->event_relay_log_name); + safe_strcpy(qev->event_relay_log_name, sizeof(qev->event_relay_log_name), + rli->event_relay_log_name); qev->event_relay_log_pos= rli->event_relay_log_pos; qev->future_event_relay_log_pos= rli->future_event_relay_log_pos; - strcpy(qev->future_event_master_log_name, rli->future_event_master_log_name); + safe_strcpy(qev->future_event_master_log_name, + sizeof(qev->future_event_master_log_name), + rli->future_event_master_log_name); return qev; } @@ -2000,11 +2006,13 @@ rpl_parallel_thread::retry_get_qev(Log_event *ev, queued_event *orig_qev, if (!qev) return NULL; qev->rgi= orig_qev->rgi; - strcpy(qev->event_relay_log_name, relay_log_name); + safe_strcpy(qev->event_relay_log_name, sizeof(qev->event_relay_log_name), + relay_log_name); qev->event_relay_log_pos= event_pos; qev->future_event_relay_log_pos= event_pos+event_size; - strcpy(qev->future_event_master_log_name, - orig_qev->future_event_master_log_name); + safe_strcpy(qev->future_event_master_log_name, + sizeof(qev->future_event_master_log_name), + orig_qev->future_event_master_log_name); return qev; } diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc index efcbd29ef39..9d4e09a362c 100644 --- a/sql/rpl_rli.cc +++ b/sql/rpl_rli.cc @@ -1008,7 +1008,8 @@ void Relay_log_info::inc_group_relay_log_pos(ulonglong log_pos, { if (cmp < 0) { - strcpy(group_master_log_name, rgi->future_event_master_log_name); + safe_strcpy(group_master_log_name, sizeof(group_master_log_name), + rgi->future_event_master_log_name); group_master_log_pos= log_pos; } else if (group_master_log_pos < log_pos) diff --git a/sql/semisync_master.cc b/sql/semisync_master.cc index 670a6d8d9ed..410439c966a 100644 --- a/sql/semisync_master.cc +++ b/sql/semisync_master.cc @@ -352,8 +352,8 @@ Repl_semi_sync_master::Repl_semi_sync_master() m_state(0), m_wait_point(0) { - strcpy(m_reply_file_name, ""); - strcpy(m_wait_file_name, ""); + m_reply_file_name[0]= '\0'; + m_wait_file_name[0]= '\0'; } int Repl_semi_sync_master::init_object() @@ -777,7 +777,8 @@ int Repl_semi_sync_master::report_binlog_update(THD* thd, const char *log_file, return 1; thd->semisync_info= log_info; } - strcpy(log_info->log_file, log_file + dirname_length(log_file)); + safe_strcpy(log_info->log_file, sizeof(log_info->log_file), + log_file + dirname_length(log_file)); log_info->log_pos = log_pos; return write_tranx_in_binlog(log_info->log_file, log_pos); diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc index badbca45aaf..61d6a529045 100644 --- a/sql/sql_connect.cc +++ b/sql/sql_connect.cc @@ -986,7 +986,7 @@ static int check_connection(THD *thd) /* See RFC 5737, 192.0.2.0/24 is reserved. */ const char* fake= "192.0.2.4"; inet_pton(AF_INET,fake, ip4); - strcpy(ip, fake); + safe_strcpy(ip, sizeof(ip), fake); peer_rc= 0; } ); @@ -1016,7 +1016,7 @@ static int check_connection(THD *thd) ip6->s6_addr[13] = 0x06; ip6->s6_addr[14] = 0x00; ip6->s6_addr[15] = 0x06; - strcpy(ip, fake); + safe_strcpy(ip, sizeof(ip), fake); peer_rc= 0; } ); diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index 5ce833bc608..6228991d46c 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -2181,7 +2181,7 @@ static int add_keyword_path(String *str, const char *keyword, const char *path) { char temp_path[FN_REFLEN]; - strcpy(temp_path, path); + safe_strcpy(temp_path, sizeof(temp_path), path); #ifdef __WIN__ /* Convert \ to / to be able to create table on unix */ char *pos, *end; diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 979407bf3ea..69dbe0d7749 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -379,9 +379,10 @@ static void fix_dl_name(MEM_ROOT *root, LEX_CSTRING *dl) my_strcasecmp(&my_charset_latin1, dl->str + dl->length - so_ext_len, SO_EXT)) { - char *s= (char*)alloc_root(root, dl->length + so_ext_len + 1); + size_t s_size= dl->length + so_ext_len + 1; + char *s= (char*)alloc_root(root, s_size); memcpy(s, dl->str, dl->length); - strcpy(s + dl->length, SO_EXT); + safe_strcpy(s + dl->length, s_size - dl->length, SO_EXT); dl->str= s; dl->length+= so_ext_len; } @@ -3838,7 +3839,7 @@ static int construct_options(MEM_ROOT *mem_root, struct st_plugin_int *tmp, DBUG_ENTER("construct_options"); plugin_name_ptr= (char*) alloc_root(mem_root, plugin_name_len + 1); - strcpy(plugin_name_ptr, plugin_name); + safe_strcpy(plugin_name_ptr, plugin_name_len + 1, plugin_name); my_casedn_str(&my_charset_latin1, plugin_name_ptr); convert_underscore_to_dash(plugin_name_ptr, plugin_name_len); plugin_name_with_prefix_ptr= (char*) alloc_root(mem_root, diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 972478fcb8f..54290cff242 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -3085,7 +3085,7 @@ err: info->error= ER_MASTER_FATAL_ERROR_READING_BINLOG; } else if (info->errmsg != NULL) - strcpy(info->error_text, info->errmsg); + safe_strcpy(info->error_text, sizeof(info->error_text), info->errmsg); my_message(info->error, info->error_text, MYF(0)); From 28073a979fa5a33dd9fe6768e14ddfb63929c6a2 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Mon, 20 May 2024 13:29:59 +0400 Subject: [PATCH 12/31] MDEV-34187 On startup: UBSAN: runtime error: applying zero offset to null pointer in skip_trailing_space and my_hash_sort_utf8mb3_general1400_nopad_as_ci The last element in func_array_oracle_overrides[] equal to {0,0} was erroneously passed to Native_functions_hash::replace(). Removing this element. --- sql/item_create.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sql/item_create.cc b/sql/item_create.cc index 2fc1ea28529..1e72a66f8e4 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -5687,8 +5687,7 @@ const Native_func_registry func_array_oracle_overrides[] = { { STRING_WITH_LEN("REGEXP_REPLACE") }, BUILDER(Create_func_regexp_replace_oracle)}, { { STRING_WITH_LEN("RPAD") }, BUILDER(Create_func_rpad_oracle)}, - { { STRING_WITH_LEN("RTRIM") }, BUILDER(Create_func_rtrim_oracle)}, - { {0, 0}, NULL} + { { STRING_WITH_LEN("RTRIM") }, BUILDER(Create_func_rtrim_oracle)} }; Native_func_registry_array From ac2e02e961f681903c0e288c881536c3ec24d78f Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Mon, 20 May 2024 18:18:41 +0530 Subject: [PATCH 13/31] MDEV-34175 mtr_t::log_close() warning should change the shutdown condition - InnoDB should print the warning message saying "Shutdown is in progress" only when shutdown state is greater than SRV_SHUTDOWN_INITIATED. --- storage/innobase/mtr/mtr0mtr.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/innobase/mtr/mtr0mtr.cc b/storage/innobase/mtr/mtr0mtr.cc index 4f730dd4eff..3b405b0f324 100644 --- a/storage/innobase/mtr/mtr0mtr.cc +++ b/storage/innobase/mtr/mtr0mtr.cc @@ -925,7 +925,7 @@ static mtr_t::page_flush_ahead log_close(lsn_t lsn) " last checkpoint LSN=" LSN_PF ", current LSN=" LSN_PF "%s.", lsn_t{log_sys.last_checkpoint_lsn}, lsn, - srv_shutdown_state != SRV_SHUTDOWN_INITIATED + srv_shutdown_state > SRV_SHUTDOWN_INITIATED ? ". Shutdown is in progress" : ""); } } From 86adee38067effe039c8e4c5f6016baadaac7c6c Mon Sep 17 00:00:00 2001 From: Yuchen Pei Date: Wed, 1 May 2024 14:22:46 +1000 Subject: [PATCH 14/31] MDEV-31475 remove unnecessary assignment to spider share init_error The init, init_error, and init_error_time fields of a SPIDER_SHARE should only be assigned when actually doing the initialisation of a SPIDER_SHARE, otherwise they could result in spurious failures from spider_get_share() in a subsequent statement. --- storage/spider/ha_spider.cc | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/storage/spider/ha_spider.cc b/storage/spider/ha_spider.cc index 31498328535..5c8b094001a 100644 --- a/storage/spider/ha_spider.cc +++ b/storage/spider/ha_spider.cc @@ -8328,8 +8328,6 @@ int ha_spider::info( spider_init_error_table->init_error_time = (time_t) time((time_t*) 0); } - share->init_error = TRUE; - share->init = TRUE; } if (wide_handler->sql_command == SQLCOM_SHOW_CREATE || wide_handler->sql_command == SQLCOM_SHOW_FIELDS) @@ -8382,10 +8380,6 @@ int ha_spider::info( share, TRUE)) ) { spider_init_error_table->init_error = error_num; -/* - if (!thd->is_error()) - my_error(error_num, MYF(0), ""); -*/ if ((spider_init_error_table->init_error_with_message = thd->is_error())) strmov(spider_init_error_table->init_error_msg, @@ -8393,8 +8387,6 @@ int ha_spider::info( spider_init_error_table->init_error_time = (time_t) time((time_t*) 0); } - share->init_error = TRUE; - share->init = TRUE; } if (wide_handler->sql_command == SQLCOM_SHOW_CREATE || wide_handler->sql_command == SQLCOM_SHOW_FIELDS) @@ -8688,8 +8680,6 @@ ha_rows ha_spider::records_in_range( spider_init_error_table->init_error_time = (time_t) time((time_t*) 0); } - share->init_error = TRUE; - share->init = TRUE; } if (check_error_mode(error_num)) my_errno = error_num; @@ -8993,8 +8983,6 @@ int ha_spider::check_crd() spider_init_error_table->init_error_time = (time_t) time((time_t*) 0); } - share->init_error = TRUE; - share->init = TRUE; } DBUG_RETURN(check_error_mode(error_num)); } From 698dae54effd0b2e1ce8d564f8b7d0ed04c431e2 Mon Sep 17 00:00:00 2001 From: Yuchen Pei Date: Wed, 1 May 2024 14:25:39 +1000 Subject: [PATCH 15/31] MDEV-31475 Spider: only reset wide_handler when owning it A wide_handler is shared among ha_spider of partitions of the same spider table, where the last partition is designated the owner of the wide_handler, and is responsible for its deallocation. Therefore in case of failure, we only reset wide_handler in error handling if the current ha_spider is the owner of the wide_handler, otherwise it will result in segv in the destructor of ha_spider, or during ha_spider::close(). --- storage/spider/ha_spider.cc | 3 +- storage/spider/ha_spider.h | 1 + .../spider/bugfix/r/mdev_31475.result | 23 +++++++++++++ .../spider/bugfix/t/mdev_31475.test | 32 +++++++++++++++++++ storage/spider/spd_include.h | 4 +++ 5 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 storage/spider/mysql-test/spider/bugfix/r/mdev_31475.result create mode 100644 storage/spider/mysql-test/spider/bugfix/t/mdev_31475.test diff --git a/storage/spider/ha_spider.cc b/storage/spider/ha_spider.cc index 5c8b094001a..bdf2470f6cb 100644 --- a/storage/spider/ha_spider.cc +++ b/storage/spider/ha_spider.cc @@ -614,7 +614,8 @@ error_get_share: owner->wide_handler = NULL; owner->wide_handler_owner = FALSE; } - wide_handler = NULL; + if (!wide_handler_owner) + wide_handler = NULL; error_wide_handler_alloc: DBUG_RETURN(error_num); } diff --git a/storage/spider/ha_spider.h b/storage/spider/ha_spider.h index 89b39d585fa..969fbf850cd 100644 --- a/storage/spider/ha_spider.h +++ b/storage/spider/ha_spider.h @@ -94,6 +94,7 @@ public: #ifdef WITH_PARTITION_STORAGE_ENGINE SPIDER_PARTITION_HANDLER *partition_handler; #endif + /* Whether this ha_spider is the owner of its wide_handler. */ bool wide_handler_owner = FALSE; SPIDER_WIDE_HANDLER *wide_handler = NULL; diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_31475.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_31475.result new file mode 100644 index 00000000000..b4ad3692432 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_31475.result @@ -0,0 +1,23 @@ +for master_1 +for child2 +for child3 +CREATE TABLE t3 (c1 MEDIUMINT NULL, c2 CHAR(5)) ENGINE=Spider PARTITION BY KEY(c1) PARTITIONS 2; +ALTER TABLE t3 DROP PRIMARY KEY; +ERROR 42000: Can't DROP INDEX `PRIMARY`; check that it exists +SELECT * FROM t3 WHERE c1 <=> '1000-00-01 00:00:00' ORDER BY c1,c2 LIMIT 2; +ERROR HY000: Unable to connect to foreign data source: localhost +CREATE TABLE t1 (a INT UNSIGNED NOT NULL PRIMARY KEY, b INT UNSIGNED NOT NULL, c INT UNSIGNED, UNIQUE (b, c) USING HASH) ENGINE=Spider; +SELECT t1.c1 FROM t3 RIGHT JOIN t1 ON t1.c1=current_date() UNION SELECT t1.c2 FROM t1 LEFT OUTER JOIN t3 ON t1.c2; +ERROR HY000: Unable to connect to foreign data source: localhost +drop table t1, t3; +set spider_same_server_link= 1; +CREATE SERVER srv FOREIGN DATA WRAPPER mysql +OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); +CREATE TABLE t1 (a INT, b VARCHAR(255), PRIMARY KEY(a)) ENGINE=Spider PARTITION BY RANGE (a) (PARTITION p1 VALUES LESS THAN (3), PARTITION p2 VALUES LESS THAN MAXVALUE COMMENT='srv "srv"'); +DROP SERVER srv; +SELECT * FROM t1; +ERROR HY000: The foreign server name you are trying to reference does not exist. Data source error: srv +drop table t1; +for master_1 +for child2 +for child3 diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_31475.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_31475.test new file mode 100644 index 00000000000..6794e9df19e --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_31475.test @@ -0,0 +1,32 @@ +--disable_query_log +--disable_result_log +--source ../../t/test_init.inc +--enable_result_log +--enable_query_log + +# test 1 +CREATE TABLE t3 (c1 MEDIUMINT NULL, c2 CHAR(5)) ENGINE=Spider PARTITION BY KEY(c1) PARTITIONS 2; +--error ER_CANT_DROP_FIELD_OR_KEY +ALTER TABLE t3 DROP PRIMARY KEY; +--error ER_CONNECT_TO_FOREIGN_DATA_SOURCE +SELECT * FROM t3 WHERE c1 <=> '1000-00-01 00:00:00' ORDER BY c1,c2 LIMIT 2; +CREATE TABLE t1 (a INT UNSIGNED NOT NULL PRIMARY KEY, b INT UNSIGNED NOT NULL, c INT UNSIGNED, UNIQUE (b, c) USING HASH) ENGINE=Spider; +--error ER_CONNECT_TO_FOREIGN_DATA_SOURCE +SELECT t1.c1 FROM t3 RIGHT JOIN t1 ON t1.c1=current_date() UNION SELECT t1.c2 FROM t1 LEFT OUTER JOIN t3 ON t1.c2; +drop table t1, t3; + +# test 2 +set spider_same_server_link= 1; +evalp CREATE SERVER srv FOREIGN DATA WRAPPER mysql +OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); +CREATE TABLE t1 (a INT, b VARCHAR(255), PRIMARY KEY(a)) ENGINE=Spider PARTITION BY RANGE (a) (PARTITION p1 VALUES LESS THAN (3), PARTITION p2 VALUES LESS THAN MAXVALUE COMMENT='srv "srv"'); +DROP SERVER srv; +--error 1477 +SELECT * FROM t1; +drop table t1; + +--disable_query_log +--disable_result_log +--source ../../t/test_deinit.inc +--enable_result_log +--enable_query_log diff --git a/storage/spider/spd_include.h b/storage/spider/spd_include.h index ecf336f1c8e..d6525b7b730 100644 --- a/storage/spider/spd_include.h +++ b/storage/spider/spd_include.h @@ -879,6 +879,10 @@ enum spider_hnd_stage { SPD_HND_STAGE_CLEAR_TOP_TABLE_FIELDS }; +/* + A wide handler is shared among ha_spider of partitions of the same + table. It is owned by the last partition. +*/ typedef struct st_spider_wide_handler { spider_hnd_stage stage; From 0907df3d897149d4223800533e8e41ffdeb6ac8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 21 May 2024 09:52:35 +0300 Subject: [PATCH 16/31] MDEV-34204 Assertion `!*detailed_error' failed on shutdown after XA PREPARE trx_free_at_shutdown(): Similar to trx_t::commit_in_memory(), clear the detailed_error (FOREIGN KEY constraint error) before invoking trx_t::free(). We only do this on debug instrumented builds in order to avoid a debug assertion failure on shutdown. --- mysql-test/suite/innodb/r/xa_recovery.result | 17 ++++++++++++++--- mysql-test/suite/innodb/t/xa_recovery.test | 15 ++++++++++++--- storage/innobase/trx/trx0trx.cc | 1 + 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/mysql-test/suite/innodb/r/xa_recovery.result b/mysql-test/suite/innodb/r/xa_recovery.result index ed9f19b7eb3..833ccf2015f 100644 --- a/mysql-test/suite/innodb/r/xa_recovery.result +++ b/mysql-test/suite/innodb/r/xa_recovery.result @@ -1,4 +1,4 @@ -CREATE TABLE t1 (a INT) ENGINE=InnoDB; +CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB; INSERT INTO t1 VALUES (1); connect con1,localhost,root; XA START 'x'; @@ -6,7 +6,7 @@ UPDATE t1 set a=2; XA END 'x'; XA PREPARE 'x'; connect con2,localhost,root; -CREATE TABLE t2 (a INT) ENGINE=InnoDB; +CREATE TABLE t2 (a INT PRIMARY KEY) ENGINE=InnoDB; XA START 'y'; INSERT INTO t2 VALUES (1); XA END 'y'; @@ -29,7 +29,18 @@ XA ROLLBACK 'x'; SELECT * FROM t1; a 1 -DROP TABLE t1; +CREATE TABLE t3(a INT PRIMARY KEY REFERENCES t1(a)) ENGINE=InnoDB; +XA START 'a'; +INSERT INTO t3 SET a=1; +INSERT INTO t3 SET a=42; +ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t3`, CONSTRAINT `t3_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`a`)) +XA END 'a'; +XA PREPARE 'a'; SET GLOBAL innodb_fast_shutdown=0; # restart +XA COMMIT 'a'; +SELECT * FROM t3; +a +1 +DROP TABLE t3,t1; XA ROLLBACK 'y'; diff --git a/mysql-test/suite/innodb/t/xa_recovery.test b/mysql-test/suite/innodb/t/xa_recovery.test index da9626ebd29..6bdc986ae88 100644 --- a/mysql-test/suite/innodb/t/xa_recovery.test +++ b/mysql-test/suite/innodb/t/xa_recovery.test @@ -10,12 +10,12 @@ call mtr.add_suppression("Found [12] prepared XA transactions"); FLUSH TABLES; --enable_query_log -CREATE TABLE t1 (a INT) ENGINE=InnoDB; +CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB; INSERT INTO t1 VALUES (1); connect (con1,localhost,root); XA START 'x'; UPDATE t1 set a=2; XA END 'x'; XA PREPARE 'x'; connect (con2,localhost,root); -CREATE TABLE t2 (a INT) ENGINE=InnoDB; +CREATE TABLE t2 (a INT PRIMARY KEY) ENGINE=InnoDB; XA START 'y'; INSERT INTO t2 VALUES (1); XA END 'y'; XA PREPARE 'y'; connection default; @@ -53,9 +53,18 @@ SELECT * FROM t1; XA ROLLBACK 'x'; SELECT * FROM t1; -DROP TABLE t1; +CREATE TABLE t3(a INT PRIMARY KEY REFERENCES t1(a)) ENGINE=InnoDB; +XA START 'a'; +INSERT INTO t3 SET a=1; +--error ER_NO_REFERENCED_ROW_2 +INSERT INTO t3 SET a=42; +XA END 'a'; +XA PREPARE 'a'; SET GLOBAL innodb_fast_shutdown=0; --source include/restart_mysqld.inc +XA COMMIT 'a'; +SELECT * FROM t3; +DROP TABLE t3,t1; XA ROLLBACK 'y'; diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc index 606416e677e..7f1f26547dc 100644 --- a/storage/innobase/trx/trx0trx.cc +++ b/storage/innobase/trx/trx0trx.cc @@ -554,6 +554,7 @@ trx_free_at_shutdown(trx_t *trx) trx->state = TRX_STATE_NOT_STARTED; ut_ad(!UT_LIST_GET_LEN(trx->lock.trx_locks)); trx->id = 0; + ut_d(*trx->detailed_error = '\0'); trx->free(); } From b2944adb76e93d22b9cfe088a2c568c46d8ecfd9 Mon Sep 17 00:00:00 2001 From: mariadb-DebarunBanerjee Date: Wed, 15 May 2024 17:30:52 +0530 Subject: [PATCH 17/31] MDEV-34166 Server could hang with BP < 80M under stress BUF_LRU_MIN_LEN (256) is too high value for low buffer pool(BP) size. For example, for BP size lower than 80M and 16 K page size, the limit is more than 5% of total BP and for lowest BP 5M, it is 80% of the BP. Non-data objects like explicit locks could occupy part of the BP pool reducing the pages available for LRU. If LRU reaches minimum limit and if no free pages are available, server would hang with page cleaner not able to free any more pages. Fix: To avoid such hang, we adjust the LRU limit lower than the limit for data objects as checked in buf_LRU_check_size_of_non_data_objects() i.e. one page less than 5% of BP. --- .../suite/innodb/r/lock_memory_debug.result | 13 +++++++++++++ .../suite/innodb/t/lock_memory_debug.opt | 1 + .../suite/innodb/t/lock_memory_debug.test | 19 +++++++++++++++++++ storage/innobase/buf/buf0flu.cc | 14 +++++++++++++- storage/innobase/lock/lock0lock.cc | 5 +++++ 5 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 mysql-test/suite/innodb/r/lock_memory_debug.result create mode 100644 mysql-test/suite/innodb/t/lock_memory_debug.opt create mode 100644 mysql-test/suite/innodb/t/lock_memory_debug.test diff --git a/mysql-test/suite/innodb/r/lock_memory_debug.result b/mysql-test/suite/innodb/r/lock_memory_debug.result new file mode 100644 index 00000000000..36d7433974e --- /dev/null +++ b/mysql-test/suite/innodb/r/lock_memory_debug.result @@ -0,0 +1,13 @@ +# +# MDEV-34166 Server could hang with BP < 80M under stress +# +call mtr.add_suppression("\\[Warning\\] InnoDB: Over 67 percent of the buffer pool"); +CREATE TABLE t1 (col1 INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1),(2),(3),(4),(5); +SET STATEMENT debug_dbug='+d,innodb_skip_lock_bitmap' FOR +INSERT INTO t1 SELECT a.* FROM t1 a, t1 b, t1 c, t1 d, t1 e, t1 f, t1 g LIMIT 45000; +ERROR HY000: The total number of locks exceeds the lock table size +SELECT COUNT(*) FROM t1; +COUNT(*) +5 +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/lock_memory_debug.opt b/mysql-test/suite/innodb/t/lock_memory_debug.opt new file mode 100644 index 00000000000..67c8423cf2a --- /dev/null +++ b/mysql-test/suite/innodb/t/lock_memory_debug.opt @@ -0,0 +1 @@ +--innodb_buffer_pool_size=5M diff --git a/mysql-test/suite/innodb/t/lock_memory_debug.test b/mysql-test/suite/innodb/t/lock_memory_debug.test new file mode 100644 index 00000000000..51e0e8fd57e --- /dev/null +++ b/mysql-test/suite/innodb/t/lock_memory_debug.test @@ -0,0 +1,19 @@ +--source include/have_innodb.inc +--source include/have_debug.inc + +--echo # +--echo # MDEV-34166 Server could hang with BP < 80M under stress +--echo # + +call mtr.add_suppression("\\[Warning\\] InnoDB: Over 67 percent of the buffer pool"); + +CREATE TABLE t1 (col1 INT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1),(2),(3),(4),(5); + +--error ER_LOCK_TABLE_FULL +SET STATEMENT debug_dbug='+d,innodb_skip_lock_bitmap' FOR +INSERT INTO t1 SELECT a.* FROM t1 a, t1 b, t1 c, t1 d, t1 e, t1 f, t1 g LIMIT 45000; + +SELECT COUNT(*) FROM t1; + +DROP TABLE t1; diff --git a/storage/innobase/buf/buf0flu.cc b/storage/innobase/buf/buf0flu.cc index a554309915d..b2d7d10b855 100644 --- a/storage/innobase/buf/buf0flu.cc +++ b/storage/innobase/buf/buf0flu.cc @@ -1300,9 +1300,21 @@ static void buf_flush_LRU_list_batch(ulint max, bool evict, static_assert(FIL_NULL > SRV_TMP_SPACE_ID, "consistency"); static_assert(FIL_NULL > SRV_SPACE_ID_UPPER_BOUND, "consistency"); + /* BUF_LRU_MIN_LEN (256) is too high value for low buffer pool(BP) size. For + example, for BP size lower than 80M and 16 K page size, the limit is more than + 5% of total BP and for lowest BP 5M, it is 80% of the BP. Non-data objects + like explicit locks could occupy part of the BP pool reducing the pages + available for LRU. If LRU reaches minimum limit and if no free pages are + available, server would hang with page cleaner not able to free any more + pages. To avoid such hang, we adjust the LRU limit lower than the limit for + data objects as checked in buf_LRU_check_size_of_non_data_objects() i.e. one + page less than 5% of BP. */ + size_t pool_limit= buf_pool.curr_size / 20 - 1; + auto buf_lru_min_len= std::min(pool_limit, BUF_LRU_MIN_LEN); + for (buf_page_t *bpage= UT_LIST_GET_LAST(buf_pool.LRU); bpage && - ((UT_LIST_GET_LEN(buf_pool.LRU) > BUF_LRU_MIN_LEN && + ((UT_LIST_GET_LEN(buf_pool.LRU) > buf_lru_min_len && UT_LIST_GET_LEN(buf_pool.free) < free_limit) || recv_recovery_is_on()); ++scanned) { diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc index 0891ad5ceb7..d9a3c96aab0 100644 --- a/storage/innobase/lock/lock0lock.cc +++ b/storage/innobase/lock/lock0lock.cc @@ -1739,6 +1739,11 @@ lock_rec_find_similar_on_page( const trx_t* trx) /*!< in: transaction */ { ut_ad(lock_mutex_own()); + DBUG_EXECUTE_IF("innodb_skip_lock_bitmap", { + if (!trx->in_rollback) { + return nullptr; + } + }); for (/* No op */; lock != NULL; From 310fd6ff695541247db766baf3ade1e3b4db16e9 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Tue, 21 May 2024 08:53:40 +0400 Subject: [PATCH 18/31] Backporting bugs fixes fixed by MDEV-31340 from 11.5 The patch for MDEV-31340 fixed the following bugs: MDEV-33084 LASTVAL(t1) and LASTVAL(T1) do not work well with lower-case-table-names=0 MDEV-33085 Tables T1 and t1 do not work well with ENGINE=CSV and lower-case-table-names=0 MDEV-33086 SHOW OPEN TABLES IN DB1 -- is case insensitive with lower-case-table-names=0 MDEV-33088 Cannot create triggers in the database `MYSQL` MDEV-33103 LOCK TABLE t1 AS t2 -- alias is not case sensitive with lower-case-table-names=0 MDEV-33108 TABLE_STATISTICS and INDEX_STATISTICS are case insensitive with lower-case-table-names=0 MDEV-33109 DROP DATABASE MYSQL -- does not drop SP with lower-case-table-names=0 MDEV-33110 HANDLER commands are case insensitive with lower-case-table-names=0 MDEV-33119 User is case insensitive in INFORMATION_SCHEMA.VIEWS MDEV-33120 System log table names are case insensitive with lower-cast-table-names=0 Backporting the fixes from 11.5 to 10.5 --- mysql-test/main/lowercase_table5.result | 142 +++++++++++++++++++ mysql-test/main/lowercase_table5.test | 138 ++++++++++++++++++ mysql-test/main/view_grant.result | 31 ++++ mysql-test/main/view_grant.test | 27 ++++ mysql-test/suite/csv/lowercase_table0.result | 15 ++ mysql-test/suite/csv/lowercase_table0.test | 16 +++ sql/lex_ident.h | 85 +++++++++++ sql/sql_acl.cc | 18 +-- sql/sql_base.cc | 52 +++---- sql/sql_base.h | 3 +- sql/sql_class.cc | 5 +- sql/sql_class.h | 1 + sql/sql_connect.cc | 6 +- sql/sql_db.cc | 3 +- sql/sql_handler.cc | 7 +- sql/sql_parse.cc | 15 +- sql/sql_show.cc | 12 +- sql/sql_string.h | 5 + sql/sql_trigger.cc | 2 +- sql/table.cc | 35 +++-- sql/table.h | 17 ++- sql/temporary_tables.cc | 13 +- storage/csv/ha_tina.cc | 3 +- 23 files changed, 561 insertions(+), 90 deletions(-) create mode 100644 mysql-test/suite/csv/lowercase_table0.result create mode 100644 mysql-test/suite/csv/lowercase_table0.test create mode 100644 sql/lex_ident.h diff --git a/mysql-test/main/lowercase_table5.result b/mysql-test/main/lowercase_table5.result index 7e78f71b75f..cededde9525 100644 --- a/mysql-test/main/lowercase_table5.result +++ b/mysql-test/main/lowercase_table5.result @@ -47,3 +47,145 @@ DROP PROCEDURE SP; # # End of 10.4 tests # +# +# Start of 10.5 tests +# +# +# MDEV-33084 LASTVAL(t1) and LASTVAL(T1) do not work well with lower-case-table-names=0 +# +CREATE SEQUENCE t1; +CREATE SEQUENCE T1; +SELECT nextval(t1), lastval(t1); +nextval(t1) lastval(t1) +1 1 +SELECT nextval(T1), lastval(T1); +nextval(T1) lastval(T1) +1 1 +SELECT lastval(t1), lastval(T1) l2; +lastval(t1) l2 +1 1 +DROP SEQUENCE t1, T1; +# +# MDEV-33086 SHOW OPEN TABLES IN DB1 -- is case insensitive with lower-case-table-names=0 +# +CREATE DATABASE db1; +CREATE TABLE db1.t1 (a INT); +SELECT * FROM db1.t1; +a +SHOW OPEN TABLES IN DB1; +Database Table In_use Name_locked +SHOW OPEN TABLES IN db1; +Database Table In_use Name_locked +db1 t1 0 0 +DROP DATABASE db1; +# +# MDEV-33088 Cannot create triggers in the database `MYSQL` +# +CREATE DATABASE MYSQL; +CREATE TABLE MYSQL.t1 (a INT); +CREATE TABLE MYSQL.t2 (a INT); +CREATE TRIGGER MYSQL.tr1 AFTER INSERT ON t1 FOR EACH ROW INSERT INTO t2 VALUES (new.a); +INSERT INTO MYSQL.t1 VALUES (10); +SELECT * FROM MYSQL.t1; +a +10 +SELECT * FROM MYSQL.t2; +a +10 +DROP DATABASE MYSQL; +# +# MDEV-33103 LOCK TABLE t1 AS t2 -- alias is not case sensitive with lower-case-table-names=0 +# +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1); +LOCK TABLE t1 AS t2 READ; +SELECT * FROM t1 AS t2; +a +1 +UNLOCK TABLES; +LOCK TABLE t1 AS t2 READ; +SELECT * FROM t1 AS T2; +ERROR HY000: Table 'T2' was not locked with LOCK TABLES +UNLOCK TABLES; +DROP TABLE t1; +# +# MDEV-33108 TABLE_STATISTICS and INDEX_STATISTICS are case insensitive with lower-case-table-names=0 +# +SET GLOBAL userstat=1; +CREATE TABLE t1 (a INT, KEY(a)); +INSERT INTO t1 VALUES (1),(2),(3),(4); +SELECT * FROM t1 ORDER BY a; +a +1 +2 +3 +4 +CREATE TABLE T1 (a INT, KEY(a)); +INSERT INTO T1 VALUES (1),(2),(3),(4); +SELECT * FROM T1 ORDER BY a; +a +1 +2 +3 +4 +SELECT * FROM INFORMATION_SCHEMA.TABLE_STATISTICS ORDER BY BINARY TABLE_NAME; +TABLE_SCHEMA TABLE_NAME ROWS_READ ROWS_CHANGED ROWS_CHANGED_X_INDEXES +test T1 4 4 4 +test t1 4 4 4 +SELECT * FROM INFORMATION_SCHEMA.INDEX_STATISTICS ORDER BY BINARY TABLE_NAME; +TABLE_SCHEMA TABLE_NAME INDEX_NAME ROWS_READ +test T1 a 4 +test t1 a 4 +DROP TABLE t1; +DROP TABLE T1; +SET GLOBAL userstat=DEFAULT; +# +# MDEV-33109 DROP DATABASE MYSQL -- does not drop SP with lower-case-table-names=0 +# +CREATE DATABASE MYSQL; +CREATE FUNCTION MYSQL.f1() RETURNS INT RETURN 1; +DROP DATABASE MYSQL; +SELECT db, name, body FROM mysql.proc WHERE db=BINARY 'MYSQL' AND name='f1'; +db name body +# +# MDEV-33110 HANDLER commands are case insensitive with lower-case-table-names=0 +# +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1),(2); +HANDLER t1 OPEN; +HANDLER t1 READ FIRST; +a +1 +CREATE OR REPLACE TABLE T1 (a INT); +DROP TABLE T1; +HANDLER t1 READ NEXT; +a +2 +HANDLER t1 CLOSE; +DROP TABLE t1; +# +# MDEV-33120 System log table names are case insensitive with lower-cast-table-names=0 +# +CREATE TABLE mysql.GENERAL_log (a INT); +INSERT INTO mysql.GENERAL_log VALUES (1),(2); +DROP TABLE mysql.GENERAL_log; +CREATE TABLE mysql.SLOW_log (a INT); +INSERT INTO mysql.SLOW_log VALUES (1),(2); +DROP TABLE mysql.SLOW_log; +CREATE TABLE mysql.TRANSACTION_registry (a INT); +INSERT INTO mysql.TRANSACTION_registry VALUES (1),(2); +DROP TABLE mysql.TRANSACTION_registry; +CREATE DATABASE MYSQL; +CREATE TABLE MYSQL.general_log (a INT); +INSERT INTO MYSQL.general_log VALUES (1),(2); +DROP TABLE MYSQL.general_log; +CREATE TABLE MYSQL.slow_log (a INT); +INSERT INTO MYSQL.slow_log VALUES (1),(2); +DROP TABLE MYSQL.slow_log; +CREATE TABLE MYSQL.transaction_registry (a INT); +INSERT INTO MYSQL.transaction_registry VALUES (1),(2); +DROP TABLE MYSQL.transaction_registry; +DROP DATABASE MYSQL; +# +# End of 10.5 tests +# diff --git a/mysql-test/main/lowercase_table5.test b/mysql-test/main/lowercase_table5.test index 0103dbf5fd2..fcbb3fefb33 100644 --- a/mysql-test/main/lowercase_table5.test +++ b/mysql-test/main/lowercase_table5.test @@ -49,3 +49,141 @@ DROP PROCEDURE SP; --echo # --echo # End of 10.4 tests --echo # + +--echo # +--echo # Start of 10.5 tests +--echo # + +--echo # +--echo # MDEV-33084 LASTVAL(t1) and LASTVAL(T1) do not work well with lower-case-table-names=0 +--echo # + +CREATE SEQUENCE t1; +CREATE SEQUENCE T1; +--disable_ps2_protocol +SELECT nextval(t1), lastval(t1); +SELECT nextval(T1), lastval(T1); +SELECT lastval(t1), lastval(T1) l2; +--enable_ps2_protocol +DROP SEQUENCE t1, T1; + +--echo # +--echo # MDEV-33086 SHOW OPEN TABLES IN DB1 -- is case insensitive with lower-case-table-names=0 +--echo # + +CREATE DATABASE db1; +CREATE TABLE db1.t1 (a INT); +SELECT * FROM db1.t1; +SHOW OPEN TABLES IN DB1; +SHOW OPEN TABLES IN db1; +DROP DATABASE db1; + +--echo # +--echo # MDEV-33088 Cannot create triggers in the database `MYSQL` +--echo # + +CREATE DATABASE MYSQL; +CREATE TABLE MYSQL.t1 (a INT); +CREATE TABLE MYSQL.t2 (a INT); +CREATE TRIGGER MYSQL.tr1 AFTER INSERT ON t1 FOR EACH ROW INSERT INTO t2 VALUES (new.a); +INSERT INTO MYSQL.t1 VALUES (10); +SELECT * FROM MYSQL.t1; +SELECT * FROM MYSQL.t2; +DROP DATABASE MYSQL; + + +--echo # +--echo # MDEV-33103 LOCK TABLE t1 AS t2 -- alias is not case sensitive with lower-case-table-names=0 +--echo # + +--disable_view_protocol +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1); +LOCK TABLE t1 AS t2 READ; +SELECT * FROM t1 AS t2; +UNLOCK TABLES; +LOCK TABLE t1 AS t2 READ; +--error ER_TABLE_NOT_LOCKED +SELECT * FROM t1 AS T2; +UNLOCK TABLES; +DROP TABLE t1; +--enable_view_protocol + + +--echo # +--echo # MDEV-33108 TABLE_STATISTICS and INDEX_STATISTICS are case insensitive with lower-case-table-names=0 +--echo # + +SET GLOBAL userstat=1; +CREATE TABLE t1 (a INT, KEY(a)); +INSERT INTO t1 VALUES (1),(2),(3),(4); +--disable_ps2_protocol +SELECT * FROM t1 ORDER BY a; +CREATE TABLE T1 (a INT, KEY(a)); +INSERT INTO T1 VALUES (1),(2),(3),(4); +SELECT * FROM T1 ORDER BY a; +--enable_ps2_protocol +SELECT * FROM INFORMATION_SCHEMA.TABLE_STATISTICS ORDER BY BINARY TABLE_NAME; +SELECT * FROM INFORMATION_SCHEMA.INDEX_STATISTICS ORDER BY BINARY TABLE_NAME; +DROP TABLE t1; +DROP TABLE T1; +SET GLOBAL userstat=DEFAULT; + + +--echo # +--echo # MDEV-33109 DROP DATABASE MYSQL -- does not drop SP with lower-case-table-names=0 +--echo # + +CREATE DATABASE MYSQL; +CREATE FUNCTION MYSQL.f1() RETURNS INT RETURN 1; +DROP DATABASE MYSQL; +SELECT db, name, body FROM mysql.proc WHERE db=BINARY 'MYSQL' AND name='f1'; + + +--echo # +--echo # MDEV-33110 HANDLER commands are case insensitive with lower-case-table-names=0 +--echo # + +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1),(2); +HANDLER t1 OPEN; +HANDLER t1 READ FIRST; +CREATE OR REPLACE TABLE T1 (a INT); +DROP TABLE T1; +HANDLER t1 READ NEXT; +HANDLER t1 CLOSE; +DROP TABLE t1; + +--echo # +--echo # MDEV-33120 System log table names are case insensitive with lower-cast-table-names=0 +--echo # + +CREATE TABLE mysql.GENERAL_log (a INT); +INSERT INTO mysql.GENERAL_log VALUES (1),(2); +DROP TABLE mysql.GENERAL_log; + +CREATE TABLE mysql.SLOW_log (a INT); +INSERT INTO mysql.SLOW_log VALUES (1),(2); +DROP TABLE mysql.SLOW_log; + +CREATE TABLE mysql.TRANSACTION_registry (a INT); +INSERT INTO mysql.TRANSACTION_registry VALUES (1),(2); +DROP TABLE mysql.TRANSACTION_registry; + +CREATE DATABASE MYSQL; +CREATE TABLE MYSQL.general_log (a INT); +INSERT INTO MYSQL.general_log VALUES (1),(2); +DROP TABLE MYSQL.general_log; + +CREATE TABLE MYSQL.slow_log (a INT); +INSERT INTO MYSQL.slow_log VALUES (1),(2); +DROP TABLE MYSQL.slow_log; + +CREATE TABLE MYSQL.transaction_registry (a INT); +INSERT INTO MYSQL.transaction_registry VALUES (1),(2); +DROP TABLE MYSQL.transaction_registry; +DROP DATABASE MYSQL; + +--echo # +--echo # End of 10.5 tests +--echo # diff --git a/mysql-test/main/view_grant.result b/mysql-test/main/view_grant.result index 04e3d013b48..818a15f86ce 100644 --- a/mysql-test/main/view_grant.result +++ b/mysql-test/main/view_grant.result @@ -1954,3 +1954,34 @@ connection default; drop user user_11766767; drop database mysqltest1; drop database mysqltest2; +# +# MDEV-33119 User is case insensitive in INFORMATION_SCHEMA.VIEWS +# +USE test; +CREATE USER foo; +CREATE USER FOO; +GRANT SELECT ON test.* TO foo; +GRANT SELECT ON test.* TO FOO; +CREATE DEFINER=foo SQL SECURITY INVOKER VIEW v1 AS SELECT 1 AS c1; +connect FOO, localhost, FOO, , test; +connection FOO; +SELECT CURRENT_USER; +CURRENT_USER +FOO@% +SELECT * FROM INFORMATION_SCHEMA.VIEWS; +TABLE_CATALOG def +TABLE_SCHEMA test +TABLE_NAME v1 +VIEW_DEFINITION +CHECK_OPTION NONE +IS_UPDATABLE NO +DEFINER foo@% +SECURITY_TYPE INVOKER +CHARACTER_SET_CLIENT latin1 +COLLATION_CONNECTION latin1_swedish_ci +ALGORITHM UNDEFINED +disconnect FOO; +connection default; +DROP VIEW v1; +DROP USER foo; +DROP USER FOO; diff --git a/mysql-test/main/view_grant.test b/mysql-test/main/view_grant.test index c9bb9569145..a5019e88d65 100644 --- a/mysql-test/main/view_grant.test +++ b/mysql-test/main/view_grant.test @@ -2207,3 +2207,30 @@ drop database mysqltest2; # Wait till we reached the initial number of concurrent sessions --source include/wait_until_count_sessions.inc + +--echo # +--echo # MDEV-33119 User is case insensitive in INFORMATION_SCHEMA.VIEWS +--echo # + +USE test; +CREATE USER foo; +CREATE USER FOO; +GRANT SELECT ON test.* TO foo; +GRANT SELECT ON test.* TO FOO; + +CREATE DEFINER=foo SQL SECURITY INVOKER VIEW v1 AS SELECT 1 AS c1; + +--connect (FOO, localhost, FOO, , test) +--connection FOO + +SELECT CURRENT_USER; +--vertical_results +--query_vertical SELECT * FROM INFORMATION_SCHEMA.VIEWS +--horizontal_results + +--disconnect FOO +--connection default + +DROP VIEW v1; +DROP USER foo; +DROP USER FOO; diff --git a/mysql-test/suite/csv/lowercase_table0.result b/mysql-test/suite/csv/lowercase_table0.result new file mode 100644 index 00000000000..fba6a509aea --- /dev/null +++ b/mysql-test/suite/csv/lowercase_table0.result @@ -0,0 +1,15 @@ +# +# MDEV-33085 Tables T1 and t1 do not work well with ENGINE=CSV and lower-case-table-names=0 +# +CREATE OR REPLACE TABLE t1 (a INT NOT NULL) ENGINE=CSV; +CREATE OR REPLACE TABLE T1 (a INT NOT NULL) ENGINE=CSV; +INSERT INTO t1 VALUES (10); +INSERT INTO T1 VALUES (20); +SELECT * FROM t1; +a +10 +SELECT * FROM T1; +a +20 +DROP TABLE t1; +DROP TABLE T1; diff --git a/mysql-test/suite/csv/lowercase_table0.test b/mysql-test/suite/csv/lowercase_table0.test new file mode 100644 index 00000000000..2bb0e486cb6 --- /dev/null +++ b/mysql-test/suite/csv/lowercase_table0.test @@ -0,0 +1,16 @@ +--source include/have_csv.inc +--source include/have_lowercase0.inc +--source include/have_case_sensitive_file_system.inc + +--echo # +--echo # MDEV-33085 Tables T1 and t1 do not work well with ENGINE=CSV and lower-case-table-names=0 +--echo # + +CREATE OR REPLACE TABLE t1 (a INT NOT NULL) ENGINE=CSV; +CREATE OR REPLACE TABLE T1 (a INT NOT NULL) ENGINE=CSV; +INSERT INTO t1 VALUES (10); +INSERT INTO T1 VALUES (20); +SELECT * FROM t1; +SELECT * FROM T1; +DROP TABLE t1; +DROP TABLE T1; diff --git a/sql/lex_ident.h b/sql/lex_ident.h new file mode 100644 index 00000000000..3af52ab99d0 --- /dev/null +++ b/sql/lex_ident.h @@ -0,0 +1,85 @@ +#ifndef LEX_IDENT_INCLUDED +#define LEX_IDENT_INCLUDED +/* + Copyright (c) 2023, MariaDB + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; version 2 of + the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA +*/ + + +extern MYSQL_PLUGIN_IMPORT CHARSET_INFO *table_alias_charset; + + +/* + Identifiers for the database objects stored on disk, + e.g. databases, tables, triggers. +*/ +class Lex_ident_fs: public LEX_CSTRING +{ +public: + static CHARSET_INFO *charset_info() + { + return table_alias_charset; + } +public: + Lex_ident_fs() + :LEX_CSTRING({0,0}) + { } + Lex_ident_fs(const char *str, size_t length) + :LEX_CSTRING({str, length}) + { } + explicit Lex_ident_fs(const LEX_CSTRING &str) + :LEX_CSTRING(str) + { } +#if MYSQL_VERSION_ID<=110501 +private: + static bool is_valid_ident(const LEX_CSTRING &str) + { + // NULL identifier, or 0-terminated identifier + return (str.str == NULL && str.length == 0) || str.str[str.length] == 0; + } +public: + bool streq(const LEX_CSTRING &rhs) const + { + DBUG_ASSERT(is_valid_ident(*this)); + DBUG_ASSERT(is_valid_ident(rhs)); + return length == rhs.length && + my_strcasecmp(charset_info(), str, rhs.str) == 0; + } +#else +/* + Starting from 11.5.1 streq() is inherited from the base. + The above implementations of streq() and is_valid_ident() should be removed. +*/ +#error Remove streq() above. +#endif +}; + + +class Lex_ident_db: public Lex_ident_fs +{ +public: + using Lex_ident_fs::Lex_ident_fs; +}; + + +class Lex_ident_table: public Lex_ident_fs +{ +public: + using Lex_ident_fs::Lex_ident_fs; +}; + + +#endif // LEX_IDENT_INCLUDED diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 8aee0624ed1..dd222998b3a 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -7226,8 +7226,8 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, continue; // Add next user } - db_name= table_list->get_db_name(); - table_name= table_list->get_table_name(); + db_name= table_list->get_db_name().str; + table_name= table_list->get_table_name().str; /* Find/create cached table grant */ grant_table= table_hash_search(Str->host.str, NullS, db_name, @@ -8294,8 +8294,8 @@ bool check_grant(THD *thd, privilege_t want_access, TABLE_LIST *tables, const ACL_internal_table_access *access= get_cached_table_access(&t_ref->grant.m_internal, - t_ref->get_db_name(), - t_ref->get_table_name()); + t_ref->get_db_name().str, + t_ref->get_table_name().str); if (access) { @@ -8359,14 +8359,14 @@ bool check_grant(THD *thd, privilege_t want_access, TABLE_LIST *tables, } grant_table= table_hash_search(sctx->host, sctx->ip, - t_ref->get_db_name(), + t_ref->get_db_name().str, sctx->priv_user, - t_ref->get_table_name(), + t_ref->get_table_name().str, FALSE); if (sctx->priv_role[0]) - grant_table_role= table_hash_search("", NULL, t_ref->get_db_name(), + grant_table_role= table_hash_search("", NULL, t_ref->get_db_name().str, sctx->priv_role, - t_ref->get_table_name(), + t_ref->get_table_name().str, TRUE); if (!grant_table && !grant_table_role) @@ -8414,7 +8414,7 @@ err: command, sctx->priv_user, sctx->host_or_ip, tl ? tl->db.str : "unknown", - tl ? tl->get_table_name() : "unknown"); + tl ? tl->get_table_name().str : "unknown"); } DBUG_RETURN(TRUE); } diff --git a/sql/sql_base.cc b/sql/sql_base.cc index f1fd0053a82..eb66d33b5b0 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -200,9 +200,9 @@ uint get_table_def_key(const TABLE_LIST *table_list, const char **key) is properly initialized, so table definition cache can be produced from key used by MDL subsystem. */ - DBUG_ASSERT(!strcmp(table_list->get_db_name(), + DBUG_ASSERT(!strcmp(table_list->get_db_name().str, table_list->mdl_request.key.db_name())); - DBUG_ASSERT(!strcmp(table_list->get_table_name(), + DBUG_ASSERT(!strcmp(table_list->get_table_name().str, table_list->mdl_request.key.name())); *key= (const char*)table_list->mdl_request.key.ptr() + 1; @@ -233,33 +233,40 @@ uint get_table_def_key(const TABLE_LIST *table_list, const char **key) # Pointer to list of names of open tables. */ -struct list_open_tables_arg +class list_open_tables_arg { +public: THD *thd; - const char *db; + const Lex_ident_db db; const char *wild; TABLE_LIST table_list; OPEN_TABLE_LIST **start_list, *open_list; + + list_open_tables_arg(THD *thd_arg, const LEX_CSTRING &db_arg, + const char *wild_arg) + :thd(thd_arg), db(db_arg), wild(wild_arg), + start_list(&open_list), open_list(0) + { + bzero((char*) &table_list, sizeof(table_list)); + } }; static my_bool list_open_tables_callback(TDC_element *element, list_open_tables_arg *arg) { - const char *db= (char*) element->m_key; - size_t db_length= strlen(db); - const char *table_name= db + db_length + 1; + const Lex_ident_db + db= Lex_ident_db(Lex_cstring_strlen((const char*) element->m_key)); + const char *table_name= db.str + db.length + 1; - if (arg->db && my_strcasecmp(system_charset_info, arg->db, db)) + if (arg->db.str && !arg->db.streq(db)) return FALSE; if (arg->wild && wild_compare(table_name, arg->wild, 0)) return FALSE; /* Check if user has SELECT privilege for any column in the table */ - arg->table_list.db.str= db; - arg->table_list.db.length= db_length; - arg->table_list.table_name.str= table_name; - arg->table_list.table_name.length= strlen(table_name); + arg->table_list.db= db; + arg->table_list.table_name= Lex_cstring_strlen(table_name); arg->table_list.grant.privilege= NO_ACL; if (check_table_access(arg->thd, SELECT_ACL, &arg->table_list, TRUE, 1, TRUE)) @@ -271,7 +278,7 @@ static my_bool list_open_tables_callback(TDC_element *element, strmov((*arg->start_list)->table= strmov(((*arg->start_list)->db= (char*) ((*arg->start_list) + 1)), - db) + 1, table_name); + db.str) + 1, table_name); (*arg->start_list)->in_use= 0; mysql_mutex_lock(&element->LOCK_table_share); @@ -288,17 +295,12 @@ static my_bool list_open_tables_callback(TDC_element *element, } -OPEN_TABLE_LIST *list_open_tables(THD *thd, const char *db, const char *wild) +OPEN_TABLE_LIST *list_open_tables(THD *thd, + const LEX_CSTRING &db, + const char *wild) { - list_open_tables_arg argument; DBUG_ENTER("list_open_tables"); - - argument.thd= thd; - argument.db= db; - argument.wild= wild; - bzero((char*) &argument.table_list, sizeof(argument.table_list)); - argument.start_list= &argument.open_list; - argument.open_list= 0; + list_open_tables_arg argument(thd, db, wild); if (tdc_iterate(thd, (my_hash_walk_action) list_open_tables_callback, &argument, true)) @@ -1682,7 +1684,7 @@ bool open_table(THD *thd, TABLE_LIST *table_list, Open_table_context *ot_ctx) TABLE *table; const char *key; uint key_length; - const char *alias= table_list->alias.str; + const LEX_CSTRING &alias= table_list->alias; uint flags= ot_ctx->get_flags(); MDL_ticket *mdl_ticket; TABLE_SHARE *share; @@ -1750,7 +1752,7 @@ bool open_table(THD *thd, TABLE_LIST *table_list, Open_table_context *ot_ctx) if (table->s->table_cache_key.length == key_length && !memcmp(table->s->table_cache_key.str, key, key_length)) { - if (!my_strcasecmp(system_charset_info, table->alias.c_ptr(), alias) && + if (Lex_ident_table(table->alias.to_lex_cstring()).streq(alias) && table->query_id != thd->query_id && /* skip tables already used */ (thd->locked_tables_mode == LTM_LOCK_TABLES || table->query_id == 0)) @@ -1821,7 +1823,7 @@ bool open_table(THD *thd, TABLE_LIST *table_list, Open_table_context *ot_ctx) if (thd->locked_tables_mode == LTM_PRELOCKED) my_error(ER_NO_SUCH_TABLE, MYF(0), table_list->db.str, table_list->alias.str); else - my_error(ER_TABLE_NOT_LOCKED, MYF(0), alias); + my_error(ER_TABLE_NOT_LOCKED, MYF(0), alias.str); DBUG_RETURN(TRUE); } diff --git a/sql/sql_base.h b/sql/sql_base.h index 267acede7dd..7cfe10ea2d1 100644 --- a/sql/sql_base.h +++ b/sql/sql_base.h @@ -309,7 +309,8 @@ bool flush_tables(THD *thd, flush_tables_type flag); void close_all_tables_for_name(THD *thd, TABLE_SHARE *share, ha_extra_function extra, TABLE *skip_table); -OPEN_TABLE_LIST *list_open_tables(THD *thd, const char *db, const char *wild); +OPEN_TABLE_LIST *list_open_tables(THD *thd, const LEX_CSTRING &db, + const char *wild); bool tdc_open_view(THD *thd, TABLE_LIST *table_list, uint flags); TABLE *find_table_for_mdl_upgrade(THD *thd, const char *db, diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 7913f1a40d2..34cd63d7839 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -855,7 +855,7 @@ THD::THD(my_thread_id id, bool is_wsrep_applier) my_hash_init(key_memory_user_var_entry, &user_vars, system_charset_info, USER_VARS_HASH_SIZE, 0, 0, (my_hash_get_key) get_var_key, (my_hash_free_key) free_user_var, HASH_THREAD_SPECIFIC); - my_hash_init(PSI_INSTRUMENT_ME, &sequences, system_charset_info, + my_hash_init(PSI_INSTRUMENT_ME, &sequences, Lex_ident_fs::charset_info(), SEQUENCES_HASH_SIZE, 0, 0, (my_hash_get_key) get_sequence_last_key, (my_hash_free_key) free_sequence_last, HASH_THREAD_SPECIFIC); @@ -1450,7 +1450,8 @@ void THD::change_user(void) my_hash_init(key_memory_user_var_entry, &user_vars, system_charset_info, USER_VARS_HASH_SIZE, 0, 0, (my_hash_get_key) get_var_key, (my_hash_free_key) free_user_var, HASH_THREAD_SPECIFIC); - my_hash_init(key_memory_user_var_entry, &sequences, system_charset_info, + my_hash_init(key_memory_user_var_entry, &sequences, + Lex_ident_fs::charset_info(), SEQUENCES_HASH_SIZE, 0, 0, (my_hash_get_key) get_sequence_last_key, (my_hash_free_key) free_sequence_last, HASH_THREAD_SPECIFIC); diff --git a/sql/sql_class.h b/sql/sql_class.h index 7e5d9ac96e3..7324ba73bf1 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -23,6 +23,7 @@ #include "dur_prop.h" #include #include "sql_const.h" +#include "lex_ident.h" #include #include "log.h" #include "rpl_tblmap.h" diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc index 61d6a529045..b371e27eb3a 100644 --- a/sql/sql_connect.cc +++ b/sql/sql_connect.cc @@ -509,7 +509,8 @@ extern "C" void free_table_stats(TABLE_STATS* table_stats) void init_global_table_stats(void) { - my_hash_init(PSI_INSTRUMENT_ME, &global_table_stats, system_charset_info, + my_hash_init(PSI_INSTRUMENT_ME, &global_table_stats, + Lex_ident_fs::charset_info(), max_connections, 0, 0, (my_hash_get_key) get_key_table_stats, (my_hash_free_key) free_table_stats, 0); } @@ -528,7 +529,8 @@ extern "C" void free_index_stats(INDEX_STATS* index_stats) void init_global_index_stats(void) { - my_hash_init(PSI_INSTRUMENT_ME, &global_index_stats, system_charset_info, + my_hash_init(PSI_INSTRUMENT_ME, &global_index_stats, + Lex_ident_fs::charset_info(), max_connections, 0, 0, (my_hash_get_key) get_key_index_stats, (my_hash_free_key) free_index_stats, 0); } diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 1dcc51f1332..63cd5c83d98 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -919,8 +919,7 @@ mysql_rm_db_internal(THD *thd, const LEX_CSTRING *db, bool if_exists, bool silen Disable drop of enabled log tables, must be done before name locking. This check is only needed if we are dropping the "mysql" database. */ - if ((rm_mysql_schema= - (my_strcasecmp(system_charset_info, MYSQL_SCHEMA_NAME.str, db->str) == 0))) + if ((rm_mysql_schema= MYSQL_SCHEMA_NAME.streq(*db))) { for (table= tables; table; table= table->next_local) if (check_if_log_table(table, TRUE, "DROP")) diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index 276cef6236b..4108f42eb14 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -1067,10 +1067,9 @@ static SQL_HANDLER *mysql_ha_find_match(THD *thd, TABLE_LIST *tables) if (tables->is_anonymous_derived_table()) continue; if ((! tables->db.str[0] || - ! my_strcasecmp(&my_charset_latin1, hash_tables->db.str, - tables->get_db_name())) && - ! my_strcasecmp(&my_charset_latin1, hash_tables->table_name.str, - tables->get_table_name())) + Lex_ident_db(tables->get_db_name()).streq(hash_tables->db)) && + Lex_ident_table(tables->get_table_name()). + streq(hash_tables->table_name)) { /* Link into hash_tables list */ hash_tables->next= head; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 5db53b6f2b8..e458cd51dde 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1154,8 +1154,9 @@ static bool wsrep_tables_accessible_when_detached(const TABLE_LIST *tables) { for (const TABLE_LIST *table= tables; table; table= table->next_global) { - LEX_CSTRING db= table->db, tn= table->table_name; - if (get_table_category(&db, &tn) < TABLE_CATEGORY_INFORMATION) + if (get_table_category(Lex_ident_db(table->db), + Lex_ident_table(table->table_name)) + < TABLE_CATEGORY_INFORMATION) return false; } return tables != NULL; @@ -6522,15 +6523,15 @@ static TABLE *find_temporary_table_for_rename(THD *thd, { TABLE_LIST *next= table->next_local; - if (!strcmp(table->get_db_name(), cur_table->get_db_name()) && - !strcmp(table->get_table_name(), cur_table->get_table_name())) + if (!strcmp(table->get_db_name().str, cur_table->get_db_name().str) && + !strcmp(table->get_table_name().str, cur_table->get_table_name().str)) { /* Table was moved away, can't be same as 'table' */ found= 1; res= 0; // Table can't be a temporary table } - if (!strcmp(next->get_db_name(), cur_table->get_db_name()) && - !strcmp(next->get_table_name(), cur_table->get_table_name())) + if (!strcmp(next->get_db_name().str, cur_table->get_db_name().str) && + !strcmp(next->get_table_name().str, cur_table->get_table_name().str)) { /* Table has matching name with new name of this table. cur_table should @@ -7299,7 +7300,7 @@ check_table_access(THD *thd, privilege_t requirements, TABLE_LIST *tables, INSERT_ACL : SELECT_ACL); } - if (check_access(thd, want_access, table_ref->get_db_name(), + if (check_access(thd, want_access, table_ref->get_db_name().str, &table_ref->grant.privilege, &table_ref->grant.m_internal, 0, no_errors)) diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 3ed8e108f8d..eb84ef56419 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1053,7 +1053,8 @@ public: ER_THD(thd, ER_TABLEACCESS_DENIED_ERROR), "SHOW VIEW", m_sctx->priv_user, m_sctx->host_or_ip, - m_top_view->get_db_name(), m_top_view->get_table_name()); + m_top_view->get_db_name().str, + m_top_view->get_table_name().str); } return m_view_access_denied_message_ptr; } @@ -1098,8 +1099,8 @@ public: push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, ER_VIEW_INVALID, ER_THD(thd, ER_VIEW_INVALID), - m_top_view->get_db_name(), - m_top_view->get_table_name()); + m_top_view->get_db_name().str, + m_top_view->get_table_name().str); is_handled= TRUE; break; @@ -6887,8 +6888,7 @@ static int get_schema_views_record(THD *thd, TABLE_LIST *tables, Security_context *sctx= thd->security_ctx; if (!tables->allowed_show) { - if (!my_strcasecmp(system_charset_info, tables->definer.user.str, - sctx->priv_user) && + if (!strcmp(tables->definer.user.str, sctx->priv_user) && !my_strcasecmp(system_charset_info, tables->definer.host.str, sctx->priv_host)) tables->allowed_show= TRUE; @@ -7981,7 +7981,7 @@ int fill_open_tables(THD *thd, TABLE_LIST *tables, COND *cond) TABLE *table= tables->table; CHARSET_INFO *cs= system_charset_info; OPEN_TABLE_LIST *open_list; - if (!(open_list= list_open_tables(thd, thd->lex->first_select_lex()->db.str, + if (!(open_list= list_open_tables(thd, thd->lex->first_select_lex()->db, wild)) && thd->is_fatal_error) DBUG_RETURN(1); diff --git a/sql/sql_string.h b/sql/sql_string.h index 3dbeb7b83cf..0475b2d1f6e 100644 --- a/sql/sql_string.h +++ b/sql/sql_string.h @@ -572,6 +572,11 @@ public: if (str.Alloced_length) Alloced_length= (uint32) (str.Alloced_length - offset); } + LEX_CSTRING to_lex_cstring() const + { + LEX_CSTRING tmp= {Ptr, str_length}; + return tmp; + } inline LEX_CSTRING *get_value(LEX_CSTRING *res) { res->str= Ptr; diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index d2e5ecbb4d8..8a0d761f51d 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -446,7 +446,7 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create) /* We don't allow creating triggers on tables in the 'mysql' schema */ - if (create && lex_string_eq(&tables->db, STRING_WITH_LEN("mysql"))) + if (create && Lex_ident_db(tables->db).streq(MYSQL_SCHEMA_NAME)) { my_error(ER_NO_TRIGGERS_ON_SYSTEM_SCHEMA, MYF(0)); DBUG_RETURN(TRUE); diff --git a/sql/table.cc b/sql/table.cc index cc8fb094e36..8f5b0ce3bcc 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -89,7 +89,7 @@ LEX_CSTRING INFORMATION_SCHEMA_NAME= {STRING_WITH_LEN("information_schema")}; LEX_CSTRING PERFORMANCE_SCHEMA_DB_NAME= {STRING_WITH_LEN("performance_schema")}; /* MYSQL_SCHEMA name */ -LEX_CSTRING MYSQL_SCHEMA_NAME= {STRING_WITH_LEN("mysql")}; +Lex_ident_db MYSQL_SCHEMA_NAME= {STRING_WITH_LEN("mysql")}; /* GENERAL_LOG name */ LEX_CSTRING GENERAL_LOG_NAME= {STRING_WITH_LEN("general_log")}; @@ -273,42 +273,38 @@ const char *fn_frm_ext(const char *name) } -TABLE_CATEGORY get_table_category(const LEX_CSTRING *db, - const LEX_CSTRING *name) +TABLE_CATEGORY get_table_category(const Lex_ident_db &db, + const Lex_ident_table &name) { - DBUG_ASSERT(db != NULL); - DBUG_ASSERT(name != NULL); - #ifdef WITH_WSREP - if (db->str && - my_strcasecmp(system_charset_info, db->str, WSREP_SCHEMA) == 0) + if (db.str && db.streq(MYSQL_SCHEMA_NAME)) { - if ((my_strcasecmp(system_charset_info, name->str, WSREP_STREAMING_TABLE) == 0 || - my_strcasecmp(system_charset_info, name->str, WSREP_CLUSTER_TABLE) == 0 || - my_strcasecmp(system_charset_info, name->str, WSREP_MEMBERS_TABLE) == 0)) + if (name.streq(Lex_ident_table{STRING_WITH_LEN(WSREP_STREAMING_TABLE)}) || + name.streq(Lex_ident_table{STRING_WITH_LEN(WSREP_CLUSTER_TABLE)}) || + name.streq(Lex_ident_table{STRING_WITH_LEN(WSREP_MEMBERS_TABLE)})) { return TABLE_CATEGORY_INFORMATION; } } #endif /* WITH_WSREP */ - if (is_infoschema_db(db)) + if (is_infoschema_db(&db)) return TABLE_CATEGORY_INFORMATION; - if (is_perfschema_db(db)) + if (is_perfschema_db(&db)) return TABLE_CATEGORY_PERFORMANCE; - if (lex_string_eq(&MYSQL_SCHEMA_NAME, db)) + if (db.streq(MYSQL_SCHEMA_NAME)) { - if (is_system_table_name(name->str, name->length)) + if (is_system_table_name(name.str, name.length)) return TABLE_CATEGORY_SYSTEM; - if (lex_string_eq(&GENERAL_LOG_NAME, name)) + if (name.streq(GENERAL_LOG_NAME)) return TABLE_CATEGORY_LOG; - if (lex_string_eq(&SLOW_LOG_NAME, name)) + if (name.streq(SLOW_LOG_NAME)) return TABLE_CATEGORY_LOG; - if (lex_string_eq(&TRANSACTION_REG_NAME, name)) + if (name.streq(TRANSACTION_REG_NAME)) return TABLE_CATEGORY_LOG; } @@ -361,7 +357,8 @@ TABLE_SHARE *alloc_table_share(const char *db, const char *table_name, strmov(path_buff, path); share->normalized_path.str= share->path.str; share->normalized_path.length= path_length; - share->table_category= get_table_category(& share->db, & share->table_name); + share->table_category= get_table_category(Lex_ident_db(share->db), + Lex_ident_table(share->table_name)); share->open_errno= ENOENT; /* The following will be updated in open_table_from_share */ share->can_do_row_logging= 1; diff --git a/sql/table.h b/sql/table.h index 97e595979b9..16a42b6e81e 100644 --- a/sql/table.h +++ b/sql/table.h @@ -22,6 +22,7 @@ #include "datadict.h" #include "sql_string.h" /* String */ #include "lex_string.h" +#include "lex_ident.h" #ifndef MYSQL_CLIENT @@ -522,8 +523,8 @@ enum enum_table_category typedef enum enum_table_category TABLE_CATEGORY; -TABLE_CATEGORY get_table_category(const LEX_CSTRING *db, - const LEX_CSTRING *name); +TABLE_CATEGORY get_table_category(const Lex_ident_db &db, + const Lex_ident_table &name); typedef struct st_table_field_type @@ -2880,7 +2881,10 @@ struct TABLE_LIST @brief Returns the name of the database that the referenced table belongs to. */ - const char *get_db_name() const { return view != NULL ? view_db.str : db.str; } + const LEX_CSTRING get_db_name() const + { + return view != NULL ? view_db : db; + } /** @brief Returns the name of the table that this TABLE_LIST represents. @@ -2888,7 +2892,10 @@ struct TABLE_LIST @details The unqualified table name or view name for a table or view, respectively. */ - const char *get_table_name() const { return view != NULL ? view_name.str : table_name.str; } + const LEX_CSTRING get_table_name() const + { + return view != NULL ? view_name : table_name; + } bool is_active_sjm(); bool is_jtbm() { return MY_TEST(jtbm_subselect != NULL); } st_select_lex_unit *get_unit(); @@ -3292,7 +3299,7 @@ extern LEX_CSTRING TRANSACTION_REG_NAME; /* information schema */ extern LEX_CSTRING INFORMATION_SCHEMA_NAME; -extern LEX_CSTRING MYSQL_SCHEMA_NAME; +extern Lex_ident_db MYSQL_SCHEMA_NAME; /* table names */ extern LEX_CSTRING MYSQL_PROC_NAME; diff --git a/sql/temporary_tables.cc b/sql/temporary_tables.cc index a28b5f96935..9687506762c 100644 --- a/sql/temporary_tables.cc +++ b/sql/temporary_tables.cc @@ -154,7 +154,8 @@ TABLE *THD::find_temporary_table(const TABLE_LIST *tl, Temporary_table_state state) { DBUG_ENTER("THD::find_temporary_table"); - TABLE *table= find_temporary_table(tl->get_db_name(), tl->get_table_name(), + TABLE *table= find_temporary_table(tl->get_db_name().str, + tl->get_table_name().str, state); DBUG_RETURN(table); } @@ -243,8 +244,8 @@ TMP_TABLE_SHARE *THD::find_tmp_table_share(const char *db, TMP_TABLE_SHARE *THD::find_tmp_table_share(const TABLE_LIST *tl) { DBUG_ENTER("THD::find_tmp_table_share"); - TMP_TABLE_SHARE *share= find_tmp_table_share(tl->get_db_name(), - tl->get_table_name()); + TMP_TABLE_SHARE *share= find_tmp_table_share(tl->get_db_name().str, + tl->get_table_name().str); DBUG_RETURN(share); } @@ -385,7 +386,7 @@ bool THD::open_temporary_table(TABLE_LIST *tl) */ if (!table && (share= find_tmp_table_share(tl))) { - table= open_temporary_table(share, tl->get_table_name()); + table= open_temporary_table(share, tl->get_table_name().str); /* Temporary tables are not safe for parallel replication. They were designed to be visible to one thread only, so have no table locking. @@ -1172,8 +1173,8 @@ bool THD::find_and_use_tmp_table(const TABLE_LIST *tl, TABLE **out_table) bool result; DBUG_ENTER("THD::find_and_use_tmp_table"); - key_length= create_tmp_table_def_key(key, tl->get_db_name(), - tl->get_table_name()); + key_length= create_tmp_table_def_key(key, tl->get_db_name().str, + tl->get_table_name().str); result= use_temporary_table(find_temporary_table(key, key_length, TMP_TABLE_NOT_IN_USE), out_table); diff --git a/storage/csv/ha_tina.cc b/storage/csv/ha_tina.cc index ec569feec9d..04e63530c0e 100644 --- a/storage/csv/ha_tina.cc +++ b/storage/csv/ha_tina.cc @@ -184,7 +184,8 @@ static int tina_init_func(void *p) tina_hton= (handlerton *)p; mysql_mutex_init(csv_key_mutex_tina, &tina_mutex, MY_MUTEX_INIT_FAST); (void) my_hash_init(csv_key_memory_tina_share, &tina_open_tables, - system_charset_info, 32, 0, 0, (my_hash_get_key) + Lex_ident_table::charset_info(), + 32, 0, 0, (my_hash_get_key) tina_get_key, 0, 0); tina_hton->db_type= DB_TYPE_CSV_DB; tina_hton->create= tina_create_handler; From 266495b93ef550210cd598f1d7eff6031b34a7a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 21 May 2024 16:45:07 +0300 Subject: [PATCH 19/31] MDEV-33817 fixup: Disable for macOS According to https://discussions.apple.com/thread/8256853 an attempt to use AVX512 registers on macOS will result in #UD (crash at runtime). Also, starting with clang-18 and GCC 14, we must add "evex512" to the target flags so that AVX and SSE instructions can use AVX512 specific encodings. This flag was introduced together with the avx10.1-512 target. Older compiler versions do not recognize "evex512". We do not want to write "avx10.1-512" because it could enable some AVX512 subfeatures that we do not have any CPUID check for. Reviewed by: Vladislav Vaintroub Tested on macOS by: Valerii Kravchuk --- mysys/crc32/crc32c_x86.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/mysys/crc32/crc32c_x86.cc b/mysys/crc32/crc32c_x86.cc index 317b3545c0c..1ea0689a14b 100644 --- a/mysys/crc32/crc32c_x86.cc +++ b/mysys/crc32/crc32c_x86.cc @@ -24,7 +24,11 @@ # endif #else # include -# if __GNUC__ >= 11 || (defined __clang_major__ && __clang_major__ >= 8) +# ifdef __APPLE__ /* AVX512 states are not enabled in XCR0 */ +# elif __GNUC__ >= 14 || (defined __clang_major__ && __clang_major__ >= 18) +# define TARGET "pclmul,evex512,avx512f,avx512dq,avx512bw,avx512vl,vpclmulqdq" +# define USE_VPCLMULQDQ __attribute__((target(TARGET))) +# elif __GNUC__ >= 11 || (defined __clang_major__ && __clang_major__ >= 8) # define TARGET "pclmul,avx512f,avx512dq,avx512bw,avx512vl,vpclmulqdq" # define USE_VPCLMULQDQ __attribute__((target(TARGET))) # endif From c4020b541c25b8f8bed2dd2b58d8d7a3a3122495 Mon Sep 17 00:00:00 2001 From: Yuchen Pei Date: Mon, 20 May 2024 09:44:47 +1000 Subject: [PATCH 20/31] MDEV-24610 MEMORY SE: check overflow in info calls with HA_STATUS_AUTO --- mysql-test/suite/parts/r/mdev_24610.result | 24 ++++++++++++++++++++++ mysql-test/suite/parts/t/mdev_24610.test | 22 ++++++++++++++++++++ storage/heap/hp_info.c | 6 +++++- 3 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 mysql-test/suite/parts/r/mdev_24610.result create mode 100644 mysql-test/suite/parts/t/mdev_24610.test diff --git a/mysql-test/suite/parts/r/mdev_24610.result b/mysql-test/suite/parts/r/mdev_24610.result new file mode 100644 index 00000000000..6b49b059993 --- /dev/null +++ b/mysql-test/suite/parts/r/mdev_24610.result @@ -0,0 +1,24 @@ +CREATE TABLE t (c BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY) ENGINE=MEMORY PARTITION BY KEY(); +INSERT INTO t VALUES (18446744073709551615); +select * from t; +c +18446744073709551615 +drop table t; +CREATE TABLE t (c BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY) ENGINE=MEMORY; +INSERT INTO t VALUES (18446744073709551615); +ALTER TABLE t PARTITION BY KEY(); +INSERT INTO t VALUES (1); +select * from t; +c +18446744073709551615 +1 +drop table t; +CREATE TABLE t (c BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY) ENGINE=MEMORY; +INSERT INTO t VALUES (18446744073709551615); +ALTER TABLE t PARTITION BY KEY(); +INSERT INTO t VALUES (NULL); +ERROR HY000: Failed to read auto-increment value from storage engine +select * from t; +c +18446744073709551615 +drop table t; diff --git a/mysql-test/suite/parts/t/mdev_24610.test b/mysql-test/suite/parts/t/mdev_24610.test new file mode 100644 index 00000000000..df3ce9fdf0b --- /dev/null +++ b/mysql-test/suite/parts/t/mdev_24610.test @@ -0,0 +1,22 @@ +--source include/have_innodb.inc +--source include/have_partition.inc + +CREATE TABLE t (c BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY) ENGINE=MEMORY PARTITION BY KEY(); +INSERT INTO t VALUES (18446744073709551615); +select * from t; +drop table t; + +CREATE TABLE t (c BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY) ENGINE=MEMORY; +INSERT INTO t VALUES (18446744073709551615); +ALTER TABLE t PARTITION BY KEY(); +INSERT INTO t VALUES (1); +select * from t; +drop table t; + +CREATE TABLE t (c BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY) ENGINE=MEMORY; +INSERT INTO t VALUES (18446744073709551615); +ALTER TABLE t PARTITION BY KEY(); +--error ER_AUTOINC_READ_FAILED +INSERT INTO t VALUES (NULL); +select * from t; +drop table t; diff --git a/storage/heap/hp_info.c b/storage/heap/hp_info.c index 41596d864a2..47b1ed6e846 100644 --- a/storage/heap/hp_info.c +++ b/storage/heap/hp_info.c @@ -40,6 +40,10 @@ int heap_info(reg1 HP_INFO *info,reg2 HEAPINFO *x, int flag ) x->errkey = info->errkey; x->create_time = info->s->create_time; if (flag & HA_STATUS_AUTO) - x->auto_increment= info->s->auto_increment + 1; + { + x->auto_increment= info->s->auto_increment+1; + if (!x->auto_increment) /* This shouldn't happen */ + x->auto_increment= ~(ulonglong) 0; + } DBUG_RETURN(0); } /* heap_info */ From 7c4c082349869b63ace23cd621585562684bbdf6 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Thu, 23 May 2024 14:18:34 +0400 Subject: [PATCH 21/31] MDEV-28387 UBSAN: runtime error: negation of -9223372036854775808 cannot be represented in type 'long long int'; cast to an unsigned type to negate this value to itself in my_strtoll10 on SELECT Fixing the condition to raise an overflow in the ulonglong representation of the number is greater or equal to 0x8000000000000000ULL. Before this change the condition did not catch -9223372036854775808 (the smallest possible signed negative longlong number). --- mysql-test/main/func_str.result | 8 ++++++++ mysql-test/main/func_str.test | 9 +++++++++ strings/my_strtoll10.c | 2 +- 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/mysql-test/main/func_str.result b/mysql-test/main/func_str.result index c071b92318a..e5a21af03a3 100644 --- a/mysql-test/main/func_str.result +++ b/mysql-test/main/func_str.result @@ -5311,5 +5311,13 @@ NULL DROP TABLE t1; DROP VIEW v1; # +# MDEV-28387 UBSAN: runtime error: negation of -9223372036854775808 cannot be represented in type 'long long int'; cast to an unsigned type to negate this value to itself in my_strtoll10 on SELECT +# +SET @a='-9223372036854775808'; +CREATE TABLE t (c1 INT,c2 CHAR); +SELECT SUBSTR(0,@a) FROM t; +SUBSTR(0,@a) +DROP TABLE t; +# # End of 10.5 tests # diff --git a/mysql-test/main/func_str.test b/mysql-test/main/func_str.test index 69161349720..49b5546abb8 100644 --- a/mysql-test/main/func_str.test +++ b/mysql-test/main/func_str.test @@ -2348,6 +2348,15 @@ DROP TABLE t1; DROP VIEW v1; +--echo # +--echo # MDEV-28387 UBSAN: runtime error: negation of -9223372036854775808 cannot be represented in type 'long long int'; cast to an unsigned type to negate this value to itself in my_strtoll10 on SELECT +--echo # + +SET @a='-9223372036854775808'; # Quite specific value; considerably varying it will not work +CREATE TABLE t (c1 INT,c2 CHAR); +SELECT SUBSTR(0,@a) FROM t; +DROP TABLE t; + --echo # --echo # End of 10.5 tests --echo # diff --git a/strings/my_strtoll10.c b/strings/my_strtoll10.c index 183829d7074..8144be7a1da 100644 --- a/strings/my_strtoll10.c +++ b/strings/my_strtoll10.c @@ -241,7 +241,7 @@ end4: *endptr= (char*) s; if (negative) { - if (li > MAX_NEGATIVE_NUMBER) + if (li >= MAX_NEGATIVE_NUMBER) goto overflow; return -((longlong) li); } From 736449d30ffb2ec71bd700ac84eb38ba30bb662c Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Tue, 21 May 2024 16:03:13 +0200 Subject: [PATCH 22/31] MDEV-34205: ASAN stack buffer overflow in strxnmov() in frm_file_exists Correct the second parameter for strxnmov to prevent potential buffer overflows. The second parameter must be one less than the size of the input buffer to avoid writing past the end of the buffer. While the second parameter is usually correct, there are exceptions that need fixing. This commit addresses the issue within frm_file_exists() and other affected places. --- mysql-test/main/drop.result | 5 +++++ mysql-test/main/drop.test | 6 ++++++ sql/handler.cc | 2 +- sql/sql_parse.cc | 2 +- sql/sql_table.cc | 2 +- sql/sys_vars.cc | 2 +- storage/innobase/handler/ha_innodb.cc | 2 +- 7 files changed, 16 insertions(+), 5 deletions(-) diff --git a/mysql-test/main/drop.result b/mysql-test/main/drop.result index d50ffabc9fa..710986fa1ec 100644 --- a/mysql-test/main/drop.result +++ b/mysql-test/main/drop.result @@ -256,3 +256,8 @@ drop database mysqltest; Warnings: Note 1008 Can't drop database 'mysqltest'; database doesn't exist set @@session.sql_if_exists=0; +# +# MDEV-34205 ASAN stack-buffer-overflow in strxnmov | frm_file_exists +# +DROP TABLE `##################################################_long`.`#################################################_long`; +ERROR 42S02: Unknown table '##################################################_long.#########################################...' diff --git a/mysql-test/main/drop.test b/mysql-test/main/drop.test index 5185ce30db0..6b926d3f0c1 100644 --- a/mysql-test/main/drop.test +++ b/mysql-test/main/drop.test @@ -361,3 +361,9 @@ drop table mysqltest.does_not_exists; drop database mysqltest; drop database mysqltest; set @@session.sql_if_exists=0; + +--echo # +--echo # MDEV-34205 ASAN stack-buffer-overflow in strxnmov | frm_file_exists +--echo # +--error ER_BAD_TABLE_ERROR +DROP TABLE `##################################################_long`.`#################################################_long`; diff --git a/sql/handler.cc b/sql/handler.cc index 42e1c3e7212..3acc0246aab 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -4356,7 +4356,7 @@ void handler::print_error(int error, myf errflag) if (error < HA_ERR_FIRST && bas_ext()[0]) { char buff[FN_REFLEN]; - strxnmov(buff, sizeof(buff), + strxnmov(buff, sizeof(buff)-1, table_share->normalized_path.str, bas_ext()[0], NULL); my_error(textno, errflag, buff, error); } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index e458cd51dde..b071c74b245 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -9564,7 +9564,7 @@ sql_kill_user(THD *thd, LEX_USER *user, killed_state state) break; case ER_KILL_DENIED_ERROR: char buf[DEFINER_LENGTH+1]; - strxnmov(buf, sizeof(buf), user->user.str, "@", user->host.str, NULL); + strxnmov(buf, sizeof(buf)-1, user->user.str, "@", user->host.str, NULL); my_printf_error(ER_KILL_DENIED_ERROR, ER_THD(thd, ER_CANNOT_USER), MYF(0), "KILL USER", buf); break; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 7941f1de78c..1ef0a6e3bef 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1906,7 +1906,7 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags) */ build_table_filename(path, sizeof(path) - 1, lpt->alter_info->db.str, lpt->alter_info->table_name.str, "", 0); - strxnmov(frm_name, sizeof(frm_name), path, reg_ext, NullS); + strxnmov(frm_name, sizeof(frm_name)-1, path, reg_ext, NullS); /* When we are changing to use new frm file we need to ensure that we don't collide with another thread in process to open the frm file. diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index 9a4180ae000..8ccd1bb235e 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -4655,7 +4655,7 @@ bool Sys_var_timestamp::on_check_access_session(THD *thd) const break; } char buf[1024]; - strxnmov(buf, sizeof(buf), "--secure-timestamp=", + strxnmov(buf, sizeof(buf)-1, "--secure-timestamp=", secure_timestamp_levels[opt_secure_timestamp], NULL); my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), buf); return true; diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index ff928a7d92a..7bed0ed73eb 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -13313,7 +13313,7 @@ ha_innobase::discard_or_import_tablespace( static bool frm_file_exists(const char *path) { char buff[FN_REFLEN]; - strxnmov(buff, FN_REFLEN, path, reg_ext, NullS); + strxnmov(buff, sizeof(buff)-1, path, reg_ext, NullS); return !access(buff, F_OK); } From 0ffa340a49cbbc7c5d3db563dc583fd23fa90c01 Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Fri, 24 May 2024 10:51:32 +0530 Subject: [PATCH 23/31] MDEV-34221 Errors about checksum mismatch on crash recovery are confusing - InnoDB should avoid printing the error message before restoring the first page from doublewrite buffer. --- mysql-test/suite/innodb/r/undo_space_dblwr.result | 2 +- mysql-test/suite/innodb/t/undo_space_dblwr.test | 2 +- storage/innobase/srv/srv0start.cc | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/mysql-test/suite/innodb/r/undo_space_dblwr.result b/mysql-test/suite/innodb/r/undo_space_dblwr.result index 4466df9857b..2172ce53cb7 100644 --- a/mysql-test/suite/innodb/r/undo_space_dblwr.result +++ b/mysql-test/suite/innodb/r/undo_space_dblwr.result @@ -12,7 +12,7 @@ set global innodb_fil_make_page_dirty_debug = 1; SET GLOBAL innodb_buf_flush_list_now = 1; # Kill the server # restart: --debug_dbug=+d,ib_log_checkpoint_avoid_hard --innodb_flush_sync=0 -FOUND 1 /Checksum mismatch in the first page of file/ in mysqld.1.err +FOUND 1 /Restoring page \[page id: space=1, page number=0\] of datafile '.*undo001' from the doublewrite buffer./ in mysqld.1.err check table t1; Table Op Msg_type Msg_text test.t1 check status OK diff --git a/mysql-test/suite/innodb/t/undo_space_dblwr.test b/mysql-test/suite/innodb/t/undo_space_dblwr.test index 52b19a4b7fb..4cf4d3b8b6d 100644 --- a/mysql-test/suite/innodb/t/undo_space_dblwr.test +++ b/mysql-test/suite/innodb/t/undo_space_dblwr.test @@ -39,7 +39,7 @@ EOF --source include/start_mysqld.inc let SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.err; -let SEARCH_PATTERN= Checksum mismatch in the first page of file; +let SEARCH_PATTERN= Restoring page \[page id: space=1, page number=0\] of datafile '.*undo001' from the doublewrite buffer.; --source include/search_pattern_in_file.inc check table t1; diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc index 9d64d4ce57f..640e83a33cf 100644 --- a/storage/innobase/srv/srv0start.cc +++ b/storage/innobase/srv/srv0start.cc @@ -554,7 +554,6 @@ err_exit: fsp_flags= mach_read_from_4(FSP_HEADER_OFFSET + FSP_SPACE_FLAGS + page); if (buf_page_is_corrupted(false, page, fsp_flags)) { - ib::error() << "Checksum mismatch in the first page of file " << name; if (recv_sys.dblwr.restore_first_page(space_id, name, fh)) goto err_exit; } From 44b23bb18476b9f2f3d88fabab41f206f3531f98 Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Fri, 24 May 2024 13:17:27 +0530 Subject: [PATCH 24/31] MDEV-34222 Alter operation on redundant table aborts the server - InnoDB page compression works only on COMPACT or DYNAMIC row format tables. So InnoDB should throw error when alter table tries to enable PAGE_COMPRESSED for redundant table. --- mysql-test/suite/innodb/r/table_flags.result | 11 +++++++++++ mysql-test/suite/innodb/t/table_flags.test | 12 ++++++++++++ storage/innobase/handler/handler0alter.cc | 9 +++++++++ 3 files changed, 32 insertions(+) diff --git a/mysql-test/suite/innodb/r/table_flags.result b/mysql-test/suite/innodb/r/table_flags.result index eada084d669..fcf2b68c7f6 100644 --- a/mysql-test/suite/innodb/r/table_flags.result +++ b/mysql-test/suite/innodb/r/table_flags.result @@ -210,3 +210,14 @@ ALTER TABLE t1 PAGE_COMPRESSED = 1; INSERT INTO t1 VALUES(2); # restart DROP TABLE t1; +# +# MDEV-34222 Alter operation on redundant table aborts the server +# +SET @df_row = @@global.INNODB_DEFAULT_ROW_FORMAT; +SET GLOBAL INNODB_DEFAULT_ROW_FORMAT=REDUNDANT; +CREATE TABLE t1 (c CHAR(1)) ENGINE=InnoDB; +SET GLOBAL INNODB_DEFAULT_ROW_FORMAT=compact; +ALTER TABLE t1 PAGE_COMPRESSED=1; +ERROR HY000: Table storage engine 'InnoDB' does not support the create option 'PAGE_COMPRESSED=1 ROW_FORMAT=REDUNDANT' +DROP TABLE t1; +SET @@global.INNODB_DEFAULT_ROW_FORMAT = @df_row; diff --git a/mysql-test/suite/innodb/t/table_flags.test b/mysql-test/suite/innodb/t/table_flags.test index 92ebdda442a..ab3c707af95 100644 --- a/mysql-test/suite/innodb/t/table_flags.test +++ b/mysql-test/suite/innodb/t/table_flags.test @@ -257,3 +257,15 @@ INSERT INTO t1 VALUES(2); let $shutdown_timeout = 0; --source include/restart_mysqld.inc DROP TABLE t1; + +--echo # +--echo # MDEV-34222 Alter operation on redundant table aborts the server +--echo # +SET @df_row = @@global.INNODB_DEFAULT_ROW_FORMAT; +SET GLOBAL INNODB_DEFAULT_ROW_FORMAT=REDUNDANT; +CREATE TABLE t1 (c CHAR(1)) ENGINE=InnoDB; +SET GLOBAL INNODB_DEFAULT_ROW_FORMAT=compact; +--error ER_ILLEGAL_HA_CREATE_OPTION +ALTER TABLE t1 PAGE_COMPRESSED=1; +DROP TABLE t1; +SET @@global.INNODB_DEFAULT_ROW_FORMAT = @df_row; diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 0c107111b34..ec34b7d1b67 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -8339,6 +8339,15 @@ field_changed: DBUG_RETURN(true); } + if ((ha_alter_info->handler_flags & ALTER_OPTIONS) + && ctx->page_compression_level + && !ctx->old_table->not_redundant()) { + my_error(ER_ILLEGAL_HA_CREATE_OPTION, MYF(0), + table_type(), + "PAGE_COMPRESSED=1 ROW_FORMAT=REDUNDANT"); + DBUG_RETURN(true); + } + if (!(ha_alter_info->handler_flags & INNOBASE_ALTER_DATA) && alter_templ_needs_rebuild(altered_table, ha_alter_info, ctx->new_table) From 79253261834e6e5286928e211b358d7508113dea Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Thu, 23 May 2024 16:42:15 +0400 Subject: [PATCH 25/31] MDEV-30931 UBSAN: negation of -X cannot be represented in type 'long long int'; cast to an unsigned type to negate this value to itself in get_interval_value on SELECT - Fixing the code in get_interval_value() to use Longlong_hybrid_null. This allows to handle correctly: - Signed and unsigned arguments (the old code assumed the argument to be signed) - Avoid undefined negation behavior the corner case with LONGLONG_MIN This fixes the UBSAN warning: negation of -9223372036854775808 cannot be represented in type 'long long int'; - Fixing the code in get_interval_value() to avoid overflow in the INTERVAL_QUARTER and INTERVAL_WEEK branches. This fixes the UBSAN warning: signed integer overflow: -9223372036854775808 * 7 cannot be represented in type 'long long int' - Fixing the INTERVAL_WEEK branch in date_add_interval() to handle huge numbers correctly. Before the change, huge positive numeber were treated as their negative complements. Note, some other branches still can be affected by this problem and should also be fixed eventually. --- mysql-test/main/func_date_add.result | 31 +++++++++++++++++++++++++ mysql-test/main/func_date_add.test | 17 ++++++++++++++ sql/item_timefunc.cc | 34 +++++++++++++++++++--------- sql/sql_time.cc | 16 +++++++++---- strings/my_strtoll10.c | 2 +- 5 files changed, 83 insertions(+), 17 deletions(-) diff --git a/mysql-test/main/func_date_add.result b/mysql-test/main/func_date_add.result index a6201a3c23f..1c2d9ab5eb1 100644 --- a/mysql-test/main/func_date_add.result +++ b/mysql-test/main/func_date_add.result @@ -200,3 +200,34 @@ select 30 + (20010101 + interval 2 day), x from v1; 20010133 20010133 drop view v1; End of 10.2 tests +# +# Start of 10.5 tests +# +# +# MDEV-30931 UBSAN: negation of -X cannot be represented in type 'long long int'; cast to an unsigned type to negate this value to itself in get_interval_value on SELECT +# +SELECT DATE_ADD('01-01-23',INTERVAL '9223372036854775808-02' WEEK); +DATE_ADD('01-01-23',INTERVAL '9223372036854775808-02' WEEK) +NULL +Warnings: +Warning 1292 Truncated incorrect INTEGER value: '9223372036854775808-02' +Warning 1441 Datetime function: datetime field overflow +SELECT DATE_ADD('01-01-23',INTERVAL -9223372036854775807 WEEK); +DATE_ADD('01-01-23',INTERVAL -9223372036854775807 WEEK) +NULL +Warnings: +Warning 1441 Datetime function: datetime field overflow +SELECT DATE_ADD('01-01-23',INTERVAL -9223372036854775808 WEEK); +DATE_ADD('01-01-23',INTERVAL -9223372036854775808 WEEK) +NULL +Warnings: +Warning 1441 Datetime function: datetime field overflow +SELECT DATE_ADD('01-01-23',INTERVAL -9223372036854775809 WEEK); +DATE_ADD('01-01-23',INTERVAL -9223372036854775809 WEEK) +NULL +Warnings: +Warning 1916 Got overflow when converting '-9223372036854775809' to INT. Value truncated +Warning 1441 Datetime function: datetime field overflow +# +# End of 10.5 tests +# diff --git a/mysql-test/main/func_date_add.test b/mysql-test/main/func_date_add.test index f9287b952d2..aa00fd144e2 100644 --- a/mysql-test/main/func_date_add.test +++ b/mysql-test/main/func_date_add.test @@ -169,3 +169,20 @@ select 30 + (20010101 + interval 2 day), x from v1; drop view v1; --echo End of 10.2 tests + +--echo # +--echo # Start of 10.5 tests +--echo # + +--echo # +--echo # MDEV-30931 UBSAN: negation of -X cannot be represented in type 'long long int'; cast to an unsigned type to negate this value to itself in get_interval_value on SELECT +--echo # + +SELECT DATE_ADD('01-01-23',INTERVAL '9223372036854775808-02' WEEK); +SELECT DATE_ADD('01-01-23',INTERVAL -9223372036854775807 WEEK); +SELECT DATE_ADD('01-01-23',INTERVAL -9223372036854775808 WEEK); +SELECT DATE_ADD('01-01-23',INTERVAL -9223372036854775809 WEEK); + +--echo # +--echo # End of 10.5 tests +--echo # diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 2f689acc54c..cd0e88544e0 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -1306,6 +1306,15 @@ my_decimal *Item_func_time_to_sec::decimal_op(my_decimal* buf) } +static inline +uint32 adjust_interval_field_uint32(ulonglong value, int32 multiplier) +{ + return value > ((ulonglong) (uint32) (UINT_MAX32)) / multiplier ? + (uint32) UINT_MAX32 : + (uint32) (value * multiplier); +} + + /** Convert a string to a interval value. @@ -1316,7 +1325,7 @@ bool get_interval_value(THD *thd, Item *args, interval_type int_type, INTERVAL *interval) { ulonglong array[5]; - longlong UNINIT_VAR(value); + ulonglong UNINIT_VAR(value); const char *UNINIT_VAR(str); size_t UNINIT_VAR(length); CHARSET_INFO *UNINIT_VAR(cs); @@ -1343,14 +1352,17 @@ bool get_interval_value(THD *thd, Item *args, } else if ((int) int_type <= INTERVAL_MICROSECOND) { - value= args->val_int(); - if (args->null_value) - return 1; - if (value < 0) - { - interval->neg=1; - value= -value; - } + /* + Let's use Longlong_hybrid_null to handle correctly: + - signed and unsigned values + - the corner case with LONGLONG_MIN + (avoid undefined behavior with its negation) + */ + const Longlong_hybrid_null nr= args->to_longlong_hybrid_null(); + if (nr.is_null()) + return true; + value= nr.abs(); + interval->neg= nr.neg() ? 1 : 0; } else { @@ -1377,13 +1389,13 @@ bool get_interval_value(THD *thd, Item *args, interval->year= (ulong) value; break; case INTERVAL_QUARTER: - interval->month= (ulong)(value*3); + interval->month= adjust_interval_field_uint32(value, 3); break; case INTERVAL_MONTH: interval->month= (ulong) value; break; case INTERVAL_WEEK: - interval->day= (ulong)(value*7); + interval->day= adjust_interval_field_uint32(value, 7); break; case INTERVAL_DAY: interval->day= (ulong) value; diff --git a/sql/sql_time.cc b/sql/sql_time.cc index 12e4460ed25..90bf701fadc 100644 --- a/sql/sql_time.cc +++ b/sql/sql_time.cc @@ -930,7 +930,7 @@ void make_truncated_value_warning(THD *thd, bool date_add_interval(THD *thd, MYSQL_TIME *ltime, interval_type int_type, const INTERVAL &interval, bool push_warn) { - long period, sign; + long sign; sign= (interval.neg == (bool)ltime->neg ? 1 : -1); @@ -1001,13 +1001,17 @@ bool date_add_interval(THD *thd, MYSQL_TIME *ltime, interval_type int_type, break; } case INTERVAL_WEEK: - period= (calc_daynr(ltime->year,ltime->month,ltime->day) + - sign * (long) interval.day); + { + longlong period= calc_daynr(ltime->year, ltime->month, ltime->day) + + (longlong) sign * (longlong) interval.day; + if (period < 0 || period > 0x7FFFFFFF) + goto invalid_date; /* Daynumber from year 0 to 9999-12-31 */ if (get_date_from_daynr((long) period,<ime->year,<ime->month, <ime->day)) goto invalid_date; break; + } case INTERVAL_YEAR: ltime->year+= sign * (long) interval.year; if ((ulong) ltime->year >= 10000L) @@ -1019,8 +1023,9 @@ bool date_add_interval(THD *thd, MYSQL_TIME *ltime, interval_type int_type, case INTERVAL_YEAR_MONTH: case INTERVAL_QUARTER: case INTERVAL_MONTH: - period= (ltime->year*12 + sign * (long) interval.year*12 + - ltime->month-1 + sign * (long) interval.month); + { + long period= (ltime->year*12 + sign * (long) interval.year*12 + + ltime->month-1 + sign * (long) interval.month); if ((ulong) period >= 120000L) goto invalid_date; ltime->year= (uint) (period / 12); @@ -1033,6 +1038,7 @@ bool date_add_interval(THD *thd, MYSQL_TIME *ltime, interval_type int_type, ltime->day++; // Leap-year } break; + } default: goto null_date; } diff --git a/strings/my_strtoll10.c b/strings/my_strtoll10.c index 8144be7a1da..74baef080eb 100644 --- a/strings/my_strtoll10.c +++ b/strings/my_strtoll10.c @@ -241,7 +241,7 @@ end4: *endptr= (char*) s; if (negative) { - if (li >= MAX_NEGATIVE_NUMBER) + if (li >= MAX_NEGATIVE_NUMBER) // Avoid undefined behavior goto overflow; return -((longlong) li); } From 4a158ec167028060000f4087db69703aab3c42a5 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Mon, 27 May 2024 12:46:51 +0400 Subject: [PATCH 26/31] MDEV-34226 On startup: UBSAN: applying zero offset to null pointer in my_copy_fix_mb from strings/ctype-mb.c and other locations nullptr+0 is an UB (undefined behavior). - Fixing my_string_metadata_get_mb() to handle {nullptr,0} without UB. - Fixing THD::copy_with_error() to disallow {nullptr,0} by DBUG_ASSERT(). - Fixing parse_client_handshake_packet() to call THD::copy_with_error() with an empty string {"",0} instead of NULL string {nullptr,0}. --- mysql-test/main/connect-no-db.result | 9 +++++++++ mysql-test/main/connect-no-db.test | 10 ++++++++++ sql/sql_acl.cc | 4 +++- sql/sql_class.cc | 2 ++ strings/ctype.c | 2 +- 5 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 mysql-test/main/connect-no-db.result create mode 100644 mysql-test/main/connect-no-db.test diff --git a/mysql-test/main/connect-no-db.result b/mysql-test/main/connect-no-db.result new file mode 100644 index 00000000000..75597c0753c --- /dev/null +++ b/mysql-test/main/connect-no-db.result @@ -0,0 +1,9 @@ +# +# MDEV-34226 On startup: UBSAN: applying zero offset to null pointer in my_copy_fix_mb from strings/ctype-mb.c and other locations +# +connect con1,localhost,root,,"*NO-ONE*"; +SELECT database(); +database() +NULL +disconnect con1; +connection default; diff --git a/mysql-test/main/connect-no-db.test b/mysql-test/main/connect-no-db.test new file mode 100644 index 00000000000..bc36499e703 --- /dev/null +++ b/mysql-test/main/connect-no-db.test @@ -0,0 +1,10 @@ +--echo # +--echo # MDEV-34226 On startup: UBSAN: applying zero offset to null pointer in my_copy_fix_mb from strings/ctype-mb.c and other locations +--echo # + +# Connect without a database + +connect (con1,localhost,root,,"*NO-ONE*"); +SELECT database(); +disconnect con1; +connection default; diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index dd222998b3a..ee0351cb38f 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -13799,9 +13799,11 @@ static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio, Since 4.1 all database names are stored in utf8 The cast is ok as copy_with_error will create a new area for db */ + DBUG_ASSERT(db || !db_len); + // Don't pass db==nullptr to avoid UB nullptr+0 inside copy_with_error() if (unlikely(thd->copy_with_error(system_charset_info, (LEX_STRING*) &mpvio->db, - thd->charset(), db, db_len))) + thd->charset(), db ? db : "", db_len))) return packet_error; user_len= copy_and_convert(user_buff, sizeof(user_buff) - 1, diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 34cd63d7839..124ed6e051d 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -2522,6 +2522,8 @@ bool THD::copy_with_error(CHARSET_INFO *dstcs, LEX_STRING *dst, CHARSET_INFO *srccs, const char *src, size_t src_length) { + // Don't allow NULL to avoid UB in the called functions: nullptr+0 + DBUG_ASSERT(src); String_copier_with_error status; return copy_fix(dstcs, dst, srccs, src, src_length, &status) || status.check_errors(srccs, src, src_length); diff --git a/strings/ctype.c b/strings/ctype.c index f1c1ec9d7fc..ccc59a20fe8 100644 --- a/strings/ctype.c +++ b/strings/ctype.c @@ -867,7 +867,7 @@ static void my_string_metadata_get_mb(MY_STRING_METADATA *metadata, CHARSET_INFO *cs, const char *str, ulong length) { - const char *strend= str + length; + const char *strend= str ? str + length : NULL; // Avoid UB nullptr+0 for (my_string_metadata_init(metadata) ; str < strend; metadata->char_length++) From 83a04be84aa5ed95f24371d2eb125216e4a89eab Mon Sep 17 00:00:00 2001 From: Souradeep Saha Date: Thu, 23 May 2024 21:35:18 +0000 Subject: [PATCH 27/31] Fix Various Typos Fix various typos, in comments and DEBUG statements, and code changes are non-functional. All new code of the whole pull request, including one or several files that are either new files or modified ones, are contributed under the BSD-new license. I am contributing on behalf of my employer Amazon Web Services, Inc. --- client/mysqladmin.cc | 2 +- client/mysqldump.c | 6 +++--- client/mysqlimport.c | 8 ++++---- sql-common/client.c | 14 +++++++------- sql-common/my_time.c | 20 ++++++++++---------- 5 files changed, 25 insertions(+), 25 deletions(-) diff --git a/client/mysqladmin.cc b/client/mysqladmin.cc index 098e7ef7c83..2dba3d272fb 100644 --- a/client/mysqladmin.cc +++ b/client/mysqladmin.cc @@ -417,7 +417,7 @@ int main(int argc,char *argv[]) is given a t!=0, we get an endless loop, or n iterations if --count=n was given an n!=0. If --sleep wasn't given, we get one iteration. - To wit, --wait loops the connection-attempts, while --sleep loops + To wait, --wait loops the connection-attempts, while --sleep loops the command execution (endlessly if no --count is given). */ diff --git a/client/mysqldump.c b/client/mysqldump.c index d3d6851b65a..521e048497d 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -5842,7 +5842,7 @@ static int dump_selected_tables(char *db, char **table_names, int tables) free_root(&glob_root, MYF(0)); } maybe_die(EX_ILLEGAL_TABLE, "Couldn't find table: \"%s\"", *table_names); - /* We shall countinue here, if --force was given */ + /* We shall continue here, if --force was given */ } } end= pos; @@ -5863,7 +5863,7 @@ static int dump_selected_tables(char *db, char **table_names, int tables) free_root(&glob_root, MYF(0)); } DB_error(mysql, "when doing LOCK TABLES"); - /* We shall countinue here, if --force was given */ + /* We shall continue here, if --force was given */ } } dynstr_free(&lock_tables_query); @@ -5875,7 +5875,7 @@ static int dump_selected_tables(char *db, char **table_names, int tables) free_root(&glob_root, MYF(0)); DB_error(mysql, "when doing refresh"); } - /* We shall countinue here, if --force was given */ + /* We shall continue here, if --force was given */ else verbose_msg("-- dump_selected_tables : logs flushed successfully!\n"); } diff --git a/client/mysqlimport.c b/client/mysqlimport.c index b7c507e359d..3a9f9005cb6 100644 --- a/client/mysqlimport.c +++ b/client/mysqlimport.c @@ -414,7 +414,7 @@ static void lock_table(MYSQL *mysql, int tablecount, char **raw_tablename) dynstr_append(&query, " WRITE,"); } if (mysql_real_query(mysql, query.str, (ulong)query.length-1)) - db_error(mysql); /* We shall countinue here, if --force was given */ + db_error(mysql); /* We shall continue here, if --force was given */ } @@ -612,7 +612,7 @@ pthread_handler_t worker_thread(void *arg) if (mysql_query(mysql, "/*!40101 set @@character_set_database=binary */;")) { - db_error(mysql); /* We shall countinue here, if --force was given */ + db_error(mysql); /* We shall continue here, if --force was given */ goto error; } @@ -736,12 +736,12 @@ int main(int argc, char **argv) if (!(mysql= db_connect(current_host,current_db,current_user,opt_password))) { free_defaults(argv_to_free); - return(1); /* purecov: deadcode */ + return(1); /* purecov: dead code */ } if (mysql_query(mysql, "/*!40101 set @@character_set_database=binary */;")) { - db_error(mysql); /* We shall countinue here, if --force was given */ + db_error(mysql); /* We shall continue here, if --force was given */ return(1); } diff --git a/sql-common/client.c b/sql-common/client.c index 687f28cea28..13882caa340 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -21,7 +21,7 @@ The differences for the two cases are: - Things that only works for the client: - - Trying to automaticly determinate user name if not supplied to + - Trying to automatically determinate user name if not supplied to mysql_real_connect() - Support for reading local file with LOAD DATA LOCAL - SHARED memory handling @@ -30,7 +30,7 @@ - Things that only works for the server - Alarm handling on connect - In all other cases, the code should be idential for the client and + In all other cases, the code should be identical for the client and server. */ @@ -1457,7 +1457,7 @@ mysql_init(MYSQL *mysql) mysql_reconnect()). This is a change: < 5.0.3 mysql->reconnect was set to 1 by default. How this change impacts existing apps: - - existing apps which relyed on the default will see a behaviour change; + - existing apps which relied on the default will see a behaviour change; they will have to set reconnect=1 after mysql_real_connect(). - existing apps which explicitly asked for reconnection (the only way they could do it was by setting mysql.reconnect to 1 after mysql_real_connect()) @@ -1936,7 +1936,7 @@ typedef struct { /* - Write 1-8 bytes of string length header infromation to dest depending on + Write 1-8 bytes of string length header information to dest depending on value of src_len, then copy src_len bytes from src to dest. @param dest Destination buffer of size src_len+8 @@ -2217,7 +2217,7 @@ static int send_client_reply_packet(MCPVIO_EXT *mpvio, } #endif /* HAVE_OPENSSL */ - DBUG_PRINT("info",("Server version = '%s' capabilites: %lu status: %u client_flag: %lu", + DBUG_PRINT("info",("Server version = '%s' capabilities: %lu status: %u client_flag: %lu", mysql->server_version, mysql->server_capabilities, mysql->server_status, mysql->client_flag)); @@ -2354,7 +2354,7 @@ static int client_mpvio_read_packet(struct st_plugin_vio *mpv, uchar **buf) to send data to the server. It transparently wraps the data into a change user or authentication - handshake packet, if neccessary. + handshake packet, if necessary. */ static int client_mpvio_write_packet(struct st_plugin_vio *mpv, const uchar *pkt, int pkt_len) @@ -3830,7 +3830,7 @@ mysql_options(MYSQL *mysql,enum mysql_option option, const void *arg) mysql->options.compress= 1; /* Remember for connect */ mysql->options.client_flag|= CLIENT_COMPRESS; break; - case MYSQL_OPT_NAMED_PIPE: /* This option is depricated */ + case MYSQL_OPT_NAMED_PIPE: /* This option is deprecated */ mysql->options.protocol=MYSQL_PROTOCOL_PIPE; /* Force named pipe */ break; case MYSQL_OPT_LOCAL_INFILE: /* Allow LOAD DATA LOCAL ?*/ diff --git a/sql-common/my_time.c b/sql-common/my_time.c index 96674723b34..eff39cd5eae 100644 --- a/sql-common/my_time.c +++ b/sql-common/my_time.c @@ -475,7 +475,7 @@ str_to_DDhhmmssff_internal(my_bool neg, const char *str, size_t length, DESCRIPTION - At least the following formats are recogniced (based on number of digits) + At least the following formats are recognized (based on number of digits) YYMMDD, YYYYMMDD, YYMMDDHHMMSS, YYYYMMDDHHMMSS YY-MM-DD, YYYY-MM-DD, YY-MM-DD HH.MM.SS YYYYMMDDTHHMMSS where T is a the character T (ISO8601) @@ -1223,7 +1223,7 @@ long calc_daynr(uint year,uint month,uint day) /* Convert time in MYSQL_TIME representation in system time zone to its - my_time_t form (number of seconds in UTC since begginning of Unix Epoch). + my_time_t form (number of seconds in UTC since beginning of Unix Epoch). SYNOPSIS my_system_gmt_sec() @@ -1291,7 +1291,7 @@ my_system_gmt_sec(const MYSQL_TIME *t_src, long *my_timezone, uint *error_code) two days earlier, and then add these days to the final value. The same trick is done for the values close to 0 in time_t - representation for platfroms with unsigned time_t (QNX). + representation for platforms with unsigned time_t (QNX). To be more verbose, here is a sample (extracted from the code below): (calc_daynr(2038, 1, 19) - (long) days_at_timestart)*86400L + 4*3600L @@ -1303,9 +1303,9 @@ my_system_gmt_sec(const MYSQL_TIME *t_src, long *my_timezone, uint *error_code) will give -3600. On some platforms, (E.g. on QNX) time_t is unsigned and localtime(-3600) - wil give us a date around 2106 year. Which is no good. + will give us a date around 2106 year. Which is no good. - Theoreticaly, there could be problems with the latter conversion: + Theoretically, there could be problems with the latter conversion: there are at least two timezones, which had time switches near 1 Jan of 1970 (because of political reasons). These are America/Hermosillo and America/Mazatlan time zones. They changed their offset on @@ -1335,7 +1335,7 @@ my_system_gmt_sec(const MYSQL_TIME *t_src, long *my_timezone, uint *error_code) else { /* - We can get 0 in time_t representaion only on 1969, 31 of Dec or on + We can get 0 in time_t representation only on 1969, 31 of Dec or on 1970, 1 of Jan. For both dates we use shift, which is added to t->day in order to step out a bit from the border. This is required for platforms, where time_t is unsigned. @@ -1430,9 +1430,9 @@ my_system_gmt_sec(const MYSQL_TIME *t_src, long *my_timezone, uint *error_code) First check will pass for platforms with signed time_t. instruction above (tmp+= shift*86400L) could exceed MAX_INT32 (== TIMESTAMP_MAX_VALUE) and overflow will happen. - So, tmp < TIMESTAMP_MIN_VALUE will be triggered. On platfroms + So, tmp < TIMESTAMP_MIN_VALUE will be triggered. On platforms with unsigned time_t tmp+= shift*86400L might result in a number, - larger then TIMESTAMP_MAX_VALUE, so another check will work. + larger than TIMESTAMP_MAX_VALUE, so another check will work. */ if (!IS_TIME_T_VALID_FOR_TIMESTAMP(tmp)) { @@ -1545,8 +1545,8 @@ static inline char* fmt_number2(uint8 val, char *out) - 0.225 sec (current) - 0.219 sec (array) - It demonstrated an additional 3% performance imrovement one these queries. - However, as the array size is too huge, we afraid that it will flush data + It demonstrated an additional 3% performance improvement one these queries. + However, as the array size is too huge, we are afraid that it will flush data from the CPU memory cache, which under real load may affect negatively. Let's keep using the fmt_number4() version with division and remainder From 1929a698a362cd9811161a06518608b9aefcee45 Mon Sep 17 00:00:00 2001 From: Andrew Hutchings Date: Wed, 29 May 2024 10:27:58 +0100 Subject: [PATCH 28/31] Update README for branch choice This commit updates the README to indicate that the "Get the code, build it, test it" link will help decide the correct branch to work in. Also fixes a grammar issue and cleans-up the Markdown a little bit. --- README.md | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 5fe95f46a6b..a8fbc119f0f 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,8 @@ -Code status: ------------- +# Code status: * [![Appveyor CI status](https://ci.appveyor.com/api/projects/status/4u6pexmtpuf8jq66?svg=true)](https://ci.appveyor.com/project/rasmushoj/server) ci.appveyor.com -## MariaDB: The innovative open source database +## MariaDB: The innovative open source database MariaDB was designed as a drop-in replacement of MySQL(R) with more features, new storage engines, fewer bugs, and better performance. @@ -33,20 +32,19 @@ https://mariadb.com/kb/en/mariadb-versus-mysql-compatibility/ https://mariadb.com/kb/en/new-and-old-releases/ -Getting the code, building it and testing it ---------------------------------------------------------------- +# Getting the code, building it and testing it -Refer to the following guide: https://mariadb.org/get-involved/getting-started-for-developers/get-code-build-test/ which outlines how to correctly build the source code and run the MariaDB testing framework. +Refer to the following guide: https://mariadb.org/get-involved/getting-started-for-developers/get-code-build-test/ +which outlines how to build the source code correctly and run the MariaDB testing framework, +as well as which branch to target for your contributions. -Help ------ +# Help More help is available from the Maria Discuss mailing list https://lists.mariadb.org/postorius/lists/discuss.lists.mariadb.org/ and MariaDB's Zulip -instance, https://mariadb.zulipchat.com/ +instance, https://mariadb.zulipchat.com/ -Licensing ---------- +# Licensing *************************************************************************** @@ -60,8 +58,7 @@ license information can be found in the THIRDPARTY file. *************************************************************************** -Bug Reports ------------- +# Bug Reports Bug and/or error reports regarding MariaDB should be submitted at: https://jira.mariadb.org From b0b463a894bab4e6cd7786924b1a0afa62d0cd42 Mon Sep 17 00:00:00 2001 From: Dave Gosselin Date: Wed, 29 May 2024 12:36:58 -0400 Subject: [PATCH 29/31] MDEV-33616 Fix memleak in pfs_noop Invoke cleanup routine at the end of pfs_noop. --- storage/perfschema/unittest/pfs_noop-t.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/storage/perfschema/unittest/pfs_noop-t.cc b/storage/perfschema/unittest/pfs_noop-t.cc index 57e8cfd8a0a..6d5e4eb152f 100644 --- a/storage/perfschema/unittest/pfs_noop-t.cc +++ b/storage/perfschema/unittest/pfs_noop-t.cc @@ -240,6 +240,7 @@ int main(int, char **) MY_INIT("pfs_noop-t"); test_noop(); + my_end(MY_CHECK_ERROR); return (exit_status()); } From c71275b69ee4f36a7e46160ae4f3709e662cc72c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 30 May 2024 14:22:00 +0300 Subject: [PATCH 30/31] Fix ./mtr --repeat=2 main.func_str --- mysql-test/main/func_str.test | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/main/func_str.test b/mysql-test/main/func_str.test index 49b5546abb8..c42c27538d8 100644 --- a/mysql-test/main/func_str.test +++ b/mysql-test/main/func_str.test @@ -1545,6 +1545,7 @@ CREATE TABLE t1 ( a TEXT ); SELECT insert( substring_index( 'a', 'a', 'b' ), 1, 0, 'x' ); --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR --eval LOAD DATA INFILE '$MYSQLTEST_VARDIR/tmp/bug58165.txt' INTO TABLE t1; +--remove_file $MYSQLTEST_VARDIR/tmp/bug58165.txt SELECT * FROM t1; DROP TABLE t1; From 0c440abd5e0f2a31e1e82c0a927e7d2a0d3b9c5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 30 May 2024 14:23:45 +0300 Subject: [PATCH 31/31] MDEV-31340 fixup: Add end-of-test marker --- mysql-test/main/view_grant.result | 1 + mysql-test/main/view_grant.test | 2 ++ 2 files changed, 3 insertions(+) diff --git a/mysql-test/main/view_grant.result b/mysql-test/main/view_grant.result index 818a15f86ce..f1bebf98ecd 100644 --- a/mysql-test/main/view_grant.result +++ b/mysql-test/main/view_grant.result @@ -1985,3 +1985,4 @@ connection default; DROP VIEW v1; DROP USER foo; DROP USER FOO; +# End of 10.5 tests diff --git a/mysql-test/main/view_grant.test b/mysql-test/main/view_grant.test index a5019e88d65..686a9428bf6 100644 --- a/mysql-test/main/view_grant.test +++ b/mysql-test/main/view_grant.test @@ -2234,3 +2234,5 @@ SELECT CURRENT_USER; DROP VIEW v1; DROP USER foo; DROP USER FOO; + +--echo # End of 10.5 tests