From 363ba107842127c8b23869b314a285e914f4a74f Mon Sep 17 00:00:00 2001 From: Robert Bindar Date: Tue, 2 Feb 2021 14:57:16 +0200 Subject: [PATCH 01/26] MDEV-24363 mysql.user password_expired column is incorrect The mysql.user view password_expired column should display the right result, in sync with whether an account has its password expired or not For mariadb 10.4+ upgrades before this commit, the mysql.user view needs to be dropped and recreated to actually make the view display the correct value for the password_expired column. --- mysql-test/main/information_schema.result | 2 +- mysql-test/main/mysql_upgrade.result | 4 +- mysql-test/main/system_mysql_db.result | 2 +- .../main/system_mysql_db_fix40123.result | 2 +- .../main/system_mysql_db_fix50030.result | 2 +- .../main/system_mysql_db_fix50117.result | 2 +- mysql-test/main/upgrade_MDEV-23102-1.result | 1 - mysql-test/main/upgrade_MDEV-23102-1.test | 1 - mysql-test/main/upgrade_MDEV-23102-2.result | 1 - mysql-test/main/upgrade_MDEV-23102-2.test | 1 - mysql-test/main/upgrade_mdev_24363.result | 129 ++++++++++++++++++ mysql-test/main/upgrade_mdev_24363.test | 71 ++++++++++ scripts/mysql_system_tables.sql | 2 +- scripts/mysql_system_tables_fix.sql | 2 +- 14 files changed, 209 insertions(+), 13 deletions(-) create mode 100644 mysql-test/main/upgrade_mdev_24363.result create mode 100644 mysql-test/main/upgrade_mdev_24363.test diff --git a/mysql-test/main/information_schema.result b/mysql-test/main/information_schema.result index 024d481cca9..76423a266d7 100644 --- a/mysql-test/main/information_schema.result +++ b/mysql-test/main/information_schema.result @@ -565,7 +565,7 @@ create view v2 (c) as select a from t1 WITH LOCAL CHECK OPTION; create view v3 (c) as select a from t1 WITH CASCADED CHECK OPTION; select * from information_schema.views; TABLE_CATALOG TABLE_SCHEMA TABLE_NAME VIEW_DEFINITION CHECK_OPTION IS_UPDATABLE DEFINER SECURITY_TYPE CHARACTER_SET_CLIENT COLLATION_CONNECTION ALGORITHM -def mysql user select `mysql`.`global_priv`.`Host` AS `Host`,`mysql`.`global_priv`.`User` AS `User`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.plugin') in ('mysql_native_password','mysql_old_password'),ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.authentication_string'),''),'') AS `Password`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 1,'Y','N') AS `Select_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 2,'Y','N') AS `Insert_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 4,'Y','N') AS `Update_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 8,'Y','N') AS `Delete_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 16,'Y','N') AS `Create_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 32,'Y','N') AS `Drop_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 64,'Y','N') AS `Reload_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 128,'Y','N') AS `Shutdown_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 256,'Y','N') AS `Process_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 512,'Y','N') AS `File_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 1024,'Y','N') AS `Grant_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 2048,'Y','N') AS `References_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 4096,'Y','N') AS `Index_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 8192,'Y','N') AS `Alter_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 16384,'Y','N') AS `Show_db_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 32768,'Y','N') AS `Super_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 65536,'Y','N') AS `Create_tmp_table_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 131072,'Y','N') AS `Lock_tables_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 262144,'Y','N') AS `Execute_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 524288,'Y','N') AS `Repl_slave_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 1048576,'Y','N') AS `Repl_client_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 2097152,'Y','N') AS `Create_view_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 4194304,'Y','N') AS `Show_view_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 8388608,'Y','N') AS `Create_routine_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 16777216,'Y','N') AS `Alter_routine_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 33554432,'Y','N') AS `Create_user_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 67108864,'Y','N') AS `Event_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 134217728,'Y','N') AS `Trigger_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 268435456,'Y','N') AS `Create_tablespace_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 536870912,'Y','N') AS `Delete_history_priv`,elt(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.ssl_type'),0) + 1,'','ANY','X509','SPECIFIED') AS `ssl_type`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.ssl_cipher'),'') AS `ssl_cipher`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.x509_issuer'),'') AS `x509_issuer`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.x509_subject'),'') AS `x509_subject`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_questions'),0) as unsigned) AS `max_questions`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_updates'),0) as unsigned) AS `max_updates`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_connections'),0) as unsigned) AS `max_connections`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_user_connections'),0) as signed) AS `max_user_connections`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.plugin'),'') AS `plugin`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.authentication_string'),'') AS `authentication_string`,'N' AS `password_expired`,elt(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.is_role'),0) + 1,'N','Y') AS `is_role`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.default_role'),'') AS `default_role`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_statement_time'),0.0) as decimal(12,6)) AS `max_statement_time` from `mysql`.`global_priv` NONE YES mariadb.sys@localhost DEFINER latin1 latin1_swedish_ci UNDEFINED +def mysql user select `mysql`.`global_priv`.`Host` AS `Host`,`mysql`.`global_priv`.`User` AS `User`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.plugin') in ('mysql_native_password','mysql_old_password'),ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.authentication_string'),''),'') AS `Password`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 1,'Y','N') AS `Select_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 2,'Y','N') AS `Insert_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 4,'Y','N') AS `Update_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 8,'Y','N') AS `Delete_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 16,'Y','N') AS `Create_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 32,'Y','N') AS `Drop_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 64,'Y','N') AS `Reload_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 128,'Y','N') AS `Shutdown_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 256,'Y','N') AS `Process_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 512,'Y','N') AS `File_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 1024,'Y','N') AS `Grant_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 2048,'Y','N') AS `References_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 4096,'Y','N') AS `Index_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 8192,'Y','N') AS `Alter_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 16384,'Y','N') AS `Show_db_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 32768,'Y','N') AS `Super_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 65536,'Y','N') AS `Create_tmp_table_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 131072,'Y','N') AS `Lock_tables_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 262144,'Y','N') AS `Execute_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 524288,'Y','N') AS `Repl_slave_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 1048576,'Y','N') AS `Repl_client_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 2097152,'Y','N') AS `Create_view_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 4194304,'Y','N') AS `Show_view_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 8388608,'Y','N') AS `Create_routine_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 16777216,'Y','N') AS `Alter_routine_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 33554432,'Y','N') AS `Create_user_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 67108864,'Y','N') AS `Event_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 134217728,'Y','N') AS `Trigger_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 268435456,'Y','N') AS `Create_tablespace_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 536870912,'Y','N') AS `Delete_history_priv`,elt(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.ssl_type'),0) + 1,'','ANY','X509','SPECIFIED') AS `ssl_type`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.ssl_cipher'),'') AS `ssl_cipher`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.x509_issuer'),'') AS `x509_issuer`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.x509_subject'),'') AS `x509_subject`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_questions'),0) as unsigned) AS `max_questions`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_updates'),0) as unsigned) AS `max_updates`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_connections'),0) as unsigned) AS `max_connections`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_user_connections'),0) as signed) AS `max_user_connections`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.plugin'),'') AS `plugin`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.authentication_string'),'') AS `authentication_string`,if(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.password_last_changed'),1) = 0,'Y','N') AS `password_expired`,elt(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.is_role'),0) + 1,'N','Y') AS `is_role`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.default_role'),'') AS `default_role`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_statement_time'),0.0) as decimal(12,6)) AS `max_statement_time` from `mysql`.`global_priv` NONE YES mariadb.sys@localhost DEFINER latin1 latin1_swedish_ci UNDEFINED def test v1 select `test`.`t1`.`a` AS `c` from `test`.`t1` CASCADED YES root@localhost DEFINER latin1 latin1_swedish_ci UNDEFINED def test v2 select `test`.`t1`.`a` AS `c` from `test`.`t1` LOCAL YES root@localhost DEFINER latin1 latin1_swedish_ci UNDEFINED def test v3 select `test`.`t1`.`a` AS `c` from `test`.`t1` CASCADED YES root@localhost DEFINER latin1 latin1_swedish_ci UNDEFINED diff --git a/mysql-test/main/mysql_upgrade.result b/mysql-test/main/mysql_upgrade.result index 937c9c6b8d6..596b2673d82 100644 --- a/mysql-test/main/mysql_upgrade.result +++ b/mysql-test/main/mysql_upgrade.result @@ -675,7 +675,7 @@ Phase 7/7: Running 'FLUSH PRIVILEGES' OK SHOW CREATE TABLE mysql.user; View Create View character_set_client collation_connection -user CREATE ALGORITHM=UNDEFINED DEFINER=`mariadb.sys`@`localhost` SQL SECURITY DEFINER VIEW `mysql`.`user` AS select `mysql`.`global_priv`.`Host` AS `Host`,`mysql`.`global_priv`.`User` AS `User`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.plugin') in ('mysql_native_password','mysql_old_password'),ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.authentication_string'),''),'') AS `Password`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 1,'Y','N') AS `Select_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 2,'Y','N') AS `Insert_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 4,'Y','N') AS `Update_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 8,'Y','N') AS `Delete_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 16,'Y','N') AS `Create_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 32,'Y','N') AS `Drop_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 64,'Y','N') AS `Reload_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 128,'Y','N') AS `Shutdown_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 256,'Y','N') AS `Process_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 512,'Y','N') AS `File_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 1024,'Y','N') AS `Grant_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 2048,'Y','N') AS `References_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 4096,'Y','N') AS `Index_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 8192,'Y','N') AS `Alter_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 16384,'Y','N') AS `Show_db_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 32768,'Y','N') AS `Super_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 65536,'Y','N') AS `Create_tmp_table_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 131072,'Y','N') AS `Lock_tables_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 262144,'Y','N') AS `Execute_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 524288,'Y','N') AS `Repl_slave_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 1048576,'Y','N') AS `Repl_client_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 2097152,'Y','N') AS `Create_view_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 4194304,'Y','N') AS `Show_view_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 8388608,'Y','N') AS `Create_routine_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 16777216,'Y','N') AS `Alter_routine_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 33554432,'Y','N') AS `Create_user_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 67108864,'Y','N') AS `Event_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 134217728,'Y','N') AS `Trigger_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 268435456,'Y','N') AS `Create_tablespace_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 536870912,'Y','N') AS `Delete_history_priv`,elt(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.ssl_type'),0) + 1,'','ANY','X509','SPECIFIED') AS `ssl_type`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.ssl_cipher'),'') AS `ssl_cipher`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.x509_issuer'),'') AS `x509_issuer`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.x509_subject'),'') AS `x509_subject`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_questions'),0) as unsigned) AS `max_questions`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_updates'),0) as unsigned) AS `max_updates`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_connections'),0) as unsigned) AS `max_connections`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_user_connections'),0) as signed) AS `max_user_connections`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.plugin'),'') AS `plugin`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.authentication_string'),'') AS `authentication_string`,'N' AS `password_expired`,elt(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.is_role'),0) + 1,'N','Y') AS `is_role`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.default_role'),'') AS `default_role`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_statement_time'),0.0) as decimal(12,6)) AS `max_statement_time` from `mysql`.`global_priv` latin1 latin1_swedish_ci +user CREATE ALGORITHM=UNDEFINED DEFINER=`mariadb.sys`@`localhost` SQL SECURITY DEFINER VIEW `mysql`.`user` AS select `mysql`.`global_priv`.`Host` AS `Host`,`mysql`.`global_priv`.`User` AS `User`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.plugin') in ('mysql_native_password','mysql_old_password'),ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.authentication_string'),''),'') AS `Password`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 1,'Y','N') AS `Select_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 2,'Y','N') AS `Insert_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 4,'Y','N') AS `Update_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 8,'Y','N') AS `Delete_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 16,'Y','N') AS `Create_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 32,'Y','N') AS `Drop_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 64,'Y','N') AS `Reload_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 128,'Y','N') AS `Shutdown_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 256,'Y','N') AS `Process_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 512,'Y','N') AS `File_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 1024,'Y','N') AS `Grant_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 2048,'Y','N') AS `References_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 4096,'Y','N') AS `Index_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 8192,'Y','N') AS `Alter_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 16384,'Y','N') AS `Show_db_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 32768,'Y','N') AS `Super_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 65536,'Y','N') AS `Create_tmp_table_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 131072,'Y','N') AS `Lock_tables_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 262144,'Y','N') AS `Execute_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 524288,'Y','N') AS `Repl_slave_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 1048576,'Y','N') AS `Repl_client_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 2097152,'Y','N') AS `Create_view_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 4194304,'Y','N') AS `Show_view_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 8388608,'Y','N') AS `Create_routine_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 16777216,'Y','N') AS `Alter_routine_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 33554432,'Y','N') AS `Create_user_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 67108864,'Y','N') AS `Event_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 134217728,'Y','N') AS `Trigger_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 268435456,'Y','N') AS `Create_tablespace_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 536870912,'Y','N') AS `Delete_history_priv`,elt(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.ssl_type'),0) + 1,'','ANY','X509','SPECIFIED') AS `ssl_type`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.ssl_cipher'),'') AS `ssl_cipher`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.x509_issuer'),'') AS `x509_issuer`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.x509_subject'),'') AS `x509_subject`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_questions'),0) as unsigned) AS `max_questions`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_updates'),0) as unsigned) AS `max_updates`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_connections'),0) as unsigned) AS `max_connections`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_user_connections'),0) as signed) AS `max_user_connections`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.plugin'),'') AS `plugin`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.authentication_string'),'') AS `authentication_string`,if(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.password_last_changed'),1) = 0,'Y','N') AS `password_expired`,elt(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.is_role'),0) + 1,'N','Y') AS `is_role`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.default_role'),'') AS `default_role`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_statement_time'),0.0) as decimal(12,6)) AS `max_statement_time` from `mysql`.`global_priv` latin1 latin1_swedish_ci CREATE ROLE `aRole`; SET ROLE `aRole`; FLUSH PRIVILEGES; @@ -749,7 +749,7 @@ Phase 7/7: Running 'FLUSH PRIVILEGES' OK SHOW CREATE TABLE mysql.user; View Create View character_set_client collation_connection -user CREATE ALGORITHM=UNDEFINED DEFINER=`mariadb.sys`@`localhost` SQL SECURITY DEFINER VIEW `mysql`.`user` AS select `mysql`.`global_priv`.`Host` AS `Host`,`mysql`.`global_priv`.`User` AS `User`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.plugin') in ('mysql_native_password','mysql_old_password'),ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.authentication_string'),''),'') AS `Password`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 1,'Y','N') AS `Select_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 2,'Y','N') AS `Insert_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 4,'Y','N') AS `Update_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 8,'Y','N') AS `Delete_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 16,'Y','N') AS `Create_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 32,'Y','N') AS `Drop_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 64,'Y','N') AS `Reload_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 128,'Y','N') AS `Shutdown_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 256,'Y','N') AS `Process_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 512,'Y','N') AS `File_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 1024,'Y','N') AS `Grant_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 2048,'Y','N') AS `References_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 4096,'Y','N') AS `Index_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 8192,'Y','N') AS `Alter_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 16384,'Y','N') AS `Show_db_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 32768,'Y','N') AS `Super_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 65536,'Y','N') AS `Create_tmp_table_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 131072,'Y','N') AS `Lock_tables_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 262144,'Y','N') AS `Execute_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 524288,'Y','N') AS `Repl_slave_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 1048576,'Y','N') AS `Repl_client_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 2097152,'Y','N') AS `Create_view_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 4194304,'Y','N') AS `Show_view_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 8388608,'Y','N') AS `Create_routine_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 16777216,'Y','N') AS `Alter_routine_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 33554432,'Y','N') AS `Create_user_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 67108864,'Y','N') AS `Event_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 134217728,'Y','N') AS `Trigger_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 268435456,'Y','N') AS `Create_tablespace_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 536870912,'Y','N') AS `Delete_history_priv`,elt(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.ssl_type'),0) + 1,'','ANY','X509','SPECIFIED') AS `ssl_type`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.ssl_cipher'),'') AS `ssl_cipher`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.x509_issuer'),'') AS `x509_issuer`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.x509_subject'),'') AS `x509_subject`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_questions'),0) as unsigned) AS `max_questions`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_updates'),0) as unsigned) AS `max_updates`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_connections'),0) as unsigned) AS `max_connections`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_user_connections'),0) as signed) AS `max_user_connections`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.plugin'),'') AS `plugin`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.authentication_string'),'') AS `authentication_string`,'N' AS `password_expired`,elt(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.is_role'),0) + 1,'N','Y') AS `is_role`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.default_role'),'') AS `default_role`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_statement_time'),0.0) as decimal(12,6)) AS `max_statement_time` from `mysql`.`global_priv` latin1 latin1_swedish_ci +user CREATE ALGORITHM=UNDEFINED DEFINER=`mariadb.sys`@`localhost` SQL SECURITY DEFINER VIEW `mysql`.`user` AS select `mysql`.`global_priv`.`Host` AS `Host`,`mysql`.`global_priv`.`User` AS `User`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.plugin') in ('mysql_native_password','mysql_old_password'),ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.authentication_string'),''),'') AS `Password`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 1,'Y','N') AS `Select_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 2,'Y','N') AS `Insert_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 4,'Y','N') AS `Update_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 8,'Y','N') AS `Delete_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 16,'Y','N') AS `Create_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 32,'Y','N') AS `Drop_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 64,'Y','N') AS `Reload_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 128,'Y','N') AS `Shutdown_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 256,'Y','N') AS `Process_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 512,'Y','N') AS `File_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 1024,'Y','N') AS `Grant_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 2048,'Y','N') AS `References_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 4096,'Y','N') AS `Index_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 8192,'Y','N') AS `Alter_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 16384,'Y','N') AS `Show_db_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 32768,'Y','N') AS `Super_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 65536,'Y','N') AS `Create_tmp_table_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 131072,'Y','N') AS `Lock_tables_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 262144,'Y','N') AS `Execute_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 524288,'Y','N') AS `Repl_slave_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 1048576,'Y','N') AS `Repl_client_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 2097152,'Y','N') AS `Create_view_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 4194304,'Y','N') AS `Show_view_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 8388608,'Y','N') AS `Create_routine_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 16777216,'Y','N') AS `Alter_routine_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 33554432,'Y','N') AS `Create_user_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 67108864,'Y','N') AS `Event_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 134217728,'Y','N') AS `Trigger_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 268435456,'Y','N') AS `Create_tablespace_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 536870912,'Y','N') AS `Delete_history_priv`,elt(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.ssl_type'),0) + 1,'','ANY','X509','SPECIFIED') AS `ssl_type`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.ssl_cipher'),'') AS `ssl_cipher`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.x509_issuer'),'') AS `x509_issuer`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.x509_subject'),'') AS `x509_subject`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_questions'),0) as unsigned) AS `max_questions`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_updates'),0) as unsigned) AS `max_updates`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_connections'),0) as unsigned) AS `max_connections`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_user_connections'),0) as signed) AS `max_user_connections`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.plugin'),'') AS `plugin`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.authentication_string'),'') AS `authentication_string`,if(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.password_last_changed'),1) = 0,'Y','N') AS `password_expired`,elt(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.is_role'),0) + 1,'N','Y') AS `is_role`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.default_role'),'') AS `default_role`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_statement_time'),0.0) as decimal(12,6)) AS `max_statement_time` from `mysql`.`global_priv` latin1 latin1_swedish_ci CREATE ROLE `aRole`; SET DEFAULT ROLE aRole; SHOW GRANTS; diff --git a/mysql-test/main/system_mysql_db.result b/mysql-test/main/system_mysql_db.result index 838591b3b4b..37ade694489 100644 --- a/mysql-test/main/system_mysql_db.result +++ b/mysql-test/main/system_mysql_db.result @@ -62,7 +62,7 @@ db CREATE TABLE `db` ( ) ENGINE=Aria DEFAULT CHARSET=utf8 COLLATE=utf8_bin PAGE_CHECKSUM=1 TRANSACTIONAL=1 COMMENT='Database privileges' show create table user; View Create View character_set_client collation_connection -user CREATE ALGORITHM=UNDEFINED DEFINER=`mariadb.sys`@`localhost` SQL SECURITY DEFINER VIEW `user` AS select `global_priv`.`Host` AS `Host`,`global_priv`.`User` AS `User`,if(json_value(`global_priv`.`Priv`,'$.plugin') in ('mysql_native_password','mysql_old_password'),ifnull(json_value(`global_priv`.`Priv`,'$.authentication_string'),''),'') AS `Password`,if(json_value(`global_priv`.`Priv`,'$.access') & 1,'Y','N') AS `Select_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 2,'Y','N') AS `Insert_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 4,'Y','N') AS `Update_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 8,'Y','N') AS `Delete_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 16,'Y','N') AS `Create_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 32,'Y','N') AS `Drop_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 64,'Y','N') AS `Reload_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 128,'Y','N') AS `Shutdown_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 256,'Y','N') AS `Process_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 512,'Y','N') AS `File_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 1024,'Y','N') AS `Grant_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 2048,'Y','N') AS `References_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 4096,'Y','N') AS `Index_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 8192,'Y','N') AS `Alter_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 16384,'Y','N') AS `Show_db_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 32768,'Y','N') AS `Super_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 65536,'Y','N') AS `Create_tmp_table_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 131072,'Y','N') AS `Lock_tables_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 262144,'Y','N') AS `Execute_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 524288,'Y','N') AS `Repl_slave_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 1048576,'Y','N') AS `Repl_client_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 2097152,'Y','N') AS `Create_view_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 4194304,'Y','N') AS `Show_view_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 8388608,'Y','N') AS `Create_routine_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 16777216,'Y','N') AS `Alter_routine_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 33554432,'Y','N') AS `Create_user_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 67108864,'Y','N') AS `Event_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 134217728,'Y','N') AS `Trigger_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 268435456,'Y','N') AS `Create_tablespace_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 536870912,'Y','N') AS `Delete_history_priv`,elt(ifnull(json_value(`global_priv`.`Priv`,'$.ssl_type'),0) + 1,'','ANY','X509','SPECIFIED') AS `ssl_type`,ifnull(json_value(`global_priv`.`Priv`,'$.ssl_cipher'),'') AS `ssl_cipher`,ifnull(json_value(`global_priv`.`Priv`,'$.x509_issuer'),'') AS `x509_issuer`,ifnull(json_value(`global_priv`.`Priv`,'$.x509_subject'),'') AS `x509_subject`,cast(ifnull(json_value(`global_priv`.`Priv`,'$.max_questions'),0) as unsigned) AS `max_questions`,cast(ifnull(json_value(`global_priv`.`Priv`,'$.max_updates'),0) as unsigned) AS `max_updates`,cast(ifnull(json_value(`global_priv`.`Priv`,'$.max_connections'),0) as unsigned) AS `max_connections`,cast(ifnull(json_value(`global_priv`.`Priv`,'$.max_user_connections'),0) as signed) AS `max_user_connections`,ifnull(json_value(`global_priv`.`Priv`,'$.plugin'),'') AS `plugin`,ifnull(json_value(`global_priv`.`Priv`,'$.authentication_string'),'') AS `authentication_string`,'N' AS `password_expired`,elt(ifnull(json_value(`global_priv`.`Priv`,'$.is_role'),0) + 1,'N','Y') AS `is_role`,ifnull(json_value(`global_priv`.`Priv`,'$.default_role'),'') AS `default_role`,cast(ifnull(json_value(`global_priv`.`Priv`,'$.max_statement_time'),0.0) as decimal(12,6)) AS `max_statement_time` from `global_priv` latin1 latin1_swedish_ci +user CREATE ALGORITHM=UNDEFINED DEFINER=`mariadb.sys`@`localhost` SQL SECURITY DEFINER VIEW `user` AS select `global_priv`.`Host` AS `Host`,`global_priv`.`User` AS `User`,if(json_value(`global_priv`.`Priv`,'$.plugin') in ('mysql_native_password','mysql_old_password'),ifnull(json_value(`global_priv`.`Priv`,'$.authentication_string'),''),'') AS `Password`,if(json_value(`global_priv`.`Priv`,'$.access') & 1,'Y','N') AS `Select_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 2,'Y','N') AS `Insert_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 4,'Y','N') AS `Update_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 8,'Y','N') AS `Delete_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 16,'Y','N') AS `Create_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 32,'Y','N') AS `Drop_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 64,'Y','N') AS `Reload_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 128,'Y','N') AS `Shutdown_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 256,'Y','N') AS `Process_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 512,'Y','N') AS `File_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 1024,'Y','N') AS `Grant_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 2048,'Y','N') AS `References_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 4096,'Y','N') AS `Index_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 8192,'Y','N') AS `Alter_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 16384,'Y','N') AS `Show_db_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 32768,'Y','N') AS `Super_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 65536,'Y','N') AS `Create_tmp_table_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 131072,'Y','N') AS `Lock_tables_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 262144,'Y','N') AS `Execute_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 524288,'Y','N') AS `Repl_slave_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 1048576,'Y','N') AS `Repl_client_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 2097152,'Y','N') AS `Create_view_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 4194304,'Y','N') AS `Show_view_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 8388608,'Y','N') AS `Create_routine_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 16777216,'Y','N') AS `Alter_routine_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 33554432,'Y','N') AS `Create_user_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 67108864,'Y','N') AS `Event_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 134217728,'Y','N') AS `Trigger_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 268435456,'Y','N') AS `Create_tablespace_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 536870912,'Y','N') AS `Delete_history_priv`,elt(ifnull(json_value(`global_priv`.`Priv`,'$.ssl_type'),0) + 1,'','ANY','X509','SPECIFIED') AS `ssl_type`,ifnull(json_value(`global_priv`.`Priv`,'$.ssl_cipher'),'') AS `ssl_cipher`,ifnull(json_value(`global_priv`.`Priv`,'$.x509_issuer'),'') AS `x509_issuer`,ifnull(json_value(`global_priv`.`Priv`,'$.x509_subject'),'') AS `x509_subject`,cast(ifnull(json_value(`global_priv`.`Priv`,'$.max_questions'),0) as unsigned) AS `max_questions`,cast(ifnull(json_value(`global_priv`.`Priv`,'$.max_updates'),0) as unsigned) AS `max_updates`,cast(ifnull(json_value(`global_priv`.`Priv`,'$.max_connections'),0) as unsigned) AS `max_connections`,cast(ifnull(json_value(`global_priv`.`Priv`,'$.max_user_connections'),0) as signed) AS `max_user_connections`,ifnull(json_value(`global_priv`.`Priv`,'$.plugin'),'') AS `plugin`,ifnull(json_value(`global_priv`.`Priv`,'$.authentication_string'),'') AS `authentication_string`,if(ifnull(json_value(`global_priv`.`Priv`,'$.password_last_changed'),1) = 0,'Y','N') AS `password_expired`,elt(ifnull(json_value(`global_priv`.`Priv`,'$.is_role'),0) + 1,'N','Y') AS `is_role`,ifnull(json_value(`global_priv`.`Priv`,'$.default_role'),'') AS `default_role`,cast(ifnull(json_value(`global_priv`.`Priv`,'$.max_statement_time'),0.0) as decimal(12,6)) AS `max_statement_time` from `global_priv` latin1 latin1_swedish_ci show create table func; Table Create Table func CREATE TABLE `func` ( diff --git a/mysql-test/main/system_mysql_db_fix40123.result b/mysql-test/main/system_mysql_db_fix40123.result index fc9a5763dbd..f76a4b37e31 100644 --- a/mysql-test/main/system_mysql_db_fix40123.result +++ b/mysql-test/main/system_mysql_db_fix40123.result @@ -100,7 +100,7 @@ db CREATE TABLE `db` ( ) ENGINE=Aria DEFAULT CHARSET=utf8 COLLATE=utf8_bin PAGE_CHECKSUM=1 TRANSACTIONAL=1 COMMENT='Database privileges' show create table user; View Create View character_set_client collation_connection -user CREATE ALGORITHM=UNDEFINED DEFINER=`mariadb.sys`@`localhost` SQL SECURITY DEFINER VIEW `user` AS select `global_priv`.`Host` AS `Host`,`global_priv`.`User` AS `User`,if(json_value(`global_priv`.`Priv`,'$.plugin') in ('mysql_native_password','mysql_old_password'),ifnull(json_value(`global_priv`.`Priv`,'$.authentication_string'),''),'') AS `Password`,if(json_value(`global_priv`.`Priv`,'$.access') & 1,'Y','N') AS `Select_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 2,'Y','N') AS `Insert_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 4,'Y','N') AS `Update_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 8,'Y','N') AS `Delete_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 16,'Y','N') AS `Create_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 32,'Y','N') AS `Drop_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 64,'Y','N') AS `Reload_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 128,'Y','N') AS `Shutdown_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 256,'Y','N') AS `Process_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 512,'Y','N') AS `File_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 1024,'Y','N') AS `Grant_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 2048,'Y','N') AS `References_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 4096,'Y','N') AS `Index_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 8192,'Y','N') AS `Alter_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 16384,'Y','N') AS `Show_db_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 32768,'Y','N') AS `Super_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 65536,'Y','N') AS `Create_tmp_table_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 131072,'Y','N') AS `Lock_tables_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 262144,'Y','N') AS `Execute_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 524288,'Y','N') AS `Repl_slave_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 1048576,'Y','N') AS `Repl_client_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 2097152,'Y','N') AS `Create_view_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 4194304,'Y','N') AS `Show_view_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 8388608,'Y','N') AS `Create_routine_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 16777216,'Y','N') AS `Alter_routine_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 33554432,'Y','N') AS `Create_user_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 67108864,'Y','N') AS `Event_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 134217728,'Y','N') AS `Trigger_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 268435456,'Y','N') AS `Create_tablespace_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 536870912,'Y','N') AS `Delete_history_priv`,elt(ifnull(json_value(`global_priv`.`Priv`,'$.ssl_type'),0) + 1,'','ANY','X509','SPECIFIED') AS `ssl_type`,ifnull(json_value(`global_priv`.`Priv`,'$.ssl_cipher'),'') AS `ssl_cipher`,ifnull(json_value(`global_priv`.`Priv`,'$.x509_issuer'),'') AS `x509_issuer`,ifnull(json_value(`global_priv`.`Priv`,'$.x509_subject'),'') AS `x509_subject`,cast(ifnull(json_value(`global_priv`.`Priv`,'$.max_questions'),0) as unsigned) AS `max_questions`,cast(ifnull(json_value(`global_priv`.`Priv`,'$.max_updates'),0) as unsigned) AS `max_updates`,cast(ifnull(json_value(`global_priv`.`Priv`,'$.max_connections'),0) as unsigned) AS `max_connections`,cast(ifnull(json_value(`global_priv`.`Priv`,'$.max_user_connections'),0) as signed) AS `max_user_connections`,ifnull(json_value(`global_priv`.`Priv`,'$.plugin'),'') AS `plugin`,ifnull(json_value(`global_priv`.`Priv`,'$.authentication_string'),'') AS `authentication_string`,'N' AS `password_expired`,elt(ifnull(json_value(`global_priv`.`Priv`,'$.is_role'),0) + 1,'N','Y') AS `is_role`,ifnull(json_value(`global_priv`.`Priv`,'$.default_role'),'') AS `default_role`,cast(ifnull(json_value(`global_priv`.`Priv`,'$.max_statement_time'),0.0) as decimal(12,6)) AS `max_statement_time` from `global_priv` latin1 latin1_swedish_ci +user CREATE ALGORITHM=UNDEFINED DEFINER=`mariadb.sys`@`localhost` SQL SECURITY DEFINER VIEW `user` AS select `global_priv`.`Host` AS `Host`,`global_priv`.`User` AS `User`,if(json_value(`global_priv`.`Priv`,'$.plugin') in ('mysql_native_password','mysql_old_password'),ifnull(json_value(`global_priv`.`Priv`,'$.authentication_string'),''),'') AS `Password`,if(json_value(`global_priv`.`Priv`,'$.access') & 1,'Y','N') AS `Select_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 2,'Y','N') AS `Insert_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 4,'Y','N') AS `Update_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 8,'Y','N') AS `Delete_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 16,'Y','N') AS `Create_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 32,'Y','N') AS `Drop_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 64,'Y','N') AS `Reload_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 128,'Y','N') AS `Shutdown_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 256,'Y','N') AS `Process_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 512,'Y','N') AS `File_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 1024,'Y','N') AS `Grant_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 2048,'Y','N') AS `References_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 4096,'Y','N') AS `Index_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 8192,'Y','N') AS `Alter_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 16384,'Y','N') AS `Show_db_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 32768,'Y','N') AS `Super_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 65536,'Y','N') AS `Create_tmp_table_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 131072,'Y','N') AS `Lock_tables_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 262144,'Y','N') AS `Execute_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 524288,'Y','N') AS `Repl_slave_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 1048576,'Y','N') AS `Repl_client_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 2097152,'Y','N') AS `Create_view_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 4194304,'Y','N') AS `Show_view_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 8388608,'Y','N') AS `Create_routine_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 16777216,'Y','N') AS `Alter_routine_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 33554432,'Y','N') AS `Create_user_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 67108864,'Y','N') AS `Event_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 134217728,'Y','N') AS `Trigger_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 268435456,'Y','N') AS `Create_tablespace_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 536870912,'Y','N') AS `Delete_history_priv`,elt(ifnull(json_value(`global_priv`.`Priv`,'$.ssl_type'),0) + 1,'','ANY','X509','SPECIFIED') AS `ssl_type`,ifnull(json_value(`global_priv`.`Priv`,'$.ssl_cipher'),'') AS `ssl_cipher`,ifnull(json_value(`global_priv`.`Priv`,'$.x509_issuer'),'') AS `x509_issuer`,ifnull(json_value(`global_priv`.`Priv`,'$.x509_subject'),'') AS `x509_subject`,cast(ifnull(json_value(`global_priv`.`Priv`,'$.max_questions'),0) as unsigned) AS `max_questions`,cast(ifnull(json_value(`global_priv`.`Priv`,'$.max_updates'),0) as unsigned) AS `max_updates`,cast(ifnull(json_value(`global_priv`.`Priv`,'$.max_connections'),0) as unsigned) AS `max_connections`,cast(ifnull(json_value(`global_priv`.`Priv`,'$.max_user_connections'),0) as signed) AS `max_user_connections`,ifnull(json_value(`global_priv`.`Priv`,'$.plugin'),'') AS `plugin`,ifnull(json_value(`global_priv`.`Priv`,'$.authentication_string'),'') AS `authentication_string`,if(ifnull(json_value(`global_priv`.`Priv`,'$.password_last_changed'),1) = 0,'Y','N') AS `password_expired`,elt(ifnull(json_value(`global_priv`.`Priv`,'$.is_role'),0) + 1,'N','Y') AS `is_role`,ifnull(json_value(`global_priv`.`Priv`,'$.default_role'),'') AS `default_role`,cast(ifnull(json_value(`global_priv`.`Priv`,'$.max_statement_time'),0.0) as decimal(12,6)) AS `max_statement_time` from `global_priv` latin1 latin1_swedish_ci show create table func; Table Create Table func CREATE TABLE `func` ( diff --git a/mysql-test/main/system_mysql_db_fix50030.result b/mysql-test/main/system_mysql_db_fix50030.result index 02047dc4a8c..a9ef62aa5d4 100644 --- a/mysql-test/main/system_mysql_db_fix50030.result +++ b/mysql-test/main/system_mysql_db_fix50030.result @@ -104,7 +104,7 @@ db CREATE TABLE `db` ( ) ENGINE=Aria DEFAULT CHARSET=utf8 COLLATE=utf8_bin PAGE_CHECKSUM=1 TRANSACTIONAL=1 COMMENT='Database privileges' show create table user; View Create View character_set_client collation_connection -user CREATE ALGORITHM=UNDEFINED DEFINER=`mariadb.sys`@`localhost` SQL SECURITY DEFINER VIEW `user` AS select `global_priv`.`Host` AS `Host`,`global_priv`.`User` AS `User`,if(json_value(`global_priv`.`Priv`,'$.plugin') in ('mysql_native_password','mysql_old_password'),ifnull(json_value(`global_priv`.`Priv`,'$.authentication_string'),''),'') AS `Password`,if(json_value(`global_priv`.`Priv`,'$.access') & 1,'Y','N') AS `Select_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 2,'Y','N') AS `Insert_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 4,'Y','N') AS `Update_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 8,'Y','N') AS `Delete_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 16,'Y','N') AS `Create_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 32,'Y','N') AS `Drop_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 64,'Y','N') AS `Reload_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 128,'Y','N') AS `Shutdown_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 256,'Y','N') AS `Process_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 512,'Y','N') AS `File_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 1024,'Y','N') AS `Grant_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 2048,'Y','N') AS `References_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 4096,'Y','N') AS `Index_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 8192,'Y','N') AS `Alter_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 16384,'Y','N') AS `Show_db_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 32768,'Y','N') AS `Super_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 65536,'Y','N') AS `Create_tmp_table_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 131072,'Y','N') AS `Lock_tables_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 262144,'Y','N') AS `Execute_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 524288,'Y','N') AS `Repl_slave_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 1048576,'Y','N') AS `Repl_client_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 2097152,'Y','N') AS `Create_view_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 4194304,'Y','N') AS `Show_view_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 8388608,'Y','N') AS `Create_routine_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 16777216,'Y','N') AS `Alter_routine_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 33554432,'Y','N') AS `Create_user_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 67108864,'Y','N') AS `Event_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 134217728,'Y','N') AS `Trigger_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 268435456,'Y','N') AS `Create_tablespace_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 536870912,'Y','N') AS `Delete_history_priv`,elt(ifnull(json_value(`global_priv`.`Priv`,'$.ssl_type'),0) + 1,'','ANY','X509','SPECIFIED') AS `ssl_type`,ifnull(json_value(`global_priv`.`Priv`,'$.ssl_cipher'),'') AS `ssl_cipher`,ifnull(json_value(`global_priv`.`Priv`,'$.x509_issuer'),'') AS `x509_issuer`,ifnull(json_value(`global_priv`.`Priv`,'$.x509_subject'),'') AS `x509_subject`,cast(ifnull(json_value(`global_priv`.`Priv`,'$.max_questions'),0) as unsigned) AS `max_questions`,cast(ifnull(json_value(`global_priv`.`Priv`,'$.max_updates'),0) as unsigned) AS `max_updates`,cast(ifnull(json_value(`global_priv`.`Priv`,'$.max_connections'),0) as unsigned) AS `max_connections`,cast(ifnull(json_value(`global_priv`.`Priv`,'$.max_user_connections'),0) as signed) AS `max_user_connections`,ifnull(json_value(`global_priv`.`Priv`,'$.plugin'),'') AS `plugin`,ifnull(json_value(`global_priv`.`Priv`,'$.authentication_string'),'') AS `authentication_string`,'N' AS `password_expired`,elt(ifnull(json_value(`global_priv`.`Priv`,'$.is_role'),0) + 1,'N','Y') AS `is_role`,ifnull(json_value(`global_priv`.`Priv`,'$.default_role'),'') AS `default_role`,cast(ifnull(json_value(`global_priv`.`Priv`,'$.max_statement_time'),0.0) as decimal(12,6)) AS `max_statement_time` from `global_priv` latin1 latin1_swedish_ci +user CREATE ALGORITHM=UNDEFINED DEFINER=`mariadb.sys`@`localhost` SQL SECURITY DEFINER VIEW `user` AS select `global_priv`.`Host` AS `Host`,`global_priv`.`User` AS `User`,if(json_value(`global_priv`.`Priv`,'$.plugin') in ('mysql_native_password','mysql_old_password'),ifnull(json_value(`global_priv`.`Priv`,'$.authentication_string'),''),'') AS `Password`,if(json_value(`global_priv`.`Priv`,'$.access') & 1,'Y','N') AS `Select_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 2,'Y','N') AS `Insert_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 4,'Y','N') AS `Update_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 8,'Y','N') AS `Delete_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 16,'Y','N') AS `Create_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 32,'Y','N') AS `Drop_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 64,'Y','N') AS `Reload_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 128,'Y','N') AS `Shutdown_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 256,'Y','N') AS `Process_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 512,'Y','N') AS `File_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 1024,'Y','N') AS `Grant_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 2048,'Y','N') AS `References_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 4096,'Y','N') AS `Index_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 8192,'Y','N') AS `Alter_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 16384,'Y','N') AS `Show_db_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 32768,'Y','N') AS `Super_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 65536,'Y','N') AS `Create_tmp_table_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 131072,'Y','N') AS `Lock_tables_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 262144,'Y','N') AS `Execute_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 524288,'Y','N') AS `Repl_slave_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 1048576,'Y','N') AS `Repl_client_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 2097152,'Y','N') AS `Create_view_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 4194304,'Y','N') AS `Show_view_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 8388608,'Y','N') AS `Create_routine_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 16777216,'Y','N') AS `Alter_routine_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 33554432,'Y','N') AS `Create_user_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 67108864,'Y','N') AS `Event_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 134217728,'Y','N') AS `Trigger_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 268435456,'Y','N') AS `Create_tablespace_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 536870912,'Y','N') AS `Delete_history_priv`,elt(ifnull(json_value(`global_priv`.`Priv`,'$.ssl_type'),0) + 1,'','ANY','X509','SPECIFIED') AS `ssl_type`,ifnull(json_value(`global_priv`.`Priv`,'$.ssl_cipher'),'') AS `ssl_cipher`,ifnull(json_value(`global_priv`.`Priv`,'$.x509_issuer'),'') AS `x509_issuer`,ifnull(json_value(`global_priv`.`Priv`,'$.x509_subject'),'') AS `x509_subject`,cast(ifnull(json_value(`global_priv`.`Priv`,'$.max_questions'),0) as unsigned) AS `max_questions`,cast(ifnull(json_value(`global_priv`.`Priv`,'$.max_updates'),0) as unsigned) AS `max_updates`,cast(ifnull(json_value(`global_priv`.`Priv`,'$.max_connections'),0) as unsigned) AS `max_connections`,cast(ifnull(json_value(`global_priv`.`Priv`,'$.max_user_connections'),0) as signed) AS `max_user_connections`,ifnull(json_value(`global_priv`.`Priv`,'$.plugin'),'') AS `plugin`,ifnull(json_value(`global_priv`.`Priv`,'$.authentication_string'),'') AS `authentication_string`,if(ifnull(json_value(`global_priv`.`Priv`,'$.password_last_changed'),1) = 0,'Y','N') AS `password_expired`,elt(ifnull(json_value(`global_priv`.`Priv`,'$.is_role'),0) + 1,'N','Y') AS `is_role`,ifnull(json_value(`global_priv`.`Priv`,'$.default_role'),'') AS `default_role`,cast(ifnull(json_value(`global_priv`.`Priv`,'$.max_statement_time'),0.0) as decimal(12,6)) AS `max_statement_time` from `global_priv` latin1 latin1_swedish_ci show create table func; Table Create Table func CREATE TABLE `func` ( diff --git a/mysql-test/main/system_mysql_db_fix50117.result b/mysql-test/main/system_mysql_db_fix50117.result index 07119cda6c6..1557817fc80 100644 --- a/mysql-test/main/system_mysql_db_fix50117.result +++ b/mysql-test/main/system_mysql_db_fix50117.result @@ -84,7 +84,7 @@ db CREATE TABLE `db` ( ) ENGINE=Aria DEFAULT CHARSET=utf8 COLLATE=utf8_bin PAGE_CHECKSUM=1 TRANSACTIONAL=1 COMMENT='Database privileges' show create table user; View Create View character_set_client collation_connection -user CREATE ALGORITHM=UNDEFINED DEFINER=`mariadb.sys`@`localhost` SQL SECURITY DEFINER VIEW `user` AS select `global_priv`.`Host` AS `Host`,`global_priv`.`User` AS `User`,if(json_value(`global_priv`.`Priv`,'$.plugin') in ('mysql_native_password','mysql_old_password'),ifnull(json_value(`global_priv`.`Priv`,'$.authentication_string'),''),'') AS `Password`,if(json_value(`global_priv`.`Priv`,'$.access') & 1,'Y','N') AS `Select_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 2,'Y','N') AS `Insert_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 4,'Y','N') AS `Update_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 8,'Y','N') AS `Delete_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 16,'Y','N') AS `Create_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 32,'Y','N') AS `Drop_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 64,'Y','N') AS `Reload_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 128,'Y','N') AS `Shutdown_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 256,'Y','N') AS `Process_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 512,'Y','N') AS `File_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 1024,'Y','N') AS `Grant_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 2048,'Y','N') AS `References_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 4096,'Y','N') AS `Index_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 8192,'Y','N') AS `Alter_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 16384,'Y','N') AS `Show_db_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 32768,'Y','N') AS `Super_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 65536,'Y','N') AS `Create_tmp_table_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 131072,'Y','N') AS `Lock_tables_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 262144,'Y','N') AS `Execute_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 524288,'Y','N') AS `Repl_slave_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 1048576,'Y','N') AS `Repl_client_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 2097152,'Y','N') AS `Create_view_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 4194304,'Y','N') AS `Show_view_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 8388608,'Y','N') AS `Create_routine_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 16777216,'Y','N') AS `Alter_routine_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 33554432,'Y','N') AS `Create_user_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 67108864,'Y','N') AS `Event_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 134217728,'Y','N') AS `Trigger_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 268435456,'Y','N') AS `Create_tablespace_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 536870912,'Y','N') AS `Delete_history_priv`,elt(ifnull(json_value(`global_priv`.`Priv`,'$.ssl_type'),0) + 1,'','ANY','X509','SPECIFIED') AS `ssl_type`,ifnull(json_value(`global_priv`.`Priv`,'$.ssl_cipher'),'') AS `ssl_cipher`,ifnull(json_value(`global_priv`.`Priv`,'$.x509_issuer'),'') AS `x509_issuer`,ifnull(json_value(`global_priv`.`Priv`,'$.x509_subject'),'') AS `x509_subject`,cast(ifnull(json_value(`global_priv`.`Priv`,'$.max_questions'),0) as unsigned) AS `max_questions`,cast(ifnull(json_value(`global_priv`.`Priv`,'$.max_updates'),0) as unsigned) AS `max_updates`,cast(ifnull(json_value(`global_priv`.`Priv`,'$.max_connections'),0) as unsigned) AS `max_connections`,cast(ifnull(json_value(`global_priv`.`Priv`,'$.max_user_connections'),0) as signed) AS `max_user_connections`,ifnull(json_value(`global_priv`.`Priv`,'$.plugin'),'') AS `plugin`,ifnull(json_value(`global_priv`.`Priv`,'$.authentication_string'),'') AS `authentication_string`,'N' AS `password_expired`,elt(ifnull(json_value(`global_priv`.`Priv`,'$.is_role'),0) + 1,'N','Y') AS `is_role`,ifnull(json_value(`global_priv`.`Priv`,'$.default_role'),'') AS `default_role`,cast(ifnull(json_value(`global_priv`.`Priv`,'$.max_statement_time'),0.0) as decimal(12,6)) AS `max_statement_time` from `global_priv` latin1 latin1_swedish_ci +user CREATE ALGORITHM=UNDEFINED DEFINER=`mariadb.sys`@`localhost` SQL SECURITY DEFINER VIEW `user` AS select `global_priv`.`Host` AS `Host`,`global_priv`.`User` AS `User`,if(json_value(`global_priv`.`Priv`,'$.plugin') in ('mysql_native_password','mysql_old_password'),ifnull(json_value(`global_priv`.`Priv`,'$.authentication_string'),''),'') AS `Password`,if(json_value(`global_priv`.`Priv`,'$.access') & 1,'Y','N') AS `Select_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 2,'Y','N') AS `Insert_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 4,'Y','N') AS `Update_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 8,'Y','N') AS `Delete_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 16,'Y','N') AS `Create_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 32,'Y','N') AS `Drop_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 64,'Y','N') AS `Reload_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 128,'Y','N') AS `Shutdown_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 256,'Y','N') AS `Process_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 512,'Y','N') AS `File_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 1024,'Y','N') AS `Grant_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 2048,'Y','N') AS `References_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 4096,'Y','N') AS `Index_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 8192,'Y','N') AS `Alter_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 16384,'Y','N') AS `Show_db_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 32768,'Y','N') AS `Super_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 65536,'Y','N') AS `Create_tmp_table_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 131072,'Y','N') AS `Lock_tables_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 262144,'Y','N') AS `Execute_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 524288,'Y','N') AS `Repl_slave_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 1048576,'Y','N') AS `Repl_client_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 2097152,'Y','N') AS `Create_view_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 4194304,'Y','N') AS `Show_view_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 8388608,'Y','N') AS `Create_routine_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 16777216,'Y','N') AS `Alter_routine_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 33554432,'Y','N') AS `Create_user_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 67108864,'Y','N') AS `Event_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 134217728,'Y','N') AS `Trigger_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 268435456,'Y','N') AS `Create_tablespace_priv`,if(json_value(`global_priv`.`Priv`,'$.access') & 536870912,'Y','N') AS `Delete_history_priv`,elt(ifnull(json_value(`global_priv`.`Priv`,'$.ssl_type'),0) + 1,'','ANY','X509','SPECIFIED') AS `ssl_type`,ifnull(json_value(`global_priv`.`Priv`,'$.ssl_cipher'),'') AS `ssl_cipher`,ifnull(json_value(`global_priv`.`Priv`,'$.x509_issuer'),'') AS `x509_issuer`,ifnull(json_value(`global_priv`.`Priv`,'$.x509_subject'),'') AS `x509_subject`,cast(ifnull(json_value(`global_priv`.`Priv`,'$.max_questions'),0) as unsigned) AS `max_questions`,cast(ifnull(json_value(`global_priv`.`Priv`,'$.max_updates'),0) as unsigned) AS `max_updates`,cast(ifnull(json_value(`global_priv`.`Priv`,'$.max_connections'),0) as unsigned) AS `max_connections`,cast(ifnull(json_value(`global_priv`.`Priv`,'$.max_user_connections'),0) as signed) AS `max_user_connections`,ifnull(json_value(`global_priv`.`Priv`,'$.plugin'),'') AS `plugin`,ifnull(json_value(`global_priv`.`Priv`,'$.authentication_string'),'') AS `authentication_string`,if(ifnull(json_value(`global_priv`.`Priv`,'$.password_last_changed'),1) = 0,'Y','N') AS `password_expired`,elt(ifnull(json_value(`global_priv`.`Priv`,'$.is_role'),0) + 1,'N','Y') AS `is_role`,ifnull(json_value(`global_priv`.`Priv`,'$.default_role'),'') AS `default_role`,cast(ifnull(json_value(`global_priv`.`Priv`,'$.max_statement_time'),0.0) as decimal(12,6)) AS `max_statement_time` from `global_priv` latin1 latin1_swedish_ci show create table func; Table Create Table func CREATE TABLE `func` ( diff --git a/mysql-test/main/upgrade_MDEV-23102-1.result b/mysql-test/main/upgrade_MDEV-23102-1.result index 8caa49180ee..c02b255798a 100644 --- a/mysql-test/main/upgrade_MDEV-23102-1.result +++ b/mysql-test/main/upgrade_MDEV-23102-1.result @@ -61,7 +61,6 @@ CAST(IFNULL(JSON_VALUE(Priv, '$.max_connections'), 0) AS UNSIGNED) AS max_connec CAST(IFNULL(JSON_VALUE(Priv, '$.max_user_connections'), 0) AS SIGNED) AS max_user_connections, IFNULL(JSON_VALUE(Priv, '$.plugin'), '') AS plugin, IFNULL(JSON_VALUE(Priv, '$.authentication_string'), '') AS authentication_string, -'N' AS password_expired, ELT(IFNULL(JSON_VALUE(Priv, '$.is_role'), 0) + 1, 'N', 'Y') AS is_role, IFNULL(JSON_VALUE(Priv, '$.default_role'), '') AS default_role, CAST(IFNULL(JSON_VALUE(Priv, '$.max_statement_time'), 0.0) AS DECIMAL(12,6)) AS max_statement_time diff --git a/mysql-test/main/upgrade_MDEV-23102-1.test b/mysql-test/main/upgrade_MDEV-23102-1.test index 8491ddfffe4..1b929f7cabf 100644 --- a/mysql-test/main/upgrade_MDEV-23102-1.test +++ b/mysql-test/main/upgrade_MDEV-23102-1.test @@ -69,7 +69,6 @@ CREATE DEFINER='superuser'@'localhost' SQL SECURITY DEFINER VIEW IF NOT EXISTS u CAST(IFNULL(JSON_VALUE(Priv, '$.max_user_connections'), 0) AS SIGNED) AS max_user_connections, IFNULL(JSON_VALUE(Priv, '$.plugin'), '') AS plugin, IFNULL(JSON_VALUE(Priv, '$.authentication_string'), '') AS authentication_string, - 'N' AS password_expired, ELT(IFNULL(JSON_VALUE(Priv, '$.is_role'), 0) + 1, 'N', 'Y') AS is_role, IFNULL(JSON_VALUE(Priv, '$.default_role'), '') AS default_role, CAST(IFNULL(JSON_VALUE(Priv, '$.max_statement_time'), 0.0) AS DECIMAL(12,6)) AS max_statement_time diff --git a/mysql-test/main/upgrade_MDEV-23102-2.result b/mysql-test/main/upgrade_MDEV-23102-2.result index 4702fae812f..53240f0c2a7 100644 --- a/mysql-test/main/upgrade_MDEV-23102-2.result +++ b/mysql-test/main/upgrade_MDEV-23102-2.result @@ -61,7 +61,6 @@ CAST(IFNULL(JSON_VALUE(Priv, '$.max_connections'), 0) AS UNSIGNED) AS max_connec CAST(IFNULL(JSON_VALUE(Priv, '$.max_user_connections'), 0) AS SIGNED) AS max_user_connections, IFNULL(JSON_VALUE(Priv, '$.plugin'), '') AS plugin, IFNULL(JSON_VALUE(Priv, '$.authentication_string'), '') AS authentication_string, -'N' AS password_expired, ELT(IFNULL(JSON_VALUE(Priv, '$.is_role'), 0) + 1, 'N', 'Y') AS is_role, IFNULL(JSON_VALUE(Priv, '$.default_role'), '') AS default_role, CAST(IFNULL(JSON_VALUE(Priv, '$.max_statement_time'), 0.0) AS DECIMAL(12,6)) AS max_statement_time diff --git a/mysql-test/main/upgrade_MDEV-23102-2.test b/mysql-test/main/upgrade_MDEV-23102-2.test index 5ce7682fea6..1491f7d7bd2 100644 --- a/mysql-test/main/upgrade_MDEV-23102-2.test +++ b/mysql-test/main/upgrade_MDEV-23102-2.test @@ -69,7 +69,6 @@ CREATE DEFINER='superuser'@'localhost' SQL SECURITY DEFINER VIEW IF NOT EXISTS u CAST(IFNULL(JSON_VALUE(Priv, '$.max_user_connections'), 0) AS SIGNED) AS max_user_connections, IFNULL(JSON_VALUE(Priv, '$.plugin'), '') AS plugin, IFNULL(JSON_VALUE(Priv, '$.authentication_string'), '') AS authentication_string, - 'N' AS password_expired, ELT(IFNULL(JSON_VALUE(Priv, '$.is_role'), 0) + 1, 'N', 'Y') AS is_role, IFNULL(JSON_VALUE(Priv, '$.default_role'), '') AS default_role, CAST(IFNULL(JSON_VALUE(Priv, '$.max_statement_time'), 0.0) AS DECIMAL(12,6)) AS max_statement_time diff --git a/mysql-test/main/upgrade_mdev_24363.result b/mysql-test/main/upgrade_mdev_24363.result new file mode 100644 index 00000000000..d507193088e --- /dev/null +++ b/mysql-test/main/upgrade_mdev_24363.result @@ -0,0 +1,129 @@ +# +# MDEV-24363 10.4: change definition of mysql.user view +# to reflect the correct value from mysql.global_priv +# This change was added because mysql.user view definition +# was already changed when mariadb.sys was introduced, so +# it's decently ok if we change it again to fix mdev-24363 +# +# Test that mysql.user password_expired column +# shows the right value as in mysql.global_priv +# +create user gigi@localhost; +show create user gigi@localhost; +CREATE USER for gigi@localhost +CREATE USER `gigi`@`localhost` +select password_expired from mysql.user where user='gigi' and host='localhost'; +password_expired +N +alter user gigi@localhost password expire; +show create user gigi@localhost; +CREATE USER for gigi@localhost +CREATE USER `gigi`@`localhost` PASSWORD EXPIRE +select password_expired from mysql.user where user='gigi' and host='localhost'; +password_expired +Y +drop user gigi@localhost; +# +# Test that upgrades from 10.4+ versions before this mdev +# correctly drop and recreate the mysql.user view +# +use mysql; +set @def = (select view_definition from information_schema.views where table_name='user' and table_schema='mysql'); +set @trimmed_def = (select trim(trailing 'from `mysql`.`global_priv`' from @def)); +set @newdef = (select concat(@trimmed_def, ", 'N' AS password_expired from mysql.global_priv")); +set @pos = (select instr(@newdef, 'password_expired')); +create or replace view user as select `mysql`.`global_priv`.`Host` AS `Host`,`mysql`.`global_priv`.`User` AS `User`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.plugin') in ('mysql_native_password','mysql_old_password'),ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.authentication_string'),''),'') AS `Password`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 1,'Y','N') AS `Select_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 2,'Y','N') AS `Insert_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 4,'Y','N') AS `Update_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 8,'Y','N') AS `Delete_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 16,'Y','N') AS `Create_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 32,'Y','N') AS `Drop_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 64,'Y','N') AS `Reload_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 128,'Y','N') AS `Shutdown_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 256,'Y','N') AS `Process_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 512,'Y','N') AS `File_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 1024,'Y','N') AS `Grant_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 2048,'Y','N') AS `References_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 4096,'Y','N') AS `Index_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 8192,'Y','N') AS `Alter_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 16384,'Y','N') AS `Show_db_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 32768,'Y','N') AS `Super_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 65536,'Y','N') AS `Create_tmp_table_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 131072,'Y','N') AS `Lock_tables_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 262144,'Y','N') AS `Execute_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 524288,'Y','N') AS `Repl_slave_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 1048576,'Y','N') AS `Repl_client_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 2097152,'Y','N') AS `Create_view_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 4194304,'Y','N') AS `Show_view_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 8388608,'Y','N') AS `Create_routine_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 16777216,'Y','N') AS `Alter_routine_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 33554432,'Y','N') AS `Create_user_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 67108864,'Y','N') AS `Event_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 134217728,'Y','N') AS `Trigger_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 268435456,'Y','N') AS `Create_tablespace_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 536870912,'Y','N') AS `Delete_history_priv`,elt(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.ssl_type'),0) + 1,'','ANY','X509','SPECIFIED') AS `ssl_type`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.ssl_cipher'),'') AS `ssl_cipher`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.x509_issuer'),'') AS `x509_issuer`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.x509_subject'),'') AS `x509_subject`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_questions'),0) as unsigned) AS `max_questions`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_updates'),0) as unsigned) AS `max_updates`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_connections'),0) as unsigned) AS `max_connections`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_user_connections'),0) as signed) AS `max_user_connections`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.plugin'),'') AS `plugin`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.authentication_string'),'') AS `authentication_string`,if(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.password_last_changed'),1) = 0,'Y','N') AS `abcsword_expired`,elt(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.is_role'),0) + 1,'N','Y') AS `is_role`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.default_role'),'') AS `default_role`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_statement_time'),0.0) as decimal(12,6)) AS `max_statement_time` , 'N' AS password_expired from mysql.global_priv;; +create user gigi@localhost; +show create user gigi@localhost; +CREATE USER for gigi@localhost +CREATE USER `gigi`@`localhost` +select password_expired from mysql.user where user='gigi' and host='localhost'; +password_expired +N +alter user gigi@localhost password expire; +show create user gigi@localhost; +CREATE USER for gigi@localhost +CREATE USER `gigi`@`localhost` PASSWORD EXPIRE +select password_expired from mysql.user where user='gigi' and host='localhost'; +password_expired +N +drop user gigi@localhost; +# Run mysql_upgrade +Phase 1/7: Checking and upgrading mysql database +Processing databases +mysql +mysql.column_stats OK +mysql.columns_priv OK +mysql.db OK +mysql.event OK +mysql.func OK +mysql.global_priv OK +mysql.gtid_slave_pos OK +mysql.help_category OK +mysql.help_keyword OK +mysql.help_relation OK +mysql.help_topic OK +mysql.index_stats OK +mysql.innodb_index_stats +Error : Unknown storage engine 'InnoDB' +error : Corrupt +mysql.innodb_table_stats +Error : Unknown storage engine 'InnoDB' +error : Corrupt +mysql.plugin OK +mysql.proc OK +mysql.procs_priv OK +mysql.proxies_priv OK +mysql.roles_mapping OK +mysql.servers OK +mysql.table_stats OK +mysql.tables_priv OK +mysql.time_zone OK +mysql.time_zone_leap_second OK +mysql.time_zone_name OK +mysql.time_zone_transition OK +mysql.time_zone_transition_type OK +mysql.transaction_registry +Error : Unknown storage engine 'InnoDB' +error : Corrupt + +Repairing tables +mysql.innodb_index_stats +Error : Unknown storage engine 'InnoDB' +error : Corrupt +mysql.innodb_table_stats +Error : Unknown storage engine 'InnoDB' +error : Corrupt +mysql.transaction_registry +Error : Unknown storage engine 'InnoDB' +error : Corrupt +Phase 2/7: Installing used storage engines... Skipped +Phase 3/7: Fixing views +mysql.user OK +Phase 4/7: Running 'mysql_fix_privilege_tables' +Phase 5/7: Fixing table and database names +Phase 6/7: Checking and upgrading tables +Processing databases +information_schema +mtr +mtr.global_suppressions OK +mtr.test_suppressions OK +performance_schema +test +Phase 7/7: Running 'FLUSH PRIVILEGES' +OK +create user gigi@localhost; +show create user gigi@localhost; +CREATE USER for gigi@localhost +CREATE USER `gigi`@`localhost` +select password_expired from mysql.user where user='gigi' and host='localhost'; +password_expired +N +alter user gigi@localhost password expire; +show create user gigi@localhost; +CREATE USER for gigi@localhost +CREATE USER `gigi`@`localhost` PASSWORD EXPIRE +select password_expired from mysql.user where user='gigi' and host='localhost'; +password_expired +Y +drop user gigi@localhost; diff --git a/mysql-test/main/upgrade_mdev_24363.test b/mysql-test/main/upgrade_mdev_24363.test new file mode 100644 index 00000000000..cdb49037a40 --- /dev/null +++ b/mysql-test/main/upgrade_mdev_24363.test @@ -0,0 +1,71 @@ +--echo # +--echo # MDEV-24363 10.4: change definition of mysql.user view +--echo # to reflect the correct value from mysql.global_priv +--echo # This change was added because mysql.user view definition +--echo # was already changed when mariadb.sys was introduced, so +--echo # it's decently ok if we change it again to fix mdev-24363 + +--echo # +--echo # Test that mysql.user password_expired column +--echo # shows the right value as in mysql.global_priv +--echo # + +create user gigi@localhost; +show create user gigi@localhost; +select password_expired from mysql.user where user='gigi' and host='localhost'; + +alter user gigi@localhost password expire; +show create user gigi@localhost; +select password_expired from mysql.user where user='gigi' and host='localhost'; + +drop user gigi@localhost; + +--echo # +--echo # Test that upgrades from 10.4+ versions before this mdev +--echo # correctly drop and recreate the mysql.user view +--echo # + +--source include/mysql_upgrade_preparation.inc + +use mysql; + +# Do all these string operations to replace password_expired definition +# with "'N' as password_expired" and avoid listing in one more test +# all the fields of the user view +set @def = (select view_definition from information_schema.views where table_name='user' and table_schema='mysql'); +set @trimmed_def = (select trim(trailing 'from `mysql`.`global_priv`' from @def)); +set @newdef = (select concat(@trimmed_def, ", 'N' AS password_expired from mysql.global_priv")); +set @pos = (select instr(@newdef, 'password_expired')); +let $viewdef = `select insert(@newdef, @pos, 3, 'abc')`; + +--eval create or replace view user as $viewdef; + +create user gigi@localhost; +show create user gigi@localhost; +select password_expired from mysql.user where user='gigi' and host='localhost'; + +# password should be expired, but mysql.user.password_expired should be 'N' +alter user gigi@localhost password expire; +show create user gigi@localhost; +select password_expired from mysql.user where user='gigi' and host='localhost'; + +drop user gigi@localhost; + +--echo # Run mysql_upgrade +--exec $MYSQL_UPGRADE 2>&1 +let $MYSQLD_DATADIR= `select @@datadir`; +--file_exists $MYSQLD_DATADIR/mysql_upgrade_info +--remove_file $MYSQLD_DATADIR/mysql_upgrade_info + +create user gigi@localhost; +show create user gigi@localhost; +select password_expired from mysql.user where user='gigi' and host='localhost'; + +# mysql.user view should've been recreated by mariadb_upgrade, thus +# password_expired should show 'Y' +alter user gigi@localhost password expire; +show create user gigi@localhost; +select password_expired from mysql.user where user='gigi' and host='localhost'; + +drop user gigi@localhost; + diff --git a/scripts/mysql_system_tables.sql b/scripts/mysql_system_tables.sql index d4d16c74c11..020385992ea 100644 --- a/scripts/mysql_system_tables.sql +++ b/scripts/mysql_system_tables.sql @@ -93,7 +93,7 @@ CREATE DEFINER='mariadb.sys'@'localhost' SQL SECURITY DEFINER VIEW IF NOT EXISTS CAST(IFNULL(JSON_VALUE(Priv, '$.max_user_connections'), 0) AS SIGNED) AS max_user_connections, IFNULL(JSON_VALUE(Priv, '$.plugin'), '') AS plugin, IFNULL(JSON_VALUE(Priv, '$.authentication_string'), '') AS authentication_string, - 'N' AS password_expired, + IF(IFNULL(JSON_VALUE(Priv, '$.password_last_changed'), 1) = 0, 'Y', 'N') AS password_expired, ELT(IFNULL(JSON_VALUE(Priv, '$.is_role'), 0) + 1, 'N', 'Y') AS is_role, IFNULL(JSON_VALUE(Priv, '$.default_role'), '') AS default_role, CAST(IFNULL(JSON_VALUE(Priv, '$.max_statement_time'), 0.0) AS DECIMAL(12,6)) AS max_statement_time diff --git a/scripts/mysql_system_tables_fix.sql b/scripts/mysql_system_tables_fix.sql index 733ed0ed4c1..ac71edccae9 100644 --- a/scripts/mysql_system_tables_fix.sql +++ b/scripts/mysql_system_tables_fix.sql @@ -824,7 +824,7 @@ IF 'BASE TABLE' = (select table_type from information_schema.tables where table_ DROP TABLE user; END IF// -IF 1 = (SELECT count(*) FROM information_schema.VIEWS WHERE TABLE_CATALOG = 'def' and TABLE_SCHEMA = 'mysql' and TABLE_NAME='user' and DEFINER = 'root@localhost') THEN +IF 1 = (SELECT count(*) FROM information_schema.VIEWS WHERE TABLE_CATALOG = 'def' and TABLE_SCHEMA = 'mysql' and TABLE_NAME='user' and (DEFINER = 'root@localhost' or VIEW_DEFINITION LIKE "%'N' AS `password_expired`%")) THEN DROP VIEW IF EXISTS mysql.user; END IF// From 44b85406b8b46977ef291daee697ef0c399b9560 Mon Sep 17 00:00:00 2001 From: Robert Bindar Date: Fri, 5 Mar 2021 11:11:13 +0200 Subject: [PATCH 02/26] MDEV-24363 (followup refactor) avoid listing mysql.user view definition in tests as it wastes lots of time when they fail for minor fixes like adding/changing a new column in the view, also it's less code --- mysql-test/main/upgrade_MDEV-23102-1.result | 50 +------------------- mysql-test/main/upgrade_MDEV-23102-1.test | 52 +-------------------- mysql-test/main/upgrade_MDEV-23102-2.result | 50 +------------------- mysql-test/main/upgrade_MDEV-23102-2.test | 52 +-------------------- 4 files changed, 6 insertions(+), 198 deletions(-) diff --git a/mysql-test/main/upgrade_MDEV-23102-1.result b/mysql-test/main/upgrade_MDEV-23102-1.result index c02b255798a..78993550901 100644 --- a/mysql-test/main/upgrade_MDEV-23102-1.result +++ b/mysql-test/main/upgrade_MDEV-23102-1.result @@ -16,55 +16,7 @@ use mysql; # make changed definition of gis procedures and user view create user superuser@localhost; grant all privileges on mysql.* to superuser@localhost; -drop view user; -CREATE DEFINER='superuser'@'localhost' SQL SECURITY DEFINER VIEW IF NOT EXISTS user AS SELECT -Host, -User, -IF(JSON_VALUE(Priv, '$.plugin') IN ('mysql_native_password', 'mysql_old_password'), IFNULL(JSON_VALUE(Priv, '$.authentication_string'), ''), '') AS Password, -IF(JSON_VALUE(Priv, '$.access') & 1, 'Y', 'N') AS Select_priv, -IF(JSON_VALUE(Priv, '$.access') & 2, 'Y', 'N') AS Insert_priv, -IF(JSON_VALUE(Priv, '$.access') & 4, 'Y', 'N') AS Update_priv, -IF(JSON_VALUE(Priv, '$.access') & 8, 'Y', 'N') AS Delete_priv, -IF(JSON_VALUE(Priv, '$.access') & 16, 'Y', 'N') AS Create_priv, -IF(JSON_VALUE(Priv, '$.access') & 32, 'Y', 'N') AS Drop_priv, -IF(JSON_VALUE(Priv, '$.access') & 64, 'Y', 'N') AS Reload_priv, -IF(JSON_VALUE(Priv, '$.access') & 128, 'Y', 'N') AS Shutdown_priv, -IF(JSON_VALUE(Priv, '$.access') & 256, 'Y', 'N') AS Process_priv, -IF(JSON_VALUE(Priv, '$.access') & 512, 'Y', 'N') AS File_priv, -IF(JSON_VALUE(Priv, '$.access') & 1024, 'Y', 'N') AS Grant_priv, -IF(JSON_VALUE(Priv, '$.access') & 2048, 'Y', 'N') AS References_priv, -IF(JSON_VALUE(Priv, '$.access') & 4096, 'Y', 'N') AS Index_priv, -IF(JSON_VALUE(Priv, '$.access') & 8192, 'Y', 'N') AS Alter_priv, -IF(JSON_VALUE(Priv, '$.access') & 16384, 'Y', 'N') AS Show_db_priv, -IF(JSON_VALUE(Priv, '$.access') & 32768, 'Y', 'N') AS Super_priv, -IF(JSON_VALUE(Priv, '$.access') & 65536, 'Y', 'N') AS Create_tmp_table_priv, -IF(JSON_VALUE(Priv, '$.access') & 131072, 'Y', 'N') AS Lock_tables_priv, -IF(JSON_VALUE(Priv, '$.access') & 262144, 'Y', 'N') AS Execute_priv, -IF(JSON_VALUE(Priv, '$.access') & 524288, 'Y', 'N') AS Repl_slave_priv, -IF(JSON_VALUE(Priv, '$.access') & 1048576, 'Y', 'N') AS Repl_client_priv, -IF(JSON_VALUE(Priv, '$.access') & 2097152, 'Y', 'N') AS Create_view_priv, -IF(JSON_VALUE(Priv, '$.access') & 4194304, 'Y', 'N') AS Show_view_priv, -IF(JSON_VALUE(Priv, '$.access') & 8388608, 'Y', 'N') AS Create_routine_priv, -IF(JSON_VALUE(Priv, '$.access') & 16777216, 'Y', 'N') AS Alter_routine_priv, -IF(JSON_VALUE(Priv, '$.access') & 33554432, 'Y', 'N') AS Create_user_priv, -IF(JSON_VALUE(Priv, '$.access') & 67108864, 'Y', 'N') AS Event_priv, -IF(JSON_VALUE(Priv, '$.access') & 134217728, 'Y', 'N') AS Trigger_priv, -IF(JSON_VALUE(Priv, '$.access') & 268435456, 'Y', 'N') AS Create_tablespace_priv, -IF(JSON_VALUE(Priv, '$.access') & 536870912, 'Y', 'N') AS Delete_history_priv, -ELT(IFNULL(JSON_VALUE(Priv, '$.ssl_type'), 0) + 1, '', 'ANY','X509', 'SPECIFIED') AS ssl_type, -IFNULL(JSON_VALUE(Priv, '$.ssl_cipher'), '') AS ssl_cipher, -IFNULL(JSON_VALUE(Priv, '$.x509_issuer'), '') AS x509_issuer, -IFNULL(JSON_VALUE(Priv, '$.x509_subject'), '') AS x509_subject, -CAST(IFNULL(JSON_VALUE(Priv, '$.max_questions'), 0) AS UNSIGNED) AS max_questions, -CAST(IFNULL(JSON_VALUE(Priv, '$.max_updates'), 0) AS UNSIGNED) AS max_updates, -CAST(IFNULL(JSON_VALUE(Priv, '$.max_connections'), 0) AS UNSIGNED) AS max_connections, -CAST(IFNULL(JSON_VALUE(Priv, '$.max_user_connections'), 0) AS SIGNED) AS max_user_connections, -IFNULL(JSON_VALUE(Priv, '$.plugin'), '') AS plugin, -IFNULL(JSON_VALUE(Priv, '$.authentication_string'), '') AS authentication_string, -ELT(IFNULL(JSON_VALUE(Priv, '$.is_role'), 0) + 1, 'N', 'Y') AS is_role, -IFNULL(JSON_VALUE(Priv, '$.default_role'), '') AS default_role, -CAST(IFNULL(JSON_VALUE(Priv, '$.max_statement_time'), 0.0) AS DECIMAL(12,6)) AS max_statement_time -FROM global_priv; +create or replace definer=superuser@localhost sql security definer view user as select `mysql`.`global_priv`.`Host` AS `Host`,`mysql`.`global_priv`.`User` AS `User`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.plugin') in ('mysql_native_password','mysql_old_password'),ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.authentication_string'),''),'') AS `Password`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 1,'Y','N') AS `Select_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 2,'Y','N') AS `Insert_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 4,'Y','N') AS `Update_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 8,'Y','N') AS `Delete_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 16,'Y','N') AS `Create_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 32,'Y','N') AS `Drop_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 64,'Y','N') AS `Reload_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 128,'Y','N') AS `Shutdown_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 256,'Y','N') AS `Process_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 512,'Y','N') AS `File_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 1024,'Y','N') AS `Grant_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 2048,'Y','N') AS `References_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 4096,'Y','N') AS `Index_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 8192,'Y','N') AS `Alter_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 16384,'Y','N') AS `Show_db_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 32768,'Y','N') AS `Super_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 65536,'Y','N') AS `Create_tmp_table_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 131072,'Y','N') AS `Lock_tables_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 262144,'Y','N') AS `Execute_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 524288,'Y','N') AS `Repl_slave_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 1048576,'Y','N') AS `Repl_client_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 2097152,'Y','N') AS `Create_view_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 4194304,'Y','N') AS `Show_view_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 8388608,'Y','N') AS `Create_routine_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 16777216,'Y','N') AS `Alter_routine_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 33554432,'Y','N') AS `Create_user_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 67108864,'Y','N') AS `Event_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 134217728,'Y','N') AS `Trigger_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 268435456,'Y','N') AS `Create_tablespace_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 536870912,'Y','N') AS `Delete_history_priv`,elt(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.ssl_type'),0) + 1,'','ANY','X509','SPECIFIED') AS `ssl_type`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.ssl_cipher'),'') AS `ssl_cipher`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.x509_issuer'),'') AS `x509_issuer`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.x509_subject'),'') AS `x509_subject`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_questions'),0) as unsigned) AS `max_questions`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_updates'),0) as unsigned) AS `max_updates`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_connections'),0) as unsigned) AS `max_connections`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_user_connections'),0) as signed) AS `max_user_connections`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.plugin'),'') AS `plugin`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.authentication_string'),'') AS `authentication_string`,if(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.password_last_changed'),1) = 0,'Y','N') AS `password_expired`,elt(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.is_role'),0) + 1,'N','Y') AS `is_role`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.default_role'),'') AS `default_role`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_statement_time'),0.0) as decimal(12,6)) AS `max_statement_time` from `mysql`.`global_priv`;; SET sql_mode=''; DROP PROCEDURE IF EXISTS mysql.AddGeometryColumn; DROP PROCEDURE IF EXISTS mysql.DropGeometryColumn; diff --git a/mysql-test/main/upgrade_MDEV-23102-1.test b/mysql-test/main/upgrade_MDEV-23102-1.test index 1b929f7cabf..d764a6ca84a 100644 --- a/mysql-test/main/upgrade_MDEV-23102-1.test +++ b/mysql-test/main/upgrade_MDEV-23102-1.test @@ -23,57 +23,9 @@ use mysql; create user superuser@localhost; grant all privileges on mysql.* to superuser@localhost; -drop view user; - -CREATE DEFINER='superuser'@'localhost' SQL SECURITY DEFINER VIEW IF NOT EXISTS user AS SELECT - Host, - User, - IF(JSON_VALUE(Priv, '$.plugin') IN ('mysql_native_password', 'mysql_old_password'), IFNULL(JSON_VALUE(Priv, '$.authentication_string'), ''), '') AS Password, - IF(JSON_VALUE(Priv, '$.access') & 1, 'Y', 'N') AS Select_priv, - IF(JSON_VALUE(Priv, '$.access') & 2, 'Y', 'N') AS Insert_priv, - IF(JSON_VALUE(Priv, '$.access') & 4, 'Y', 'N') AS Update_priv, - IF(JSON_VALUE(Priv, '$.access') & 8, 'Y', 'N') AS Delete_priv, - IF(JSON_VALUE(Priv, '$.access') & 16, 'Y', 'N') AS Create_priv, - IF(JSON_VALUE(Priv, '$.access') & 32, 'Y', 'N') AS Drop_priv, - IF(JSON_VALUE(Priv, '$.access') & 64, 'Y', 'N') AS Reload_priv, - IF(JSON_VALUE(Priv, '$.access') & 128, 'Y', 'N') AS Shutdown_priv, - IF(JSON_VALUE(Priv, '$.access') & 256, 'Y', 'N') AS Process_priv, - IF(JSON_VALUE(Priv, '$.access') & 512, 'Y', 'N') AS File_priv, - IF(JSON_VALUE(Priv, '$.access') & 1024, 'Y', 'N') AS Grant_priv, - IF(JSON_VALUE(Priv, '$.access') & 2048, 'Y', 'N') AS References_priv, - IF(JSON_VALUE(Priv, '$.access') & 4096, 'Y', 'N') AS Index_priv, - IF(JSON_VALUE(Priv, '$.access') & 8192, 'Y', 'N') AS Alter_priv, - IF(JSON_VALUE(Priv, '$.access') & 16384, 'Y', 'N') AS Show_db_priv, - IF(JSON_VALUE(Priv, '$.access') & 32768, 'Y', 'N') AS Super_priv, - IF(JSON_VALUE(Priv, '$.access') & 65536, 'Y', 'N') AS Create_tmp_table_priv, - IF(JSON_VALUE(Priv, '$.access') & 131072, 'Y', 'N') AS Lock_tables_priv, - IF(JSON_VALUE(Priv, '$.access') & 262144, 'Y', 'N') AS Execute_priv, - IF(JSON_VALUE(Priv, '$.access') & 524288, 'Y', 'N') AS Repl_slave_priv, - IF(JSON_VALUE(Priv, '$.access') & 1048576, 'Y', 'N') AS Repl_client_priv, - IF(JSON_VALUE(Priv, '$.access') & 2097152, 'Y', 'N') AS Create_view_priv, - IF(JSON_VALUE(Priv, '$.access') & 4194304, 'Y', 'N') AS Show_view_priv, - IF(JSON_VALUE(Priv, '$.access') & 8388608, 'Y', 'N') AS Create_routine_priv, - IF(JSON_VALUE(Priv, '$.access') & 16777216, 'Y', 'N') AS Alter_routine_priv, - IF(JSON_VALUE(Priv, '$.access') & 33554432, 'Y', 'N') AS Create_user_priv, - IF(JSON_VALUE(Priv, '$.access') & 67108864, 'Y', 'N') AS Event_priv, - IF(JSON_VALUE(Priv, '$.access') & 134217728, 'Y', 'N') AS Trigger_priv, - IF(JSON_VALUE(Priv, '$.access') & 268435456, 'Y', 'N') AS Create_tablespace_priv, - IF(JSON_VALUE(Priv, '$.access') & 536870912, 'Y', 'N') AS Delete_history_priv, - ELT(IFNULL(JSON_VALUE(Priv, '$.ssl_type'), 0) + 1, '', 'ANY','X509', 'SPECIFIED') AS ssl_type, - IFNULL(JSON_VALUE(Priv, '$.ssl_cipher'), '') AS ssl_cipher, - IFNULL(JSON_VALUE(Priv, '$.x509_issuer'), '') AS x509_issuer, - IFNULL(JSON_VALUE(Priv, '$.x509_subject'), '') AS x509_subject, - CAST(IFNULL(JSON_VALUE(Priv, '$.max_questions'), 0) AS UNSIGNED) AS max_questions, - CAST(IFNULL(JSON_VALUE(Priv, '$.max_updates'), 0) AS UNSIGNED) AS max_updates, - CAST(IFNULL(JSON_VALUE(Priv, '$.max_connections'), 0) AS UNSIGNED) AS max_connections, - CAST(IFNULL(JSON_VALUE(Priv, '$.max_user_connections'), 0) AS SIGNED) AS max_user_connections, - IFNULL(JSON_VALUE(Priv, '$.plugin'), '') AS plugin, - IFNULL(JSON_VALUE(Priv, '$.authentication_string'), '') AS authentication_string, - ELT(IFNULL(JSON_VALUE(Priv, '$.is_role'), 0) + 1, 'N', 'Y') AS is_role, - IFNULL(JSON_VALUE(Priv, '$.default_role'), '') AS default_role, - CAST(IFNULL(JSON_VALUE(Priv, '$.max_statement_time'), 0.0) AS DECIMAL(12,6)) AS max_statement_time - FROM global_priv; +let $viewdef = `select view_definition from information_schema.views where table_name='user' and table_schema='mysql'`; +--eval create or replace definer=superuser@localhost sql security definer view user as $viewdef; SET sql_mode=''; diff --git a/mysql-test/main/upgrade_MDEV-23102-2.result b/mysql-test/main/upgrade_MDEV-23102-2.result index 53240f0c2a7..c7f373dd69d 100644 --- a/mysql-test/main/upgrade_MDEV-23102-2.result +++ b/mysql-test/main/upgrade_MDEV-23102-2.result @@ -16,55 +16,7 @@ use mysql; # make changed definition of gis procedures and user view create user superuser@localhost; grant all privileges on mysql.* to superuser@localhost; -drop view user; -CREATE DEFINER='superuser'@'localhost' SQL SECURITY DEFINER VIEW IF NOT EXISTS user AS SELECT -Host, -User, -IF(JSON_VALUE(Priv, '$.plugin') IN ('mysql_native_password', 'mysql_old_password'), IFNULL(JSON_VALUE(Priv, '$.authentication_string'), ''), '') AS Password, -IF(JSON_VALUE(Priv, '$.access') & 1, 'Y', 'N') AS Select_priv, -IF(JSON_VALUE(Priv, '$.access') & 2, 'Y', 'N') AS Insert_priv, -IF(JSON_VALUE(Priv, '$.access') & 4, 'Y', 'N') AS Update_priv, -IF(JSON_VALUE(Priv, '$.access') & 8, 'Y', 'N') AS Delete_priv, -IF(JSON_VALUE(Priv, '$.access') & 16, 'Y', 'N') AS Create_priv, -IF(JSON_VALUE(Priv, '$.access') & 32, 'Y', 'N') AS Drop_priv, -IF(JSON_VALUE(Priv, '$.access') & 64, 'Y', 'N') AS Reload_priv, -IF(JSON_VALUE(Priv, '$.access') & 128, 'Y', 'N') AS Shutdown_priv, -IF(JSON_VALUE(Priv, '$.access') & 256, 'Y', 'N') AS Process_priv, -IF(JSON_VALUE(Priv, '$.access') & 512, 'Y', 'N') AS File_priv, -IF(JSON_VALUE(Priv, '$.access') & 1024, 'Y', 'N') AS Grant_priv, -IF(JSON_VALUE(Priv, '$.access') & 2048, 'Y', 'N') AS References_priv, -IF(JSON_VALUE(Priv, '$.access') & 4096, 'Y', 'N') AS Index_priv, -IF(JSON_VALUE(Priv, '$.access') & 8192, 'Y', 'N') AS Alter_priv, -IF(JSON_VALUE(Priv, '$.access') & 16384, 'Y', 'N') AS Show_db_priv, -IF(JSON_VALUE(Priv, '$.access') & 32768, 'Y', 'N') AS Super_priv, -IF(JSON_VALUE(Priv, '$.access') & 65536, 'Y', 'N') AS Create_tmp_table_priv, -IF(JSON_VALUE(Priv, '$.access') & 131072, 'Y', 'N') AS Lock_tables_priv, -IF(JSON_VALUE(Priv, '$.access') & 262144, 'Y', 'N') AS Execute_priv, -IF(JSON_VALUE(Priv, '$.access') & 524288, 'Y', 'N') AS Repl_slave_priv, -IF(JSON_VALUE(Priv, '$.access') & 1048576, 'Y', 'N') AS Repl_client_priv, -IF(JSON_VALUE(Priv, '$.access') & 2097152, 'Y', 'N') AS Create_view_priv, -IF(JSON_VALUE(Priv, '$.access') & 4194304, 'Y', 'N') AS Show_view_priv, -IF(JSON_VALUE(Priv, '$.access') & 8388608, 'Y', 'N') AS Create_routine_priv, -IF(JSON_VALUE(Priv, '$.access') & 16777216, 'Y', 'N') AS Alter_routine_priv, -IF(JSON_VALUE(Priv, '$.access') & 33554432, 'Y', 'N') AS Create_user_priv, -IF(JSON_VALUE(Priv, '$.access') & 67108864, 'Y', 'N') AS Event_priv, -IF(JSON_VALUE(Priv, '$.access') & 134217728, 'Y', 'N') AS Trigger_priv, -IF(JSON_VALUE(Priv, '$.access') & 268435456, 'Y', 'N') AS Create_tablespace_priv, -IF(JSON_VALUE(Priv, '$.access') & 536870912, 'Y', 'N') AS Delete_history_priv, -ELT(IFNULL(JSON_VALUE(Priv, '$.ssl_type'), 0) + 1, '', 'ANY','X509', 'SPECIFIED') AS ssl_type, -IFNULL(JSON_VALUE(Priv, '$.ssl_cipher'), '') AS ssl_cipher, -IFNULL(JSON_VALUE(Priv, '$.x509_issuer'), '') AS x509_issuer, -IFNULL(JSON_VALUE(Priv, '$.x509_subject'), '') AS x509_subject, -CAST(IFNULL(JSON_VALUE(Priv, '$.max_questions'), 0) AS UNSIGNED) AS max_questions, -CAST(IFNULL(JSON_VALUE(Priv, '$.max_updates'), 0) AS UNSIGNED) AS max_updates, -CAST(IFNULL(JSON_VALUE(Priv, '$.max_connections'), 0) AS UNSIGNED) AS max_connections, -CAST(IFNULL(JSON_VALUE(Priv, '$.max_user_connections'), 0) AS SIGNED) AS max_user_connections, -IFNULL(JSON_VALUE(Priv, '$.plugin'), '') AS plugin, -IFNULL(JSON_VALUE(Priv, '$.authentication_string'), '') AS authentication_string, -ELT(IFNULL(JSON_VALUE(Priv, '$.is_role'), 0) + 1, 'N', 'Y') AS is_role, -IFNULL(JSON_VALUE(Priv, '$.default_role'), '') AS default_role, -CAST(IFNULL(JSON_VALUE(Priv, '$.max_statement_time'), 0.0) AS DECIMAL(12,6)) AS max_statement_time -FROM global_priv; +create or replace definer=superuser@localhost sql security definer view user as select `mysql`.`global_priv`.`Host` AS `Host`,`mysql`.`global_priv`.`User` AS `User`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.plugin') in ('mysql_native_password','mysql_old_password'),ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.authentication_string'),''),'') AS `Password`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 1,'Y','N') AS `Select_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 2,'Y','N') AS `Insert_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 4,'Y','N') AS `Update_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 8,'Y','N') AS `Delete_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 16,'Y','N') AS `Create_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 32,'Y','N') AS `Drop_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 64,'Y','N') AS `Reload_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 128,'Y','N') AS `Shutdown_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 256,'Y','N') AS `Process_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 512,'Y','N') AS `File_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 1024,'Y','N') AS `Grant_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 2048,'Y','N') AS `References_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 4096,'Y','N') AS `Index_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 8192,'Y','N') AS `Alter_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 16384,'Y','N') AS `Show_db_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 32768,'Y','N') AS `Super_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 65536,'Y','N') AS `Create_tmp_table_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 131072,'Y','N') AS `Lock_tables_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 262144,'Y','N') AS `Execute_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 524288,'Y','N') AS `Repl_slave_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 1048576,'Y','N') AS `Repl_client_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 2097152,'Y','N') AS `Create_view_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 4194304,'Y','N') AS `Show_view_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 8388608,'Y','N') AS `Create_routine_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 16777216,'Y','N') AS `Alter_routine_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 33554432,'Y','N') AS `Create_user_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 67108864,'Y','N') AS `Event_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 134217728,'Y','N') AS `Trigger_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 268435456,'Y','N') AS `Create_tablespace_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 536870912,'Y','N') AS `Delete_history_priv`,elt(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.ssl_type'),0) + 1,'','ANY','X509','SPECIFIED') AS `ssl_type`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.ssl_cipher'),'') AS `ssl_cipher`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.x509_issuer'),'') AS `x509_issuer`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.x509_subject'),'') AS `x509_subject`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_questions'),0) as unsigned) AS `max_questions`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_updates'),0) as unsigned) AS `max_updates`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_connections'),0) as unsigned) AS `max_connections`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_user_connections'),0) as signed) AS `max_user_connections`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.plugin'),'') AS `plugin`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.authentication_string'),'') AS `authentication_string`,if(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.password_last_changed'),1) = 0,'Y','N') AS `password_expired`,elt(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.is_role'),0) + 1,'N','Y') AS `is_role`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.default_role'),'') AS `default_role`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_statement_time'),0.0) as decimal(12,6)) AS `max_statement_time` from `mysql`.`global_priv`;; DROP PROCEDURE IF EXISTS mysql.AddGeometryColumn; DROP PROCEDURE IF EXISTS mysql.DropGeometryColumn; drop user 'mariadb.sys'@'localhost'; diff --git a/mysql-test/main/upgrade_MDEV-23102-2.test b/mysql-test/main/upgrade_MDEV-23102-2.test index 1491f7d7bd2..27ee75ea58c 100644 --- a/mysql-test/main/upgrade_MDEV-23102-2.test +++ b/mysql-test/main/upgrade_MDEV-23102-2.test @@ -23,57 +23,9 @@ use mysql; create user superuser@localhost; grant all privileges on mysql.* to superuser@localhost; -drop view user; - -CREATE DEFINER='superuser'@'localhost' SQL SECURITY DEFINER VIEW IF NOT EXISTS user AS SELECT - Host, - User, - IF(JSON_VALUE(Priv, '$.plugin') IN ('mysql_native_password', 'mysql_old_password'), IFNULL(JSON_VALUE(Priv, '$.authentication_string'), ''), '') AS Password, - IF(JSON_VALUE(Priv, '$.access') & 1, 'Y', 'N') AS Select_priv, - IF(JSON_VALUE(Priv, '$.access') & 2, 'Y', 'N') AS Insert_priv, - IF(JSON_VALUE(Priv, '$.access') & 4, 'Y', 'N') AS Update_priv, - IF(JSON_VALUE(Priv, '$.access') & 8, 'Y', 'N') AS Delete_priv, - IF(JSON_VALUE(Priv, '$.access') & 16, 'Y', 'N') AS Create_priv, - IF(JSON_VALUE(Priv, '$.access') & 32, 'Y', 'N') AS Drop_priv, - IF(JSON_VALUE(Priv, '$.access') & 64, 'Y', 'N') AS Reload_priv, - IF(JSON_VALUE(Priv, '$.access') & 128, 'Y', 'N') AS Shutdown_priv, - IF(JSON_VALUE(Priv, '$.access') & 256, 'Y', 'N') AS Process_priv, - IF(JSON_VALUE(Priv, '$.access') & 512, 'Y', 'N') AS File_priv, - IF(JSON_VALUE(Priv, '$.access') & 1024, 'Y', 'N') AS Grant_priv, - IF(JSON_VALUE(Priv, '$.access') & 2048, 'Y', 'N') AS References_priv, - IF(JSON_VALUE(Priv, '$.access') & 4096, 'Y', 'N') AS Index_priv, - IF(JSON_VALUE(Priv, '$.access') & 8192, 'Y', 'N') AS Alter_priv, - IF(JSON_VALUE(Priv, '$.access') & 16384, 'Y', 'N') AS Show_db_priv, - IF(JSON_VALUE(Priv, '$.access') & 32768, 'Y', 'N') AS Super_priv, - IF(JSON_VALUE(Priv, '$.access') & 65536, 'Y', 'N') AS Create_tmp_table_priv, - IF(JSON_VALUE(Priv, '$.access') & 131072, 'Y', 'N') AS Lock_tables_priv, - IF(JSON_VALUE(Priv, '$.access') & 262144, 'Y', 'N') AS Execute_priv, - IF(JSON_VALUE(Priv, '$.access') & 524288, 'Y', 'N') AS Repl_slave_priv, - IF(JSON_VALUE(Priv, '$.access') & 1048576, 'Y', 'N') AS Repl_client_priv, - IF(JSON_VALUE(Priv, '$.access') & 2097152, 'Y', 'N') AS Create_view_priv, - IF(JSON_VALUE(Priv, '$.access') & 4194304, 'Y', 'N') AS Show_view_priv, - IF(JSON_VALUE(Priv, '$.access') & 8388608, 'Y', 'N') AS Create_routine_priv, - IF(JSON_VALUE(Priv, '$.access') & 16777216, 'Y', 'N') AS Alter_routine_priv, - IF(JSON_VALUE(Priv, '$.access') & 33554432, 'Y', 'N') AS Create_user_priv, - IF(JSON_VALUE(Priv, '$.access') & 67108864, 'Y', 'N') AS Event_priv, - IF(JSON_VALUE(Priv, '$.access') & 134217728, 'Y', 'N') AS Trigger_priv, - IF(JSON_VALUE(Priv, '$.access') & 268435456, 'Y', 'N') AS Create_tablespace_priv, - IF(JSON_VALUE(Priv, '$.access') & 536870912, 'Y', 'N') AS Delete_history_priv, - ELT(IFNULL(JSON_VALUE(Priv, '$.ssl_type'), 0) + 1, '', 'ANY','X509', 'SPECIFIED') AS ssl_type, - IFNULL(JSON_VALUE(Priv, '$.ssl_cipher'), '') AS ssl_cipher, - IFNULL(JSON_VALUE(Priv, '$.x509_issuer'), '') AS x509_issuer, - IFNULL(JSON_VALUE(Priv, '$.x509_subject'), '') AS x509_subject, - CAST(IFNULL(JSON_VALUE(Priv, '$.max_questions'), 0) AS UNSIGNED) AS max_questions, - CAST(IFNULL(JSON_VALUE(Priv, '$.max_updates'), 0) AS UNSIGNED) AS max_updates, - CAST(IFNULL(JSON_VALUE(Priv, '$.max_connections'), 0) AS UNSIGNED) AS max_connections, - CAST(IFNULL(JSON_VALUE(Priv, '$.max_user_connections'), 0) AS SIGNED) AS max_user_connections, - IFNULL(JSON_VALUE(Priv, '$.plugin'), '') AS plugin, - IFNULL(JSON_VALUE(Priv, '$.authentication_string'), '') AS authentication_string, - ELT(IFNULL(JSON_VALUE(Priv, '$.is_role'), 0) + 1, 'N', 'Y') AS is_role, - IFNULL(JSON_VALUE(Priv, '$.default_role'), '') AS default_role, - CAST(IFNULL(JSON_VALUE(Priv, '$.max_statement_time'), 0.0) AS DECIMAL(12,6)) AS max_statement_time - FROM global_priv; +let $viewdef = `select view_definition from information_schema.views where table_name='user' and table_schema='mysql'`; +--eval create or replace definer=superuser@localhost sql security definer view user as $viewdef; DROP PROCEDURE IF EXISTS mysql.AddGeometryColumn; DROP PROCEDURE IF EXISTS mysql.DropGeometryColumn; From cf1ca57e75de0a06349d13813146396c4b0e3a9d Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sat, 6 Mar 2021 12:18:48 +0100 Subject: [PATCH 03/26] cleanup: renames, no need to create a new .inc file if it's the whole content of a test anyway. --- .../binlog/include/binlog_write_error.inc | 108 ------------------ .../suite/binlog/r/binlog_write_error.result | 19 --- .../suite/binlog/t/binlog_write_error.test | 80 ++++++++++++- .../binlog_write_error.result | 19 --- .../binlog_encryption/binlog_write_error.test | 2 +- 5 files changed, 80 insertions(+), 148 deletions(-) delete mode 100644 mysql-test/suite/binlog/include/binlog_write_error.inc diff --git a/mysql-test/suite/binlog/include/binlog_write_error.inc b/mysql-test/suite/binlog/include/binlog_write_error.inc deleted file mode 100644 index fa3ba087a7e..00000000000 --- a/mysql-test/suite/binlog/include/binlog_write_error.inc +++ /dev/null @@ -1,108 +0,0 @@ -# -# This include file is used by more than one test suite -# (currently binlog and binlog_encryption). -# Please check all dependent tests after modifying it -# - -# -# === Name === -# -# binlog_write_error.test -# -# === Description === -# -# This test case check if the error of writing binlog file is properly -# reported and handled when executing statements. -# -# === Related Bugs === -# -# BUG#37148 -# - -source include/have_log_bin.inc; -source include/have_debug.inc; -source include/have_binlog_format_mixed_or_statement.inc; - ---echo # ---echo # Initialization ---echo # - -disable_warnings; -DROP TABLE IF EXISTS t1, t2; -DROP FUNCTION IF EXISTS f1; -DROP FUNCTION IF EXISTS f2; -DROP PROCEDURE IF EXISTS p1; -DROP PROCEDURE IF EXISTS p2; -DROP TRIGGER IF EXISTS tr1; -DROP TRIGGER IF EXISTS tr2; -DROP VIEW IF EXISTS v1, v2; -enable_warnings; - ---echo # ---echo # Test injecting binlog write error when executing queries ---echo # - -let $query= CREATE TABLE t1 (a INT); -source include/binlog_inject_error.inc; - -INSERT INTO t1 VALUES (1),(2),(3); - -let $query= INSERT INTO t1 VALUES (4),(5),(6); -source include/binlog_inject_error.inc; - -let $query= UPDATE t1 set a=a+1; -source include/binlog_inject_error.inc; - -let $query= DELETE FROM t1; -source include/binlog_inject_error.inc; - -let $query= CREATE TRIGGER tr1 AFTER INSERT ON t1 FOR EACH ROW INSERT INTO t1 VALUES (new.a + 100); -source include/binlog_inject_error.inc; - -let $query= DROP TRIGGER tr1; -source include/binlog_inject_error.inc; - -let $query= ALTER TABLE t1 ADD (b INT); -source include/binlog_inject_error.inc; - -let $query= CREATE VIEW v1 AS SELECT a FROM t1; -source include/binlog_inject_error.inc; - -let $query= DROP VIEW v1; -source include/binlog_inject_error.inc; - -let $query= CREATE PROCEDURE p1(OUT rows_cnt INT) SELECT count(*) INTO rows_cnt FROM t1; -source include/binlog_inject_error.inc; - -let $query= DROP PROCEDURE p1; -source include/binlog_inject_error.inc; - -let $query= DROP TABLE t1; -source include/binlog_inject_error.inc; - -let $query= CREATE FUNCTION f1() RETURNS INT return 1; -source include/binlog_inject_error.inc; - -let $query= DROP FUNCTION f1; -source include/binlog_inject_error.inc; - -let $query= CREATE USER user1; -source include/binlog_inject_error.inc; - -let $query= REVOKE ALL PRIVILEGES, GRANT OPTION FROM user1; -source include/binlog_inject_error.inc; - -let $query= DROP USER user1; -source include/binlog_inject_error.inc; - ---echo # ---echo # Cleanup ---echo # - -disable_warnings; -DROP TABLE IF EXISTS t1, t2; -DROP FUNCTION IF EXISTS f1; -DROP PROCEDURE IF EXISTS p1; -DROP TRIGGER IF EXISTS tr1; -DROP VIEW IF EXISTS v1, v2; -enable_warnings; diff --git a/mysql-test/suite/binlog/r/binlog_write_error.result b/mysql-test/suite/binlog/r/binlog_write_error.result index 6e8a212035a..f37351770ac 100644 --- a/mysql-test/suite/binlog/r/binlog_write_error.result +++ b/mysql-test/suite/binlog/r/binlog_write_error.result @@ -1,15 +1,4 @@ # -# Initialization -# -DROP TABLE IF EXISTS t1, t2; -DROP FUNCTION IF EXISTS f1; -DROP FUNCTION IF EXISTS f2; -DROP PROCEDURE IF EXISTS p1; -DROP PROCEDURE IF EXISTS p2; -DROP TRIGGER IF EXISTS tr1; -DROP TRIGGER IF EXISTS tr2; -DROP VIEW IF EXISTS v1, v2; -# # Test injecting binlog write error when executing queries # set @saved_dbug = @@global.debug_dbug; @@ -115,11 +104,3 @@ DROP USER user1; DROP USER user1; ERROR HY000: Error writing file 'master-bin' ((errno: #) set @@global.debug_dbug = @saved_dbug; -# -# Cleanup -# -DROP TABLE IF EXISTS t1, t2; -DROP FUNCTION IF EXISTS f1; -DROP PROCEDURE IF EXISTS p1; -DROP TRIGGER IF EXISTS tr1; -DROP VIEW IF EXISTS v1, v2; diff --git a/mysql-test/suite/binlog/t/binlog_write_error.test b/mysql-test/suite/binlog/t/binlog_write_error.test index d66efb0bcf3..1eccee31a9f 100644 --- a/mysql-test/suite/binlog/t/binlog_write_error.test +++ b/mysql-test/suite/binlog/t/binlog_write_error.test @@ -1 +1,79 @@ ---source include/binlog_write_error.inc +# +# This file is included by binlog_encryption.binlog_write_error +# Please check all dependent tests after modifying it +# + +# +# === Name === +# +# binlog_write_error.test +# +# === Description === +# +# This test case check if the error of writing binlog file is properly +# reported and handled when executing statements. +# +# === Related Bugs === +# +# BUG#37148 +# + +source include/have_debug.inc; +source include/have_binlog_format_mixed_or_statement.inc; + +--echo # +--echo # Test injecting binlog write error when executing queries +--echo # + +let $query= CREATE TABLE t1 (a INT); +source include/binlog_inject_error.inc; + +INSERT INTO t1 VALUES (1),(2),(3); + +let $query= INSERT INTO t1 VALUES (4),(5),(6); +source include/binlog_inject_error.inc; + +let $query= UPDATE t1 set a=a+1; +source include/binlog_inject_error.inc; + +let $query= DELETE FROM t1; +source include/binlog_inject_error.inc; + +let $query= CREATE TRIGGER tr1 AFTER INSERT ON t1 FOR EACH ROW INSERT INTO t1 VALUES (new.a + 100); +source include/binlog_inject_error.inc; + +let $query= DROP TRIGGER tr1; +source include/binlog_inject_error.inc; + +let $query= ALTER TABLE t1 ADD (b INT); +source include/binlog_inject_error.inc; + +let $query= CREATE VIEW v1 AS SELECT a FROM t1; +source include/binlog_inject_error.inc; + +let $query= DROP VIEW v1; +source include/binlog_inject_error.inc; + +let $query= CREATE PROCEDURE p1(OUT rows_cnt INT) SELECT count(*) INTO rows_cnt FROM t1; +source include/binlog_inject_error.inc; + +let $query= DROP PROCEDURE p1; +source include/binlog_inject_error.inc; + +let $query= DROP TABLE t1; +source include/binlog_inject_error.inc; + +let $query= CREATE FUNCTION f1() RETURNS INT return 1; +source include/binlog_inject_error.inc; + +let $query= DROP FUNCTION f1; +source include/binlog_inject_error.inc; + +let $query= CREATE USER user1; +source include/binlog_inject_error.inc; + +let $query= REVOKE ALL PRIVILEGES, GRANT OPTION FROM user1; +source include/binlog_inject_error.inc; + +let $query= DROP USER user1; +source include/binlog_inject_error.inc; diff --git a/mysql-test/suite/binlog_encryption/binlog_write_error.result b/mysql-test/suite/binlog_encryption/binlog_write_error.result index 6e8a212035a..f37351770ac 100644 --- a/mysql-test/suite/binlog_encryption/binlog_write_error.result +++ b/mysql-test/suite/binlog_encryption/binlog_write_error.result @@ -1,15 +1,4 @@ # -# Initialization -# -DROP TABLE IF EXISTS t1, t2; -DROP FUNCTION IF EXISTS f1; -DROP FUNCTION IF EXISTS f2; -DROP PROCEDURE IF EXISTS p1; -DROP PROCEDURE IF EXISTS p2; -DROP TRIGGER IF EXISTS tr1; -DROP TRIGGER IF EXISTS tr2; -DROP VIEW IF EXISTS v1, v2; -# # Test injecting binlog write error when executing queries # set @saved_dbug = @@global.debug_dbug; @@ -115,11 +104,3 @@ DROP USER user1; DROP USER user1; ERROR HY000: Error writing file 'master-bin' ((errno: #) set @@global.debug_dbug = @saved_dbug; -# -# Cleanup -# -DROP TABLE IF EXISTS t1, t2; -DROP FUNCTION IF EXISTS f1; -DROP PROCEDURE IF EXISTS p1; -DROP TRIGGER IF EXISTS tr1; -DROP VIEW IF EXISTS v1, v2; diff --git a/mysql-test/suite/binlog_encryption/binlog_write_error.test b/mysql-test/suite/binlog_encryption/binlog_write_error.test index 68e59655eab..8add24da984 100644 --- a/mysql-test/suite/binlog_encryption/binlog_write_error.test +++ b/mysql-test/suite/binlog_encryption/binlog_write_error.test @@ -1 +1 @@ ---source suite/binlog/include/binlog_write_error.inc +--source suite/binlog/t/binlog_write_error.test From 9742cf42035b3bebd50bbefe787e316cd041bf01 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sat, 6 Mar 2021 12:31:02 +0100 Subject: [PATCH 04/26] MDEV-24668 debug assert on SET PASSWORD when binlog fails don't use `result` both for an error status and to remember if the mutex was locked --- mysql-test/suite/binlog/r/binlog_write_error.result | 6 ++++++ mysql-test/suite/binlog/t/binlog_write_error.test | 3 +++ .../suite/binlog_encryption/binlog_write_error.result | 6 ++++++ sql/sql_acl.cc | 8 ++++---- 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/mysql-test/suite/binlog/r/binlog_write_error.result b/mysql-test/suite/binlog/r/binlog_write_error.result index f37351770ac..2ee68465243 100644 --- a/mysql-test/suite/binlog/r/binlog_write_error.result +++ b/mysql-test/suite/binlog/r/binlog_write_error.result @@ -100,6 +100,12 @@ ERROR HY000: Error writing file 'master-bin' ((errno: #) set @@global.debug_dbug = @saved_dbug; set @saved_dbug = @@global.debug_dbug; SET GLOBAL debug_dbug='d,injecting_fault_writing'; +SET PASSWORD FOR user1=PASSWORD('foobar'); +SET PASSWORD FOR user1=PASSWORD('foobar'); +ERROR HY000: Error writing file 'master-bin' ((errno: #) +set @@global.debug_dbug = @saved_dbug; +set @saved_dbug = @@global.debug_dbug; +SET GLOBAL debug_dbug='d,injecting_fault_writing'; DROP USER user1; DROP USER user1; ERROR HY000: Error writing file 'master-bin' ((errno: #) diff --git a/mysql-test/suite/binlog/t/binlog_write_error.test b/mysql-test/suite/binlog/t/binlog_write_error.test index 1eccee31a9f..2c55173c2a1 100644 --- a/mysql-test/suite/binlog/t/binlog_write_error.test +++ b/mysql-test/suite/binlog/t/binlog_write_error.test @@ -75,5 +75,8 @@ source include/binlog_inject_error.inc; let $query= REVOKE ALL PRIVILEGES, GRANT OPTION FROM user1; source include/binlog_inject_error.inc; +let $query= SET PASSWORD FOR user1=PASSWORD('foobar'); +source include/binlog_inject_error.inc; + let $query= DROP USER user1; source include/binlog_inject_error.inc; diff --git a/mysql-test/suite/binlog_encryption/binlog_write_error.result b/mysql-test/suite/binlog_encryption/binlog_write_error.result index f37351770ac..2ee68465243 100644 --- a/mysql-test/suite/binlog_encryption/binlog_write_error.result +++ b/mysql-test/suite/binlog_encryption/binlog_write_error.result @@ -100,6 +100,12 @@ ERROR HY000: Error writing file 'master-bin' ((errno: #) set @@global.debug_dbug = @saved_dbug; set @saved_dbug = @@global.debug_dbug; SET GLOBAL debug_dbug='d,injecting_fault_writing'; +SET PASSWORD FOR user1=PASSWORD('foobar'); +SET PASSWORD FOR user1=PASSWORD('foobar'); +ERROR HY000: Error writing file 'master-bin' ((errno: #) +set @@global.debug_dbug = @saved_dbug; +set @saved_dbug = @@global.debug_dbug; +SET GLOBAL debug_dbug='d,injecting_fault_writing'; DROP USER user1; DROP USER user1; ERROR HY000: Error writing file 'master-bin' ((errno: #) diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 85f4b178b36..b8c061456c8 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -3794,7 +3794,7 @@ bool change_password(THD *thd, LEX_USER *user) char buff[512]; ulong query_length= 0; enum_binlog_format save_binlog_format; - int result=0; + bool result, acl_cache_is_locked= false; ACL_USER *acl_user; ACL_USER::AUTH auth; const char *password_plugin= 0; @@ -3819,7 +3819,7 @@ bool change_password(THD *thd, LEX_USER *user) if ((result= tables.open_and_lock(thd, Table_user, TL_WRITE))) DBUG_RETURN(result != 1); - result= 1; + acl_cache_is_locked= 1; mysql_mutex_lock(&acl_cache->lock); if (!(acl_user= find_user_exact(user->host.str, user->user.str))) @@ -3872,7 +3872,7 @@ bool change_password(THD *thd, LEX_USER *user) acl_cache->clear(1); // Clear locked hostname cache mysql_mutex_unlock(&acl_cache->lock); - result= 0; + result= acl_cache_is_locked= 0; if (mysql_bin_log.is_open()) { query_length= sprintf(buff, "SET PASSWORD FOR '%-.120s'@'%-.120s'='%-.120s'", @@ -3883,7 +3883,7 @@ bool change_password(THD *thd, LEX_USER *user) FALSE, FALSE, FALSE, 0) > 0; } end: - if (result) + if (acl_cache_is_locked) mysql_mutex_unlock(&acl_cache->lock); close_mysql_tables(thd); From f24038b8515864e496dd2c55d973a0227b3698df Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 7 Mar 2021 14:06:01 +0100 Subject: [PATCH 05/26] mark Aria allocations for temp tables as MY_THREAD_SPECIFIC --- storage/maria/ma_bitmap.c | 5 +++-- storage/maria/ma_blockrec.c | 24 ++++++++++++--------- storage/maria/ma_check.c | 11 +++++----- storage/maria/ma_create.c | 18 +++++++++------- storage/maria/ma_dynrec.c | 13 ++++++----- storage/maria/ma_extra.c | 5 +++-- storage/maria/ma_open.c | 43 +++++++++++++++++++------------------ storage/maria/ma_packrec.c | 23 ++++++++++++-------- storage/maria/maria_def.h | 2 +- 9 files changed, 81 insertions(+), 63 deletions(-) diff --git a/storage/maria/ma_bitmap.c b/storage/maria/ma_bitmap.c index fadf04861fa..4f3a2ae5f89 100644 --- a/storage/maria/ma_bitmap.c +++ b/storage/maria/ma_bitmap.c @@ -232,15 +232,16 @@ my_bool _ma_bitmap_init(MARIA_SHARE *share, File file, uint max_page_size; MARIA_FILE_BITMAP *bitmap= &share->bitmap; uint size= share->block_size; + myf flag= MY_WME | (share->temporary ? MY_THREAD_SPECIFIC : 0); pgcache_page_no_t first_bitmap_with_space; #ifndef DBUG_OFF /* We want to have a copy of the bitmap to be able to print differences */ size*= 2; #endif - if (((bitmap->map= (uchar*) my_malloc(size, MYF(MY_WME))) == NULL) || + if (((bitmap->map= (uchar*) my_malloc(size, flag)) == NULL) || my_init_dynamic_array(&bitmap->pinned_pages, - sizeof(MARIA_PINNED_PAGE), 1, 1, MYF(0))) + sizeof(MARIA_PINNED_PAGE), 1, 1, flag)) return 1; bitmap->share= share; diff --git a/storage/maria/ma_blockrec.c b/storage/maria/ma_blockrec.c index a82637e2b82..592aab6da41 100644 --- a/storage/maria/ma_blockrec.c +++ b/storage/maria/ma_blockrec.c @@ -485,10 +485,11 @@ my_bool _ma_init_block_record(MARIA_HA *info) { MARIA_ROW *row= &info->cur_row, *new_row= &info->new_row; MARIA_SHARE *share= info->s; + myf flag= MY_WME | (share->temporary ? MY_THREAD_SPECIFIC : 0); uint default_extents; DBUG_ENTER("_ma_init_block_record"); - if (!my_multi_malloc(MY_WME, + if (!my_multi_malloc(flag, &row->empty_bits, share->base.pack_bytes, &row->field_lengths, share->base.max_field_lengths + 2, @@ -527,13 +528,12 @@ my_bool _ma_init_block_record(MARIA_HA *info) FULL_PAGE_SIZE(share) / BLOB_SEGMENT_MIN_SIZE)); - if (my_init_dynamic_array(&info->bitmap_blocks, - sizeof(MARIA_BITMAP_BLOCK), default_extents, - 64, MYF(0))) + if (my_init_dynamic_array(&info->bitmap_blocks, sizeof(MARIA_BITMAP_BLOCK), + default_extents, 64, flag)) goto err; info->cur_row.extents_buffer_length= default_extents * ROW_EXTENT_SIZE; if (!(info->cur_row.extents= my_malloc(info->cur_row.extents_buffer_length, - MYF(MY_WME)))) + flag))) goto err; info->row_base_length= share->base_length; @@ -2642,6 +2642,7 @@ static my_bool write_block_record(MARIA_HA *info, LSN lsn; my_off_t position; uint save_my_errno; + myf myflag= MY_WME | (share->temporary ? MY_THREAD_SPECIFIC : 0); DBUG_ENTER("write_block_record"); head_block= bitmap_blocks->block; @@ -2708,7 +2709,7 @@ static my_bool write_block_record(MARIA_HA *info, for every data segment we want to store. */ if (_ma_alloc_buffer(&info->rec_buff, &info->rec_buff_size, - row->head_length)) + row->head_length, myflag)) DBUG_RETURN(1); tmp_data_used= 0; /* Either 0 or last used uchar in 'data' */ @@ -4718,6 +4719,7 @@ int _ma_read_block_record2(MARIA_HA *info, uchar *record, MARIA_EXTENT_CURSOR extent; MARIA_COLUMNDEF *column, *end_column; MARIA_ROW *cur_row= &info->cur_row; + myf myflag= MY_WME | (share->temporary ? MY_THREAD_SPECIFIC : 0); DBUG_ENTER("_ma_read_block_record2"); start_of_data= data; @@ -4763,7 +4765,7 @@ int _ma_read_block_record2(MARIA_HA *info, uchar *record, if (cur_row->extents_buffer_length < row_extent_size && _ma_alloc_buffer(&cur_row->extents, &cur_row->extents_buffer_length, - row_extent_size)) + row_extent_size, myflag)) DBUG_RETURN(my_errno); memcpy(cur_row->extents, data, ROW_EXTENT_SIZE); data+= ROW_EXTENT_SIZE; @@ -4944,7 +4946,7 @@ int _ma_read_block_record2(MARIA_HA *info, uchar *record, cur_row->blob_length= blob_lengths; DBUG_PRINT("info", ("Total blob length: %lu", blob_lengths)); if (_ma_alloc_buffer(&info->blob_buff, &info->blob_buff_size, - blob_lengths)) + blob_lengths, myflag)) DBUG_RETURN(my_errno); blob_buffer= info->blob_buff; } @@ -5050,6 +5052,7 @@ static my_bool read_row_extent_info(MARIA_HA *info, uchar *buff, uint flag, row_extents, row_extents_size; uint field_lengths __attribute__ ((unused)); uchar *extents, *end; + myf myflag= MY_WME | (share->temporary ? MY_THREAD_SPECIFIC : 0); DBUG_ENTER("read_row_extent_info"); if (!(data= get_record_position(share, buff, @@ -5073,7 +5076,7 @@ static my_bool read_row_extent_info(MARIA_HA *info, uchar *buff, if (info->cur_row.extents_buffer_length < row_extents_size && _ma_alloc_buffer(&info->cur_row.extents, &info->cur_row.extents_buffer_length, - row_extents_size)) + row_extents_size, myflag)) DBUG_RETURN(1); memcpy(info->cur_row.extents, data, ROW_EXTENT_SIZE); data+= ROW_EXTENT_SIZE; @@ -5244,6 +5247,7 @@ my_bool _ma_cmp_block_unique(MARIA_HA *info, MARIA_UNIQUEDEF *def, my_bool _ma_scan_init_block_record(MARIA_HA *info) { MARIA_SHARE *share= info->s; + myf flag= MY_WME | (share->temporary ? MY_THREAD_SPECIFIC : 0); DBUG_ENTER("_ma_scan_init_block_record"); DBUG_ASSERT(info->dfile.file == share->bitmap.file.file); @@ -5253,7 +5257,7 @@ my_bool _ma_scan_init_block_record(MARIA_HA *info) */ if (!(info->scan.bitmap_buff || ((info->scan.bitmap_buff= - (uchar *) my_malloc(share->block_size * 2, MYF(MY_WME)))))) + (uchar *) my_malloc(share->block_size * 2, flag))))) DBUG_RETURN(1); info->scan.page_buff= info->scan.bitmap_buff + share->block_size; info->scan.bitmap_end= info->scan.bitmap_buff + share->bitmap.max_total_size; diff --git a/storage/maria/ma_check.c b/storage/maria/ma_check.c index 26a9241c205..e1722d7f2a8 100644 --- a/storage/maria/ma_check.c +++ b/storage/maria/ma_check.c @@ -1271,6 +1271,7 @@ static int check_dynamic_record(HA_CHECK *param, MARIA_HA *info, int extend, ulong UNINIT_VAR(left_length); uint b_type; char llbuff[22],llbuff2[22],llbuff3[22]; + myf myflag= MY_WME | (share->temporary ? MY_THREAD_SPECIFIC : 0); DBUG_ENTER("check_dynamic_record"); pos= 0; @@ -1378,7 +1379,7 @@ static int check_dynamic_record(HA_CHECK *param, MARIA_HA *info, int extend, { if (_ma_alloc_buffer(&info->rec_buff, &info->rec_buff_size, block_info.rec_len + - share->base.extra_rec_buff_size)) + share->base.extra_rec_buff_size, myflag)) { _ma_check_print_error(param, @@ -2694,7 +2695,7 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info, (uchar *) my_malloc((uint) share->base.default_rec_buff_size, MYF(0))) || _ma_alloc_buffer(&sort_param.rec_buff, &sort_param.rec_buff_size, - share->base.default_rec_buff_size)) + share->base.default_rec_buff_size, MYF(0))) { _ma_check_print_error(param, "Not enough memory for extra record"); goto err; @@ -3782,7 +3783,7 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info, (uchar*) my_malloc((size_t) share->base.default_rec_buff_size, MYF(0))) || _ma_alloc_buffer(&sort_param.rec_buff, &sort_param.rec_buff_size, - share->base.default_rec_buff_size)) + share->base.default_rec_buff_size, MYF(0))) { _ma_check_print_error(param, "Not enough memory for extra record"); goto err; @@ -4425,7 +4426,7 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info, sort_param[i].record= (((uchar *)(sort_param+share->base.keys))+ (share->base.pack_reclength * i)); if (_ma_alloc_buffer(&sort_param[i].rec_buff, &sort_param[i].rec_buff_size, - share->base.default_rec_buff_size)) + share->base.default_rec_buff_size, MYF(0))) { _ma_check_print_error(param,"Not enough memory!"); goto err; @@ -5155,7 +5156,7 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param) if (_ma_alloc_buffer(&sort_param->rec_buff, &sort_param->rec_buff_size, block_info.rec_len + - share->base.extra_rec_buff_size)) + share->base.extra_rec_buff_size, MYF(0))) { if (param->max_record_length >= block_info.rec_len) diff --git a/storage/maria/ma_create.c b/storage/maria/ma_create.c index ba147f08b45..85e158a9fd6 100644 --- a/storage/maria/ma_create.c +++ b/storage/maria/ma_create.c @@ -64,10 +64,10 @@ int maria_create(const char *name, enum data_file_type datafile_type, uint uniques, MARIA_UNIQUEDEF *uniquedefs, MARIA_CREATE_INFO *ci,uint flags) { - register uint i,j; + uint i,j; File UNINIT_VAR(dfile), UNINIT_VAR(file); int errpos,save_errno, create_mode= O_RDWR | O_TRUNC, res; - myf create_flag; + myf create_flag, common_flag= MY_WME, sync_dir= 0; uint length,max_key_length,packed,pack_bytes,pointer,real_length_diff, key_length,info_length,key_segs,options,min_key_length, base_pos,long_varchar_count, @@ -93,7 +93,6 @@ int maria_create(const char *name, enum data_file_type datafile_type, MARIA_CREATE_INFO tmp_create_info; my_bool tmp_table= FALSE; /* cache for presence of HA_OPTION_TMP_TABLE */ my_bool forced_packed; - myf sync_dir= 0; uchar *log_data= NULL; my_bool encrypted= maria_encrypt_tables && datafile_type == BLOCK_RECORD; my_bool insert_order= MY_TEST(flags & HA_PRESERVE_INSERT_ORDER); @@ -104,6 +103,9 @@ int maria_create(const char *name, enum data_file_type datafile_type, DBUG_ASSERT(maria_inited); + if (flags & HA_CREATE_TMP_TABLE) + common_flag|= MY_THREAD_SPECIFIC; + if (!ci) { bzero((char*) &tmp_create_info,sizeof(tmp_create_info)); @@ -148,7 +150,7 @@ int maria_create(const char *name, enum data_file_type datafile_type, (double*) my_malloc((keys + uniques)*HA_MAX_KEY_SEG*sizeof(double) + (keys + uniques)*HA_MAX_KEY_SEG*sizeof(ulong) + sizeof(uint16) * columns, - MYF(MY_WME | MY_ZEROFILL)))) + MYF(common_flag | MY_ZEROFILL)))) DBUG_RETURN(my_errno); nulls_per_key_part= (ulong*) (rec_per_key_part + (keys + uniques) * HA_MAX_KEY_SEG); @@ -924,7 +926,7 @@ int maria_create(const char *name, enum data_file_type datafile_type, if ((file= mysql_file_create_with_symlink(key_file_kfile, klinkname_ptr, kfilename, 0, create_mode, - MYF(MY_WME|create_flag))) < 0) + MYF(common_flag|create_flag))) < 0) goto err; errpos=1; @@ -1027,7 +1029,7 @@ int maria_create(const char *name, enum data_file_type datafile_type, MARIA_COLUMNDEF **col_order, **pos; if (!(col_order= (MARIA_COLUMNDEF**) my_malloc(share.base.fields * sizeof(MARIA_COLUMNDEF*), - MYF(MY_WME)))) + common_flag))) goto err; for (column= columndef, pos= col_order ; column != end_column ; @@ -1206,8 +1208,8 @@ int maria_create(const char *name, enum data_file_type datafile_type, } if ((dfile= mysql_file_create_with_symlink(key_file_dfile, dlinkname_ptr, - dfilename, 0, create_mode, - MYF(MY_WME | create_flag | sync_dir))) < 0) + dfilename, 0, create_mode, + MYF(common_flag | create_flag | sync_dir))) < 0) goto err; errpos=3; diff --git a/storage/maria/ma_dynrec.c b/storage/maria/ma_dynrec.c index ae6fc57c114..829e5b5cd02 100644 --- a/storage/maria/ma_dynrec.c +++ b/storage/maria/ma_dynrec.c @@ -1477,6 +1477,8 @@ int _ma_read_dynamic_record(MARIA_HA *info, uchar *buf, File file; uchar *UNINIT_VAR(to); uint UNINIT_VAR(left_length); + MARIA_SHARE *share= info->s; + myf flag= MY_WME | (share->temporary ? MY_THREAD_SPECIFIC : 0); DBUG_ENTER("_ma_read_dynamic_record"); if (filepos == HA_OFFSET_ERROR) @@ -1507,13 +1509,13 @@ int _ma_read_dynamic_record(MARIA_HA *info, uchar *buf, if (block_of_record++ == 0) /* First block */ { info->cur_row.total_length= block_info.rec_len; - if (block_info.rec_len > (uint) info->s->base.max_pack_length) + if (block_info.rec_len > (uint) share->base.max_pack_length) goto panic; - if (info->s->base.blobs) + if (share->base.blobs) { if (_ma_alloc_buffer(&info->rec_buff, &info->rec_buff_size, block_info.rec_len + - info->s->base.extra_rec_buff_size)) + share->base.extra_rec_buff_size, flag)) goto err; } to= info->rec_buff; @@ -1549,7 +1551,7 @@ int _ma_read_dynamic_record(MARIA_HA *info, uchar *buf, there is no equivalent without seeking. We are at the right position already. :( */ - if (info->s->file_read(info, to, block_info.data_len, + if (share->file_read(info, to, block_info.data_len, filepos, MYF(MY_NABP))) goto panic; left_length-=block_info.data_len; @@ -1769,6 +1771,7 @@ int _ma_read_rnd_dynamic_record(MARIA_HA *info, uchar *UNINIT_VAR(to); MARIA_BLOCK_INFO block_info; MARIA_SHARE *share= info->s; + myf flag= MY_WME | (share->temporary ? MY_THREAD_SPECIFIC : 0); DBUG_ENTER("_ma_read_rnd_dynamic_record"); #ifdef MARIA_EXTERNAL_LOCKING @@ -1859,7 +1862,7 @@ int _ma_read_rnd_dynamic_record(MARIA_HA *info, { if (_ma_alloc_buffer(&info->rec_buff, &info->rec_buff_size, block_info.rec_len + - info->s->base.extra_rec_buff_size)) + share->base.extra_rec_buff_size, flag)) goto err; } to= info->rec_buff; diff --git a/storage/maria/ma_extra.c b/storage/maria/ma_extra.c index b464cf4f94e..2573133ece5 100644 --- a/storage/maria/ma_extra.c +++ b/storage/maria/ma_extra.c @@ -533,6 +533,7 @@ int maria_reset(MARIA_HA *info) { int error= 0; MARIA_SHARE *share= info->s; + myf flag= MY_WME | (share->temporary ? MY_THREAD_SPECIFIC : 0); DBUG_ENTER("maria_reset"); /* Free buffers and reset the following flags: @@ -553,13 +554,13 @@ int maria_reset(MARIA_HA *info) { info->rec_buff_size= 1; /* Force realloc */ _ma_alloc_buffer(&info->rec_buff, &info->rec_buff_size, - share->base.default_rec_buff_size); + share->base.default_rec_buff_size, flag); } if (info->blob_buff_size > MARIA_SMALL_BLOB_BUFFER) { info->blob_buff_size= 1; /* Force realloc */ _ma_alloc_buffer(&info->blob_buff, &info->blob_buff_size, - MARIA_SMALL_BLOB_BUFFER); + MARIA_SMALL_BLOB_BUFFER, flag); } } #if defined(HAVE_MMAP) && defined(HAVE_MADVISE) diff --git a/storage/maria/ma_open.c b/storage/maria/ma_open.c index 89848fae03e..06183c72895 100644 --- a/storage/maria/ma_open.c +++ b/storage/maria/ma_open.c @@ -39,7 +39,7 @@ static void maria_scan_end_dummy(MARIA_HA *info); static my_bool maria_once_init_dummy(MARIA_SHARE *, File); static my_bool maria_once_end_dummy(MARIA_SHARE *); static uchar *_ma_base_info_read(uchar *ptr, MARIA_BASE_INFO *base); -static uchar *_ma_state_info_read(uchar *ptr, MARIA_STATE_INFO *state); +static uchar *_ma_state_info_read(uchar *, MARIA_STATE_INFO *, myf); #define get_next_element(to,pos,size) { memcpy((char*) to,pos,(size_t) size); \ pos+=size;} @@ -98,6 +98,7 @@ static MARIA_HA *maria_clone_internal(MARIA_SHARE *share, uint errpos; MARIA_HA info,*m_info; my_bitmap_map *changed_fields_bitmap; + myf flag= MY_WME | (share->temporary ? MY_THREAD_SPECIFIC : 0); DBUG_ENTER("maria_clone_internal"); errpos= 0; @@ -115,7 +116,7 @@ static MARIA_HA *maria_clone_internal(MARIA_SHARE *share, errpos= 5; /* alloc and set up private structure parts */ - if (!my_multi_malloc(MY_WME, + if (!my_multi_malloc(flag, &m_info,sizeof(MARIA_HA), &info.blobs,sizeof(MARIA_BLOB)*share->base.blobs, &info.buff,(share->base.max_key_block_length*2+ @@ -163,10 +164,9 @@ static MARIA_HA *maria_clone_internal(MARIA_SHARE *share, goto err; /* The following should be big enough for all pinning purposes */ - if (my_init_dynamic_array(&info.pinned_pages, - sizeof(MARIA_PINNED_PAGE), + if (my_init_dynamic_array(&info.pinned_pages, sizeof(MARIA_PINNED_PAGE), MY_MAX(share->base.blobs*2 + 4, - MARIA_MAX_TREE_LEVELS*3), 16, MYF(0))) + MARIA_MAX_TREE_LEVELS*3), 16, flag)) goto err; @@ -202,7 +202,7 @@ static MARIA_HA *maria_clone_internal(MARIA_SHARE *share, /* Allocate buffer for one record */ /* prerequisites: info->rec_buffer == 0 && info->rec_buff_size == 0 */ if (_ma_alloc_buffer(&info.rec_buff, &info.rec_buff_size, - share->base.default_rec_buff_size)) + share->base.default_rec_buff_size, flag)) goto err; bzero(info.rec_buff, share->base.default_rec_buff_size); @@ -265,6 +265,7 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags) uint i,j,len,errpos,head_length,base_pos,keys, realpath_err, key_parts,base_key_parts,unique_key_parts,fulltext_keys,uniques; uint internal_table= MY_TEST(open_flags & HA_OPEN_INTERNAL_TABLE); + myf common_flag= open_flags & HA_OPEN_TMP_TABLE ? MY_THREAD_SPECIFIC : 0; uint file_version; size_t info_length; char name_buff[FN_REFLEN], org_name[FN_REFLEN], index_name[FN_REFLEN], @@ -322,13 +323,13 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags) DEBUG_SYNC_C("mi_open_kfile"); if ((kfile=mysql_file_open(key_file_kfile, name_buff, (open_mode=O_RDWR) | O_SHARE | O_NOFOLLOW | O_CLOEXEC, - MYF(MY_NOSYMLINKS))) < 0) + MYF(common_flag | MY_NOSYMLINKS))) < 0) { if ((errno != EROFS && errno != EACCES) || mode != O_RDONLY || (kfile=mysql_file_open(key_file_kfile, name_buff, (open_mode=O_RDONLY) | O_SHARE | O_NOFOLLOW | O_CLOEXEC, - MYF(MY_NOSYMLINKS))) < 0) + MYF(common_flag | MY_NOSYMLINKS))) < 0) goto err; } share->mode=open_mode; @@ -393,7 +394,7 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags) Allocate space for header information and for data that is too big to keep on stack */ - if (!(disk_cache= my_malloc(info_length+128, MYF(MY_WME)))) + if (!(disk_cache= my_malloc(info_length+128, MYF(MY_WME | common_flag)))) { my_errno=ENOMEM; goto err; @@ -420,7 +421,7 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags) } share->state_diff_length=len-MARIA_STATE_INFO_SIZE; - if (!_ma_state_info_read(disk_cache, &share->state)) + if (!_ma_state_info_read(disk_cache, &share->state, common_flag)) goto err; len= mi_uint2korr(share->state.header.base_info_length); if (len != MARIA_BASE_INFO_SIZE) @@ -561,12 +562,10 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags) share->index_file_name.length= strlen(index_name); share->data_file_name.length= strlen(data_name); share->open_file_name.length= strlen(name); - if (!my_multi_malloc(MY_WME, + if (!my_multi_malloc(MYF(MY_WME | common_flag), &share,sizeof(*share), - &rec_per_key_part, - sizeof(double) * key_parts, - &nulls_per_key_part, - sizeof(long)* key_parts, + &rec_per_key_part, sizeof(double) * key_parts, + &nulls_per_key_part, sizeof(long)* key_parts, &share->keyinfo,keys*sizeof(MARIA_KEYDEF), &share->uniqueinfo,uniques*sizeof(MARIA_UNIQUEDEF), &share->keyparts, @@ -883,9 +882,9 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags) share->options|= HA_OPTION_READ_ONLY_DATA; share->is_log_table= FALSE; - if (open_flags & HA_OPEN_TMP_TABLE || - (share->options & HA_OPTION_TMP_TABLE)) + if (open_flags & HA_OPEN_TMP_TABLE || share->options & HA_OPTION_TMP_TABLE) { + common_flag|= MY_THREAD_SPECIFIC; share->options|= HA_OPTION_TMP_TABLE; share->temporary= share->delay_key_write= 1; share->write_flag=MYF(MY_NABP); @@ -1113,13 +1112,13 @@ err: */ my_bool _ma_alloc_buffer(uchar **old_addr, size_t *old_size, - size_t new_size) + size_t new_size, myf flag) { if (*old_size < new_size) { uchar *addr; if (!(addr= (uchar*) my_realloc(*old_addr, new_size, - MYF(MY_ALLOW_ZERO_PTR)))) + MYF(MY_ALLOW_ZERO_PTR | flag)))) return 1; *old_addr= addr; *old_size= new_size; @@ -1498,7 +1497,7 @@ uint _ma_state_info_write_sub(File file, MARIA_STATE_INFO *state, uint pWrite) } -static uchar *_ma_state_info_read(uchar *ptr, MARIA_STATE_INFO *state) +static uchar *_ma_state_info_read(uchar *ptr, MARIA_STATE_INFO *state, myf flag) { uint i,keys,key_parts; DBUG_ENTER("_ma_state_info_read"); @@ -1510,7 +1509,7 @@ static uchar *_ma_state_info_read(uchar *ptr, MARIA_STATE_INFO *state) /* Allocate memory for key parts if not already done */ if (!state->rec_per_key_part && - !my_multi_malloc(MY_WME, + !my_multi_malloc(MYF(MY_WME | flag), &state->rec_per_key_part, sizeof(*state->rec_per_key_part) * key_parts, &state->nulls_per_key_part, @@ -1955,6 +1954,8 @@ void _ma_set_index_pagecache_callbacks(PAGECACHE_FILE *file, int _ma_open_datafile(MARIA_HA *info, MARIA_SHARE *share) { myf flags= MY_WME | (share->mode & O_NOFOLLOW ? MY_NOSYMLINKS : 0); + if (share->temporary) + flags|= MY_THREAD_SPECIFIC; DEBUG_SYNC_C("mi_open_datafile"); info->dfile.file= share->bitmap.file.file= mysql_file_open(key_file_dfile, share->data_file_name.str, diff --git a/storage/maria/ma_packrec.c b/storage/maria/ma_packrec.c index e42e9300d14..d1c30a57146 100644 --- a/storage/maria/ma_packrec.c +++ b/storage/maria/ma_packrec.c @@ -1413,10 +1413,12 @@ uint _ma_pack_get_block_info(MARIA_HA *maria, MARIA_BIT_BUFF *bit_buff, { uchar *header= info->header; uint head_length,UNINIT_VAR(ref_length); + MARIA_SHARE *share= maria->s; + myf flag= MY_WME | (share->temporary ? MY_THREAD_SPECIFIC : 0); if (file >= 0) { - ref_length=maria->s->pack.ref_length; + ref_length=share->pack.ref_length; /* We can't use my_pread() here because _ma_read_rnd_pack_record assumes position is ok @@ -1426,11 +1428,11 @@ uint _ma_pack_get_block_info(MARIA_HA *maria, MARIA_BIT_BUFF *bit_buff, return BLOCK_FATAL_ERROR; DBUG_DUMP("header", header, ref_length); } - head_length= read_pack_length((uint) maria->s->pack.version, header, + head_length= read_pack_length((uint) share->pack.version, header, &info->rec_len); - if (maria->s->base.blobs) + if (share->base.blobs) { - head_length+= read_pack_length((uint) maria->s->pack.version, + head_length+= read_pack_length((uint) share->pack.version, header + head_length, &info->blob_len); /* Ensure that the record buffer is big enough for the compressed @@ -1439,7 +1441,7 @@ uint _ma_pack_get_block_info(MARIA_HA *maria, MARIA_BIT_BUFF *bit_buff, */ if (_ma_alloc_buffer(rec_buff_p, rec_buff_size_p, info->rec_len + info->blob_len + - maria->s->base.extra_rec_buff_size)) + share->base.extra_rec_buff_size, flag)) return BLOCK_FATAL_ERROR; /* not enough memory */ bit_buff->blob_pos= *rec_buff_p + info->rec_len; bit_buff->blob_end= bit_buff->blob_pos + info->blob_len; @@ -1580,15 +1582,18 @@ _ma_mempack_get_block_info(MARIA_HA *maria, size_t *rec_buff_size_p, uchar *header) { - header+= read_pack_length((uint) maria->s->pack.version, header, + MARIA_SHARE *share= maria->s; + myf flag= MY_WME | (share->temporary ? MY_THREAD_SPECIFIC : 0); + + header+= read_pack_length((uint) share->pack.version, header, &info->rec_len); - if (maria->s->base.blobs) + if (share->base.blobs) { - header+= read_pack_length((uint) maria->s->pack.version, header, + header+= read_pack_length((uint) share->pack.version, header, &info->blob_len); /* _ma_alloc_rec_buff sets my_errno on error */ if (_ma_alloc_buffer(rec_buff_p, rec_buff_size_p, - info->blob_len + maria->s->base.extra_rec_buff_size)) + info->blob_len + share->base.extra_rec_buff_size, flag)) return 0; /* not enough memory */ bit_buff->blob_pos= *rec_buff_p; bit_buff->blob_end= *rec_buff_p + info->blob_len; diff --git a/storage/maria/maria_def.h b/storage/maria/maria_def.h index c89623daea9..6c9649ede45 100644 --- a/storage/maria/maria_def.h +++ b/storage/maria/maria_def.h @@ -1198,7 +1198,7 @@ extern my_bool _ma_read_cache(MARIA_HA *, IO_CACHE *info, uchar *buff, uint re_read_if_possibly); extern ulonglong ma_retrieve_auto_increment(const uchar *key, uint8 key_type); extern my_bool _ma_alloc_buffer(uchar **old_addr, size_t *old_size, - size_t new_size); + size_t new_size, myf flag); extern size_t _ma_rec_unpack(MARIA_HA *info, uchar *to, uchar *from, size_t reclength); extern my_bool _ma_rec_check(MARIA_HA *info, const uchar *record, From 01a0d739c8f9dca99301e550ab36c032ca8c6c0e Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 7 Mar 2021 01:53:52 +0100 Subject: [PATCH 06/26] MDEV-24975 Server consumes extra 4G memory upon querying INFORMATION_SCHEMA.OPTIIMIZER_TRACE if a query used no fields from an I_S table, we were creating a temp table with one, first, field (as a table cannot have zero fields), with its length truncated to 1. Now - force also this dummy field to be a normal field, not a BLOB --- mysql-test/main/opt_trace.result | 9 +++++++++ mysql-test/main/opt_trace.test | 13 +++++++++++++ sql/sql_show.cc | 1 + 3 files changed, 23 insertions(+) diff --git a/mysql-test/main/opt_trace.result b/mysql-test/main/opt_trace.result index ee1273decf6..0ced5f19e14 100644 --- a/mysql-test/main/opt_trace.result +++ b/mysql-test/main/opt_trace.result @@ -8591,4 +8591,13 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.range_scan_alternatives')) ] DROP TABLE t1; set optimizer_trace='enabled=off'; +# +# MDEV-24975 Server consumes extra 4G memory upon querying INFORMATION_SCHEMA.OPTIIMIZER_TRACE +# +set max_session_mem_used=1024*1024*1024; +select count(*) from information_schema.optimizer_trace; +select * from information_schema.optimizer_trace; +set max_session_mem_used=default; +# # End of 10.4 tests +# diff --git a/mysql-test/main/opt_trace.test b/mysql-test/main/opt_trace.test index 9040b5a54d0..3fae7f34750 100644 --- a/mysql-test/main/opt_trace.test +++ b/mysql-test/main/opt_trace.test @@ -623,4 +623,17 @@ SELECT JSON_DETAILED(JSON_EXTRACT(trace, '$**.range_scan_alternatives')) from IN DROP TABLE t1; set optimizer_trace='enabled=off'; + +--echo # +--echo # MDEV-24975 Server consumes extra 4G memory upon querying INFORMATION_SCHEMA.OPTIIMIZER_TRACE +--echo # +set max_session_mem_used=1024*1024*1024; +--disable_result_log +select count(*) from information_schema.optimizer_trace; +select * from information_schema.optimizer_trace; +--enable_result_log +set max_session_mem_used=default; + +--echo # --echo # End of 10.4 tests +--echo # diff --git a/sql/sql_show.cc b/sql/sql_show.cc index c6be14540f3..3f807bdc275 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -8767,6 +8767,7 @@ bool optimize_schema_tables_memory_usage(List &tables) { /* all fields were optimized away. Force a non-0-length row */ table->s->reclength= to_recinfo->length= 1; + to_recinfo->type= FIELD_NORMAL; to_recinfo++; } p->recinfo= to_recinfo; From 1d762ee8fe6b2e2b031cfaa95429408479f7eb67 Mon Sep 17 00:00:00 2001 From: Robert Bindar Date: Mon, 8 Mar 2021 17:51:33 +0200 Subject: [PATCH 07/26] MDEV-24363 (followup fix) mysql.user view should not be dropped if the DEFINER is custom. Revert changes to MDEV-23102 tests as they were designed to catch this corner case. The explanation for this corner case is that users historically used to tweak the mysql.user table and probably still do even though mysql.user is now a view. Thus, if the DEFINER of the view is not default, i.e. root@localhost or mariadb.sys@localhost, we should avoid dropping the view during upgrade process to not discard potential custom changes. --- mysql-test/main/upgrade_MDEV-23102-1.result | 51 +++++++++++++++++++- mysql-test/main/upgrade_MDEV-23102-1.test | 52 ++++++++++++++++++++- mysql-test/main/upgrade_MDEV-23102-2.result | 51 +++++++++++++++++++- mysql-test/main/upgrade_MDEV-23102-2.test | 52 ++++++++++++++++++++- scripts/mysql_system_tables_fix.sql | 2 +- 5 files changed, 201 insertions(+), 7 deletions(-) diff --git a/mysql-test/main/upgrade_MDEV-23102-1.result b/mysql-test/main/upgrade_MDEV-23102-1.result index 78993550901..8caa49180ee 100644 --- a/mysql-test/main/upgrade_MDEV-23102-1.result +++ b/mysql-test/main/upgrade_MDEV-23102-1.result @@ -16,7 +16,56 @@ use mysql; # make changed definition of gis procedures and user view create user superuser@localhost; grant all privileges on mysql.* to superuser@localhost; -create or replace definer=superuser@localhost sql security definer view user as select `mysql`.`global_priv`.`Host` AS `Host`,`mysql`.`global_priv`.`User` AS `User`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.plugin') in ('mysql_native_password','mysql_old_password'),ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.authentication_string'),''),'') AS `Password`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 1,'Y','N') AS `Select_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 2,'Y','N') AS `Insert_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 4,'Y','N') AS `Update_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 8,'Y','N') AS `Delete_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 16,'Y','N') AS `Create_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 32,'Y','N') AS `Drop_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 64,'Y','N') AS `Reload_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 128,'Y','N') AS `Shutdown_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 256,'Y','N') AS `Process_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 512,'Y','N') AS `File_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 1024,'Y','N') AS `Grant_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 2048,'Y','N') AS `References_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 4096,'Y','N') AS `Index_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 8192,'Y','N') AS `Alter_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 16384,'Y','N') AS `Show_db_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 32768,'Y','N') AS `Super_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 65536,'Y','N') AS `Create_tmp_table_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 131072,'Y','N') AS `Lock_tables_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 262144,'Y','N') AS `Execute_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 524288,'Y','N') AS `Repl_slave_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 1048576,'Y','N') AS `Repl_client_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 2097152,'Y','N') AS `Create_view_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 4194304,'Y','N') AS `Show_view_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 8388608,'Y','N') AS `Create_routine_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 16777216,'Y','N') AS `Alter_routine_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 33554432,'Y','N') AS `Create_user_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 67108864,'Y','N') AS `Event_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 134217728,'Y','N') AS `Trigger_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 268435456,'Y','N') AS `Create_tablespace_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 536870912,'Y','N') AS `Delete_history_priv`,elt(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.ssl_type'),0) + 1,'','ANY','X509','SPECIFIED') AS `ssl_type`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.ssl_cipher'),'') AS `ssl_cipher`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.x509_issuer'),'') AS `x509_issuer`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.x509_subject'),'') AS `x509_subject`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_questions'),0) as unsigned) AS `max_questions`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_updates'),0) as unsigned) AS `max_updates`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_connections'),0) as unsigned) AS `max_connections`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_user_connections'),0) as signed) AS `max_user_connections`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.plugin'),'') AS `plugin`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.authentication_string'),'') AS `authentication_string`,if(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.password_last_changed'),1) = 0,'Y','N') AS `password_expired`,elt(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.is_role'),0) + 1,'N','Y') AS `is_role`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.default_role'),'') AS `default_role`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_statement_time'),0.0) as decimal(12,6)) AS `max_statement_time` from `mysql`.`global_priv`;; +drop view user; +CREATE DEFINER='superuser'@'localhost' SQL SECURITY DEFINER VIEW IF NOT EXISTS user AS SELECT +Host, +User, +IF(JSON_VALUE(Priv, '$.plugin') IN ('mysql_native_password', 'mysql_old_password'), IFNULL(JSON_VALUE(Priv, '$.authentication_string'), ''), '') AS Password, +IF(JSON_VALUE(Priv, '$.access') & 1, 'Y', 'N') AS Select_priv, +IF(JSON_VALUE(Priv, '$.access') & 2, 'Y', 'N') AS Insert_priv, +IF(JSON_VALUE(Priv, '$.access') & 4, 'Y', 'N') AS Update_priv, +IF(JSON_VALUE(Priv, '$.access') & 8, 'Y', 'N') AS Delete_priv, +IF(JSON_VALUE(Priv, '$.access') & 16, 'Y', 'N') AS Create_priv, +IF(JSON_VALUE(Priv, '$.access') & 32, 'Y', 'N') AS Drop_priv, +IF(JSON_VALUE(Priv, '$.access') & 64, 'Y', 'N') AS Reload_priv, +IF(JSON_VALUE(Priv, '$.access') & 128, 'Y', 'N') AS Shutdown_priv, +IF(JSON_VALUE(Priv, '$.access') & 256, 'Y', 'N') AS Process_priv, +IF(JSON_VALUE(Priv, '$.access') & 512, 'Y', 'N') AS File_priv, +IF(JSON_VALUE(Priv, '$.access') & 1024, 'Y', 'N') AS Grant_priv, +IF(JSON_VALUE(Priv, '$.access') & 2048, 'Y', 'N') AS References_priv, +IF(JSON_VALUE(Priv, '$.access') & 4096, 'Y', 'N') AS Index_priv, +IF(JSON_VALUE(Priv, '$.access') & 8192, 'Y', 'N') AS Alter_priv, +IF(JSON_VALUE(Priv, '$.access') & 16384, 'Y', 'N') AS Show_db_priv, +IF(JSON_VALUE(Priv, '$.access') & 32768, 'Y', 'N') AS Super_priv, +IF(JSON_VALUE(Priv, '$.access') & 65536, 'Y', 'N') AS Create_tmp_table_priv, +IF(JSON_VALUE(Priv, '$.access') & 131072, 'Y', 'N') AS Lock_tables_priv, +IF(JSON_VALUE(Priv, '$.access') & 262144, 'Y', 'N') AS Execute_priv, +IF(JSON_VALUE(Priv, '$.access') & 524288, 'Y', 'N') AS Repl_slave_priv, +IF(JSON_VALUE(Priv, '$.access') & 1048576, 'Y', 'N') AS Repl_client_priv, +IF(JSON_VALUE(Priv, '$.access') & 2097152, 'Y', 'N') AS Create_view_priv, +IF(JSON_VALUE(Priv, '$.access') & 4194304, 'Y', 'N') AS Show_view_priv, +IF(JSON_VALUE(Priv, '$.access') & 8388608, 'Y', 'N') AS Create_routine_priv, +IF(JSON_VALUE(Priv, '$.access') & 16777216, 'Y', 'N') AS Alter_routine_priv, +IF(JSON_VALUE(Priv, '$.access') & 33554432, 'Y', 'N') AS Create_user_priv, +IF(JSON_VALUE(Priv, '$.access') & 67108864, 'Y', 'N') AS Event_priv, +IF(JSON_VALUE(Priv, '$.access') & 134217728, 'Y', 'N') AS Trigger_priv, +IF(JSON_VALUE(Priv, '$.access') & 268435456, 'Y', 'N') AS Create_tablespace_priv, +IF(JSON_VALUE(Priv, '$.access') & 536870912, 'Y', 'N') AS Delete_history_priv, +ELT(IFNULL(JSON_VALUE(Priv, '$.ssl_type'), 0) + 1, '', 'ANY','X509', 'SPECIFIED') AS ssl_type, +IFNULL(JSON_VALUE(Priv, '$.ssl_cipher'), '') AS ssl_cipher, +IFNULL(JSON_VALUE(Priv, '$.x509_issuer'), '') AS x509_issuer, +IFNULL(JSON_VALUE(Priv, '$.x509_subject'), '') AS x509_subject, +CAST(IFNULL(JSON_VALUE(Priv, '$.max_questions'), 0) AS UNSIGNED) AS max_questions, +CAST(IFNULL(JSON_VALUE(Priv, '$.max_updates'), 0) AS UNSIGNED) AS max_updates, +CAST(IFNULL(JSON_VALUE(Priv, '$.max_connections'), 0) AS UNSIGNED) AS max_connections, +CAST(IFNULL(JSON_VALUE(Priv, '$.max_user_connections'), 0) AS SIGNED) AS max_user_connections, +IFNULL(JSON_VALUE(Priv, '$.plugin'), '') AS plugin, +IFNULL(JSON_VALUE(Priv, '$.authentication_string'), '') AS authentication_string, +'N' AS password_expired, +ELT(IFNULL(JSON_VALUE(Priv, '$.is_role'), 0) + 1, 'N', 'Y') AS is_role, +IFNULL(JSON_VALUE(Priv, '$.default_role'), '') AS default_role, +CAST(IFNULL(JSON_VALUE(Priv, '$.max_statement_time'), 0.0) AS DECIMAL(12,6)) AS max_statement_time +FROM global_priv; SET sql_mode=''; DROP PROCEDURE IF EXISTS mysql.AddGeometryColumn; DROP PROCEDURE IF EXISTS mysql.DropGeometryColumn; diff --git a/mysql-test/main/upgrade_MDEV-23102-1.test b/mysql-test/main/upgrade_MDEV-23102-1.test index d764a6ca84a..172e0d595b2 100644 --- a/mysql-test/main/upgrade_MDEV-23102-1.test +++ b/mysql-test/main/upgrade_MDEV-23102-1.test @@ -23,9 +23,57 @@ use mysql; create user superuser@localhost; grant all privileges on mysql.* to superuser@localhost; -let $viewdef = `select view_definition from information_schema.views where table_name='user' and table_schema='mysql'`; +drop view user; ---eval create or replace definer=superuser@localhost sql security definer view user as $viewdef; +CREATE DEFINER='superuser'@'localhost' SQL SECURITY DEFINER VIEW IF NOT EXISTS user AS SELECT + Host, + User, + IF(JSON_VALUE(Priv, '$.plugin') IN ('mysql_native_password', 'mysql_old_password'), IFNULL(JSON_VALUE(Priv, '$.authentication_string'), ''), '') AS Password, + IF(JSON_VALUE(Priv, '$.access') & 1, 'Y', 'N') AS Select_priv, + IF(JSON_VALUE(Priv, '$.access') & 2, 'Y', 'N') AS Insert_priv, + IF(JSON_VALUE(Priv, '$.access') & 4, 'Y', 'N') AS Update_priv, + IF(JSON_VALUE(Priv, '$.access') & 8, 'Y', 'N') AS Delete_priv, + IF(JSON_VALUE(Priv, '$.access') & 16, 'Y', 'N') AS Create_priv, + IF(JSON_VALUE(Priv, '$.access') & 32, 'Y', 'N') AS Drop_priv, + IF(JSON_VALUE(Priv, '$.access') & 64, 'Y', 'N') AS Reload_priv, + IF(JSON_VALUE(Priv, '$.access') & 128, 'Y', 'N') AS Shutdown_priv, + IF(JSON_VALUE(Priv, '$.access') & 256, 'Y', 'N') AS Process_priv, + IF(JSON_VALUE(Priv, '$.access') & 512, 'Y', 'N') AS File_priv, + IF(JSON_VALUE(Priv, '$.access') & 1024, 'Y', 'N') AS Grant_priv, + IF(JSON_VALUE(Priv, '$.access') & 2048, 'Y', 'N') AS References_priv, + IF(JSON_VALUE(Priv, '$.access') & 4096, 'Y', 'N') AS Index_priv, + IF(JSON_VALUE(Priv, '$.access') & 8192, 'Y', 'N') AS Alter_priv, + IF(JSON_VALUE(Priv, '$.access') & 16384, 'Y', 'N') AS Show_db_priv, + IF(JSON_VALUE(Priv, '$.access') & 32768, 'Y', 'N') AS Super_priv, + IF(JSON_VALUE(Priv, '$.access') & 65536, 'Y', 'N') AS Create_tmp_table_priv, + IF(JSON_VALUE(Priv, '$.access') & 131072, 'Y', 'N') AS Lock_tables_priv, + IF(JSON_VALUE(Priv, '$.access') & 262144, 'Y', 'N') AS Execute_priv, + IF(JSON_VALUE(Priv, '$.access') & 524288, 'Y', 'N') AS Repl_slave_priv, + IF(JSON_VALUE(Priv, '$.access') & 1048576, 'Y', 'N') AS Repl_client_priv, + IF(JSON_VALUE(Priv, '$.access') & 2097152, 'Y', 'N') AS Create_view_priv, + IF(JSON_VALUE(Priv, '$.access') & 4194304, 'Y', 'N') AS Show_view_priv, + IF(JSON_VALUE(Priv, '$.access') & 8388608, 'Y', 'N') AS Create_routine_priv, + IF(JSON_VALUE(Priv, '$.access') & 16777216, 'Y', 'N') AS Alter_routine_priv, + IF(JSON_VALUE(Priv, '$.access') & 33554432, 'Y', 'N') AS Create_user_priv, + IF(JSON_VALUE(Priv, '$.access') & 67108864, 'Y', 'N') AS Event_priv, + IF(JSON_VALUE(Priv, '$.access') & 134217728, 'Y', 'N') AS Trigger_priv, + IF(JSON_VALUE(Priv, '$.access') & 268435456, 'Y', 'N') AS Create_tablespace_priv, + IF(JSON_VALUE(Priv, '$.access') & 536870912, 'Y', 'N') AS Delete_history_priv, + ELT(IFNULL(JSON_VALUE(Priv, '$.ssl_type'), 0) + 1, '', 'ANY','X509', 'SPECIFIED') AS ssl_type, + IFNULL(JSON_VALUE(Priv, '$.ssl_cipher'), '') AS ssl_cipher, + IFNULL(JSON_VALUE(Priv, '$.x509_issuer'), '') AS x509_issuer, + IFNULL(JSON_VALUE(Priv, '$.x509_subject'), '') AS x509_subject, + CAST(IFNULL(JSON_VALUE(Priv, '$.max_questions'), 0) AS UNSIGNED) AS max_questions, + CAST(IFNULL(JSON_VALUE(Priv, '$.max_updates'), 0) AS UNSIGNED) AS max_updates, + CAST(IFNULL(JSON_VALUE(Priv, '$.max_connections'), 0) AS UNSIGNED) AS max_connections, + CAST(IFNULL(JSON_VALUE(Priv, '$.max_user_connections'), 0) AS SIGNED) AS max_user_connections, + IFNULL(JSON_VALUE(Priv, '$.plugin'), '') AS plugin, + IFNULL(JSON_VALUE(Priv, '$.authentication_string'), '') AS authentication_string, + 'N' AS password_expired, + ELT(IFNULL(JSON_VALUE(Priv, '$.is_role'), 0) + 1, 'N', 'Y') AS is_role, + IFNULL(JSON_VALUE(Priv, '$.default_role'), '') AS default_role, + CAST(IFNULL(JSON_VALUE(Priv, '$.max_statement_time'), 0.0) AS DECIMAL(12,6)) AS max_statement_time + FROM global_priv; SET sql_mode=''; diff --git a/mysql-test/main/upgrade_MDEV-23102-2.result b/mysql-test/main/upgrade_MDEV-23102-2.result index c7f373dd69d..4702fae812f 100644 --- a/mysql-test/main/upgrade_MDEV-23102-2.result +++ b/mysql-test/main/upgrade_MDEV-23102-2.result @@ -16,7 +16,56 @@ use mysql; # make changed definition of gis procedures and user view create user superuser@localhost; grant all privileges on mysql.* to superuser@localhost; -create or replace definer=superuser@localhost sql security definer view user as select `mysql`.`global_priv`.`Host` AS `Host`,`mysql`.`global_priv`.`User` AS `User`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.plugin') in ('mysql_native_password','mysql_old_password'),ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.authentication_string'),''),'') AS `Password`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 1,'Y','N') AS `Select_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 2,'Y','N') AS `Insert_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 4,'Y','N') AS `Update_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 8,'Y','N') AS `Delete_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 16,'Y','N') AS `Create_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 32,'Y','N') AS `Drop_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 64,'Y','N') AS `Reload_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 128,'Y','N') AS `Shutdown_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 256,'Y','N') AS `Process_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 512,'Y','N') AS `File_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 1024,'Y','N') AS `Grant_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 2048,'Y','N') AS `References_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 4096,'Y','N') AS `Index_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 8192,'Y','N') AS `Alter_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 16384,'Y','N') AS `Show_db_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 32768,'Y','N') AS `Super_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 65536,'Y','N') AS `Create_tmp_table_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 131072,'Y','N') AS `Lock_tables_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 262144,'Y','N') AS `Execute_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 524288,'Y','N') AS `Repl_slave_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 1048576,'Y','N') AS `Repl_client_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 2097152,'Y','N') AS `Create_view_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 4194304,'Y','N') AS `Show_view_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 8388608,'Y','N') AS `Create_routine_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 16777216,'Y','N') AS `Alter_routine_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 33554432,'Y','N') AS `Create_user_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 67108864,'Y','N') AS `Event_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 134217728,'Y','N') AS `Trigger_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 268435456,'Y','N') AS `Create_tablespace_priv`,if(json_value(`mysql`.`global_priv`.`Priv`,'$.access') & 536870912,'Y','N') AS `Delete_history_priv`,elt(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.ssl_type'),0) + 1,'','ANY','X509','SPECIFIED') AS `ssl_type`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.ssl_cipher'),'') AS `ssl_cipher`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.x509_issuer'),'') AS `x509_issuer`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.x509_subject'),'') AS `x509_subject`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_questions'),0) as unsigned) AS `max_questions`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_updates'),0) as unsigned) AS `max_updates`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_connections'),0) as unsigned) AS `max_connections`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_user_connections'),0) as signed) AS `max_user_connections`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.plugin'),'') AS `plugin`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.authentication_string'),'') AS `authentication_string`,if(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.password_last_changed'),1) = 0,'Y','N') AS `password_expired`,elt(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.is_role'),0) + 1,'N','Y') AS `is_role`,ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.default_role'),'') AS `default_role`,cast(ifnull(json_value(`mysql`.`global_priv`.`Priv`,'$.max_statement_time'),0.0) as decimal(12,6)) AS `max_statement_time` from `mysql`.`global_priv`;; +drop view user; +CREATE DEFINER='superuser'@'localhost' SQL SECURITY DEFINER VIEW IF NOT EXISTS user AS SELECT +Host, +User, +IF(JSON_VALUE(Priv, '$.plugin') IN ('mysql_native_password', 'mysql_old_password'), IFNULL(JSON_VALUE(Priv, '$.authentication_string'), ''), '') AS Password, +IF(JSON_VALUE(Priv, '$.access') & 1, 'Y', 'N') AS Select_priv, +IF(JSON_VALUE(Priv, '$.access') & 2, 'Y', 'N') AS Insert_priv, +IF(JSON_VALUE(Priv, '$.access') & 4, 'Y', 'N') AS Update_priv, +IF(JSON_VALUE(Priv, '$.access') & 8, 'Y', 'N') AS Delete_priv, +IF(JSON_VALUE(Priv, '$.access') & 16, 'Y', 'N') AS Create_priv, +IF(JSON_VALUE(Priv, '$.access') & 32, 'Y', 'N') AS Drop_priv, +IF(JSON_VALUE(Priv, '$.access') & 64, 'Y', 'N') AS Reload_priv, +IF(JSON_VALUE(Priv, '$.access') & 128, 'Y', 'N') AS Shutdown_priv, +IF(JSON_VALUE(Priv, '$.access') & 256, 'Y', 'N') AS Process_priv, +IF(JSON_VALUE(Priv, '$.access') & 512, 'Y', 'N') AS File_priv, +IF(JSON_VALUE(Priv, '$.access') & 1024, 'Y', 'N') AS Grant_priv, +IF(JSON_VALUE(Priv, '$.access') & 2048, 'Y', 'N') AS References_priv, +IF(JSON_VALUE(Priv, '$.access') & 4096, 'Y', 'N') AS Index_priv, +IF(JSON_VALUE(Priv, '$.access') & 8192, 'Y', 'N') AS Alter_priv, +IF(JSON_VALUE(Priv, '$.access') & 16384, 'Y', 'N') AS Show_db_priv, +IF(JSON_VALUE(Priv, '$.access') & 32768, 'Y', 'N') AS Super_priv, +IF(JSON_VALUE(Priv, '$.access') & 65536, 'Y', 'N') AS Create_tmp_table_priv, +IF(JSON_VALUE(Priv, '$.access') & 131072, 'Y', 'N') AS Lock_tables_priv, +IF(JSON_VALUE(Priv, '$.access') & 262144, 'Y', 'N') AS Execute_priv, +IF(JSON_VALUE(Priv, '$.access') & 524288, 'Y', 'N') AS Repl_slave_priv, +IF(JSON_VALUE(Priv, '$.access') & 1048576, 'Y', 'N') AS Repl_client_priv, +IF(JSON_VALUE(Priv, '$.access') & 2097152, 'Y', 'N') AS Create_view_priv, +IF(JSON_VALUE(Priv, '$.access') & 4194304, 'Y', 'N') AS Show_view_priv, +IF(JSON_VALUE(Priv, '$.access') & 8388608, 'Y', 'N') AS Create_routine_priv, +IF(JSON_VALUE(Priv, '$.access') & 16777216, 'Y', 'N') AS Alter_routine_priv, +IF(JSON_VALUE(Priv, '$.access') & 33554432, 'Y', 'N') AS Create_user_priv, +IF(JSON_VALUE(Priv, '$.access') & 67108864, 'Y', 'N') AS Event_priv, +IF(JSON_VALUE(Priv, '$.access') & 134217728, 'Y', 'N') AS Trigger_priv, +IF(JSON_VALUE(Priv, '$.access') & 268435456, 'Y', 'N') AS Create_tablespace_priv, +IF(JSON_VALUE(Priv, '$.access') & 536870912, 'Y', 'N') AS Delete_history_priv, +ELT(IFNULL(JSON_VALUE(Priv, '$.ssl_type'), 0) + 1, '', 'ANY','X509', 'SPECIFIED') AS ssl_type, +IFNULL(JSON_VALUE(Priv, '$.ssl_cipher'), '') AS ssl_cipher, +IFNULL(JSON_VALUE(Priv, '$.x509_issuer'), '') AS x509_issuer, +IFNULL(JSON_VALUE(Priv, '$.x509_subject'), '') AS x509_subject, +CAST(IFNULL(JSON_VALUE(Priv, '$.max_questions'), 0) AS UNSIGNED) AS max_questions, +CAST(IFNULL(JSON_VALUE(Priv, '$.max_updates'), 0) AS UNSIGNED) AS max_updates, +CAST(IFNULL(JSON_VALUE(Priv, '$.max_connections'), 0) AS UNSIGNED) AS max_connections, +CAST(IFNULL(JSON_VALUE(Priv, '$.max_user_connections'), 0) AS SIGNED) AS max_user_connections, +IFNULL(JSON_VALUE(Priv, '$.plugin'), '') AS plugin, +IFNULL(JSON_VALUE(Priv, '$.authentication_string'), '') AS authentication_string, +'N' AS password_expired, +ELT(IFNULL(JSON_VALUE(Priv, '$.is_role'), 0) + 1, 'N', 'Y') AS is_role, +IFNULL(JSON_VALUE(Priv, '$.default_role'), '') AS default_role, +CAST(IFNULL(JSON_VALUE(Priv, '$.max_statement_time'), 0.0) AS DECIMAL(12,6)) AS max_statement_time +FROM global_priv; DROP PROCEDURE IF EXISTS mysql.AddGeometryColumn; DROP PROCEDURE IF EXISTS mysql.DropGeometryColumn; drop user 'mariadb.sys'@'localhost'; diff --git a/mysql-test/main/upgrade_MDEV-23102-2.test b/mysql-test/main/upgrade_MDEV-23102-2.test index 27ee75ea58c..f2d7ac578e0 100644 --- a/mysql-test/main/upgrade_MDEV-23102-2.test +++ b/mysql-test/main/upgrade_MDEV-23102-2.test @@ -23,9 +23,57 @@ use mysql; create user superuser@localhost; grant all privileges on mysql.* to superuser@localhost; -let $viewdef = `select view_definition from information_schema.views where table_name='user' and table_schema='mysql'`; +drop view user; ---eval create or replace definer=superuser@localhost sql security definer view user as $viewdef; +CREATE DEFINER='superuser'@'localhost' SQL SECURITY DEFINER VIEW IF NOT EXISTS user AS SELECT + Host, + User, + IF(JSON_VALUE(Priv, '$.plugin') IN ('mysql_native_password', 'mysql_old_password'), IFNULL(JSON_VALUE(Priv, '$.authentication_string'), ''), '') AS Password, + IF(JSON_VALUE(Priv, '$.access') & 1, 'Y', 'N') AS Select_priv, + IF(JSON_VALUE(Priv, '$.access') & 2, 'Y', 'N') AS Insert_priv, + IF(JSON_VALUE(Priv, '$.access') & 4, 'Y', 'N') AS Update_priv, + IF(JSON_VALUE(Priv, '$.access') & 8, 'Y', 'N') AS Delete_priv, + IF(JSON_VALUE(Priv, '$.access') & 16, 'Y', 'N') AS Create_priv, + IF(JSON_VALUE(Priv, '$.access') & 32, 'Y', 'N') AS Drop_priv, + IF(JSON_VALUE(Priv, '$.access') & 64, 'Y', 'N') AS Reload_priv, + IF(JSON_VALUE(Priv, '$.access') & 128, 'Y', 'N') AS Shutdown_priv, + IF(JSON_VALUE(Priv, '$.access') & 256, 'Y', 'N') AS Process_priv, + IF(JSON_VALUE(Priv, '$.access') & 512, 'Y', 'N') AS File_priv, + IF(JSON_VALUE(Priv, '$.access') & 1024, 'Y', 'N') AS Grant_priv, + IF(JSON_VALUE(Priv, '$.access') & 2048, 'Y', 'N') AS References_priv, + IF(JSON_VALUE(Priv, '$.access') & 4096, 'Y', 'N') AS Index_priv, + IF(JSON_VALUE(Priv, '$.access') & 8192, 'Y', 'N') AS Alter_priv, + IF(JSON_VALUE(Priv, '$.access') & 16384, 'Y', 'N') AS Show_db_priv, + IF(JSON_VALUE(Priv, '$.access') & 32768, 'Y', 'N') AS Super_priv, + IF(JSON_VALUE(Priv, '$.access') & 65536, 'Y', 'N') AS Create_tmp_table_priv, + IF(JSON_VALUE(Priv, '$.access') & 131072, 'Y', 'N') AS Lock_tables_priv, + IF(JSON_VALUE(Priv, '$.access') & 262144, 'Y', 'N') AS Execute_priv, + IF(JSON_VALUE(Priv, '$.access') & 524288, 'Y', 'N') AS Repl_slave_priv, + IF(JSON_VALUE(Priv, '$.access') & 1048576, 'Y', 'N') AS Repl_client_priv, + IF(JSON_VALUE(Priv, '$.access') & 2097152, 'Y', 'N') AS Create_view_priv, + IF(JSON_VALUE(Priv, '$.access') & 4194304, 'Y', 'N') AS Show_view_priv, + IF(JSON_VALUE(Priv, '$.access') & 8388608, 'Y', 'N') AS Create_routine_priv, + IF(JSON_VALUE(Priv, '$.access') & 16777216, 'Y', 'N') AS Alter_routine_priv, + IF(JSON_VALUE(Priv, '$.access') & 33554432, 'Y', 'N') AS Create_user_priv, + IF(JSON_VALUE(Priv, '$.access') & 67108864, 'Y', 'N') AS Event_priv, + IF(JSON_VALUE(Priv, '$.access') & 134217728, 'Y', 'N') AS Trigger_priv, + IF(JSON_VALUE(Priv, '$.access') & 268435456, 'Y', 'N') AS Create_tablespace_priv, + IF(JSON_VALUE(Priv, '$.access') & 536870912, 'Y', 'N') AS Delete_history_priv, + ELT(IFNULL(JSON_VALUE(Priv, '$.ssl_type'), 0) + 1, '', 'ANY','X509', 'SPECIFIED') AS ssl_type, + IFNULL(JSON_VALUE(Priv, '$.ssl_cipher'), '') AS ssl_cipher, + IFNULL(JSON_VALUE(Priv, '$.x509_issuer'), '') AS x509_issuer, + IFNULL(JSON_VALUE(Priv, '$.x509_subject'), '') AS x509_subject, + CAST(IFNULL(JSON_VALUE(Priv, '$.max_questions'), 0) AS UNSIGNED) AS max_questions, + CAST(IFNULL(JSON_VALUE(Priv, '$.max_updates'), 0) AS UNSIGNED) AS max_updates, + CAST(IFNULL(JSON_VALUE(Priv, '$.max_connections'), 0) AS UNSIGNED) AS max_connections, + CAST(IFNULL(JSON_VALUE(Priv, '$.max_user_connections'), 0) AS SIGNED) AS max_user_connections, + IFNULL(JSON_VALUE(Priv, '$.plugin'), '') AS plugin, + IFNULL(JSON_VALUE(Priv, '$.authentication_string'), '') AS authentication_string, + 'N' AS password_expired, + ELT(IFNULL(JSON_VALUE(Priv, '$.is_role'), 0) + 1, 'N', 'Y') AS is_role, + IFNULL(JSON_VALUE(Priv, '$.default_role'), '') AS default_role, + CAST(IFNULL(JSON_VALUE(Priv, '$.max_statement_time'), 0.0) AS DECIMAL(12,6)) AS max_statement_time + FROM global_priv; DROP PROCEDURE IF EXISTS mysql.AddGeometryColumn; DROP PROCEDURE IF EXISTS mysql.DropGeometryColumn; diff --git a/scripts/mysql_system_tables_fix.sql b/scripts/mysql_system_tables_fix.sql index ac71edccae9..9dd775aaf30 100644 --- a/scripts/mysql_system_tables_fix.sql +++ b/scripts/mysql_system_tables_fix.sql @@ -824,7 +824,7 @@ IF 'BASE TABLE' = (select table_type from information_schema.tables where table_ DROP TABLE user; END IF// -IF 1 = (SELECT count(*) FROM information_schema.VIEWS WHERE TABLE_CATALOG = 'def' and TABLE_SCHEMA = 'mysql' and TABLE_NAME='user' and (DEFINER = 'root@localhost' or VIEW_DEFINITION LIKE "%'N' AS `password_expired`%")) THEN +IF 1 = (SELECT count(*) FROM information_schema.VIEWS WHERE TABLE_CATALOG = 'def' and TABLE_SCHEMA = 'mysql' and TABLE_NAME='user' and (DEFINER = 'root@localhost' or (DEFINER = 'mariadb.sys@localhost' and VIEW_DEFINITION LIKE "%'N' AS `password_expired`%"))) THEN DROP VIEW IF EXISTS mysql.user; END IF// From 449871458b49f224b27b26858784ef5408353f1b Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Mon, 8 Mar 2021 18:00:55 +0100 Subject: [PATCH 08/26] Fix Windows clang build with newest cmake --- cmake/pcre.cmake | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/cmake/pcre.cmake b/cmake/pcre.cmake index 1a5dece481a..214e1413ae2 100644 --- a/cmake/pcre.cmake +++ b/cmake/pcre.cmake @@ -14,8 +14,14 @@ MACRO(BUNDLE_PCRE2) IF(WIN32) # Debug libary name. # Same condition as in pcre2 CMakeLists.txt that adds "d" - SET(file ${dir}/src/pcre2-build/${CMAKE_CFG_INTDIR}/${CMAKE_STATIC_LIBRARY_PREFIX}${lib}${CMAKE_STATIC_LIBRARY_SUFFIX}) - SET(file_d ${dir}/src/pcre2-build/${CMAKE_CFG_INTDIR}/${CMAKE_STATIC_LIBRARY_PREFIX}${lib}d${CMAKE_STATIC_LIBRARY_SUFFIX}) + IF(GENERATOR_IS_MULTI_CONFIG) + SET(intdir "${CMAKE_CFG_INTDIR}/") + ELSE() + SET(intdir) + ENDIF() + + SET(file ${dir}/src/pcre2-build${intdir}${CMAKE_STATIC_LIBRARY_PREFIX}${lib}${CMAKE_STATIC_LIBRARY_SUFFIX}) + SET(file_d ${dir}/src/pcre2-build${intdir}${CMAKE_STATIC_LIBRARY_PREFIX}${lib}d${CMAKE_STATIC_LIBRARY_SUFFIX}) SET_TARGET_PROPERTIES(${lib} PROPERTIES IMPORTED_LOCATION_DEBUG ${file_d}) ELSE() SET(file ${dir}/src/pcre2-build/${CMAKE_STATIC_LIBRARY_PREFIX}${lib}${CMAKE_STATIC_LIBRARY_SUFFIX}) From 75f781f0d27d73dce4c7570e5b94b9482903c907 Mon Sep 17 00:00:00 2001 From: Nayuta Yanagisawa Date: Fri, 5 Mar 2021 17:51:17 +0000 Subject: [PATCH 09/26] MDEV-24868 Server crashes in optimize_schema_tables_memory_usage after select from information_schema.innodb_sys_columns optimize_schema_tables_memory_usage() crashed when its argument included TABLE struct that was not fully initialized. To prevent such a crash, we check if a table is an information schema table at the beginning of each iteration. Closes #1768 --- mysql-test/main/information_schema.result | 7 +++++++ mysql-test/main/information_schema.test | 8 ++++++++ sql/sql_show.cc | 11 ++++++++--- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/mysql-test/main/information_schema.result b/mysql-test/main/information_schema.result index c65a10cbd4b..28c1122ac03 100644 --- a/mysql-test/main/information_schema.result +++ b/mysql-test/main/information_schema.result @@ -2316,5 +2316,12 @@ count(*) 2 DROP TABLE t1; # +# MDEV-24868 Server crashes in optimize_schema_tables_memory_usage after select from information_schema.innodb_sys_columns +# +create table t1 ( name varchar(64) character set utf8, len int); +select * from t1 where (name, len) in (select name, len from information_schema.innodb_sys_columns having len = 8); +name len +drop table t1; +# # End of 10.3 tests # diff --git a/mysql-test/main/information_schema.test b/mysql-test/main/information_schema.test index 4468eb18e45..71e700f3f18 100644 --- a/mysql-test/main/information_schema.test +++ b/mysql-test/main/information_schema.test @@ -2044,6 +2044,14 @@ INSERT INTO t1 VALUES ('2012-12-12'),('2021-11-11'); SELECT count(*) FROM t1 AS t1a LEFT JOIN (t1 AS t1b JOIN INFORMATION_SCHEMA.ROUTINES) ON (t1b.a IS NULL); SELECT count(*) FROM t1 AS t1a LEFT JOIN (t1 AS t1b JOIN INFORMATION_SCHEMA.PROFILING) ON (t1b.a IS NULL); DROP TABLE t1; + +--echo # +--echo # MDEV-24868 Server crashes in optimize_schema_tables_memory_usage after select from information_schema.innodb_sys_columns +--echo # +create table t1 ( name varchar(64) character set utf8, len int); +select * from t1 where (name, len) in (select name, len from information_schema.innodb_sys_columns having len = 8); +drop table t1; + --echo # --echo # End of 10.3 tests --echo # diff --git a/sql/sql_show.cc b/sql/sql_show.cc index e6b5461e5af..469f28acf6c 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -8672,14 +8672,19 @@ end: bool optimize_schema_tables_memory_usage(List &tables) { + DBUG_ENTER("optimize_schema_tables_memory_usage"); + List_iterator tli(tables); while (TABLE_LIST *table_list= tli++) { + if (!table_list->schema_table) + continue; + TABLE *table= table_list->table; THD *thd=table->in_use; - if (!table_list->schema_table || !thd->fill_information_schema_tables()) + if (!thd->fill_information_schema_tables()) continue; if (!table->is_created()) @@ -8726,10 +8731,10 @@ bool optimize_schema_tables_memory_usage(List &tables) // TODO switch from Aria to Memory if all blobs were optimized away? if (instantiate_tmp_table(table, p->keyinfo, p->start_recinfo, &p->recinfo, table_list->select_lex->options | thd->variables.option_bits)) - return 1; + DBUG_RETURN(1); } } - return 0; + DBUG_RETURN(0); } From baddbaa0e328396d70d75c2c30e52fa3bd9e91b9 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Tue, 9 Mar 2021 11:44:29 +0100 Subject: [PATCH 10/26] fixup 449871458b49f224b27b26858784ef5408353f1b --- cmake/pcre.cmake | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/cmake/pcre.cmake b/cmake/pcre.cmake index 214e1413ae2..208f9ee755e 100644 --- a/cmake/pcre.cmake +++ b/cmake/pcre.cmake @@ -14,14 +14,15 @@ MACRO(BUNDLE_PCRE2) IF(WIN32) # Debug libary name. # Same condition as in pcre2 CMakeLists.txt that adds "d" - IF(GENERATOR_IS_MULTI_CONFIG) + GET_PROPERTY(MULTICONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) + IF(MULTICONFIG) SET(intdir "${CMAKE_CFG_INTDIR}/") ELSE() SET(intdir) ENDIF() - SET(file ${dir}/src/pcre2-build${intdir}${CMAKE_STATIC_LIBRARY_PREFIX}${lib}${CMAKE_STATIC_LIBRARY_SUFFIX}) - SET(file_d ${dir}/src/pcre2-build${intdir}${CMAKE_STATIC_LIBRARY_PREFIX}${lib}d${CMAKE_STATIC_LIBRARY_SUFFIX}) + SET(file ${dir}/src/pcre2-build/${intdir}${CMAKE_STATIC_LIBRARY_PREFIX}${lib}${CMAKE_STATIC_LIBRARY_SUFFIX}) + SET(file_d ${dir}/src/pcre2-build/${intdir}${CMAKE_STATIC_LIBRARY_PREFIX}${lib}d${CMAKE_STATIC_LIBRARY_SUFFIX}) SET_TARGET_PROPERTIES(${lib} PROPERTIES IMPORTED_LOCATION_DEBUG ${file_d}) ELSE() SET(file ${dir}/src/pcre2-build/${CMAKE_STATIC_LIBRARY_PREFIX}${lib}${CMAKE_STATIC_LIBRARY_SUFFIX}) From e3a597378ebfc69e044e5c0317a337bd46a593bf Mon Sep 17 00:00:00 2001 From: David CARLIER Date: Wed, 3 Feb 2021 19:44:34 +0000 Subject: [PATCH 11/26] mariabackup utility, binary path implementation for Mac. implements in a native way get_exepath which gives reliably the full path. --- extra/mariabackup/xtrabackup.cc | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc index 49a774ba576..f02520787e6 100644 --- a/extra/mariabackup/xtrabackup.cc +++ b/extra/mariabackup/xtrabackup.cc @@ -61,6 +61,10 @@ Street, Fifth Floor, Boston, MA 02110-1335 USA #include #endif +#ifdef __APPLE__ +# include "libproc.h" +#endif + #include #include @@ -6913,6 +6917,12 @@ static int get_exepath(char *buf, size_t size, const char *argv0) ssize_t ret = readlink("/proc/self/exe", buf, size-1); if(ret > 0) return 0; +#elif defined(__APPLE__) + size_t ret = proc_pidpath(getpid(), buf, static_cast(size)); + if (ret > 0) { + buf[ret] = 0; + return 0; + } #endif return my_realpath(buf, argv0, 0); From 1dff411e84d5c2ef672619a5b211210454798449 Mon Sep 17 00:00:00 2001 From: David CARLIER Date: Mon, 8 Mar 2021 18:54:58 +0000 Subject: [PATCH 12/26] arguments overflow fix proposal. the list is assumed to be implictly null terminated at usage time. --- extra/mariabackup/xtrabackup.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc index f02520787e6..9a2a544fd8f 100644 --- a/extra/mariabackup/xtrabackup.cc +++ b/extra/mariabackup/xtrabackup.cc @@ -6451,8 +6451,9 @@ void handle_options(int argc, char **argv, char ***argv_server, } } + mariabackup_args.push_back(nullptr); *argv_client= *argv_server= *argv_backup= &mariabackup_args[0]; - int argc_backup= static_cast(mariabackup_args.size()); + int argc_backup= static_cast(mariabackup_args.size() - 1); int argc_client= argc_backup; int argc_server= argc_backup; From 8f4a3bf07cc9d3f42899314411da344dabd66c5e Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Fri, 5 Mar 2021 13:35:29 +0530 Subject: [PATCH 13/26] MDEV-25057 Assertion `n_fields < dtuple_get_n_fields(entry)' failed in dtuple_convert_big_rec In dtuple_convert_big_rec(), InnoDB fails to consider the instant metadata blob while choosing the variable length field. --- mysql-test/suite/innodb/r/instant_alter.result | 13 +++++++++++++ mysql-test/suite/innodb/t/instant_alter.test | 14 ++++++++++++++ storage/innobase/data/data0data.cc | 2 +- 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/mysql-test/suite/innodb/r/instant_alter.result b/mysql-test/suite/innodb/r/instant_alter.result index e0661557159..b803d968836 100644 --- a/mysql-test/suite/innodb/r/instant_alter.result +++ b/mysql-test/suite/innodb/r/instant_alter.result @@ -2841,3 +2841,16 @@ t1 CREATE TABLE `t1` ( KEY `i1` (`a`) COMMENT 'comment2' ) ENGINE=InnoDB DEFAULT CHARSET=latin1 DROP TABLE t1; +# +# MDEV-25057 Assertion `n_fields < dtuple_get_n_fields(entry)' +# failed in dtuple_convert_big_rec +# +CREATE TABLE t1 (pk INT PRIMARY KEY AUTO_INCREMENT, +a CHAR(255) NOT NULL, +b CHAR(255) NOT NULL, c INT) ENGINE=InnoDB CHARSET utf32; +ALTER TABLE t1 DROP c; +INSERT INTO t1(a, b) SELECT '', '' FROM seq_1_to_16; +SELECT COUNT(*) FROM t1; +COUNT(*) +16 +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/instant_alter.test b/mysql-test/suite/innodb/t/instant_alter.test index 83dca4cb5a6..3d567cb0704 100644 --- a/mysql-test/suite/innodb/t/instant_alter.test +++ b/mysql-test/suite/innodb/t/instant_alter.test @@ -1,4 +1,5 @@ --source include/innodb_page_size.inc +--source include/have_sequence.inc --echo # --echo # MDEV-11369: Instant ADD COLUMN for InnoDB @@ -903,3 +904,16 @@ CREATE INDEX i1 ON t1(a) COMMENT 'comment1'; ALTER TABLE t1 DROP INDEX i1, ADD INDEX i1(a) COMMENT 'comment2', ALGORITHM=INSTANT; SHOW CREATE TABLE t1; DROP TABLE t1; + +--echo # +--echo # MDEV-25057 Assertion `n_fields < dtuple_get_n_fields(entry)' +--echo # failed in dtuple_convert_big_rec +--echo # +CREATE TABLE t1 (pk INT PRIMARY KEY AUTO_INCREMENT, + a CHAR(255) NOT NULL, + b CHAR(255) NOT NULL, c INT) ENGINE=InnoDB CHARSET utf32; +ALTER TABLE t1 DROP c; +INSERT INTO t1(a, b) SELECT '', '' FROM seq_1_to_16; +SELECT COUNT(*) FROM t1; +# Cleanup +DROP TABLE t1; diff --git a/storage/innobase/data/data0data.cc b/storage/innobase/data/data0data.cc index 36fc484b82f..fe849d8ae29 100644 --- a/storage/innobase/data/data0data.cc +++ b/storage/innobase/data/data0data.cc @@ -686,7 +686,7 @@ dtuple_convert_big_rec( goto skip_field; } - longest_i = i; + longest_i = i + mblob; longest = savings; skip_field: From bba6c3863053318f8b417e0f44042039b03226c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Otto=20Kek=C3=A4l=C3=A4inen?= Date: Tue, 9 Mar 2021 11:27:47 +0200 Subject: [PATCH 14/26] Deb: Sync downstream changes upstream - Reduce Build-Depends https://salsa.debian.org/mariadb-team/mariadb-10.5/-/commit/150bf990c6059a2fca95ea9bc4d108c9789b179d Dependencies chrpath, dh-apparmor and libarchive-dev are not needed. Fixes buildbot sid failures that error on: Unmet build dependencies: chrpath dh-apparmor libarchive-dev - Salsa-CI: Remove mysql-5.7 upgrade in Sid test as package was removed https://salsa.debian.org/mariadb-team/mariadb-10.5/-/commit/6f55ac620ce26046475b2a430838367732b47d54 Also clean away extra Salsa-CI markup not needed anymore. - Autopkgtest: Simplify autopkgtest 'smoke' to be easier to debug https://salsa.debian.org/mariadb-team/mariadb-10.5/-/commit/836907989ad8d355b2f88f8013a6acb8a64cf7d9 - Autopkgtest: Skip main.failed_auth_unixsocket on armhf and i386 https://salsa.debian.org/mariadb-team/mariadb-10.5/-/commit/74601f8b31a6c59e825089c52a1ca21545062813 --- debian/control | 7 ++----- debian/salsa-ci.yml | 29 +---------------------------- debian/tests/smoke | 28 +++++++++++++++++++++++----- debian/tests/upstream | 8 ++++++-- 4 files changed, 32 insertions(+), 40 deletions(-) diff --git a/debian/control b/debian/control index 7311affd464..5d29563485e 100644 --- a/debian/control +++ b/debian/control @@ -3,17 +3,14 @@ Section: database Priority: optional Maintainer: MariaDB Developers Build-Depends: bison, - chrpath, cmake, - cracklib-runtime, + cracklib-runtime , debhelper (>= 9), - dh-apparmor, dh-exec, dh-systemd, flex [amd64], - gdb, + gdb , libaio-dev [linux-any], - libarchive-dev, libboost-atomic-dev [amd64], libboost-chrono-dev [amd64], libboost-date-time-dev [amd64], diff --git a/debian/salsa-ci.yml b/debian/salsa-ci.yml index 290ba6f89cf..cbf5b931ad8 100644 --- a/debian/salsa-ci.yml +++ b/debian/salsa-ci.yml @@ -292,7 +292,7 @@ mariadb-10.1 Stretch to mariadb-10.5 upgrade: # Install almost everything currently in Debian Stretch, # omitting libmariadbclient-dev-compat as it would conflict - apt-get install -y 'default-mysql*' 'mariadb-*' 'libmariadbd*' 'libmariadbclient*' - # Verify installation of MariaDB from Buster + # Verify installation of MariaDB from Stretch - *test-verify-initial - *test-enable-sid-repos - *test-install @@ -562,31 +562,6 @@ mysql-8.0 Sid to mariadb-10.5 upgrade: # Installation often fails (not a MariaDB reason), so do not require this test to pass allow_failure: true -mysql-5.7 Sid to mariadb-10.5 upgrade: - stage: upgrade in Sid - needs: - - job: build - artifacts: true - image: debian:sid - artifacts: - when: always - name: "$CI_BUILD_NAME" - paths: - - ${WORKING_DIR}/debug - script: - - *test-prepare-container - - apt-get install -y mysql-server-5.7 'libmysqlc*' - - *test-verify-initial - - *test-install - - service mysql status - - sleep 5 # Give the mysql_upgrade a bit of time to complete before querying the server - - *test-verify-final - variables: - GIT_STRATEGY: none - except: - variables: - - $CI_COMMIT_TAG != null && $SALSA_CI_ENABLE_PIPELINE_ON_TAGS !~ /^(1|yes|true)$/ - # Upgrading from MySQL 8.0 with datadir in place is not possible. Users need to do a data dump. # The Debian maintainer scripts detect this situation and simply moves old datadir aside and start fresh. mysql-8.0 Focal to mariadb-10.5 upgrade: @@ -622,8 +597,6 @@ mysql-8.0 Focal to mariadb-10.5 upgrade: except: variables: - $CI_COMMIT_TAG != null && $SALSA_CI_ENABLE_PIPELINE_ON_TAGS !~ /^(1|yes|true)$/ - # Installation often fails (not a MariaDB reason), so do not require this test to pass - allow_failure: true mysql-5.7 Bionic to mariadb-10.5 upgrade: stage: upgrade extras diff --git a/debian/tests/smoke b/debian/tests/smoke index 26d407cf439..5de9d425e16 100644 --- a/debian/tests/smoke +++ b/debian/tests/smoke @@ -24,7 +24,7 @@ echo "Running test 'smoke'" set -ex -# Start the deamon if it was not running. For example in Docker testing +# Start the daemon if it was not running. For example in Docker testing # environments there might not be any systemd et al and the service needs to # be started manually. if ! which systemctl @@ -66,16 +66,24 @@ DROP DATABASE testdatabase; DROP USER 'testuser'@'localhost'; EOT -mysql <&2 + exit 1 + fi done else ! dpkg-query -W $plugin diff --git a/debian/tests/upstream b/debian/tests/upstream index 6ca9ddf7f1c..4e9b3a7cc8b 100644 --- a/debian/tests/upstream +++ b/debian/tests/upstream @@ -50,8 +50,12 @@ EOF fi ARCH=$(dpkg --print-architecture) -if [ "$ARCH" = "s390x" ]; then - echo "main.func_regexp_pcre : recursion fails on s390x https://bugs.launchpad.net/ubuntu/+source/mariadb-10.1/+bug/1723947" >> $SKIP_TEST_LST +if [ "$ARCH" = "s390x" ] +then + echo "main.func_regexp_pcre : recursion fails on s390x https://bugs.launchpad.net/ubuntu/+source/mariadb-10.1/+bug/1723947" >> $SKIP_TEST_LST +elif [ "$ARCH" = "armhf" ] || [ "$ARCH" = "i386" ] +then + echo "main.failed_auth_unixsocket : Test returns wrong exit code on armhf and i386 (but only in debci) https://jira.mariadb.org/browse/MDEV-23933" >> $SKIP_TEST_LST fi cd /usr/share/mysql/mysql-test From cc9c303a450bf9cbb9bda51638d0c435fe755336 Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Wed, 10 Mar 2021 16:46:42 +0530 Subject: [PATCH 15/26] MDEV-25070 SIGSEGV in fts_create_in_mem_aux_table InnoDB set the space in dict_table_t as NULL when table is discarded. So InnoDB shouldn't use the space present in table to detect whether the given tablespace is temporary tablespace. --- mysql-test/suite/innodb_fts/r/fulltext.result | 16 ++++++++++++++++ mysql-test/suite/innodb_fts/t/fulltext.test | 9 +++++++++ storage/innobase/fts/fts0fts.cc | 2 +- 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/mysql-test/suite/innodb_fts/r/fulltext.result b/mysql-test/suite/innodb_fts/r/fulltext.result index 0e30dd0be05..f41b938604d 100644 --- a/mysql-test/suite/innodb_fts/r/fulltext.result +++ b/mysql-test/suite/innodb_fts/r/fulltext.result @@ -689,3 +689,19 @@ FTS_DOC_ID t 2 foo bar 3 foo DROP TABLE t; +# +# MDEV-25070 SIGSEGV in fts_create_in_mem_aux_table +# +CREATE TABLE t1 (a CHAR, FULLTEXT KEY(a)) ENGINE=InnoDB; +ALTER TABLE t1 DISCARD TABLESPACE; +ALTER TABLE t1 ADD FULLTEXT INDEX (a); +Warnings: +Warning 1814 Tablespace has been discarded for table `t1` +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` char(1) DEFAULT NULL, + FULLTEXT KEY `a` (`a`), + FULLTEXT KEY `a_2` (`a`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +DROP TABLE t1; diff --git a/mysql-test/suite/innodb_fts/t/fulltext.test b/mysql-test/suite/innodb_fts/t/fulltext.test index 663b202265b..560ee8f96f2 100644 --- a/mysql-test/suite/innodb_fts/t/fulltext.test +++ b/mysql-test/suite/innodb_fts/t/fulltext.test @@ -717,3 +717,12 @@ while ($N) } DROP TABLE t; + +--echo # +--echo # MDEV-25070 SIGSEGV in fts_create_in_mem_aux_table +--echo # +CREATE TABLE t1 (a CHAR, FULLTEXT KEY(a)) ENGINE=InnoDB; +ALTER TABLE t1 DISCARD TABLESPACE; +ALTER TABLE t1 ADD FULLTEXT INDEX (a); +SHOW CREATE TABLE t1; +DROP TABLE t1; diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc index 859ec5051f2..cf76e3c83cd 100644 --- a/storage/innobase/fts/fts0fts.cc +++ b/storage/innobase/fts/fts0fts.cc @@ -1730,7 +1730,7 @@ fts_create_in_mem_aux_table( dict_table_t* new_table = dict_mem_table_create( aux_table_name, NULL, n_cols, 0, table->flags, table->space_id == TRX_SYS_SPACE - ? 0 : table->space->purpose == FIL_TYPE_TEMPORARY + ? 0 : table->space_id == SRV_TMP_SPACE_ID ? DICT_TF2_TEMPORARY : DICT_TF2_USE_FILE_PER_TABLE); if (DICT_TF_HAS_DATA_DIR(table->flags)) { From 322129dfb4c2d3a85dfb80c43e11df8d301ce79b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vicen=C8=9Biu=20Ciorbaru?= Date: Wed, 10 Mar 2021 10:31:22 +0200 Subject: [PATCH 16/26] Skip mysql_json_mysql_upgrade if plugin is not built Do not use --source directive as we don't want to load the plugin when the test starts. --- mysql-test/main/mysql_json_mysql_upgrade.test | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mysql-test/main/mysql_json_mysql_upgrade.test b/mysql-test/main/mysql_json_mysql_upgrade.test index 20f8ae588b7..4380b004c70 100644 --- a/mysql-test/main/mysql_json_mysql_upgrade.test +++ b/mysql-test/main/mysql_json_mysql_upgrade.test @@ -6,6 +6,10 @@ -- source include/have_utf8.inc -- source include/mysql_upgrade_preparation.inc +if (!$TYPE_MYSQL_JSON_SO) { + skip Need MYSQL_JSON plugin; +} + SET NAMES utf8; let $MYSQLD_DATADIR= `select @@datadir`; From 1799caa3a1305d21acaa37169e6b14307b4b5f08 Mon Sep 17 00:00:00 2001 From: Monty Date: Wed, 10 Mar 2021 17:27:01 +0200 Subject: [PATCH 17/26] MDEV-24422 Server crashes in ha_connect::GetRealType upon ALTER TABLE The problem was that the CONNECT engine is trying to open the .frm file during drop_table(), which the code did not take into account. Fixed by adding the HA_REUSES_FILE_NAMES table flag to CONNECT. Other things: - Fixed a wrong test of HA_REUSE_FILE_NAMES of in mysql_alter_table() (Comment was correct, no the code) - Added a test in the connect engine that if the .frm it tries to use in delete is not made for connect, it will generate an error instead of crash. --- sql/handler.h | 6 +++++- sql/sql_table.cc | 11 +++++------ storage/connect/ha_connect.cc | 11 ++++++++++- .../connect/mysql-test/connect/r/alter_engine.result | 11 +++++++++++ .../connect/mysql-test/connect/t/alter_engine.test | 11 +++++++++++ 5 files changed, 42 insertions(+), 8 deletions(-) create mode 100644 storage/connect/mysql-test/connect/r/alter_engine.result create mode 100644 storage/connect/mysql-test/connect/t/alter_engine.test diff --git a/sql/handler.h b/sql/handler.h index b00643d0ace..4c013733833 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -307,7 +307,11 @@ enum chf_create_flags { #define HA_PERSISTENT_TABLE (1ULL << 48) -/* If storage engine uses another engine as a base */ +/* + If storage engine uses another engine as a base + This flag is also needed if the table tries to open the .frm file + as part of drop table. +*/ #define HA_REUSES_FILE_NAMES (1ULL << 49) /* diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 0824672df4a..91051df29b7 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -10900,12 +10900,11 @@ do_continue:; The above is mainly true for the sequence and the partition engine. */ engine_changed= ((new_table->file->ht != table->file->ht) && - (((!(new_table->file->ha_table_flags() & HA_FILE_BASED) || - !(table->file->ha_table_flags() & HA_FILE_BASED))) || - (!(table->file->ha_table_flags() & HA_REUSES_FILE_NAMES) && - !(new_table->file->ha_table_flags() & - HA_REUSES_FILE_NAMES)))); - + ((!(new_table->file->ha_table_flags() & HA_FILE_BASED) || + !(table->file->ha_table_flags() & HA_FILE_BASED))) && + !(table->file->ha_table_flags() & HA_REUSES_FILE_NAMES) && + !(new_table->file->ha_table_flags() & + HA_REUSES_FILE_NAMES)); /* Close the intermediate table that will be the new table, but do not delete it! Even though MERGE tables do not have their children diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc index 2206cfc271d..b1449af9636 100644 --- a/storage/connect/ha_connect.cc +++ b/storage/connect/ha_connect.cc @@ -1169,7 +1169,8 @@ ulonglong ha_connect::table_flags() const // HA_NULL_IN_KEY | not implemented yet // HA_FAST_KEY_READ | causes error when sorting (???) HA_NO_TRANSACTIONS | HA_DUPLICATE_KEY_NOT_IN_ORDER | - HA_NO_BLOBS | HA_MUST_USE_TABLE_CONDITION_PUSHDOWN; + HA_NO_BLOBS | HA_MUST_USE_TABLE_CONDITION_PUSHDOWN | + HA_REUSES_FILE_NAMES; ha_connect *hp= (ha_connect*)this; PTOS pos= hp->GetTableOptionStruct(); @@ -5244,6 +5245,14 @@ int ha_connect::delete_or_rename_table(const char *name, const char *to) thd->push_internal_handler(&error_handler); bool got_error= open_table_def(thd, share); thd->pop_internal_handler(); + if (!got_error && share->db_type() != connect_hton) + { + /* The .frm file is not for the connect engine. Something is wrong! */ + got_error= 1; + rc= HA_ERR_INTERNAL_ERROR; + my_error(HA_ERR_INTERNAL_ERROR, MYF(0), + "TABLE_SHARE is not for the CONNECT engine"); + } if (!got_error) { // Now we can work if ((pos= share->option_struct)) { diff --git a/storage/connect/mysql-test/connect/r/alter_engine.result b/storage/connect/mysql-test/connect/r/alter_engine.result new file mode 100644 index 00000000000..530574d276d --- /dev/null +++ b/storage/connect/mysql-test/connect/r/alter_engine.result @@ -0,0 +1,11 @@ +# +# MDEV-24422 Server crashes in GetTypeID / ha_connect::GetRealType upon +# altering table engine +# +CREATE TABLE t1 (f INT) ENGINE=CONNECT; +Warnings: +Warning 1105 No table_type. Will be set to DOS +Warning 1105 No file name. Table will use t1.dos +ALTER TABLE t1 ENGINE InnoDB; +ALTER TABLE t1 ENGINE CONNECT; +DROP TABLE t1; diff --git a/storage/connect/mysql-test/connect/t/alter_engine.test b/storage/connect/mysql-test/connect/t/alter_engine.test new file mode 100644 index 00000000000..789a0955d3b --- /dev/null +++ b/storage/connect/mysql-test/connect/t/alter_engine.test @@ -0,0 +1,11 @@ +--source include/have_innodb.inc + +--echo # +--echo # MDEV-24422 Server crashes in GetTypeID / ha_connect::GetRealType upon +--echo # altering table engine +--echo # + +CREATE TABLE t1 (f INT) ENGINE=CONNECT; +ALTER TABLE t1 ENGINE InnoDB; +ALTER TABLE t1 ENGINE CONNECT; +DROP TABLE t1; From fa5f60681fe4ed9d5bb160e551381cb7b1be5850 Mon Sep 17 00:00:00 2001 From: Rinat Ibragimov Date: Thu, 18 Jun 2020 01:11:39 +0300 Subject: [PATCH 18/26] MDEV-20946: Hard FTWRL deadlock under user level locks It was possibile for a user to create an interlocked state which may go on for a significant period of time. There is a tight loop in the FTWRL code path that tries to repeatedly acquire a read lock. As the weight of FTWRL lock is the smallest among others, it's always selected by the deadlock detector, but can never be killed. Imaging the following sequence: connection_0 connection_1 GET_LOCK("l1", 0); LOCK TABLES t WRITE; FLUSH TABLES WITH READ LOCK; GET_LOCK("l1", 1000); The GET_LOCK statement in connection_1 triggers the deadlock detector, which tries to select the lock in FTWRL, since its weight is 0. However, since a loop in Global_read_lock::lock_global_read_lock() tries to always win, it tries to acquire lock again. Which invokes the deadlock detector, and that cycle continues until GET_LOCK in connection_1 times out. This patch resolves the live-locking by introducing a dynamic bonus to the deadlock weight associated with every lock. Each lock gets a bonus weight each time it's selected by the deadlock detector. In case of a live-lock situation, those locks that cannot be killed, get additional weight each iteration. Eventually their weight becomes so high that the deadlock detector shifts its attention to other lock, until it find the one that can be killed. --- mysql-test/main/deadlock_ftwrl.result | 21 ++++++++++++++++ mysql-test/main/deadlock_ftwrl.test | 36 +++++++++++++++++++++++++++ sql/mdl.cc | 1 + sql/mdl.h | 4 ++- 4 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 mysql-test/main/deadlock_ftwrl.result create mode 100644 mysql-test/main/deadlock_ftwrl.test diff --git a/mysql-test/main/deadlock_ftwrl.result b/mysql-test/main/deadlock_ftwrl.result new file mode 100644 index 00000000000..95eed70f664 --- /dev/null +++ b/mysql-test/main/deadlock_ftwrl.result @@ -0,0 +1,21 @@ +CREATE TABLE t1(a INT); +SELECT GET_LOCK("l1", 0); +GET_LOCK("l1", 0) +1 +connect con1,localhost,root,,; +LOCK TABLES t1 WRITE; +connection default; +set debug_sync='mdl_acquire_lock_wait SIGNAL ftwrl'; +FLUSH TABLES WITH READ LOCK; +connection con1; +set debug_sync='now WAIT_FOR ftwrl'; +SELECT GET_LOCK("l1", 1000); +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +disconnect con1; +connection default; +SELECT RELEASE_LOCK("l1"); +RELEASE_LOCK("l1") +1 +UNLOCK TABLES; +DROP TABLE t1; +set debug_sync='reset'; diff --git a/mysql-test/main/deadlock_ftwrl.test b/mysql-test/main/deadlock_ftwrl.test new file mode 100644 index 00000000000..fc943bcf953 --- /dev/null +++ b/mysql-test/main/deadlock_ftwrl.test @@ -0,0 +1,36 @@ +# MDEV-20946 Hard FTWRL deadlock under user level locks +# +# Deadlock detector should resolve conflicts between FTWRL and user locks. + +--source include/have_debug_sync.inc +--source include/count_sessions.inc + +CREATE TABLE t1(a INT); +SELECT GET_LOCK("l1", 0); + +connect(con1,localhost,root,,); +LOCK TABLES t1 WRITE; + +connection default; +set debug_sync='mdl_acquire_lock_wait SIGNAL ftwrl'; +send FLUSH TABLES WITH READ LOCK; +# At this point "default" is waiting for tables to be unlocked from +# LOCK TABLES WRITE issued by "con1". + +connection con1; +set debug_sync='now WAIT_FOR ftwrl'; +# The lock in the following GET_LOCK cannot be acquired since "default" holds +# a lock on "l1" and is waiting in FLUSH TABLES for con1. +--error ER_LOCK_DEADLOCK +SELECT GET_LOCK("l1", 1000); +disconnect con1; # Performs an implicit UNLOCK TABLES. + +connection default; +reap; +SELECT RELEASE_LOCK("l1"); +UNLOCK TABLES; +DROP TABLE t1; + +set debug_sync='reset'; + +--source include/wait_until_count_sessions.inc diff --git a/sql/mdl.cc b/sql/mdl.cc index 1798d3039fa..5e54178db70 100644 --- a/sql/mdl.cc +++ b/sql/mdl.cc @@ -2782,6 +2782,7 @@ void MDL_context::find_deadlock() context was waiting is concurrently satisfied. */ (void) victim->m_wait.set_status(MDL_wait::VICTIM); + victim->inc_deadlock_overweight(); victim->unlock_deadlock_victim(); if (victim == this) diff --git a/sql/mdl.h b/sql/mdl.h index 9a788b0ea31..a2cb7c2aa85 100644 --- a/sql/mdl.h +++ b/sql/mdl.h @@ -909,7 +909,8 @@ public: /** @pre Only valid if we started waiting for lock. */ inline uint get_deadlock_weight() const - { return m_waiting_for->get_deadlock_weight(); } + { return m_waiting_for->get_deadlock_weight() + m_deadlock_overweight; } + void inc_deadlock_overweight() { m_deadlock_overweight++; } /** Post signal to the context (and wake it up if necessary). @@ -1027,6 +1028,7 @@ private: */ MDL_wait_for_subgraph *m_waiting_for; LF_PINS *m_pins; + uint m_deadlock_overweight= 0; private: MDL_ticket *find_ticket(MDL_request *mdl_req, enum_mdl_duration *duration); From f11b60879beba19798a76e17af206a95fd8fd204 Mon Sep 17 00:00:00 2001 From: Krunal Bauskar Date: Tue, 23 Feb 2021 16:21:30 +0800 Subject: [PATCH 19/26] MDEV-24949: Enabling idle flushing (possible regression from MDEV-23855) - Currently page cleaner thread will stop flushing if dirty_pct < innodb_max_dirty_pages_pct_lwm. - If the server is not performing any activity then said resources/time could be used to flush the pending dirty pages and keep buffer pool clean for the next burst of the cycle. This flushing is called idle flushing. - flushing logic underwent a complete revamp in 10.5.7/8 and as part of the revamp idle flushing logic got removed. - New proposed logic of idle flushing is based on updated logic of the page cleaner that will enable idle flushing if - buf page cleaner is idle - there are dirty pages (< innodb_max_dirty_pages_pct_lwm) - server is not performing any activity Logic will kickstart the idle flushing bounded by innodb_io_capacity. (Thanks to Marko Makela for reviewing the patch and idea right from the its inception). --- storage/innobase/buf/buf0buf.cc | 2 + storage/innobase/buf/buf0flu.cc | 65 +++++++++++++++++++++++++++--- storage/innobase/include/buf0buf.h | 9 +++++ 3 files changed, 71 insertions(+), 5 deletions(-) diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index d531be43a8b..2f40ea28e0c 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -1480,6 +1480,8 @@ bool buf_pool_t::create() srv_buf_pool_old_size= srv_buf_pool_size; srv_buf_pool_base_size= srv_buf_pool_size; + last_activity_count= srv_get_activity_count(); + chunk_t::map_ref= chunk_t::map_reg; buf_LRU_old_ratio_update(100 * 3 / 8, false); btr_search_sys_create(); diff --git a/storage/innobase/buf/buf0flu.cc b/storage/innobase/buf/buf0flu.cc index 0acf9334c2c..9ece21ed3a4 100644 --- a/storage/innobase/buf/buf0flu.cc +++ b/storage/innobase/buf/buf0flu.cc @@ -134,7 +134,34 @@ inline void buf_pool_t::page_cleaner_wakeup() double dirty_pct= double(UT_LIST_GET_LEN(buf_pool.flush_list)) * 100.0 / double(UT_LIST_GET_LEN(buf_pool.LRU) + UT_LIST_GET_LEN(buf_pool.free)); double pct_lwm= srv_max_dirty_pages_pct_lwm; + + /* if pct_lwm != 0.0 means adpative flushing is enabled. + signal buf page cleaner thread + - if pct_lwm <= dirty_pct then it will invoke apdative flushing flow + - if pct_lwm > dirty_pct then it will invoke idle flushing flow. + + idle_flushing: + dirty_pct < innodb_max_dirty_pages_pct_lwm so it could be an + idle flushing use-case. + + Why is last_activity_count not updated always? + - let's first understand when is server activity count updated. + - it is updated on commit of a transaction trx_t::commit() and not + on adding a page to the flush list. + - page_cleaner_wakeup is called when a page is added to the flush list. + + - now let's say the first user thread, updates the count from X -> Y but + is yet to commit the transaction (so activity count is still Y). + followup user threads will see the updated count as (Y) that is matching + the universal server activity count (Y), giving a false impression that + the server is idle. + + How to avoid this? + - by allowing last_activity_count to updated when page-cleaner is made + active and has work to do. This ensures that the last_activity signal + is consumed by the page-cleaner before the next one is generated. */ if ((pct_lwm != 0.0 && pct_lwm <= dirty_pct) || + (pct_lwm != 0.0 && last_activity_count == srv_get_activity_count()) || srv_max_buf_pool_modified_pct <= dirty_pct) { page_cleaner_is_idle= false; @@ -2076,6 +2103,7 @@ static os_thread_ret_t DECLARE_THREAD(buf_flush_page_cleaner)(void*) mysql_mutex_lock(&buf_pool.flush_list_mutex); lsn_t lsn_limit; + ulint last_activity_count= srv_get_activity_count(); for (;;) { @@ -2095,9 +2123,14 @@ furious_flush: else if (srv_shutdown_state > SRV_SHUTDOWN_INITIATED) break; - if (buf_pool.page_cleaner_idle()) - my_cond_wait(&buf_pool.do_flush_list, - &buf_pool.flush_list_mutex.m_mutex); + + /* If buf pager cleaner is idle and there is no work + (either dirty pages are all flushed or adaptive flushing + is not enabled) then opt for non-timed wait */ + if (buf_pool.page_cleaner_idle() && + (!UT_LIST_GET_LEN(buf_pool.flush_list) || + srv_max_dirty_pages_pct_lwm == 0.0)) + my_cond_wait(&buf_pool.do_flush_list, &buf_pool.flush_list_mutex.m_mutex); else my_cond_timedwait(&buf_pool.do_flush_list, &buf_pool.flush_list_mutex.m_mutex, &abstime); @@ -2135,10 +2168,26 @@ unemployed: const double dirty_pct= double(dirty_blocks) * 100.0 / double(UT_LIST_GET_LEN(buf_pool.LRU) + UT_LIST_GET_LEN(buf_pool.free)); + bool idle_flush= false; + if (lsn_limit); else if (srv_max_dirty_pages_pct_lwm != 0.0) { - if (dirty_pct < srv_max_dirty_pages_pct_lwm) + const ulint activity_count= srv_get_activity_count(); + if (activity_count != last_activity_count) + last_activity_count= activity_count; + else if (buf_pool.page_cleaner_idle() && buf_pool.n_pend_reads == 0) + { + /* reaching here means 3 things: + - last_activity_count == activity_count: suggesting server is idle + (no trx_t::commit activity) + - page cleaner is idle (dirty_pct < srv_max_dirty_pages_pct_lwm) + - there are no pending reads but there are dirty pages to flush */ + idle_flush= true; + buf_pool.update_last_activity_count(activity_count); + } + + if (!idle_flush && dirty_pct < srv_max_dirty_pages_pct_lwm) goto unemployed; } else if (dirty_pct < srv_max_buf_pool_modified_pct) @@ -2163,7 +2212,7 @@ unemployed: pthread_cond_broadcast(&buf_pool.done_flush_list); goto try_checkpoint; } - else if (!srv_adaptive_flushing) + else if (idle_flush || !srv_adaptive_flushing) { n_flushed= buf_flush_lists(srv_io_capacity, LSN_MAX); try_checkpoint: @@ -2220,6 +2269,12 @@ do_checkpoint: next: #endif /* !DBUG_OFF */ mysql_mutex_lock(&buf_pool.flush_list_mutex); + + /* when idle flushing kicks in page_cleaner is marked active. + reset it back to idle since the it was made active as part of + idle flushing stage. */ + if (idle_flush) + buf_pool.page_cleaner_set_idle(true); } mysql_mutex_unlock(&buf_pool.flush_list_mutex); diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h index 12fb139f1bf..deff8054362 100644 --- a/storage/innobase/include/buf0buf.h +++ b/storage/innobase/include/buf0buf.h @@ -1946,6 +1946,8 @@ public: private: /** whether the page cleaner needs wakeup from indefinite sleep */ bool page_cleaner_is_idle; + /** track server activity count for signaling idle flushing */ + ulint last_activity_count; public: /** signalled to wake up the page_cleaner; protected by flush_list_mutex */ pthread_cond_t do_flush_list; @@ -1966,6 +1968,13 @@ public: page_cleaner_is_idle= deep_sleep; } + /** Update server last activity count */ + void update_last_activity_count(ulint activity_count) + { + mysql_mutex_assert_owner(&flush_list_mutex); + last_activity_count= activity_count; + } + // n_flush_LRU + n_flush_list is approximately COUNT(io_fix()==BUF_IO_WRITE) // in flush_list From a6cd4612a9e802a365f8fc37e0da6a24e2541133 Mon Sep 17 00:00:00 2001 From: David CARLIER Date: Wed, 10 Mar 2021 16:02:55 +0000 Subject: [PATCH 20/26] connect storage, little compile issues fix proposal. --- storage/connect/bsonudf.cpp | 12 ++++++------ storage/connect/jsonudf.cpp | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/storage/connect/bsonudf.cpp b/storage/connect/bsonudf.cpp index 29fe0a6bf22..5b4332d6e9e 100644 --- a/storage/connect/bsonudf.cpp +++ b/storage/connect/bsonudf.cpp @@ -653,7 +653,7 @@ PVAL BJNX::GetCalcValue(PGLOBAL g, PBVAL bap, int n) { // For calculated arrays, a local Value must be used int lng = 0; - short type, prec = 0; + short type = 0, prec = 0; bool b = n < Nod - 1; PVAL valp; PBVAL vlp, vp; @@ -4714,7 +4714,7 @@ char *bfile_convert(UDF_INIT* initid, UDF_ARGS* args, char* result, str = (char*)g->Xchk; if (!str) { - PUSH_WARNING(g->Message ? g->Message : "Unexpected error"); + PUSH_WARNING(g->Message[0] != '\0' ? g->Message : "Unexpected error"); *is_null = 1; *error = 1; *res_length = 0; @@ -4774,7 +4774,7 @@ char *bfile_bjson(UDF_INIT *initid, UDF_ARGS *args, char *result, if (!g->Xchk) { int msgid = MSGID_OPEN_MODE_STRERROR; - FILE *fout; + FILE *fout = NULL; FILE *fin; if (!(fin = global_fopen(g, msgid, fn, "rt"))) @@ -4837,7 +4837,7 @@ char *bfile_bjson(UDF_INIT *initid, UDF_ARGS *args, char *result, str = (char*)g->Xchk; if (!str) { - if (g->Message) + if (g->Message[0] != '\0') str = strcpy(result, g->Message); else str = strcpy(result, "Unexpected error"); @@ -5003,7 +5003,7 @@ char *bbin_array_add(UDF_INIT *initid, UDF_ARGS *args, char *result, uint n = 2; int* x = GetIntArgPtr(g, args, n); BJNX bnx(g, NULL, TYPE_STRING); - PBVAL jarp, top, jvp = NULL; + PBVAL top, jarp = NULL, jvp = NULL; PBVAL jsp = bnx.MakeValue(args, 0, true, &top); if (bnx.CheckPath(g, args, jsp, jvp, 2)) @@ -5636,7 +5636,7 @@ char *bbin_object_values(UDF_INIT *initid, UDF_ARGS *args, char *result, if (!bsp) { if (!CheckMemory(g, initid, args, 1, true, true)) { BJNX bnx(g); - PBVAL top, jarp; + PBVAL top, jarp = NULL; PBVAL jvp = bnx.MakeValue(args, 0, true, &top); if (jvp->Type == TYPE_JOB) { diff --git a/storage/connect/jsonudf.cpp b/storage/connect/jsonudf.cpp index 96e1db8f6c3..79e1534c51c 100644 --- a/storage/connect/jsonudf.cpp +++ b/storage/connect/jsonudf.cpp @@ -5865,7 +5865,7 @@ char *jfile_convert(UDF_INIT* initid, UDF_ARGS* args, char* result, str = (char*)g->Xchk; if (!str) { - PUSH_WARNING(g->Message ? g->Message : "Unexpected error"); + PUSH_WARNING(g->Message[0] != '\0' ? g->Message : "Unexpected error"); *is_null = 1; *error = 1; *res_length = 0; @@ -5926,7 +5926,7 @@ char *jfile_bjson(UDF_INIT *initid, UDF_ARGS *args, char *result, if (!g->Xchk) { int msgid = MSGID_OPEN_MODE_STRERROR; - FILE *fout; + FILE *fout = NULL; FILE *fin; if (!(fin = global_fopen(g, msgid, fn, "rt"))) @@ -5993,7 +5993,7 @@ char *jfile_bjson(UDF_INIT *initid, UDF_ARGS *args, char *result, str = (char*)g->Xchk; if (!str) { - if (g->Message) + if (g->Message[0] != '\0') str = strcpy(result, g->Message); else str = strcpy(result, "Unexpected error"); From 6e7ac4060d28a35e12d6a34450e5624734d3a9be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 11 Mar 2021 12:34:56 +0200 Subject: [PATCH 21/26] MDEV-25070 fixup: Correct the result --- mysql-test/suite/innodb_fts/r/fulltext.result | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/suite/innodb_fts/r/fulltext.result b/mysql-test/suite/innodb_fts/r/fulltext.result index f41b938604d..c3345548c0d 100644 --- a/mysql-test/suite/innodb_fts/r/fulltext.result +++ b/mysql-test/suite/innodb_fts/r/fulltext.result @@ -691,7 +691,7 @@ FTS_DOC_ID t DROP TABLE t; # # MDEV-25070 SIGSEGV in fts_create_in_mem_aux_table -# +# CREATE TABLE t1 (a CHAR, FULLTEXT KEY(a)) ENGINE=InnoDB; ALTER TABLE t1 DISCARD TABLESPACE; ALTER TABLE t1 ADD FULLTEXT INDEX (a); From 08e8ad7c717302a77db91cfa06909eb8c10006fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 11 Mar 2021 12:50:04 +0200 Subject: [PATCH 22/26] MDEV-25106 Deprecation warning for innodb_checksum_algorithm=none,innodb,... MDEV-25105 (commit 7a4fbb55b02b449a135fe935f624422eaacfdd7c) in MariaDB 10.6 will refuse the innodb_checksum_algorithm values none, innodb, strict_none, strict_innodb. We will issue a deprecation warning if innodb_checksum_algorithm is set to any of these non-default unsafe values. innodb_checksum_algorithm=crc32 was made the default in MySQL 5.7 and MariaDB Server 10.2, and given that older versions of the server have reached their end of life, there is no valid reason to use anything else than innodb_checksum_algorithm=crc32 or innodb_checksum_algorithm=strict_crc32 in MariaDB 10.3. Reviewed by: Sergei Golubchik --- .../r/innodb-checksum-algorithm.result | 18 ++++++++++ .../r/innodb_checksum_algorithm_basic.result | 8 +++++ storage/innobase/handler/ha_innodb.cc | 33 +++++++++++++++++-- 3 files changed, 56 insertions(+), 3 deletions(-) diff --git a/mysql-test/suite/encryption/r/innodb-checksum-algorithm.result b/mysql-test/suite/encryption/r/innodb-checksum-algorithm.result index ff42e975b8d..a43676dcebe 100644 --- a/mysql-test/suite/encryption/r/innodb-checksum-algorithm.result +++ b/mysql-test/suite/encryption/r/innodb-checksum-algorithm.result @@ -8,6 +8,8 @@ SET GLOBAL innodb_encrypt_tables = ON; SET GLOBAL innodb_encryption_threads = 4; call mtr.add_suppression("InnoDB: innodb_checksum_algorithm is set to \"strict_(crc32|none|innodb)\" but the page \\[page id: space=[0-9]+, page number=[0-9]+\\] contains a valid checksum \"(innodb|none|crc32)\""); SET GLOBAL innodb_checksum_algorithm = innodb; +Warnings: +Warning 138 Setting innodb_checksum_algorithm to values other than crc32 or strict_crc32 is UNSAFE and DEPRECATED. These deprecated values will be disallowed in MariaDB 10.6. SET GLOBAL innodb_default_encryption_key_id=4; SET GLOBAL innodb_checksum_algorithm=crc32; create table tce_crc32(a serial, b blob, index(b(10))) engine=innodb @@ -90,6 +92,8 @@ update tpe_crc32 set b=substr(b,1); ALTER TABLE tp_crc32 IMPORT TABLESPACE; update tp_crc32 set b=substr(b,1); SET GLOBAL innodb_checksum_algorithm=innodb; +Warnings: +Warning 138 Setting innodb_checksum_algorithm to values other than crc32 or strict_crc32 is UNSAFE and DEPRECATED. These deprecated values will be disallowed in MariaDB 10.6. ALTER TABLE tce_crc32 DISCARD TABLESPACE; ALTER TABLE tc_crc32 DISCARD TABLESPACE; ALTER TABLE te_crc32 DISCARD TABLESPACE; @@ -115,6 +119,8 @@ update tpe_crc32 set b=substr(b,1); ALTER TABLE tp_crc32 IMPORT TABLESPACE; update tp_crc32 set b=substr(b,1); SET GLOBAL innodb_checksum_algorithm=none; +Warnings: +Warning 138 Setting innodb_checksum_algorithm to values other than crc32 or strict_crc32 is UNSAFE and DEPRECATED. These deprecated values will be disallowed in MariaDB 10.6. ALTER TABLE tce_crc32 DISCARD TABLESPACE; ALTER TABLE tc_crc32 DISCARD TABLESPACE; ALTER TABLE te_crc32 DISCARD TABLESPACE; @@ -151,6 +157,8 @@ test.tp_crc32 check status OK DROP TABLE tce_crc32, tc_crc32, te_crc32, t_crc32, tpe_crc32, tp_crc32; SET GLOBAL innodb_checksum_algorithm=innodb; +Warnings: +Warning 138 Setting innodb_checksum_algorithm to values other than crc32 or strict_crc32 is UNSAFE and DEPRECATED. These deprecated values will be disallowed in MariaDB 10.6. create table tce_innodb(a serial, b blob, index(b(10))) engine=innodb ROW_FORMAT=COMPRESSED encrypted=yes; create table tc_innodb(a serial, b blob, index(b(10))) engine=innodb @@ -231,6 +239,8 @@ update tpe_innodb set b=substr(b,1); ALTER TABLE tp_innodb IMPORT TABLESPACE; update tp_innodb set b=substr(b,1); SET GLOBAL innodb_checksum_algorithm=innodb; +Warnings: +Warning 138 Setting innodb_checksum_algorithm to values other than crc32 or strict_crc32 is UNSAFE and DEPRECATED. These deprecated values will be disallowed in MariaDB 10.6. ALTER TABLE tce_innodb DISCARD TABLESPACE; ALTER TABLE tc_innodb DISCARD TABLESPACE; ALTER TABLE te_innodb DISCARD TABLESPACE; @@ -256,6 +266,8 @@ update tpe_innodb set b=substr(b,1); ALTER TABLE tp_innodb IMPORT TABLESPACE; update tp_innodb set b=substr(b,1); SET GLOBAL innodb_checksum_algorithm=none; +Warnings: +Warning 138 Setting innodb_checksum_algorithm to values other than crc32 or strict_crc32 is UNSAFE and DEPRECATED. These deprecated values will be disallowed in MariaDB 10.6. ALTER TABLE tce_innodb DISCARD TABLESPACE; ALTER TABLE tc_innodb DISCARD TABLESPACE; ALTER TABLE te_innodb DISCARD TABLESPACE; @@ -292,6 +304,8 @@ test.tp_innodb check status OK DROP TABLE tce_innodb, tc_innodb, te_innodb, t_innodb, tpe_innodb, tp_innodb; SET GLOBAL innodb_checksum_algorithm=none; +Warnings: +Warning 138 Setting innodb_checksum_algorithm to values other than crc32 or strict_crc32 is UNSAFE and DEPRECATED. These deprecated values will be disallowed in MariaDB 10.6. create table tce_none(a serial, b blob, index(b(10))) engine=innodb ROW_FORMAT=COMPRESSED encrypted=yes; create table tc_none(a serial, b blob, index(b(10))) engine=innodb @@ -372,6 +386,8 @@ update tpe_none set b=substr(b,1); ALTER TABLE tp_none IMPORT TABLESPACE; update tp_none set b=substr(b,1); SET GLOBAL innodb_checksum_algorithm=innodb; +Warnings: +Warning 138 Setting innodb_checksum_algorithm to values other than crc32 or strict_crc32 is UNSAFE and DEPRECATED. These deprecated values will be disallowed in MariaDB 10.6. ALTER TABLE tce_none DISCARD TABLESPACE; ALTER TABLE tc_none DISCARD TABLESPACE; ALTER TABLE te_none DISCARD TABLESPACE; @@ -397,6 +413,8 @@ update tpe_none set b=substr(b,1); ALTER TABLE tp_none IMPORT TABLESPACE; update tp_none set b=substr(b,1); SET GLOBAL innodb_checksum_algorithm=none; +Warnings: +Warning 138 Setting innodb_checksum_algorithm to values other than crc32 or strict_crc32 is UNSAFE and DEPRECATED. These deprecated values will be disallowed in MariaDB 10.6. ALTER TABLE tce_none DISCARD TABLESPACE; ALTER TABLE tc_none DISCARD TABLESPACE; ALTER TABLE te_none DISCARD TABLESPACE; diff --git a/mysql-test/suite/sys_vars/r/innodb_checksum_algorithm_basic.result b/mysql-test/suite/sys_vars/r/innodb_checksum_algorithm_basic.result index 9c2e95b3c7c..912acb69ab0 100644 --- a/mysql-test/suite/sys_vars/r/innodb_checksum_algorithm_basic.result +++ b/mysql-test/suite/sys_vars/r/innodb_checksum_algorithm_basic.result @@ -11,18 +11,26 @@ SELECT @@global.innodb_checksum_algorithm; @@global.innodb_checksum_algorithm strict_crc32 SET GLOBAL innodb_checksum_algorithm = 'innodb'; +Warnings: +Warning 138 Setting innodb_checksum_algorithm to values other than crc32 or strict_crc32 is UNSAFE and DEPRECATED. These deprecated values will be disallowed in MariaDB 10.6. SELECT @@global.innodb_checksum_algorithm; @@global.innodb_checksum_algorithm innodb SET GLOBAL innodb_checksum_algorithm = 'strict_innodb'; +Warnings: +Warning 138 Setting innodb_checksum_algorithm to values other than crc32 or strict_crc32 is UNSAFE and DEPRECATED. These deprecated values will be disallowed in MariaDB 10.6. SELECT @@global.innodb_checksum_algorithm; @@global.innodb_checksum_algorithm strict_innodb SET GLOBAL innodb_checksum_algorithm = 'none'; +Warnings: +Warning 138 Setting innodb_checksum_algorithm to values other than crc32 or strict_crc32 is UNSAFE and DEPRECATED. These deprecated values will be disallowed in MariaDB 10.6. SELECT @@global.innodb_checksum_algorithm; @@global.innodb_checksum_algorithm none SET GLOBAL innodb_checksum_algorithm = 'strict_none'; +Warnings: +Warning 138 Setting innodb_checksum_algorithm to values other than crc32 or strict_crc32 is UNSAFE and DEPRECATED. These deprecated values will be disallowed in MariaDB 10.6. SELECT @@global.innodb_checksum_algorithm; @@global.innodb_checksum_algorithm strict_none diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index b0b7a96116a..5074855af64 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -3509,6 +3509,11 @@ static int innodb_init_abort() static const char* deprecated_idle_flush_pct = "innodb_idle_flush_pct is DEPRECATED and has no effect."; +static const char* deprecated_innodb_checksum_algorithm + = "Setting innodb_checksum_algorithm to values other than" + " crc32 or strict_crc32 is UNSAFE and DEPRECATED." + " These deprecated values will be disallowed in MariaDB 10.6."; + static ulong innodb_idle_flush_pct; /** If applicable, emit a message that log checksums cannot be disabled. @@ -3537,6 +3542,21 @@ innodb_log_checksums_func_update(THD* thd, bool check) return(check); } +static void innodb_checksum_algorithm_update(THD *thd, st_mysql_sys_var*, + void *, const void *save) +{ + srv_checksum_algorithm= *static_cast(save); + switch (srv_checksum_algorithm) { + case SRV_CHECKSUM_ALGORITHM_CRC32: + case SRV_CHECKSUM_ALGORITHM_STRICT_CRC32: + break; + default: + push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, + HA_ERR_UNSUPPORTED, + deprecated_innodb_checksum_algorithm); + } +} + /****************************************************************//** Gives the file extension of an InnoDB single-table tablespace. */ static const char* ha_innobase_exts[] = { @@ -3953,9 +3973,16 @@ static int innodb_init_params() if (!innobase_use_checksums) { ib::warn() << "Setting innodb_checksums to OFF is DEPRECATED." - " This option may be removed in future releases. You" - " should set innodb_checksum_algorithm=NONE instead."; + " This option was removed in MariaDB 10.5."; srv_checksum_algorithm = SRV_CHECKSUM_ALGORITHM_NONE; + } else { + switch (srv_checksum_algorithm) { + case SRV_CHECKSUM_ALGORITHM_CRC32: + case SRV_CHECKSUM_ALGORITHM_STRICT_CRC32: + break; + default: + ib::warn() << deprecated_innodb_checksum_algorithm; + } } innodb_log_checksums = innodb_log_checksums_func_update( @@ -19111,7 +19138,7 @@ static MYSQL_SYSVAR_ENUM(checksum_algorithm, srv_checksum_algorithm, " magic number when reading;" " Files updated when this option is set to crc32 or strict_crc32 will" " not be readable by MariaDB versions older than 10.0.4", - NULL, NULL, SRV_CHECKSUM_ALGORITHM_CRC32, + NULL, innodb_checksum_algorithm_update, SRV_CHECKSUM_ALGORITHM_CRC32, &innodb_checksum_algorithm_typelib); static MYSQL_SYSVAR_BOOL(log_checksums, innodb_log_checksums, From 549a70d7f01ce723b1b06fd7be569211a8270bcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 9 Mar 2021 18:03:31 +0200 Subject: [PATCH 23/26] MDEV-25031 Not applying INSERT_*_REDUNDANT due to corruption on page page_apply_insert_redundant(): Replace a too strict condition hdr_c > pextra_size. It turns out that page_cur_insert_rec_low() is not even computing the extra_size of cur->rec when it is trying to reuse header bytes of the preceding record. --- storage/innobase/include/page0cur.h | 4 ++-- storage/innobase/page/page0cur.cc | 8 +++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/storage/innobase/include/page0cur.h b/storage/innobase/include/page0cur.h index 57c3a8f66fc..c0f3bf6866e 100644 --- a/storage/innobase/include/page0cur.h +++ b/storage/innobase/include/page0cur.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2018, 2020, MariaDB Corporation. +Copyright (c) 2018, 2021, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -205,7 +205,7 @@ page_cur_delete_rec( written by page_cur_insert_rec_low() for a ROW_FORMAT=REDUNDANT page. @param block B-tree or R-tree page in ROW_FORMAT=COMPACT or DYNAMIC @param reuse false=allocate from PAGE_HEAP_TOP; true=reuse PAGE_FREE -@param prev byte offset of the predecessor, relative to PAGE_NEW_INFIMUM +@param prev byte offset of the predecessor, relative to PAGE_OLD_INFIMUM @param enc_hdr encoded fixed-size header bits @param hdr_c number of common record header bytes with prev @param data_c number of common data bytes with prev diff --git a/storage/innobase/page/page0cur.cc b/storage/innobase/page/page0cur.cc index 781884842ef..cb4293f998a 100644 --- a/storage/innobase/page/page0cur.cc +++ b/storage/innobase/page/page0cur.cc @@ -2,7 +2,7 @@ Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2012, Facebook Inc. -Copyright (c) 2018, 2020, MariaDB Corporation. +Copyright (c) 2018, 2021, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -2288,7 +2288,7 @@ page_cur_delete_rec( written by page_cur_insert_rec_low() for a ROW_FORMAT=REDUNDANT page. @param block B-tree or R-tree page in ROW_FORMAT=COMPACT or DYNAMIC @param reuse false=allocate from PAGE_HEAP_TOP; true=reuse PAGE_FREE -@param prev byte offset of the predecessor, relative to PAGE_NEW_INFIMUM +@param prev byte offset of the predecessor, relative to PAGE_OLD_INFIMUM @param enc_hdr encoded fixed-size header bits @param hdr_c number of common record header bytes with prev @param data_c number of common data bytes with prev @@ -2350,6 +2350,8 @@ corrupted: if (prev_rec == &block.frame[PAGE_OLD_INFIMUM]); else if (UNIV_UNLIKELY(prev_rec - pextra_size < heap_bot)) goto corrupted; + if (UNIV_UNLIKELY(hdr_c && prev_rec - hdr_c < heap_bot)) + goto corrupted; const ulint pdata_size= rec_get_data_size_old(prev_rec); if (UNIV_UNLIKELY(prev_rec + pdata_size > heap_top)) goto corrupted; @@ -2365,7 +2367,7 @@ corrupted: const ulint extra_size= REC_N_OLD_EXTRA_BYTES + (is_short ? n_fields : n_fields * 2); hdr_c+= REC_N_OLD_EXTRA_BYTES; - if (UNIV_UNLIKELY(hdr_c > extra_size || hdr_c > pextra_size)) + if (UNIV_UNLIKELY(hdr_c > extra_size)) goto corrupted; if (UNIV_UNLIKELY(extra_size - hdr_c > data_len)) goto corrupted; From a8650b64ede7330e83e84226cccd77ba8e05fa29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 10 Mar 2021 19:33:09 +0200 Subject: [PATCH 24/26] MDEV-25110 [FATAL] InnoDB: Trying to write ... outside the bounds In commit 118e258aaac5da75a2ac4556201aaea3688fac67 (part of MDEV-23855) we inadvertently broke crash recovery, reintroducing MDEV-11556. fil_system_t::extend_to_recv_size(): Extend all open tablespace files to the recovered size. recv_sys_t::apply(): Invoke fil_system.extend_to_recv_size() at the start of each batch. In this way, any fil_space_t::recv_size changes that were parsed after the file was opened will be applied. --- storage/innobase/fil/fil0fil.cc | 27 +++++++++++++++++++++++++++ storage/innobase/include/fil0fil.h | 5 ++++- storage/innobase/log/log0recv.cc | 2 ++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc index d000bc471d9..e245076a822 100644 --- a/storage/innobase/fil/fil0fil.cc +++ b/storage/innobase/fil/fil0fil.cc @@ -1305,6 +1305,33 @@ void fil_system_t::close() #endif /* UNIV_LINUX */ } +/** Extend all open data files to the recovered size */ +ATTRIBUTE_COLD void fil_system_t::extend_to_recv_size() +{ + ut_ad(is_initialised()); + mutex_enter(&mutex); + for (fil_space_t *space= UT_LIST_GET_FIRST(fil_system.space_list); space; + space= UT_LIST_GET_NEXT(space_list, space)) + { + const uint32_t size= space->recv_size; + + if (size > space->size) + { + if (space->is_closing()) + continue; + space->reacquire(); + bool success; + while (fil_space_extend_must_retry(space, UT_LIST_GET_LAST(space->chain), + size, &success)) + mutex_enter(&mutex); + /* Crash recovery requires the file extension to succeed. */ + ut_a(success); + space->release(); + } + } + mutex_exit(&mutex); +} + /** Close all tablespace files at shutdown */ void fil_space_t::close_all() { diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h index f011eb6af69..f4ca4e9a73e 100644 --- a/storage/innobase/include/fil0fil.h +++ b/storage/innobase/include/fil0fil.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2013, 2020, MariaDB Corporation. +Copyright (c) 2013, 2021, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -1422,6 +1422,9 @@ public: @retval NULL if this was the last */ inline fil_space_t* keyrotate_next(fil_space_t *space, bool recheck, bool encrypt); + + /** Extend all open data files to the recovered size */ + ATTRIBUTE_COLD void extend_to_recv_size(); }; /** The tablespace memory cache. */ diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc index 7c9d8af0859..67ac088f629 100644 --- a/storage/innobase/log/log0recv.cc +++ b/storage/innobase/log/log0recv.cc @@ -2662,6 +2662,8 @@ void recv_sys_t::apply(bool last_batch) trim(page_id_t(id + srv_undo_space_id_start, t.pages), t.lsn); } + fil_system.extend_to_recv_size(); + buf_block_t *free_block= buf_LRU_get_free_block(false); for (map::iterator p= pages.begin(); p != pages.end(); ) From 06df0b0dce95d597a6947aeeba2778af9961d520 Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Thu, 11 Mar 2021 20:52:30 +0530 Subject: [PATCH 25/26] MDEV-25107 Check TABLE miscalutates the length of column - This is caused by merge commit a26e7a37266d8296094dabca52f0f6646fd73926. InnoDB fails to fetch the next index field when there is a externally stored column length check involved. --- storage/innobase/btr/btr0btr.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/storage/innobase/btr/btr0btr.cc b/storage/innobase/btr/btr0btr.cc index a01eafb9492..e24e8d928f2 100644 --- a/storage/innobase/btr/btr0btr.cc +++ b/storage/innobase/btr/btr0btr.cc @@ -4673,7 +4673,7 @@ n_field_mismatch: ulint extern_len = mach_read_from_4( data + len + BTR_EXTERN_LEN + 4); if (fixed_size == extern_len) { - continue; + goto next_field; } } } @@ -4708,7 +4708,7 @@ len_mismatch: } return(FALSE); } - +next_field: field++; } From 2c3014e8a787713be57e47d47fd8cc0bfbdb6b45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 11 Mar 2021 19:14:35 +0200 Subject: [PATCH 26/26] MDEV-24668 fixup: uninitialized return value with Galera --- sql/sql_acl.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index b8c061456c8..ddaa54588d7 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -3794,7 +3794,7 @@ bool change_password(THD *thd, LEX_USER *user) char buff[512]; ulong query_length= 0; enum_binlog_format save_binlog_format; - bool result, acl_cache_is_locked= false; + bool result= false, acl_cache_is_locked= false; ACL_USER *acl_user; ACL_USER::AUTH auth; const char *password_plugin= 0;