From 0ffdcf678451121792021aba0693539e8e62900d Mon Sep 17 00:00:00 2001 From: asklavou Date: Mon, 7 Nov 2022 14:56:09 +0000 Subject: MDEV 28970: Add RESET MASTER to clear possible remaining binlog from previous test --- mysql-test/main/mysql_upgrade_view.result | 1 + mysql-test/main/mysql_upgrade_view.test | 2 +- mysql-test/main/stat_tables_rbr.result | 1 + mysql-test/main/stat_tables_rbr.test | 2 +- mysql-test/suite/binlog/r/binlog_stm_binlog.result | 1 + mysql-test/suite/binlog/r/binlog_stm_datetime_ranges_mdev15289.result | 1 + mysql-test/suite/binlog/r/binlog_stm_do_db.result | 1 + mysql-test/suite/binlog/r/innodb_autoinc_lock_mode_binlog.result | 1 + mysql-test/suite/binlog/t/binlog_stm_binlog.test | 2 +- mysql-test/suite/binlog/t/binlog_stm_datetime_ranges_mdev15289.test | 2 +- mysql-test/suite/binlog/t/binlog_stm_do_db.test | 2 +- mysql-test/suite/binlog/t/innodb_autoinc_lock_mode_binlog.test | 2 +- 12 files changed, 12 insertions(+), 6 deletions(-) diff --git a/mysql-test/main/mysql_upgrade_view.result b/mysql-test/main/mysql_upgrade_view.result index 172ef7e4159..052a320d0ee 100644 --- a/mysql-test/main/mysql_upgrade_view.result +++ b/mysql-test/main/mysql_upgrade_view.result @@ -1,3 +1,4 @@ +reset master; set sql_log_bin=0; drop table if exists t1,v1,v2,v3,v4,v1badcheck; drop view if exists t1,v1,v2,v3,v4,v1badcheck; diff --git a/mysql-test/main/mysql_upgrade_view.test b/mysql-test/main/mysql_upgrade_view.test index 6a496858d22..f894b56b08b 100644 --- a/mysql-test/main/mysql_upgrade_view.test +++ b/mysql-test/main/mysql_upgrade_view.test @@ -1,5 +1,5 @@ -- source include/have_log_bin.inc - +reset master; # clear binlogs set sql_log_bin=0; --disable_warnings drop table if exists t1,v1,v2,v3,v4,v1badcheck; diff --git a/mysql-test/main/stat_tables_rbr.result b/mysql-test/main/stat_tables_rbr.result index 7ae7ade4398..c154ef03b0c 100644 --- a/mysql-test/main/stat_tables_rbr.result +++ b/mysql-test/main/stat_tables_rbr.result @@ -1,3 +1,4 @@ +RESET MASTER; # # Bug mdev-463: assertion failure when running ANALYZE with RBR on # diff --git a/mysql-test/main/stat_tables_rbr.test b/mysql-test/main/stat_tables_rbr.test index 29f7c4e6622..95890d35ac7 100644 --- a/mysql-test/main/stat_tables_rbr.test +++ b/mysql-test/main/stat_tables_rbr.test @@ -1,7 +1,7 @@ --source include/have_binlog_format_row.inc --source include/have_innodb.inc --source include/have_partition.inc - +RESET MASTER; # clear up binlogs --echo # --echo # Bug mdev-463: assertion failure when running ANALYZE with RBR on --echo # diff --git a/mysql-test/suite/binlog/r/binlog_stm_binlog.result b/mysql-test/suite/binlog/r/binlog_stm_binlog.result index 5016ed70242..69d7191e0ac 100644 --- a/mysql-test/suite/binlog/r/binlog_stm_binlog.result +++ b/mysql-test/suite/binlog/r/binlog_stm_binlog.result @@ -1,3 +1,4 @@ +reset master; drop table if exists t1; create table t1 (a int, b int) engine=innodb; begin; diff --git a/mysql-test/suite/binlog/r/binlog_stm_datetime_ranges_mdev15289.result b/mysql-test/suite/binlog/r/binlog_stm_datetime_ranges_mdev15289.result index 0c3e72133b8..ade3e8acf10 100644 --- a/mysql-test/suite/binlog/r/binlog_stm_datetime_ranges_mdev15289.result +++ b/mysql-test/suite/binlog/r/binlog_stm_datetime_ranges_mdev15289.result @@ -1,3 +1,4 @@ +reset master; include/show_binlog_events.inc Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # GTID #-#-# diff --git a/mysql-test/suite/binlog/r/binlog_stm_do_db.result b/mysql-test/suite/binlog/r/binlog_stm_do_db.result index 3d23594135d..c39404aef55 100644 --- a/mysql-test/suite/binlog/r/binlog_stm_do_db.result +++ b/mysql-test/suite/binlog/r/binlog_stm_do_db.result @@ -1,3 +1,4 @@ +RESET MASTER; SET @old_isolation_level= @@session.tx_isolation; SET @@session.tx_isolation= 'READ-COMMITTED'; CREATE DATABASE b42829; diff --git a/mysql-test/suite/binlog/r/innodb_autoinc_lock_mode_binlog.result b/mysql-test/suite/binlog/r/innodb_autoinc_lock_mode_binlog.result index d0132931968..021b5b9af43 100644 --- a/mysql-test/suite/binlog/r/innodb_autoinc_lock_mode_binlog.result +++ b/mysql-test/suite/binlog/r/innodb_autoinc_lock_mode_binlog.result @@ -1,3 +1,4 @@ +reset master; call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); select @@innodb_autoinc_lock_mode; @@innodb_autoinc_lock_mode diff --git a/mysql-test/suite/binlog/t/binlog_stm_binlog.test b/mysql-test/suite/binlog/t/binlog_stm_binlog.test index c3d8066f807..cd4be69712d 100644 --- a/mysql-test/suite/binlog/t/binlog_stm_binlog.test +++ b/mysql-test/suite/binlog/t/binlog_stm_binlog.test @@ -2,7 +2,7 @@ -- source include/have_binlog_format_mixed.inc let collation=utf8_unicode_ci; --source include/have_collation.inc - +reset master; # clear up binlogs --disable_warnings drop table if exists t1; --enable_warnings diff --git a/mysql-test/suite/binlog/t/binlog_stm_datetime_ranges_mdev15289.test b/mysql-test/suite/binlog/t/binlog_stm_datetime_ranges_mdev15289.test index ae4cab62fec..d277db979fb 100644 --- a/mysql-test/suite/binlog/t/binlog_stm_datetime_ranges_mdev15289.test +++ b/mysql-test/suite/binlog/t/binlog_stm_datetime_ranges_mdev15289.test @@ -1,6 +1,6 @@ --source include/not_embedded.inc --source include/have_binlog_format_statement.inc - +reset master; # clear up binlogs --exec $MYSQL_CLIENT_TEST test_datetime_ranges_mdev15289 > $MYSQLTEST_VARDIR/log/binlog_stm_datetime_ranges_mysql_client_test.out.log 2>&1 --let $binlog_file = LAST diff --git a/mysql-test/suite/binlog/t/binlog_stm_do_db.test b/mysql-test/suite/binlog/t/binlog_stm_do_db.test index 991fdef1bea..3ed1734f18d 100644 --- a/mysql-test/suite/binlog/t/binlog_stm_do_db.test +++ b/mysql-test/suite/binlog/t/binlog_stm_do_db.test @@ -37,7 +37,7 @@ -- source include/have_log_bin.inc -- source include/have_innodb.inc -- source include/have_binlog_format_statement.inc - +RESET MASTER; # clear up binlogs SET @old_isolation_level= @@session.tx_isolation; SET @@session.tx_isolation= 'READ-COMMITTED'; diff --git a/mysql-test/suite/binlog/t/innodb_autoinc_lock_mode_binlog.test b/mysql-test/suite/binlog/t/innodb_autoinc_lock_mode_binlog.test index a7d43db4c1b..283862ec3be 100644 --- a/mysql-test/suite/binlog/t/innodb_autoinc_lock_mode_binlog.test +++ b/mysql-test/suite/binlog/t/innodb_autoinc_lock_mode_binlog.test @@ -1,6 +1,6 @@ --source include/have_innodb.inc --source include/have_binlog_format_mixed.inc - +reset master; #clear up binlogs call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); select @@innodb_autoinc_lock_mode; -- cgit v1.2.1 From 0235a528e3c2cf8c3197e4817596c9fa1947d2b8 Mon Sep 17 00:00:00 2001 From: Vlad Lesin Date: Thu, 3 Nov 2022 10:00:03 +0300 Subject: MDEV-10087 mysqld_update()/mysql_delete() continues execution even after subquery with JOIN gets error from storage engine The issue is that record_should_be_deleted() returns true in mysql_delete() even if sub-select with join gets error from storage engine when DELETE FROM ... WHERE ... IN (SELECT ...) statement is executed. The same is true for mysql_update() where select->skip_record() returns true even if sub-select with join gets error from storage engine. In the test case if sub-select is chosen as deadlock victim the whole transaction is rolled back during sub-select execution, but mysql_delete()/mysql_update() continues transaction execution and invokes table->delete_row() as record_should_be_deleted() wrongly returns true in mysql_delete() and table->update_row() as select->skip_record(thd) wrongly returns 1 for mysql_update(). record_should_be_deleted() wrogly returns true because thd->is_error() returns false SQL_SELECT::skip_record() invoked from record_should_be_deleted(). It's supposed that THD error should be set in rr_handle_error() called from rr_sequential() during sub-select JOIN::exec_inner() execution. But rr_handle_error() does not set THD error because READ_RECORD::print_error is not set in JOIN_TAB::read_record. READ_RECORD::print_error should be initialized in init_read_record()/init_read_record_idx(). But make_join_readinfo() does not invoke init_read_record()/init_read_record_idx() for JOIN_TAB::read_record. The fix is to set JOIN_TAB::read_record.print_error in make_join_readinfo(), i.e. in the same place where JOIN_TAB::read_record.table is set. Reviewed by Sergey Petrunya. --- .../innodb/r/deadlock_in_subqueries_join.result | 50 +++++++++++++ .../innodb/t/deadlock_in_subqueries_join.test | 81 ++++++++++++++++++++++ sql/sql_select.cc | 1 + 3 files changed, 132 insertions(+) create mode 100644 mysql-test/suite/innodb/r/deadlock_in_subqueries_join.result create mode 100644 mysql-test/suite/innodb/t/deadlock_in_subqueries_join.test diff --git a/mysql-test/suite/innodb/r/deadlock_in_subqueries_join.result b/mysql-test/suite/innodb/r/deadlock_in_subqueries_join.result new file mode 100644 index 00000000000..2e82b0662f8 --- /dev/null +++ b/mysql-test/suite/innodb/r/deadlock_in_subqueries_join.result @@ -0,0 +1,50 @@ +CREATE TABLE t1 ( +pkey int NOT NULL PRIMARY KEY, +c int +) ENGINE=InnoDB; +INSERT INTO t1 VALUES(1,1); +CREATE TABLE t2 ( +pkey int NOT NULL PRIMARY KEY, +c int +) ENGINE=InnoDB DEFAULT CHARSET=latin1; +INSERT INTO t2 VALUES (2, NULL); +CREATE TABLE t3 (c int) engine = InnoDB; +INSERT INTO t3 VALUES (10), (20), (30), (40), (50); +connect con1, localhost,root,,; +connection default; +START TRANSACTION; +UPDATE t3 SET c=c+1000; +SELECT * FROM t1 FOR UPDATE; +pkey c +1 1 +connection con1; +START TRANSACTION; +DELETE FROM t2 WHERE c NOT IN (SELECT ref_0.pkey FROM t1 AS ref_0 INNER JOIN t1 AS ref_1 ON ref_0.c = ref_0.pkey); +connection default; +SELECT * FROM t2 FOR UPDATE; +pkey c +2 NULL +COMMIT; +connection con1; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +COMMIT; +connection default; +START TRANSACTION; +UPDATE t3 SET c=c+1000; +SELECT * FROM t1 FOR UPDATE; +pkey c +1 1 +connection con1; +START TRANSACTION; +UPDATE t2 SET pkey=pkey+10 WHERE c NOT IN (SELECT ref_0.pkey FROM t1 AS ref_0 INNER JOIN t1 AS ref_1 ON ref_0.c = ref_0.pkey); +connection default; +SELECT * FROM t2 FOR UPDATE; +pkey c +2 NULL +COMMIT; +connection con1; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +COMMIT; +disconnect con1; +connection default; +DROP TABLE t1,t2,t3; diff --git a/mysql-test/suite/innodb/t/deadlock_in_subqueries_join.test b/mysql-test/suite/innodb/t/deadlock_in_subqueries_join.test new file mode 100644 index 00000000000..b3adfb3b02d --- /dev/null +++ b/mysql-test/suite/innodb/t/deadlock_in_subqueries_join.test @@ -0,0 +1,81 @@ +--source include/have_innodb.inc +--source include/count_sessions.inc + +CREATE TABLE t1 ( + pkey int NOT NULL PRIMARY KEY, + c int +) ENGINE=InnoDB; + +INSERT INTO t1 VALUES(1,1); + +CREATE TABLE t2 ( + pkey int NOT NULL PRIMARY KEY, + c int +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + +INSERT INTO t2 VALUES (2, NULL); + +# The following table is to increase tansaction weight on deadlock resolution +CREATE TABLE t3 (c int) engine = InnoDB; +INSERT INTO t3 VALUES (10), (20), (30), (40), (50); + +--let $i= 2 +--let $delete= 2 +--let $update= 1 +--connect(con1, localhost,root,,) + +while($i) { +--connection default +START TRANSACTION; # trx 1 +# The following update is necessary to increase the transaction weight, which is +# calculated as the number of locks + the number of undo records during deadlock +# report. Victim's transaction should have minimum weight. We need trx 2 to be +# choosen as victim, that's why we need to increase the current transaction +# weight. +UPDATE t3 SET c=c+1000; +SELECT * FROM t1 FOR UPDATE; + +--connection con1 +START TRANSACTION; # trx 2 +# 1) read record from t2, lock it +# 2) check if the read record should be deleted, i.e. read record from t1, +# as the record from t1 is locked by trx 1, the subselect will be suspended. +# see 'while' loop in mysql_delete() or mysql_update() and +# select->skip_record(thd) call for details. +if ($i == $delete) { +--send DELETE FROM t2 WHERE c NOT IN (SELECT ref_0.pkey FROM t1 AS ref_0 INNER JOIN t1 AS ref_1 ON ref_0.c = ref_0.pkey) +} +if ($i == $update) { +--send UPDATE t2 SET pkey=pkey+10 WHERE c NOT IN (SELECT ref_0.pkey FROM t1 AS ref_0 INNER JOIN t1 AS ref_1 ON ref_0.c = ref_0.pkey) +} + +--connection default +let $wait_condition= + SELECT count(*) = 1 FROM information_schema.processlist + WHERE (state = 'Sending data' OR state = "Updating") + AND (info LIKE 'delete from t2 where%' OR + info LIKE 'UPDATE t2 SET pkey=pkey+10 WHERE%'); +--source include/wait_condition.inc + +# The record from t2 is locked by the previous delete, so trx 2 is waiting for +# trx 1, and trx 1 will be blocked by trx 2 with the following SELECT. So we +# have deadlock here. And trx 2 is chosen as deadlock victim as trx 1 has +# greater weight. +SELECT * FROM t2 FOR UPDATE; +COMMIT; + +--connection con1 +# If the bug is not fixed, there will be assertion failure as +# mysql_delete()/mysql_update() will continue execution despite its subselect +# got deadlock error +--error ER_LOCK_DEADLOCK +--reap +COMMIT; +--dec $i +} + +--disconnect con1 + +--connection default +DROP TABLE t1,t2,t3; +--source include/wait_until_count_sessions.inc diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 0b330528452..a85dc71e9e4 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -12509,6 +12509,7 @@ make_join_readinfo(JOIN *join, ulonglong options, uint no_jbuf_after) uint jcl= tab->used_join_cache_level; tab->read_record.table= table; tab->read_record.unlock_row= rr_unlock_row; + tab->read_record.print_error= true; tab->sorted= sorted; sorted= 0; // only first must be sorted -- cgit v1.2.1 From dc6a0171110741d633cef7877013d8e29d5e6def Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Mon, 7 Nov 2022 15:58:40 +1100 Subject: MDEV-27882 Innodb - recognise MySQL-8.0 innodb flags and give a specific error message MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Per fsp0types.h, SDI is on tablespace flags position 14 where MariaDB stores its pagesize. Flag at position 13, also in MariaDB pagesize flags, is a MySQL encryption flag. These are checked only if fsp_flags_is_valid fails, so valid MariaDB pages sizes don't become errors. The error message "Cannot reset LSNs in table" was rather specific and not always true to replaced with more generic error. ALTER TABLE tbl IMPORT TABLESPACE now reports Unsupported on MySQL tablespace (rather than index corrupted) along with a server error message. MySQL innodb Errors are with with UNSUPPORTED rather than CORRUPTED to avoid user anxiety. Reviewer: Marko Mäkelä --- mysql-test/std_data/mysql80/ibdata1_16384 | Bin 0 -> 16384 bytes mysql-test/std_data/mysql80/ibdata1_32768 | Bin 0 -> 32768 bytes mysql-test/std_data/mysql80/ibdata1_4096 | Bin 0 -> 4096 bytes mysql-test/std_data/mysql80/ibdata1_65536 | Bin 0 -> 65536 bytes mysql-test/std_data/mysql80/ibdata1_8192 | Bin 0 -> 8192 bytes mysql-test/std_data/mysql80/t1.ibd | Bin 0 -> 16384 bytes .../encryption/r/encryption_key_corruption.result | 2 +- .../r/default_row_format_compatibility.result | 2 +- mysql-test/suite/innodb/r/innodb-wl5522-1.result | 16 ++++++ .../suite/innodb/r/innodb-wl5522-debug.result | 8 +-- mysql-test/suite/innodb/r/restart.result | 10 +++- mysql-test/suite/innodb/t/innodb-wl5522-1.test | 31 ++++++++++ mysql-test/suite/innodb/t/restart.test | 63 ++++++++++++++++++++- .../suite/innodb_zip/r/wl5522_debug_zip.result | 8 +-- storage/innobase/fsp/fsp0file.cc | 22 +++++-- storage/innobase/include/fsp0fsp.h | 14 +++++ storage/innobase/row/row0import.cc | 15 +++-- 17 files changed, 170 insertions(+), 21 deletions(-) create mode 100644 mysql-test/std_data/mysql80/ibdata1_16384 create mode 100644 mysql-test/std_data/mysql80/ibdata1_32768 create mode 100644 mysql-test/std_data/mysql80/ibdata1_4096 create mode 100644 mysql-test/std_data/mysql80/ibdata1_65536 create mode 100644 mysql-test/std_data/mysql80/ibdata1_8192 create mode 100644 mysql-test/std_data/mysql80/t1.ibd diff --git a/mysql-test/std_data/mysql80/ibdata1_16384 b/mysql-test/std_data/mysql80/ibdata1_16384 new file mode 100644 index 00000000000..7eeea4fdaf1 Binary files /dev/null and b/mysql-test/std_data/mysql80/ibdata1_16384 differ diff --git a/mysql-test/std_data/mysql80/ibdata1_32768 b/mysql-test/std_data/mysql80/ibdata1_32768 new file mode 100644 index 00000000000..ebcaef08d39 Binary files /dev/null and b/mysql-test/std_data/mysql80/ibdata1_32768 differ diff --git a/mysql-test/std_data/mysql80/ibdata1_4096 b/mysql-test/std_data/mysql80/ibdata1_4096 new file mode 100644 index 00000000000..67834106f48 Binary files /dev/null and b/mysql-test/std_data/mysql80/ibdata1_4096 differ diff --git a/mysql-test/std_data/mysql80/ibdata1_65536 b/mysql-test/std_data/mysql80/ibdata1_65536 new file mode 100644 index 00000000000..3d3d3043b4c Binary files /dev/null and b/mysql-test/std_data/mysql80/ibdata1_65536 differ diff --git a/mysql-test/std_data/mysql80/ibdata1_8192 b/mysql-test/std_data/mysql80/ibdata1_8192 new file mode 100644 index 00000000000..5082eff5ee2 Binary files /dev/null and b/mysql-test/std_data/mysql80/ibdata1_8192 differ diff --git a/mysql-test/std_data/mysql80/t1.ibd b/mysql-test/std_data/mysql80/t1.ibd new file mode 100644 index 00000000000..5cfd9b54496 Binary files /dev/null and b/mysql-test/std_data/mysql80/t1.ibd differ diff --git a/mysql-test/suite/encryption/r/encryption_key_corruption.result b/mysql-test/suite/encryption/r/encryption_key_corruption.result index f467207d0f7..349b530b474 100644 --- a/mysql-test/suite/encryption/r/encryption_key_corruption.result +++ b/mysql-test/suite/encryption/r/encryption_key_corruption.result @@ -9,5 +9,5 @@ DROP TABLE src; CREATE TABLE dst (pk INT PRIMARY KEY, value INT) ENGINE=INNODB; ALTER TABLE dst DISCARD TABLESPACE; ALTER TABLE dst IMPORT TABLESPACE; -ERROR HY000: Internal error: Cannot reset LSNs in table `test`.`dst` : Data structure corruption +ERROR HY000: Internal error: Error importing tablespace for table `test`.`dst` : Data structure corruption DROP TABLE dst; diff --git a/mysql-test/suite/innodb/r/default_row_format_compatibility.result b/mysql-test/suite/innodb/r/default_row_format_compatibility.result index 5070fa33a2e..00cddd4c370 100644 --- a/mysql-test/suite/innodb/r/default_row_format_compatibility.result +++ b/mysql-test/suite/innodb/r/default_row_format_compatibility.result @@ -38,7 +38,7 @@ tab InnoDB # Compact # # # # # # NULL # NULL NULL latin1_swedish_ci NULL 0 N ALTER TABLE tab DISCARD TABLESPACE; call mtr.add_suppression("InnoDB: Tried to read .* bytes at offset 0"); ALTER TABLE tab IMPORT TABLESPACE; -ERROR HY000: Internal error: Cannot reset LSNs in table `test`.`tab` : I/O error +ERROR HY000: Internal error: Error importing tablespace for table `test`.`tab` : I/O error ALTER TABLE tab IMPORT TABLESPACE; SELECT * FROM tab; a diff --git a/mysql-test/suite/innodb/r/innodb-wl5522-1.result b/mysql-test/suite/innodb/r/innodb-wl5522-1.result index 55557a8fb99..0f7ef6b2865 100644 --- a/mysql-test/suite/innodb/r/innodb-wl5522-1.result +++ b/mysql-test/suite/innodb/r/innodb-wl5522-1.result @@ -795,3 +795,19 @@ DROP DATABASE testdb_wl5522; call mtr.add_suppression("Got error -1 when reading table '.*'"); call mtr.add_suppression("InnoDB: Error: tablespace id and flags in file '.*'.*"); call mtr.add_suppression("InnoDB: The table .* doesn't have a corresponding tablespace, it was discarded"); +# +# MDEV-27882 Innodb - recognise MySQL-8.0 innodb flags and give a specific error message +# +# +CREATE TABLE `t1` (`i` int(11) NOT NULL, PRIMARY KEY (`i`) ) ENGINE=InnoDB; +FLUSH TABLES t1 FOR EXPORT; +backup: t1 +UNLOCK TABLES; +ALTER TABLE t1 DISCARD TABLESPACE; +call mtr.add_suppression("InnoDB: unsupported MySQL tablespace"); +ALTER TABLE t1 IMPORT TABLESPACE; +ERROR HY000: Internal error: Error importing tablespace for table `test`.`t1` : Unsupported +DROP TABLE t1; +# +# End of 10.3 tests +# diff --git a/mysql-test/suite/innodb/r/innodb-wl5522-debug.result b/mysql-test/suite/innodb/r/innodb-wl5522-debug.result index 9415d3c119a..f2209f9ca91 100644 --- a/mysql-test/suite/innodb/r/innodb-wl5522-debug.result +++ b/mysql-test/suite/innodb/r/innodb-wl5522-debug.result @@ -448,7 +448,7 @@ ERROR HY000: Tablespace has been discarded for table `t1` restore: t1 .ibd and .cfg files SET SESSION debug_dbug="+d,ib_import_reset_space_and_lsn_failure"; ALTER TABLE t1 IMPORT TABLESPACE; -ERROR HY000: Internal error: Cannot reset LSNs in table `test`.`t1` : Too many concurrent transactions +ERROR HY000: Internal error: Error importing tablespace for table `test`.`t1` : Too many concurrent transactions restore: t1 .ibd and .cfg files SET SESSION debug_dbug=@saved_debug_dbug; SET SESSION debug_dbug="+d,ib_import_open_tablespace_failure"; @@ -873,7 +873,7 @@ ERROR HY000: Tablespace has been discarded for table `t1` restore: t1 .ibd and .cfg files SET SESSION debug_dbug="+d,ib_import_trigger_corruption_1"; ALTER TABLE t1 IMPORT TABLESPACE; -ERROR HY000: Internal error: Cannot reset LSNs in table `test`.`t1` : Data structure corruption +ERROR HY000: Internal error: Error importing tablespace for table `test`.`t1` : Data structure corruption SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE t1; unlink: t1.ibd @@ -885,7 +885,7 @@ ERROR HY000: Tablespace has been discarded for table `t1` restore: t1 .ibd and .cfg files SET SESSION debug_dbug="+d,buf_page_import_corrupt_failure"; ALTER TABLE t1 IMPORT TABLESPACE; -ERROR HY000: Internal error: Cannot reset LSNs in table `test`.`t1` : Data structure corruption +ERROR HY000: Internal error: Error importing tablespace for table `test`.`t1` : Data structure corruption SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE t1; unlink: t1.ibd @@ -957,7 +957,7 @@ ERROR HY000: Tablespace has been discarded for table `t1` restore: t1 .ibd and .cfg files SET SESSION debug_dbug="+d,fsp_flags_is_valid_failure"; ALTER TABLE t1 IMPORT TABLESPACE; -ERROR HY000: Internal error: Cannot reset LSNs in table `test`.`t1` : Data structure corruption +ERROR HY000: Internal error: Error importing tablespace for table `test`.`t1` : Data structure corruption SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE t1; unlink: t1.ibd diff --git a/mysql-test/suite/innodb/r/restart.result b/mysql-test/suite/innodb/r/restart.result index 606e94d81db..ee2450a9270 100644 --- a/mysql-test/suite/innodb/r/restart.result +++ b/mysql-test/suite/innodb/r/restart.result @@ -3,7 +3,8 @@ # # FIXME: Unlike MySQL, maybe MariaDB should not read the .ibd files # of tables with .isl file or DATA DIRECTORY attribute. -call mtr.add_suppression("\\[ERROR\\] InnoDB: Invalid flags 0x7a207879 in .*td\\.ibd"); +call mtr.add_suppression("\\[ERROR\\] InnoDB: MySQL-8\\.0 tablespace in "); +call mtr.add_suppression("\\[ERROR\\] InnoDB: Restart in MySQL for migration/recovery\\."); # FIXME: This is much more noisy than MariaDB 10.1! call mtr.add_suppression("\\[ERROR\\] InnoDB: Operating system error number .* in a file operation\\."); call mtr.add_suppression("\\[ERROR\\] InnoDB: The error means the system cannot find the path specified\\."); @@ -39,3 +40,10 @@ Warning 1210 innodb_buffer_pool_size must be at least MIN_VAL for innodb_page_si Error 1231 Variable 'innodb_buffer_pool_size' can't be set to the value of 'WRONG_VALUE' EXECUTE IMMEDIATE 'SET GLOBAL innodb_buffer_pool_size = ?' USING (@min_pool_size); SET GLOBAL innodb_buffer_pool_size = @innodb_buffer_pool_size_orig; +# +# MDEV-27882 Innodb - recognise MySQL-8.0 innodb flags and give a specific error message +# +FOUND 1 /InnoDB: MySQL-8\.0 tablespace in \./ibdata1/ in attempted_start.err +# +# End of 10.3 tests +# diff --git a/mysql-test/suite/innodb/t/innodb-wl5522-1.test b/mysql-test/suite/innodb/t/innodb-wl5522-1.test index 0d59df11c44..bccf670a1c9 100644 --- a/mysql-test/suite/innodb/t/innodb-wl5522-1.test +++ b/mysql-test/suite/innodb/t/innodb-wl5522-1.test @@ -932,3 +932,34 @@ call mtr.add_suppression("InnoDB: The table .* doesn't have a corresponding tabl --remove_file $MYSQLTEST_VARDIR/tmp/t1.ibd --remove_file $MYSQLTEST_VARDIR/tmp/t1_fk.cfg --remove_file $MYSQLTEST_VARDIR/tmp/t1_fk.ibd + +--echo # +--echo # MDEV-27882 Innodb - recognise MySQL-8.0 innodb flags and give a specific error message +--echo # +--echo # + +CREATE TABLE `t1` (`i` int(11) NOT NULL, PRIMARY KEY (`i`) ) ENGINE=InnoDB; +FLUSH TABLES t1 FOR EXPORT; + +# We use the cfg file of ours. +perl; +do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +ib_backup_tablespaces("test", "t1"); +EOF + +UNLOCK TABLES; +ALTER TABLE t1 DISCARD TABLESPACE; + +--move_file $MYSQLTEST_VARDIR/tmp/t1.cfg $MYSQLD_DATADIR/test/t1.cfg +--copy_file std_data/mysql80/t1.ibd $MYSQLD_DATADIR/test/t1.ibd + +call mtr.add_suppression("InnoDB: unsupported MySQL tablespace"); +--error ER_INTERNAL_ERROR +ALTER TABLE t1 IMPORT TABLESPACE; + +DROP TABLE t1; +--remove_file $MYSQLTEST_VARDIR/tmp/t1.ibd + +--echo # +--echo # End of 10.3 tests +--echo # diff --git a/mysql-test/suite/innodb/t/restart.test b/mysql-test/suite/innodb/t/restart.test index 16c6d20f621..eecb62ad464 100644 --- a/mysql-test/suite/innodb/t/restart.test +++ b/mysql-test/suite/innodb/t/restart.test @@ -15,7 +15,9 @@ let page_size= `select @@innodb_page_size`; --echo # FIXME: Unlike MySQL, maybe MariaDB should not read the .ibd files --echo # of tables with .isl file or DATA DIRECTORY attribute. -call mtr.add_suppression("\\[ERROR\\] InnoDB: Invalid flags 0x7a207879 in .*td\\.ibd"); +call mtr.add_suppression("\\[ERROR\\] InnoDB: MySQL-8\\.0 tablespace in "); +call mtr.add_suppression("\\[ERROR\\] InnoDB: Restart in MySQL for migration/recovery\\."); + --echo # FIXME: This is much more noisy than MariaDB 10.1! call mtr.add_suppression("\\[ERROR\\] InnoDB: Operating system error number .* in a file operation\\."); call mtr.add_suppression("\\[ERROR\\] InnoDB: The error means the system cannot find the path specified\\."); @@ -47,7 +49,7 @@ die unless open OUT, ">", "$ENV{datadir}/test/tc.ibd"; print OUT "bar " x $ENV{page_size}; close OUT or die; die unless open OUT, ">", "$ENV{MYSQL_TMP_DIR}/test/td.ibd"; -print OUT "xyz " x $ENV{page_size}; +print OUT "Xyz " x $ENV{page_size}; close OUT or die; EOF @@ -101,3 +103,60 @@ EXECUTE IMMEDIATE 'SET GLOBAL innodb_buffer_pool_size = ?' USING (@min_pool_size --source include/wait_condition.inc SET GLOBAL innodb_buffer_pool_size = @innodb_buffer_pool_size_orig; + +--echo # +--echo # MDEV-27882 Innodb - recognise MySQL-8.0 innodb flags and give a specific error message +--echo # + +--let MYSQLD_DATADIR= `SELECT @@datadir` +--let SERVER_ID= `SELECT @@server_id` +--let EXPECT_FILE_NAME= $MYSQLTEST_VARDIR/tmp/mysqld.$SERVER_ID.expect + +--source include/shutdown_mysqld.inc + +--move_file $MYSQLD_DATADIR/ibdata1 $MYSQLD_DATADIR/ibdata1.bak +--copy_file std_data/mysql80/ibdata1_$page_size $MYSQLD_DATADIR/ibdata1 + +perl; +use IO::Handle; +my $size = 9 * 1048576; +if ($ENV{MTR_COMBINATION_32K}) { + $size *= 2; +} +if ($ENV{MTR_COMBINATION_64K}) { + $size *= 4; +} +$size -= $ENV{page_size}; +die unless open(FILE, ">>", "$ENV{MYSQLD_DATADIR}/ibdata1"); +binmode FILE; + +print FILE chr(0) x $size; +close(FILE); +EOF + +--let ibdata_size='9M' +if ($MTR_COMBINATION_32K) +{ +--let ibdata_size='18M' +} +if ($MTR_COMBINATION_64K) +{ +--let ibdata_size='36M' +} + +--error 1 +exec $MYSQLD --no-defaults --skip-networking --innodb_data_file_path=ibdata1:$ibdata_size --innodb-page-size=$page_size --datadir=$MYSQLD_DATADIR --log-error=$MYSQL_TMP_DIR/attempted_start.err; + +let SEARCH_FILE= $MYSQL_TMP_DIR/attempted_start.err; +let SEARCH_PATTERN= InnoDB: MySQL-8\.0 tablespace in \./ibdata1; +source include/search_pattern_in_file.inc; + +--remove_file $MYSQL_TMP_DIR/attempted_start.err +--remove_file $MYSQLD_DATADIR/ibdata1 +--move_file $MYSQLD_DATADIR/ibdata1.bak $MYSQLD_DATADIR/ibdata1 + +--source include/start_mysqld.inc + +--echo # +--echo # End of 10.3 tests +--echo # diff --git a/mysql-test/suite/innodb_zip/r/wl5522_debug_zip.result b/mysql-test/suite/innodb_zip/r/wl5522_debug_zip.result index bce37b6bdc0..42ccc70cd5b 100644 --- a/mysql-test/suite/innodb_zip/r/wl5522_debug_zip.result +++ b/mysql-test/suite/innodb_zip/r/wl5522_debug_zip.result @@ -78,7 +78,7 @@ ERROR HY000: Tablespace has been discarded for table `t1` restore: t1 .ibd and .cfg files SET SESSION debug_dbug="+d,ib_import_reset_space_and_lsn_failure"; ALTER TABLE t1 IMPORT TABLESPACE; -ERROR HY000: Internal error: Cannot reset LSNs in table `test`.`t1` : Too many concurrent transactions +ERROR HY000: Internal error: Error importing tablespace for table `test`.`t1` : Too many concurrent transactions restore: t1 .ibd and .cfg files SET SESSION debug_dbug=@saved_debug_dbug; SET SESSION debug_dbug="+d,ib_import_open_tablespace_failure"; @@ -322,7 +322,7 @@ ERROR HY000: Tablespace has been discarded for table `t1` restore: t1 .ibd and .cfg files SET SESSION debug_dbug="+d,ib_import_trigger_corruption_1"; ALTER TABLE t1 IMPORT TABLESPACE; -ERROR HY000: Internal error: Cannot reset LSNs in table `test`.`t1` : Data structure corruption +ERROR HY000: Internal error: Error importing tablespace for table `test`.`t1` : Data structure corruption SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE t1; unlink: t1.ibd @@ -335,7 +335,7 @@ ERROR HY000: Tablespace has been discarded for table `t1` restore: t1 .ibd and .cfg files SET SESSION debug_dbug="+d,buf_page_import_corrupt_failure"; ALTER TABLE t1 IMPORT TABLESPACE; -ERROR HY000: Internal error: Cannot reset LSNs in table `test`.`t1` : Data structure corruption +ERROR HY000: Internal error: Error importing tablespace for table `test`.`t1` : Data structure corruption SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE t1; unlink: t1.ibd @@ -413,7 +413,7 @@ ERROR HY000: Tablespace has been discarded for table `t1` restore: t1 .ibd and .cfg files SET SESSION debug_dbug="+d,fsp_flags_is_valid_failure"; ALTER TABLE t1 IMPORT TABLESPACE; -ERROR HY000: Internal error: Cannot reset LSNs in table `test`.`t1` : Data structure corruption +ERROR HY000: Internal error: Error importing tablespace for table `test`.`t1` : Data structure corruption SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE t1; unlink: t1.ibd diff --git a/storage/innobase/fsp/fsp0file.cc b/storage/innobase/fsp/fsp0file.cc index 90ddca77549..a320b16d636 100644 --- a/storage/innobase/fsp/fsp0file.cc +++ b/storage/innobase/fsp/fsp0file.cc @@ -29,6 +29,7 @@ Created 2013-7-26 by Kevin Lewis #include "os0file.h" #include "page0page.h" #include "srv0start.h" +#include "log.h" /** Initialize the name, size and order of this datafile @param[in] name tablespace name, will be copied @@ -346,10 +347,23 @@ Datafile::read_first_page(bool read_only_mode) if (!fsp_flags_is_valid(m_flags, m_space_id)) { ulint cflags = fsp_flags_convert_from_101(m_flags); if (cflags == ULINT_UNDEFINED) { - ib::error() - << "Invalid flags " << ib::hex(m_flags) - << " in " << m_filepath; - return(DB_CORRUPTION); + switch (fsp_flags_is_incompatible_mysql(m_flags)) { + case 0: + sql_print_error("InnoDB: Invalid flags 0x%zx in %s", + m_flags, m_filepath); + return(DB_CORRUPTION); + case 3: + case 2: + sql_print_error("InnoDB: MySQL-8.0 tablespace in %s", + m_filepath); + break; + case 1: + sql_print_error("InnoDB: MySQL Encrypted tablespace in %s", + m_filepath); + break; + } + sql_print_error("InnoDB: Restart in MySQL for migration/recovery."); + return(DB_UNSUPPORTED); } else { m_flags = cflags; } diff --git a/storage/innobase/include/fsp0fsp.h b/storage/innobase/include/fsp0fsp.h index eff1b4ab4ae..d8057e8e4bf 100644 --- a/storage/innobase/include/fsp0fsp.h +++ b/storage/innobase/include/fsp0fsp.h @@ -755,6 +755,20 @@ fsp_flags_match(ulint expected, ulint actual) return(actual == expected); } +/** Determine if FSP_SPACE_FLAGS are from an incompatible MySQL format. +@param flags the contents of FSP_SPACE_FLAGS +@return MySQL flags shifted. +@retval 0, if not a MySQL incompatible format. */ +MY_ATTRIBUTE((warn_unused_result, const)) +inline ulint fsp_flags_is_incompatible_mysql(ulint flags) +{ + /* + MySQL-8.0 SDI flag (bit 14), + or MySQL 5.7 Encyption flag (bit 13) + */ + return flags >> 13 & 3; +} + /** Calculates the descriptor index within a descriptor page. @param[in] page_size page size @param[in] offset page offset diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc index db4c22b4969..77d027e44d3 100644 --- a/storage/innobase/row/row0import.cc +++ b/storage/innobase/row/row0import.cc @@ -46,6 +46,7 @@ Created 2012-02-08 by Sunny Bains. #ifdef HAVE_SNAPPY #include "snappy-c.h" #endif +#include "log.h" #include @@ -571,9 +572,15 @@ AbstractCallback::init( if (!fsp_flags_is_valid(m_space_flags, true)) { ulint cflags = fsp_flags_convert_from_101(m_space_flags); if (cflags == ULINT_UNDEFINED) { - ib::error() << "Invalid FSP_SPACE_FLAGS=" - << ib::hex(m_space_flags); - return(DB_CORRUPTION); + switch (fsp_flags_is_incompatible_mysql(m_space_flags)) { + case 0: + sql_print_error("InnoDB: Invalid FSP_SPACE_FLAGS=0x%zx", + m_space_flags); + return(DB_CORRUPTION); + default: + sql_print_error("InnoDB: unsupported MySQL tablespace"); + return(DB_UNSUPPORTED); + } } m_space_flags = cflags; } @@ -4171,7 +4178,7 @@ row_import_for_mysql( ib_errf(trx->mysql_thd, IB_LOG_LEVEL_ERROR, ER_INTERNAL_ERROR, - "Cannot reset LSNs in table %s : %s", + "Error importing tablespace for table %s : %s", table_name, ut_strerr(err)); } -- cgit v1.2.1 From 043c1d183088c7179037bb562d1715848fdf9d7e Mon Sep 17 00:00:00 2001 From: Andrew Hutchings Date: Mon, 31 Oct 2022 17:02:58 +0000 Subject: MDEV-28489 CONNECT used incorrect CHAR length CONNECT engine was using dividing UTF8 columns by 3 to get the length, but in reality it did need the byte length. This fixes MDEV-26722 too. --- storage/connect/ha_connect.cc | 9 ++---- storage/connect/mysql-test/connect/r/mysql.result | 38 +++++++++++++++++++++++ storage/connect/mysql-test/connect/t/mysql.test | 30 ++++++++++++++++++ 3 files changed, 70 insertions(+), 7 deletions(-) diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc index 5af952afcd4..0071aed69c2 100644 --- a/storage/connect/ha_connect.cc +++ b/storage/connect/ha_connect.cc @@ -1618,14 +1618,9 @@ void *ha_connect::GetColumnOption(PGLOBAL g, void *field, PCOLINFO pcf) pcf->Scale= 0; pcf->Opt= (fop) ? (int)fop->opt : 0; - if (fp->field_length >= 0) { + if (fp->field_length >= 0) pcf->Length= fp->field_length; - - // length is bytes for Connect, not characters - if (!strnicmp(chset, "utf8", 4)) - pcf->Length /= 3; - - } else + else pcf->Length= 256; // BLOB? pcf->Precision= pcf->Length; diff --git a/storage/connect/mysql-test/connect/r/mysql.result b/storage/connect/mysql-test/connect/r/mysql.result index 918256ac395..d3c244b277a 100644 --- a/storage/connect/mysql-test/connect/r/mysql.result +++ b/storage/connect/mysql-test/connect/r/mysql.result @@ -326,5 +326,43 @@ id DROP TABLE t1; DROP TABLE t2; # +# MDEV-28489 / MDEV-26722 UTF8 bytes calculated incorrectly +# +CREATE TABLE t1 (name varchar(20)) CHARSET=utf8; +INSERT INTO t1 (name) VALUES ('Иванова'), ('Ivanova'); +CREATE TABLE t2 (name varchar(1)) ENGINE=CONNECT TABLE_TYPE=MYSQL DBNAME='test' TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=PORT' CHARSET=utf8; +SELECT hex(name) from t1; +hex(name) +C390CB9CC390C2B2C390C2B0C390C2BDC390C2BEC390C2B2C390C2B0 +4976616E6F7661 +SELECT hex(name) from t2; +hex(name) +C390 +49 +Warnings: +Warning 1105 Out of range value for column name at row 1 +Warning 1265 Data truncated for column 'name' at row 1 +Warning 1105 Out of range value Ð? for column 'name' at row 1 +Warning 1105 Out of range value for column name at row 2 +Warning 1265 Data truncated for column 'name' at row 2 +Warning 1105 Out of range value Iva for column 'name' at row 2 +DROP TABLE t2; +DROP TABLE t1; +CREATE TABLE t1 (col char(5)) CHARSET=utf8; +INSERT INTO t1 (col) VALUES ('glace'), ('glacé'); +Warnings: +Warning 1406 Data too long for column 'col' at row 2 +CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL DBNAME='test' TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=PORT' CHARSET=utf8; +SELECT hex(col) from t1; +hex(col) +676C616365 +676C6163C383 +SELECT hex(col) from t2; +hex(col) +676C616365 +676C6163C383 +DROP TABLE t2; +DROP TABLE t1; +# # End of 10.3 tests # diff --git a/storage/connect/mysql-test/connect/t/mysql.test b/storage/connect/mysql-test/connect/t/mysql.test index ce76a4665d5..a50db4a6457 100644 --- a/storage/connect/mysql-test/connect/t/mysql.test +++ b/storage/connect/mysql-test/connect/t/mysql.test @@ -503,6 +503,36 @@ SELECT `id` FROM t2 WHERE t2.`spaced col` = 'C-003'; DROP TABLE t1; DROP TABLE t2; +--echo # +--echo # MDEV-28489 / MDEV-26722 UTF8 bytes calculated incorrectly +--echo # + +CREATE TABLE t1 (name varchar(20)) CHARSET=utf8; +INSERT INTO t1 (name) VALUES ('Иванова'), ('Ivanova'); + +--replace_result $PORT PORT +--eval CREATE TABLE t2 (name varchar(1)) ENGINE=CONNECT TABLE_TYPE=MYSQL DBNAME='test' TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT' CHARSET=utf8 + +SELECT hex(name) from t1; +# This will warn as we are truncating data +SELECT hex(name) from t2; + +DROP TABLE t2; +DROP TABLE t1; + +CREATE TABLE t1 (col char(5)) CHARSET=utf8; +INSERT INTO t1 (col) VALUES ('glace'), ('glacé'); + +--replace_result $PORT PORT +--eval CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL DBNAME='test' TABNAME='t1' OPTION_LIST='host=localhost,user=root,port=$PORT' CHARSET=utf8 + +SELECT hex(col) from t1; +SELECT hex(col) from t2; + +DROP TABLE t2; +DROP TABLE t1; + + --echo # --echo # End of 10.3 tests --echo # -- cgit v1.2.1 From 1895c769c2c4170fa4d6f46f0014e98ea6295794 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 14 Nov 2022 16:22:11 +0200 Subject: Clean up file load.in in a test This fixes the following test invocation: ./mtr --no-reorder parts.partition_special_myisam parts.partition_debug This was broken ever since afd4b25d8a0ab1447d37033a377ee05a03314d44 a.k.a. mysql/mysql-server@bde21e58108a1f311d15088c50414bb43ab45d62 --- mysql-test/suite/parts/t/partition_special_myisam.test | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/suite/parts/t/partition_special_myisam.test b/mysql-test/suite/parts/t/partition_special_myisam.test index 5a573259373..b6f25484f3a 100644 --- a/mysql-test/suite/parts/t/partition_special_myisam.test +++ b/mysql-test/suite/parts/t/partition_special_myisam.test @@ -74,6 +74,7 @@ COMMIT; --connection con3 --reap +--remove_file $MYSQLD_DATADIR/test/load.in DROP TABLE t1; --disconnect con3 -- cgit v1.2.1 From df4c3d96a4aba0e5a9af3bd5158cd2049a978130 Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Thu, 10 Nov 2022 12:09:16 +0530 Subject: MDEV-29977 Memory leak in row_log_table_apply_update - InnoDB fails to free the persistent cursor for the clustered index when InnoDB replays the update operation on the table that is being rebuilt. --- .../suite/innodb/r/innodb-table-online.result | 20 ++++++++++++++++++-- mysql-test/suite/innodb/t/innodb-table-online.test | 21 +++++++++++++++++++-- storage/innobase/row/row0log.cc | 2 ++ 3 files changed, 39 insertions(+), 4 deletions(-) diff --git a/mysql-test/suite/innodb/r/innodb-table-online.result b/mysql-test/suite/innodb/r/innodb-table-online.result index ea56ea41c87..d54b79b5da7 100644 --- a/mysql-test/suite/innodb/r/innodb-table-online.result +++ b/mysql-test/suite/innodb/r/innodb-table-online.result @@ -459,10 +459,26 @@ SET DEBUG_SYNC = 'now WAIT_FOR created'; UPDATE t1 SET f = REPEAT('a', 20000); SET DEBUG_SYNC = 'now SIGNAL updated'; connection con1; -disconnect con1; connection default; DROP TABLE t1; -SET DEBUG_SYNC = 'RESET'; +# +# MDEV-29977 Memory leak in row_log_table_apply_update +# +CREATE TABLE t1(f1 longtext, f2 int, KEY(f1(1024)), KEY(f2, f1(20))) ENGINE=InnoDB; +INSERT INTO t1 VALUES('a', 1); +connection con1; +set DEBUG_SYNC="innodb_inplace_alter_table_enter SIGNAL con_default WAIT_FOR con1_signal"; +ALTER TABLE t1 FORCE; +connection default; +SET DEBUG_SYNC="now WAIT_FOR con_default"; +UPDATE t1 SET f1 = NULL; +UPDATE t1 SET f1 = REPEAT('b', 9000); +SET DEBUG_SYNC="now SIGNAL con1_signal"; +connection con1; +DROP TABLE t1; +connection default; +SET DEBUG_SYNC=RESET; +disconnect con1; SET GLOBAL innodb_file_per_table = @global_innodb_file_per_table_orig; SET GLOBAL innodb_monitor_enable = default; SET GLOBAL innodb_monitor_disable = default; diff --git a/mysql-test/suite/innodb/t/innodb-table-online.test b/mysql-test/suite/innodb/t/innodb-table-online.test index 997b0a5bf10..a89073db4f7 100644 --- a/mysql-test/suite/innodb/t/innodb-table-online.test +++ b/mysql-test/suite/innodb/t/innodb-table-online.test @@ -413,11 +413,28 @@ SET DEBUG_SYNC = 'now SIGNAL updated'; connection con1; reap; -disconnect con1; connection default; DROP TABLE t1; -SET DEBUG_SYNC = 'RESET'; +--echo # +--echo # MDEV-29977 Memory leak in row_log_table_apply_update +--echo # +CREATE TABLE t1(f1 longtext, f2 int, KEY(f1(1024)), KEY(f2, f1(20))) ENGINE=InnoDB; +INSERT INTO t1 VALUES('a', 1); +connection con1; +set DEBUG_SYNC="innodb_inplace_alter_table_enter SIGNAL con_default WAIT_FOR con1_signal"; +send ALTER TABLE t1 FORCE; +connection default; +SET DEBUG_SYNC="now WAIT_FOR con_default"; +UPDATE t1 SET f1 = NULL; +UPDATE t1 SET f1 = REPEAT('b', 9000); +SET DEBUG_SYNC="now SIGNAL con1_signal"; +connection con1; +reap; +DROP TABLE t1; +connection default; +SET DEBUG_SYNC=RESET; +disconnect con1; # Check that all connections opened by test cases in this file are really # gone so execution of other tests won't be affected by their presence. diff --git a/storage/innobase/row/row0log.cc b/storage/innobase/row/row0log.cc index aa001a84deb..eab53e0c87c 100644 --- a/storage/innobase/row/row0log.cc +++ b/storage/innobase/row/row0log.cc @@ -2364,6 +2364,8 @@ func_exit_committed: mtr_start(&mtr); index->set_modified(mtr); + ut_free(pcur.old_rec_buf); + if (ROW_FOUND != row_search_index_entry( index, entry, BTR_MODIFY_TREE, &pcur, &mtr)) { ut_ad(0); -- cgit v1.2.1 From 6216a2dfa2faabf8abfd3099a6cd46b00cef4115 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Thu, 17 Nov 2022 17:51:01 +0400 Subject: MDEV-29473 UBSAN: Signed integer overflow: X * Y cannot be represented in type 'int' in strings/dtoa.c Fixing a few problems relealed by UBSAN in type_float.test - multiplication overflow in dtoa.c - uninitialized Field::geom_type (and Field::srid as well) - Wrong call-back function types used in combination with SHOW_FUNC. Changes in the mysql_show_var_func data type definition were not properly addressed all around the code by the following commits: b4ff64568c88ab3ce559e7bd39853d9cbf86704a 18feb62feeb833494d003615861b9c78ec008a90 0ee879ff8ac1b80cd9a963015344f5698a81f309 Adding a helper SHOW_FUNC_ENTRY() function and replacing all mysql_show_var_func declarations using SHOW_FUNC to SHOW_FUNC_ENTRY, to catch mysql_show_var_func in the future at compilation time. --- include/myisampack.h | 2 +- include/mysql/plugin.h | 12 ++++++++++ include/mysql/plugin_audit.h.pp | 10 ++++++++ include/mysql/plugin_auth.h.pp | 10 ++++++++ include/mysql/plugin_encryption.h.pp | 10 ++++++++ include/mysql/plugin_ftparser.h.pp | 10 ++++++++ include/mysql/plugin_password_validation.h.pp | 10 ++++++++ mysql-test/main/type_float.result | 7 ++++++ mysql-test/main/type_float.test | 10 ++++++++ .../handler_socket/handlersocket/handlersocket.cpp | 6 +++-- sql/field.cc | 2 ++ sql/log.cc | 2 +- sql/mysqld.cc | 28 ++++++++++++---------- storage/innobase/handler/ha_innodb.cc | 6 +++-- storage/rocksdb/ha_rocksdb.cc | 21 ++++++++++------ storage/tokudb/hatoku_hton.cc | 6 +++-- strings/dtoa.c | 5 +++- 17 files changed, 128 insertions(+), 29 deletions(-) diff --git a/include/myisampack.h b/include/myisampack.h index 6bfe1958fbc..a7ba32b629c 100644 --- a/include/myisampack.h +++ b/include/myisampack.h @@ -30,7 +30,7 @@ #define mi_uint1korr(A) ((uint8)(*A)) #define mi_sint2korr(A) ((int16) (((int16) (((const uchar*) (A))[1])) |\ - ((int16) ((int16) ((const char*) (A))[0]) << 8))) + ((int16) ((uint16) ((const uchar*) (A))[0]) << 8))) #define mi_sint3korr(A) ((int32) (((((const uchar*) (A))[0]) & 128) ? \ (((uint32) 255L << 24) | \ (((uint32) ((const uchar*) (A))[0]) << 16) |\ diff --git a/include/mysql/plugin.h b/include/mysql/plugin.h index 360f633b7dd..b15f42fe6c7 100644 --- a/include/mysql/plugin.h +++ b/include/mysql/plugin.h @@ -200,6 +200,18 @@ struct system_status_var; typedef int (*mysql_show_var_func)(MYSQL_THD, struct st_mysql_show_var*, void *, struct system_status_var *status_var, enum enum_var_type); +static inline +struct st_mysql_show_var SHOW_FUNC_ENTRY(const char *name, + mysql_show_var_func func_arg) +{ + struct st_mysql_show_var tmp; + tmp.name= name; + tmp.value= (void*) func_arg; + tmp.type= SHOW_FUNC; + return tmp; +}; + + /* Constants for plugin flags. */ diff --git a/include/mysql/plugin_audit.h.pp b/include/mysql/plugin_audit.h.pp index 89f7dcc36c4..b8cafee28ec 100644 --- a/include/mysql/plugin_audit.h.pp +++ b/include/mysql/plugin_audit.h.pp @@ -400,6 +400,16 @@ struct st_mysql_show_var { }; struct system_status_var; typedef int (*mysql_show_var_func)(void*, struct st_mysql_show_var*, void *, struct system_status_var *status_var, enum enum_var_type); +static inline +struct st_mysql_show_var SHOW_FUNC_ENTRY(const char *name, + mysql_show_var_func func_arg) +{ + struct st_mysql_show_var tmp; + tmp.name= name; + tmp.value= (void*) func_arg; + tmp.type= SHOW_FUNC; + return tmp; +}; struct st_mysql_sys_var; struct st_mysql_value; typedef int (*mysql_var_check_func)(void* thd, diff --git a/include/mysql/plugin_auth.h.pp b/include/mysql/plugin_auth.h.pp index e515699cad6..68e2bcb9956 100644 --- a/include/mysql/plugin_auth.h.pp +++ b/include/mysql/plugin_auth.h.pp @@ -400,6 +400,16 @@ struct st_mysql_show_var { }; struct system_status_var; typedef int (*mysql_show_var_func)(void*, struct st_mysql_show_var*, void *, struct system_status_var *status_var, enum enum_var_type); +static inline +struct st_mysql_show_var SHOW_FUNC_ENTRY(const char *name, + mysql_show_var_func func_arg) +{ + struct st_mysql_show_var tmp; + tmp.name= name; + tmp.value= (void*) func_arg; + tmp.type= SHOW_FUNC; + return tmp; +}; struct st_mysql_sys_var; struct st_mysql_value; typedef int (*mysql_var_check_func)(void* thd, diff --git a/include/mysql/plugin_encryption.h.pp b/include/mysql/plugin_encryption.h.pp index 7defe0aec2c..838d0e49ed5 100644 --- a/include/mysql/plugin_encryption.h.pp +++ b/include/mysql/plugin_encryption.h.pp @@ -400,6 +400,16 @@ struct st_mysql_show_var { }; struct system_status_var; typedef int (*mysql_show_var_func)(void*, struct st_mysql_show_var*, void *, struct system_status_var *status_var, enum enum_var_type); +static inline +struct st_mysql_show_var SHOW_FUNC_ENTRY(const char *name, + mysql_show_var_func func_arg) +{ + struct st_mysql_show_var tmp; + tmp.name= name; + tmp.value= (void*) func_arg; + tmp.type= SHOW_FUNC; + return tmp; +}; struct st_mysql_sys_var; struct st_mysql_value; typedef int (*mysql_var_check_func)(void* thd, diff --git a/include/mysql/plugin_ftparser.h.pp b/include/mysql/plugin_ftparser.h.pp index a36f51e74e1..3c28bd3b2e0 100644 --- a/include/mysql/plugin_ftparser.h.pp +++ b/include/mysql/plugin_ftparser.h.pp @@ -400,6 +400,16 @@ struct st_mysql_show_var { }; struct system_status_var; typedef int (*mysql_show_var_func)(void*, struct st_mysql_show_var*, void *, struct system_status_var *status_var, enum enum_var_type); +static inline +struct st_mysql_show_var SHOW_FUNC_ENTRY(const char *name, + mysql_show_var_func func_arg) +{ + struct st_mysql_show_var tmp; + tmp.name= name; + tmp.value= (void*) func_arg; + tmp.type= SHOW_FUNC; + return tmp; +}; struct st_mysql_sys_var; struct st_mysql_value; typedef int (*mysql_var_check_func)(void* thd, diff --git a/include/mysql/plugin_password_validation.h.pp b/include/mysql/plugin_password_validation.h.pp index 9701ad1b92f..bf05ca36351 100644 --- a/include/mysql/plugin_password_validation.h.pp +++ b/include/mysql/plugin_password_validation.h.pp @@ -400,6 +400,16 @@ struct st_mysql_show_var { }; struct system_status_var; typedef int (*mysql_show_var_func)(void*, struct st_mysql_show_var*, void *, struct system_status_var *status_var, enum enum_var_type); +static inline +struct st_mysql_show_var SHOW_FUNC_ENTRY(const char *name, + mysql_show_var_func func_arg) +{ + struct st_mysql_show_var tmp; + tmp.name= name; + tmp.value= (void*) func_arg; + tmp.type= SHOW_FUNC; + return tmp; +}; struct st_mysql_sys_var; struct st_mysql_value; typedef int (*mysql_var_check_func)(void* thd, diff --git a/mysql-test/main/type_float.result b/mysql-test/main/type_float.result index a5f70d9ef80..5354fa50e19 100644 --- a/mysql-test/main/type_float.result +++ b/mysql-test/main/type_float.result @@ -964,5 +964,12 @@ id a DELETE FROM t1 WHERE a=CAST(0.671437 AS FLOAT); DROP TABLE t1; # +# MDEV-29473 UBSAN: Signed integer overflow: X * Y cannot be represented in type 'int' in strings/dtoa.c +# +CREATE TABLE t1 (c DOUBLE); +INSERT INTO t1 VALUES ('1e4294967297'); +ERROR 22003: Out of range value for column 'c' at row 1 +DROP TABLE t1; +# # End of 10.3 tests # diff --git a/mysql-test/main/type_float.test b/mysql-test/main/type_float.test index 5d7f7de7d0b..3f9781e6224 100644 --- a/mysql-test/main/type_float.test +++ b/mysql-test/main/type_float.test @@ -670,6 +670,16 @@ SELECT * FROM t1; DELETE FROM t1 WHERE a=CAST(0.671437 AS FLOAT); DROP TABLE t1; +--echo # +--echo # MDEV-29473 UBSAN: Signed integer overflow: X * Y cannot be represented in type 'int' in strings/dtoa.c +--echo # + +# This test was failing with UBSAN builds + +CREATE TABLE t1 (c DOUBLE); +--error ER_WARN_DATA_OUT_OF_RANGE +INSERT INTO t1 VALUES ('1e4294967297'); +DROP TABLE t1; --echo # --echo # End of 10.3 tests diff --git a/plugin/handler_socket/handlersocket/handlersocket.cpp b/plugin/handler_socket/handlersocket/handlersocket.cpp index 8133497044c..45c9e13b2ca 100644 --- a/plugin/handler_socket/handlersocket/handlersocket.cpp +++ b/plugin/handler_socket/handlersocket/handlersocket.cpp @@ -185,7 +185,9 @@ static SHOW_VAR hs_status_variables[] = { {NullS, NullS, SHOW_LONG} }; -static int show_hs_vars(THD *thd, SHOW_VAR *var, char *buff) +static int show_hs_vars(THD *thd, SHOW_VAR *var, void *buff, + struct system_status_var *status_var, + enum enum_var_type var_type) { var->type= SHOW_ARRAY; var->value= (char *) &hs_status_variables; @@ -193,7 +195,7 @@ static int show_hs_vars(THD *thd, SHOW_VAR *var, char *buff) } static SHOW_VAR daemon_handlersocket_status_variables[] = { - {"Hs", (char*) show_hs_vars, SHOW_FUNC}, + SHOW_FUNC_ENTRY("Hs", &show_hs_vars), {NullS, NullS, SHOW_LONG} }; diff --git a/sql/field.cc b/sql/field.cc index f430e6209d5..43514347106 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -11073,6 +11073,8 @@ bool Field_vers_trx_id::test_if_equality_guarantees_uniqueness(const Item* item) Column_definition::Column_definition(THD *thd, Field *old_field, Field *orig_field) { + geom_type= Field::GEOM_GEOMETRY; + srid= 0; on_update= NULL; field_name= old_field->field_name; length= old_field->field_length; diff --git a/sql/log.cc b/sql/log.cc index 7ca9b38dc6e..4b071f133f7 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -10501,7 +10501,7 @@ static int show_binlog_vars(THD *thd, SHOW_VAR *var, void *, } static SHOW_VAR binlog_status_vars_top[]= { - {"Binlog", (char *) &show_binlog_vars, SHOW_FUNC}, + SHOW_FUNC_ENTRY("Binlog", &show_binlog_vars), {NullS, NullS, SHOW_LONG} }; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 84c3b9fb0a6..d58f2ed557f 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -8395,7 +8395,9 @@ static int show_ssl_get_cipher_list(THD *thd, SHOW_VAR *var, char *buff, rpl_semi_sync_master_show_##name #define DEF_SHOW_FUNC(name, show_type) \ - static int SHOW_FNAME(name)(MYSQL_THD thd, SHOW_VAR *var, char *buff) \ + static int SHOW_FNAME(name)(MYSQL_THD thd, SHOW_VAR *var, void *buff, \ + system_status_var *status_var, \ + enum_var_type var_type) \ { \ repl_semisync_master.set_export_stats(); \ var->type= show_type; \ @@ -8661,7 +8663,7 @@ SHOW_VAR status_vars[]= { {"Created_tmp_files", (char*) &my_tmp_file_created, SHOW_LONG}, {"Created_tmp_tables", (char*) offsetof(STATUS_VAR, created_tmp_tables_), SHOW_LONG_STATUS}, #ifndef DBUG_OFF - {"Debug", (char*) &debug_status_func, SHOW_FUNC}, + SHOW_FUNC_ENTRY("Debug", &debug_status_func), #endif {"Delayed_errors", (char*) &delayed_insert_errors, SHOW_LONG}, {"Delayed_insert_threads", (char*) &delayed_insert_threads, SHOW_LONG_NOFLUSH}, @@ -8713,7 +8715,7 @@ SHOW_VAR status_vars[]= { {"Handler_tmp_write", (char*) offsetof(STATUS_VAR, ha_tmp_write_count), SHOW_LONG_STATUS}, {"Handler_update", (char*) offsetof(STATUS_VAR, ha_update_count), SHOW_LONG_STATUS}, {"Handler_write", (char*) offsetof(STATUS_VAR, ha_write_count), SHOW_LONG_STATUS}, - {"Key", (char*) &show_default_keycache, SHOW_FUNC}, + SHOW_FUNC_ENTRY("Key", &show_default_keycache), {"Last_query_cost", (char*) offsetof(STATUS_VAR, last_query_cost), SHOW_DOUBLE_STATUS}, {"Max_statement_time_exceeded", (char*) offsetof(STATUS_VAR, max_statement_time_exceeded), SHOW_LONG_STATUS}, {"Master_gtid_wait_count", (char*) offsetof(STATUS_VAR, master_gtid_wait_count), SHOW_LONG_STATUS}, @@ -8737,20 +8739,20 @@ SHOW_VAR status_vars[]= { {"Rows_read", (char*) offsetof(STATUS_VAR, rows_read), SHOW_LONGLONG_STATUS}, {"Rows_tmp_read", (char*) offsetof(STATUS_VAR, rows_tmp_read), SHOW_LONGLONG_STATUS}, #ifdef HAVE_REPLICATION - {"Rpl_semi_sync_master_status", (char*) &SHOW_FNAME(status), SHOW_FUNC}, - {"Rpl_semi_sync_master_clients", (char*) &SHOW_FNAME(clients), SHOW_FUNC}, + SHOW_FUNC_ENTRY("Rpl_semi_sync_master_status", &SHOW_FNAME(status)), + SHOW_FUNC_ENTRY("Rpl_semi_sync_master_clients", &SHOW_FNAME(clients)), {"Rpl_semi_sync_master_yes_tx", (char*) &rpl_semi_sync_master_yes_transactions, SHOW_LONG}, {"Rpl_semi_sync_master_no_tx", (char*) &rpl_semi_sync_master_no_transactions, SHOW_LONG}, - {"Rpl_semi_sync_master_wait_sessions", (char*) &SHOW_FNAME(wait_sessions), SHOW_FUNC}, + SHOW_FUNC_ENTRY("Rpl_semi_sync_master_wait_sessions", &SHOW_FNAME(wait_sessions)), {"Rpl_semi_sync_master_no_times", (char*) &rpl_semi_sync_master_off_times, SHOW_LONG}, {"Rpl_semi_sync_master_timefunc_failures", (char*) &rpl_semi_sync_master_timefunc_fails, SHOW_LONG}, {"Rpl_semi_sync_master_wait_pos_backtraverse", (char*) &rpl_semi_sync_master_wait_pos_backtraverse, SHOW_LONG}, - {"Rpl_semi_sync_master_tx_wait_time", (char*) &SHOW_FNAME(trx_wait_time), SHOW_FUNC}, - {"Rpl_semi_sync_master_tx_waits", (char*) &SHOW_FNAME(trx_wait_num), SHOW_FUNC}, - {"Rpl_semi_sync_master_tx_avg_wait_time", (char*) &SHOW_FNAME(avg_trx_wait_time), SHOW_FUNC}, - {"Rpl_semi_sync_master_net_wait_time", (char*) &SHOW_FNAME(net_wait_time), SHOW_FUNC}, - {"Rpl_semi_sync_master_net_waits", (char*) &SHOW_FNAME(net_wait_num), SHOW_FUNC}, - {"Rpl_semi_sync_master_net_avg_wait_time", (char*) &SHOW_FNAME(avg_net_wait_time), SHOW_FUNC}, + SHOW_FUNC_ENTRY("Rpl_semi_sync_master_tx_wait_time", &SHOW_FNAME(trx_wait_time)), + SHOW_FUNC_ENTRY("Rpl_semi_sync_master_tx_waits", &SHOW_FNAME(trx_wait_num)), + SHOW_FUNC_ENTRY("Rpl_semi_sync_master_tx_avg_wait_time", &SHOW_FNAME(avg_trx_wait_time)), + SHOW_FUNC_ENTRY("Rpl_semi_sync_master_net_wait_time", &SHOW_FNAME(net_wait_time)), + SHOW_FUNC_ENTRY("Rpl_semi_sync_master_net_waits", &SHOW_FNAME(net_wait_num)), + SHOW_FUNC_ENTRY("Rpl_semi_sync_master_net_avg_wait_time", &SHOW_FNAME(avg_net_wait_time)), {"Rpl_semi_sync_master_request_ack", (char*) &rpl_semi_sync_master_request_ack, SHOW_LONGLONG}, {"Rpl_semi_sync_master_get_ack", (char*)&rpl_semi_sync_master_get_ack, SHOW_LONGLONG}, {"Rpl_semi_sync_slave_status", (char*) &rpl_semi_sync_slave_status, SHOW_BOOL}, @@ -8858,7 +8860,7 @@ SHOW_VAR status_vars[]= { {"Uptime_since_flush_status",(char*) &show_flushstatustime, SHOW_SIMPLE_FUNC}, #endif #ifdef WITH_WSREP - {"wsrep", (char*) &wsrep_show_status, SHOW_FUNC}, + SHOW_FUNC_ENTRY("wsrep", &wsrep_show_status), #endif {NullS, NullS, SHOW_LONG} }; diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index cd2d36df112..81236343642 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -18415,7 +18415,9 @@ innodb_enable_monitor_at_startup( /****************************************************************//** Callback function for accessing the InnoDB variables from MySQL: SHOW VARIABLES. */ -static int show_innodb_vars(THD*, SHOW_VAR* var, char*) +static int show_innodb_vars(THD*, SHOW_VAR* var, void *, + struct system_status_var *status_var, + enum enum_var_type var_type) { innodb_export_status(); var->type = SHOW_ARRAY; @@ -18861,7 +18863,7 @@ innobase_debug_sync_set(THD *thd, st_mysql_sys_var*, void *, const void *value) #endif static SHOW_VAR innodb_status_variables_export[]= { - {"Innodb", (char*) &show_innodb_vars, SHOW_FUNC}, + SHOW_FUNC_ENTRY("Innodb", &show_innodb_vars), {NullS, NullS, SHOW_LONG} }; diff --git a/storage/rocksdb/ha_rocksdb.cc b/storage/rocksdb/ha_rocksdb.cc index cd366a12462..aa934695322 100644 --- a/storage/rocksdb/ha_rocksdb.cc +++ b/storage/rocksdb/ha_rocksdb.cc @@ -13102,7 +13102,9 @@ bool ha_rocksdb::commit_inplace_alter_table( #define SHOW_FNAME(name) rocksdb_show_##name #define DEF_SHOW_FUNC(name, key) \ - static int SHOW_FNAME(name)(MYSQL_THD thd, SHOW_VAR * var, char *buff) { \ + static int SHOW_FNAME(name)(MYSQL_THD thd, SHOW_VAR * var, void *buff, \ + struct system_status_var *status_var, \ + enum enum_var_type var_type) { \ rocksdb_status_counters.name = \ rocksdb_stats->getTickerCount(rocksdb::key); \ var->type = SHOW_LONGLONG; \ @@ -13111,7 +13113,7 @@ bool ha_rocksdb::commit_inplace_alter_table( } #define DEF_STATUS_VAR(name) \ - { "rocksdb_" #name, (char *)&SHOW_FNAME(name), SHOW_FUNC } + SHOW_FUNC_ENTRY( "rocksdb_" #name, &SHOW_FNAME(name)) #define DEF_STATUS_VAR_PTR(name, ptr, option) \ { "rocksdb_" name, (char *)ptr, option } @@ -13339,11 +13341,14 @@ static SHOW_VAR myrocks_status_variables[] = { {NullS, NullS, SHOW_LONG}}; -static void show_myrocks_vars(THD *thd, SHOW_VAR *var, char *buff) { +static int show_myrocks_vars(THD *thd, SHOW_VAR *var, void *buff, + struct system_status_var *, + enum enum_var_type) { myrocks_update_status(); myrocks_update_memory_status(); var->type = SHOW_ARRAY; var->value = reinterpret_cast(&myrocks_status_variables); + return 0; } static ulonglong io_stall_prop_value( @@ -13424,10 +13429,13 @@ static SHOW_VAR rocksdb_stall_status_variables[] = { // end of the array marker {NullS, NullS, SHOW_LONG}}; -static void show_rocksdb_stall_vars(THD *thd, SHOW_VAR *var, char *buff) { +static int show_rocksdb_stall_vars(THD *thd, SHOW_VAR *var, void *buff, + struct system_status_var *, + enum enum_var_type) { update_rocksdb_stall_status(); var->type = SHOW_ARRAY; var->value = reinterpret_cast(&rocksdb_stall_status_variables); + return 0; } static SHOW_VAR rocksdb_status_vars[] = { @@ -13532,9 +13540,8 @@ static SHOW_VAR rocksdb_status_vars[] = { // the variables generated by SHOW_FUNC are sorted only by prefix (first // arg in the tuple below), so make sure it is unique to make sorting // deterministic as quick sort is not stable - {"rocksdb", reinterpret_cast(&show_myrocks_vars), SHOW_FUNC}, - {"rocksdb_stall", reinterpret_cast(&show_rocksdb_stall_vars), - SHOW_FUNC}, + SHOW_FUNC_ENTRY("rocksdb", &show_myrocks_vars), + SHOW_FUNC_ENTRY("rocksdb_stall", &show_rocksdb_stall_vars), {NullS, NullS, SHOW_LONG}}; /* diff --git a/storage/tokudb/hatoku_hton.cc b/storage/tokudb/hatoku_hton.cc index 81355ea20ff..79ca28188ac 100644 --- a/storage/tokudb/hatoku_hton.cc +++ b/storage/tokudb/hatoku_hton.cc @@ -1894,7 +1894,9 @@ static void tokudb_lock_wait_needed_callback( // and prefixed with "TOKUDB_" static int show_tokudb_vars(TOKUDB_UNUSED(THD* thd), SHOW_VAR* var, - TOKUDB_UNUSED(char* buff)) { + TOKUDB_UNUSED(void* buff), + TOKUDB_UNUSED(system_status_var *status_var), + TOKUDB_UNUSED(enum_var_type var_type)) { TOKUDB_DBUG_ENTER(""); int error; @@ -1994,7 +1996,7 @@ static int show_tokudb_vars(TOKUDB_UNUSED(THD* thd), } static SHOW_VAR toku_global_status_variables_export[]= { - {"Tokudb", (char*)&show_tokudb_vars, SHOW_FUNC}, + SHOW_FUNC_ENTRY("Tokudb", &show_tokudb_vars), {NullS, NullS, SHOW_LONG} }; diff --git a/strings/dtoa.c b/strings/dtoa.c index e31b7e92d7c..13e28821f69 100644 --- a/strings/dtoa.c +++ b/strings/dtoa.c @@ -1478,7 +1478,10 @@ static double my_strtod_int(const char *s00, char **se, int *error, char *buf, s L= c - '0'; s1= s; while (++s < end && (c= *s) >= '0' && c <= '9') - L= 10*L + c - '0'; + { + if (L < 19999) + L= 10*L + c - '0'; + } if (s - s1 > 8 || L > 19999) /* Avoid confusion from exponents * so large that e might overflow. -- cgit v1.2.1 From f4a1298f245f678badc8a5b55571ca4f460718b1 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Fri, 18 Nov 2022 21:28:06 +1100 Subject: MDEV-12274: Too many connections warning in error log (#2213) Because of the default warning level, aborted unauthenticated connections are in the error log. These errors frequently occur in production environments because cancelled connectiosn occur all the time when web pages are shutdown. Rather than flood our user's errors log with these ordinary messages, lets push them down to the warning level at log-warnings=4 level. Concept approved by Monty. --- sql/sql_connect.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc index 4d9ef98d22b..91a99e0aded 100644 --- a/sql/sql_connect.cc +++ b/sql/sql_connect.cc @@ -1263,7 +1263,8 @@ void prepare_new_connection_state(THD* thd) and the main Diagnostics Area contains an error condition. */ if (packet_length != packet_error) - my_error(ER_NEW_ABORTING_CONNECTION, MYF(0), + my_error(ER_NEW_ABORTING_CONNECTION, + (thd->db.str || sctx->user) ? MYF(0) : MYF(ME_JUST_WARNING), thd->thread_id, thd->db.str ? thd->db.str : "unconnected", sctx->user ? sctx->user : "unauthenticated", -- cgit v1.2.1 From 71c93fb8fd894e39b81b801a67ccb9de535b6ce8 Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Thu, 17 Nov 2022 17:24:13 +0530 Subject: MDEV-28462 Race condition between instant alter and AHI access - InnoDB AHI tries to access the concurrent instant alter column, leads to asan failure. Instant alter column should acquire the clustered index search latch in exclusive mode before changing the table cache definition. - Removed the default parameter for the function btr_search_drop_page_hash_index() - Addressed the DWITH_INNODB_AHI=0 compilation failure by passing two parameters from all callers of btr_search_drop_page_hash_index() --- storage/innobase/btr/btr0btr.cc | 16 ++++++++-------- storage/innobase/btr/btr0defragment.cc | 2 +- storage/innobase/btr/btr0sea.cc | 14 +++++++------- storage/innobase/buf/buf0buf.cc | 2 +- storage/innobase/buf/buf0lru.cc | 4 +++- storage/innobase/handler/handler0alter.cc | 12 +++++++++++- storage/innobase/include/btr0sea.h | 2 +- storage/innobase/page/page0zip.cc | 2 +- 8 files changed, 33 insertions(+), 21 deletions(-) diff --git a/storage/innobase/btr/btr0btr.cc b/storage/innobase/btr/btr0btr.cc index 6b575885f81..82619531d5c 100644 --- a/storage/innobase/btr/btr0btr.cc +++ b/storage/innobase/btr/btr0btr.cc @@ -994,7 +994,7 @@ static void btr_free_root(buf_block_t* block, mtr_t* mtr, bool invalidate) | MTR_MEMO_PAGE_SX_FIX)); ut_ad(mtr->is_named_space(block->page.id.space())); - btr_search_drop_page_hash_index(block); + btr_search_drop_page_hash_index(block, false); header = buf_block_get_frame(block) + PAGE_HEADER + PAGE_BTR_SEG_TOP; #ifdef UNIV_BTR_DEBUG @@ -1496,7 +1496,7 @@ btr_page_reorganize_low( buf_frame_copy(temp_page, page); if (!recovery) { - btr_search_drop_page_hash_index(block); + btr_search_drop_page_hash_index(block, false); } /* Save the cursor position. */ @@ -1785,7 +1785,7 @@ btr_page_empty( ut_a(!page_zip || page_zip_validate(page_zip, page, index)); #endif /* UNIV_ZIP_DEBUG */ - btr_search_drop_page_hash_index(block); + btr_search_drop_page_hash_index(block, false); /* Recreate the page: note that global data on page (possible segment headers, next page-field, etc.) is preserved intact */ @@ -3410,7 +3410,7 @@ btr_lift_page_up( mem_heap_free(heap); } - btr_search_drop_page_hash_index(block); + btr_search_drop_page_hash_index(block, false); /* Make the father empty */ btr_page_empty(father_block, father_page_zip, index, page_level, mtr); @@ -3728,7 +3728,7 @@ retry: goto err_exit; } - btr_search_drop_page_hash_index(block); + btr_search_drop_page_hash_index(block, false); /* Remove the page from the level list */ if (DB_SUCCESS != btr_level_list_remove(index->table->space_id, @@ -3848,7 +3848,7 @@ retry: goto err_exit; } - btr_search_drop_page_hash_index(block); + btr_search_drop_page_hash_index(block, false); #ifdef UNIV_BTR_DEBUG if (merge_page_zip && left_page_no == FIL_NULL) { @@ -4081,7 +4081,7 @@ btr_discard_only_page_on_level( ut_ad(fil_page_index_page_check(page)); ut_ad(block->page.id.space() == index->table->space->id); ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX)); - btr_search_drop_page_hash_index(block); + btr_search_drop_page_hash_index(block, false); if (dict_index_is_spatial(index)) { /* Check any concurrent search having this page */ @@ -4221,7 +4221,7 @@ btr_discard_page( page = buf_block_get_frame(block); ut_a(page_is_comp(merge_page) == page_is_comp(page)); - btr_search_drop_page_hash_index(block); + btr_search_drop_page_hash_index(block, false); if (left_page_no == FIL_NULL && !page_is_leaf(page)) { diff --git a/storage/innobase/btr/btr0defragment.cc b/storage/innobase/btr/btr0defragment.cc index 3fefd77041e..3bfd4d55b0e 100644 --- a/storage/innobase/btr/btr0defragment.cc +++ b/storage/innobase/btr/btr0defragment.cc @@ -486,7 +486,7 @@ btr_defragment_merge_pages( free it. */ lock_update_merge_left(to_block, orig_pred, from_block); - btr_search_drop_page_hash_index(from_block); + btr_search_drop_page_hash_index(from_block, false); ut_a(DB_SUCCESS == btr_level_list_remove( index->table->space_id, diff --git a/storage/innobase/btr/btr0sea.cc b/storage/innobase/btr/btr0sea.cc index ff5a0e1e737..6171e1a3d25 100644 --- a/storage/innobase/btr/btr0sea.cc +++ b/storage/innobase/btr/btr0sea.cc @@ -682,7 +682,7 @@ btr_search_update_hash_ref( if (cursor->index != index) { ut_ad(cursor->index->id == index->id); - btr_search_drop_page_hash_index(block); + btr_search_drop_page_hash_index(block, false); return; } @@ -1312,7 +1312,7 @@ void btr_search_drop_page_hash_when_freed(const page_id_t page_id) dropping the table (preventing eviction). */ ut_ad(index->table->get_ref_count() > 0 || mutex_own(&dict_sys->mutex)); - btr_search_drop_page_hash_index(block); + btr_search_drop_page_hash_index(block, false); } } @@ -1384,7 +1384,7 @@ btr_search_build_page_hash_index( } if (rebuild) { - btr_search_drop_page_hash_index(block); + btr_search_drop_page_hash_index(block, false); } /* Check that the values for hash index build are sensible */ @@ -1610,7 +1610,7 @@ btr_search_move_or_delete_hash_entries( if (new_block->index) { drop_exit: - btr_search_drop_page_hash_index(block); + btr_search_drop_page_hash_index(block, false); return; } @@ -1686,7 +1686,7 @@ void btr_search_update_hash_on_delete(btr_cur_t* cursor) if (index != cursor->index) { ut_ad(index->id == cursor->index->id); - btr_search_drop_page_hash_index(block); + btr_search_drop_page_hash_index(block, false); return; } @@ -1766,7 +1766,7 @@ btr_search_update_hash_node_on_insert(btr_cur_t* cursor, rw_lock_t* ahi_latch) if (cursor->index != index) { ut_ad(cursor->index->id == index->id); - btr_search_drop_page_hash_index(block); + btr_search_drop_page_hash_index(block, false); return; } @@ -1861,7 +1861,7 @@ btr_search_update_hash_on_insert(btr_cur_t* cursor, rw_lock_t* ahi_latch) #endif if (index != cursor->index) { ut_ad(index->id == cursor->index->id); - btr_search_drop_page_hash_index(block); + btr_search_drop_page_hash_index(block, false); return; } diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index fe2c0c6b880..6a9f041deee 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -5414,7 +5414,7 @@ loop: } #ifdef BTR_CUR_HASH_ADAPT if (drop_hash_entry) { - btr_search_drop_page_hash_index(block); + btr_search_drop_page_hash_index(block, false); } #endif /* BTR_CUR_HASH_ADAPT */ diff --git a/storage/innobase/buf/buf0lru.cc b/storage/innobase/buf/buf0lru.cc index d3bba9a1130..72612ebd9ad 100644 --- a/storage/innobase/buf/buf0lru.cc +++ b/storage/innobase/buf/buf0lru.cc @@ -1608,10 +1608,12 @@ func_exit: order to avoid bogus Valgrind or MSAN warnings.*/ buf_block_t* block = reinterpret_cast(bpage); +#ifdef BTR_CUR_HASH_ADAPT MEM_MAKE_DEFINED(block->frame, srv_page_size); - btr_search_drop_page_hash_index(block); + btr_search_drop_page_hash_index(block, false); MEM_UNDEFINED(block->frame, srv_page_size); +#endif /* BTR_CUR_HASH_ADAPT */ buf_pool_mutex_enter(buf_pool); if (b) { diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 0cba7d953d1..cd40fe3145e 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -4371,8 +4371,18 @@ innobase_add_instant_try( DBUG_ASSERT(ctx->old_table->n_cols == ctx->old_n_cols); dict_table_t* user_table = ctx->old_table; - user_table->instant_add_column(*ctx->instant_table); dict_index_t* index = dict_table_get_first_index(user_table); + +#ifdef BTR_CUR_HASH_ADAPT + /* Acquire the ahi latch to avoid the race condition + between ahi access and instant alter table */ + rw_lock_t* ahi_latch = btr_get_search_latch(index); + rw_lock_x_lock(ahi_latch); +#endif /* BTR_CUR_HASH_ADAPT */ + user_table->instant_add_column(*ctx->instant_table); +#ifdef BTR_CUR_HASH_ADAPT + rw_lock_x_unlock(ahi_latch); +#endif /* BTR_CUR_HASH_ADAPT */ /* The table may have been emptied and may have lost its 'instant-add-ness' during this instant ADD COLUMN. */ diff --git a/storage/innobase/include/btr0sea.h b/storage/innobase/include/btr0sea.h index f217f8213f8..82ae50d6fac 100644 --- a/storage/innobase/include/btr0sea.h +++ b/storage/innobase/include/btr0sea.h @@ -102,7 +102,7 @@ btr_search_move_or_delete_hash_entries( @param[in] garbage_collect drop ahi only if the index is marked as freed */ void btr_search_drop_page_hash_index(buf_block_t* block, - bool garbage_collect= false); + bool garbage_collect); /** Drop possible adaptive hash index entries when a page is evicted from the buffer pool or freed in a file, or the index is being dropped. diff --git a/storage/innobase/page/page0zip.cc b/storage/innobase/page/page0zip.cc index 7a86d825aeb..e89e1cf862c 100644 --- a/storage/innobase/page/page0zip.cc +++ b/storage/innobase/page/page0zip.cc @@ -4759,7 +4759,7 @@ page_zip_reorganize( mtr_log_t log_mode = mtr_set_log_mode(mtr, MTR_LOG_NONE); temp_block = buf_block_alloc(buf_pool); - btr_search_drop_page_hash_index(block); + btr_search_drop_page_hash_index(block, false); temp_page = temp_block->frame; /* Copy the old page to temporary space */ -- cgit v1.2.1 From f0820400ee427f1398034c6881c803e42cfd249e Mon Sep 17 00:00:00 2001 From: Julius Goryavsky Date: Wed, 19 Oct 2022 02:51:01 +0200 Subject: MDEV-29817: Issues with handling options for SSL CRLs (and some others) This patch adds the correct setting of the "--ssl-verify-server-cert" option in the client-side utilities such as mysqlcheck and mysqlslap, as well as the correct setting of the "--ssl-crl" option when executing queries on the slave side, and also add the correct option codes in the "sslopts-logopts.h" file (in the latter case, incorrect values are not a problem right now, but may cause subtle test failures in the future, if the option handling code changes). --- client/mysqlcheck.c | 2 ++ client/mysqlslap.c | 2 ++ include/sslopt-longopts.h | 4 ++-- sql/slave.cc | 6 +++--- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c index 090644e5cb0..37a76d5699b 100644 --- a/client/mysqlcheck.c +++ b/client/mysqlcheck.c @@ -1111,6 +1111,8 @@ static int dbConnect(char *host, char *user, char *passwd) mysql_options(&mysql_connection, MYSQL_OPT_SSL_CRL, opt_ssl_crl); mysql_options(&mysql_connection, MYSQL_OPT_SSL_CRLPATH, opt_ssl_crlpath); } + mysql_options(&mysql_connection, MYSQL_OPT_SSL_VERIFY_SERVER_CERT, + (char*)&opt_ssl_verify_server_cert); #endif if (opt_protocol) mysql_options(&mysql_connection,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol); diff --git a/client/mysqlslap.c b/client/mysqlslap.c index 6a41d595bff..f46c0d9c221 100644 --- a/client/mysqlslap.c +++ b/client/mysqlslap.c @@ -306,6 +306,8 @@ void set_mysql_connect_options(MYSQL *mysql) mysql_options(mysql, MYSQL_OPT_SSL_CRL, opt_ssl_crl); mysql_options(mysql, MYSQL_OPT_SSL_CRLPATH, opt_ssl_crlpath); } + mysql_options(mysql, MYSQL_OPT_SSL_VERIFY_SERVER_CERT, + (char*)&opt_ssl_verify_server_cert); #endif if (opt_protocol) mysql_options(mysql,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol); diff --git a/include/sslopt-longopts.h b/include/sslopt-longopts.h index be64e7f6590..8268ca1ada5 100644 --- a/include/sslopt-longopts.h +++ b/include/sslopt-longopts.h @@ -39,10 +39,10 @@ {"ssl-key", OPT_SSL_KEY, "X509 key in PEM format (implies --ssl).", &opt_ssl_key, &opt_ssl_key, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"ssl-crl", OPT_SSL_KEY, "Certificate revocation list (implies --ssl).", + {"ssl-crl", OPT_SSL_CRL, "Certificate revocation list (implies --ssl).", &opt_ssl_crl, &opt_ssl_crl, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"ssl-crlpath", OPT_SSL_KEY, + {"ssl-crlpath", OPT_SSL_CRLPATH, "Certificate revocation list path (implies --ssl).", &opt_ssl_crlpath, &opt_ssl_crlpath, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, diff --git a/sql/slave.cc b/sql/slave.cc index 60a62d71cf6..41e0e3c86eb 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -7210,9 +7210,9 @@ static int connect_to_master(THD* thd, MYSQL* mysql, Master_info* mi, mi->ssl_ca[0]?mi->ssl_ca:0, mi->ssl_capath[0]?mi->ssl_capath:0, mi->ssl_cipher[0]?mi->ssl_cipher:0); - mysql_options(mysql, MYSQL_OPT_SSL_VERIFY_SERVER_CERT, - &mi->ssl_verify_server_cert); - mysql_options(mysql, MYSQL_OPT_SSL_CRLPATH, + mysql_options(mysql, MYSQL_OPT_SSL_CRL, + mi->ssl_crl[0] ? mi->ssl_crl : 0); + mysql_options(mysql, MYSQL_OPT_SSL_CRLPATH, mi->ssl_crlpath[0] ? mi->ssl_crlpath : 0); mysql_options(mysql, MYSQL_OPT_SSL_VERIFY_SERVER_CERT, &mi->ssl_verify_server_cert); -- cgit v1.2.1 From d569e6dea4c451469a0c293692c3db0e963309ce Mon Sep 17 00:00:00 2001 From: Nikita Malyavin Date: Wed, 23 Nov 2022 14:53:21 +0300 Subject: MDEV-29169 Using MATCH returns NULL for Virtual Column Virtual column values are updated in handler in reading commands, like ha_index_next, etc. This was missing for ha_ft_read. handler::ha_ft_read: add table->update_virtual_fields() call --- mysql-test/suite/innodb_fts/r/fulltext2.result | 17 +++++++++++++++++ mysql-test/suite/innodb_fts/t/fulltext2.test | 16 ++++++++++++++++ sql/sql_class.h | 5 +++++ 3 files changed, 38 insertions(+) diff --git a/mysql-test/suite/innodb_fts/r/fulltext2.result b/mysql-test/suite/innodb_fts/r/fulltext2.result index e9a089ab80d..720dfe4ee71 100644 --- a/mysql-test/suite/innodb_fts/r/fulltext2.result +++ b/mysql-test/suite/innodb_fts/r/fulltext2.result @@ -278,3 +278,20 @@ ALTER TABLE t1 ADD d INT NULL; ALTER TABLE t1 ADD FULLTEXT(b); ERROR HY000: Index 'FTS_DOC_ID_INDEX' is of wrong type for an InnoDB FULLTEXT index DROP TABLE t1; +# +# MDEV-29169 Using MATCH returns NULL for Virtual Column +# +CREATE TABLE t (a TEXT DEFAULT NULL, +b TEXT AS (a), +c TEXT AS (concat(a, '1')), +d int AS (111) VIRTUAL, +FULLTEXT KEY `a` (`a`) +) ENGINE=InnoDB; +INSERT INTO t (a) VALUES ('test'); +SELECT * FROM t; +a b c d +test test test1 111 +SELECT * FROM t WHERE MATCH(a) AGAINST('test'); +a b c d +test test test1 111 +DROP TABLE t; diff --git a/mysql-test/suite/innodb_fts/t/fulltext2.test b/mysql-test/suite/innodb_fts/t/fulltext2.test index 1e3894644a0..25a4d5b24f9 100644 --- a/mysql-test/suite/innodb_fts/t/fulltext2.test +++ b/mysql-test/suite/innodb_fts/t/fulltext2.test @@ -268,3 +268,19 @@ ALTER TABLE t1 ADD d INT NULL; --error ER_INNODB_FT_WRONG_DOCID_INDEX ALTER TABLE t1 ADD FULLTEXT(b); DROP TABLE t1; + +--echo # +--echo # MDEV-29169 Using MATCH returns NULL for Virtual Column +--echo # +CREATE TABLE t (a TEXT DEFAULT NULL, + b TEXT AS (a), + c TEXT AS (concat(a, '1')), + d int AS (111) VIRTUAL, + FULLTEXT KEY `a` (`a`) +) ENGINE=InnoDB; + +INSERT INTO t (a) VALUES ('test'); +SELECT * FROM t; +SELECT * FROM t WHERE MATCH(a) AGAINST('test'); + +DROP TABLE t; diff --git a/sql/sql_class.h b/sql/sql_class.h index 9ac973dc640..5e209f56458 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -6513,8 +6513,13 @@ inline int handler::ha_ft_read(uchar *buf) { int error= ft_read(buf); if (!error) + { update_rows_read(); + if (table->vfield && buf == table->record[0]) + table->update_virtual_fields(this, VCOL_UPDATE_FOR_READ); + } + table->status=error ? STATUS_NOT_FOUND: 0; return error; } -- cgit v1.2.1 From 162c1505052030e3496f83c5b711fd0ef5cb2bea Mon Sep 17 00:00:00 2001 From: Nayuta Yanagisawa Date: Sun, 23 Oct 2022 19:59:34 +0900 Subject: MDEV-29855 Crash with SPIDER_DIRECT_SQL and spider_udf_ds_use_real_table=1 The crash occurs because of the following call of TABLE_LIST::init_one_table(): table_list.init_one_table( &table_list.db, &table_list.table_name, 0, TL_WRITE); One should not pass table_list.db and table_list.table_name to the function because it update the very members internally. The function is called previously, and there is no need to call it again. So, simply removing the call will resolve the problem. --- .../mysql-test/spider/bugfix/r/mdev_29855.result | 34 ++++++++++++++++++ .../mysql-test/spider/bugfix/t/mdev_29855.cnf | 3 ++ .../mysql-test/spider/bugfix/t/mdev_29855.test | 40 ++++++++++++++++++++++ storage/spider/spd_direct_sql.cc | 11 ------ 4 files changed, 77 insertions(+), 11 deletions(-) create mode 100644 storage/spider/mysql-test/spider/bugfix/r/mdev_29855.result create mode 100644 storage/spider/mysql-test/spider/bugfix/t/mdev_29855.cnf create mode 100644 storage/spider/mysql-test/spider/bugfix/t/mdev_29855.test diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_29855.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_29855.result new file mode 100644 index 00000000000..4335d20f4c3 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_29855.result @@ -0,0 +1,34 @@ +# +# MDEV-29855 Crash with SPIDER_DIRECT_SQL and spider_udf_ds_use_real_table=1 +# +for master_1 +for child2 +child2_1 +child2_2 +child2_3 +for child3 +connection child2_1; +CREATE DATABASE auto_test_remote; +USE auto_test_remote; +CREATE TABLE tbl_a ( +a INT +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +connection master_1; +CREATE DATABASE auto_test_local; +USE auto_test_local; +CREATE TABLE tbl_a ( +a INT +) ENGINE=Spider DEFAULT CHARSET=utf8 COMMENT='table "tbl_a", srv "s_2_1"'; +SET spider_udf_ds_use_real_table=1; +SELECT SPIDER_DIRECT_SQL('select 1 as 1', 'tbl_a', 'srv "s_2_1"'); +ERROR 3D000: No database selected +connection master_1; +DROP DATABASE IF EXISTS auto_test_local; +connection child2_1; +DROP DATABASE IF EXISTS auto_test_remote; +for master_1 +for child2 +child2_1 +child2_2 +child2_3 +for child3 diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_29855.cnf b/storage/spider/mysql-test/spider/bugfix/t/mdev_29855.cnf new file mode 100644 index 00000000000..05dfd8a0bce --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_29855.cnf @@ -0,0 +1,3 @@ +!include include/default_mysqld.cnf +!include ../my_1_1.cnf +!include ../my_2_1.cnf diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_29855.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_29855.test new file mode 100644 index 00000000000..13cda064c72 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_29855.test @@ -0,0 +1,40 @@ +--echo # +--echo # MDEV-29855 Crash with SPIDER_DIRECT_SQL and spider_udf_ds_use_real_table=1 +--echo # + + +--disable_query_log +--disable_result_log +--source ../../t/test_init.inc +--enable_result_log +--enable_query_log + +--connection child2_1 +CREATE DATABASE auto_test_remote; +USE auto_test_remote; +eval CREATE TABLE tbl_a ( + a INT +) $CHILD2_1_ENGINE $CHILD2_1_CHARSET; + +--connection master_1 +CREATE DATABASE auto_test_local; +USE auto_test_local; +eval CREATE TABLE tbl_a ( + a INT +) $MASTER_1_ENGINE $MASTER_1_CHARSET COMMENT='table "tbl_a", srv "s_2_1"'; + +SET spider_udf_ds_use_real_table=1; +--error ER_NO_DB_ERROR +SELECT SPIDER_DIRECT_SQL('select 1 as 1', 'tbl_a', 'srv "s_2_1"'); + +--connection master_1 +DROP DATABASE IF EXISTS auto_test_local; + +--connection child2_1 +DROP DATABASE IF EXISTS auto_test_remote; + +--disable_query_log +--disable_result_log +--source ../t/test_deinit.inc +--enable_query_log +--enable_result_log diff --git a/storage/spider/spd_direct_sql.cc b/storage/spider/spd_direct_sql.cc index 7237d0877a7..98338cd06f5 100644 --- a/storage/spider/spd_direct_sql.cc +++ b/storage/spider/spd_direct_sql.cc @@ -1738,17 +1738,6 @@ long long spider_direct_sql_body( #else } TABLE_LIST *tables = &direct_sql->table_list[roop_count]; -#ifdef SPIDER_use_LEX_CSTRING_for_database_tablename_alias - table_list.init_one_table( - &table_list.db, &table_list.table_name, 0, TL_WRITE); -#else - tables->init_one_table( - SPIDER_TABLE_LIST_db_str(&table_list), - SPIDER_TABLE_LIST_db_length(&table_list), - SPIDER_TABLE_LIST_table_name_str(&table_list), - SPIDER_TABLE_LIST_table_name_length(&table_list), - SPIDER_TABLE_LIST_table_name_str(&table_list), TL_WRITE); -#endif tables->mdl_request.init(MDL_key::TABLE, SPIDER_TABLE_LIST_db_str(&table_list), SPIDER_TABLE_LIST_table_name_str(&table_list), -- cgit v1.2.1 From 4e9206736c403206915c09db1c9d8e3cd0fd0c5b Mon Sep 17 00:00:00 2001 From: Nayuta Yanagisawa Date: Fri, 1 Jul 2022 21:41:45 +0900 Subject: MDEV-28996 ASAN errors in String::q_append / spider_string::q_append / spider_db_mbase_util::open_item_func The server crashed due to the stack-use-after-scope on tmp_str. tmp_str will be used later so should not point to the local buffer. --- .../mysql-test/spider/bugfix/r/mdev_28996.result | 34 ++++++++++++++++++ .../mysql-test/spider/bugfix/t/mdev_28996.cnf | 3 ++ .../mysql-test/spider/bugfix/t/mdev_28996.test | 40 ++++++++++++++++++++++ storage/spider/spd_db_mysql.cc | 22 +++++++----- 4 files changed, 90 insertions(+), 9 deletions(-) create mode 100644 storage/spider/mysql-test/spider/bugfix/r/mdev_28996.result create mode 100644 storage/spider/mysql-test/spider/bugfix/t/mdev_28996.cnf create mode 100644 storage/spider/mysql-test/spider/bugfix/t/mdev_28996.test diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_28996.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_28996.result new file mode 100644 index 00000000000..f805e7ef3ad --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_28996.result @@ -0,0 +1,34 @@ +# +# MDEV-28996 ASAN errors in String::q_append / spider_string::q_append / spider_db_mbase_util::open_item_func +# +for master_1 +for child2 +child2_1 +child2_2 +child2_3 +for child3 +connection child2_1; +CREATE DATABASE auto_test_remote; +USE auto_test_remote; +CREATE TABLE tbl_a ( +a CHAR(8) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +INSERT INTO tbl_a VALUES ('foo'),('bar'); +connection master_1; +CREATE DATABASE auto_test_local; +USE auto_test_local; +CREATE TABLE tbl_a ( +a CHAR(8) +) ENGINE=Spider DEFAULT CHARSET=utf8 COMMENT='table "tbl_a", srv "s_2_1"'; +SELECT MAX(BINARY a) FROM tbl_a; +MAX(BINARY a) +foo +DROP DATABASE auto_test_local; +connection child2_1; +DROP DATABASE auto_test_remote; +for master_1 +for child2 +child2_1 +child2_2 +child2_3 +for child3 diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_28996.cnf b/storage/spider/mysql-test/spider/bugfix/t/mdev_28996.cnf new file mode 100644 index 00000000000..05dfd8a0bce --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_28996.cnf @@ -0,0 +1,3 @@ +!include include/default_mysqld.cnf +!include ../my_1_1.cnf +!include ../my_2_1.cnf diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_28996.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_28996.test new file mode 100644 index 00000000000..8097fe7e607 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_28996.test @@ -0,0 +1,40 @@ +--echo # +--echo # MDEV-28996 ASAN errors in String::q_append / spider_string::q_append / spider_db_mbase_util::open_item_func +--echo # + +--disable_query_log +--disable_result_log +--source ../t/test_init.inc +--enable_query_log +--enable_result_log + +--connection child2_1 +CREATE DATABASE auto_test_remote; +USE auto_test_remote; + +eval CREATE TABLE tbl_a ( + a CHAR(8) +) $CHILD2_1_ENGINE $CHILD2_1_CHARSET; + +INSERT INTO tbl_a VALUES ('foo'),('bar'); + +--connection master_1 +CREATE DATABASE auto_test_local; +USE auto_test_local; + +eval CREATE TABLE tbl_a ( + a CHAR(8) +) $MASTER_1_ENGINE $MASTER_1_CHARSET COMMENT='table "tbl_a", srv "s_2_1"'; + +SELECT MAX(BINARY a) FROM tbl_a; + +DROP DATABASE auto_test_local; + +--connection child2_1 +DROP DATABASE auto_test_remote; + +--disable_query_log +--disable_result_log +--source ../t/test_deinit.inc +--enable_query_log +--enable_result_log diff --git a/storage/spider/spd_db_mysql.cc b/storage/spider/spd_db_mysql.cc index 5f6107e66a0..e942d1d9063 100644 --- a/storage/spider/spd_db_mysql.cc +++ b/storage/spider/spd_db_mysql.cc @@ -4039,6 +4039,7 @@ int spider_db_mbase_util::open_item_func( int error_num; Item *item, **item_list = item_func->arguments(); Field *field; + spider_string tmp_str; uint roop_count, item_count = item_func->argument_count(), start_item = 0; const char *func_name = SPIDER_SQL_NULL_CHAR_STR, *separator_str = SPIDER_SQL_NULL_CHAR_STR, @@ -4491,10 +4492,11 @@ int spider_db_mbase_util::open_item_func( if (str) { - char tmp_buf[MAX_FIELD_WIDTH], *tmp_ptr, *tmp_ptr2; - spider_string tmp_str(tmp_buf, MAX_FIELD_WIDTH, str->charset()); + char *tmp_ptr, *tmp_ptr2; + DBUG_ASSERT(tmp_str.length() == 0); + tmp_str.set_charset(str->charset()); tmp_str.init_calc_mem(123); - tmp_str.length(0); + tmp_str.reserve(MAX_FIELD_WIDTH); str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); if (!merge_func) { @@ -4625,10 +4627,11 @@ int spider_db_mbase_util::open_item_func( if (str) { - char tmp_buf[MAX_FIELD_WIDTH], *tmp_ptr, *tmp_ptr2; - spider_string tmp_str(tmp_buf, MAX_FIELD_WIDTH, str->charset()); + char *tmp_ptr, *tmp_ptr2; + DBUG_ASSERT(tmp_str.length() == 0); + tmp_str.set_charset(str->charset()); tmp_str.init_calc_mem(124); - tmp_str.length(0); + tmp_str.reserve(MAX_FIELD_WIDTH); str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); if (!merge_func) { @@ -4779,10 +4782,11 @@ int spider_db_mbase_util::open_item_func( if (str) { - char tmp_buf[MAX_FIELD_WIDTH], *tmp_ptr, *tmp_ptr2; - spider_string tmp_str(tmp_buf, MAX_FIELD_WIDTH, str->charset()); + char *tmp_ptr, *tmp_ptr2; + DBUG_ASSERT(tmp_str.length() == 0); + tmp_str.set_charset(str->charset()); tmp_str.init_calc_mem(125); - tmp_str.length(0); + tmp_str.reserve(MAX_FIELD_WIDTH); str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN); if (!merge_func) { -- cgit v1.2.1 From 3d5ce0430bc224490dd2011c41bf05bc2e524ed0 Mon Sep 17 00:00:00 2001 From: Anel Husakovic Date: Sun, 28 Aug 2022 14:46:14 +0200 Subject: MDEV-29348 rpl.rpl_rewrt_db test fails with [gdb,manual-gdb] with wrong parsing Reviewer: Closes PR #2244 --- mysql-test/lib/My/Debugger.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/lib/My/Debugger.pm b/mysql-test/lib/My/Debugger.pm index f472a4c3316..e7428572ca4 100644 --- a/mysql-test/lib/My/Debugger.pm +++ b/mysql-test/lib/My/Debugger.pm @@ -144,7 +144,7 @@ sub do_args($$$$$) { my $v = $debuggers{$k}; # on windows mtr args are quoted (for system), otherwise not (for exec) - sub quote($) { $_[0] =~ /[; ]/ ? "\"$_[0]\"" : $_[0] } + sub quote($) { $_[0] =~ /[; >]/ ? "\"$_[0]\"" : $_[0] } sub unquote($) { $_[0] =~ s/^"(.*)"$/$1/; $_[0] } sub quote_from_mtr($) { IS_WINDOWS() ? $_[0] : quote($_[0]) } sub unquote_for_mtr($) { IS_WINDOWS() ? $_[0] : unquote($_[0]) } -- cgit v1.2.1 From 112870d7b406df38fc86f5ec09ae8c82733de4a9 Mon Sep 17 00:00:00 2001 From: Christian Gonzalez Date: Mon, 28 Nov 2022 21:20:23 +0000 Subject: MDEV-16735 Ensure mysql_upgrade works when changing alter_algorithm MDEV-16735 describes how mysql_upgrade fails when alter_algorithm is set to a value different than 'DEFAULT'/'COPY'. It was marked as fixed by 0ee0868, but the fix didn't covered the possibility of having the global value of alter_algorithm set to something different than 'DEFAULT'/'COPY'. To ensure that the upgrade process works properly regardless the global value of alter_altorithm, this commit force it's value to 'DEFAULT' (note the quotes) for the mysql_upgrade session. All new code of the whole pull request, including one or several files that are either new files or modified ones, are contributed under the BSD-new license. I am contributing on behalf of my employer Amazon Web Services, Inc. --- mysql-test/main/mysql_upgrade.result | 59 ++++++++++++++++++++++++++++++++++++ mysql-test/main/mysql_upgrade.test | 13 ++++++++ scripts/mysql_system_tables_fix.sql | 2 +- 3 files changed, 73 insertions(+), 1 deletion(-) diff --git a/mysql-test/main/mysql_upgrade.result b/mysql-test/main/mysql_upgrade.result index 547bd8ae3b7..bde6893526e 100644 --- a/mysql-test/main/mysql_upgrade.result +++ b/mysql-test/main/mysql_upgrade.result @@ -920,4 +920,63 @@ GRANT USAGE ON *.* TO `user3`@`%` GRANT ALL PRIVILEGES ON `roelt`.`test2` TO `user3`@`%` DROP USER 'user3'@'%'; update mysql.db set Delete_history_priv='Y' where db like 'test%'; +# +# MDEV-16735 Upgrades only work if 'alter_algorithm' is 'DEFAULT' +# or 'COPY'. Test that the session value 'DEFAULT' in mysql_upgrade +# properly overrides the potentially incompatible global value. +# +SET GLOBAL alter_algorithm='INPLACE'; +SHOW GLOBAL VARIABLES LIKE 'alter_algorithm'; +Variable_name Value +alter_algorithm INPLACE +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.gtid_slave_pos OK +mysql.help_category OK +mysql.help_keyword OK +mysql.help_relation OK +mysql.help_topic OK +mysql.host OK +mysql.index_stats OK +mysql.innodb_index_stats OK +mysql.innodb_table_stats OK +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 OK +mysql.user OK +Phase 2/7: Installing used storage engines... Skipped +Phase 3/7: Fixing views +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 +SET GLOBAL alter_algorithm=DEFAULT; +SHOW GLOBAL VARIABLES LIKE 'alter_algorithm'; +Variable_name Value +alter_algorithm DEFAULT End of 10.3 tests diff --git a/mysql-test/main/mysql_upgrade.test b/mysql-test/main/mysql_upgrade.test index acc4fc31d65..5d8a89b08d4 100644 --- a/mysql-test/main/mysql_upgrade.test +++ b/mysql-test/main/mysql_upgrade.test @@ -381,4 +381,17 @@ SHOW GRANTS FOR 'user3'@'%'; DROP USER 'user3'@'%'; update mysql.db set Delete_history_priv='Y' where db like 'test%'; +--echo # +--echo # MDEV-16735 Upgrades only work if 'alter_algorithm' is 'DEFAULT' +--echo # or 'COPY'. Test that the session value 'DEFAULT' in mysql_upgrade +--echo # properly overrides the potentially incompatible global value. +--echo # + +SET GLOBAL alter_algorithm='INPLACE'; +SHOW GLOBAL VARIABLES LIKE 'alter_algorithm'; +--exec $MYSQL_UPGRADE --force 2>&1 +SET GLOBAL alter_algorithm=DEFAULT; +SHOW GLOBAL VARIABLES LIKE 'alter_algorithm'; +--remove_file $MYSQLD_DATADIR/mysql_upgrade_info + --echo End of 10.3 tests diff --git a/scripts/mysql_system_tables_fix.sql b/scripts/mysql_system_tables_fix.sql index 79866d149bb..47099399722 100644 --- a/scripts/mysql_system_tables_fix.sql +++ b/scripts/mysql_system_tables_fix.sql @@ -27,7 +27,7 @@ set sql_mode=''; set storage_engine=MyISAM; set enforce_storage_engine=NULL; -set alter_algorithm=DEFAULT; +set alter_algorithm='DEFAULT'; ALTER TABLE user add File_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL; -- cgit v1.2.1 From 5b275b41aa969f08634f62414ce2fd570418feaf Mon Sep 17 00:00:00 2001 From: Monty Date: Tue, 18 Oct 2022 13:02:32 +0300 Subject: Enable valgrind for replication test The following tests are disabled when running --valgrding without --big: - rpl.rpl_ssl - rpl.rpl_semi_sync_event - All encryption test (which includes have_file_key_management.inc) --- mysql-test/include/have_file_key_management.inc | 6 ++++++ mysql-test/include/master-slave.inc | 2 -- mysql-test/suite/rpl/include/rpl_ssl.inc | 1 + mysql-test/suite/rpl/t/rpl_semi_sync_event.test | 1 + 4 files changed, 8 insertions(+), 2 deletions(-) diff --git a/mysql-test/include/have_file_key_management.inc b/mysql-test/include/have_file_key_management.inc index 06fbb510d6b..68ef49a42d9 100644 --- a/mysql-test/include/have_file_key_management.inc +++ b/mysql-test/include/have_file_key_management.inc @@ -2,3 +2,9 @@ if (`SELECT COUNT(*)=0 FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME = 'file { --skip Test requires file_key_management plugin } + +# +# This file is only included when using encryption. As all encryption test are +# very slow with valgrind, lets disable these if not run with --big +# +--source include/no_valgrind_without_big.inc diff --git a/mysql-test/include/master-slave.inc b/mysql-test/include/master-slave.inc index 5b603fbfdb3..9ed206b2c22 100644 --- a/mysql-test/include/master-slave.inc +++ b/mysql-test/include/master-slave.inc @@ -1,5 +1,3 @@ ---source include/no_valgrind_without_big.inc - # ==== Purpose ==== # # Configure two servers to be replication master and slave. diff --git a/mysql-test/suite/rpl/include/rpl_ssl.inc b/mysql-test/suite/rpl/include/rpl_ssl.inc index bd77f213ae1..59a2af9f137 100644 --- a/mysql-test/suite/rpl/include/rpl_ssl.inc +++ b/mysql-test/suite/rpl/include/rpl_ssl.inc @@ -6,6 +6,7 @@ source include/have_ssl_communication.inc; source include/master-slave.inc; +source include/no_valgrind_without_big.inc; # create a user for replication that requires ssl encryption connection master; diff --git a/mysql-test/suite/rpl/t/rpl_semi_sync_event.test b/mysql-test/suite/rpl/t/rpl_semi_sync_event.test index 4d96fd694ec..7a7e1c1e074 100644 --- a/mysql-test/suite/rpl/t/rpl_semi_sync_event.test +++ b/mysql-test/suite/rpl/t/rpl_semi_sync_event.test @@ -1,6 +1,7 @@ source include/not_embedded.inc; source include/have_innodb.inc; source include/master-slave.inc; +source include/no_valgrind_without_big.inc; let $engine_type= InnoDB; -- cgit v1.2.1 From f9c418c67d9a1339364358fe5974547e3f9c511c Mon Sep 17 00:00:00 2001 From: Monty Date: Mon, 28 Nov 2022 16:17:31 +0200 Subject: Fixed the BUILD scripts to work outside of a git repository --- BUILD/FINISH.sh | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/BUILD/FINISH.sh b/BUILD/FINISH.sh index 037b5ae5754..87077676c31 100644 --- a/BUILD/FINISH.sh +++ b/BUILD/FINISH.sh @@ -48,11 +48,15 @@ commands="$commands path=`dirname $0` . \"$path/autorun.sh\"" -if [ -z "$just_clean" ] +if [ -z "$just_clean"] then -commands="$commands -git submodule update -CC=\"$CC\" CFLAGS=\"$cflags\" CXX=\"$CXX\" CXXFLAGS=\"$cxxflags\" CXXLDFLAGS=\"$CXXLDFLAGS\" $configure" + if test -d .git + then + commands="$commands + git submodule update" + fi + commands="$commands + CC=\"$CC\" CFLAGS=\"$cflags\" CXX=\"$CXX\" CXXFLAGS=\"$cxxflags\" CXXLDFLAGS=\"$CXXLDFLAGS\" $configure" fi if [ -z "$just_configure" -a -z "$just_clean" ] -- cgit v1.2.1 From f208f6fb6fff31b9216f059ead435397ca74b56c Mon Sep 17 00:00:00 2001 From: Monty Date: Mon, 28 Nov 2022 18:07:43 +0200 Subject: Safety fix Ensure that all memory allocated by TABLE_LIST::change_refs_to_fields() is in the same memory root! --- sql/table.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/sql/table.cc b/sql/table.cc index 9dc7cabffc6..54a1e8b1b57 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -8822,15 +8822,16 @@ bool TABLE_LIST::change_refs_to_fields() List_iterator li(used_items); Item_direct_ref *ref; Field_iterator_view field_it; + Name_resolution_context *ctx; THD *thd= table->in_use; + Item **materialized_items; DBUG_ASSERT(is_merged_derived()); if (!used_items.elements) return FALSE; - Item **materialized_items= - (Item **)thd->calloc(sizeof(void *) * table->s->fields); - Name_resolution_context *ctx= new Name_resolution_context(this); + materialized_items= (Item **)thd->calloc(sizeof(void *) * table->s->fields); + ctx= new (thd->mem_root) Name_resolution_context(this); if (!materialized_items || !ctx) return TRUE; -- cgit v1.2.1 From b8ad6fbd95830b61d282abc1167300fff261be7e Mon Sep 17 00:00:00 2001 From: Monty Date: Mon, 28 Nov 2022 18:37:55 +0200 Subject: Fixed warning from innodb.create_isl_with_direct if have_symlink is disabled --- mysql-test/suite/innodb/t/create_isl_with_direct.test | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/mysql-test/suite/innodb/t/create_isl_with_direct.test b/mysql-test/suite/innodb/t/create_isl_with_direct.test index 2092d03b72f..c6a9fbcb739 100644 --- a/mysql-test/suite/innodb/t/create_isl_with_direct.test +++ b/mysql-test/suite/innodb/t/create_isl_with_direct.test @@ -1,14 +1,13 @@ ---source include/not_embedded.inc ---source include/have_innodb.inc ---source include/have_symlink.inc - --disable_query_log -CALL mtr.add_suppression(".*Failed to set O_DIRECT on file.*"); - +call mtr.add_suppression("InnoDB: Failed to set .*DIRECT"); # The below mtr suppression to avoid failure in solaris platform. CALL mtr.add_suppression("\\[ERROR\\] InnoDB: Failed to set DIRECTIO_ON on file.*"); --enable_query_log +--source include/not_embedded.inc +--source include/have_innodb.inc +--source include/have_symlink.inc + SHOW VARIABLES LIKE 'innodb_flush_method'; let MYSQLD_DATADIR=`SELECT @@datadir`; -- cgit v1.2.1 From 499ef7bf23f6fe32ed261df04c4a2ca067961e77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 29 Nov 2022 11:06:29 +0200 Subject: Add a global suppression for O_DIRECT failures Fixes up commit b8ad6fbd95830b61d282abc1167300fff261be7e --- mysql-test/mysql-test-run.pl | 1 + mysql-test/suite/innodb/t/create_isl_with_direct.test | 6 ------ 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 60955ac61a7..12afab4d28c 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -4521,6 +4521,7 @@ sub extract_warning_lines ($$) { qr|Linux Native AIO|, # warning that aio does not work on /dev/shm qr|InnoDB: io_setup\(\) attempt|, qr|InnoDB: io_setup\(\) failed with EAGAIN|, + qr/InnoDB: Failed to set (O_DIRECT|DIRECTIO_ON) on file/, qr|setrlimit could not change the size of core files to 'infinity';|, qr|feedback plugin: failed to retrieve the MAC address|, qr|Plugin 'FEEDBACK' init function returned error|, diff --git a/mysql-test/suite/innodb/t/create_isl_with_direct.test b/mysql-test/suite/innodb/t/create_isl_with_direct.test index c6a9fbcb739..45d7fbf4ea5 100644 --- a/mysql-test/suite/innodb/t/create_isl_with_direct.test +++ b/mysql-test/suite/innodb/t/create_isl_with_direct.test @@ -1,9 +1,3 @@ ---disable_query_log -call mtr.add_suppression("InnoDB: Failed to set .*DIRECT"); -# The below mtr suppression to avoid failure in solaris platform. -CALL mtr.add_suppression("\\[ERROR\\] InnoDB: Failed to set DIRECTIO_ON on file.*"); ---enable_query_log - --source include/not_embedded.inc --source include/have_innodb.inc --source include/have_symlink.inc -- cgit v1.2.1 From 9a95838a96a5bbdc2c2064de968e4d686bd6d666 Mon Sep 17 00:00:00 2001 From: Robin Newhouse Date: Tue, 29 Nov 2022 05:27:56 -0800 Subject: [MDEV-30002] Skip bad_startup_options test when running as root (#2344) Commit 32158be added a new test `bad_startup_options`. This test fails if run as root, which is common on many CI systems. This test should include `not_as_root.inc` so it is skipped, just like all other similar tests in MariaDB. All new code of the whole pull request, including one or several files that are either new files or modified ones, are contributed under the BSD-new license. I am contributing on behalf of my employer Amazon Web Services, Inc. --- mysql-test/main/bad_startup_options.test | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mysql-test/main/bad_startup_options.test b/mysql-test/main/bad_startup_options.test index bd0b6283854..e758d786049 100644 --- a/mysql-test/main/bad_startup_options.test +++ b/mysql-test/main/bad_startup_options.test @@ -1,3 +1,6 @@ +# mysqld refuses to run as root normally. +--source include/not_as_root.inc + --source include/not_embedded.inc --source include/have_ssl_communication.inc -- cgit v1.2.1 From 6c973be2e9f6068507d42ccb644ff0a92e164d08 Mon Sep 17 00:00:00 2001 From: Anel Husakovic Date: Mon, 28 Nov 2022 16:29:20 +0100 Subject: MDEV-28299: Server crashes in XINDXS::Range/CntIndexRange (Connect engine) - Bug happens only in case when the range function on empty key single column index (XINDEXS) is used. - Solution is to return with empty result in this scenario. Reviewed by: <> --- storage/connect/mysql-test/connect/r/index.result | 36 +++++++++++++++++++++++ storage/connect/mysql-test/connect/t/index.test | 26 ++++++++++++++++ storage/connect/xindex.cpp | 4 +++ 3 files changed, 66 insertions(+) diff --git a/storage/connect/mysql-test/connect/r/index.result b/storage/connect/mysql-test/connect/r/index.result index bffaaecc785..edeca2d1960 100644 --- a/storage/connect/mysql-test/connect/r/index.result +++ b/storage/connect/mysql-test/connect/r/index.result @@ -139,3 +139,39 @@ DELETE FROM t1; DROP TABLE t1; DROP TABLE t2; DROP TABLE t3; +# +# MDEV-28299: Server crashes in +# XINDXS::Range/CntIndexRange (Connect engine) +# +CREATE TABLE t1 ( a int not null, KEY (a))engine=CONNECT; +Warnings: +Warning 1105 No table_type. Will be set to DOS +Warning 1105 No file name. Table will use t1.dos +SELECT * FROM t1 WHERE a=1; +a +INSERT INTO t1 values (1),(2),(1); +SELECT * FROM t1 WHERE a=1; +a +1 +1 +DROP TABLE t1; +CREATE TABLE t1 (a int, b int, pk int, PRIMARY KEY (pk)) engine=CONNECT; +Warnings: +Warning 1105 No table_type. Will be set to DOS +Warning 1105 No file name. Table will use t1.dos +SELECT x.a +FROM t1 AS x JOIN t1 AS y ON (x.a = y.b) +WHERE x.pk > 3; +a +INSERT INTO t1 values (1,2,1),(2,1,2),(1,2,3),(3,4,4); +SELECT x.a +FROM t1 AS x JOIN t1 AS y ON (x.a = y.b) +WHERE x.pk > 3; +a +INSERT INTO t1 values (1,2,5); +SELECT x.a +FROM t1 AS x JOIN t1 AS y ON (x.a = y.b) +WHERE x.pk > 3; +a +1 +DROP TABLE t1; diff --git a/storage/connect/mysql-test/connect/t/index.test b/storage/connect/mysql-test/connect/t/index.test index 5e913582734..9dc6357074d 100644 --- a/storage/connect/mysql-test/connect/t/index.test +++ b/storage/connect/mysql-test/connect/t/index.test @@ -84,3 +84,29 @@ DROP TABLE t3; --remove_file $MYSQLD_DATADIR/test/emp.txt --remove_file $MYSQLD_DATADIR/test/sexe.csv --remove_file $MYSQLD_DATADIR/test/sitmat.csv + +--echo # +--echo # MDEV-28299: Server crashes in +--echo # XINDXS::Range/CntIndexRange (Connect engine) +--echo # + +CREATE TABLE t1 ( a int not null, KEY (a))engine=CONNECT; +SELECT * FROM t1 WHERE a=1; + +INSERT INTO t1 values (1),(2),(1); +SELECT * FROM t1 WHERE a=1; +DROP TABLE t1; + +CREATE TABLE t1 (a int, b int, pk int, PRIMARY KEY (pk)) engine=CONNECT; +SELECT x.a +FROM t1 AS x JOIN t1 AS y ON (x.a = y.b) +WHERE x.pk > 3; +INSERT INTO t1 values (1,2,1),(2,1,2),(1,2,3),(3,4,4); +SELECT x.a +FROM t1 AS x JOIN t1 AS y ON (x.a = y.b) +WHERE x.pk > 3; +INSERT INTO t1 values (1,2,5); +SELECT x.a +FROM t1 AS x JOIN t1 AS y ON (x.a = y.b) +WHERE x.pk > 3; +DROP TABLE t1; diff --git a/storage/connect/xindex.cpp b/storage/connect/xindex.cpp index 9892bf889ce..334a70c4688 100644 --- a/storage/connect/xindex.cpp +++ b/storage/connect/xindex.cpp @@ -2028,6 +2028,10 @@ int XINDXS::Range(PGLOBAL g, int limit, bool incl) PXCOL kp = To_KeyCol; OPVAL op = Op; +// In case single column index doesn't exist return + if (!kp) + return 0; + switch (limit) { case 1: Op = (incl) ? OP_GE : OP_GT; break; case 2: Op = (incl) ? OP_GT : OP_GE; break; -- cgit v1.2.1 From b527bfe82310dba39894feff61a1cd7d76a8cc4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vicen=C8=9Biu=20Ciorbaru?= Date: Thu, 24 Nov 2022 19:50:14 +0200 Subject: MDEV-30023 Revoking Privilege on the Column Yields the Error The change from MDEV-29465 exposed a flaw in replace_column_table where again we were not properly updating the column-level bits. replace_table_table was changed in MDEV-29465 to properly update grant_table->init_cols, however replace_column_table still only modified grant_column->rights when the GRANT_COLUMN already existed. This lead to a missmatch between GRANT_COLUMN::init_rights and GRANT_COLUMN::rights, *if* the GRANT_COLUMN already existed. As an example: GRANT SELECT (col1) ... Here: For col1 GRANT_COLUMN::init_rights and GRANT_COLUMN::rights are set to 1 (SELECT) in replace_column_table. GRANT INSERT (col1) ... Here, without this patch GRANT_COLUMN::init_rights is still 1 and GRANT_COLUMN::rights is 3 (SELECT_PRIV | INSERT_PRIV) Finally, if before this patch, one does: REVOKE SELECT (col1) ... replace_table_table will see that init_rights loses bit 1 thus it considers there are no more rights granted on that particular table. This prompts the whole GRANT_TABLE to be removed via the first revoke, when the GRANT_COLUMN corresponding to it should still have init_rights == 2. By also updating replace_column_table to keep init_rights in sync properly, the issue is resolved. Reviewed by --- mysql-test/main/grant5.result | 24 ++++++++++++++++++++++++ mysql-test/main/grant5.test | 19 +++++++++++++++++++ sql/sql_acl.cc | 7 +++++-- 3 files changed, 48 insertions(+), 2 deletions(-) diff --git a/mysql-test/main/grant5.result b/mysql-test/main/grant5.result index 908a05aadf1..dc8ee527378 100644 --- a/mysql-test/main/grant5.result +++ b/mysql-test/main/grant5.result @@ -296,4 +296,28 @@ drop database db; drop user foo@localhost; drop user bar@localhost; drop user buz@localhost; +CREATE USER foo; +CREATE DATABASE db; +CREATE TABLE db.test_getcolpriv(col1 INT, col2 INT); +GRANT SELECT (col1,col2) ON db.test_getcolpriv TO foo; +GRANT INSERT (col1) ON db.test_getcolpriv TO foo; +SHOW GRANTS FOR foo; +Grants for foo@% +GRANT USAGE ON *.* TO `foo`@`%` +GRANT SELECT (col2, col1), INSERT (col1) ON `db`.`test_getcolpriv` TO `foo`@`%` +REVOKE SELECT (col1,col2) ON db.test_getcolpriv FROM foo; +SHOW GRANTS FOR foo; +Grants for foo@% +GRANT USAGE ON *.* TO `foo`@`%` +GRANT INSERT (col1) ON `db`.`test_getcolpriv` TO `foo`@`%` +REVOKE INSERT (col1) ON db.test_getcolpriv FROM foo; +SHOW GRANTS FOR foo; +Grants for foo@% +GRANT USAGE ON *.* TO `foo`@`%` +FLUSH PRIVILEGES; +SHOW GRANTS FOR foo; +Grants for foo@% +GRANT USAGE ON *.* TO `foo`@`%` +DROP USER foo; +DROP DATABASE db; # End of 10.3 tests diff --git a/mysql-test/main/grant5.test b/mysql-test/main/grant5.test index 35df5a6ec03..cff63d2a9f9 100644 --- a/mysql-test/main/grant5.test +++ b/mysql-test/main/grant5.test @@ -259,4 +259,23 @@ drop user foo@localhost; drop user bar@localhost; drop user buz@localhost; +CREATE USER foo; +CREATE DATABASE db; +CREATE TABLE db.test_getcolpriv(col1 INT, col2 INT); + +GRANT SELECT (col1,col2) ON db.test_getcolpriv TO foo; +GRANT INSERT (col1) ON db.test_getcolpriv TO foo; + +SHOW GRANTS FOR foo; +REVOKE SELECT (col1,col2) ON db.test_getcolpriv FROM foo; +SHOW GRANTS FOR foo; +REVOKE INSERT (col1) ON db.test_getcolpriv FROM foo; + +SHOW GRANTS FOR foo; +FLUSH PRIVILEGES; +SHOW GRANTS FOR foo; + +DROP USER foo; +DROP DATABASE db; + --echo # End of 10.3 tests diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 059a6ed4127..b48a4d2fc8d 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -5148,8 +5148,11 @@ static int replace_column_table(GRANT_TABLE *g_t, error= 0; grant_column= column_hash_search(g_t, column->column.ptr(), column->column.length()); - if (grant_column) // Should always be true - grant_column->rights= privileges; // Update hash + if (grant_column) // Should always be true + { + grant_column->rights= privileges; // Update hash + grant_column->init_rights= privileges; + } } else // new grant { -- cgit v1.2.1 From cc86360f4afb5b7b9fe64bbffef18538b2e3589b Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Thu, 1 Dec 2022 16:34:17 +0300 Subject: MDEV-30112 ASAN errors in Item_ident::print / generate_partition_syntax Like in MDEV-16110 we must release items allocated on thd->mem_root by reopening the table. MDEV-16290 relocated MDEV-16110 fix in 10.5 so it works for MDEV-28576 as well. 10.3 without MDEV-16290 now duplicates this fix. --- mysql-test/main/partition_alter.result | 13 +++++++++++++ mysql-test/main/partition_alter.test | 10 ++++++++++ sql/sql_table.cc | 2 ++ 3 files changed, 25 insertions(+) diff --git a/mysql-test/main/partition_alter.result b/mysql-test/main/partition_alter.result index 2b0a09d2653..09a6cec2ed8 100644 --- a/mysql-test/main/partition_alter.result +++ b/mysql-test/main/partition_alter.result @@ -211,4 +211,17 @@ Table Op Msg_type Msg_text test.t check status OK delete from t order by b limit 1; drop table t; +# +# MDEV-30112 ASAN errors in Item_ident::print / generate_partition_syntax +# +create table t (a int) partition by hash(a); +alter table t change a b int, drop a; +ERROR 42S22: Unknown column 'a' in 't' +show create table t; +Table Create Table +t CREATE TABLE `t` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci + PARTITION BY HASH (`a`) +drop table t; # End of 10.3 tests diff --git a/mysql-test/main/partition_alter.test b/mysql-test/main/partition_alter.test index 7a80779e386..1228ccf7ac9 100644 --- a/mysql-test/main/partition_alter.test +++ b/mysql-test/main/partition_alter.test @@ -196,4 +196,14 @@ delete from t order by b limit 1; # cleanup drop table t; +--echo # +--echo # MDEV-30112 ASAN errors in Item_ident::print / generate_partition_syntax +--echo # +create table t (a int) partition by hash(a); +--error ER_BAD_FIELD_ERROR +alter table t change a b int, drop a; +show create table t; +# Cleanup +drop table t; + --echo # End of 10.3 tests diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 413d78ae814..042ed9e1d6f 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -8328,6 +8328,8 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, } /* if (def->change.str) */ } /* while (def) */ } /* if (part_field_list || subpart_field_list) */ + // Force reopen because new column name is on thd->mem_root + table->mark_table_for_reopen(); } /* if (part_info) */ } #endif -- cgit v1.2.1 From b91b4e0b970381603b42e52d701a4f5a176ccfd6 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Thu, 1 Dec 2022 15:04:59 +0400 Subject: MDEV-28696 View created as "select b''; " references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them --- mysql-test/main/varbinary.test | 3 --- mysql-test/main/view.result | 8 ++++++++ mysql-test/main/view.test | 9 +++++++++ sql/item.cc | 19 +++++++++++++++++++ sql/item.h | 1 + 5 files changed, 37 insertions(+), 3 deletions(-) diff --git a/mysql-test/main/varbinary.test b/mysql-test/main/varbinary.test index b35819b0fb3..19e0e88932e 100644 --- a/mysql-test/main/varbinary.test +++ b/mysql-test/main/varbinary.test @@ -149,12 +149,9 @@ select N'', length(N''); select '', length(''); --enable_view_protocol -#enable after fix MDEV-28696 ---disable_view_protocol select b'', 0+b''; select x'', 0+x''; ---enable_view_protocol --error ER_BAD_FIELD_ERROR select 0x; diff --git a/mysql-test/main/view.result b/mysql-test/main/view.result index fd84cff9fa1..7354e1dbb91 100644 --- a/mysql-test/main/view.result +++ b/mysql-test/main/view.result @@ -6905,5 +6905,13 @@ deallocate prepare stmt; drop view v1; drop table t1; # +# MDEV-28696 View created as "select b''; " references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them +# +CREATE VIEW v1 as select b''; +SELECT * FROM v1; +b'' + +DROP VIEW v1; +# # End of 10.3 tests # diff --git a/mysql-test/main/view.test b/mysql-test/main/view.test index 038c7107d07..987e96fc79d 100644 --- a/mysql-test/main/view.test +++ b/mysql-test/main/view.test @@ -6644,6 +6644,15 @@ deallocate prepare stmt; drop view v1; drop table t1; +--echo # +--echo # MDEV-28696 View created as "select b''; " references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them +--echo # + +CREATE VIEW v1 as select b''; +SELECT * FROM v1; +DROP VIEW v1; + + --echo # --echo # End of 10.3 tests --echo # diff --git a/sql/item.cc b/sql/item.cc index 012dcebdaee..757f09dec01 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -7409,6 +7409,25 @@ Item_bin_string::Item_bin_string(THD *thd, const char *str, size_t str_length): } +void Item_bin_string::print(String *str, enum_query_type query_type) +{ + if (!str_value.length()) + { + /* + Historically a bit string such as b'01100001' + prints itself in the hex hybrid notation: 0x61 + In case of an empty bit string b'', the hex hybrid + notation would result in a bad syntax: 0x + So let's print empty bit strings using bit string notation: b'' + */ + static const LEX_CSTRING empty_bit_string= {STRING_WITH_LEN("b''")}; + str->append(empty_bit_string); + } + else + Item_hex_hybrid::print(str, query_type); +} + + bool Item_temporal_literal::eq(const Item *item, bool binary_cmp) const { return diff --git a/sql/item.h b/sql/item.h index a291678529e..07fbe848bb7 100644 --- a/sql/item.h +++ b/sql/item.h @@ -4490,6 +4490,7 @@ class Item_bin_string: public Item_hex_hybrid { public: Item_bin_string(THD *thd, const char *str, size_t str_length); + void print(String *str, enum_query_type query_type); }; -- cgit v1.2.1 From 126619047a6ce270fb1d6b9717a2194048fe33a8 Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Fri, 2 Dec 2022 11:59:36 +0100 Subject: MDEV-28643: view protocol fails due to different column name Decent name given to the column. --- mysql-test/main/func_encrypt_ucs2.result | 8 ++++---- mysql-test/main/func_encrypt_ucs2.test | 5 ++--- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/mysql-test/main/func_encrypt_ucs2.result b/mysql-test/main/func_encrypt_ucs2.result index 5ab3b08fb5d..989d593da8f 100644 --- a/mysql-test/main/func_encrypt_ucs2.result +++ b/mysql-test/main/func_encrypt_ucs2.result @@ -9,11 +9,11 @@ CONVERT(DES_ENCRYPT(0, CHAR('1' USING ucs2)),UNSIGNED) 0 Warnings: Warning 1292 Truncated incorrect INTEGER value: '\xFFT\xDCiK\x92j\xE6\xFC' -SELECT CHAR_LENGTH(DES_DECRYPT(0xFF0DC9FC9537CA75F4, CHAR('1' USING ucs2))); -CHAR_LENGTH(DES_DECRYPT(0xFF0DC9FC9537CA75F4, CHAR('1' USING ucs2))) +SELECT CHAR_LENGTH(DES_DECRYPT(0xFF0DC9FC9537CA75F4, CHAR('1' USING ucs2))) as a; +a 4 -SELECT CONVERT(DES_DECRYPT(0xFF0DC9FC9537CA75F4, CHAR('1' using ucs2)), UNSIGNED); -CONVERT(DES_DECRYPT(0xFF0DC9FC9537CA75F4, CHAR('1' using ucs2)), UNSIGNED) +SELECT CONVERT(DES_DECRYPT(0xFF0DC9FC9537CA75F4, CHAR('1' using ucs2)), UNSIGNED) as a; +a 0 Warnings: Warning 1292 Truncated incorrect INTEGER value: 'test' diff --git a/mysql-test/main/func_encrypt_ucs2.test b/mysql-test/main/func_encrypt_ucs2.test index 6c1306955aa..088af7ffee7 100644 --- a/mysql-test/main/func_encrypt_ucs2.test +++ b/mysql-test/main/func_encrypt_ucs2.test @@ -8,8 +8,7 @@ SELECT CHAR_LENGTH(DES_ENCRYPT(0, CHAR('1' USING ucs2))); SELECT CONVERT(DES_ENCRYPT(0, CHAR('1' USING ucs2)),UNSIGNED); -#enable after fix MDEV-28643, MDEV-27871 --disable_view_protocol -SELECT CHAR_LENGTH(DES_DECRYPT(0xFF0DC9FC9537CA75F4, CHAR('1' USING ucs2))); -SELECT CONVERT(DES_DECRYPT(0xFF0DC9FC9537CA75F4, CHAR('1' using ucs2)), UNSIGNED); +SELECT CHAR_LENGTH(DES_DECRYPT(0xFF0DC9FC9537CA75F4, CHAR('1' USING ucs2))) as a; +SELECT CONVERT(DES_DECRYPT(0xFF0DC9FC9537CA75F4, CHAR('1' using ucs2)), UNSIGNED) as a; --enable_view_protocol -- cgit v1.2.1 From 4fb8f7d07a23b1ac1249dd1f60195ff946450c79 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 1 Nov 2022 20:46:48 +0100 Subject: cleanup: clarify innobase_init_vc_templ usage --- storage/innobase/handler/ha_innodb.cc | 9 +++------ storage/innobase/row/row0ins.cc | 6 +----- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 81236343642..9b6736bf993 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -20981,16 +20981,13 @@ static TABLE* innodb_find_table_for_vc(THD* thd, dict_table_t* table) return mysql_table; } -/** Get the computed value by supplying the base column values. -@param[in,out] table table whose virtual column - template to be built */ +/** Only used by the purge thread +@param[in,out] table table whose virtual column template to be built */ TABLE* innobase_init_vc_templ(dict_table_t* table) { - if (table->vc_templ != NULL) { - return NULL; - } DBUG_ENTER("innobase_init_vc_templ"); + ut_ad(table->vc_templ == NULL); table->vc_templ = UT_NEW_NOKEY(dict_vcol_templ_t()); TABLE *mysql_table= innodb_find_table_for_vc(current_thd, table); diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc index 8330e3ef0c8..2683ad8251f 100644 --- a/storage/innobase/row/row0ins.cc +++ b/storage/innobase/row/row0ins.cc @@ -899,11 +899,7 @@ row_ins_foreign_fill_virtual( &ext, update->heap); n_diff = update->n_fields; - if (index->table->vc_templ == NULL) { - /** This can occur when there is a cascading - delete or update after restart. */ - innobase_init_vc_templ(index->table); - } + ut_ad(index->table->vc_templ != NULL); ib_vcol_row vc(NULL); uchar *record = vc.record(thd, index, &mysql_table); -- cgit v1.2.1 From d08f2ab6d61b1b431be3c003c4ecc9495faebffc Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 1 Nov 2022 19:50:20 +0100 Subject: MDEV-28855 SEGV around dict_free_vc_templ during DROP INDEX protect shared dict_table_t::vc_templ with a mutex, same as in ha_innobase::open --- storage/innobase/handler/ha_innodb.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 9b6736bf993..aa1bc5844e3 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -20988,7 +20988,6 @@ TABLE* innobase_init_vc_templ(dict_table_t* table) DBUG_ENTER("innobase_init_vc_templ"); ut_ad(table->vc_templ == NULL); - table->vc_templ = UT_NEW_NOKEY(dict_vcol_templ_t()); TABLE *mysql_table= innodb_find_table_for_vc(current_thd, table); @@ -20998,6 +20997,7 @@ TABLE* innobase_init_vc_templ(dict_table_t* table) } mutex_enter(&dict_sys->mutex); + table->vc_templ = UT_NEW_NOKEY(dict_vcol_templ_t()); innobase_build_v_templ(mysql_table, table, table->vc_templ, NULL, true); mutex_exit(&dict_sys->mutex); DBUG_RETURN(mysql_table); -- cgit v1.2.1 From da3fc33e88c70bc526a7e03dfe9c3e701a1a1892 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 23 Nov 2022 00:35:14 +0100 Subject: cleanup: union.test --- mysql-test/main/union.result | 1 - mysql-test/main/union.test | 44 ++++++++++++++++++++------------------------ 2 files changed, 20 insertions(+), 25 deletions(-) diff --git a/mysql-test/main/union.result b/mysql-test/main/union.result index 717f7e1c4ec..bf65bbd44d1 100644 --- a/mysql-test/main/union.result +++ b/mysql-test/main/union.result @@ -1,4 +1,3 @@ -drop table if exists t1,t2,t3,t4,t5,t6; CREATE TABLE t1 (a int not null, b char (10) not null); insert into t1 values(1,'a'),(2,'b'),(3,'c'),(3,'c'); CREATE TABLE t2 (a int not null, b char (10) not null); diff --git a/mysql-test/main/union.test b/mysql-test/main/union.test index a3a672e2937..eff3cfd260b 100644 --- a/mysql-test/main/union.test +++ b/mysql-test/main/union.test @@ -2,10 +2,6 @@ # Test of unions # ---disable_warnings -drop table if exists t1,t2,t3,t4,t5,t6; ---enable_warnings - CREATE TABLE t1 (a int not null, b char (10) not null); insert into t1 values(1,'a'),(2,'b'),(3,'c'),(3,'c'); CREATE TABLE t2 (a int not null, b char (10) not null); @@ -23,7 +19,7 @@ select 't1',b,count(*) from t1 group by b UNION select 't2',b,count(*) from t2 g (select a,b from t1 limit 2) union all (select a,b from t2 order by a) limit 4; (select a,b from t1 limit 2) union all (select a,b from t2 order by a limit 1); (select a,b from t1 limit 2) union all (select a,b from t2 order by a limit 1) order by b desc; ---error 1250 +--error ER_TABLENAME_NOT_ALLOWED_HERE (select a,b from t1 limit 2) union all (select a,b from t2 order by a limit 1) order by t1.b; explain extended (select a,b from t1 limit 2) union all (select a,b from t2 order by a limit 1) order by b desc; --disable_view_protocol @@ -42,13 +38,13 @@ select found_rows(); explain select a,b from t1 union all select a,b from t2; ---error 1054 +--error ER_BAD_FIELD_ERROR explain select xx from t1 union select 1; ---error 1222 +--error ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT explain select a,b from t1 union select 1; ---error 1222 +--error ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT explain select 1 union select a,b from t1 union select 1; ---error 1222 +--error ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT explain select a,b from t1 union select 1 limit 0; --error ER_PARSE_ERROR @@ -60,19 +56,19 @@ select a,b from t1 order by a union select a,b from t2; --error ER_PARSE_ERROR insert into t3 select a from t1 order by a union select a from t2; ---error 1222 +--error ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT create table t3 select a,b from t1 union select a from t2; ---error 1222 +--error ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT select a,b from t1 union select a from t2; ---error 1222 +--error ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT select * from t1 union select a from t2; ---error 1222 +--error ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT select a from t1 union select * from t2; ---error 1234 +--error ER_CANT_USE_OPTION_HERE select * from t1 union select SQL_BUFFER_RESULT * from t2; # Test CREATE, INSERT and REPLACE @@ -86,13 +82,13 @@ drop table t1,t2,t3; # # Test some unions without tables # ---error 1096 +--error ER_NO_TABLES_USED select * union select 1; select 1 as a,(select a union select a); ---error 1054 +--error ER_BAD_FIELD_ERROR (select 1) union (select 2) order by 0; SELECT @a:=1 UNION SELECT @a:=@a+1; ---error 1054 +--error ER_BAD_FIELD_ERROR (SELECT 1) UNION (SELECT 2) ORDER BY (SELECT a); (SELECT 1,3) UNION (SELECT 2,1) ORDER BY (SELECT 2); @@ -294,7 +290,7 @@ SELECT * FROM t1 UNION SELECT * FROM t2 ORDER BY a desc LIMIT 1; (SELECT * FROM t1 ORDER by a) UNION ALL (SELECT * FROM t2 ORDER BY a) ORDER BY A desc LIMIT 4; # Wrong usage ---error 1234 +--error ER_CANT_USE_OPTION_HERE (SELECT * FROM t1) UNION all (SELECT SQL_CALC_FOUND_ROWS * FROM t2) LIMIT 1; create temporary table t1 select a from t1 union select a from t2; @@ -477,7 +473,7 @@ create table t1 select 1 union select -1; select * from t1; show create table t1; drop table t1; --- error 1267 +-- error ER_CANT_AGGREGATE_2COLLATIONS create table t1 select _latin1"test" union select _latin2"testt" ; create table t1 select _latin2"test" union select _latin2"testt" ; show create table t1; @@ -585,7 +581,7 @@ set sql_select_limit=default; # CREATE TABLE t1 (i int(11) default NULL,c char(1) default NULL,KEY i (i)); CREATE TABLE t2 (i int(11) default NULL,c char(1) default NULL,KEY i (i)); ---error 1054 +--error ER_BAD_FIELD_ERROR explain (select * from t1) union (select * from t2) order by not_existing_column; drop table t1, t2; @@ -687,7 +683,7 @@ drop table t1; create table t2 ( a char character set latin1 collate latin1_swedish_ci, b char character set latin1 collate latin1_german1_ci); ---error 1271 +--error ER_CANT_AGGREGATE_NCOLLATIONS create table t1 as (select a from t2) union (select b from t2); @@ -984,7 +980,7 @@ CREATE TABLE t1 (a int); INSERT INTO t1 VALUES (3),(1),(2),(4),(1); SELECT a FROM (SELECT a FROM t1 UNION SELECT a FROM t1 ORDER BY a) AS test; ---error 1054 +--error ER_BAD_FIELD_ERROR SELECT a FROM (SELECT a FROM t1 UNION SELECT a FROM t1 ORDER BY c) AS test; DROP TABLE t1; @@ -992,11 +988,11 @@ DROP TABLE t1; # # Bug#23345: Wrongly allowed INTO in a non-last select of a UNION. # ---error 1221 +--error ER_WRONG_USAGE (select 1 into @var) union (select 1); (select 1) union (select 1 into @var); select @var; ---error 1172 +--error ER_TOO_MANY_ROWS (select 2) union (select 1 into @var); # -- cgit v1.2.1 From cfb47ddde2bbbdc3065ed2b959bd4719247fbd30 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 23 Nov 2022 00:58:07 +0100 Subject: MDEV-30066 (limit + offset) union all (...) limit = incorrect result select_union_direct::send_data() only sends a record when the LIMIT ... OFFSET clause of the individual select won't skip it. Thus, select_union_direct::send_data() should not do any actions related to a sending a record if the offset of a select isn't reached yet --- mysql-test/main/union.result | 15 +++++++++++++++ mysql-test/main/union.test | 9 +++++++++ sql/sql_union.cc | 13 ++++++++----- 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/mysql-test/main/union.result b/mysql-test/main/union.result index bf65bbd44d1..8d9d9752e1d 100644 --- a/mysql-test/main/union.result +++ b/mysql-test/main/union.result @@ -2748,5 +2748,20 @@ a b c d 3 4 2 197 drop table t1,t2; # +# MDEV-30066 (limit + offset) union all (...) limit = incorrect result +# +create table t1(id int primary key auto_increment, c1 int); +insert into t1(c1) values(1),(2),(3); +(select * from t1 where c1>=1 order by c1 desc limit 2,1) union all (select * from t1 where c1>1 order by c1 desc); +id c1 +1 1 +2 2 +3 3 +(select * from t1 where c1>=1 order by c1 desc limit 2,1) union all (select * from t1 where c1>1 order by c1 desc) limit 2; +id c1 +1 1 +2 2 +drop table t1; +# # End of 10.3 tests # diff --git a/mysql-test/main/union.test b/mysql-test/main/union.test index eff3cfd260b..ba9ee278228 100644 --- a/mysql-test/main/union.test +++ b/mysql-test/main/union.test @@ -1982,6 +1982,15 @@ union (select 0 as a, 99 as b, drop table t1,t2; +--echo # +--echo # MDEV-30066 (limit + offset) union all (...) limit = incorrect result +--echo # +create table t1(id int primary key auto_increment, c1 int); +insert into t1(c1) values(1),(2),(3); +(select * from t1 where c1>=1 order by c1 desc limit 2,1) union all (select * from t1 where c1>1 order by c1 desc); +(select * from t1 where c1>=1 order by c1 desc limit 2,1) union all (select * from t1 where c1>1 order by c1 desc) limit 2; +drop table t1; + --echo # --echo # End of 10.3 tests --echo # diff --git a/sql/sql_union.cc b/sql/sql_union.cc index e831e2a479c..902e25d084e 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -551,14 +551,17 @@ int select_union_direct::send_data(List &items) { if (!limit) return false; - limit--; - if (offset) + if (!unit->offset_limit_cnt) { - offset--; - return false; + limit--; + if (offset) + { + offset--; + return false; + } + send_records++; } - send_records++; fill_record(thd, table, table->field, items, true, false); if (unlikely(thd->is_error())) return true; /* purecov: inspected */ -- cgit v1.2.1 From c7c1461b9454606eb67020a57de658c6df21730a Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Thu, 24 Nov 2022 21:51:19 +0100 Subject: fix embedded startup with no command line arguments &fake_argv cannot be cast to char*** this causes a crash when resolving --- libmysqld/lib_sql.cc | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc index a2afcabe073..3ef9ad98e0e 100644 --- a/libmysqld/lib_sql.cc +++ b/libmysqld/lib_sql.cc @@ -518,7 +518,6 @@ int init_embedded_server(int argc, char **argv, char **groups) */ int *argcp; char ***argvp; - int fake_argc = 1; char *fake_argv[] = { (char *)"", 0 }; const char *fake_groups[] = { "server", "embedded", 0 }; my_bool acl_error; @@ -531,16 +530,14 @@ int init_embedded_server(int argc, char **argv, char **groups) if (init_early_variables()) return 1; - if (argc) + if (!argc) { - argcp= &argc; - argvp= (char***) &argv; - } - else - { - argcp= &fake_argc; - argvp= (char ***) &fake_argv; + argc= 1; + argv= fake_argv; } + argcp= &argc; + argvp= &argv; + if (!groups) groups= (char**) fake_groups; -- cgit v1.2.1 From f915681d2f70f2c10dd3434dc3bb985bc31d3b1a Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 25 Nov 2022 17:52:56 +0100 Subject: MDEV-30036 NULL pointer dereference in partition_info::set_partition_bitmaps_from_table remove dead code --- sql/partition_info.cc | 21 --------------------- sql/partition_info.h | 1 - 2 files changed, 22 deletions(-) diff --git a/sql/partition_info.cc b/sql/partition_info.cc index 17a65ad8cd4..1efef6db52b 100644 --- a/sql/partition_info.cc +++ b/sql/partition_info.cc @@ -324,27 +324,6 @@ bool partition_info::set_partition_bitmaps(List *partition_names) } -/** - Set read/lock_partitions bitmap over non pruned partitions - - @param table_list Possible TABLE_LIST which can contain - list of partition names to query - - @return Operation status - @retval FALSE OK - @retval TRUE Failed to allocate memory for bitmap or list of partitions - did not match - - @note OK to call multiple times without the need for free_bitmaps. -*/ -bool partition_info::set_partition_bitmaps_from_table(TABLE_LIST *table_list) -{ - List *partition_names= table_list ? - NULL : table_list->partition_names; - return set_partition_bitmaps(partition_names); -} - - /* Create a memory area where default partition names are stored and fill it up with the names. diff --git a/sql/partition_info.h b/sql/partition_info.h index ddbb89fa605..7055dc9eb89 100644 --- a/sql/partition_info.h +++ b/sql/partition_info.h @@ -330,7 +330,6 @@ public: partition_info *get_clone(THD *thd, bool empty_data_and_index_file= FALSE); bool set_named_partition_bitmap(const char *part_name, size_t length); bool set_partition_bitmaps(List *partition_names); - bool set_partition_bitmaps_from_table(TABLE_LIST *table_list); /* Answers the question if subpartitioning is used for a certain table */ bool is_sub_partitioned() { -- cgit v1.2.1 From 53e57a8681a5ec9d1ae1b59a861a6241824ca699 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 25 Nov 2022 19:04:31 +0100 Subject: MDEV-30056 Impossible to export column grants --- mysql-test/main/fix_priv_tables.result | 4 +-- mysql-test/main/grant.result | 34 +++++++++++----------- mysql-test/main/grant2.result | 4 +-- mysql-test/main/grant3.result | 4 +-- mysql-test/main/grant5.result | 4 +-- mysql-test/main/information_schema.result | 2 +- mysql-test/suite/funcs_1/r/innodb_trig_03.result | 12 ++++---- mysql-test/suite/funcs_1/r/innodb_trig_03e.result | 12 ++++---- .../suite/funcs_1/r/is_check_constraints.result | 2 +- .../suite/funcs_1/r/is_column_privileges.result | 16 +++++----- mysql-test/suite/funcs_1/r/is_statistics.result | 8 ++--- .../suite/funcs_1/r/is_table_constraints.result | 4 +-- mysql-test/suite/funcs_1/r/memory_trig_03.result | 12 ++++---- mysql-test/suite/funcs_1/r/memory_trig_03e.result | 12 ++++---- mysql-test/suite/funcs_1/r/myisam_trig_03.result | 12 ++++---- mysql-test/suite/funcs_1/r/myisam_trig_03e.result | 12 ++++---- mysql-test/suite/roles/recursive.result | 6 ++-- mysql-test/suite/roles/recursive_dbug.result | 6 ++-- .../suite/roles/set_role-table-column-priv.result | 4 +-- mysql-test/suite/rpl/r/rpl_ignore_table.result | 8 ++--- sql/sql_acl.cc | 5 ++-- 21 files changed, 91 insertions(+), 92 deletions(-) diff --git a/mysql-test/main/fix_priv_tables.result b/mysql-test/main/fix_priv_tables.result index 3f1830aadbc..c39ebfb9227 100644 --- a/mysql-test/main/fix_priv_tables.result +++ b/mysql-test/main/fix_priv_tables.result @@ -17,7 +17,7 @@ GRANT SELECT(c1) on testdb.v1 to 'select_only_c1'@localhost; SHOW GRANTS FOR 'select_only_c1'@'localhost'; Grants for select_only_c1@localhost GRANT USAGE ON *.* TO `select_only_c1`@`localhost` -GRANT SELECT (c1) ON `testdb`.`v1` TO `select_only_c1`@`localhost` +GRANT SELECT (`c1`) ON `testdb`.`v1` TO `select_only_c1`@`localhost` "after fix privs" SHOW GRANTS FOR 'show_view_tbl'@'localhost'; @@ -28,7 +28,7 @@ GRANT CREATE VIEW, SHOW VIEW ON `testdb`.`v1` TO `show_view_tbl`@`localhost` SHOW GRANTS FOR 'select_only_c1'@'localhost'; Grants for select_only_c1@localhost GRANT USAGE ON *.* TO `select_only_c1`@`localhost` -GRANT SELECT (c1) ON `testdb`.`v1` TO `select_only_c1`@`localhost` +GRANT SELECT (`c1`) ON `testdb`.`v1` TO `select_only_c1`@`localhost` DROP USER 'show_view_tbl'@'localhost'; DROP USER 'select_only_c1'@'localhost'; diff --git a/mysql-test/main/grant.result b/mysql-test/main/grant.result index 332b74d2e93..d283ec94ee0 100644 --- a/mysql-test/main/grant.result +++ b/mysql-test/main/grant.result @@ -247,7 +247,7 @@ GRANT select (a), update (a),insert(a), references(a) on t1 to mysqltest_1@local show grants for mysqltest_1@localhost; Grants for mysqltest_1@localhost GRANT USAGE ON *.* TO `mysqltest_1`@`localhost` -GRANT SELECT, SELECT (a), INSERT, INSERT (a), UPDATE, UPDATE (a), REFERENCES (a) ON `test`.`t1` TO `mysqltest_1`@`localhost` +GRANT SELECT, SELECT (`a`), INSERT, INSERT (`a`), UPDATE, UPDATE (`a`), REFERENCES (`a`) ON `test`.`t1` TO `mysqltest_1`@`localhost` select table_priv,column_priv from mysql.tables_priv where user="mysqltest_1"; table_priv column_priv Select,Insert,Update Select,Insert,Update,References @@ -255,12 +255,12 @@ REVOKE select (a), update on t1 from mysqltest_1@localhost; show grants for mysqltest_1@localhost; Grants for mysqltest_1@localhost GRANT USAGE ON *.* TO `mysqltest_1`@`localhost` -GRANT SELECT, INSERT, INSERT (a), REFERENCES (a) ON `test`.`t1` TO `mysqltest_1`@`localhost` +GRANT SELECT, INSERT, INSERT (`a`), REFERENCES (`a`) ON `test`.`t1` TO `mysqltest_1`@`localhost` REVOKE select,update,insert,insert (a) on t1 from mysqltest_1@localhost; show grants for mysqltest_1@localhost; Grants for mysqltest_1@localhost GRANT USAGE ON *.* TO `mysqltest_1`@`localhost` -GRANT REFERENCES (a) ON `test`.`t1` TO `mysqltest_1`@`localhost` +GRANT REFERENCES (`a`) ON `test`.`t1` TO `mysqltest_1`@`localhost` GRANT select,references on t1 to mysqltest_1@localhost; select table_priv,column_priv from mysql.tables_priv where user="mysqltest_1"; table_priv column_priv @@ -340,13 +340,13 @@ show grants for drop_user@localhost; Grants for drop_user@localhost GRANT ALL PRIVILEGES ON *.* TO `drop_user`@`localhost` WITH GRANT OPTION GRANT ALL PRIVILEGES ON `test`.* TO `drop_user`@`localhost` WITH GRANT OPTION -GRANT SELECT (a) ON `test`.`t1` TO `drop_user`@`localhost` +GRANT SELECT (`a`) ON `test`.`t1` TO `drop_user`@`localhost` set sql_mode=ansi_quotes; show grants for drop_user@localhost; Grants for drop_user@localhost GRANT ALL PRIVILEGES ON *.* TO "drop_user"@"localhost" WITH GRANT OPTION GRANT ALL PRIVILEGES ON "test".* TO "drop_user"@"localhost" WITH GRANT OPTION -GRANT SELECT (a) ON "test"."t1" TO "drop_user"@"localhost" +GRANT SELECT ("a") ON "test"."t1" TO "drop_user"@"localhost" set sql_mode=default; set sql_quote_show_create=0; show grants for drop_user@localhost; @@ -365,13 +365,13 @@ show grants for drop_user@localhost; Grants for drop_user@localhost GRANT ALL PRIVILEGES ON *.* TO "drop_user"@"localhost" WITH GRANT OPTION GRANT ALL PRIVILEGES ON "test".* TO "drop_user"@"localhost" WITH GRANT OPTION -GRANT SELECT (a) ON "test"."t1" TO "drop_user"@"localhost" +GRANT SELECT ("a") ON "test"."t1" TO "drop_user"@"localhost" set sql_mode=""; show grants for drop_user@localhost; Grants for drop_user@localhost GRANT ALL PRIVILEGES ON *.* TO `drop_user`@`localhost` WITH GRANT OPTION GRANT ALL PRIVILEGES ON `test`.* TO `drop_user`@`localhost` WITH GRANT OPTION -GRANT SELECT (a) ON `test`.`t1` TO `drop_user`@`localhost` +GRANT SELECT (`a`) ON `test`.`t1` TO `drop_user`@`localhost` revoke all privileges, grant option from drop_user@localhost; show grants for drop_user@localhost; Grants for drop_user@localhost @@ -419,7 +419,7 @@ GRANT SELECT ( SHOW GRANTS FOR ÀÚÅÒ@localhost; Grants for ÀÚÅÒ@localhost GRANT USAGE ON *.* TO `ÀÚÅÒ`@`localhost` -GRANT SELECT (ËÏÌ) ON `ÂÄ`.`ÔÁÂ` TO `ÀÚÅÒ`@`localhost` +GRANT SELECT (`ËÏÌ`) ON `ÂÄ`.`ÔÁÂ` TO `ÀÚÅÒ`@`localhost` REVOKE SELECT (ËÏÌ) ON ÂÄ.ÔÁ FROM ÀÚÅÒ@localhost; DROP USER ÀÚÅÒ@localhost; DROP DATABASE ÂÄ; @@ -496,7 +496,7 @@ grant insert(b), insert(c), insert(d), insert(a) on t1 to grant_user@localhost; show grants for grant_user@localhost; Grants for grant_user@localhost GRANT USAGE ON *.* TO `grant_user`@`localhost` -GRANT INSERT (a, d, c, b) ON `test`.`t1` TO `grant_user`@`localhost` +GRANT INSERT (`a`, `d`, `c`, `b`) ON `test`.`t1` TO `grant_user`@`localhost` select Host,Db,User,Table_name,Column_name,Column_priv from mysql.columns_priv order by Column_name; Host Db User Table_name Column_name Column_priv localhost test grant_user t1 a Insert @@ -911,20 +911,20 @@ grant update (a) on t1 to mysqltest_8; show grants for mysqltest_8@''; Grants for mysqltest_8@% GRANT USAGE ON *.* TO `mysqltest_8`@`%` -GRANT UPDATE (a) ON `test`.`t1` TO `mysqltest_8`@`%` +GRANT UPDATE (`a`) ON `test`.`t1` TO `mysqltest_8`@`%` show grants for mysqltest_8; Grants for mysqltest_8@% GRANT USAGE ON *.* TO `mysqltest_8`@`%` -GRANT UPDATE (a) ON `test`.`t1` TO `mysqltest_8`@`%` +GRANT UPDATE (`a`) ON `test`.`t1` TO `mysqltest_8`@`%` flush privileges; show grants for mysqltest_8@''; Grants for mysqltest_8@% GRANT USAGE ON *.* TO `mysqltest_8`@`%` -GRANT UPDATE (a) ON `test`.`t1` TO `mysqltest_8`@`%` +GRANT UPDATE (`a`) ON `test`.`t1` TO `mysqltest_8`@`%` show grants for mysqltest_8; Grants for mysqltest_8@% GRANT USAGE ON *.* TO `mysqltest_8`@`%` -GRANT UPDATE (a) ON `test`.`t1` TO `mysqltest_8`@`%` +GRANT UPDATE (`a`) ON `test`.`t1` TO `mysqltest_8`@`%` select * from information_schema.column_privileges; GRANTEE TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME PRIVILEGE_TYPE IS_GRANTABLE 'mysqltest_8'@'%' def test t1 a UPDATE NO @@ -1003,12 +1003,12 @@ show grants for mysqltest_8@''; Grants for mysqltest_8@% GRANT USAGE ON *.* TO `mysqltest_8`@`%` GRANT ALL PRIVILEGES ON `mysqltest`.* TO `mysqltest_8`@`%` -GRANT UPDATE, UPDATE (a) ON `test`.`t1` TO `mysqltest_8`@`%` +GRANT UPDATE, UPDATE (`a`) ON `test`.`t1` TO `mysqltest_8`@`%` show grants for mysqltest_8; Grants for mysqltest_8@% GRANT USAGE ON *.* TO `mysqltest_8`@`%` GRANT ALL PRIVILEGES ON `mysqltest`.* TO `mysqltest_8`@`%` -GRANT UPDATE, UPDATE (a) ON `test`.`t1` TO `mysqltest_8`@`%` +GRANT UPDATE, UPDATE (`a`) ON `test`.`t1` TO `mysqltest_8`@`%` select * from information_schema.user_privileges where grantee like "'mysqltest_8'%"; GRANTEE TABLE_CATALOG PRIVILEGE_TYPE IS_GRANTABLE @@ -1024,12 +1024,12 @@ show grants for mysqltest_8@''; Grants for mysqltest_8@% GRANT USAGE ON *.* TO `mysqltest_8`@`%` GRANT ALL PRIVILEGES ON `mysqltest`.* TO `mysqltest_8`@`%` -GRANT UPDATE, UPDATE (a) ON `test`.`t1` TO `mysqltest_8`@`%` +GRANT UPDATE, UPDATE (`a`) ON `test`.`t1` TO `mysqltest_8`@`%` show grants for mysqltest_8; Grants for mysqltest_8@% GRANT USAGE ON *.* TO `mysqltest_8`@`%` GRANT ALL PRIVILEGES ON `mysqltest`.* TO `mysqltest_8`@`%` -GRANT UPDATE, UPDATE (a) ON `test`.`t1` TO `mysqltest_8`@`%` +GRANT UPDATE, UPDATE (`a`) ON `test`.`t1` TO `mysqltest_8`@`%` drop user mysqltest_8@''; show grants for mysqltest_8@''; ERROR 42000: There is no such grant defined for user 'mysqltest_8' on host '%' diff --git a/mysql-test/main/grant2.result b/mysql-test/main/grant2.result index de192ecc28e..b19c118a7de 100644 --- a/mysql-test/main/grant2.result +++ b/mysql-test/main/grant2.result @@ -203,7 +203,7 @@ show grants for 'mysqltest_2'; Grants for mysqltest_2@% GRANT SELECT ON *.* TO "mysqltest_2"@"%" IDENTIFIED BY PASSWORD '*BD447CBA355AF58578D3AE33BA2E2CD388BA08D1' GRANT INSERT ON "test".* TO "mysqltest_2"@"%" -GRANT UPDATE (c2) ON "test"."t2" TO "mysqltest_2"@"%" +GRANT UPDATE ("c2") ON "test"."t2" TO "mysqltest_2"@"%" GRANT UPDATE ON "test"."t1" TO "mysqltest_2"@"%" drop user 'mysqltest_1'; select host,user,password from mysql.user where user like 'mysqltest_%' order by host,user,password; @@ -241,7 +241,7 @@ show grants for 'mysqltest_1'; Grants for mysqltest_1@% GRANT SELECT ON *.* TO "mysqltest_1"@"%" IDENTIFIED BY PASSWORD '*BD447CBA355AF58578D3AE33BA2E2CD388BA08D1' GRANT INSERT ON "test".* TO "mysqltest_1"@"%" -GRANT UPDATE (c2) ON "test"."t2" TO "mysqltest_1"@"%" +GRANT UPDATE ("c2") ON "test"."t2" TO "mysqltest_1"@"%" GRANT UPDATE ON "test"."t1" TO "mysqltest_1"@"%" drop user 'mysqltest_1', 'mysqltest_3'; drop user 'mysqltest_1'; diff --git a/mysql-test/main/grant3.result b/mysql-test/main/grant3.result index e26f19ee492..b75b307049f 100644 --- a/mysql-test/main/grant3.result +++ b/mysql-test/main/grant3.result @@ -172,14 +172,14 @@ GRANT SELECT (a), INSERT (b) ON `temp`.`t1` TO 'user2'@'%'; SHOW GRANTS FOR 'user2'@'%'; Grants for user2@% GRANT USAGE ON *.* TO `user2`@`%` -GRANT SELECT (a), INSERT (b) ON `temp`.`t1` TO `user2`@`%` +GRANT SELECT (`a`), INSERT (`b`) ON `temp`.`t1` TO `user2`@`%` # Connect as the renamed user connect conn1, localhost, user2,,; connection conn1; SHOW GRANTS; Grants for user2@% GRANT USAGE ON *.* TO `user2`@`%` -GRANT SELECT (a), INSERT (b) ON `temp`.`t1` TO `user2`@`%` +GRANT SELECT (`a`), INSERT (`b`) ON `temp`.`t1` TO `user2`@`%` SELECT a FROM temp.t1; a 1 diff --git a/mysql-test/main/grant5.result b/mysql-test/main/grant5.result index dc8ee527378..42c75405f22 100644 --- a/mysql-test/main/grant5.result +++ b/mysql-test/main/grant5.result @@ -304,12 +304,12 @@ GRANT INSERT (col1) ON db.test_getcolpriv TO foo; SHOW GRANTS FOR foo; Grants for foo@% GRANT USAGE ON *.* TO `foo`@`%` -GRANT SELECT (col2, col1), INSERT (col1) ON `db`.`test_getcolpriv` TO `foo`@`%` +GRANT SELECT (`col2`, `col1`), INSERT (`col1`) ON `db`.`test_getcolpriv` TO `foo`@`%` REVOKE SELECT (col1,col2) ON db.test_getcolpriv FROM foo; SHOW GRANTS FOR foo; Grants for foo@% GRANT USAGE ON *.* TO `foo`@`%` -GRANT INSERT (col1) ON `db`.`test_getcolpriv` TO `foo`@`%` +GRANT INSERT (`col1`) ON `db`.`test_getcolpriv` TO `foo`@`%` REVOKE INSERT (col1) ON db.test_getcolpriv FROM foo; SHOW GRANTS FOR foo; Grants for foo@% diff --git a/mysql-test/main/information_schema.result b/mysql-test/main/information_schema.result index 827a2fac749..fba61b354f3 100644 --- a/mysql-test/main/information_schema.result +++ b/mysql-test/main/information_schema.result @@ -1043,7 +1043,7 @@ GRANTEE TABLE_CATALOG PRIVILEGE_TYPE IS_GRANTABLE show grants; Grants for user1@localhost GRANT USAGE ON *.* TO `user1`@`localhost` -GRANT SELECT (f1) ON `mysqltest`.`t1` TO `user1`@`localhost` +GRANT SELECT (`f1`) ON `mysqltest`.`t1` TO `user1`@`localhost` connection con2; select * from information_schema.column_privileges order by grantee; GRANTEE TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME PRIVILEGE_TYPE IS_GRANTABLE diff --git a/mysql-test/suite/funcs_1/r/innodb_trig_03.result b/mysql-test/suite/funcs_1/r/innodb_trig_03.result index 8e8606c6754..79180896955 100644 --- a/mysql-test/suite/funcs_1/r/innodb_trig_03.result +++ b/mysql-test/suite/funcs_1/r/innodb_trig_03.result @@ -391,7 +391,7 @@ connection no_privs_424d; show grants; Grants for test_noprivs@localhost GRANT TRIGGER ON *.* TO `test_noprivs`@`localhost` IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' -GRANT SELECT (f1), INSERT (f1) ON `priv_db`.`t1` TO `test_noprivs`@`localhost` +GRANT SELECT (`f1`), INSERT (`f1`) ON `priv_db`.`t1` TO `test_noprivs`@`localhost` use priv_db; create trigger trg4d_1 before INSERT on t1 for each row set new.f1 = 'trig 3.5.3.7-1d'; @@ -413,7 +413,7 @@ connection yes_privs_424d; show grants; Grants for test_yesprivs@localhost GRANT TRIGGER ON *.* TO `test_yesprivs`@`localhost` IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' -GRANT UPDATE (f1) ON `priv_db`.`t1` TO `test_yesprivs`@`localhost` +GRANT UPDATE (`f1`) ON `priv_db`.`t1` TO `test_yesprivs`@`localhost` use priv_db; create trigger trg4d_2 before INSERT on t1 for each row set new.f1 = 'trig 3.5.3.7-2d'; @@ -618,14 +618,14 @@ grant UPDATE (f1), INSERT (f1) on priv_db.t1 to test_noprivs@localhost; show grants for test_noprivs@localhost; Grants for test_noprivs@localhost GRANT TRIGGER ON *.* TO `test_noprivs`@`localhost` IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' -GRANT INSERT (f1), UPDATE (f1) ON `priv_db`.`t1` TO `test_noprivs`@`localhost` +GRANT INSERT (`f1`), UPDATE (`f1`) ON `priv_db`.`t1` TO `test_noprivs`@`localhost` revoke ALL PRIVILEGES, GRANT OPTION FROM test_yesprivs@localhost; grant TRIGGER on *.* to test_yesprivs@localhost; grant SELECT (f1) on priv_db.t1 to test_yesprivs@localhost; show grants for test_noprivs@localhost; Grants for test_noprivs@localhost GRANT TRIGGER ON *.* TO `test_noprivs`@`localhost` IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' -GRANT INSERT (f1), UPDATE (f1) ON `priv_db`.`t1` TO `test_noprivs`@`localhost` +GRANT INSERT (`f1`), UPDATE (`f1`) ON `priv_db`.`t1` TO `test_noprivs`@`localhost` connect no_privs_425d,localhost,test_noprivs,PWD,test,$MASTER_MYPORT,$MASTER_MYSOCK; connect yes_privs_425d,localhost,test_yesprivs,PWD,test,$MASTER_MYPORT,$MASTER_MYSOCK; connection default; @@ -633,7 +633,7 @@ connection no_privs_425d; show grants; Grants for test_noprivs@localhost GRANT TRIGGER ON *.* TO `test_noprivs`@`localhost` IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' -GRANT INSERT (f1), UPDATE (f1) ON `priv_db`.`t1` TO `test_noprivs`@`localhost` +GRANT INSERT (`f1`), UPDATE (`f1`) ON `priv_db`.`t1` TO `test_noprivs`@`localhost` use priv_db; create trigger trg5d_1 before INSERT on t1 for each row set @test_var= new.f1; @@ -649,7 +649,7 @@ connection yes_privs_425d; show grants; Grants for test_yesprivs@localhost GRANT TRIGGER ON *.* TO `test_yesprivs`@`localhost` IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' -GRANT SELECT (f1) ON `priv_db`.`t1` TO `test_yesprivs`@`localhost` +GRANT SELECT (`f1`) ON `priv_db`.`t1` TO `test_yesprivs`@`localhost` use priv_db; create trigger trg5d_2 before INSERT on t1 for each row set @test_var= new.f1; diff --git a/mysql-test/suite/funcs_1/r/innodb_trig_03e.result b/mysql-test/suite/funcs_1/r/innodb_trig_03e.result index 48ad0c8d05f..e9aec65afad 100644 --- a/mysql-test/suite/funcs_1/r/innodb_trig_03e.result +++ b/mysql-test/suite/funcs_1/r/innodb_trig_03e.result @@ -1541,8 +1541,8 @@ show grants for test_yesprivs@localhost; Grants for test_yesprivs@localhost GRANT USAGE ON *.* TO `test_yesprivs`@`localhost` IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' GRANT TRIGGER ON `priv_db`.* TO `test_yesprivs`@`localhost` -GRANT SELECT (f1), INSERT ON `priv_db`.`t2` TO `test_yesprivs`@`localhost` -GRANT SELECT (f1), INSERT, UPDATE (f1) ON `priv_db`.`t1` TO `test_yesprivs`@`localhost` +GRANT SELECT (`f1`), INSERT ON `priv_db`.`t2` TO `test_yesprivs`@`localhost` +GRANT SELECT (`f1`), INSERT, UPDATE (`f1`) ON `priv_db`.`t1` TO `test_yesprivs`@`localhost` connection yes_privs; select current_user; current_user @@ -1692,8 +1692,8 @@ to test_yesprivs@localhost; show grants for test_yesprivs@localhost; Grants for test_yesprivs@localhost GRANT USAGE ON *.* TO `test_yesprivs`@`localhost` IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' -GRANT SELECT (f1), INSERT, UPDATE ON `priv_db`.`t2` TO `test_yesprivs`@`localhost` -GRANT SELECT, SELECT (f1), INSERT, UPDATE (f3, f2), TRIGGER ON `priv_db`.`t1` TO `test_yesprivs`@`localhost` +GRANT SELECT (`f1`), INSERT, UPDATE ON `priv_db`.`t2` TO `test_yesprivs`@`localhost` +GRANT SELECT, SELECT (`f1`), INSERT, UPDATE (`f3`, `f2`), TRIGGER ON `priv_db`.`t1` TO `test_yesprivs`@`localhost` connection yes_privs; select current_user; current_user @@ -1735,8 +1735,8 @@ to test_yesprivs@localhost; show grants for test_yesprivs@localhost; Grants for test_yesprivs@localhost GRANT USAGE ON *.* TO `test_yesprivs`@`localhost` IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' -GRANT SELECT (f1), INSERT, UPDATE ON `priv_db`.`t2` TO `test_yesprivs`@`localhost` -GRANT SELECT, SELECT (f1), INSERT, UPDATE (f3, f2, f1) ON `priv_db`.`t1` TO `test_yesprivs`@`localhost` +GRANT SELECT (`f1`), INSERT, UPDATE ON `priv_db`.`t2` TO `test_yesprivs`@`localhost` +GRANT SELECT, SELECT (`f1`), INSERT, UPDATE (`f3`, `f2`, `f1`) ON `priv_db`.`t1` TO `test_yesprivs`@`localhost` connection no_privs; select current_user; current_user diff --git a/mysql-test/suite/funcs_1/r/is_check_constraints.result b/mysql-test/suite/funcs_1/r/is_check_constraints.result index e4d0b322563..4f9ac93bee0 100644 --- a/mysql-test/suite/funcs_1/r/is_check_constraints.result +++ b/mysql-test/suite/funcs_1/r/is_check_constraints.result @@ -134,7 +134,7 @@ GRANT SELECT (a) ON t1 TO foo; SHOW GRANTS FOR foo; Grants for foo@% GRANT USAGE ON *.* TO `foo`@`%` -GRANT SELECT (a) ON `db`.`t1` TO `foo`@`%` +GRANT SELECT (`a`) ON `db`.`t1` TO `foo`@`%` SELECT * FROM information_schema.check_constraints; CONSTRAINT_CATALOG CONSTRAINT_SCHEMA TABLE_NAME CONSTRAINT_NAME CHECK_CLAUSE def db t1 CONSTRAINT_1 `b` > 0 diff --git a/mysql-test/suite/funcs_1/r/is_column_privileges.result b/mysql-test/suite/funcs_1/r/is_column_privileges.result index d5d42a84f30..70effc9e5ed 100644 --- a/mysql-test/suite/funcs_1/r/is_column_privileges.result +++ b/mysql-test/suite/funcs_1/r/is_column_privileges.result @@ -219,7 +219,7 @@ SHOW GRANTS FOR 'testuser1'@'localhost'; Grants for testuser1@localhost GRANT USAGE ON *.* TO `testuser1`@`localhost` GRANT ALL PRIVILEGES ON `test`.* TO `testuser1`@`localhost` -GRANT SELECT (f3, f1) ON `db_datadict`.`my_table` TO `testuser1`@`localhost` +GRANT SELECT (`f3`, `f1`) ON `db_datadict`.`my_table` TO `testuser1`@`localhost` connection testuser1; SELECT * FROM information_schema.column_privileges WHERE table_name = 'my_table' @@ -231,7 +231,7 @@ SHOW GRANTS FOR 'testuser1'@'localhost'; Grants for testuser1@localhost GRANT USAGE ON *.* TO `testuser1`@`localhost` GRANT ALL PRIVILEGES ON `test`.* TO `testuser1`@`localhost` -GRANT SELECT (f3, f1) ON `db_datadict`.`my_table` TO `testuser1`@`localhost` +GRANT SELECT (`f3`, `f1`) ON `db_datadict`.`my_table` TO `testuser1`@`localhost` connection default; ALTER TABLE db_datadict.my_table DROP COLUMN f3; GRANT UPDATE (f1) ON db_datadict.my_table TO 'testuser1'@'localhost'; @@ -246,7 +246,7 @@ SHOW GRANTS FOR 'testuser1'@'localhost'; Grants for testuser1@localhost GRANT USAGE ON *.* TO `testuser1`@`localhost` GRANT ALL PRIVILEGES ON `test`.* TO `testuser1`@`localhost` -GRANT SELECT (f3, f1), UPDATE (f1) ON `db_datadict`.`my_table` TO `testuser1`@`localhost` +GRANT SELECT (`f3`, `f1`), UPDATE (`f1`) ON `db_datadict`.`my_table` TO `testuser1`@`localhost` connection testuser1; SELECT * FROM information_schema.column_privileges WHERE table_name = 'my_table' @@ -259,7 +259,7 @@ SHOW GRANTS FOR 'testuser1'@'localhost'; Grants for testuser1@localhost GRANT USAGE ON *.* TO `testuser1`@`localhost` GRANT ALL PRIVILEGES ON `test`.* TO `testuser1`@`localhost` -GRANT SELECT (f3, f1), UPDATE (f1) ON `db_datadict`.`my_table` TO `testuser1`@`localhost` +GRANT SELECT (`f3`, `f1`), UPDATE (`f1`) ON `db_datadict`.`my_table` TO `testuser1`@`localhost` SELECT f1, f3 FROM db_datadict.my_table; ERROR 42S22: Unknown column 'f3' in 'field list' connection default; @@ -275,7 +275,7 @@ SHOW GRANTS FOR 'testuser1'@'localhost'; Grants for testuser1@localhost GRANT USAGE ON *.* TO `testuser1`@`localhost` GRANT ALL PRIVILEGES ON `test`.* TO `testuser1`@`localhost` -GRANT SELECT (f3, f1), UPDATE (f1) ON `db_datadict`.`my_table` TO `testuser1`@`localhost` +GRANT SELECT (`f3`, `f1`), UPDATE (`f1`) ON `db_datadict`.`my_table` TO `testuser1`@`localhost` connection testuser1; SELECT * FROM information_schema.column_privileges WHERE table_name = 'my_table' @@ -288,7 +288,7 @@ SHOW GRANTS FOR 'testuser1'@'localhost'; Grants for testuser1@localhost GRANT USAGE ON *.* TO `testuser1`@`localhost` GRANT ALL PRIVILEGES ON `test`.* TO `testuser1`@`localhost` -GRANT SELECT (f3, f1), UPDATE (f1) ON `db_datadict`.`my_table` TO `testuser1`@`localhost` +GRANT SELECT (`f3`, `f1`), UPDATE (`f1`) ON `db_datadict`.`my_table` TO `testuser1`@`localhost` connection default; DROP TABLE db_datadict.my_table; SELECT * FROM information_schema.column_privileges @@ -302,7 +302,7 @@ SHOW GRANTS FOR 'testuser1'@'localhost'; Grants for testuser1@localhost GRANT USAGE ON *.* TO `testuser1`@`localhost` GRANT ALL PRIVILEGES ON `test`.* TO `testuser1`@`localhost` -GRANT SELECT (f3, f1), UPDATE (f1) ON `db_datadict`.`my_table` TO `testuser1`@`localhost` +GRANT SELECT (`f3`, `f1`), UPDATE (`f1`) ON `db_datadict`.`my_table` TO `testuser1`@`localhost` connection testuser1; SELECT * FROM information_schema.column_privileges WHERE table_name = 'my_table' @@ -315,7 +315,7 @@ SHOW GRANTS FOR 'testuser1'@'localhost'; Grants for testuser1@localhost GRANT USAGE ON *.* TO `testuser1`@`localhost` GRANT ALL PRIVILEGES ON `test`.* TO `testuser1`@`localhost` -GRANT SELECT (f3, f1), UPDATE (f1) ON `db_datadict`.`my_table` TO `testuser1`@`localhost` +GRANT SELECT (`f3`, `f1`), UPDATE (`f1`) ON `db_datadict`.`my_table` TO `testuser1`@`localhost` connection default; REVOKE ALL ON db_datadict.my_table FROM 'testuser1'@'localhost'; SELECT * FROM information_schema.column_privileges diff --git a/mysql-test/suite/funcs_1/r/is_statistics.result b/mysql-test/suite/funcs_1/r/is_statistics.result index aff871dc488..d76374d29f9 100644 --- a/mysql-test/suite/funcs_1/r/is_statistics.result +++ b/mysql-test/suite/funcs_1/r/is_statistics.result @@ -241,7 +241,7 @@ SHOW GRANTS FOR 'testuser1'@'localhost'; Grants for testuser1@localhost GRANT USAGE ON *.* TO `testuser1`@`localhost` GRANT SELECT ON `db_datadict`.`t1` TO `testuser1`@`localhost` WITH GRANT OPTION -GRANT SELECT (f5, f1) ON `db_datadict_2`.`t3` TO `testuser1`@`localhost` +GRANT SELECT (`f5`, `f1`) ON `db_datadict_2`.`t3` TO `testuser1`@`localhost` SHOW GRANTS FOR 'testuser2'@'localhost'; Grants for testuser2@localhost GRANT USAGE ON *.* TO `testuser2`@`localhost` @@ -260,7 +260,7 @@ SHOW GRANTS FOR 'testuser1'@'localhost'; Grants for testuser1@localhost GRANT USAGE ON *.* TO `testuser1`@`localhost` GRANT SELECT ON `db_datadict`.`t1` TO `testuser1`@`localhost` WITH GRANT OPTION -GRANT SELECT (f5, f1) ON `db_datadict_2`.`t3` TO `testuser1`@`localhost` +GRANT SELECT (`f5`, `f1`) ON `db_datadict_2`.`t3` TO `testuser1`@`localhost` SHOW GRANTS FOR 'testuser2'@'localhost'; ERROR 42000: Access denied for user 'testuser1'@'localhost' to database 'mysql' connection testuser2; @@ -278,7 +278,7 @@ REVOKE SELECT,GRANT OPTION ON db_datadict.t1 FROM 'testuser1'@'localhost'; SHOW GRANTS FOR 'testuser1'@'localhost'; Grants for testuser1@localhost GRANT USAGE ON *.* TO `testuser1`@`localhost` -GRANT SELECT (f5, f1) ON `db_datadict_2`.`t3` TO `testuser1`@`localhost` +GRANT SELECT (`f5`, `f1`) ON `db_datadict_2`.`t3` TO `testuser1`@`localhost` connection testuser1; SELECT * FROM information_schema.statistics WHERE table_schema LIKE 'db_datadict%' @@ -291,7 +291,7 @@ def db_datadict_2 t3 0 db_datadict_2 PRIMARY 1 f1 NULL 0 NULL NULL HASH SHOW GRANTS FOR 'testuser1'@'localhost'; Grants for testuser1@localhost GRANT USAGE ON *.* TO `testuser1`@`localhost` -GRANT SELECT (f5, f1) ON `db_datadict_2`.`t3` TO `testuser1`@`localhost` +GRANT SELECT (`f5`, `f1`) ON `db_datadict_2`.`t3` TO `testuser1`@`localhost` connection default; disconnect testuser1; disconnect testuser2; diff --git a/mysql-test/suite/funcs_1/r/is_table_constraints.result b/mysql-test/suite/funcs_1/r/is_table_constraints.result index 37765a7bb04..f0a9fe4fd54 100644 --- a/mysql-test/suite/funcs_1/r/is_table_constraints.result +++ b/mysql-test/suite/funcs_1/r/is_table_constraints.result @@ -110,7 +110,7 @@ GRANT SELECT(f5) ON db_datadict.t1 TO 'testuser1'@'localhost'; SHOW GRANTS FOR 'testuser1'@'localhost'; Grants for testuser1@localhost GRANT USAGE ON *.* TO `testuser1`@`localhost` -GRANT SELECT (f5) ON `db_datadict`.`t1` TO `testuser1`@`localhost` +GRANT SELECT (`f5`) ON `db_datadict`.`t1` TO `testuser1`@`localhost` SELECT * FROM information_schema.table_constraints WHERE table_schema = 'db_datadict' ORDER BY table_schema,table_name, constraint_name; @@ -134,7 +134,7 @@ connect testuser1, localhost, testuser1, , db_datadict; SHOW GRANTS FOR 'testuser1'@'localhost'; Grants for testuser1@localhost GRANT USAGE ON *.* TO `testuser1`@`localhost` -GRANT SELECT (f5) ON `db_datadict`.`t1` TO `testuser1`@`localhost` +GRANT SELECT (`f5`) ON `db_datadict`.`t1` TO `testuser1`@`localhost` SELECT * FROM information_schema.table_constraints WHERE table_schema = 'db_datadict' ORDER BY table_schema,table_name, constraint_name; diff --git a/mysql-test/suite/funcs_1/r/memory_trig_03.result b/mysql-test/suite/funcs_1/r/memory_trig_03.result index 6b9c6c8ddc3..6726f6dd658 100644 --- a/mysql-test/suite/funcs_1/r/memory_trig_03.result +++ b/mysql-test/suite/funcs_1/r/memory_trig_03.result @@ -391,7 +391,7 @@ connection no_privs_424d; show grants; Grants for test_noprivs@localhost GRANT TRIGGER ON *.* TO `test_noprivs`@`localhost` IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' -GRANT SELECT (f1), INSERT (f1) ON `priv_db`.`t1` TO `test_noprivs`@`localhost` +GRANT SELECT (`f1`), INSERT (`f1`) ON `priv_db`.`t1` TO `test_noprivs`@`localhost` use priv_db; create trigger trg4d_1 before INSERT on t1 for each row set new.f1 = 'trig 3.5.3.7-1d'; @@ -413,7 +413,7 @@ connection yes_privs_424d; show grants; Grants for test_yesprivs@localhost GRANT TRIGGER ON *.* TO `test_yesprivs`@`localhost` IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' -GRANT UPDATE (f1) ON `priv_db`.`t1` TO `test_yesprivs`@`localhost` +GRANT UPDATE (`f1`) ON `priv_db`.`t1` TO `test_yesprivs`@`localhost` use priv_db; create trigger trg4d_2 before INSERT on t1 for each row set new.f1 = 'trig 3.5.3.7-2d'; @@ -618,14 +618,14 @@ grant UPDATE (f1), INSERT (f1) on priv_db.t1 to test_noprivs@localhost; show grants for test_noprivs@localhost; Grants for test_noprivs@localhost GRANT TRIGGER ON *.* TO `test_noprivs`@`localhost` IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' -GRANT INSERT (f1), UPDATE (f1) ON `priv_db`.`t1` TO `test_noprivs`@`localhost` +GRANT INSERT (`f1`), UPDATE (`f1`) ON `priv_db`.`t1` TO `test_noprivs`@`localhost` revoke ALL PRIVILEGES, GRANT OPTION FROM test_yesprivs@localhost; grant TRIGGER on *.* to test_yesprivs@localhost; grant SELECT (f1) on priv_db.t1 to test_yesprivs@localhost; show grants for test_noprivs@localhost; Grants for test_noprivs@localhost GRANT TRIGGER ON *.* TO `test_noprivs`@`localhost` IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' -GRANT INSERT (f1), UPDATE (f1) ON `priv_db`.`t1` TO `test_noprivs`@`localhost` +GRANT INSERT (`f1`), UPDATE (`f1`) ON `priv_db`.`t1` TO `test_noprivs`@`localhost` connect no_privs_425d,localhost,test_noprivs,PWD,test,$MASTER_MYPORT,$MASTER_MYSOCK; connect yes_privs_425d,localhost,test_yesprivs,PWD,test,$MASTER_MYPORT,$MASTER_MYSOCK; connection default; @@ -633,7 +633,7 @@ connection no_privs_425d; show grants; Grants for test_noprivs@localhost GRANT TRIGGER ON *.* TO `test_noprivs`@`localhost` IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' -GRANT INSERT (f1), UPDATE (f1) ON `priv_db`.`t1` TO `test_noprivs`@`localhost` +GRANT INSERT (`f1`), UPDATE (`f1`) ON `priv_db`.`t1` TO `test_noprivs`@`localhost` use priv_db; create trigger trg5d_1 before INSERT on t1 for each row set @test_var= new.f1; @@ -649,7 +649,7 @@ connection yes_privs_425d; show grants; Grants for test_yesprivs@localhost GRANT TRIGGER ON *.* TO `test_yesprivs`@`localhost` IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' -GRANT SELECT (f1) ON `priv_db`.`t1` TO `test_yesprivs`@`localhost` +GRANT SELECT (`f1`) ON `priv_db`.`t1` TO `test_yesprivs`@`localhost` use priv_db; create trigger trg5d_2 before INSERT on t1 for each row set @test_var= new.f1; diff --git a/mysql-test/suite/funcs_1/r/memory_trig_03e.result b/mysql-test/suite/funcs_1/r/memory_trig_03e.result index a72a8a1221d..234dbfc5d06 100644 --- a/mysql-test/suite/funcs_1/r/memory_trig_03e.result +++ b/mysql-test/suite/funcs_1/r/memory_trig_03e.result @@ -1480,8 +1480,8 @@ show grants for test_yesprivs@localhost; Grants for test_yesprivs@localhost GRANT USAGE ON *.* TO `test_yesprivs`@`localhost` IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' GRANT TRIGGER ON `priv_db`.* TO `test_yesprivs`@`localhost` -GRANT SELECT (f1), INSERT ON `priv_db`.`t2` TO `test_yesprivs`@`localhost` -GRANT SELECT (f1), INSERT, UPDATE (f1) ON `priv_db`.`t1` TO `test_yesprivs`@`localhost` +GRANT SELECT (`f1`), INSERT ON `priv_db`.`t2` TO `test_yesprivs`@`localhost` +GRANT SELECT (`f1`), INSERT, UPDATE (`f1`) ON `priv_db`.`t1` TO `test_yesprivs`@`localhost` connection yes_privs; select current_user; current_user @@ -1631,8 +1631,8 @@ to test_yesprivs@localhost; show grants for test_yesprivs@localhost; Grants for test_yesprivs@localhost GRANT USAGE ON *.* TO `test_yesprivs`@`localhost` IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' -GRANT SELECT (f1), INSERT, UPDATE ON `priv_db`.`t2` TO `test_yesprivs`@`localhost` -GRANT SELECT, SELECT (f1), INSERT, UPDATE (f3, f2), TRIGGER ON `priv_db`.`t1` TO `test_yesprivs`@`localhost` +GRANT SELECT (`f1`), INSERT, UPDATE ON `priv_db`.`t2` TO `test_yesprivs`@`localhost` +GRANT SELECT, SELECT (`f1`), INSERT, UPDATE (`f3`, `f2`), TRIGGER ON `priv_db`.`t1` TO `test_yesprivs`@`localhost` connection yes_privs; select current_user; current_user @@ -1674,8 +1674,8 @@ to test_yesprivs@localhost; show grants for test_yesprivs@localhost; Grants for test_yesprivs@localhost GRANT USAGE ON *.* TO `test_yesprivs`@`localhost` IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' -GRANT SELECT (f1), INSERT, UPDATE ON `priv_db`.`t2` TO `test_yesprivs`@`localhost` -GRANT SELECT, SELECT (f1), INSERT, UPDATE (f3, f2, f1) ON `priv_db`.`t1` TO `test_yesprivs`@`localhost` +GRANT SELECT (`f1`), INSERT, UPDATE ON `priv_db`.`t2` TO `test_yesprivs`@`localhost` +GRANT SELECT, SELECT (`f1`), INSERT, UPDATE (`f3`, `f2`, `f1`) ON `priv_db`.`t1` TO `test_yesprivs`@`localhost` connection no_privs; select current_user; current_user diff --git a/mysql-test/suite/funcs_1/r/myisam_trig_03.result b/mysql-test/suite/funcs_1/r/myisam_trig_03.result index 6b9c6c8ddc3..6726f6dd658 100644 --- a/mysql-test/suite/funcs_1/r/myisam_trig_03.result +++ b/mysql-test/suite/funcs_1/r/myisam_trig_03.result @@ -391,7 +391,7 @@ connection no_privs_424d; show grants; Grants for test_noprivs@localhost GRANT TRIGGER ON *.* TO `test_noprivs`@`localhost` IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' -GRANT SELECT (f1), INSERT (f1) ON `priv_db`.`t1` TO `test_noprivs`@`localhost` +GRANT SELECT (`f1`), INSERT (`f1`) ON `priv_db`.`t1` TO `test_noprivs`@`localhost` use priv_db; create trigger trg4d_1 before INSERT on t1 for each row set new.f1 = 'trig 3.5.3.7-1d'; @@ -413,7 +413,7 @@ connection yes_privs_424d; show grants; Grants for test_yesprivs@localhost GRANT TRIGGER ON *.* TO `test_yesprivs`@`localhost` IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' -GRANT UPDATE (f1) ON `priv_db`.`t1` TO `test_yesprivs`@`localhost` +GRANT UPDATE (`f1`) ON `priv_db`.`t1` TO `test_yesprivs`@`localhost` use priv_db; create trigger trg4d_2 before INSERT on t1 for each row set new.f1 = 'trig 3.5.3.7-2d'; @@ -618,14 +618,14 @@ grant UPDATE (f1), INSERT (f1) on priv_db.t1 to test_noprivs@localhost; show grants for test_noprivs@localhost; Grants for test_noprivs@localhost GRANT TRIGGER ON *.* TO `test_noprivs`@`localhost` IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' -GRANT INSERT (f1), UPDATE (f1) ON `priv_db`.`t1` TO `test_noprivs`@`localhost` +GRANT INSERT (`f1`), UPDATE (`f1`) ON `priv_db`.`t1` TO `test_noprivs`@`localhost` revoke ALL PRIVILEGES, GRANT OPTION FROM test_yesprivs@localhost; grant TRIGGER on *.* to test_yesprivs@localhost; grant SELECT (f1) on priv_db.t1 to test_yesprivs@localhost; show grants for test_noprivs@localhost; Grants for test_noprivs@localhost GRANT TRIGGER ON *.* TO `test_noprivs`@`localhost` IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' -GRANT INSERT (f1), UPDATE (f1) ON `priv_db`.`t1` TO `test_noprivs`@`localhost` +GRANT INSERT (`f1`), UPDATE (`f1`) ON `priv_db`.`t1` TO `test_noprivs`@`localhost` connect no_privs_425d,localhost,test_noprivs,PWD,test,$MASTER_MYPORT,$MASTER_MYSOCK; connect yes_privs_425d,localhost,test_yesprivs,PWD,test,$MASTER_MYPORT,$MASTER_MYSOCK; connection default; @@ -633,7 +633,7 @@ connection no_privs_425d; show grants; Grants for test_noprivs@localhost GRANT TRIGGER ON *.* TO `test_noprivs`@`localhost` IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' -GRANT INSERT (f1), UPDATE (f1) ON `priv_db`.`t1` TO `test_noprivs`@`localhost` +GRANT INSERT (`f1`), UPDATE (`f1`) ON `priv_db`.`t1` TO `test_noprivs`@`localhost` use priv_db; create trigger trg5d_1 before INSERT on t1 for each row set @test_var= new.f1; @@ -649,7 +649,7 @@ connection yes_privs_425d; show grants; Grants for test_yesprivs@localhost GRANT TRIGGER ON *.* TO `test_yesprivs`@`localhost` IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' -GRANT SELECT (f1) ON `priv_db`.`t1` TO `test_yesprivs`@`localhost` +GRANT SELECT (`f1`) ON `priv_db`.`t1` TO `test_yesprivs`@`localhost` use priv_db; create trigger trg5d_2 before INSERT on t1 for each row set @test_var= new.f1; diff --git a/mysql-test/suite/funcs_1/r/myisam_trig_03e.result b/mysql-test/suite/funcs_1/r/myisam_trig_03e.result index f6bd346cabe..c10d7dcb17f 100644 --- a/mysql-test/suite/funcs_1/r/myisam_trig_03e.result +++ b/mysql-test/suite/funcs_1/r/myisam_trig_03e.result @@ -1480,8 +1480,8 @@ show grants for test_yesprivs@localhost; Grants for test_yesprivs@localhost GRANT USAGE ON *.* TO `test_yesprivs`@`localhost` IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' GRANT TRIGGER ON `priv_db`.* TO `test_yesprivs`@`localhost` -GRANT SELECT (f1), INSERT ON `priv_db`.`t2` TO `test_yesprivs`@`localhost` -GRANT SELECT (f1), INSERT, UPDATE (f1) ON `priv_db`.`t1` TO `test_yesprivs`@`localhost` +GRANT SELECT (`f1`), INSERT ON `priv_db`.`t2` TO `test_yesprivs`@`localhost` +GRANT SELECT (`f1`), INSERT, UPDATE (`f1`) ON `priv_db`.`t1` TO `test_yesprivs`@`localhost` connection yes_privs; select current_user; current_user @@ -1631,8 +1631,8 @@ to test_yesprivs@localhost; show grants for test_yesprivs@localhost; Grants for test_yesprivs@localhost GRANT USAGE ON *.* TO `test_yesprivs`@`localhost` IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' -GRANT SELECT (f1), INSERT, UPDATE ON `priv_db`.`t2` TO `test_yesprivs`@`localhost` -GRANT SELECT, SELECT (f1), INSERT, UPDATE (f3, f2), TRIGGER ON `priv_db`.`t1` TO `test_yesprivs`@`localhost` +GRANT SELECT (`f1`), INSERT, UPDATE ON `priv_db`.`t2` TO `test_yesprivs`@`localhost` +GRANT SELECT, SELECT (`f1`), INSERT, UPDATE (`f3`, `f2`), TRIGGER ON `priv_db`.`t1` TO `test_yesprivs`@`localhost` connection yes_privs; select current_user; current_user @@ -1674,8 +1674,8 @@ to test_yesprivs@localhost; show grants for test_yesprivs@localhost; Grants for test_yesprivs@localhost GRANT USAGE ON *.* TO `test_yesprivs`@`localhost` IDENTIFIED BY PASSWORD '*C49735D016A099C0CF104EF9183F374A54CA2576' -GRANT SELECT (f1), INSERT, UPDATE ON `priv_db`.`t2` TO `test_yesprivs`@`localhost` -GRANT SELECT, SELECT (f1), INSERT, UPDATE (f3, f2, f1) ON `priv_db`.`t1` TO `test_yesprivs`@`localhost` +GRANT SELECT (`f1`), INSERT, UPDATE ON `priv_db`.`t2` TO `test_yesprivs`@`localhost` +GRANT SELECT, SELECT (`f1`), INSERT, UPDATE (`f3`, `f2`, `f1`) ON `priv_db`.`t1` TO `test_yesprivs`@`localhost` connection no_privs; select current_user; current_user diff --git a/mysql-test/suite/roles/recursive.result b/mysql-test/suite/roles/recursive.result index 05f28745f02..daacd2ed250 100644 --- a/mysql-test/suite/roles/recursive.result +++ b/mysql-test/suite/roles/recursive.result @@ -202,7 +202,7 @@ count(concat(User)) 22 show grants; Grants for foo@localhost -GRANT SELECT (User) ON `mysql`.`roles_mapping` TO `role1` +GRANT SELECT (`User`) ON `mysql`.`roles_mapping` TO `role1` GRANT USAGE ON *.* TO `foo`@`localhost` GRANT USAGE ON *.* TO `role10` GRANT USAGE ON *.* TO `role1` @@ -236,8 +236,8 @@ count(concat(User,Host)) 22 show grants; Grants for foo@localhost -GRANT SELECT (Host) ON `mysql`.`roles_mapping` TO `role3` -GRANT SELECT (User) ON `mysql`.`roles_mapping` TO `role1` +GRANT SELECT (`Host`) ON `mysql`.`roles_mapping` TO `role3` +GRANT SELECT (`User`) ON `mysql`.`roles_mapping` TO `role1` GRANT USAGE ON *.* TO `foo`@`localhost` GRANT USAGE ON *.* TO `role10` GRANT USAGE ON *.* TO `role1` diff --git a/mysql-test/suite/roles/recursive_dbug.result b/mysql-test/suite/roles/recursive_dbug.result index 55bbad51c09..b94f55ae6fb 100644 --- a/mysql-test/suite/roles/recursive_dbug.result +++ b/mysql-test/suite/roles/recursive_dbug.result @@ -246,7 +246,7 @@ count(concat(User)) 22 show grants; Grants for foo@localhost -GRANT SELECT (User) ON `mysql`.`roles_mapping` TO `role1` +GRANT SELECT (`User`) ON `mysql`.`roles_mapping` TO `role1` GRANT USAGE ON *.* TO `foo`@`localhost` GRANT USAGE ON *.* TO `role10` GRANT USAGE ON *.* TO `role1` @@ -285,8 +285,8 @@ count(concat(User,Host)) 22 show grants; Grants for foo@localhost -GRANT SELECT (Host) ON `mysql`.`roles_mapping` TO `role3` -GRANT SELECT (User) ON `mysql`.`roles_mapping` TO `role1` +GRANT SELECT (`Host`) ON `mysql`.`roles_mapping` TO `role3` +GRANT SELECT (`User`) ON `mysql`.`roles_mapping` TO `role1` GRANT USAGE ON *.* TO `foo`@`localhost` GRANT USAGE ON *.* TO `role10` GRANT USAGE ON *.* TO `role1` diff --git a/mysql-test/suite/roles/set_role-table-column-priv.result b/mysql-test/suite/roles/set_role-table-column-priv.result index 0ee3fceaef5..b9232180bef 100644 --- a/mysql-test/suite/roles/set_role-table-column-priv.result +++ b/mysql-test/suite/roles/set_role-table-column-priv.result @@ -30,7 +30,7 @@ current_user() current_role() test_user@localhost test_role1 show grants; Grants for test_user@localhost -GRANT SELECT (Role) ON `mysql`.`roles_mapping` TO `test_role2` +GRANT SELECT (`Role`) ON `mysql`.`roles_mapping` TO `test_role2` GRANT USAGE ON *.* TO `test_role1` GRANT USAGE ON *.* TO `test_role2` GRANT USAGE ON *.* TO `test_user`@`localhost` @@ -46,7 +46,7 @@ test_role2 test_role2 show grants; Grants for test_user@localhost -GRANT SELECT (Role) ON `mysql`.`roles_mapping` TO `test_role2` +GRANT SELECT (`Role`) ON `mysql`.`roles_mapping` TO `test_role2` GRANT USAGE ON *.* TO `test_role1` GRANT USAGE ON *.* TO `test_role2` GRANT USAGE ON *.* TO `test_user`@`localhost` diff --git a/mysql-test/suite/rpl/r/rpl_ignore_table.result b/mysql-test/suite/rpl/r/rpl_ignore_table.result index 1e0d6f537ab..8f0ed99397c 100644 --- a/mysql-test/suite/rpl/r/rpl_ignore_table.result +++ b/mysql-test/suite/rpl/r/rpl_ignore_table.result @@ -55,7 +55,7 @@ show grants for mysqltest3@localhost; Grants for mysqltest3@localhost GRANT USAGE ON *.* TO `mysqltest3`@`localhost` GRANT SELECT ON `test`.* TO `mysqltest3`@`localhost` -GRANT SELECT (a), INSERT, INSERT (a), UPDATE (a), REFERENCES (a) ON `test`.`t4` TO `mysqltest3`@`localhost` +GRANT SELECT (`a`), INSERT, INSERT (`a`), UPDATE (`a`), REFERENCES (`a`) ON `test`.`t4` TO `mysqltest3`@`localhost` show grants for mysqltest4@localhost; Grants for mysqltest4@localhost GRANT USAGE ON *.* TO `mysqltest4`@`localhost` IDENTIFIED BY PASSWORD '*196BDEDE2AE4F84CA44C47D54D78478C7E2BD7B7' @@ -80,7 +80,7 @@ show grants for mysqltest3@localhost; Grants for mysqltest3@localhost GRANT USAGE ON *.* TO `mysqltest3`@`localhost` GRANT SELECT ON `test`.* TO `mysqltest3`@`localhost` -GRANT SELECT (a), INSERT, INSERT (a), UPDATE (a), REFERENCES (a) ON `test`.`t4` TO `mysqltest3`@`localhost` +GRANT SELECT (`a`), INSERT, INSERT (`a`), UPDATE (`a`), REFERENCES (`a`) ON `test`.`t4` TO `mysqltest3`@`localhost` show grants for mysqltest4@localhost; Grants for mysqltest4@localhost GRANT USAGE ON *.* TO `mysqltest4`@`localhost` IDENTIFIED BY PASSWORD '*196BDEDE2AE4F84CA44C47D54D78478C7E2BD7B7' @@ -107,7 +107,7 @@ show grants for mysqltest3@localhost; Grants for mysqltest3@localhost GRANT USAGE ON *.* TO `mysqltest3`@`localhost` GRANT SELECT ON `test`.* TO `mysqltest3`@`localhost` -GRANT INSERT, INSERT (a), UPDATE (a), REFERENCES (a) ON `test`.`t4` TO `mysqltest3`@`localhost` +GRANT INSERT, INSERT (`a`), UPDATE (`a`), REFERENCES (`a`) ON `test`.`t4` TO `mysqltest3`@`localhost` show grants for mysqltest4@localhost; Grants for mysqltest4@localhost GRANT USAGE ON *.* TO `mysqltest4`@`localhost` IDENTIFIED BY PASSWORD '*196BDEDE2AE4F84CA44C47D54D78478C7E2BD7B7' @@ -119,7 +119,7 @@ show grants for mysqltest3@localhost; Grants for mysqltest3@localhost GRANT USAGE ON *.* TO `mysqltest3`@`localhost` GRANT SELECT ON `test`.* TO `mysqltest3`@`localhost` -GRANT INSERT, INSERT (a), UPDATE (a), REFERENCES (a) ON `test`.`t4` TO `mysqltest3`@`localhost` +GRANT INSERT, INSERT (`a`), UPDATE (`a`), REFERENCES (`a`) ON `test`.`t4` TO `mysqltest3`@`localhost` show grants for mysqltest4@localhost; Grants for mysqltest4@localhost GRANT USAGE ON *.* TO `mysqltest4`@`localhost` IDENTIFIED BY PASSWORD '*196BDEDE2AE4F84CA44C47D54D78478C7E2BD7B7' diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index b48a4d2fc8d..f4a3ab14f57 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -9196,9 +9196,8 @@ static bool show_table_and_column_privileges(THD *thd, const char *username, } else global.append(STRING_WITH_LEN(", ")); - global.append(grant_column->column, - grant_column->key_length, - system_charset_info); + append_identifier(thd, &global, grant_column->column, + grant_column->key_length); } } if (found_col) -- cgit v1.2.1 From a6b327e90a8d7c7fe7f64cd2e3ed8535282ff7ff Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sat, 26 Nov 2022 13:39:25 +0100 Subject: cleanup: VCOL_NOT_VIRTUAL->VCOL_NEXTVAL rename to stress that is a specific hack for Item_func_nextval and should not be used for other items. If a vcol uses Item_func_nextval, a corresponding table for the sequence should be added to the prelocking list (in that sense NEXTVAL is not simply a function, but more like a subquery), see add_internal_tables() in DML_prelocking_strategy::handle_table(). At the moment it is only implemented for DEFAULT, not for GENERATED ALWAYS AS, thus the VCOL_NEXTVAL hack. --- mysql-test/suite/gcol/inc/gcol_blocked_sql_funcs_main.inc | 4 ++++ mysql-test/suite/gcol/r/gcol_blocked_sql_funcs_innodb.result | 3 +++ mysql-test/suite/gcol/r/gcol_blocked_sql_funcs_myisam.result | 3 +++ sql/field.cc | 4 ++-- sql/field.h | 5 ++--- sql/item_func.h | 4 +--- 6 files changed, 15 insertions(+), 8 deletions(-) diff --git a/mysql-test/suite/gcol/inc/gcol_blocked_sql_funcs_main.inc b/mysql-test/suite/gcol/inc/gcol_blocked_sql_funcs_main.inc index 9435551ce6f..879e2fe857d 100644 --- a/mysql-test/suite/gcol/inc/gcol_blocked_sql_funcs_main.inc +++ b/mysql-test/suite/gcol/inc/gcol_blocked_sql_funcs_main.inc @@ -247,3 +247,7 @@ create table t1 (a int); alter table t1 add column r blob generated always as (match(a) against ('' in boolean mode)) virtual; drop table t1; + +--echo # +--echo # End of 10.3 tests +--echo # diff --git a/mysql-test/suite/gcol/r/gcol_blocked_sql_funcs_innodb.result b/mysql-test/suite/gcol/r/gcol_blocked_sql_funcs_innodb.result index fa8f2660aef..b9fe877b0f2 100644 --- a/mysql-test/suite/gcol/r/gcol_blocked_sql_funcs_innodb.result +++ b/mysql-test/suite/gcol/r/gcol_blocked_sql_funcs_innodb.result @@ -170,6 +170,9 @@ alter table t1 add column r blob generated always as (match(a) against ('' in boolean mode)) virtual; ERROR HY000: Function or expression 'match ... against()' cannot be used in the GENERATED ALWAYS AS clause of `r` drop table t1; +# +# End of 10.3 tests +# DROP VIEW IF EXISTS v1,v2; DROP TABLE IF EXISTS t1,t2,t3; DROP PROCEDURE IF EXISTS p1; diff --git a/mysql-test/suite/gcol/r/gcol_blocked_sql_funcs_myisam.result b/mysql-test/suite/gcol/r/gcol_blocked_sql_funcs_myisam.result index b777bb485de..23fdea42488 100644 --- a/mysql-test/suite/gcol/r/gcol_blocked_sql_funcs_myisam.result +++ b/mysql-test/suite/gcol/r/gcol_blocked_sql_funcs_myisam.result @@ -172,6 +172,9 @@ alter table t1 add column r blob generated always as (match(a) against ('' in boolean mode)) virtual; ERROR HY000: Function or expression 'match ... against()' cannot be used in the GENERATED ALWAYS AS clause of `r` drop table t1; +# +# End of 10.3 tests +# DROP VIEW IF EXISTS v1,v2; DROP TABLE IF EXISTS t1,t2,t3; DROP PROCEDURE IF EXISTS p1; diff --git a/sql/field.cc b/sql/field.cc index 43514347106..de92d1dea94 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -10525,8 +10525,8 @@ bool check_expression(Virtual_column_info *vcol, LEX_CSTRING *name, uint filter= VCOL_IMPOSSIBLE; if (type != VCOL_GENERATED_VIRTUAL && type != VCOL_DEFAULT) filter|= VCOL_NOT_STRICTLY_DETERMINISTIC; - if (type == VCOL_GENERATED_VIRTUAL) - filter|= VCOL_NOT_VIRTUAL; + if (type != VCOL_DEFAULT) + filter|= VCOL_NEXTVAL; if (unlikely(ret || (res.errors & filter))) { diff --git a/sql/field.h b/sql/field.h index 4ef4483a15a..757a6cc23d0 100644 --- a/sql/field.h +++ b/sql/field.h @@ -528,10 +528,10 @@ static inline const char *vcol_type_name(enum_vcol_info_type type) #define VCOL_FIELD_REF 1 #define VCOL_NON_DETERMINISTIC 2 #define VCOL_SESSION_FUNC 4 /* uses session data, e.g. USER or DAYNAME */ -#define VCOL_TIME_FUNC 8 +#define VCOL_TIME_FUNC 8 /* safe for SBR */ #define VCOL_AUTO_INC 16 #define VCOL_IMPOSSIBLE 32 -#define VCOL_NOT_VIRTUAL 64 /* Function can't be virtual */ +#define VCOL_NEXTVAL 64 /* NEXVAL is not implemented for vcols */ #define VCOL_NOT_STRICTLY_DETERMINISTIC \ (VCOL_NON_DETERMINISTIC | VCOL_TIME_FUNC | VCOL_SESSION_FUNC) @@ -4965,5 +4965,4 @@ ulonglong TABLE::vers_start_id() const return static_cast(vers_start_field()->val_int()); } - #endif /* FIELD_INCLUDED */ diff --git a/sql/item_func.h b/sql/item_func.h index 7268b56eb97..d7fd24d7fa2 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -3159,9 +3159,7 @@ public: void print(String *str, enum_query_type query_type); bool check_vcol_func_processor(void *arg) { - return mark_unsupported_function(func_name(), "()", arg, - (VCOL_NON_DETERMINISTIC | - VCOL_NOT_VIRTUAL)); + return mark_unsupported_function(func_name(), "()", arg, VCOL_NEXTVAL); } }; -- cgit v1.2.1 From ae53f684d3d02c1ef342891087fa0326b601c2fd Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 27 Nov 2022 14:09:01 +0100 Subject: MDEV-30016 Virtual columns do not support autoincrement columns change vcol_upgrade test to use stored gcols --- mysql-test/std_data/vcol_autoinc.MYI | Bin 1024 -> 1024 bytes mysql-test/std_data/vcol_autoinc.frm | Bin 951 -> 8587 bytes mysql-test/suite/gcol/inc/gcol_column_def_options.inc | 17 ++++++++++++----- .../gcol/r/gcol_column_def_options_innodb.result | 18 ++++++++++++++++++ .../gcol/r/gcol_column_def_options_myisam.result | 18 ++++++++++++++++++ mysql-test/suite/vcol/r/upgrade.result | 2 +- sql/field.h | 3 +++ sql/table.cc | 4 +++- 8 files changed, 55 insertions(+), 7 deletions(-) diff --git a/mysql-test/std_data/vcol_autoinc.MYI b/mysql-test/std_data/vcol_autoinc.MYI index ddb3f2e0748..9b174844f9f 100644 Binary files a/mysql-test/std_data/vcol_autoinc.MYI and b/mysql-test/std_data/vcol_autoinc.MYI differ diff --git a/mysql-test/std_data/vcol_autoinc.frm b/mysql-test/std_data/vcol_autoinc.frm index bff7983735c..ee43f878856 100644 Binary files a/mysql-test/std_data/vcol_autoinc.frm and b/mysql-test/std_data/vcol_autoinc.frm differ diff --git a/mysql-test/suite/gcol/inc/gcol_column_def_options.inc b/mysql-test/suite/gcol/inc/gcol_column_def_options.inc index 17e926758ee..6f4a8ab7240 100644 --- a/mysql-test/suite/gcol/inc/gcol_column_def_options.inc +++ b/mysql-test/suite/gcol/inc/gcol_column_def_options.inc @@ -49,18 +49,18 @@ alter table t1 add column (h int generated always as (a+1) virtual, i int as(5) drop table t1; --echo # DEFAULT ---error 1064 +--error ER_PARSE_ERROR create table t1 (a int, b int generated always as (a+1) virtual default 0); create table t1 (a int); ---error 1064 +--error ER_PARSE_ERROR alter table t1 add column b int generated always as (a+1) virtual default 0; drop table t1; --echo # AUTO_INCREMENT ---error 1064 +--error ER_PARSE_ERROR create table t1 (a int, b int generated always as (a+1) virtual AUTO_INCREMENT); create table t1 (a int); ---error 1064 +--error ER_PARSE_ERROR alter table t1 add column b int generated always as (a+1) virtual AUTO_INCREMENT; drop table t1; @@ -138,7 +138,7 @@ create table t1 (a int, b int generated always as (a % 2) stored references t2(a show create table t1; drop table t1; create table t1 (a int, b int generated always as (a % 2) virtual); ---error 1064 +--error ER_PARSE_ERROR alter table t1 modify b int generated always as (a % 2) stored references t2(a); show create table t1; drop table t1; @@ -199,6 +199,13 @@ create table t1 (a int, b int generated always as(-b) virtual, c int generated a create table t1 (a int, b int generated always as(-c) virtual, c int generated always as (b + 1) virtual); --error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED create table t1 (pk int auto_increment primary key, col_int_nokey int generated always as (pk + col_int_key) stored, col_int_key int); +--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (pk int auto_increment primary key, col_int_nokey int generated always as (pk + col_int_key) unique, col_int_key int); +create table t1 (pk int auto_increment primary key, col_int_nokey int generated always as (pk + col_int_key), col_int_key int); +show create table t1; +insert t1 (col_int_key) values (10),(20),(30); +select * from t1; +drop table t1; --echo # Bug#20339347: FAIL TO USE CREATE ....SELECT STATEMENT TO CREATE A NEW TABLE create table t1 (a int, b int generated always as(-a) virtual, c int generated always as (b + 1) stored); diff --git a/mysql-test/suite/gcol/r/gcol_column_def_options_innodb.result b/mysql-test/suite/gcol/r/gcol_column_def_options_innodb.result index daa372fac8b..2422bdca363 100644 --- a/mysql-test/suite/gcol/r/gcol_column_def_options_innodb.result +++ b/mysql-test/suite/gcol/r/gcol_column_def_options_innodb.result @@ -260,6 +260,24 @@ create table t1 (a int, b int generated always as(-c) virtual, c int generated a ERROR 01000: Expression for field `b` is referring to uninitialized field `c` create table t1 (pk int auto_increment primary key, col_int_nokey int generated always as (pk + col_int_key) stored, col_int_key int); ERROR HY000: Function or expression 'AUTO_INCREMENT' cannot be used in the GENERATED ALWAYS AS clause of `pk` +create table t1 (pk int auto_increment primary key, col_int_nokey int generated always as (pk + col_int_key) unique, col_int_key int); +ERROR HY000: Function or expression 'AUTO_INCREMENT' cannot be used in the GENERATED ALWAYS AS clause of `pk` +create table t1 (pk int auto_increment primary key, col_int_nokey int generated always as (pk + col_int_key), col_int_key int); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `pk` int(11) NOT NULL AUTO_INCREMENT, + `col_int_nokey` int(11) GENERATED ALWAYS AS (`pk` + `col_int_key`) VIRTUAL, + `col_int_key` int(11) DEFAULT NULL, + PRIMARY KEY (`pk`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +insert t1 (col_int_key) values (10),(20),(30); +select * from t1; +pk col_int_nokey col_int_key +1 11 10 +2 22 20 +3 33 30 +drop table t1; # Bug#20339347: FAIL TO USE CREATE ....SELECT STATEMENT TO CREATE A NEW TABLE create table t1 (a int, b int generated always as(-a) virtual, c int generated always as (b + 1) stored); insert into t1(a) values(1),(2); diff --git a/mysql-test/suite/gcol/r/gcol_column_def_options_myisam.result b/mysql-test/suite/gcol/r/gcol_column_def_options_myisam.result index 59215426b31..82c4b65512f 100644 --- a/mysql-test/suite/gcol/r/gcol_column_def_options_myisam.result +++ b/mysql-test/suite/gcol/r/gcol_column_def_options_myisam.result @@ -260,6 +260,24 @@ create table t1 (a int, b int generated always as(-c) virtual, c int generated a ERROR 01000: Expression for field `b` is referring to uninitialized field `c` create table t1 (pk int auto_increment primary key, col_int_nokey int generated always as (pk + col_int_key) stored, col_int_key int); ERROR HY000: Function or expression 'AUTO_INCREMENT' cannot be used in the GENERATED ALWAYS AS clause of `pk` +create table t1 (pk int auto_increment primary key, col_int_nokey int generated always as (pk + col_int_key) unique, col_int_key int); +ERROR HY000: Function or expression 'AUTO_INCREMENT' cannot be used in the GENERATED ALWAYS AS clause of `pk` +create table t1 (pk int auto_increment primary key, col_int_nokey int generated always as (pk + col_int_key), col_int_key int); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `pk` int(11) NOT NULL AUTO_INCREMENT, + `col_int_nokey` int(11) GENERATED ALWAYS AS (`pk` + `col_int_key`) VIRTUAL, + `col_int_key` int(11) DEFAULT NULL, + PRIMARY KEY (`pk`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +insert t1 (col_int_key) values (10),(20),(30); +select * from t1; +pk col_int_nokey col_int_key +1 11 10 +2 22 20 +3 33 30 +drop table t1; # Bug#20339347: FAIL TO USE CREATE ....SELECT STATEMENT TO CREATE A NEW TABLE create table t1 (a int, b int generated always as(-a) virtual, c int generated always as (b + 1) stored); insert into t1(a) values(1),(2); diff --git a/mysql-test/suite/vcol/r/upgrade.result b/mysql-test/suite/vcol/r/upgrade.result index fea6588a5f3..5393a3543dc 100644 --- a/mysql-test/suite/vcol/r/upgrade.result +++ b/mysql-test/suite/vcol/r/upgrade.result @@ -6,7 +6,7 @@ show create table vcol_autoinc; Table Create Table vcol_autoinc CREATE TABLE `vcol_autoinc` ( `pk` int(11) NOT NULL AUTO_INCREMENT, - `v3` int(11) GENERATED ALWAYS AS (`pk`) VIRTUAL, + `v3` int(11) GENERATED ALWAYS AS (`pk`) STORED, PRIMARY KEY (`pk`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci select * from vcol_autoinc; diff --git a/sql/field.h b/sql/field.h index 757a6cc23d0..ce15184ea1d 100644 --- a/sql/field.h +++ b/sql/field.h @@ -498,6 +498,8 @@ enum enum_vcol_info_type VCOL_GENERATED_VIRTUAL, VCOL_GENERATED_STORED, VCOL_DEFAULT, VCOL_CHECK_FIELD, VCOL_CHECK_TABLE, /* Additional types should be added here */ + + VCOL_GENERATED_VIRTUAL_INDEXED, // this is never written in .frm /* Following is the highest value last */ VCOL_TYPE_NONE = 127 // Since the 0 value is already in use }; @@ -507,6 +509,7 @@ static inline const char *vcol_type_name(enum_vcol_info_type type) switch (type) { case VCOL_GENERATED_VIRTUAL: + case VCOL_GENERATED_VIRTUAL_INDEXED: case VCOL_GENERATED_STORED: return "GENERATED ALWAYS AS"; case VCOL_DEFAULT: diff --git a/sql/table.cc b/sql/table.cc index 54a1e8b1b57..b2d8c4676e6 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -2629,6 +2629,8 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, share->stored_fields--; if (reg_field->flags & BLOB_FLAG) share->virtual_not_stored_blob_fields++; + if (reg_field->flags & PART_KEY_FLAG) + vcol_info->set_vcol_type(VCOL_GENERATED_VIRTUAL_INDEXED); /* Correct stored_rec_length as non stored fields are last */ recpos= (uint) (reg_field->ptr - record); if (share->stored_rec_length >= recpos) @@ -3159,7 +3161,7 @@ bool Virtual_column_info::fix_and_check_expr(THD *thd, TABLE *table) get_vcol_type_name(), name.str); DBUG_RETURN(1); } - else if (unlikely(res.errors & VCOL_AUTO_INC)) + else if (res.errors & VCOL_AUTO_INC && vcol_type != VCOL_GENERATED_VIRTUAL) { /* An auto_increment field may not be used in an expression for -- cgit v1.2.1 From 37bfe32c6d4a65ea7b8297817e01954d6212c863 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 27 Nov 2022 00:03:04 +0100 Subject: try harder to reject not strictly deterministic vcols in indexes/stored detect non-determinism in vcol of vcol, like: create table t1 (a int, b real as (rand()), c real as (b) stored); --- mysql-test/suite/vcol/r/not_supported.result | 13 +++++++++++++ mysql-test/suite/vcol/t/not_supported.test | 15 +++++++++++++++ sql/item.h | 11 ++++++----- sql/table.cc | 9 ++++++++- 4 files changed, 42 insertions(+), 6 deletions(-) diff --git a/mysql-test/suite/vcol/r/not_supported.result b/mysql-test/suite/vcol/r/not_supported.result index d8703f755da..37ce4865dcc 100644 --- a/mysql-test/suite/vcol/r/not_supported.result +++ b/mysql-test/suite/vcol/r/not_supported.result @@ -42,3 +42,16 @@ ERROR 42000: You have an error in your SQL syntax; check the manual that corresp # # End of 10.2 tests # +create table t1 (a int, b real as (rand()), c real as (b) stored); +ERROR HY000: Function or expression 'b' cannot be used in the GENERATED ALWAYS AS clause of `c` +create table t1 (a int, b real as (rand()), c real as (b) unique); +ERROR HY000: Function or expression 'b' cannot be used in the GENERATED ALWAYS AS clause of `c` +create table t1 (a int auto_increment primary key, +b int as (a+1), c int as (b+1) stored); +ERROR HY000: Function or expression 'b' cannot be used in the GENERATED ALWAYS AS clause of `c` +create table t1 (a int auto_increment primary key, +b int as (a+1), c int as (b+1) unique); +ERROR HY000: Function or expression 'b' cannot be used in the GENERATED ALWAYS AS clause of `c` +# +# End of 10.3 tests +# diff --git a/mysql-test/suite/vcol/t/not_supported.test b/mysql-test/suite/vcol/t/not_supported.test index 2b5baf4ff4b..d58b207a7eb 100644 --- a/mysql-test/suite/vcol/t/not_supported.test +++ b/mysql-test/suite/vcol/t/not_supported.test @@ -49,3 +49,18 @@ create table t1 (a int, b serial as (a+1)); --echo # --echo # End of 10.2 tests --echo # + +--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a int, b real as (rand()), c real as (b) stored); +--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a int, b real as (rand()), c real as (b) unique); +--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a int auto_increment primary key, + b int as (a+1), c int as (b+1) stored); +--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a int auto_increment primary key, + b int as (a+1), c int as (b+1) unique); + +--echo # +--echo # End of 10.3 tests +--echo # diff --git a/sql/item.h b/sql/item.h index 07fbe848bb7..ec87a3fb812 100644 --- a/sql/item.h +++ b/sql/item.h @@ -3184,12 +3184,13 @@ public: bool check_vcol_func_processor(void *arg) { context= 0; + uint res= VCOL_FIELD_REF; if (field && (field->unireg_check == Field::NEXT_NUMBER)) - { - // Auto increment fields are unsupported - return mark_unsupported_function(field_name.str, arg, VCOL_FIELD_REF | VCOL_AUTO_INC); - } - return mark_unsupported_function(field_name.str, arg, VCOL_FIELD_REF); + res|= VCOL_AUTO_INC; + if (field && field->vcol_info && + field->vcol_info->flags & (VCOL_NOT_STRICTLY_DETERMINISTIC | VCOL_AUTO_INC)) + res|= VCOL_NON_DETERMINISTIC; + return mark_unsupported_function(field_name.str, arg, res); } bool set_fields_as_dependent_processor(void *arg) { diff --git a/sql/table.cc b/sql/table.cc index b2d8c4676e6..ec49241dd7a 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -3172,11 +3172,18 @@ bool Virtual_column_info::fix_and_check_expr(THD *thd, TABLE *table) pointer at that time */ myf warn= table->s->frm_version < FRM_VER_EXPRESSSIONS ? ME_JUST_WARNING : 0; - my_error(ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED, MYF(warn), + my_error(ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED, MYF(warn), "AUTO_INCREMENT", get_vcol_type_name(), res.name); if (!warn) DBUG_RETURN(1); } + else if (vcol_type != VCOL_GENERATED_VIRTUAL && vcol_type != VCOL_DEFAULT && + res.errors & VCOL_NOT_STRICTLY_DETERMINISTIC) + { + my_error(ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED, MYF(0), + res.name, get_vcol_type_name(), name.str); + DBUG_RETURN(1); + } flags= res.errors; if (!table->s->tmp_table && need_refix()) -- cgit v1.2.1 From 401ae95a6089b0cec5e5b9900bdb44a1f78c4248 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 27 Nov 2022 19:50:02 +0100 Subject: MDEV-30082 View definition losing brackets changes semantics of the query and causes wrong result Item_func_not_all::print() either uses Item_func::print() or directly invokes args[0]->print(). Thus the precedence should be either the one of Item_func or of args[0]. Item_allany_subselect::print() prints args[0], then a comparison op, then a subquery. That is, the precedence should be the one of a comparison. --- mysql-test/main/precedence_bugs.result | 18 ++++++++++++++++++ mysql-test/main/precedence_bugs.test | 16 ++++++++++++++++ sql/item_cmpfunc.h | 2 ++ sql/item_subselect.h | 1 + 4 files changed, 37 insertions(+) diff --git a/mysql-test/main/precedence_bugs.result b/mysql-test/main/precedence_bugs.result index 4b13e820d7f..723ab823b48 100644 --- a/mysql-test/main/precedence_bugs.result +++ b/mysql-test/main/precedence_bugs.result @@ -58,3 +58,21 @@ Create View CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY D character_set_client latin1 collation_connection latin1_swedish_ci drop view v1; +# +# MDEV-30082 View definition losing brackets changes semantics of the query and causes wrong result +# +create table t1 (a varchar(1), b bool) engine=myisam; +insert into t1 values ('u',1),('s',1); +select * from t1 where t1.b in (t1.a <= all (select 'a')); +a b +create view v as select * from t1 where t1.b in (t1.a <= all (select 'a')); +select * from v; +a b +show create view v; +View Create View character_set_client collation_connection +v CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v` AS select `t1`.`a` AS `a`,`t1`.`b` AS `b` from `t1` where `t1`.`b` = (`t1`.`a` <= all (select 'a')) latin1 latin1_swedish_ci +drop view v; +drop table t1; +# +# End of 10.3 results +# diff --git a/mysql-test/main/precedence_bugs.test b/mysql-test/main/precedence_bugs.test index 6e8e624c840..ae35ca91527 100644 --- a/mysql-test/main/precedence_bugs.test +++ b/mysql-test/main/precedence_bugs.test @@ -39,3 +39,19 @@ drop table t1; create view v1 as select 1 like (now() between '2000-01-01' and '2012-12-12' ); query_vertical show create view v1; drop view v1; + +--echo # +--echo # MDEV-30082 View definition losing brackets changes semantics of the query and causes wrong result +--echo # +create table t1 (a varchar(1), b bool) engine=myisam; +insert into t1 values ('u',1),('s',1); +select * from t1 where t1.b in (t1.a <= all (select 'a')); +create view v as select * from t1 where t1.b in (t1.a <= all (select 'a')); +select * from v; +show create view v; +drop view v; +drop table t1; + +--echo # +--echo # End of 10.3 results +--echo # diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index f3d3be44b62..671fa52635d 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -668,6 +668,8 @@ public: longlong val_int(); enum Functype functype() const { return NOT_ALL_FUNC; } const char *func_name() const { return ""; } + enum precedence precedence() const + { return show ? Item_func::precedence() : args[0]->precedence(); } bool fix_fields(THD *thd, Item **ref) {return Item_func::fix_fields(thd, ref);} virtual void print(String *str, enum_query_type query_type); diff --git a/sql/item_subselect.h b/sql/item_subselect.h index b95a02d28b2..32bedb522ac 100644 --- a/sql/item_subselect.h +++ b/sql/item_subselect.h @@ -783,6 +783,7 @@ public: bool select_transformer(JOIN *join); void create_comp_func(bool invert) { func= func_creator(invert); } void print(String *str, enum_query_type query_type); + enum precedence precedence() const { return CMP_PRECEDENCE; } bool is_maxmin_applicable(JOIN *join); bool transform_into_max_min(JOIN *join); void no_rows_in_result(); -- cgit v1.2.1 From 1547e55489813ff7dc3d75a1d7feb0d532f02acf Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 30 Nov 2022 22:49:44 +0100 Subject: fix more sporadic failures on main.kill sometimes `KILL QUERY ID @id` was executed before the previous `send SELECT SLEEP(1000)` has reached the parser. As the statement resets the kill status before execution, the effect of the KILL was ignored. --- mysql-test/main/kill.test | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mysql-test/main/kill.test b/mysql-test/main/kill.test index f7fe0f38272..b197865f5ed 100644 --- a/mysql-test/main/kill.test +++ b/mysql-test/main/kill.test @@ -542,7 +542,7 @@ connection default; --echo # send SELECT SLEEP(1000); connection con1; -let $wait_condition= SELECT @id:=QUERY_ID FROM INFORMATION_SCHEMA.PROCESSLIST WHERE INFO='SELECT SLEEP(1000)'; +let $wait_condition= SELECT @id:=QUERY_ID FROM INFORMATION_SCHEMA.PROCESSLIST WHERE INFO='SELECT SLEEP(1000)' AND STATE='User sleep'; source include/wait_condition.inc; KILL QUERY ID @id; connection default; @@ -560,7 +560,7 @@ CREATE USER u1@localhost; send SELECT SLEEP(1000); connection con1; -let $wait_condition= SELECT @id:=QUERY_ID FROM INFORMATION_SCHEMA.PROCESSLIST WHERE INFO='SELECT SLEEP(1000)'; +let $wait_condition= SELECT @id:=QUERY_ID FROM INFORMATION_SCHEMA.PROCESSLIST WHERE INFO='SELECT SLEEP(1000)' AND STATE='User sleep'; source include/wait_condition.inc; let $id= `SELECT @id`; -- cgit v1.2.1 From 43173ef2614030afbf0d393a93932e7e8bab1d3e Mon Sep 17 00:00:00 2001 From: Anel Husakovic Date: Tue, 27 Jul 2021 16:09:30 +0200 Subject: MDEV-26102 dgcov: add support for *.gcda.gcov.json.gz files of gcov 9.1+ - Script covers situation for gcov (gcc) < 9 with non-json format of generated files as well as for gcov (gcc) >=8 with json generated format Reviewed by: serg@mariadb.com --- mysql-test/dgcov.pl | 54 +++++++++++++++++++++++++++++++++++------------------ 1 file changed, 36 insertions(+), 18 deletions(-) diff --git a/mysql-test/dgcov.pl b/mysql-test/dgcov.pl index 2c00c64d1ff..7ef0a918a96 100755 --- a/mysql-test/dgcov.pl +++ b/mysql-test/dgcov.pl @@ -62,13 +62,16 @@ my $res; my $cmd; if ($opt_purge) { - $cmd= "find . -name '*.da' -o -name '*.gcda' -o -name '*.gcov' -o ". + $cmd= "find . -name '*.da' -o -name '*.gcda*' -o -name '*.gcov' -o ". "-name '*.dgcov' | grep -v 'README\.gcov' | xargs rm -f ''"; logv "Running: $cmd"; system($cmd)==0 or die "system($cmd): $? $!"; exit 0; } +my $gcc_version= `gcc -dumpversion`; +$gcc_version=~ s/(\d).*$/$1/; + find(\&gcov_one_file, $root); find(\&write_coverage, $root) if $opt_generate; exit 0 if $opt_only_gcov; @@ -162,26 +165,41 @@ sub gcov_one_file { } # now, read the generated file - for my $gcov_file (<$_*.gcov>) { - open FH, '<', "$gcov_file" or die "open(<$gcov_file): $!"; - my $fname; - while () { - chomp; - if (/^function:/) { - next; - } - if (/^file:/) { - $fname=realpath(-f $' ? $' : $root.$'); - next; + if ($gcc_version <9){ + for my $gcov_file (<$_*.gcov>) { + open FH, '<', "$gcov_file" or die "open(<$gcov_file): $!"; + my $fname; + while () { + chomp; + if (/^function:/) { + next; + } + if (/^file:/) { + $fname=realpath(-f $' ? $' : $root.$'); + next; + } + next if /^lcount:\d+,-\d+/; # whatever that means + unless (/^lcount:(\d+),(\d+)/ and $fname) { + warn "unknown line '$_' in $gcov_file"; + next; + } + $cov{$fname}->{$1}+=$2; } - next if /^lcount:\d+,-\d+/; # whatever that means - unless (/^lcount:(\d+),(\d+)/ and $fname) { - warn "unknown line '$_' in $gcov_file"; - next; + close(FH); + } + } else { + use IO::Uncompress::Gunzip qw(gunzip $GunzipError); + use JSON::PP; + my $gcov_file_json; + my $fname; + gunzip "$_.gcov.json.gz" => \$gcov_file_json or die "gunzip($_.gcov.json.gz): $GunzipError"; + my $obj= decode_json $gcov_file_json; + for my $file (@{$obj->{files}}) { + $fname= $file->{file}; + for my $line (@{$file->{lines}}){ + $cov{$fname}->{$line->{line_number}}+= $line->{count}; } - $cov{$fname}->{$1}+=$2; } - close(FH); } } -- cgit v1.2.1 From 7baf24a0f8e9491a55e47734d5242821a360f1bc Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Thu, 1 Dec 2022 20:24:12 +0100 Subject: MDEV-26102 followup * update README * fix version regex to support versions with two digits * die if the version cannot be parsed * support gcc versions 11+ * require JSON::PP not use, to avoid introducing new rpm dependency into MariaDB-test --- mysql-test/README-gcov | 15 ++++----------- mysql-test/dgcov.pl | 9 +++++---- 2 files changed, 9 insertions(+), 15 deletions(-) diff --git a/mysql-test/README-gcov b/mysql-test/README-gcov index ba22a796423..64a97ce47e2 100644 --- a/mysql-test/README-gcov +++ b/mysql-test/README-gcov @@ -2,14 +2,7 @@ To be able to see the level of coverage with the current test suite, do the following: - Make sure gcov is installed - - Compile the MySQL distribution with BUILD/compile-pentium64-gcov (if your - machine does not have a pentium CPU, hack this script, or just live with - the pentium-specific stuff) - - In the mysql-test directory, run this command: ./mysql-test-run -gcov - - To see the level of coverage for a given source file: - grep -1 source_file_name ../mysql-test-gcov.msg - - To see which lines are not yet covered, look at source_file_name.gcov in - the source tree. You can find this by doing something like: - find source-directory -name "mysqld.cc.gcov" - Then think hard about a test case that will cover those lines, and write - one! + - Compile the MariaDB distribution with -DENABLE_GCOV=1 + - In the mysql-test directory, run this command: `./mysql-test-run --gcov` + - see var/last_changes.dgcov for the coverage of uncommitted code + - see `./dgcov -h` for more options diff --git a/mysql-test/dgcov.pl b/mysql-test/dgcov.pl index 7ef0a918a96..4adafd552fa 100755 --- a/mysql-test/dgcov.pl +++ b/mysql-test/dgcov.pl @@ -63,14 +63,14 @@ my $cmd; if ($opt_purge) { $cmd= "find . -name '*.da' -o -name '*.gcda*' -o -name '*.gcov' -o ". - "-name '*.dgcov' | grep -v 'README\.gcov' | xargs rm -f ''"; + "-name '*.dgcov' | xargs rm -f ''"; logv "Running: $cmd"; system($cmd)==0 or die "system($cmd): $? $!"; exit 0; } my $gcc_version= `gcc -dumpversion`; -$gcc_version=~ s/(\d).*$/$1/; +$gcc_version=~ s/^(\d+)\..*$/$1/ or die "Cannot parse gcc -dumpversion: $gcc_version"; find(\&gcov_one_file, $root); find(\&write_coverage, $root) if $opt_generate; @@ -189,11 +189,12 @@ sub gcov_one_file { } } else { use IO::Uncompress::Gunzip qw(gunzip $GunzipError); - use JSON::PP; + require JSON::PP; my $gcov_file_json; my $fname; + s/\.gcda$// if $gcc_version >= 11; gunzip "$_.gcov.json.gz" => \$gcov_file_json or die "gunzip($_.gcov.json.gz): $GunzipError"; - my $obj= decode_json $gcov_file_json; + my $obj= JSON::PP::decode_json $gcov_file_json; for my $file (@{$obj->{files}}) { $fname= $file->{file}; for my $line (@{$file->{lines}}){ -- cgit v1.2.1 From 180b2bcd5389082e200f65ebc13a9b81bcc3e882 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 4 Dec 2022 00:31:29 +0100 Subject: dgcov: also remove rpm dependency on IO::Uncompress::Gunzip and enable option bundling --- mysql-test/dgcov.pl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/mysql-test/dgcov.pl b/mysql-test/dgcov.pl index 4adafd552fa..c05c4211caa 100755 --- a/mysql-test/dgcov.pl +++ b/mysql-test/dgcov.pl @@ -36,6 +36,7 @@ my $opt_skip_gcov; my %cov; my $file_no=0; +Getopt::Long::Configure ("bundling"); GetOptions ("v|verbose+" => \$opt_verbose, "h|help" => \$opt_help, @@ -188,17 +189,16 @@ sub gcov_one_file { close(FH); } } else { - use IO::Uncompress::Gunzip qw(gunzip $GunzipError); + require IO::Uncompress::Gunzip; require JSON::PP; my $gcov_file_json; - my $fname; s/\.gcda$// if $gcc_version >= 11; - gunzip "$_.gcov.json.gz" => \$gcov_file_json or die "gunzip($_.gcov.json.gz): $GunzipError"; + IO::Uncompress::Gunzip::gunzip("$_.gcov.json.gz", \$gcov_file_json) + or die "gunzip($_.gcov.json.gz): $IO::Uncompress::Gunzip::GunzipError"; my $obj= JSON::PP::decode_json $gcov_file_json; for my $file (@{$obj->{files}}) { - $fname= $file->{file}; for my $line (@{$file->{lines}}){ - $cov{$fname}->{$line->{line_number}}+= $line->{count}; + $cov{$file->{file}}->{$line->{line_number}}+= $line->{count}; } } } -- cgit v1.2.1 From a59dffb0e92704b308476e1e38651318a4c044b2 Mon Sep 17 00:00:00 2001 From: Anel Husakovic Date: Mon, 5 Dec 2022 11:13:21 +0100 Subject: dgcov: parsing without dot to get specific version - Regression introduced 7baf24a0f8e9491a55 for multidigit gcc dump. There is no dot in `dumpversion`. ``` $ gcc -dumpversion 10 ``` Otherwise it will fail and not produce the output ``` Running dgcov Name "IO::Uncompress::Gunzip::GunzipError" used only once: possible typo at ./dgcov.pl line 197. Cannot parse gcc -dumpversion: 9 ``` - The warning `once` is always generated: ``` Running dgcov Name "IO::Uncompress::Gunzip::GunzipError" used only once: possible typo at ./dgcov.pl line 197. ``` Suppresing the line `Name "IO::Uncompress::Gunzip::GunzipError" used only once: possible typo at ./dgcov.pl line 197.` with the patch. - Reviewed by: <> --- mysql-test/dgcov.pl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mysql-test/dgcov.pl b/mysql-test/dgcov.pl index c05c4211caa..94fe48805d1 100755 --- a/mysql-test/dgcov.pl +++ b/mysql-test/dgcov.pl @@ -71,7 +71,7 @@ if ($opt_purge) } my $gcc_version= `gcc -dumpversion`; -$gcc_version=~ s/^(\d+)\..*$/$1/ or die "Cannot parse gcc -dumpversion: $gcc_version"; +$gcc_version=~ s/^(\d+).*$/$1/ or die "Cannot parse gcc -dumpversion: $gcc_version"; find(\&gcov_one_file, $root); find(\&write_coverage, $root) if $opt_generate; @@ -191,6 +191,7 @@ sub gcov_one_file { } else { require IO::Uncompress::Gunzip; require JSON::PP; + no warnings 'once'; my $gcov_file_json; s/\.gcda$// if $gcc_version >= 11; IO::Uncompress::Gunzip::gunzip("$_.gcov.json.gz", \$gcov_file_json) -- cgit v1.2.1 From 2beede9ba48c270d94662f66c49c5129caaa1e8b Mon Sep 17 00:00:00 2001 From: Nayuta Yanagisawa Date: Tue, 27 Sep 2022 12:01:29 +0900 Subject: MDEV-29636 Assertion `part_share->auto_inc_initialized || !can_use_for_auto_inc_init()' failed in ha_partition::set_auto_increment_if_higher upon REPLACE with partition pruning The bug is caused by a similar mechanism as MDEV-21027. The function, check_insert_or_replace_autoincrement, failed to open all the partitions on REPLACE SELECT statements and it results in the assertion error. --- mysql-test/suite/parts/inc/partition_auto_increment.inc | 13 +++++++++++++ .../suite/parts/r/partition_auto_increment_blackhole.result | 12 ++++++++++++ .../suite/parts/r/partition_auto_increment_innodb.result | 12 ++++++++++++ .../suite/parts/r/partition_auto_increment_maria.result | 12 ++++++++++++ .../suite/parts/r/partition_auto_increment_memory.result | 12 ++++++++++++ .../suite/parts/r/partition_auto_increment_myisam.result | 12 ++++++++++++ sql/ha_partition.h | 3 ++- .../tokudb_parts/r/partition_auto_increment_tokudb.result | 12 ++++++++++++ 8 files changed, 87 insertions(+), 1 deletion(-) diff --git a/mysql-test/suite/parts/inc/partition_auto_increment.inc b/mysql-test/suite/parts/inc/partition_auto_increment.inc index fcfd5bce746..974e4fe559d 100644 --- a/mysql-test/suite/parts/inc/partition_auto_increment.inc +++ b/mysql-test/suite/parts/inc/partition_auto_increment.inc @@ -873,6 +873,19 @@ eval CREATE OR REPLACE TABLE t1 (pk INT AUTO_INCREMENT, a INT, KEY(pk)) ENGINE=$ INSERT INTO t1 VALUES (1,1),(2,2); UPDATE t1 SET pk = 0; DROP TABLE t1; + +--echo # +--echo # MDEV-29636 Assertion `part_share->auto_inc_initialized || !can_use_for_auto_inc_init()' +--echo # failed in ha_partition::set_auto_increment_if_higher upon REPLACE +--echo # with partition pruning +--echo # +eval CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY) ENGINE=$engine +PARTITION BY RANGE (a) ( + PARTITION p0 VALUES LESS THAN (10), + PARTITION pn VALUES LESS THAN MAXVALUE +); +REPLACE INTO t1 PARTITION (p0) SELECT 1; +DROP TABLE t1; } if (!$skip_delete) diff --git a/mysql-test/suite/parts/r/partition_auto_increment_blackhole.result b/mysql-test/suite/parts/r/partition_auto_increment_blackhole.result index 94e4a64ab6a..8c82541b988 100644 --- a/mysql-test/suite/parts/r/partition_auto_increment_blackhole.result +++ b/mysql-test/suite/parts/r/partition_auto_increment_blackhole.result @@ -704,6 +704,18 @@ INSERT INTO t1 VALUES (1,1),(2,2); UPDATE t1 SET pk = 0; DROP TABLE t1; # +# MDEV-29636 Assertion `part_share->auto_inc_initialized || !can_use_for_auto_inc_init()' +# failed in ha_partition::set_auto_increment_if_higher upon REPLACE +# with partition pruning +# +CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY) ENGINE='Blackhole' +PARTITION BY RANGE (a) ( +PARTITION p0 VALUES LESS THAN (10), +PARTITION pn VALUES LESS THAN MAXVALUE +); +REPLACE INTO t1 PARTITION (p0) SELECT 1; +DROP TABLE t1; +# # MDEV-21027 Assertion `part_share->auto_inc_initialized || !can_use_for_auto_inc_init()' # ha_partition::set_auto_increment_if_higher # diff --git a/mysql-test/suite/parts/r/partition_auto_increment_innodb.result b/mysql-test/suite/parts/r/partition_auto_increment_innodb.result index a10eee73a2e..48b0d06575a 100644 --- a/mysql-test/suite/parts/r/partition_auto_increment_innodb.result +++ b/mysql-test/suite/parts/r/partition_auto_increment_innodb.result @@ -1111,6 +1111,18 @@ INSERT INTO t1 VALUES (1,1),(2,2); UPDATE t1 SET pk = 0; DROP TABLE t1; # +# MDEV-29636 Assertion `part_share->auto_inc_initialized || !can_use_for_auto_inc_init()' +# failed in ha_partition::set_auto_increment_if_higher upon REPLACE +# with partition pruning +# +CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY) ENGINE='InnoDB' +PARTITION BY RANGE (a) ( +PARTITION p0 VALUES LESS THAN (10), +PARTITION pn VALUES LESS THAN MAXVALUE +); +REPLACE INTO t1 PARTITION (p0) SELECT 1; +DROP TABLE t1; +# # MDEV-21027 Assertion `part_share->auto_inc_initialized || !can_use_for_auto_inc_init()' # ha_partition::set_auto_increment_if_higher # diff --git a/mysql-test/suite/parts/r/partition_auto_increment_maria.result b/mysql-test/suite/parts/r/partition_auto_increment_maria.result index d9bc3b77ed5..3767a278503 100644 --- a/mysql-test/suite/parts/r/partition_auto_increment_maria.result +++ b/mysql-test/suite/parts/r/partition_auto_increment_maria.result @@ -1158,6 +1158,18 @@ INSERT INTO t1 VALUES (1,1),(2,2); UPDATE t1 SET pk = 0; DROP TABLE t1; # +# MDEV-29636 Assertion `part_share->auto_inc_initialized || !can_use_for_auto_inc_init()' +# failed in ha_partition::set_auto_increment_if_higher upon REPLACE +# with partition pruning +# +CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY) ENGINE='Aria' +PARTITION BY RANGE (a) ( +PARTITION p0 VALUES LESS THAN (10), +PARTITION pn VALUES LESS THAN MAXVALUE +); +REPLACE INTO t1 PARTITION (p0) SELECT 1; +DROP TABLE t1; +# # MDEV-21027 Assertion `part_share->auto_inc_initialized || !can_use_for_auto_inc_init()' # ha_partition::set_auto_increment_if_higher # diff --git a/mysql-test/suite/parts/r/partition_auto_increment_memory.result b/mysql-test/suite/parts/r/partition_auto_increment_memory.result index c265ffeeed6..936e3e9e1cb 100644 --- a/mysql-test/suite/parts/r/partition_auto_increment_memory.result +++ b/mysql-test/suite/parts/r/partition_auto_increment_memory.result @@ -1139,6 +1139,18 @@ INSERT INTO t1 VALUES (1,1),(2,2); UPDATE t1 SET pk = 0; DROP TABLE t1; # +# MDEV-29636 Assertion `part_share->auto_inc_initialized || !can_use_for_auto_inc_init()' +# failed in ha_partition::set_auto_increment_if_higher upon REPLACE +# with partition pruning +# +CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY) ENGINE='Memory' +PARTITION BY RANGE (a) ( +PARTITION p0 VALUES LESS THAN (10), +PARTITION pn VALUES LESS THAN MAXVALUE +); +REPLACE INTO t1 PARTITION (p0) SELECT 1; +DROP TABLE t1; +# # MDEV-21027 Assertion `part_share->auto_inc_initialized || !can_use_for_auto_inc_init()' # ha_partition::set_auto_increment_if_higher # diff --git a/mysql-test/suite/parts/r/partition_auto_increment_myisam.result b/mysql-test/suite/parts/r/partition_auto_increment_myisam.result index a0befe8ef2c..475533ceb76 100644 --- a/mysql-test/suite/parts/r/partition_auto_increment_myisam.result +++ b/mysql-test/suite/parts/r/partition_auto_increment_myisam.result @@ -1158,6 +1158,18 @@ INSERT INTO t1 VALUES (1,1),(2,2); UPDATE t1 SET pk = 0; DROP TABLE t1; # +# MDEV-29636 Assertion `part_share->auto_inc_initialized || !can_use_for_auto_inc_init()' +# failed in ha_partition::set_auto_increment_if_higher upon REPLACE +# with partition pruning +# +CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY) ENGINE='MyISAM' +PARTITION BY RANGE (a) ( +PARTITION p0 VALUES LESS THAN (10), +PARTITION pn VALUES LESS THAN MAXVALUE +); +REPLACE INTO t1 PARTITION (p0) SELECT 1; +DROP TABLE t1; +# # MDEV-21027 Assertion `part_share->auto_inc_initialized || !can_use_for_auto_inc_init()' # ha_partition::set_auto_increment_if_higher # diff --git a/sql/ha_partition.h b/sql/ha_partition.h index 5d1ca70d3a9..eee73451cdc 100644 --- a/sql/ha_partition.h +++ b/sql/ha_partition.h @@ -1410,7 +1410,8 @@ private: if (!part_share->auto_inc_initialized && (ha_thd()->lex->sql_command == SQLCOM_INSERT || ha_thd()->lex->sql_command == SQLCOM_INSERT_SELECT || - ha_thd()->lex->sql_command == SQLCOM_REPLACE) && + ha_thd()->lex->sql_command == SQLCOM_REPLACE || + ha_thd()->lex->sql_command == SQLCOM_REPLACE_SELECT) && table->found_next_number_field) bitmap_set_all(&m_part_info->read_partitions); } diff --git a/storage/tokudb/mysql-test/tokudb_parts/r/partition_auto_increment_tokudb.result b/storage/tokudb/mysql-test/tokudb_parts/r/partition_auto_increment_tokudb.result index b111de8f344..543cc0e1122 100644 --- a/storage/tokudb/mysql-test/tokudb_parts/r/partition_auto_increment_tokudb.result +++ b/storage/tokudb/mysql-test/tokudb_parts/r/partition_auto_increment_tokudb.result @@ -1125,6 +1125,18 @@ INSERT INTO t1 VALUES (1,1),(2,2); UPDATE t1 SET pk = 0; DROP TABLE t1; # +# MDEV-29636 Assertion `part_share->auto_inc_initialized || !can_use_for_auto_inc_init()' +# failed in ha_partition::set_auto_increment_if_higher upon REPLACE +# with partition pruning +# +CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY) ENGINE='TokuDB' +PARTITION BY RANGE (a) ( +PARTITION p0 VALUES LESS THAN (10), +PARTITION pn VALUES LESS THAN MAXVALUE +); +REPLACE INTO t1 PARTITION (p0) SELECT 1; +DROP TABLE t1; +# # MDEV-21027 Assertion `part_share->auto_inc_initialized || !can_use_for_auto_inc_init()' # ha_partition::set_auto_increment_if_higher # -- cgit v1.2.1 From d360fa6fa897d9556dc3813e6f3366e01df8e715 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Mon, 5 Dec 2022 15:07:50 +0100 Subject: MDEV-30162 Fix occasional "Permission denied" on Windows caused by buggy 3rd party Add retry logic for CreateFile, DeleteFile, or MoveFile when GetLastError() is ERROR_SHARING_VIOLATION. --- mysql-test/main/windows_debug.result | 10 +- mysql-test/main/windows_debug.test | 12 ++- mysys/my_delete.c | 173 +++++++++++++++++++---------------- mysys/my_rename.c | 29 ++---- mysys/my_winfile.c | 38 +++++++- mysys/mysys_priv.h | 39 ++++++++ 6 files changed, 194 insertions(+), 107 deletions(-) diff --git a/mysql-test/main/windows_debug.result b/mysql-test/main/windows_debug.result index e6816cdd99b..797056b00a1 100644 --- a/mysql-test/main/windows_debug.result +++ b/mysql-test/main/windows_debug.result @@ -1,4 +1,10 @@ # mdev-23741 sharing violation when renaming .frm file in ALTER -CREATE TABLE t(i int); -SET STATEMENT debug_dbug='+d,rename_sharing_violation' FOR ALTER TABLE t ADD PRIMARY KEY (i); +SET @saved_dbug = @@SESSION.debug_dbug; +SET debug_dbug='+d,file_sharing_violation'; +CREATE TABLE t(i int) ENGINE=ARIA; +ALTER TABLE t ADD PRIMARY KEY (i); +FLUSH TABLES t; +SELECT * FROM t; +i DROP TABLE t; +SET debug_dbug=@saved_dbug; diff --git a/mysql-test/main/windows_debug.test b/mysql-test/main/windows_debug.test index bb0880ddc55..32ea57552a7 100644 --- a/mysql-test/main/windows_debug.test +++ b/mysql-test/main/windows_debug.test @@ -4,8 +4,16 @@ --source include/windows.inc --echo # mdev-23741 sharing violation when renaming .frm file in ALTER -CREATE TABLE t(i int); -SET STATEMENT debug_dbug='+d,rename_sharing_violation' FOR ALTER TABLE t ADD PRIMARY KEY (i); + +SET @saved_dbug = @@SESSION.debug_dbug; +SET debug_dbug='+d,file_sharing_violation'; + +CREATE TABLE t(i int) ENGINE=ARIA; +ALTER TABLE t ADD PRIMARY KEY (i); +FLUSH TABLES t; +SELECT * FROM t; DROP TABLE t; +SET debug_dbug=@saved_dbug; + #End of 10.3 tests diff --git a/mysys/my_delete.c b/mysys/my_delete.c index cce26643ef7..0e9da9f50ca 100644 --- a/mysys/my_delete.c +++ b/mysys/my_delete.c @@ -79,7 +79,8 @@ int my_delete(const char *name, myf MyFlags) a file to unique name. Symbolic link are deleted without renaming. Directories are not deleted. - */ +*/ + static int my_win_unlink(const char *name) { HANDLE handle= INVALID_HANDLE_VALUE; @@ -87,99 +88,113 @@ static int my_win_unlink(const char *name) uint last_error; char unique_filename[MAX_PATH + 35]; unsigned long long tsc; /* time stamp counter, for unique filename*/ - + int retries; DBUG_ENTER("my_win_unlink"); - attributes= GetFileAttributes(name); - if (attributes == INVALID_FILE_ATTRIBUTES) - { - last_error= GetLastError(); - DBUG_PRINT("error",("GetFileAttributes(%s) failed with %u\n", name, last_error)); - goto error; - } - if (attributes & FILE_ATTRIBUTE_DIRECTORY) - { - DBUG_PRINT("error",("can't remove %s - it is a directory\n", name)); - errno= EINVAL; - DBUG_RETURN(-1); - } - - if (attributes & FILE_ATTRIBUTE_REPARSE_POINT) + DBUG_INJECT_FILE_SHARING_VIOLATION(name); + + for (retries= FILE_SHARING_VIOLATION_RETRIES; ; retries--) { - /* Symbolic link. Delete link, the not target */ - if (!DeleteFile(name)) + attributes= GetFileAttributes(name); + if (attributes == INVALID_FILE_ATTRIBUTES) { - last_error= GetLastError(); - DBUG_PRINT("error",("DeleteFile(%s) failed with %u\n", name,last_error)); - goto error; + last_error= GetLastError(); + DBUG_PRINT("error", + ("GetFileAttributes(%s) failed with %u\n", name, last_error)); + goto error; } - DBUG_RETURN(0); - } - /* - Try Windows 10 method, delete with "posix semantics" (file is not visible, and creating - a file with the same name won't fail, even if it the fiile was open) - */ - struct - { - DWORD _Flags; - } disp={0x3}; - /* 0x3 = FILE_DISPOSITION_FLAG_DELETE | FILE_DISPOSITION_FLAG_POSIX_SEMANTICS */ + if (attributes & FILE_ATTRIBUTE_DIRECTORY) + { + DBUG_PRINT("error", ("can't remove %s - it is a directory\n", name)); + errno= EINVAL; + DBUG_RETURN(-1); + } - handle= CreateFile(name, DELETE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - NULL, OPEN_EXISTING, 0, NULL); - if (handle != INVALID_HANDLE_VALUE) - { - BOOL ok= SetFileInformationByHandle(handle, - (FILE_INFO_BY_HANDLE_CLASS) 21, &disp, sizeof(disp)); - CloseHandle(handle); - if (ok) + if (attributes & FILE_ATTRIBUTE_REPARSE_POINT) + { + /* Symbolic link. Delete link, the not target */ + if (!DeleteFile(name)) + { + last_error= GetLastError(); + DBUG_PRINT("error", + ("DeleteFile(%s) failed with %u\n", name, last_error)); + goto error; + } DBUG_RETURN(0); - } + } - handle= CreateFile(name, DELETE, 0, NULL, OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, NULL); - if (handle != INVALID_HANDLE_VALUE) - { /* - We opened file without sharing flags (exclusive), no one else has this file - opened, thus it is save to close handle to remove it. No renaming is - necessary. + Try Windows 10 method, delete with "posix semantics" (file is not + visible, and creating a file with the same name won't fail, even if it + the file was open) */ - CloseHandle(handle); - DBUG_RETURN(0); - } + handle= CreateFile(name, DELETE, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + NULL, OPEN_EXISTING, 0, NULL); + if (handle != INVALID_HANDLE_VALUE) + { + /* 0x3 = FILE_DISPOSITION_FLAG_DELETE | FILE_DISPOSITION_FLAG_POSIX_SEMANTICS */ + struct {DWORD _Flags;} disp= {0x3}; + BOOL ok= SetFileInformationByHandle( + handle, (FILE_INFO_BY_HANDLE_CLASS) 21, &disp, sizeof(disp)); + CloseHandle(handle); + if (ok) + DBUG_RETURN(0); + } - /* - Can't open file exclusively, hence the file must be already opened by - someone else. Open it for delete (with all FILE_SHARE flags set), - rename to unique name, close. - */ - handle= CreateFile(name, DELETE, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, - NULL, OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, NULL); - if (handle == INVALID_HANDLE_VALUE) - { - last_error= GetLastError(); - DBUG_PRINT("error", - ("CreateFile(%s) with FILE_FLAG_DELETE_ON_CLOSE failed with %u\n", - name,last_error)); - goto error; - } + handle= CreateFile(name, DELETE, 0, NULL, OPEN_EXISTING, + FILE_FLAG_DELETE_ON_CLOSE, NULL); + if (handle != INVALID_HANDLE_VALUE) + { + /* + We opened file without sharing flags (exclusive), no one else has this + file opened, thus it is safe to close handle to remove it. No renaming + is necessary. + */ + CloseHandle(handle); + DBUG_RETURN(0); + } - tsc= __rdtsc(); - my_snprintf(unique_filename,sizeof(unique_filename),"%s.%llx.deleted", - name, tsc); - if (!MoveFile(name, unique_filename)) - { - DBUG_PRINT("warning", ("moving %s to unique filename failed, error %lu\n", - name,GetLastError())); - } + /* + Can't open file exclusively, hence the file must be already opened by + someone else. Open it for delete (with all FILE_SHARE flags set), + rename to unique name, close. + */ + handle= CreateFile(name, DELETE, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + NULL, OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, NULL); + if (handle == INVALID_HANDLE_VALUE) + { + last_error= GetLastError(); + DBUG_PRINT( + "error", + ("CreateFile(%s) with FILE_FLAG_DELETE_ON_CLOSE failed with %u\n", + name, last_error)); + goto error; + } + + tsc= __rdtsc(); + my_snprintf(unique_filename, sizeof(unique_filename), "%s.%llx.deleted", + name, tsc); + if (!MoveFile(name, unique_filename)) + { + DBUG_PRINT("warning", + ("moving %s to unique filename failed, error %lu\n", name, + GetLastError())); + } + CloseHandle(handle); + DBUG_RETURN(0); - CloseHandle(handle); - DBUG_RETURN(0); - error: - my_osmaperr(last_error); - DBUG_RETURN(-1); + if (last_error != ERROR_SHARING_VIOLATION || retries == 0) + { + my_osmaperr(last_error); + DBUG_RETURN(-1); + } + DBUG_CLEAR_FILE_SHARING_VIOLATION(); + Sleep(FILE_SHARING_VIOLATION_DELAY_MS); + } } #endif diff --git a/mysys/my_rename.c b/mysys/my_rename.c index 23dbec2d7ff..56a1f2a7cec 100644 --- a/mysys/my_rename.c +++ b/mysys/my_rename.c @@ -34,41 +34,24 @@ */ static BOOL win_rename_with_retries(const char *from, const char *to) { -#ifndef DBUG_OFF - FILE *fp = NULL; - DBUG_EXECUTE_IF("rename_sharing_violation", - { - fp= fopen(from, "r"); - DBUG_ASSERT(fp); - } - ); -#endif + DBUG_INJECT_FILE_SHARING_VIOLATION(from); - for (int retry= RENAME_MAX_RETRIES; retry--;) + for (int retry= FILE_SHARING_VIOLATION_RETRIES; retry--;) { BOOL ret= MoveFileEx(from, to, MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING); + DBUG_CLEAR_FILE_SHARING_VIOLATION(); + if (ret) return ret; DWORD last_error= GetLastError(); + if (last_error == ERROR_SHARING_VIOLATION || last_error == ERROR_ACCESS_DENIED) { -#ifndef DBUG_OFF - /* - If error was injected in via DBUG_EXECUTE_IF, close the file - that is causing ERROR_SHARING_VIOLATION, so that retry succeeds. - */ - if (fp) - { - fclose(fp); - fp= NULL; - } -#endif - - Sleep(10); + Sleep(FILE_SHARING_VIOLATION_DELAY_MS); } else return ret; diff --git a/mysys/my_winfile.c b/mysys/my_winfile.c index 0baca6d62d7..a2b621c7aa3 100644 --- a/mysys/my_winfile.c +++ b/mysys/my_winfile.c @@ -102,6 +102,42 @@ static int my_get_open_flags(File fd) DBUG_RETURN(my_file_info[fd].oflag); } +/* + CreateFile with retry logic. + + Uses retries, to avoid or reduce CreateFile errors + with ERROR_SHARING_VIOLATION, in case the file is opened + by another process, which used incompatible sharing + flags when opening. + + See Windows' CreateFile() documentation for details. +*/ +static HANDLE my_create_file_with_retries( + LPCSTR lpFileName, DWORD dwDesiredAccess, + DWORD dwShareMode, + LPSECURITY_ATTRIBUTES lpSecurityAttributes, + DWORD dwCreationDisposition, + DWORD dwFlagsAndAttributes, + HANDLE hTemplateFile) +{ + int retries; + DBUG_INJECT_FILE_SHARING_VIOLATION(lpFileName); + + for (retries = FILE_SHARING_VIOLATION_RETRIES;;) + { + HANDLE h= CreateFile(lpFileName, dwDesiredAccess, dwShareMode, + lpSecurityAttributes, dwCreationDisposition, + dwFlagsAndAttributes, hTemplateFile); + DBUG_CLEAR_FILE_SHARING_VIOLATION(); + + if (h != INVALID_HANDLE_VALUE || + GetLastError() != ERROR_SHARING_VIOLATION || --retries == 0) + return h; + + Sleep(FILE_SHARING_VIOLATION_DELAY_MS); + } + return INVALID_HANDLE_VALUE; +} /* Open a file with sharing. Similar to _sopen() from libc, but allows managing @@ -247,7 +283,7 @@ File my_win_sopen(const char *path, int oflag, int shflag, int pmode) fileattrib|= FILE_FLAG_RANDOM_ACCESS; /* try to open/create the file */ - if ((osfh= CreateFile(path, fileaccess, fileshare, &SecurityAttributes, + if ((osfh= my_create_file_with_retries(path, fileaccess, fileshare, &SecurityAttributes, filecreate, fileattrib, NULL)) == INVALID_HANDLE_VALUE) { DWORD last_error= GetLastError(); diff --git a/mysys/mysys_priv.h b/mysys/mysys_priv.h index 0fa6a4c553f..57e734321fa 100644 --- a/mysys/mysys_priv.h +++ b/mysys/mysys_priv.h @@ -176,6 +176,45 @@ extern int my_win_fsync(File fd); extern File my_win_dup(File fd); extern File my_win_sopen(const char *path, int oflag, int shflag, int perm); extern File my_open_osfhandle(HANDLE handle, int oflag); + + +/* + The following constants are related to retries when file operation fails with + ERROR_FILE_SHARING_VIOLATION +*/ +#define FILE_SHARING_VIOLATION_RETRIES 50 +#define FILE_SHARING_VIOLATION_DELAY_MS 10 + + +/* DBUG injecting of ERROR_FILE_SHARING_VIOLATION */ +#ifndef DBUG_OFF +/* Open file, without sharing. if specific DBUG keyword is set */ +#define DBUG_INJECT_FILE_SHARING_VIOLATION(filename) \ + FILE *fp= NULL; \ + do \ + { \ + DBUG_EXECUTE_IF("file_sharing_violation", \ + fp= _fsopen(filename, "r", _SH_DENYRW);); \ + } while (0) + +/* Close the file that causes ERROR_FILE_SHARING_VIOLATION.*/ +#define DBUG_CLEAR_FILE_SHARING_VIOLATION() \ + do \ + { \ + if (fp) \ + { \ + DWORD tmp_err= GetLastError(); \ + fclose(fp); \ + SetLastError(tmp_err); \ + fp= NULL; \ + } \ + } while (0) + +#else +#define DBUG_INJECT_FILE_SHARING_VIOLATION(filename) do {} while (0) +#define DBUG_CLEAR_FILE_SHARING_VIOLATION() do {} while (0) +#endif + #endif C_MODE_END -- cgit v1.2.1 From 8f3631d0096ceecc21f2879a9558fd9242f09f8c Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Sat, 3 Dec 2022 15:09:48 +1100 Subject: MDEV-30150 ST_GeomFromGeoJSON, 'geometry' before 'type: feature' error The geometry type requires Type:"Feature" but the feature need not be first in the JSON structure. Adjust code to return an error if geometry isn't a JSON object, but continue parsing searching for Type: "Feature" to trigger the geometry parsing. Thanks Derick Magnusen for the bug report. --- mysql-test/main/gis-json.result | 3 +++ mysql-test/main/gis-json.test | 1 + sql/spatial.cc | 3 ++- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/mysql-test/main/gis-json.result b/mysql-test/main/gis-json.result index ace9e9e9ae2..644684f5a73 100644 --- a/mysql-test/main/gis-json.result +++ b/mysql-test/main/gis-json.result @@ -58,6 +58,9 @@ Warning 4038 Syntax error in JSON text in argument 1 to function 'st_geomfromgeo SELECT st_astext(st_geomfromgeojson('{ "type": "Feature", "geometry": { "type": "Point", "coordinates": [102.0, 0.5] } }')); st_astext(st_geomfromgeojson('{ "type": "Feature", "geometry": { "type": "Point", "coordinates": [102.0, 0.5] } }')) POINT(102 0.5) +SELECT st_astext(st_geomfromgeojson('{ "geometry": { "type": "Point", "coordinates": [102.0, 0.5] }, "type": "Feature" }')); +st_astext(st_geomfromgeojson('{ "geometry": { "type": "Point", "coordinates": [102.0, 0.5] }, "type": "Feature" }')) +POINT(102 0.5) SELECT st_astext(st_geomfromgeojson('{ "type": "FeatureCollection", "features": [{ "type": "Feature", "geometry": { "type": "Point", "coordinates": [102.0, 0.5] }, "properties": { "prop0": "value0" } }]}')); st_astext(st_geomfromgeojson('{ "type": "FeatureCollection", "features": [{ "type": "Feature", "geometry": { "type": "Point", "coordinates": [102.0, 0.5] }, "properties": { "prop0": "value0" } }]}')) GEOMETRYCOLLECTION(POINT(102 0.5)) diff --git a/mysql-test/main/gis-json.test b/mysql-test/main/gis-json.test index 0e1b24a91b6..cda395acab5 100644 --- a/mysql-test/main/gis-json.test +++ b/mysql-test/main/gis-json.test @@ -26,6 +26,7 @@ SELECT st_astext(st_geomfromgeojson('{"type""point"}')); #enable after fix MDEV-27871 --disable_view_protocol SELECT st_astext(st_geomfromgeojson('{ "type": "Feature", "geometry": { "type": "Point", "coordinates": [102.0, 0.5] } }')); +SELECT st_astext(st_geomfromgeojson('{ "geometry": { "type": "Point", "coordinates": [102.0, 0.5] }, "type": "Feature" }')); SELECT st_astext(st_geomfromgeojson('{ "type": "FeatureCollection", "features": [{ "type": "Feature", "geometry": { "type": "Point", "coordinates": [102.0, 0.5] }, "properties": { "prop0": "value0" } }]}')); diff --git a/sql/spatial.cc b/sql/spatial.cc index 9a30d346a1c..e772a92c744 100644 --- a/sql/spatial.cc +++ b/sql/spatial.cc @@ -611,7 +611,8 @@ Geometry *Geometry::create_from_json(Geometry_buffer *buffer, if (feature_type_found) goto handle_geometry_key; } - goto err_return; + else + goto err_return; } else { -- cgit v1.2.1 From 782b2a750067a12be07b9c305ede4d2c28f173e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Fri, 9 Dec 2022 10:42:19 +0200 Subject: MDEV-29144 ER_TABLE_SCHEMA_MISMATCH or crash on DISCARD/IMPORT mysql_discard_or_import_tablespace(): On successful ALTER TABLE...DISCARD TABLESPACE, evict the table handle from the table definition cache, so that ha_innobase::close() will be invoked, like InnoDB expects to be the case. This will avoid an assertion failure ut_a(table->get_ref_count() == 0) during IMPORT TABLESPACE. ha_innobase::open(): Do not issue any ER_TABLESPACE_DISCARDED warning. Member functions for DML will do that. ha_innobase::truncate(), ha_innobase::check_if_supported_inplace_alter(): Issue ER_TABLESPACE_DISCARDED warnings, to compensate for the removal of the warning in ha_innobase::open(). row_quiesce_write_indexes(): Only write information about committed indexes. The ALTER TABLE t NOWAIT ADD INDEX(c) in the nondeterministic test case will most of the time fail due to a metadata lock (MDL) timeout and leave behind an uncommitted index. Reviewed by: Sergei Golubchik --- .../encryption/r/innodb-bad-key-change2.result | 1 - .../suite/innodb/r/import_tablespace_race.result | 26 +++++++++++ .../suite/innodb/t/import_tablespace_race.test | 54 ++++++++++++++++++++++ sql/sql_table.cc | 4 ++ storage/innobase/handler/ha_innodb.cc | 11 +++-- storage/innobase/handler/handler0alter.cc | 6 +++ storage/innobase/row/row0quiesce.cc | 15 +++++- 7 files changed, 110 insertions(+), 7 deletions(-) create mode 100644 mysql-test/suite/innodb/r/import_tablespace_race.result create mode 100644 mysql-test/suite/innodb/t/import_tablespace_race.test diff --git a/mysql-test/suite/encryption/r/innodb-bad-key-change2.result b/mysql-test/suite/encryption/r/innodb-bad-key-change2.result index 5c28203ecf8..50da3dc7b2b 100644 --- a/mysql-test/suite/encryption/r/innodb-bad-key-change2.result +++ b/mysql-test/suite/encryption/r/innodb-bad-key-change2.result @@ -44,7 +44,6 @@ ALTER TABLE t1 DISCARD TABLESPACE; restore: t1 .ibd and .cfg files ALTER TABLE t1 DISCARD TABLESPACE; Warnings: -Warning 1814 Tablespace has been discarded for table `t1` Warning 1812 Tablespace is missing for table 'test/t1' restore: t1 .ibd and .cfg files ALTER TABLE t1 IMPORT TABLESPACE; diff --git a/mysql-test/suite/innodb/r/import_tablespace_race.result b/mysql-test/suite/innodb/r/import_tablespace_race.result new file mode 100644 index 00000000000..786b8cbd261 --- /dev/null +++ b/mysql-test/suite/innodb/r/import_tablespace_race.result @@ -0,0 +1,26 @@ +# +# MDEV-29144 ER_TABLE_SCHEMA_MISMATCH or crash on DISCARD/IMPORT +# +CREATE TABLE t (pk int PRIMARY KEY, c varchar(1024)) +ENGINE=InnoDB CHARSET latin1; +INSERT INTO t SELECT seq, 'x' FROM seq_1_to_100; +connect con1,localhost,root,,test; +BEGIN NOT ATOMIC +DECLARE a INT DEFAULT 0; +REPEAT +SET a= a+1; +UPDATE t SET c = 'xx' WHERE pk = a; +UNTIL a = 100 +END REPEAT; +END +$ +connection default; +ALTER TABLE t NOWAIT ADD INDEX (c); +connection con1; +connection default; +FLUSH TABLE t FOR EXPORT; +UNLOCK TABLES; +DROP TABLE t; +ALTER TABLE t DISCARD TABLESPACE; +ALTER TABLE t IMPORT TABLESPACE; +DROP TABLE t; diff --git a/mysql-test/suite/innodb/t/import_tablespace_race.test b/mysql-test/suite/innodb/t/import_tablespace_race.test new file mode 100644 index 00000000000..532c2684dde --- /dev/null +++ b/mysql-test/suite/innodb/t/import_tablespace_race.test @@ -0,0 +1,54 @@ +--source include/have_innodb.inc +--source include/have_sequence.inc + +--echo # +--echo # MDEV-29144 ER_TABLE_SCHEMA_MISMATCH or crash on DISCARD/IMPORT +--echo # + +CREATE TABLE t (pk int PRIMARY KEY, c varchar(1024)) +ENGINE=InnoDB CHARSET latin1; +INSERT INTO t SELECT seq, 'x' FROM seq_1_to_100; + +--connect (con1,localhost,root,,test) +--delimiter $ +--send + BEGIN NOT ATOMIC + DECLARE a INT DEFAULT 0; + REPEAT + SET a= a+1; + UPDATE t SET c = 'xx' WHERE pk = a; + UNTIL a = 100 + END REPEAT; + END +$ +--delimiter ; + +--connection default +--error 0,ER_LOCK_WAIT_TIMEOUT +ALTER TABLE t NOWAIT ADD INDEX (c); + +--connection con1 +--reap + +--connection default + +--let $datadir= `select @@datadir` + +FLUSH TABLE t FOR EXPORT; +--let $create= query_get_value(SHOW CREATE TABLE t, Create Table, 1) +--copy_file $datadir/test/t.cfg $MYSQL_TMP_DIR/t.cfg +--copy_file $datadir/test/t.ibd $MYSQL_TMP_DIR/t.ibd +UNLOCK TABLES; + +DROP TABLE t; +--disable_query_log +eval $create; +--enable_query_log + +ALTER TABLE t DISCARD TABLESPACE; +--move_file $MYSQL_TMP_DIR/t.cfg $datadir/test/t.cfg +--move_file $MYSQL_TMP_DIR/t.ibd $datadir/test/t.ibd +ALTER TABLE t IMPORT TABLESPACE; + +# Cleanup +DROP TABLE t; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 042ed9e1d6f..62a46dbf430 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -6075,6 +6075,10 @@ int mysql_discard_or_import_tablespace(THD *thd, if (unlikely(error)) goto err; + if (discard) + tdc_remove_table(thd, TDC_RT_REMOVE_NOT_OWN, table_list->table->s->db.str, + table_list->table->s->table_name.str, true); + /* The 0 in the call below means 'not in a transaction', which means immediate invalidation; that is probably what we wish here diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index aa1bc5844e3..a1f58091a90 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -6268,11 +6268,6 @@ no_such_table: MONITOR_INC(MONITOR_TABLE_OPEN); if ((ib_table->flags2 & DICT_TF2_DISCARDED)) { - - ib_senderrf(thd, - IB_LOG_LEVEL_WARN, ER_TABLESPACE_DISCARDED, - table->s->table_name.str); - /* Allow an open because a proper DISCARD should have set all the flags and index root page numbers to FIL_NULL that should prevent any DML from running but it should allow DDL @@ -13631,6 +13626,12 @@ int ha_innobase::truncate() if (ib_table->is_temporary()) { info.options|= HA_LEX_CREATE_TMP_TABLE; } else { + if (!ib_table->space) { + ib_senderrf(m_user_thd, + IB_LOG_LEVEL_WARN, ER_TABLESPACE_DISCARDED, + table->s->table_name.str); + } + dict_get_and_save_data_dir_path(ib_table, false); } diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index cd40fe3145e..19c90fed74c 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -1013,6 +1013,12 @@ ha_innobase::check_if_supported_inplace_alter( update_thd(); + if (!m_prebuilt->table->space) { + ib_senderrf(m_user_thd, IB_LOG_LEVEL_WARN, + ER_TABLESPACE_DISCARDED, + table->s->table_name.str); + } + if (ha_alter_info->handler_flags & ~(INNOBASE_INPLACE_IGNORE | INNOBASE_ALTER_INSTANT diff --git a/storage/innobase/row/row0quiesce.cc b/storage/innobase/row/row0quiesce.cc index 94a372bd046..5af026ecbe8 100644 --- a/storage/innobase/row/row0quiesce.cc +++ b/storage/innobase/row/row0quiesce.cc @@ -106,11 +106,17 @@ row_quiesce_write_indexes( FILE* file, /*!< in: file to write to */ THD* thd) /*!< in/out: session */ { + ulint n_indexes = 0; + for (const dict_index_t* index = UT_LIST_GET_FIRST(table->indexes); + index; index = UT_LIST_GET_NEXT(indexes, index)) { + n_indexes += index->is_committed(); + } + { byte row[sizeof(ib_uint32_t)]; /* Write the number of indexes in the table. */ - mach_write_to_4(row, UT_LIST_GET_LEN(table->indexes)); + mach_write_to_4(row, n_indexes); DBUG_EXECUTE_IF("ib_export_io_write_failure_11", close(fileno(file));); @@ -132,6 +138,12 @@ row_quiesce_write_indexes( index != 0 && err == DB_SUCCESS; index = UT_LIST_GET_NEXT(indexes, index)) { + if (!index->is_committed()) { + continue; + } + + ut_ad(n_indexes); ut_d(n_indexes--); + byte* ptr; byte row[sizeof(index_id_t) + sizeof(ib_uint32_t) * 8]; @@ -202,6 +214,7 @@ row_quiesce_write_indexes( err = row_quiesce_write_index_fields(index, file, thd); } + ut_ad(!n_indexes); return(err); } -- cgit v1.2.1 From 8f30973234de520d95dfccca8409e5802b845331 Mon Sep 17 00:00:00 2001 From: Julius Goryavsky Date: Fri, 28 Oct 2022 11:16:25 +0200 Subject: MDEV-29814: galera_var_notify_ssl_ipv6 causes testing system to hang This commit fixes the test system hanging due to the galera_var_notify_ssl_ipv6 test and also brings the wsrep_notify[_ssl].sh files in line with each other between the user template and the mtr suite. Quotes are also added here to avoid problems if the user specifies the value of one of the variables at the beginning of the file containing shell-specific characters, for example, if the password or username specified in the PSWD and USER variables will contain the "$" character. Also fixed an issue with automatic --ssl-verify-server-cert option substitution when the corresponding value is set by the user to "1" or "on". Also fixed some tests here to avoid joining one of the nodes to another cluster when the nodes are restarted from the mtr side, which can lead to random failures when testing with buildbot. --- mysql-test/std_data/wsrep_notify.sh | 57 ++++++++++--------- mysql-test/std_data/wsrep_notify_ssl.sh | 51 +++++++++-------- .../suite/galera/r/galera_wsrep_new_cluster.result | 12 ++++ .../suite/galera/t/galera_var_notify_ssl_ipv6.cnf | 8 +-- .../galera/t/galera_wsrep_new_cluster-master.opt | 1 - .../suite/galera/t/galera_wsrep_new_cluster.test | 54 ++++++++++++++++++ support-files/wsrep_notify.sh | 66 +++++++++++----------- 7 files changed, 161 insertions(+), 88 deletions(-) delete mode 100644 mysql-test/suite/galera/t/galera_wsrep_new_cluster-master.opt diff --git a/mysql-test/std_data/wsrep_notify.sh b/mysql-test/std_data/wsrep_notify.sh index 5dfd63462b9..6fd8acdaf9c 100755 --- a/mysql-test/std_data/wsrep_notify.sh +++ b/mysql-test/std_data/wsrep_notify.sh @@ -6,30 +6,32 @@ # # Edit parameters below to specify the address and login to server: # -USER=root -PSWD= +USER='root' +PSWD='' # # If these parameters are not set, then the values # passed by the server are taken: # -HOST=127.0.0.1 +HOST="127.0.0.1" PORT=$NODE_MYPORT_1 # # Edit parameters below to specify SSL parameters: # -ssl_key= -ssl_cert= -ssl_ca= -ssl_capath= -ssl_cipher= -ssl_crl= -ssl_crlpath= +ssl_cert="" +ssl_key="" +ssl_ca="" +ssl_capath="" +ssl_cipher="" +ssl_crl="" +ssl_crlpath="" ssl_verify_server_cert=0 # # Client executable path: # CLIENT="$EXE_MYSQL" - +# +# Name of schema and tables: +# SCHEMA="mtr_wsrep_notify" MEMB_TABLE="$SCHEMA.membership" STATUS_TABLE="$SCHEMA.status" @@ -65,9 +67,9 @@ configuration_change() do echo "INSERT INTO $MEMB_TABLE VALUES ( $idx, " # Don't forget to properly quote string values - echo "'$NODE'" | sed s/\\//\',\'/g + echo "'$NODE'" | sed s/\\//\',\'/g echo ");" - idx=$(( $idx + 1 )) + idx=$(( $idx+1 )) done echo "INSERT INTO $STATUS_TABLE VALUES($idx, $INDEX, '$STATUS', '$CLUSTER_UUID', $PRIMARY);" @@ -102,34 +104,35 @@ trim_string() fi } -COM=status_update # not a configuration change by default +COM='status_update' # not a configuration change by default STATUS="" CLUSTER_UUID="" -PRIMARY="0" +PRIMARY=0 INDEX="" MEMBERS="" while [ $# -gt 0 ]; do case $1 in - --status) + '--status') STATUS=$(trim_string "$2") shift ;; - --uuid) + '--uuid') CLUSTER_UUID=$(trim_string "$2") shift ;; - --primary) - [ "$2" = "yes" ] && PRIMARY="1" || PRIMARY="0" - COM=configuration_change + '--primary') + arg=$(trim_string "$2") + [ "$arg" = 'yes' ] && PRIMARY=1 || PRIMARY=0 + COM='configuration_change' shift ;; - --index) + '--index') INDEX=$(trim_string "$2") shift ;; - --members) + '--members') MEMBERS=$(trim_string "$2") shift ;; @@ -168,9 +171,7 @@ ssl_verify_server_cert=$(trim_string "$ssl_verify_server_cert"); SSL_PARAM="" -if [ -n "$ssl_key" -o -n "$ssl_cert" -o \ - -n "$ssl_ca" -o -n "$ssl_capath" -o \ - -n "$ssl_cipher" ] +if [ -n "$ssl_key$ssl_cert$ssl_ca$ssl_capath$ssl_cipher$ssl_crl$ssl_crlpath" ] then SSL_PARAM=' --ssl' [ -n "$ssl_key" ] && SSL_PARAM="$SSL_PARAM --ssl-key='$ssl_key'" @@ -181,8 +182,10 @@ then [ -n "$ssl_crl" ] && SSL_PARAM="$SSL_PARAM --ssl-crl='$ssl_crl'" [ -n "$ssl_crlpath" ] && SSL_PARAM="$SSL_PARAM --ssl-crlpath='$ssl_crlpath'" if [ -n "$ssl_verify_server_cert" ]; then - if [ $ssl_verify_server_cert -ne 0 ]; then - SSL_PARAM+=' --ssl-verify-server-cert' + if [ "$ssl_verify_server_cert" != "0" -o \ + "$ssl_verify_server_cert" = "on" ] + then + SSL_PARAM="$SSL_PARAM --ssl-verify-server-cert" fi fi fi diff --git a/mysql-test/std_data/wsrep_notify_ssl.sh b/mysql-test/std_data/wsrep_notify_ssl.sh index 2c6b6f4dacb..aeedfe49e6a 100755 --- a/mysql-test/std_data/wsrep_notify_ssl.sh +++ b/mysql-test/std_data/wsrep_notify_ssl.sh @@ -6,13 +6,13 @@ # # Edit parameters below to specify the address and login to server: # -USER=root -PSWD= +USER='root' +PSWD='' # # If these parameters are not set, then the values # passed by the server are taken: # -HOST=127.0.0.1 +HOST="127.0.0.1" PORT=$NODE_MYPORT_1 # # Edit parameters below to specify SSL parameters: @@ -20,16 +20,18 @@ PORT=$NODE_MYPORT_1 ssl_cert="$MYSQL_TEST_DIR/std_data/client-cert.pem" ssl_key="$MYSQL_TEST_DIR/std_data/client-key.pem" ssl_ca="$MYSQL_TEST_DIR/std_data/cacert.pem" -ssl_capath= -ssl_cipher= -ssl_crl= -ssl_crlpath= +ssl_capath="" +ssl_cipher="" +ssl_crl="" +ssl_crlpath="" ssl_verify_server_cert=0 # # Client executable path: # CLIENT="$EXE_MYSQL" - +# +# Name of schema and tables: +# SCHEMA="mtr_wsrep_notify" MEMB_TABLE="$SCHEMA.membership" STATUS_TABLE="$SCHEMA.status" @@ -65,9 +67,9 @@ configuration_change() do echo "INSERT INTO $MEMB_TABLE VALUES ( $idx, " # Don't forget to properly quote string values - echo "'$NODE'" | sed s/\\//\',\'/g + echo "'$NODE'" | sed s/\\//\',\'/g echo ");" - idx=$(( $idx + 1 )) + idx=$(( $idx+1 )) done echo "INSERT INTO $STATUS_TABLE VALUES($idx, $INDEX, '$STATUS', '$CLUSTER_UUID', $PRIMARY);" @@ -102,34 +104,35 @@ trim_string() fi } -COM=status_update # not a configuration change by default +COM='status_update' # not a configuration change by default STATUS="" CLUSTER_UUID="" -PRIMARY="0" +PRIMARY=0 INDEX="" MEMBERS="" while [ $# -gt 0 ]; do case $1 in - --status) + '--status') STATUS=$(trim_string "$2") shift ;; - --uuid) + '--uuid') CLUSTER_UUID=$(trim_string "$2") shift ;; - --primary) - [ "$2" = "yes" ] && PRIMARY="1" || PRIMARY="0" - COM=configuration_change + '--primary') + arg=$(trim_string "$2") + [ "$arg" = 'yes' ] && PRIMARY=1 || PRIMARY=0 + COM='configuration_change' shift ;; - --index) + '--index') INDEX=$(trim_string "$2") shift ;; - --members) + '--members') MEMBERS=$(trim_string "$2") shift ;; @@ -168,9 +171,7 @@ ssl_verify_server_cert=$(trim_string "$ssl_verify_server_cert"); SSL_PARAM="" -if [ -n "$ssl_key" -o -n "$ssl_cert" -o \ - -n "$ssl_ca" -o -n "$ssl_capath" -o \ - -n "$ssl_cipher" ] +if [ -n "$ssl_key$ssl_cert$ssl_ca$ssl_capath$ssl_cipher$ssl_crl$ssl_crlpath" ] then SSL_PARAM=' --ssl' [ -n "$ssl_key" ] && SSL_PARAM="$SSL_PARAM --ssl-key='$ssl_key'" @@ -181,8 +182,10 @@ then [ -n "$ssl_crl" ] && SSL_PARAM="$SSL_PARAM --ssl-crl='$ssl_crl'" [ -n "$ssl_crlpath" ] && SSL_PARAM="$SSL_PARAM --ssl-crlpath='$ssl_crlpath'" if [ -n "$ssl_verify_server_cert" ]; then - if [ $ssl_verify_server_cert -ne 0 ]; then - SSL_PARAM+=' --ssl-verify-server-cert' + if [ "$ssl_verify_server_cert" != "0" -o \ + "$ssl_verify_server_cert" = "on" ] + then + SSL_PARAM="$SSL_PARAM --ssl-verify-server-cert" fi fi fi diff --git a/mysql-test/suite/galera/r/galera_wsrep_new_cluster.result b/mysql-test/suite/galera/r/galera_wsrep_new_cluster.result index 3ba34e8ea79..ee48f7a4e1a 100644 --- a/mysql-test/suite/galera/r/galera_wsrep_new_cluster.result +++ b/mysql-test/suite/galera/r/galera_wsrep_new_cluster.result @@ -1,4 +1,12 @@ connection node_1; +connection node_2; +connection node_2; +Shutting down server ... +connection node_1; +connection node_2; +Cleaning grastate.dat file ... +Starting server ... +connection node_1; SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; VARIABLE_VALUE Primary @@ -36,3 +44,7 @@ VARIABLE_VALUE SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state_comment'; VARIABLE_VALUE Synced +Shutting down server ... +Cleaning var directory ... +Starting server ... +connection node_1; diff --git a/mysql-test/suite/galera/t/galera_var_notify_ssl_ipv6.cnf b/mysql-test/suite/galera/t/galera_var_notify_ssl_ipv6.cnf index ce121d20e03..db6f36605b7 100644 --- a/mysql-test/suite/galera/t/galera_var_notify_ssl_ipv6.cnf +++ b/mysql-test/suite/galera/t/galera_var_notify_ssl_ipv6.cnf @@ -7,14 +7,14 @@ ssl-ca=@ENV.MYSQL_TEST_DIR/std_data/cacert.pem bind-address=:: [mysqld.1] -wsrep_provider_options='base_port=@mysqld.1.#galera_port;gmcast.listen_addr=tcp://[::]:@mysqld.1.#galera_port;ist.recv_addr=[::1]:@mysqld.1.#ist_port;gcache.size=1;pc.ignore_sb=true' +wsrep_provider_options='base_host=[::1];base_port=@mysqld.1.#galera_port;gmcast.listen_addr=tcp://[::]:@mysqld.1.#galera_port;ist.recv_addr=[::1]:@mysqld.1.#ist_port;repl.causal_read_timeout=PT90S;evs.suspect_timeout=PT10S;evs.inactive_timeout=PT30S;evs.install_timeout=PT15S;gcache.size=10M' wsrep_node_incoming_address='[::1]:@mysqld.1.port' -wsrep_node_address=::1 +wsrep_node_address=[::1]:@mysqld.1.#galera_port wsrep_sst_receive_address='[::1]:@mysqld.1.#sst_port' [mysqld.2] wsrep_cluster_address='gcomm://[::1]:@mysqld.1.#galera_port' -wsrep_provider_options='base_port=@mysqld.2.#galera_port;gmcast.listen_addr=tcp://[::]:@mysqld.2.#galera_port;ist.recv_addr=[::1]:@mysqld.2.#ist_port;gcache.size=1;pc.ignore_sb=true' -wsrep_node_address=::1 +wsrep_provider_options='base_host=[::1];base_port=@mysqld.2.#galera_port;gmcast.listen_addr=tcp://[::]:@mysqld.2.#galera_port;ist.recv_addr=[::1]:@mysqld.2.#ist_port;repl.causal_read_timeout=PT90S;evs.suspect_timeout=PT10S;evs.inactive_timeout=PT30S;evs.install_timeout=PT15S;gcache.size=10M' wsrep_node_incoming_address='[::1]:@mysqld.2.port' +wsrep_node_address=[::1]:@mysqld.2.#galera_port wsrep_sst_receive_address='[::1]:@mysqld.2.#sst_port' diff --git a/mysql-test/suite/galera/t/galera_wsrep_new_cluster-master.opt b/mysql-test/suite/galera/t/galera_wsrep_new_cluster-master.opt deleted file mode 100644 index c31150c46af..00000000000 --- a/mysql-test/suite/galera/t/galera_wsrep_new_cluster-master.opt +++ /dev/null @@ -1 +0,0 @@ ---wsrep-new-cluster diff --git a/mysql-test/suite/galera/t/galera_wsrep_new_cluster.test b/mysql-test/suite/galera/t/galera_wsrep_new_cluster.test index 422759ece59..c85f6ee2503 100644 --- a/mysql-test/suite/galera/t/galera_wsrep_new_cluster.test +++ b/mysql-test/suite/galera/t/galera_wsrep_new_cluster.test @@ -7,6 +7,34 @@ --source include/galera_cluster.inc --source include/have_innodb.inc +# Save original auto_increment_offset values. +--let $node_1=node_1 +--let $node_2=node_2 +--source include/auto_increment_offset_save.inc + +--connection node_2 +--echo Shutting down server ... +--source include/shutdown_mysqld.inc + +--connection node_1 + +--let $wait_condition = SELECT VARIABLE_VALUE = 1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size' +--source include/wait_condition.inc + +--connection node_2 + +# +# Delete grastate.dat with safe_to_bootstrap: 0 +# +--echo Cleaning grastate.dat file ... +--remove_file $MYSQLTEST_VARDIR/mysqld.2/data/grastate.dat + +--echo Starting server ... +--let $restart_noprint=2 +--let $start_mysqld_params="--wsrep-new-cluster" +--source include/start_mysqld.inc +--source include/wait_until_ready.inc + --connection node_1 --let $wait_condition = SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; @@ -38,3 +66,29 @@ SELECT (VARIABLE_VALUE = 0 OR VARIABLE_VALUE = 1 ) FROM INFORMATION_SCHEMA.GLOBA SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_ready'; SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state'; SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state_comment'; + +--echo Shutting down server ... +--source include/shutdown_mysqld.inc + +# +# Force SST +# +--echo Cleaning var directory ... +--remove_file $MYSQLTEST_VARDIR/mysqld.2/data/grastate.dat +--remove_files_wildcard $MYSQLTEST_VARDIR/mysqld.2/data/mtr +--remove_files_wildcard $MYSQLTEST_VARDIR/mysqld.2/data/performance_schema +--remove_files_wildcard $MYSQLTEST_VARDIR/mysqld.2/data/test +--remove_files_wildcard $MYSQLTEST_VARDIR/mysqld.2/data/mysql +--remove_files_wildcard $MYSQLTEST_VARDIR/mysqld.2/data + +--echo Starting server ... +--let $start_mysqld_params= +--source include/start_mysqld.inc +--source include/wait_until_ready.inc + +--connection node_1 + +--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size' +--source include/wait_condition.inc + +--source include/auto_increment_offset_restore.inc diff --git a/support-files/wsrep_notify.sh b/support-files/wsrep_notify.sh index dde1ded0963..67617ebe90c 100755 --- a/support-files/wsrep_notify.sh +++ b/support-files/wsrep_notify.sh @@ -6,30 +6,32 @@ # # Edit parameters below to specify the address and login to server: # -USER=root -PSWD=rootpass +USER='root' +PSWD='rootpass' # # If these parameters are not set, then the values # passed by the server are taken: # -HOST=127.0.0.1 +HOST="127.0.0.1" PORT=3306 # # Edit parameters below to specify SSL parameters: # -ssl_key= -ssl_cert= -ssl_ca= -ssl_capath= -ssl_cipher= -ssl_crl= -ssl_crlpath= +ssl_cert="" +ssl_key="" +ssl_ca="" +ssl_capath="" +ssl_cipher="" +ssl_crl="" +ssl_crlpath="" ssl_verify_server_cert=0 # # Client executable path: # CLIENT="mysql" - +# +# Name of schema and tables: +# SCHEMA="wsrep" MEMB_TABLE="$SCHEMA.membership" STATUS_TABLE="$SCHEMA.status" @@ -37,15 +39,14 @@ STATUS_TABLE="$SCHEMA.status" WSREP_ON='SET wsrep_on=ON' WSREP_OFF='SET wsrep_on=OFF' -BEGIN="$WSREP_OFF; -DROP SCHEMA IF EXISTS $SCHEMA; CREATE SCHEMA $SCHEMA; -CREATE TABLE $MEMB_TABLE ( +BEGIN="CREATE SCHEMA IF NOT EXISTS $SCHEMA; +CREATE TABLE IF NOT EXISTS $MEMB_TABLE ( idx INT UNIQUE PRIMARY KEY, uuid CHAR(40) UNIQUE, /* node UUID */ name VARCHAR(32), /* node name */ addr VARCHAR(256) /* node address */ ) ENGINE=MEMORY; -CREATE TABLE $STATUS_TABLE ( +CREATE TABLE IF NOT EXISTS $STATUS_TABLE ( size INT, /* component size */ idx INT, /* this node index */ status CHAR(16), /* this node status */ @@ -57,7 +58,7 @@ END="COMMIT; $WSREP_ON" configuration_change() { - echo "$BEGIN;" + echo "$WSREP_OFF; DROP SCHEMA IF EXISTS $SCHEMA; $BEGIN;" local idx=0 @@ -67,7 +68,7 @@ configuration_change() # Don't forget to properly quote string values echo "'$NODE'" | sed s/\\//\',\'/g echo ");" - idx=$(( $idx + 1 )) + idx=$(( $idx+1 )) done echo "INSERT INTO $STATUS_TABLE VALUES($idx, $INDEX, '$STATUS', '$CLUSTER_UUID', $PRIMARY);" @@ -77,7 +78,7 @@ configuration_change() status_update() { - echo "$WSREP_OFF; BEGIN; UPDATE $STATUS_TABLE SET status='$STATUS'; $END;" + echo "$WSREP_OFF; $BEGIN; UPDATE $STATUS_TABLE SET status='$STATUS'; $END;" } trim_string() @@ -102,34 +103,35 @@ trim_string() fi } -COM=status_update # not a configuration change by default +COM='status_update' # not a configuration change by default STATUS="" CLUSTER_UUID="" -PRIMARY="0" +PRIMARY=0 INDEX="" MEMBERS="" while [ $# -gt 0 ]; do case $1 in - --status) + '--status') STATUS=$(trim_string "$2") shift ;; - --uuid) + '--uuid') CLUSTER_UUID=$(trim_string "$2") shift ;; - --primary) - [ "$2" = "yes" ] && PRIMARY="1" || PRIMARY="0" - COM=configuration_change + '--primary') + arg=$(trim_string "$2") + [ "$arg" = 'yes' ] && PRIMARY=1 || PRIMARY=0 + COM='configuration_change' shift ;; - --index) + '--index') INDEX=$(trim_string "$2") shift ;; - --members) + '--members') MEMBERS=$(trim_string "$2") shift ;; @@ -168,9 +170,7 @@ ssl_verify_server_cert=$(trim_string "$ssl_verify_server_cert"); SSL_PARAM="" -if [ -n "$ssl_key" -o -n "$ssl_cert" -o \ - -n "$ssl_ca" -o -n "$ssl_capath" -o \ - -n "$ssl_cipher" ] +if [ -n "$ssl_key$ssl_cert$ssl_ca$ssl_capath$ssl_cipher$ssl_crl$ssl_crlpath" ] then SSL_PARAM=' --ssl' [ -n "$ssl_key" ] && SSL_PARAM="$SSL_PARAM --ssl-key='$ssl_key'" @@ -181,8 +181,10 @@ then [ -n "$ssl_crl" ] && SSL_PARAM="$SSL_PARAM --ssl-crl='$ssl_crl'" [ -n "$ssl_crlpath" ] && SSL_PARAM="$SSL_PARAM --ssl-crlpath='$ssl_crlpath'" if [ -n "$ssl_verify_server_cert" ]; then - if [ $ssl_verify_server_cert -ne 0 ]; then - SSL_PARAM+=' --ssl-verify-server-cert' + if [ "$ssl_verify_server_cert" != "0" -o \ + "$ssl_verify_server_cert" = "on" ] + then + SSL_PARAM="$SSL_PARAM --ssl-verify-server-cert" fi fi fi -- cgit v1.2.1 From da5d3499353036d39c3a4bcd1f0466f7de3fc263 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 27 Nov 2022 16:07:40 +0100 Subject: fix error on reading 5.5 tables with generated columns --- sql/table.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sql/table.cc b/sql/table.cc index 7da22a058ab..a38a8df01ba 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -2378,11 +2378,11 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, comment_pos+= comment_length; } - if ((uchar) strpos[13] == (uchar) MYSQL_TYPE_VIRTUAL - && likely(share->mysql_version >= 100000)) + if (strpos[13] == MYSQL_TYPE_VIRTUAL && + (share->mysql_version < 50600 || share->mysql_version >= 100000)) { /* - MariaDB version 10.0 version. + MariaDB 5.5 or 10.0 version. The interval_id byte in the .frm file stores the length of the expression statement for a virtual column. */ -- cgit v1.2.1