diff options
35 files changed, 665 insertions, 292 deletions
diff --git a/mysql-test/main/grant.result b/mysql-test/main/grant.result index a1c78483643..3d609cf2d4a 100644 --- a/mysql-test/main/grant.result +++ b/mysql-test/main/grant.result @@ -2771,6 +2771,24 @@ root@localhost DROP TABLE t1; DROP USER dummy@localhost; # +# MDEV-23082: ER_TABLEACCESS_DENIED_ERROR error message is truncated, and +# inaccurately +# +CREATE USER foo; +CREATE DATABASE db; +CREATE TABLE db.t (a INT); +connect con1,localhost,foo,,; +GRANT ALL ON db.t TO foo; +ERROR 42000: SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, GRANT, REFERENCES, INDEX, ALTER, CREATE VIEW, SHOW ... command denied to user 'foo'@'localhost' for table 't' +GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, GRANT OPTION, REFERENCES, +INDEX, ALTER, CREATE VIEW, SHOW VIEW, TRIGGER ON db.t TO foo; +ERROR 42000: SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, GRANT, REFERENCES, INDEX, ALTER, CREATE VIEW, SHOW ... command denied to user 'foo'@'localhost' for table 't' +connection default; +disconnect con1; +DROP USER foo; +DROP TABLE db.t; +DROP DATABASE db; +# # End of 10.2 tests # # diff --git a/mysql-test/main/grant.test b/mysql-test/main/grant.test index 7c09236e224..eb677441e15 100644 --- a/mysql-test/main/grant.test +++ b/mysql-test/main/grant.test @@ -2268,6 +2268,31 @@ DROP TABLE t1; DROP USER dummy@localhost; --echo # +--echo # MDEV-23082: ER_TABLEACCESS_DENIED_ERROR error message is truncated, and +--echo # inaccurately +--echo # + +CREATE USER foo; +CREATE DATABASE db; +CREATE TABLE db.t (a INT); + +--connect (con1,localhost,foo,,) + +--error ER_TABLEACCESS_DENIED_ERROR +GRANT ALL ON db.t TO foo; + +--error ER_TABLEACCESS_DENIED_ERROR +GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, GRANT OPTION, REFERENCES, +INDEX, ALTER, CREATE VIEW, SHOW VIEW, TRIGGER ON db.t TO foo; + +--connection default +--disconnect con1 + +DROP USER foo; +DROP TABLE db.t; +DROP DATABASE db; + +--echo # --echo # End of 10.2 tests --echo # diff --git a/mysql-test/main/information_schema.result b/mysql-test/main/information_schema.result index 20b5985deb6..94e7244a316 100644 --- a/mysql-test/main/information_schema.result +++ b/mysql-test/main/information_schema.result @@ -2202,6 +2202,21 @@ SCHEMA_NAME # End of 10.1 tests # # +# Start of 10.2 Test +# +# MDEV-14836: Assertion `m_status == DA_ERROR' failed in +# Diagnostics_area::sql_errno upon query from I_S with LIMIT ROWS EXAMINED +# +SELECT * FROM INFORMATION_SCHEMA.`COLUMNS` LIMIT ROWS EXAMINED 10; +ERROR HY000: Unknown error +SHOW WARNINGS; +Level Code Message +Error 1105 Unknown error +Warning 1931 Query execution was interrupted. The query examined at least 11 rows, which exceeds LIMIT ROWS EXAMINED (10). The query result may be incomplete +# +# End of 10.2 Test +# +# # MDEV-21201:No records produced in information_schema query, # depending on projection # diff --git a/mysql-test/main/information_schema.test b/mysql-test/main/information_schema.test index dbb0622baf3..dd2b723e6ee 100644 --- a/mysql-test/main/information_schema.test +++ b/mysql-test/main/information_schema.test @@ -1923,6 +1923,20 @@ SELECT SCHEMA_NAME from information_schema.schemata where schema_name=REPEAT('a' --echo # End of 10.1 tests --echo # +--echo # +--echo # Start of 10.2 Test +--echo # +--echo # MDEV-14836: Assertion `m_status == DA_ERROR' failed in +--echo # Diagnostics_area::sql_errno upon query from I_S with LIMIT ROWS EXAMINED +--echo # + +--error ER_UNKNOWN_ERROR +SELECT * FROM INFORMATION_SCHEMA.`COLUMNS` LIMIT ROWS EXAMINED 10; +SHOW WARNINGS; + +--echo # +--echo # End of 10.2 Test +--echo # --echo # --echo # MDEV-21201:No records produced in information_schema query, diff --git a/mysql-test/main/mysql_tzinfo_to_sql_symlink.result b/mysql-test/main/mysql_tzinfo_to_sql_symlink.result index fc9ddce08b1..06e21beace1 100644 --- a/mysql-test/main/mysql_tzinfo_to_sql_symlink.result +++ b/mysql-test/main/mysql_tzinfo_to_sql_symlink.result @@ -85,6 +85,15 @@ END IF| # # Testing with explicit timezonefile # +\d | +IF (select count(*) from information_schema.global_variables where +variable_name='wsrep_on' and variable_value='ON') = 1 THEN +ALTER TABLE time_zone ENGINE=InnoDB; +ALTER TABLE time_zone_name ENGINE=InnoDB; +ALTER TABLE time_zone_transition ENGINE=InnoDB; +ALTER TABLE time_zone_transition_type ENGINE=InnoDB; +END IF| +\d ; INSERT INTO time_zone (Use_leap_seconds) VALUES ('N'); SET @time_zone_id= LAST_INSERT_ID(); INSERT INTO time_zone_name (Name, Time_zone_id) VALUES ('XXX', @time_zone_id); @@ -106,6 +115,15 @@ END IF| \d | IF (select count(*) from information_schema.global_variables where variable_name='wsrep_on' and variable_value='ON') = 1 THEN +ALTER TABLE time_zone ENGINE=InnoDB; +ALTER TABLE time_zone_name ENGINE=InnoDB; +ALTER TABLE time_zone_transition ENGINE=InnoDB; +ALTER TABLE time_zone_transition_type ENGINE=InnoDB; +END IF| +\d ; +\d | +IF (select count(*) from information_schema.global_variables where +variable_name='wsrep_on' and variable_value='ON') = 1 THEN ALTER TABLE time_zone_leap_second ENGINE=InnoDB; END IF| \d ; diff --git a/mysql-test/main/mysqld--help,win.rdiff b/mysql-test/main/mysqld--help,win.rdiff index 880627631bd..34ed5df7074 100644 --- a/mysql-test/main/mysqld--help,win.rdiff +++ b/mysql-test/main/mysqld--help,win.rdiff @@ -101,20 +101,6 @@ sort-buffer-size 2097152 sql-mode STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION sql-safe-updates FALSE -@@ -1686,10 +1702,10 @@ - sync-relay-log-info 10000 - sysdate-is-now FALSE - system-versioning-alter-history ERROR --table-cache 421 -+table-cache 2000 - table-definition-cache 400 --table-open-cache 421 --table-open-cache-instances 1 -+table-open-cache 2000 -+table-open-cache-instances 8 - tc-heuristic-recover OFF - tcp-keepalive-interval 0 - tcp-keepalive-probes 0 @@ -1697,6 +1713,8 @@ thread-cache-size 151 thread-pool-idle-timeout 60 diff --git a/mysql-test/main/mysqld--help.result b/mysql-test/main/mysqld--help.result index dcfbc2cd65d..54389a78f73 100644 --- a/mysql-test/main/mysqld--help.result +++ b/mysql-test/main/mysqld--help.result @@ -1499,7 +1499,6 @@ max-binlog-cache-size 18446744073709547520 max-binlog-size 1073741824 max-binlog-stmt-cache-size 18446744073709547520 max-connect-errors 100 -max-connections 151 max-delayed-threads 20 max-digest-length 1024 max-error-count 64 @@ -1686,10 +1685,7 @@ sync-relay-log 10000 sync-relay-log-info 10000 sysdate-is-now FALSE system-versioning-alter-history ERROR -table-cache 421 table-definition-cache 400 -table-open-cache 421 -table-open-cache-instances 1 tc-heuristic-recover OFF tcp-keepalive-interval 0 tcp-keepalive-probes 0 diff --git a/mysql-test/main/mysqld--help.test b/mysql-test/main/mysqld--help.test index 6e5ad058330..4077cbb548e 100644 --- a/mysql-test/main/mysqld--help.test +++ b/mysql-test/main/mysqld--help.test @@ -23,7 +23,9 @@ perl; log-slow-queries pid-file slow-query-log-file log-basename datadir slave-load-tmpdir tmpdir socket thread-pool-size large-files-support lower-case-file-system system-time-zone - collation-server character-set-server log-tc-size version.*/; + collation-server character-set-server log-tc-size table-cache + table-open-cache table-open-cache-instances max-connections + version.*/; # Plugins which may or may not be there: @plugins=qw/innodb archive blackhole federated partition diff --git a/mysql-test/main/subselect4.result b/mysql-test/main/subselect4.result index 26770c79d8d..d1d3b514549 100644 --- a/mysql-test/main/subselect4.result +++ b/mysql-test/main/subselect4.result @@ -2609,6 +2609,47 @@ Central America and the Caribbean 442 66422 SET @@optimizer_switch= @save_optimizer_switch; DROP TABLE t1; # +# MDEV-9513: Assertion `join->group_list || !join->is_in_subquery()' failed in create_sort_index +# +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1),(2); +CREATE TABLE t2 (a INT); +INSERT INTO t2 VALUES (2),(3); +EXPLAIN +SELECT t1.a FROM t1 WHERE t1.a IN ( SELECT A.a FROM t1 A UNION SELECT B.a FROM t2 B ORDER BY 1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where +2 DEPENDENT SUBQUERY A ALL NULL NULL NULL NULL 2 Using where +3 DEPENDENT UNION B ALL NULL NULL NULL NULL 2 Using where +NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL +SELECT t1.a FROM t1 WHERE t1.a IN ( SELECT A.a FROM t1 A UNION SELECT B.a FROM t2 B ORDER BY 1); +a +1 +2 +EXPLAIN +SELECT t1.a FROM t1 WHERE EXISTS (SELECT A.a FROM t1 A UNION SELECT B.a FROM t2 B ORDER BY 1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 +2 SUBQUERY A ALL NULL NULL NULL NULL 2 +3 UNION B ALL NULL NULL NULL NULL 2 +NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL +SELECT t1.a FROM t1 WHERE EXISTS (SELECT A.a FROM t1 A UNION SELECT B.a FROM t2 B ORDER BY 1); +a +1 +2 +EXPLAIN +SELECT t1.a FROM t1 WHERE t1.a IN ( SELECT A.a FROM t1 A UNION ALL SELECT B.a FROM t2 B ORDER BY 1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where +2 DEPENDENT SUBQUERY A ALL NULL NULL NULL NULL 2 Using where +3 DEPENDENT UNION B ALL NULL NULL NULL NULL 2 Using where +SELECT t1.a FROM t1 WHERE t1.a IN ( SELECT A.a FROM t1 A UNION ALL SELECT B.a FROM t2 B ORDER BY 1); +a +1 +2 +DROP TABLE t1,t2; +# end of 10.1 tests +# # MDEV-22852: SIGSEGV in sortlength (optimized builds) # SET @save_optimizer_switch=@@optimizer_switch; @@ -2620,4 +2661,29 @@ SELECT (SELECT DISTINCT t1i.b FROM t1 t1i GROUP BY t1i.a ORDER BY MAX(t1o.b)) FR 0 SET @@optimizer_switch= @save_optimizer_switch; DROP TABLE t1; +# +# MDEV-17066: Bytes lost or Assertion `status_var.local_memory_used == 0 after DELETE +# with subquery with ROLLUP +# +CREATE TABLE t1 (i INT DEFAULT 0, c VARCHAR(2048)); +INSERT INTO t1 SELECT 0, seq FROM seq_1_to_6000; +CREATE TABLE t2 (f VARCHAR(2048) DEFAULT ''); +INSERT INTO t2 VALUES ('1'),('bar'); +EXPLAIN +SELECT * FROM t2 WHERE f IN ( SELECT MAX(c) FROM t1 GROUP BY c WITH ROLLUP); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where +2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 6000 Using filesort +SELECT * FROM t2 WHERE f IN ( SELECT MAX(c) FROM t1 GROUP BY c WITH ROLLUP); +f +1 +SELECT * FROM t2; +f +1 +bar +DELETE FROM t2 WHERE f IN ( SELECT MAX(c) FROM t1 GROUP BY c WITH ROLLUP ); +SELECT * FROM t2; +f +bar +DROP TABLE t1, t2; # End of 10.2 tests diff --git a/mysql-test/main/subselect4.test b/mysql-test/main/subselect4.test index c33fe15bdcc..6eada9b27d9 100644 --- a/mysql-test/main/subselect4.test +++ b/mysql-test/main/subselect4.test @@ -7,6 +7,8 @@ drop table if exists t0,t1,t2,t3,t4,t5,t6; drop view if exists v1, v2; --enable_warnings +--source include/have_sequence.inc + set @subselect4_tmp= @@optimizer_switch; set optimizer_switch='semijoin=on,firstmatch=on,loosescan=on'; set optimizer_switch='semijoin_with_cache=on'; @@ -2142,6 +2144,31 @@ SET @@optimizer_switch= @save_optimizer_switch; DROP TABLE t1; --echo # +--echo # MDEV-9513: Assertion `join->group_list || !join->is_in_subquery()' failed in create_sort_index +--echo # + +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1),(2); + +CREATE TABLE t2 (a INT); +INSERT INTO t2 VALUES (2),(3); +EXPLAIN +SELECT t1.a FROM t1 WHERE t1.a IN ( SELECT A.a FROM t1 A UNION SELECT B.a FROM t2 B ORDER BY 1); +SELECT t1.a FROM t1 WHERE t1.a IN ( SELECT A.a FROM t1 A UNION SELECT B.a FROM t2 B ORDER BY 1); + +EXPLAIN +SELECT t1.a FROM t1 WHERE EXISTS (SELECT A.a FROM t1 A UNION SELECT B.a FROM t2 B ORDER BY 1); +SELECT t1.a FROM t1 WHERE EXISTS (SELECT A.a FROM t1 A UNION SELECT B.a FROM t2 B ORDER BY 1); + +EXPLAIN +SELECT t1.a FROM t1 WHERE t1.a IN ( SELECT A.a FROM t1 A UNION ALL SELECT B.a FROM t2 B ORDER BY 1); +SELECT t1.a FROM t1 WHERE t1.a IN ( SELECT A.a FROM t1 A UNION ALL SELECT B.a FROM t2 B ORDER BY 1); + +DROP TABLE t1,t2; + +--echo # end of 10.1 tests + +--echo # --echo # MDEV-22852: SIGSEGV in sortlength (optimized builds) --echo # @@ -2153,4 +2180,25 @@ SELECT (SELECT DISTINCT t1i.b FROM t1 t1i GROUP BY t1i.a ORDER BY MAX(t1o.b)) FR SET @@optimizer_switch= @save_optimizer_switch; DROP TABLE t1; +--echo # +--echo # MDEV-17066: Bytes lost or Assertion `status_var.local_memory_used == 0 after DELETE +--echo # with subquery with ROLLUP +--echo # + +CREATE TABLE t1 (i INT DEFAULT 0, c VARCHAR(2048)); +INSERT INTO t1 SELECT 0, seq FROM seq_1_to_6000; + +CREATE TABLE t2 (f VARCHAR(2048) DEFAULT ''); +INSERT INTO t2 VALUES ('1'),('bar'); + +EXPLAIN +SELECT * FROM t2 WHERE f IN ( SELECT MAX(c) FROM t1 GROUP BY c WITH ROLLUP); +SELECT * FROM t2 WHERE f IN ( SELECT MAX(c) FROM t1 GROUP BY c WITH ROLLUP); + +SELECT * FROM t2; +DELETE FROM t2 WHERE f IN ( SELECT MAX(c) FROM t1 GROUP BY c WITH ROLLUP ); +SELECT * FROM t2; + +DROP TABLE t1, t2; + --echo # End of 10.2 tests diff --git a/mysql-test/main/type_newdecimal.result b/mysql-test/main/type_newdecimal.result index 07ecef95e5d..85ac75351c0 100644 --- a/mysql-test/main/type_newdecimal.result +++ b/mysql-test/main/type_newdecimal.result @@ -2340,6 +2340,53 @@ t1 CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t1; # +# MDEV-23105 Cast number string with many leading zeros to decimal gives unexpected result +# +SELECT CAST(0000000000000000000000000000000000000000000000000000000000000000000000000000000020.01 AS DECIMAL(15,2)) as val; +val +20.01 +SET sql_mode=''; +CREATE TABLE t1 (a TEXT); +INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1)); +INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1,'.0')); +INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1,'.9')); +INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1,'.99')); +INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1,'.994')); +INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1,'.995')); +INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1,'.999')); +CREATE TABLE t2 (a TEXT, d DECIMAL(15,2)); +INSERT IGNORE INTO t2 (a,d) SELECT a, a FROM t1; +Warnings: +Note 1265 Data truncated for column 'd' at row 5 +Note 1265 Data truncated for column 'd' at row 6 +Note 1265 Data truncated for column 'd' at row 7 +INSERT IGNORE INTO t2 (a,d) SELECT CONCAT('-',a), CONCAT('-',a) FROM t1; +Warnings: +Note 1265 Data truncated for column 'd' at row 5 +Note 1265 Data truncated for column 'd' at row 6 +Note 1265 Data truncated for column 'd' at row 7 +SELECT d, a FROM t2 ORDER BY d,a; +d a +-2.00 -00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.995 +-2.00 -00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.999 +-1.99 -00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.99 +-1.99 -00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.994 +-1.90 -00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.9 +-1.00 -00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 +-1.00 -00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.0 +1.00 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 +1.00 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.0 +1.90 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.9 +1.99 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.99 +1.99 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.994 +2.00 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.995 +2.00 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.999 +DROP TABLE t1, t2; +SET sql_mode=DEFAULT; +# +# End of 10.1 tests +# +# # Bug#18408499 UNSIGNED BIGINT HIGH VALUES # WRONG NUMERICAL COMPARISON RESULTS # diff --git a/mysql-test/main/type_newdecimal.test b/mysql-test/main/type_newdecimal.test index 2f3409f56e9..e5d903e95cd 100644 --- a/mysql-test/main/type_newdecimal.test +++ b/mysql-test/main/type_newdecimal.test @@ -1825,6 +1825,32 @@ SHOW CREATE TABLE t1; DROP TABLE t1; --echo # +--echo # MDEV-23105 Cast number string with many leading zeros to decimal gives unexpected result +--echo # + +SELECT CAST(0000000000000000000000000000000000000000000000000000000000000000000000000000000020.01 AS DECIMAL(15,2)) as val; + +SET sql_mode=''; +CREATE TABLE t1 (a TEXT); +INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1)); +INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1,'.0')); +INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1,'.9')); +INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1,'.99')); +INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1,'.994')); +INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1,'.995')); +INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1,'.999')); +CREATE TABLE t2 (a TEXT, d DECIMAL(15,2)); +INSERT IGNORE INTO t2 (a,d) SELECT a, a FROM t1; +INSERT IGNORE INTO t2 (a,d) SELECT CONCAT('-',a), CONCAT('-',a) FROM t1; +SELECT d, a FROM t2 ORDER BY d,a; +DROP TABLE t1, t2; +SET sql_mode=DEFAULT; + +--echo # +--echo # End of 10.1 tests +--echo # + +--echo # --echo # Bug#18408499 UNSIGNED BIGINT HIGH VALUES --echo # WRONG NUMERICAL COMPARISON RESULTS --echo # diff --git a/mysql-test/main/win.result b/mysql-test/main/win.result index 24aa29598cd..08668965cf6 100644 --- a/mysql-test/main/win.result +++ b/mysql-test/main/win.result @@ -3850,6 +3850,22 @@ ERROR 42000: Too big scale 56 specified for 'rank() over w1'. Maximum is 38 SELECT cast((rank() over w1) as decimal (53,30)); ERROR HY000: Window specification with name 'w1' is not defined # +# MDEV-15180: server crashed with NTH_VALUE() +# +CREATE TABLE t1 (i1 int, a int); +INSERT INTO t1 VALUES (1, 1), (2, 2),(3, 3); +CREATE TABLE t2 (i2 int); +INSERT INTO t2 VALUES (1),(2),(5),(1),(7),(4),(3); +CREATE VIEW v1 AS (SELECT * FROM t1,t2 WHERE t1.i1=t2.i2) ; +SELECT NTH_VALUE(i1, i1) OVER (PARTITION BY i1) FROM v1; +NTH_VALUE(i1, i1) OVER (PARTITION BY i1) +1 +1 +NULL +NULL +DROP VIEW v1; +DROP TABLE t1,t2; +# # End of 10.2 tests # # diff --git a/mysql-test/main/win.test b/mysql-test/main/win.test index 37d2b616dda..bc2f6144985 100644 --- a/mysql-test/main/win.test +++ b/mysql-test/main/win.test @@ -2507,6 +2507,22 @@ SELECT cast((rank() over w1) as decimal (53,56)); SELECT cast((rank() over w1) as decimal (53,30)); --echo # +--echo # MDEV-15180: server crashed with NTH_VALUE() +--echo # + +CREATE TABLE t1 (i1 int, a int); +INSERT INTO t1 VALUES (1, 1), (2, 2),(3, 3); + +CREATE TABLE t2 (i2 int); +INSERT INTO t2 VALUES (1),(2),(5),(1),(7),(4),(3); + +CREATE VIEW v1 AS (SELECT * FROM t1,t2 WHERE t1.i1=t2.i2) ; +SELECT NTH_VALUE(i1, i1) OVER (PARTITION BY i1) FROM v1; + +DROP VIEW v1; +DROP TABLE t1,t2; + +--echo # --echo # End of 10.2 tests --echo # diff --git a/mysql-test/suite/galera/disabled.def b/mysql-test/suite/galera/disabled.def index e425efb785e..8583fd72760 100644 --- a/mysql-test/suite/galera/disabled.def +++ b/mysql-test/suite/galera/disabled.def @@ -11,6 +11,7 @@ ############################################################################## MW-286 : MDEV-18464 Killing thread can cause mutex deadlock if done concurrently with Galera/replication victim kill +MW-328A : MDEV-22666 galera.MW-328A MTR failed: "Semaphore wait has lasted > 600 seconds" and do not release port 16002 MW-329 : MDEV-19962 Galera test failure on MW-329 galera.galera_defaults : MDEV-21494 Galera test sporadic failure on galera.galera_defaults galera_as_slave_replication_bundle : MDEV-15785 OPTION_GTID_BEGIN is set in Gtid_log_event::do_apply_event() diff --git a/mysql-test/suite/galera/r/galera_bf_lock_wait.result b/mysql-test/suite/galera/r/galera_bf_lock_wait.result index 7ec524da888..0b22f963b29 100644 --- a/mysql-test/suite/galera/r/galera_bf_lock_wait.result +++ b/mysql-test/suite/galera/r/galera_bf_lock_wait.result @@ -1,23 +1,41 @@ +connection node_1; CREATE TABLE t1 ENGINE=InnoDB select 1 as a, 1 as b union select 2, 2; ALTER TABLE t1 add primary key(a); -CREATE PROCEDURE p1() +CREATE PROCEDURE p1(repeat_count INT) BEGIN +DECLARE current_num int; DECLARE CONTINUE HANDLER FOR SQLEXCEPTION rollback; -WHILE 1 DO +SET current_num = 0; +WHILE current_num < repeat_count DO start transaction; update t1 set b=connection_id() where a=1; commit; +SET current_num = current_num + 1; END WHILE; END| +connection node_2; connect node_1_p1, 127.0.0.1, root, , test, $NODE_MYPORT_1; -call p1; +SET SESSION wsrep_sync_wait=0; +call p1(1000); connect node_1_p2, 127.0.0.1, root, , test, $NODE_MYPORT_1; -call p1; +SET SESSION wsrep_sync_wait=0; +call p1(1000); connect node_2_p1, 127.0.0.1, root, , test, $NODE_MYPORT_2; -call p1; +SET SESSION wsrep_sync_wait=0; +call p1(1000); connect node_2_p2, 127.0.0.1, root, , test, $NODE_MYPORT_2; -call p1; -connection default; +SET SESSION wsrep_sync_wait=0; +call p1(1000); +connection node_1; checking error log for 'BF lock wait long' message for 10 times every 10 seconds ... +connection node_1_p1; +connection node_1_p2; +connection node_2_p1; +connection node_2_p2; +connection node_1; drop table t1; drop procedure p1; +disconnect node_1_p1; +disconnect node_1_p2; +disconnect node_2_p1; +disconnect node_2_p2; diff --git a/mysql-test/suite/galera/t/galera_bf_lock_wait.test b/mysql-test/suite/galera/t/galera_bf_lock_wait.test index e3a9077a888..c8a31506ffa 100644 --- a/mysql-test/suite/galera/t/galera_bf_lock_wait.test +++ b/mysql-test/suite/galera/t/galera_bf_lock_wait.test @@ -1,34 +1,47 @@ --source include/galera_cluster.inc --source include/big_test.inc - + +--connection node_1 CREATE TABLE t1 ENGINE=InnoDB select 1 as a, 1 as b union select 2, 2; ALTER TABLE t1 add primary key(a); DELIMITER |; -CREATE PROCEDURE p1() +CREATE PROCEDURE p1(repeat_count INT) BEGIN + DECLARE current_num int; DECLARE CONTINUE HANDLER FOR SQLEXCEPTION rollback; - WHILE 1 DO + SET current_num = 0; + + WHILE current_num < repeat_count DO start transaction; update t1 set b=connection_id() where a=1; commit; + SET current_num = current_num + 1; END WHILE; END| DELIMITER ;| - + +--connection node_2 +--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_TYPE = 'PROCEDURE' AND ROUTINE_NAME = 'p1' +--source include/wait_condition.inc + --connect node_1_p1, 127.0.0.1, root, , test, $NODE_MYPORT_1 -send call p1; +SET SESSION wsrep_sync_wait=0; +send call p1(1000); --connect node_1_p2, 127.0.0.1, root, , test, $NODE_MYPORT_1 -send call p1; +SET SESSION wsrep_sync_wait=0; +send call p1(1000); --connect node_2_p1, 127.0.0.1, root, , test, $NODE_MYPORT_2 -send call p1; +SET SESSION wsrep_sync_wait=0; +send call p1(1000); --connect node_2_p2, 127.0.0.1, root, , test, $NODE_MYPORT_2 -send call p1; +SET SESSION wsrep_sync_wait=0; +send call p1(1000); -connection default; +connection node_1; let $counter=10; let $sleep_period=10; @@ -46,7 +59,26 @@ while($counter > 0) exec grep 'BF lock wait long' $MYSQLTEST_VARDIR/log/mysqld.*.err; dec $counter; } - + +--connection node_1_p1 +--error 0,1213 +--reap +--connection node_1_p2 +--error 0,1213 +--reap +--connection node_2_p1 +--error 0,1213 +--reap +--connection node_2_p2 +--error 0,1213 +--reap + +--connection node_1 drop table t1; drop procedure p1; +--disconnect node_1_p1 +--disconnect node_1_p2 +--disconnect node_2_p1 +--disconnect node_2_p2 + diff --git a/mysql-test/suite/wsrep/r/mysql_tzinfo_to_sql_symlink.result b/mysql-test/suite/wsrep/r/mysql_tzinfo_to_sql_symlink.result index 1e6ebbbd34d..51c2e204b78 100644 --- a/mysql-test/suite/wsrep/r/mysql_tzinfo_to_sql_symlink.result +++ b/mysql-test/suite/wsrep/r/mysql_tzinfo_to_sql_symlink.result @@ -85,6 +85,15 @@ END IF| # # Testing with explicit timezonefile # +\d | +IF (select count(*) from information_schema.global_variables where +variable_name='wsrep_on' and variable_value='ON') = 1 THEN +ALTER TABLE time_zone ENGINE=InnoDB; +ALTER TABLE time_zone_name ENGINE=InnoDB; +ALTER TABLE time_zone_transition ENGINE=InnoDB; +ALTER TABLE time_zone_transition_type ENGINE=InnoDB; +END IF| +\d ; INSERT INTO time_zone (Use_leap_seconds) VALUES ('N'); SET @time_zone_id= LAST_INSERT_ID(); INSERT INTO time_zone_name (Name, Time_zone_id) VALUES ('XXX', @time_zone_id); @@ -106,6 +115,15 @@ END IF| \d | IF (select count(*) from information_schema.global_variables where variable_name='wsrep_on' and variable_value='ON') = 1 THEN +ALTER TABLE time_zone ENGINE=InnoDB; +ALTER TABLE time_zone_name ENGINE=InnoDB; +ALTER TABLE time_zone_transition ENGINE=InnoDB; +ALTER TABLE time_zone_transition_type ENGINE=InnoDB; +END IF| +\d ; +\d | +IF (select count(*) from information_schema.global_variables where +variable_name='wsrep_on' and variable_value='ON') = 1 THEN ALTER TABLE time_zone_leap_second ENGINE=InnoDB; END IF| \d ; diff --git a/sql/item_subselect.h b/sql/item_subselect.h index 3b270adfbc3..52480743855 100644 --- a/sql/item_subselect.h +++ b/sql/item_subselect.h @@ -145,6 +145,10 @@ public: Item_subselect(THD *thd); virtual subs_type substype() { return UNKNOWN_SUBS; } + bool is_exists_predicate() + { + return substype() == Item_subselect::EXISTS_SUBS; + } bool is_in_predicate() { return (substype() == Item_subselect::IN_SUBS || diff --git a/sql/records.cc b/sql/records.cc index 3d709182a4e..817caada8e2 100644 --- a/sql/records.cc +++ b/sql/records.cc @@ -316,12 +316,9 @@ bool init_read_record(READ_RECORD *info,THD *thd, TABLE *table, void end_read_record(READ_RECORD *info) -{ /* free cache if used */ - if (info->cache) - { - my_free_lock(info->cache); - info->cache=0; - } +{ + /* free cache if used */ + free_cache(info); if (info->table) { if (info->table->is_created()) @@ -332,6 +329,17 @@ void end_read_record(READ_RECORD *info) } } + +void free_cache(READ_RECORD *info) +{ + if (info->cache) + { + my_free_lock(info->cache); + info->cache=0; + } +} + + static int rr_handle_error(READ_RECORD *info, int error) { if (info->thd->killed) diff --git a/sql/records.h b/sql/records.h index faf0d13c9a9..74f64cd286f 100644 --- a/sql/records.h +++ b/sql/records.h @@ -31,6 +31,7 @@ class SORT_INFO; struct READ_RECORD; void end_read_record(READ_RECORD *info); +void free_cache(READ_RECORD *info); /** A context for reading through a single table using a chosen access method: diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt index ed8d459d1b3..dbc52697d51 100644 --- a/sql/share/errmsg-utf8.txt +++ b/sql/share/errmsg-utf8.txt @@ -3244,25 +3244,25 @@ ER_NONEXISTING_GRANT 42000 swe "Det finns inget privilegium definierat för användare '%-.48s' på '%-.64s'" ukr "Повноважень не визначено для користувача '%-.48s' з хосту '%-.64s'" ER_TABLEACCESS_DENIED_ERROR 42000 - cze "%-.32s příkaz nepřístupný pro uživatele: '%s'@'%s' pro tabulku '%-.192s'" - dan "%-.32s-kommandoen er ikke tilladt for brugeren '%s'@'%s' for tabellen '%-.192s'" - nla "%-.32s commando geweigerd voor gebruiker: '%s'@'%s' voor tabel '%-.192s'" - eng "%-.32s command denied to user '%s'@'%s' for table '%-.192s'" - jps "コマンド %-.32s は ユーザー '%s'@'%s' ,テーブル '%-.192s' に対して許可されていません", - est "%-.32s käsk ei ole lubatud kasutajale '%s'@'%s' tabelis '%-.192s'" - fre "La commande '%-.32s' est interdite à l'utilisateur: '%s'@'%s' sur la table '%-.192s'" - ger "%-.32s Befehl nicht erlaubt für Benutzer '%s'@'%s' auf Tabelle '%-.192s'" - hun "%-.32s parancs a '%s'@'%s' felhasznalo szamara nem engedelyezett a '%-.192s' tablaban" - ita "Comando %-.32s negato per l'utente: '%s'@'%s' sulla tabella '%-.192s'" - jpn "コマンド %-.32s は ユーザー '%s'@'%s' ,テーブル '%-.192s' に対して許可されていません" - kor "'%-.32s' 명령은 다음 사용자에게 거부되었습니다. : '%s'@'%s' for 테이블 '%-.192s'" - por "Comando '%-.32s' negado para o usuário '%s'@'%s' na tabela '%-.192s'" - rum "Comanda %-.32s interzisa utilizatorului: '%s'@'%s' pentru tabela '%-.192s'" - rus "Команда %-.32s запрещена пользователю '%s'@'%s' для таблицы '%-.192s'" - serbian "%-.32s komanda zabranjena za korisnika '%s'@'%s' za tabelu '%-.192s'" - spa "%-.32s comando negado para usuario: '%s'@'%s' para tabla '%-.192s'" - swe "%-.32s ej tillåtet för '%s'@'%s' för tabell '%-.192s'" - ukr "%-.32s команда заборонена користувачу: '%s'@'%s' у таблиці '%-.192s'" + cze "%-.100T příkaz nepřístupný pro uživatele: '%s'@'%s' pro tabulku '%-.192s'" + dan "%-.100T-kommandoen er ikke tilladt for brugeren '%s'@'%s' for tabellen '%-.192s'" + nla "%-.100T commando geweigerd voor gebruiker: '%s'@'%s' voor tabel '%-.192s'" + eng "%-.100T command denied to user '%s'@'%s' for table '%-.192s'" + jps "コマンド %-.100T は ユーザー '%s'@'%s' ,テーブル '%-.192s' に対して許可されていません", + est "%-.100T käsk ei ole lubatud kasutajale '%s'@'%s' tabelis '%-.192s'" + fre "La commande '%-.100T' est interdite à l'utilisateur: '%s'@'%s' sur la table '%-.192s'" + ger "%-.100T Befehl nicht erlaubt für Benutzer '%s'@'%s' auf Tabelle '%-.192s'" + hun "%-.100T parancs a '%s'@'%s' felhasznalo szamara nem engedelyezett a '%-.192s' tablaban" + ita "Comando %-.100T negato per l'utente: '%s'@'%s' sulla tabella '%-.192s'" + jpn "コマンド %-.100T は ユーザー '%s'@'%s' ,テーブル '%-.192s' に対して許可されていません" + kor "'%-.100T' 명령은 다음 사용자에게 거부되었습니다. : '%s'@'%s' for 테이블 '%-.192s'" + por "Comando '%-.100T' negado para o usuário '%s'@'%s' na tabela '%-.192s'" + rum "Comanda %-.100T interzisa utilizatorului: '%s'@'%s' pentru tabela '%-.192s'" + rus "Команда %-.100T запрещена пользователю '%s'@'%s' для таблицы '%-.192s'" + serbian "%-.100T komanda zabranjena za korisnika '%s'@'%s' za tabelu '%-.192s'" + spa "%-.100T comando negado para usuario: '%s'@'%s' para tabla '%-.192s'" + swe "%-.100T ej tillåtet för '%s'@'%s' för tabell '%-.192s'" + ukr "%-.100T команда заборонена користувачу: '%s'@'%s' у таблиці '%-.192s'" ER_COLUMNACCESS_DENIED_ERROR 42000 cze "%-.32s příkaz nepřístupný pro uživatele: '%s'@'%s' pro sloupec '%-.192s' v tabulce '%-.192s'" dan "%-.32s-kommandoen er ikke tilladt for brugeren '%s'@'%s' for kolonne '%-.192s' in tabellen '%-.192s'" diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 89846f7d29e..34c137c4732 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -13131,24 +13131,7 @@ void JOIN::cleanup(bool full) for (tab= first_linear_tab(this, WITH_BUSH_ROOTS, WITH_CONST_TABLES); tab; tab= next_linear_tab(this, tab, WITH_BUSH_ROOTS)) { - if (!tab->table) - continue; - DBUG_PRINT("info", ("close index: %s.%s alias: %s", - tab->table->s->db.str, - tab->table->s->table_name.str, - tab->table->alias.c_ptr())); - if (tab->table->is_created()) - { - tab->table->file->ha_index_or_rnd_end(); - if (tab->aggr) - { - int tmp= 0; - if ((tmp= tab->table->file->extra(HA_EXTRA_NO_CACHE))) - tab->table->file->print_error(tmp, MYF(0)); - } - } - delete tab->filesort_result; - tab->filesort_result= NULL; + tab->partial_cleanup(); } } } @@ -27943,6 +27926,40 @@ void JOIN::handle_implicit_grouping_with_window_funcs() } } + +/* + @brief + Perform a partial cleanup for the JOIN_TAB structure + + @note + this is used to cleanup resources for the re-execution of correlated + subqueries. +*/ +void JOIN_TAB::partial_cleanup() +{ + if (!table) + return; + + if (table->is_created()) + { + table->file->ha_index_or_rnd_end(); + DBUG_PRINT("info", ("close index: %s.%s alias: %s", + table->s->db.str, + table->s->table_name.str, + table->alias.c_ptr())); + if (aggr) + { + int tmp= 0; + if ((tmp= table->file->extra(HA_EXTRA_NO_CACHE))) + table->file->print_error(tmp, MYF(0)); + } + } + delete filesort_result; + filesort_result= NULL; + free_cache(&read_record); +} + + /** @} (end of group Query_Optimizer) */ diff --git a/sql/sql_select.h b/sql/sql_select.h index 313a322e8ad..df9c9b2eb0e 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -655,6 +655,8 @@ typedef struct st_join_table { bool use_order() const; ///< Use ordering provided by chosen index? bool sort_table(); bool remove_duplicates(); + + void partial_cleanup(); void add_keyuses_for_splitting(); SplM_plan_info *choose_best_splitting(double record_count, table_map remaining_tables); diff --git a/sql/sql_show.cc b/sql/sql_show.cc index a108c607ba3..b9c914f9545 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -4641,7 +4641,7 @@ fill_schema_table_by_open(THD *thd, MEM_ROOT *mem_root, Again we don't do this for SHOW COLUMNS/KEYS because of backward compatibility. */ - if (!is_show_fields_or_keys && result && + if (!is_show_fields_or_keys && result && thd->is_error() && (thd->get_stmt_da()->sql_errno() == ER_NO_SUCH_TABLE || thd->get_stmt_da()->sql_errno() == ER_WRONG_OBJECT || thd->get_stmt_da()->sql_errno() == ER_NOT_SEQUENCE)) @@ -5931,15 +5931,21 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables, I.e. we are in SELECT FROM INFORMATION_SCHEMA.COLUMS rather than in SHOW COLUMNS */ - push_warning(thd, Sql_condition::WARN_LEVEL_WARN, - thd->get_stmt_da()->sql_errno(), - thd->get_stmt_da()->message()); - thd->clear_error(); + if (thd->is_error()) + { + /* + The the query was aborted because examined rows exceeded limit. + Don't send the warning here. It is done later, in handle_select(). + */ + push_warning(thd, Sql_condition::WARN_LEVEL_WARN, + thd->get_stmt_da()->sql_errno(), + thd->get_stmt_da()->message()); + thd->clear_error(); + } res= 0; } DBUG_RETURN(res); } - show_table= tables->table; count= 0; ptr= show_table->field; diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 45b3c54460c..d15cc3fa617 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -1,5 +1,5 @@ /* Copyright (c) 2000, 2017, Oracle and/or its affiliates. - Copyright (c) 2010, 2017, Corporation + Copyright (c) 2010, 2020, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -906,6 +906,25 @@ bool st_select_lex_unit::prepare(TABLE_LIST *derived_arg, found_rows_for_union= first_sl->options & OPTION_FOUND_ROWS; is_union_select= is_unit_op() || fake_select_lex || single_tvc; + /* + If we are reading UNION output and the UNION is in the + IN/ANY/ALL/EXISTS subquery, then ORDER BY is redundant and hence should + be removed. + Example: + select ... col IN (select col2 FROM t1 union select col3 from t2 ORDER BY 1) + + (as for ORDER BY ... LIMIT, it currently not supported inside + IN/ALL/ANY subqueries) + (For non-UNION this removal of ORDER BY clause is done in + check_and_do_in_subquery_rewrites()) + */ + if (item && is_unit_op() && + (item->is_in_predicate() || item->is_exists_predicate())) + { + global_parameters()->order_list.first= NULL; + global_parameters()->order_list.elements= 0; + } + for (SELECT_LEX *s= first_sl; s; s= s->next_select()) { switch (s->linkage) @@ -920,6 +939,7 @@ bool st_select_lex_unit::prepare(TABLE_LIST *derived_arg, break; } } + /* Global option */ if (is_union_select || is_recursive) diff --git a/sql/table.h b/sql/table.h index 3d289bf241a..a42feba68c4 100644 --- a/sql/table.h +++ b/sql/table.h @@ -1312,9 +1312,16 @@ public: /* number of select if it is derived table */ uint derived_select_number; /* - 0 or JOIN_TYPE_{LEFT|RIGHT}. Currently this is only compared to 0. - If maybe_null !=0, this table is inner w.r.t. some outer join operation, - and null_row may be true. + Possible values: + - 0 by default + - JOIN_TYPE_{LEFT|RIGHT} if the table is inner w.r.t an outer join + operation + - 1 if the SELECT has mixed_implicit_grouping=1. example: + select max(col1), col2 from t1. In this case, the query produces + one row with all columns having NULL values. + + Interpetation: If maybe_null!=0, all fields of the table are considered + NULLable (and have NULL values when null_row=true) */ uint maybe_null; int current_lock; /* Type of lock on table */ diff --git a/sql/tztime.cc b/sql/tztime.cc index b7b30d36810..ca4c10975ca 100644 --- a/sql/tztime.cc +++ b/sql/tztime.cc @@ -2705,6 +2705,7 @@ main(int argc, char **argv) } if (opt_skip_write_binlog) + { /* If skip_write_binlog is set and wsrep is compiled in we disable sql_log_bin and wsrep_on to avoid Galera replicating below truncate table clauses. This will allow user to set different @@ -2712,15 +2713,9 @@ main(int argc, char **argv) printf("set @prep1=if((select count(*) from information_schema.global_variables where variable_name='wsrep_on' and variable_value='ON'), 'SET SESSION SQL_LOG_BIN=?, WSREP_ON=OFF;', 'do ?');\n" "prepare set_wsrep_write_binlog from @prep1;\n" "set @toggle=0; execute set_wsrep_write_binlog using @toggle;\n"); - - if (argc == 1 && !opt_leap) + } + else { - /* Argument is timezonedir */ - - root_name_end= strmake_buf(fullname, argv[0]); - - if(!opt_skip_write_binlog) - { // Alter time zone tables to InnoDB if wsrep_on is enabled // to allow changes to them to replicate with Galera printf("\\d |\n" @@ -2732,7 +2727,13 @@ main(int argc, char **argv) "ALTER TABLE time_zone_transition_type ENGINE=InnoDB;\n" "END IF|\n" "\\d ;\n"); - } + } + + if (argc == 1 && !opt_leap) + { + /* Argument is timezonedir */ + + root_name_end= strmake_buf(fullname, argv[0]); printf("TRUNCATE TABLE time_zone;\n"); printf("TRUNCATE TABLE time_zone_name;\n"); diff --git a/storage/innobase/fil/fil0crypt.cc b/storage/innobase/fil/fil0crypt.cc index 282b66936a8..be8db200852 100644 --- a/storage/innobase/fil/fil0crypt.cc +++ b/storage/innobase/fil/fil0crypt.cc @@ -41,9 +41,6 @@ Modified Jan Lindström jan.lindstrom@mariadb.com #include "fil0pagecompress.h" #include <my_crypt.h> -/** Mutex for keys */ -static ib_mutex_t fil_crypt_key_mutex; - static bool fil_crypt_threads_inited = false; /** Is encryption enabled/disabled */ @@ -113,8 +110,6 @@ UNIV_INTERN void fil_space_crypt_init() { - mutex_create(LATCH_ID_FIL_CRYPT_MUTEX, &fil_crypt_key_mutex); - fil_crypt_throttle_sleep_event = os_event_create(0); mutex_create(LATCH_ID_FIL_CRYPT_STAT_MUTEX, &crypt_stat_mutex); @@ -128,7 +123,6 @@ void fil_space_crypt_cleanup() { os_event_destroy(fil_crypt_throttle_sleep_event); - mutex_free(&fil_crypt_key_mutex); mutex_free(&crypt_stat_mutex); } @@ -1383,6 +1377,94 @@ fil_crypt_return_iops( fil_crypt_update_total_stat(state); } +/** Return the next tablespace from rotation_list. +@param space previous tablespace (NULL to start from the start) +@param recheck whether the removal condition needs to be rechecked after +the encryption parameters were changed +@param encrypt expected state of innodb_encrypt_tables +@return the next tablespace to process (n_pending_ops incremented) +@retval NULL if this was the last */ +inline fil_space_t *fil_system_t::keyrotate_next(fil_space_t *space, + bool recheck, bool encrypt) +{ + ut_ad(mutex_own(&mutex)); + + sized_ilist<fil_space_t, rotation_list_tag_t>::iterator it= + space ? space : rotation_list.begin(); + const sized_ilist<fil_space_t, rotation_list_tag_t>::iterator end= + rotation_list.end(); + + if (space) + { + while (++it != end && (!UT_LIST_GET_LEN(it->chain) || it->is_stopping())); + + /* If one of the encryption threads already started the encryption + of the table then don't remove the unencrypted spaces from rotation list + + If there is a change in innodb_encrypt_tables variables value then + don't remove the last processed tablespace from the rotation list. */ + space->release(); + + if (!space->referenced() && + (!recheck || space->crypt_data) && !encrypt == !srv_encrypt_tables && + space->is_in_rotation_list) + { + ut_a(!rotation_list.empty()); + rotation_list.remove(*space); + space->is_in_rotation_list= false; + } + } + + if (it == end) + return NULL; + + space= &*it; + space->acquire(); + return space; +} + +/** Return the next tablespace. +@param space previous tablespace (NULL to start from the beginning) +@param recheck whether the removal condition needs to be rechecked after +the encryption parameters were changed +@param encrypt expected state of innodb_encrypt_tables +@return pointer to the next tablespace (with n_pending_ops incremented) +@retval NULL if this was the last */ +static fil_space_t *fil_space_next(fil_space_t *space, bool recheck, + bool encrypt) +{ + mutex_enter(&fil_system.mutex); + + if (!srv_fil_crypt_rotate_key_age) + space= fil_system.keyrotate_next(space, recheck, encrypt); + else if (!space) + { + space= UT_LIST_GET_FIRST(fil_system.space_list); + /* We can trust that space is not NULL because at least the + system tablespace is always present and loaded first. */ + space->acquire(); + } + else + { + /* Move on to the next fil_space_t */ + space->release(); + space= UT_LIST_GET_NEXT(space_list, space); + + /* Skip abnormal tablespaces or those that are being created by + fil_ibd_create(), or being dropped. */ + while (space && + (UT_LIST_GET_LEN(space->chain) == 0 || + space->is_stopping() || space->purpose != FIL_TYPE_TABLESPACE)) + space= UT_LIST_GET_NEXT(space_list, space); + + if (space) + space->acquire(); + } + + mutex_exit(&fil_system.mutex); + return space; +} + /** Search for a space needing rotation @param[in,out] key_state Key state @param[in,out] state Rotation state @@ -1415,13 +1497,8 @@ static bool fil_crypt_find_space_to_rotate( state->space = NULL; } - /* If key rotation is enabled (default) we iterate all tablespaces. - If key rotation is not enabled we iterate only the tablespaces - added to keyrotation list. */ - state->space = srv_fil_crypt_rotate_key_age - ? fil_space_next(state->space) - : fil_system.keyrotate_next(state->space, *recheck, - key_state->key_version); + state->space = fil_space_next(state->space, *recheck, + key_state->key_version != 0); while (!state->should_shutdown() && state->space) { /* If there is no crypt data and we have not yet read @@ -1439,13 +1516,16 @@ static bool fil_crypt_find_space_to_rotate( return true; } - state->space = srv_fil_crypt_rotate_key_age - ? fil_space_next(state->space) - : fil_system.keyrotate_next(state->space, *recheck, - key_state->key_version); + state->space = fil_space_next(state->space, *recheck, + key_state->key_version != 0); + } + + if (state->space) { + state->space->release(); + state->space = NULL; } - /* if we didn't find any space return iops */ + /* no work to do; release our allocation of I/O capacity */ fil_crypt_return_iops(state); return false; @@ -2256,13 +2336,11 @@ static void fil_crypt_rotation_list_fill() if (!space->size) { /* Protect the tablespace while we may release fil_system.mutex. */ - space->n_pending_ops++; -#ifndef DBUG_OFF + ut_d(space->acquire()); ut_d(const fil_space_t* s=) fil_system.read_page0(space->id); ut_ad(!s || s == space); -#endif - space->n_pending_ops--; + ut_d(space->release()); if (!space->size) { /* Page 0 was not loaded. Skip this tablespace. */ diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc index 4b0d6c975dd..73208d4dddc 100644 --- a/storage/innobase/fil/fil0fil.cc +++ b/storage/innobase/fil/fil0fil.cc @@ -5141,120 +5141,6 @@ test_make_filepath() #endif /* UNIV_ENABLE_UNIT_TEST_MAKE_FILEPATH */ /* @} */ -/** Return the next fil_space_t. -Once started, the caller must keep calling this until it returns NULL. -fil_space_t::acquire() and fil_space_t::release() are invoked here which -blocks a concurrent operation from dropping the tablespace. -@param[in] prev_space Pointer to the previous fil_space_t. -If NULL, use the first fil_space_t on fil_system.space_list. -@return pointer to the next fil_space_t. -@retval NULL if this was the last*/ -fil_space_t* -fil_space_next(fil_space_t* prev_space) -{ - fil_space_t* space=prev_space; - - mutex_enter(&fil_system.mutex); - - if (!space) { - space = UT_LIST_GET_FIRST(fil_system.space_list); - } else { - ut_a(space->referenced()); - - /* Move on to the next fil_space_t */ - space->release(); - space = UT_LIST_GET_NEXT(space_list, space); - } - - /* Skip spaces that are being created by - fil_ibd_create(), or dropped, or !tablespace. */ - while (space != NULL - && (UT_LIST_GET_LEN(space->chain) == 0 - || space->is_stopping() - || space->purpose != FIL_TYPE_TABLESPACE)) { - space = UT_LIST_GET_NEXT(space_list, space); - } - - if (space != NULL) { - space->acquire(); - } - - mutex_exit(&fil_system.mutex); - - return(space); -} - -/** -Remove space from key rotation list if there are no more -pending operations. -@param[in,out] space Tablespace */ -static -void -fil_space_remove_from_keyrotation(fil_space_t* space) -{ - ut_ad(mutex_own(&fil_system.mutex)); - ut_ad(space); - - if (!space->referenced() && space->is_in_rotation_list) { - space->is_in_rotation_list = false; - ut_a(!fil_system.rotation_list.empty()); - fil_system.rotation_list.remove(*space); - } -} - - -/** Return the next fil_space_t from key rotation list. -Once started, the caller must keep calling this until it returns NULL. -fil_space_t::acquire() and fil_space_t::release() are invoked here which -blocks a concurrent operation from dropping the tablespace. -@param[in] prev_space Pointer to the previous fil_space_t. -If NULL, use the first fil_space_t on fil_system.space_list. -@param[in] recheck recheck of the tablespace is needed or - still encryption thread does write page0 for it -@param[in] key_version key version of the key state thread -@return pointer to the next fil_space_t. -@retval NULL if this was the last */ -fil_space_t *fil_system_t::keyrotate_next(fil_space_t *prev_space, - bool recheck, uint key_version) -{ - mutex_enter(&fil_system.mutex); - - /* If one of the encryption threads already started the encryption - of the table then don't remove the unencrypted spaces from rotation list - - If there is a change in innodb_encrypt_tables variables value then - don't remove the last processed tablespace from the rotation list. */ - const bool remove= (!recheck || prev_space->crypt_data) && - !key_version == !srv_encrypt_tables; - sized_ilist<fil_space_t, rotation_list_tag_t>::iterator it= - prev_space ? prev_space : fil_system.rotation_list.end(); - - if (it == fil_system.rotation_list.end()) - it= fil_system.rotation_list.begin(); - else - { - /* Move on to the next fil_space_t */ - prev_space->release(); - - ++it; - - while (it != fil_system.rotation_list.end() && - (UT_LIST_GET_LEN(it->chain) == 0 || it->is_stopping())) - ++it; - - if (remove) - fil_space_remove_from_keyrotation(prev_space); - } - - fil_space_t *space= it == fil_system.rotation_list.end() ? NULL : &*it; - - if (space) - space->acquire(); - - mutex_exit(&fil_system.mutex); - return space; -} - /** Determine the block size of the data file. @param[in] space tablespace @param[in] offset page number diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h index f86da088308..fa2db4dfa47 100644 --- a/storage/innobase/include/fil0fil.h +++ b/storage/innobase/include/fil0fil.h @@ -662,24 +662,15 @@ public: @retval NULL if the tablespace does not exist or cannot be read */ fil_space_t* read_page0(ulint id); - /** Return the next fil_space_t from key rotation list. - Once started, the caller must keep calling this until it returns NULL. - fil_space_acquire() and fil_space_t::release() are invoked here, which - blocks a concurrent operation from dropping the tablespace. - @param[in] prev_space Previous tablespace or NULL to start - from beginning of fil_system->rotation - list - @param[in] recheck recheck of the tablespace is needed or - still encryption thread does write page0 - for it - @param[in] key_version key version of the key state thread - If NULL, use the first fil_space_t on fil_system->space_list. - @return pointer to the next fil_space_t. - @retval NULL if this was the last */ - fil_space_t* keyrotate_next( - fil_space_t* prev_space, - bool remove, - uint key_version); + /** Return the next tablespace from rotation_list. + @param space previous tablespace (NULL to start from the start) + @param recheck whether the removal condition needs to be rechecked after + the encryption parameters were changed + @param encrypt expected state of innodb_encrypt_tables + @return the next tablespace to process (n_pending_ops incremented) + @retval NULL if this was the last */ + inline fil_space_t* keyrotate_next(fil_space_t *space, bool recheck, + bool encrypt); }; /** The tablespace memory cache. */ @@ -846,33 +837,6 @@ when it could be dropped concurrently. fil_space_t* fil_space_acquire_for_io(ulint id); -/** Return the next fil_space_t. -Once started, the caller must keep calling this until it returns NULL. -fil_space_acquire() and fil_space_t::release() are invoked here which -blocks a concurrent operation from dropping the tablespace. -@param[in,out] prev_space Pointer to the previous fil_space_t. -If NULL, use the first fil_space_t on fil_system.space_list. -@return pointer to the next fil_space_t. -@retval NULL if this was the last */ -fil_space_t* -fil_space_next( - fil_space_t* prev_space) - MY_ATTRIBUTE((warn_unused_result)); - -/** Return the next fil_space_t from key rotation list. -Once started, the caller must keep calling this until it returns NULL. -fil_space_acquire() and fil_space_t::release() are invoked here which -blocks a concurrent operation from dropping the tablespace. -@param[in,out] prev_space Pointer to the previous fil_space_t. -If NULL, use the first fil_space_t on fil_system.space_list. -@param[in] remove Whether to remove the previous tablespace from - the rotation list -@return pointer to the next fil_space_t. -@retval NULL if this was the last*/ -fil_space_t* -fil_space_keyrotate_next(fil_space_t* prev_space, bool remove) - MY_ATTRIBUTE((warn_unused_result)); - /********************************************************//** Creates the database directory for a table if it does not exist yet. */ void diff --git a/storage/innobase/include/sync0types.h b/storage/innobase/include/sync0types.h index 8fcb1abb0e2..d08ca94d787 100644 --- a/storage/innobase/include/sync0types.h +++ b/storage/innobase/include/sync0types.h @@ -364,7 +364,6 @@ enum latch_id_t { LATCH_ID_SCRUB_STAT_MUTEX, LATCH_ID_DEFRAGMENT_MUTEX, LATCH_ID_BTR_DEFRAGMENT_MUTEX, - LATCH_ID_FIL_CRYPT_MUTEX, LATCH_ID_FIL_CRYPT_STAT_MUTEX, LATCH_ID_FIL_CRYPT_DATA_MUTEX, LATCH_ID_FIL_CRYPT_THREADS_MUTEX, diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc index 1c7407a0c23..138104ee2c5 100644 --- a/storage/innobase/lock/lock0lock.cc +++ b/storage/innobase/lock/lock0lock.cc @@ -746,7 +746,7 @@ lock_rec_has_to_wait( /* if BF thread is locking and has conflict with another BF thread, we need to look at trx ordering and lock types */ if (wsrep_thd_is_BF(trx->mysql_thd, FALSE) - && wsrep_thd_is_BF(lock2->trx->mysql_thd, TRUE)) { + && wsrep_thd_is_BF(lock2->trx->mysql_thd, FALSE)) { mtr_t mtr; if (UNIV_UNLIKELY(wsrep_debug)) { @@ -1094,7 +1094,7 @@ wsrep_kill_victim( if (!trx->is_wsrep()) return; my_bool bf_this = wsrep_thd_is_BF(trx->mysql_thd, FALSE); - my_bool bf_other = wsrep_thd_is_BF(lock->trx->mysql_thd, TRUE); + my_bool bf_other = wsrep_thd_is_BF(lock->trx->mysql_thd, FALSE); mtr_t mtr; if ((bf_this && !bf_other) || @@ -1422,7 +1422,7 @@ lock_rec_create_low( lock_t *hash = (lock_t *)c_lock->hash; lock_t *prev = NULL; - while (hash && wsrep_thd_is_BF(hash->trx->mysql_thd, TRUE) + while (hash && wsrep_thd_is_BF(hash->trx->mysql_thd, FALSE) && wsrep_trx_order_before(hash->trx->mysql_thd, trx->mysql_thd)) { prev = hash; @@ -1821,11 +1821,9 @@ lock_rec_add_to_queue( = lock_rec_other_has_expl_req( mode, block, false, heap_no, trx); #ifdef WITH_WSREP - //ut_a(!other_lock || (wsrep_thd_is_BF(trx->mysql_thd, FALSE) && - // wsrep_thd_is_BF(other_lock->trx->mysql_thd, TRUE))); if (other_lock && trx->is_wsrep() && !wsrep_thd_is_BF(trx->mysql_thd, FALSE) && - !wsrep_thd_is_BF(other_lock->trx->mysql_thd, TRUE)) { + !wsrep_thd_is_BF(other_lock->trx->mysql_thd, FALSE)) { ib::info() << "WSREP BF lock conflict for my lock:\n BF:" << ((wsrep_thd_is_BF(trx->mysql_thd, FALSE)) ? "BF" : "normal") << " exec: " << @@ -2034,6 +2032,7 @@ lock_rec_has_to_wait_in_queue( ulint bit_offset; hash_table_t* hash; + ut_ad(wait_lock); ut_ad(lock_mutex_own()); ut_ad(lock_get_wait(wait_lock)); ut_ad(lock_get_type_low(wait_lock) == LOCK_REC); @@ -2048,9 +2047,11 @@ lock_rec_has_to_wait_in_queue( hash = lock_hash_get(wait_lock->type_mode); for (lock = lock_rec_get_first_on_page_addr(hash, space, page_no); +#ifdef WITH_WSREP + lock && +#endif lock != wait_lock; lock = lock_rec_get_next_on_page_const(lock)) { - const byte* p = (const byte*) &lock[1]; if (heap_no < lock_rec_get_n_bits(lock) @@ -2058,7 +2059,8 @@ lock_rec_has_to_wait_in_queue( && lock_has_to_wait(wait_lock, lock)) { #ifdef WITH_WSREP if (wsrep_thd_is_BF(wait_lock->trx->mysql_thd, FALSE) && - wsrep_thd_is_BF(lock->trx->mysql_thd, TRUE)) { + wsrep_thd_is_BF(lock->trx->mysql_thd, FALSE)) { + if (UNIV_UNLIKELY(wsrep_debug)) { mtr_t mtr; ib::info() << "WSREP: waiting BF trx: " << ib::hex(wait_lock->trx->id) @@ -6705,7 +6707,7 @@ DeadlockChecker::select_victim() const /* The joining transaction is 'smaller', choose it as the victim and roll it back. */ #ifdef WITH_WSREP - if (wsrep_thd_is_BF(m_start->mysql_thd, TRUE)) { + if (wsrep_thd_is_BF(m_start->mysql_thd, FALSE)) { return(m_wait_lock->trx); } #endif /* WITH_WSREP */ @@ -6713,7 +6715,7 @@ DeadlockChecker::select_victim() const } #ifdef WITH_WSREP - if (wsrep_thd_is_BF(m_wait_lock->trx->mysql_thd, TRUE)) { + if (wsrep_thd_is_BF(m_wait_lock->trx->mysql_thd, FALSE)) { return(m_start); } #endif /* WITH_WSREP */ diff --git a/storage/innobase/sync/sync0debug.cc b/storage/innobase/sync/sync0debug.cc index d1ebcd52df3..2a11bf65637 100644 --- a/storage/innobase/sync/sync0debug.cc +++ b/storage/innobase/sync/sync0debug.cc @@ -1491,8 +1491,6 @@ sync_latch_meta_init() PFS_NOT_INSTRUMENTED); LATCH_ADD_MUTEX(BTR_DEFRAGMENT_MUTEX, SYNC_NO_ORDER_CHECK, PFS_NOT_INSTRUMENTED); - LATCH_ADD_MUTEX(FIL_CRYPT_MUTEX, SYNC_NO_ORDER_CHECK, - PFS_NOT_INSTRUMENTED); LATCH_ADD_MUTEX(FIL_CRYPT_STAT_MUTEX, SYNC_NO_ORDER_CHECK, PFS_NOT_INSTRUMENTED); LATCH_ADD_MUTEX(FIL_CRYPT_DATA_MUTEX, SYNC_NO_ORDER_CHECK, diff --git a/strings/decimal.c b/strings/decimal.c index 59e60e0a328..9dae3d987f2 100644 --- a/strings/decimal.c +++ b/strings/decimal.c @@ -812,6 +812,24 @@ internal_str2dec(const char *from, decimal_t *to, char **end, my_bool fixed) while (s < end_of_string && my_isdigit(&my_charset_latin1, *s)) s++; intg= (int) (s-s1); + /* + If the integer part is long enough and it has multiple leading zeros, + let's trim them, so this expression can return 1 without overflowing: + CAST(CONCAT(REPEAT('0',90),'1') AS DECIMAL(10)) + */ + if (intg > DIG_PER_DEC1 && s1[0] == '0' && s1[1] == '0') + { + /* + Keep at least one digit, to avoid an empty string. + So we trim '0000' to '0' rather than to ''. + Otherwise the below code (converting digits to to->buf) + would fail on a fatal error. + */ + const char *iend= s - 1; + for ( ; s1 < iend && *s1 == '0'; s1++) + { } + intg= (int) (s-s1); + } if (s < end_of_string && *s=='.') { endp= s+1; |