diff options
56 files changed, 1186 insertions, 114 deletions
diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index ff6422d15da..e9640fd4365 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -1,5 +1,5 @@ # Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved. -# Copyright (c) 2008, 2018, MariaDB Corporation +# Copyright (c) 2008, 2019, 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 diff --git a/man/mysql_install_db.1 b/man/mysql_install_db.1 index ea54477f516..dcafb730860 100644 --- a/man/mysql_install_db.1 +++ b/man/mysql_install_db.1 @@ -1,6 +1,6 @@ '\" t .\" -.TH "\FBMYSQL_INSTALL_DB\" "1" "3 April 2017" "MariaDB 10\&.2" "MariaDB Database System" +.TH "\FBMYSQL_INSTALL_DB\FR" "1" "4 April 2019" "MariaDB 10\&.2" "MariaDB Database System" .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- @@ -198,6 +198,21 @@ Must be given as first option\&. .sp -1 .IP \(bu 2.3 .\} +.\" mysql_install_db: defaults-group-suffix option +.\" defaults-group-suffix option: mysql_install_db +\fB\-\-defaults\-group\-suffix=\fR\fB\fIname\fR\fR +.sp +In addition to the given groups, also read groups with this suffix\&. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} .\" mysql_install_db: force option .\" force option: mysql_install_db \fB\-\-force\fR @@ -354,7 +369,7 @@ For internal use\&. This option is used for creating Windows distributions\&. .SH "COPYRIGHT" .br .PP -Copyright 2007-2008 MySQL AB, 2008-2010 Sun Microsystems, Inc., 2010-2015 MariaDB Foundation +Copyright 2007-2008 MySQL AB, 2008-2010 Sun Microsystems, Inc., 2010-2019 MariaDB Foundation .PP This documentation is free software; you can redistribute it and/or modify it only under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. .PP diff --git a/mysql-test/r/gis-precise.result b/mysql-test/r/gis-precise.result index 56c9472bd73..d5e1751d800 100644 --- a/mysql-test/r/gis-precise.result +++ b/mysql-test/r/gis-precise.result @@ -505,6 +505,10 @@ GEOMETRYFROMTEXT('POINT(4599 60359)'), ) as relate_res; relate_res 0 +prepare s from 'do st_convexhull(st_aswkb(multipoint(point(-11702,15179),point(-5031,27960),point(-30557,11158),point(-27804,30314))))'; +execute s; +execute s; +deallocate prepare s; with cte1 as( select (st_symdifference(point(1,1),point(1,1))) as a1 ), cte2 as(select 1 as a2) select 1 from cte1 where cte1.a1 < '1'; 1 1 diff --git a/mysql-test/r/olap.result b/mysql-test/r/olap.result index 24140583d13..50c40fd1b34 100644 --- a/mysql-test/r/olap.result +++ b/mysql-test/r/olap.result @@ -786,5 +786,61 @@ t COUNT(*) 12:12:13 1 DROP TABLE t1; # +# MDEV-17830 Server crashes in Item_null_result::field_type upon SELECT with CHARSET(date) and ROLLUP +# +# Note, different MariaDB versions can return different results +# in the two rows (such as "latin1" vs "binary"). This is wrong. +# Both lines should return equal values. +# The point in this test is to make sure it does not crash. +# As this is a minor issue, bad result will be fixed +# in a later version, presumably in 10.4. +CREATE TABLE t (d DATE) ENGINE=MyISAM; +INSERT INTO t VALUES ('2018-12-12'); +SELECT CHARSET(d) AS f FROM t GROUP BY d WITH ROLLUP; +f +binary +binary +DROP TABLE t; +# +# MDEV-14041 Server crashes in String::length on queries with functions and ROLLUP +# +CREATE TABLE t1 (i INT); +INSERT INTO t1 VALUES (1),(2); +SELECT GET_LOCK( 'foo', 0 ); +GET_LOCK( 'foo', 0 ) +1 +SELECT HEX( RELEASE_LOCK( 'foo' ) ) AS f FROM t1 GROUP BY f WITH ROLLUP; +f +NULL +1 +NULL +DROP TABLE t1; +CREATE TABLE t1 (i INT); +INSERT INTO t1 VALUES (1),(2); +SELECT i FROM t1 GROUP BY i WITH ROLLUP +UNION ALL +SELECT ELT( FOUND_ROWS(), 1 ) f FROM t1 GROUP BY f WITH ROLLUP; +i +1 +2 +NULL +NULL +NULL +DROP TABLE t1; +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1),(2); +SELECT a FROM t1 GROUP BY NULLIF( CONVERT('', DATE), '2015-10-15' ) WITH ROLLUP; +a +1 +1 +Warnings: +Warning 1292 Incorrect datetime value: '' +Warning 1292 Incorrect datetime value: '' +Warning 1292 Incorrect datetime value: '' +Warning 1292 Incorrect datetime value: '' +Warning 1292 Incorrect datetime value: '' +Warning 1292 Incorrect datetime value: '' +DROP TABLE t1; +# # End of 10.1 tests # diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 5dc3c2584a2..d13af4437f3 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -7643,6 +7643,22 @@ c1 c2 count(c3) 2012-03-01 02:00:00 3 1 DROP PROCEDURE p1; # End of 5.5 test +CREATE PROCEDURE sp() ALTER TABLE non_existing_table OPTIMIZE PARTITION p0; +CALL sp; +Table Op Msg_type Msg_text +test.non_existing_table optimize Error Table 'test.non_existing_table' doesn't exist +test.non_existing_table optimize status Operation failed +SELECT 1; +1 +1 +DROP PROCEDURE sp; +CREATE PROCEDURE sp() SHOW USER_STATISTICS; +CALL sp; +User Total_connections Concurrent_connections Connected_time Busy_time Cpu_time Bytes_received Bytes_sent Binlog_bytes_written Rows_read Rows_sent Rows_deleted Rows_inserted Rows_updated Select_commands Update_commands Other_commands Commit_transactions Rollback_transactions Denied_connections Lost_connections Access_denied Empty_queries Total_ssl_connections Max_statement_time_exceeded +SELECT 1; +1 +1 +DROP PROCEDURE sp; # # Bug#12663165 SP DEAD CODE REMOVAL DOESN'T UNDERSTAND CONTINUE HANDLERS # diff --git a/mysql-test/r/stat_tables.result b/mysql-test/r/stat_tables.result index be868e55e84..7fd0b5902ec 100644 --- a/mysql-test/r/stat_tables.result +++ b/mysql-test/r/stat_tables.result @@ -625,6 +625,76 @@ MAX(pk) NULL DROP TABLE t1; # +# MDEV-17605: SHOW INDEXES with use_stat_tables='preferably' +# +set use_stat_tables='preferably'; +CREATE DATABASE dbt3_s001; +use dbt3_s001; +set @save_optimizer_switch=@@optimizer_switch; +set optimizer_switch='extended_keys=off'; +select * from mysql.table_stats; +db_name table_name cardinality +dbt3_s001 lineitem 6005 +select * from mysql.index_stats; +db_name table_name index_name prefix_arity avg_frequency +dbt3_s001 lineitem PRIMARY 1 4.0033 +dbt3_s001 lineitem PRIMARY 2 1.0000 +dbt3_s001 lineitem i_l_shipdate 1 2.6500 +dbt3_s001 lineitem i_l_suppkey_partkey 1 30.0250 +dbt3_s001 lineitem i_l_suppkey_partkey 2 8.5786 +dbt3_s001 lineitem i_l_partkey 1 30.0250 +dbt3_s001 lineitem i_l_suppkey 1 600.5000 +dbt3_s001 lineitem i_l_receiptdate 1 2.6477 +dbt3_s001 lineitem i_l_orderkey 1 4.0033 +dbt3_s001 lineitem i_l_orderkey_quantity 1 4.0033 +dbt3_s001 lineitem i_l_orderkey_quantity 2 1.0404 +dbt3_s001 lineitem i_l_commitdate 1 2.7160 +SHOW INDEXES FROM lineitem; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +lineitem 0 PRIMARY 1 l_orderkey A 1500 NULL NULL BTREE +lineitem 0 PRIMARY 2 l_linenumber A 6005 NULL NULL BTREE +lineitem 1 i_l_shipdate 1 l_shipDATE A 2266 NULL NULL YES BTREE +lineitem 1 i_l_suppkey_partkey 1 l_partkey A 200 NULL NULL YES BTREE +lineitem 1 i_l_suppkey_partkey 2 l_suppkey A 699 NULL NULL YES BTREE +lineitem 1 i_l_partkey 1 l_partkey A 200 NULL NULL YES BTREE +lineitem 1 i_l_suppkey 1 l_suppkey A 10 NULL NULL YES BTREE +lineitem 1 i_l_receiptdate 1 l_receiptDATE A 2268 NULL NULL YES BTREE +lineitem 1 i_l_orderkey 1 l_orderkey A 1500 NULL NULL BTREE +lineitem 1 i_l_orderkey_quantity 1 l_orderkey A 1500 NULL NULL BTREE +lineitem 1 i_l_orderkey_quantity 2 l_quantity A 5771 NULL NULL YES BTREE +lineitem 1 i_l_commitdate 1 l_commitDATE A 2210 NULL NULL YES BTREE +SELECT * FROM INFORMATION_SCHEMA.STATISTICS WHERE table_name='lineitem'; +TABLE_CATALOG TABLE_SCHEMA TABLE_NAME NON_UNIQUE INDEX_SCHEMA INDEX_NAME SEQ_IN_INDEX COLUMN_NAME COLLATION CARDINALITY SUB_PART PACKED NULLABLE INDEX_TYPE COMMENT INDEX_COMMENT +def dbt3_s001 lineitem 0 dbt3_s001 PRIMARY 1 l_orderkey A 1500 NULL NULL BTREE +def dbt3_s001 lineitem 0 dbt3_s001 PRIMARY 2 l_linenumber A 6005 NULL NULL BTREE +def dbt3_s001 lineitem 1 dbt3_s001 i_l_shipdate 1 l_shipDATE A 2266 NULL NULL YES BTREE +def dbt3_s001 lineitem 1 dbt3_s001 i_l_suppkey_partkey 1 l_partkey A 200 NULL NULL YES BTREE +def dbt3_s001 lineitem 1 dbt3_s001 i_l_suppkey_partkey 2 l_suppkey A 699 NULL NULL YES BTREE +def dbt3_s001 lineitem 1 dbt3_s001 i_l_partkey 1 l_partkey A 200 NULL NULL YES BTREE +def dbt3_s001 lineitem 1 dbt3_s001 i_l_suppkey 1 l_suppkey A 10 NULL NULL YES BTREE +def dbt3_s001 lineitem 1 dbt3_s001 i_l_receiptdate 1 l_receiptDATE A 2268 NULL NULL YES BTREE +def dbt3_s001 lineitem 1 dbt3_s001 i_l_orderkey 1 l_orderkey A 1500 NULL NULL BTREE +def dbt3_s001 lineitem 1 dbt3_s001 i_l_orderkey_quantity 1 l_orderkey A 1500 NULL NULL BTREE +def dbt3_s001 lineitem 1 dbt3_s001 i_l_orderkey_quantity 2 l_quantity A 5771 NULL NULL YES BTREE +def dbt3_s001 lineitem 1 dbt3_s001 i_l_commitdate 1 l_commitDATE A 2210 NULL NULL YES BTREE +SELECT +COUNT(DISTINCT l_orderkey), COUNT(DISTINCT l_orderkey,l_linenumber), +COUNT(DISTINCT l_shipDATE), +COUNT(DISTINCT l_partkey), COUNT(DISTINCT l_partkey,l_suppkey), +COUNT(DISTINCT l_suppkey), COUNT(DISTINCT l_receiptDATE), +COUNT(DISTINCT l_orderkey, l_quantity), COUNT(DISTINCT l_commitDATE) +FROM lineitem; +COUNT(DISTINCT l_orderkey) COUNT(DISTINCT l_orderkey,l_linenumber) COUNT(DISTINCT l_shipDATE) COUNT(DISTINCT l_partkey) COUNT(DISTINCT l_partkey,l_suppkey) COUNT(DISTINCT l_suppkey) COUNT(DISTINCT l_receiptDATE) COUNT(DISTINCT l_orderkey, l_quantity) COUNT(DISTINCT l_commitDATE) +1500 6005 2266 200 700 10 2268 5772 2211 +set optimizer_switch=@save_optimizer_switch; +DROP DATABASE dbt3_s001; +USE test; +delete from mysql.table_stats; +delete from mysql.column_stats; +delete from mysql.index_stats; +set @save_optimizer_switch=@@optimizer_switch; +set use_stat_tables=@save_use_stat_tables; +# # MDEV-18899: Server crashes in Field::set_warning_truncated_wrong_value # set names utf8; diff --git a/mysql-test/r/stat_tables_innodb.result b/mysql-test/r/stat_tables_innodb.result index 86088490871..2bc69c24104 100644 --- a/mysql-test/r/stat_tables_innodb.result +++ b/mysql-test/r/stat_tables_innodb.result @@ -652,6 +652,76 @@ MAX(pk) NULL DROP TABLE t1; # +# MDEV-17605: SHOW INDEXES with use_stat_tables='preferably' +# +set use_stat_tables='preferably'; +CREATE DATABASE dbt3_s001; +use dbt3_s001; +set @save_optimizer_switch=@@optimizer_switch; +set optimizer_switch='extended_keys=off'; +select * from mysql.table_stats; +db_name table_name cardinality +dbt3_s001 lineitem 6005 +select * from mysql.index_stats; +db_name table_name index_name prefix_arity avg_frequency +dbt3_s001 lineitem PRIMARY 1 4.0033 +dbt3_s001 lineitem PRIMARY 2 1.0000 +dbt3_s001 lineitem i_l_shipdate 1 2.6500 +dbt3_s001 lineitem i_l_suppkey_partkey 1 30.0250 +dbt3_s001 lineitem i_l_suppkey_partkey 2 8.5786 +dbt3_s001 lineitem i_l_partkey 1 30.0250 +dbt3_s001 lineitem i_l_suppkey 1 600.5000 +dbt3_s001 lineitem i_l_receiptdate 1 2.6477 +dbt3_s001 lineitem i_l_orderkey 1 4.0033 +dbt3_s001 lineitem i_l_orderkey_quantity 1 4.0033 +dbt3_s001 lineitem i_l_orderkey_quantity 2 1.0404 +dbt3_s001 lineitem i_l_commitdate 1 2.7160 +SHOW INDEXES FROM lineitem; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +lineitem 0 PRIMARY 1 l_orderkey A 1500 NULL NULL BTREE +lineitem 0 PRIMARY 2 l_linenumber A 6005 NULL NULL BTREE +lineitem 1 i_l_shipdate 1 l_shipDATE A 2266 NULL NULL YES BTREE +lineitem 1 i_l_suppkey_partkey 1 l_partkey A 200 NULL NULL YES BTREE +lineitem 1 i_l_suppkey_partkey 2 l_suppkey A 699 NULL NULL YES BTREE +lineitem 1 i_l_partkey 1 l_partkey A 200 NULL NULL YES BTREE +lineitem 1 i_l_suppkey 1 l_suppkey A 10 NULL NULL YES BTREE +lineitem 1 i_l_receiptdate 1 l_receiptDATE A 2268 NULL NULL YES BTREE +lineitem 1 i_l_orderkey 1 l_orderkey A 1500 NULL NULL BTREE +lineitem 1 i_l_orderkey_quantity 1 l_orderkey A 1500 NULL NULL BTREE +lineitem 1 i_l_orderkey_quantity 2 l_quantity A 5771 NULL NULL YES BTREE +lineitem 1 i_l_commitdate 1 l_commitDATE A 2210 NULL NULL YES BTREE +SELECT * FROM INFORMATION_SCHEMA.STATISTICS WHERE table_name='lineitem'; +TABLE_CATALOG TABLE_SCHEMA TABLE_NAME NON_UNIQUE INDEX_SCHEMA INDEX_NAME SEQ_IN_INDEX COLUMN_NAME COLLATION CARDINALITY SUB_PART PACKED NULLABLE INDEX_TYPE COMMENT INDEX_COMMENT +def dbt3_s001 lineitem 0 dbt3_s001 PRIMARY 1 l_orderkey A 1500 NULL NULL BTREE +def dbt3_s001 lineitem 0 dbt3_s001 PRIMARY 2 l_linenumber A 6005 NULL NULL BTREE +def dbt3_s001 lineitem 1 dbt3_s001 i_l_shipdate 1 l_shipDATE A 2266 NULL NULL YES BTREE +def dbt3_s001 lineitem 1 dbt3_s001 i_l_suppkey_partkey 1 l_partkey A 200 NULL NULL YES BTREE +def dbt3_s001 lineitem 1 dbt3_s001 i_l_suppkey_partkey 2 l_suppkey A 699 NULL NULL YES BTREE +def dbt3_s001 lineitem 1 dbt3_s001 i_l_partkey 1 l_partkey A 200 NULL NULL YES BTREE +def dbt3_s001 lineitem 1 dbt3_s001 i_l_suppkey 1 l_suppkey A 10 NULL NULL YES BTREE +def dbt3_s001 lineitem 1 dbt3_s001 i_l_receiptdate 1 l_receiptDATE A 2268 NULL NULL YES BTREE +def dbt3_s001 lineitem 1 dbt3_s001 i_l_orderkey 1 l_orderkey A 1500 NULL NULL BTREE +def dbt3_s001 lineitem 1 dbt3_s001 i_l_orderkey_quantity 1 l_orderkey A 1500 NULL NULL BTREE +def dbt3_s001 lineitem 1 dbt3_s001 i_l_orderkey_quantity 2 l_quantity A 5771 NULL NULL YES BTREE +def dbt3_s001 lineitem 1 dbt3_s001 i_l_commitdate 1 l_commitDATE A 2210 NULL NULL YES BTREE +SELECT +COUNT(DISTINCT l_orderkey), COUNT(DISTINCT l_orderkey,l_linenumber), +COUNT(DISTINCT l_shipDATE), +COUNT(DISTINCT l_partkey), COUNT(DISTINCT l_partkey,l_suppkey), +COUNT(DISTINCT l_suppkey), COUNT(DISTINCT l_receiptDATE), +COUNT(DISTINCT l_orderkey, l_quantity), COUNT(DISTINCT l_commitDATE) +FROM lineitem; +COUNT(DISTINCT l_orderkey) COUNT(DISTINCT l_orderkey,l_linenumber) COUNT(DISTINCT l_shipDATE) COUNT(DISTINCT l_partkey) COUNT(DISTINCT l_partkey,l_suppkey) COUNT(DISTINCT l_suppkey) COUNT(DISTINCT l_receiptDATE) COUNT(DISTINCT l_orderkey, l_quantity) COUNT(DISTINCT l_commitDATE) +1500 6005 2266 200 700 10 2268 5772 2211 +set optimizer_switch=@save_optimizer_switch; +DROP DATABASE dbt3_s001; +USE test; +delete from mysql.table_stats; +delete from mysql.column_stats; +delete from mysql.index_stats; +set @save_optimizer_switch=@@optimizer_switch; +set use_stat_tables=@save_use_stat_tables; +# # MDEV-18899: Server crashes in Field::set_warning_truncated_wrong_value # set names utf8; diff --git a/mysql-test/r/type_date.result b/mysql-test/r/type_date.result index 0ac62f22d10..42e5a26e8c1 100644 --- a/mysql-test/r/type_date.result +++ b/mysql-test/r/type_date.result @@ -854,5 +854,30 @@ d COUNT(*) NULL 2 DROP TABLE t1; # +# MDEV-17299 Assertion `maybe_null' failed in make_sortkey +# +CREATE TABLE t1 (pk int NOT NULL, d1 date, d2 date NOT NULL); +INSERT INTO t1 values (1,'2018-06-22','2018-06-22'),(2,'2018-07-11','2018-07-11'); +CREATE VIEW v1 AS SELECT * FROM t1; +SELECT group_concat(d1/(CASE 'b' WHEN 'j' THEN 'c' END)) +FROM v1 GROUP BY greatest(pk, 0, d2); +group_concat(d1/(CASE 'b' WHEN 'j' THEN 'c' END)) +NULL +Warnings: +Warning 1292 Incorrect datetime value: '1' for column `test`.`t1`.`pk` at row 1 +Warning 1292 Incorrect datetime value: '2' for column `test`.`t1`.`pk` at row 1 +Warning 1292 Incorrect datetime value: '1' for column `test`.`t1`.`pk` at row 1 +Warning 1292 Incorrect datetime value: '1' for column `test`.`t1`.`pk` at row 1 +Warning 1292 Incorrect datetime value: '2' for column `test`.`t1`.`pk` at row 2 +CREATE TABLE t2 AS SELECT greatest(pk, 0, d2) AS c1 FROM t1 LIMIT 0; +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `c1` date DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TABLE t2; +DROP VIEW v1; +DROP TABLE t1; +# # End of 10.1 tests # diff --git a/mysql-test/r/update_innodb.result b/mysql-test/r/update_innodb.result index 0a85c6dab3e..695561122f0 100644 --- a/mysql-test/r/update_innodb.result +++ b/mysql-test/r/update_innodb.result @@ -65,3 +65,27 @@ SELECT * FROM t1; a_id b_id c_id 1 NULL NULL drop table t1,t2; +# +# MDEV-18300: ASAN error in Field_blob::get_key_image upon UPDATE with subquery +# +set @save_optimizer_use_condition_selectivity= @@optimizer_use_condition_selectivity; +set @save_use_stat_tables= @@use_stat_tables; +set use_stat_tables=preferably; +set optimizer_use_condition_selectivity=4; +CREATE TABLE t1 (a INT, b CHAR(8)) ENGINE=InnoDB; +insert into t1 values (1,'foo'),(2, 'abc'); +CREATE TABLE t2 (c CHAR(8), d BLOB) ENGINE=InnoDB; +insert into t2 values ('abc', 'foo'),('edf', 'food'); +ANALYZE TABLE t1,t2; +UPDATE t1 SET a = 1 WHERE b = ( SELECT c FROM t2 WHERE d = 'foo' ); +SELECT * FROM t1; +a b +1 foo +1 abc +DROP TABLE t1, t2; +create table t1 (a int not null, b int, c int) engine=InnoDB; +create table t2 (d int, e int) engine=InnoDB; +update t1, t2 set a=NULL, b=2, c=NULL where b=d and e=200; +drop table t1,t2; +set @@optimizer_use_condition_selectivity= @save_optimizer_use_condition_selectivity; +set @@use_stat_tables= @save_use_stat_tables; diff --git a/mysql-test/suite/archive/archive_eits.result b/mysql-test/suite/archive/archive_eits.result new file mode 100644 index 00000000000..e077c2e4954 --- /dev/null +++ b/mysql-test/suite/archive/archive_eits.result @@ -0,0 +1,24 @@ +drop table if exists t1; +# +# MDEV-17297: stats.records=0 for a table of Archive engine when it has rows, when we run ANALYZE command +# +CREATE TABLE t1 (fid INTEGER PRIMARY KEY AUTO_INCREMENT, g POINT)engine=archive; +INSERT INTO t1 VALUES +(101, PointFromText('POINT(10 10)')), +(102, PointFromText('POINT(20 10)')), +(103, PointFromText('POINT(20 20)')), +(104, PointFromWKB(AsWKB(PointFromText('POINT(10 20)')))); +set @tmp1= @@optimizer_use_condition_selectivity; +set @tmp2= @@use_stat_tables; +set optimizer_use_condition_selectivity=4; +set use_stat_tables=PREFERABLY; +ANALYZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze note The storage engine for the table doesn't support analyze +select * from mysql.table_stats where table_name='t1' and db_name=database(); +db_name table_name cardinality +test t1 4 +drop table t1; +set optimizer_use_condition_selectivity=@tmp1; +set use_stat_tables=@tmp2; diff --git a/mysql-test/suite/archive/archive_eits.test b/mysql-test/suite/archive/archive_eits.test new file mode 100644 index 00000000000..04c4ccdb709 --- /dev/null +++ b/mysql-test/suite/archive/archive_eits.test @@ -0,0 +1,32 @@ +-- source include/have_archive.inc + +--disable_warnings +drop table if exists t1; +--enable_warnings + +--echo # +--echo # MDEV-17297: stats.records=0 for a table of Archive engine when it has rows, when we run ANALYZE command +--echo # + +CREATE TABLE t1 (fid INTEGER PRIMARY KEY AUTO_INCREMENT, g POINT)engine=archive; +INSERT INTO t1 VALUES +(101, PointFromText('POINT(10 10)')), +(102, PointFromText('POINT(20 10)')), +(103, PointFromText('POINT(20 20)')), +(104, PointFromWKB(AsWKB(PointFromText('POINT(10 20)')))); + +set @tmp1= @@optimizer_use_condition_selectivity; +set @tmp2= @@use_stat_tables; + +set optimizer_use_condition_selectivity=4; +set use_stat_tables=PREFERABLY; +ANALYZE TABLE t1; + +select * from mysql.table_stats where table_name='t1' and db_name=database(); + +drop table t1; + +set optimizer_use_condition_selectivity=@tmp1; +set use_stat_tables=@tmp2; + + diff --git a/mysql-test/suite/innodb/r/foreign_key.result b/mysql-test/suite/innodb/r/foreign_key.result index e2306d5a28f..6b4174c72e6 100644 --- a/mysql-test/suite/innodb/r/foreign_key.result +++ b/mysql-test/suite/innodb/r/foreign_key.result @@ -262,10 +262,18 @@ ALTER IGNORE TABLE t1 ADD FOREIGN KEY (a) REFERENCES t2 (b); ERROR HY000: Can't create table `test`.`t1` (errno: 150 "Foreign key constraint is incorrectly formed") SHOW WARNINGS; Level Code Message -Warning 150 Alter table test/#sql-temporary with foreign key constraint failed. Referenced table `test`.`t2` not found in the data dictionary near 'FOREIGN KEY (a) REFERENCES t2 (b)'. +Warning 150 Alter table `test`.`t1` with foreign key constraint failed. Referenced table `test`.`t2` not found in the data dictionary near 'FOREIGN KEY (a) REFERENCES t2 (b)'. Error 1005 Can't create table `test`.`t1` (errno: 150 "Foreign key constraint is incorrectly formed") Warning 1215 Cannot add foreign key constraint DROP TABLE t1; +# +# MDEV-18139 ALTER IGNORE ... ADD FOREIGN KEY causes bogus error +# +CREATE TABLE t1 (f1 INT, f2 INT, f3 INT, KEY(f1)) ENGINE=InnoDB; +CREATE TABLE t2 (f INT, KEY(f)) ENGINE=InnoDB; +ALTER TABLE t1 ADD FOREIGN KEY (f2) REFERENCES t2 (f); +ALTER IGNORE TABLE t1 ADD FOREIGN KEY (f3) REFERENCES t1 (f1); +DROP TABLE t1, t2; # Start of 10.2 tests # # MDEV-13246 Stale rows despite ON DELETE CASCADE constraint diff --git a/mysql-test/suite/innodb/r/xa_debug.result b/mysql-test/suite/innodb/r/xa_debug.result new file mode 100644 index 00000000000..902166f51c8 --- /dev/null +++ b/mysql-test/suite/innodb/r/xa_debug.result @@ -0,0 +1,361 @@ +call mtr.add_suppression("Found 50 prepared XA transactions"); +create table t1 (a int) engine=innodb; +insert into t1 values(1); +connect con$trial, localhost, root,,; +xa start 'test50'; +insert into t1 values(1); +xa end 'test50'; +xa prepare 'test50'; +connect con$trial, localhost, root,,; +xa start 'test49'; +insert into t1 values(1); +xa end 'test49'; +xa prepare 'test49'; +connect con$trial, localhost, root,,; +xa start 'test48'; +insert into t1 values(1); +xa end 'test48'; +xa prepare 'test48'; +connect con$trial, localhost, root,,; +xa start 'test47'; +insert into t1 values(1); +xa end 'test47'; +xa prepare 'test47'; +connect con$trial, localhost, root,,; +xa start 'test46'; +insert into t1 values(1); +xa end 'test46'; +xa prepare 'test46'; +connect con$trial, localhost, root,,; +xa start 'test45'; +insert into t1 values(1); +xa end 'test45'; +xa prepare 'test45'; +connect con$trial, localhost, root,,; +xa start 'test44'; +insert into t1 values(1); +xa end 'test44'; +xa prepare 'test44'; +connect con$trial, localhost, root,,; +xa start 'test43'; +insert into t1 values(1); +xa end 'test43'; +xa prepare 'test43'; +connect con$trial, localhost, root,,; +xa start 'test42'; +insert into t1 values(1); +xa end 'test42'; +xa prepare 'test42'; +connect con$trial, localhost, root,,; +xa start 'test41'; +insert into t1 values(1); +xa end 'test41'; +xa prepare 'test41'; +connect con$trial, localhost, root,,; +xa start 'test40'; +insert into t1 values(1); +xa end 'test40'; +xa prepare 'test40'; +connect con$trial, localhost, root,,; +xa start 'test39'; +insert into t1 values(1); +xa end 'test39'; +xa prepare 'test39'; +connect con$trial, localhost, root,,; +xa start 'test38'; +insert into t1 values(1); +xa end 'test38'; +xa prepare 'test38'; +connect con$trial, localhost, root,,; +xa start 'test37'; +insert into t1 values(1); +xa end 'test37'; +xa prepare 'test37'; +connect con$trial, localhost, root,,; +xa start 'test36'; +insert into t1 values(1); +xa end 'test36'; +xa prepare 'test36'; +connect con$trial, localhost, root,,; +xa start 'test35'; +insert into t1 values(1); +xa end 'test35'; +xa prepare 'test35'; +connect con$trial, localhost, root,,; +xa start 'test34'; +insert into t1 values(1); +xa end 'test34'; +xa prepare 'test34'; +connect con$trial, localhost, root,,; +xa start 'test33'; +insert into t1 values(1); +xa end 'test33'; +xa prepare 'test33'; +connect con$trial, localhost, root,,; +xa start 'test32'; +insert into t1 values(1); +xa end 'test32'; +xa prepare 'test32'; +connect con$trial, localhost, root,,; +xa start 'test31'; +insert into t1 values(1); +xa end 'test31'; +xa prepare 'test31'; +connect con$trial, localhost, root,,; +xa start 'test30'; +insert into t1 values(1); +xa end 'test30'; +xa prepare 'test30'; +connect con$trial, localhost, root,,; +xa start 'test29'; +insert into t1 values(1); +xa end 'test29'; +xa prepare 'test29'; +connect con$trial, localhost, root,,; +xa start 'test28'; +insert into t1 values(1); +xa end 'test28'; +xa prepare 'test28'; +connect con$trial, localhost, root,,; +xa start 'test27'; +insert into t1 values(1); +xa end 'test27'; +xa prepare 'test27'; +connect con$trial, localhost, root,,; +xa start 'test26'; +insert into t1 values(1); +xa end 'test26'; +xa prepare 'test26'; +connect con$trial, localhost, root,,; +xa start 'test25'; +insert into t1 values(1); +xa end 'test25'; +xa prepare 'test25'; +connect con$trial, localhost, root,,; +xa start 'test24'; +insert into t1 values(1); +xa end 'test24'; +xa prepare 'test24'; +connect con$trial, localhost, root,,; +xa start 'test23'; +insert into t1 values(1); +xa end 'test23'; +xa prepare 'test23'; +connect con$trial, localhost, root,,; +xa start 'test22'; +insert into t1 values(1); +xa end 'test22'; +xa prepare 'test22'; +connect con$trial, localhost, root,,; +xa start 'test21'; +insert into t1 values(1); +xa end 'test21'; +xa prepare 'test21'; +connect con$trial, localhost, root,,; +xa start 'test20'; +insert into t1 values(1); +xa end 'test20'; +xa prepare 'test20'; +connect con$trial, localhost, root,,; +xa start 'test19'; +insert into t1 values(1); +xa end 'test19'; +xa prepare 'test19'; +connect con$trial, localhost, root,,; +xa start 'test18'; +insert into t1 values(1); +xa end 'test18'; +xa prepare 'test18'; +connect con$trial, localhost, root,,; +xa start 'test17'; +insert into t1 values(1); +xa end 'test17'; +xa prepare 'test17'; +connect con$trial, localhost, root,,; +xa start 'test16'; +insert into t1 values(1); +xa end 'test16'; +xa prepare 'test16'; +connect con$trial, localhost, root,,; +xa start 'test15'; +insert into t1 values(1); +xa end 'test15'; +xa prepare 'test15'; +connect con$trial, localhost, root,,; +xa start 'test14'; +insert into t1 values(1); +xa end 'test14'; +xa prepare 'test14'; +connect con$trial, localhost, root,,; +xa start 'test13'; +insert into t1 values(1); +xa end 'test13'; +xa prepare 'test13'; +connect con$trial, localhost, root,,; +xa start 'test12'; +insert into t1 values(1); +xa end 'test12'; +xa prepare 'test12'; +connect con$trial, localhost, root,,; +xa start 'test11'; +insert into t1 values(1); +xa end 'test11'; +xa prepare 'test11'; +connect con$trial, localhost, root,,; +xa start 'test10'; +insert into t1 values(1); +xa end 'test10'; +xa prepare 'test10'; +connect con$trial, localhost, root,,; +xa start 'test9'; +insert into t1 values(1); +xa end 'test9'; +xa prepare 'test9'; +connect con$trial, localhost, root,,; +xa start 'test8'; +insert into t1 values(1); +xa end 'test8'; +xa prepare 'test8'; +connect con$trial, localhost, root,,; +xa start 'test7'; +insert into t1 values(1); +xa end 'test7'; +xa prepare 'test7'; +connect con$trial, localhost, root,,; +xa start 'test6'; +insert into t1 values(1); +xa end 'test6'; +xa prepare 'test6'; +connect con$trial, localhost, root,,; +xa start 'test5'; +insert into t1 values(1); +xa end 'test5'; +xa prepare 'test5'; +connect con$trial, localhost, root,,; +xa start 'test4'; +insert into t1 values(1); +xa end 'test4'; +xa prepare 'test4'; +connect con$trial, localhost, root,,; +xa start 'test3'; +insert into t1 values(1); +xa end 'test3'; +xa prepare 'test3'; +connect con$trial, localhost, root,,; +xa start 'test2'; +insert into t1 values(1); +xa end 'test2'; +xa prepare 'test2'; +connect con$trial, localhost, root,,; +xa start 'test1'; +insert into t1 values(1); +xa end 'test1'; +xa prepare 'test1'; +connection default; +xa recover; +formatID gtrid_length bqual_length data +1 5 0 test1 +1 5 0 test2 +1 5 0 test3 +1 5 0 test4 +1 5 0 test5 +1 5 0 test6 +1 5 0 test7 +1 5 0 test8 +1 5 0 test9 +1 6 0 test10 +1 6 0 test11 +1 6 0 test12 +1 6 0 test13 +1 6 0 test14 +1 6 0 test15 +1 6 0 test16 +1 6 0 test17 +1 6 0 test18 +1 6 0 test19 +1 6 0 test20 +1 6 0 test21 +1 6 0 test22 +1 6 0 test23 +1 6 0 test24 +1 6 0 test25 +1 6 0 test26 +1 6 0 test27 +1 6 0 test28 +1 6 0 test29 +1 6 0 test30 +1 6 0 test31 +1 6 0 test32 +1 6 0 test33 +1 6 0 test34 +1 6 0 test35 +1 6 0 test36 +1 6 0 test37 +1 6 0 test38 +1 6 0 test39 +1 6 0 test40 +1 6 0 test41 +1 6 0 test42 +1 6 0 test43 +1 6 0 test44 +1 6 0 test45 +1 6 0 test46 +1 6 0 test47 +1 6 0 test48 +1 6 0 test49 +1 6 0 test50 +xa recover; +formatID gtrid_length bqual_length data +1 5 0 test1 +1 5 0 test2 +1 5 0 test3 +1 5 0 test4 +1 5 0 test5 +1 5 0 test6 +1 5 0 test7 +1 5 0 test8 +1 5 0 test9 +1 6 0 test10 +1 6 0 test11 +1 6 0 test12 +1 6 0 test13 +1 6 0 test14 +1 6 0 test15 +1 6 0 test16 +1 6 0 test17 +1 6 0 test18 +1 6 0 test19 +1 6 0 test20 +1 6 0 test21 +1 6 0 test22 +1 6 0 test23 +1 6 0 test24 +1 6 0 test25 +1 6 0 test26 +1 6 0 test27 +1 6 0 test28 +1 6 0 test29 +1 6 0 test30 +1 6 0 test31 +1 6 0 test32 +1 6 0 test33 +1 6 0 test34 +1 6 0 test35 +1 6 0 test36 +1 6 0 test37 +1 6 0 test38 +1 6 0 test39 +1 6 0 test40 +1 6 0 test41 +1 6 0 test42 +1 6 0 test43 +1 6 0 test44 +1 6 0 test45 +1 6 0 test46 +1 6 0 test47 +1 6 0 test48 +1 6 0 test49 +1 6 0 test50 +xa recover; +formatID gtrid_length bqual_length data +drop table t1; diff --git a/mysql-test/suite/innodb/t/foreign_key.test b/mysql-test/suite/innodb/t/foreign_key.test index a4e045d4d5e..e7ba5530b19 100644 --- a/mysql-test/suite/innodb/t/foreign_key.test +++ b/mysql-test/suite/innodb/t/foreign_key.test @@ -244,10 +244,18 @@ DROP TABLE t1; CREATE TABLE t1 (a INT) ENGINE=InnoDB; --error ER_CANT_CREATE_TABLE ALTER IGNORE TABLE t1 ADD FOREIGN KEY (a) REFERENCES t2 (b); ---replace_regex /#sql-[0-9_a-f-]*/#sql-temporary/ SHOW WARNINGS; DROP TABLE t1; +--echo # +--echo # MDEV-18139 ALTER IGNORE ... ADD FOREIGN KEY causes bogus error +--echo # +CREATE TABLE t1 (f1 INT, f2 INT, f3 INT, KEY(f1)) ENGINE=InnoDB; +CREATE TABLE t2 (f INT, KEY(f)) ENGINE=InnoDB; +ALTER TABLE t1 ADD FOREIGN KEY (f2) REFERENCES t2 (f); +ALTER IGNORE TABLE t1 ADD FOREIGN KEY (f3) REFERENCES t1 (f1); +DROP TABLE t1, t2; + --echo # Start of 10.2 tests --echo # diff --git a/mysql-test/suite/innodb/t/xa_debug.test b/mysql-test/suite/innodb/t/xa_debug.test new file mode 100644 index 00000000000..5724891bb65 --- /dev/null +++ b/mysql-test/suite/innodb/t/xa_debug.test @@ -0,0 +1,45 @@ +-- source include/have_innodb.inc +-- source include/have_debug.inc +-- source include/not_embedded.inc + +call mtr.add_suppression("Found 50 prepared XA transactions"); +create table t1 (a int) engine=innodb; +insert into t1 values(1); + +let $trial = 50; +while ($trial) +{ +--connect (con$trial, localhost, root,,) +let $st_pre = `select concat('test', $trial)`; +eval xa start '$st_pre'; +insert into t1 values(1); +eval xa end '$st_pre'; +eval xa prepare '$st_pre'; +dec $trial; +} + +connection default; +# Kill and restart the server. +-- exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +-- shutdown_server 0 +-- source include/wait_until_disconnected.inc + +-- exec echo "restart:--debug_dbug=+d,min_xa_len" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +-- enable_reconnect +-- source include/wait_until_connected_again.inc +-- disable_reconnect +--sorted_result +xa recover; +--sorted_result +xa recover; +--disable_query_log +let $trial = 50; +while ($trial) +{ +let $st_pre = `select concat('test', $trial)`; +eval xa commit '$st_pre'; +dec $trial; +} +--enable_query_log +xa recover; +drop table t1; diff --git a/mysql-test/t/gis-precise.test b/mysql-test/t/gis-precise.test index 39a35e1c9cf..ede535596da 100644 --- a/mysql-test/t/gis-precise.test +++ b/mysql-test/t/gis-precise.test @@ -381,6 +381,12 @@ SELECT ST_RELATE( 'F*FFFF**F' ) as relate_res; +# MDEV-18920 Prepared statements with st_convexhull hang and eat 100% cpu. +prepare s from 'do st_convexhull(st_aswkb(multipoint(point(-11702,15179),point(-5031,27960),point(-30557,11158),point(-27804,30314))))'; +execute s; +execute s; +deallocate prepare s; + # MDEV- 16050 cte + geometry functions lead to crash. with cte1 as( select (st_symdifference(point(1,1),point(1,1))) as a1 ), cte2 as(select 1 as a2) select 1 from cte1 where cte1.a1 < '1'; diff --git a/mysql-test/t/olap.test b/mysql-test/t/olap.test index 4a61cebdc0d..a57cab9a0ee 100644 --- a/mysql-test/t/olap.test +++ b/mysql-test/t/olap.test @@ -425,5 +425,44 @@ DROP TABLE t1; --echo # +--echo # MDEV-17830 Server crashes in Item_null_result::field_type upon SELECT with CHARSET(date) and ROLLUP +--echo # + +--echo # Note, different MariaDB versions can return different results +--echo # in the two rows (such as "latin1" vs "binary"). This is wrong. +--echo # Both lines should return equal values. +--echo # The point in this test is to make sure it does not crash. +--echo # As this is a minor issue, bad result will be fixed +--echo # in a later version, presumably in 10.4. + +CREATE TABLE t (d DATE) ENGINE=MyISAM; +INSERT INTO t VALUES ('2018-12-12'); +SELECT CHARSET(d) AS f FROM t GROUP BY d WITH ROLLUP; +DROP TABLE t; + + +--echo # +--echo # MDEV-14041 Server crashes in String::length on queries with functions and ROLLUP +--echo # + +CREATE TABLE t1 (i INT); +INSERT INTO t1 VALUES (1),(2); +SELECT GET_LOCK( 'foo', 0 ); +SELECT HEX( RELEASE_LOCK( 'foo' ) ) AS f FROM t1 GROUP BY f WITH ROLLUP; +DROP TABLE t1; + +CREATE TABLE t1 (i INT); +INSERT INTO t1 VALUES (1),(2); +SELECT i FROM t1 GROUP BY i WITH ROLLUP +UNION ALL +SELECT ELT( FOUND_ROWS(), 1 ) f FROM t1 GROUP BY f WITH ROLLUP; +DROP TABLE t1; + +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1),(2); +SELECT a FROM t1 GROUP BY NULLIF( CONVERT('', DATE), '2015-10-15' ) WITH ROLLUP; +DROP TABLE t1; + +--echo # --echo # End of 10.1 tests --echo # diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index ac80c6cbf87..2df53a2f0aa 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -9066,6 +9066,15 @@ DROP PROCEDURE p1; --echo # End of 5.5 test +#MDEV-17610 +CREATE PROCEDURE sp() ALTER TABLE non_existing_table OPTIMIZE PARTITION p0; +CALL sp; +SELECT 1; +DROP PROCEDURE sp; +CREATE PROCEDURE sp() SHOW USER_STATISTICS; +CALL sp; +SELECT 1; +DROP PROCEDURE sp; --echo # --echo # Bug#12663165 SP DEAD CODE REMOVAL DOESN'T UNDERSTAND CONTINUE HANDLERS diff --git a/mysql-test/t/stat_tables.test b/mysql-test/t/stat_tables.test index 89c11ed4acf..93caa47ce79 100644 --- a/mysql-test/t/stat_tables.test +++ b/mysql-test/t/stat_tables.test @@ -401,6 +401,61 @@ SELECT MAX(pk) FROM t1; DROP TABLE t1; + +--echo # +--echo # MDEV-17605: SHOW INDEXES with use_stat_tables='preferably' +--echo # + +set use_stat_tables='preferably'; + +CREATE DATABASE dbt3_s001; + +use dbt3_s001; + +set @save_optimizer_switch=@@optimizer_switch; +set optimizer_switch='extended_keys=off'; + +--disable_query_log +--disable_result_log +--disable_warnings +--source include/dbt3_s001.inc +create index i_p_retailprice on part(p_retailprice); +delete from mysql.table_stats; +delete from mysql.column_stats; +delete from mysql.index_stats; +ANALYZE TABLE lineitem; +FLUSH TABLE mysql.table_stats, mysql.index_stats; +--enable_warnings +--enable_result_log +--enable_query_log + +select * from mysql.table_stats; +select * from mysql.index_stats; + +SHOW INDEXES FROM lineitem; + +SELECT * FROM INFORMATION_SCHEMA.STATISTICS WHERE table_name='lineitem'; + +SELECT + COUNT(DISTINCT l_orderkey), COUNT(DISTINCT l_orderkey,l_linenumber), + COUNT(DISTINCT l_shipDATE), + COUNT(DISTINCT l_partkey), COUNT(DISTINCT l_partkey,l_suppkey), + COUNT(DISTINCT l_suppkey), COUNT(DISTINCT l_receiptDATE), + COUNT(DISTINCT l_orderkey, l_quantity), COUNT(DISTINCT l_commitDATE) +FROM lineitem; + +set optimizer_switch=@save_optimizer_switch; + +DROP DATABASE dbt3_s001; +USE test; + +delete from mysql.table_stats; +delete from mysql.column_stats; +delete from mysql.index_stats; + +set @save_optimizer_switch=@@optimizer_switch; +set use_stat_tables=@save_use_stat_tables; + --echo # --echo # MDEV-18899: Server crashes in Field::set_warning_truncated_wrong_value --echo # diff --git a/mysql-test/t/type_date.test b/mysql-test/t/type_date.test index b7fdf7b93b7..5994caf2282 100644 --- a/mysql-test/t/type_date.test +++ b/mysql-test/t/type_date.test @@ -585,6 +585,20 @@ INSERT INTO t1 VALUES ('1985-05-13'),('1989-12-24'); SELECT d, COUNT(*) FROM t1 GROUP BY d WITH ROLLUP HAVING CASE d WHEN '2017-05-25' THEN 0 ELSE 1 END; DROP TABLE t1; +--echo # +--echo # MDEV-17299 Assertion `maybe_null' failed in make_sortkey +--echo # + +CREATE TABLE t1 (pk int NOT NULL, d1 date, d2 date NOT NULL); +INSERT INTO t1 values (1,'2018-06-22','2018-06-22'),(2,'2018-07-11','2018-07-11'); +CREATE VIEW v1 AS SELECT * FROM t1; +SELECT group_concat(d1/(CASE 'b' WHEN 'j' THEN 'c' END)) + FROM v1 GROUP BY greatest(pk, 0, d2); +CREATE TABLE t2 AS SELECT greatest(pk, 0, d2) AS c1 FROM t1 LIMIT 0; +SHOW CREATE TABLE t2; +DROP TABLE t2; +DROP VIEW v1; +DROP TABLE t1; --echo # --echo # End of 10.1 tests diff --git a/mysql-test/t/update_innodb.test b/mysql-test/t/update_innodb.test index acc8aceab00..a29dd071cf8 100644 --- a/mysql-test/t/update_innodb.test +++ b/mysql-test/t/update_innodb.test @@ -75,3 +75,32 @@ SELECT t2.b_id FROM t1,t2 WHERE t2.c_id = t1.c_id; UPDATE t1 SET b_id = (SELECT t2.b_id FROM t2 t2 WHERE t2.c_id = t1.c_id); SELECT * FROM t1; drop table t1,t2; + +--echo # +--echo # MDEV-18300: ASAN error in Field_blob::get_key_image upon UPDATE with subquery +--echo # + +set @save_optimizer_use_condition_selectivity= @@optimizer_use_condition_selectivity; +set @save_use_stat_tables= @@use_stat_tables; +set use_stat_tables=preferably; +set optimizer_use_condition_selectivity=4; + +CREATE TABLE t1 (a INT, b CHAR(8)) ENGINE=InnoDB; +insert into t1 values (1,'foo'),(2, 'abc'); +CREATE TABLE t2 (c CHAR(8), d BLOB) ENGINE=InnoDB; +insert into t2 values ('abc', 'foo'),('edf', 'food'); + +--disable_result_log +ANALYZE TABLE t1,t2; +--enable_result_log +UPDATE t1 SET a = 1 WHERE b = ( SELECT c FROM t2 WHERE d = 'foo' ); +SELECT * FROM t1; +DROP TABLE t1, t2; + +create table t1 (a int not null, b int, c int) engine=InnoDB; +create table t2 (d int, e int) engine=InnoDB; +update t1, t2 set a=NULL, b=2, c=NULL where b=d and e=200; +drop table t1,t2; + +set @@optimizer_use_condition_selectivity= @save_optimizer_use_condition_selectivity; +set @@use_stat_tables= @save_use_stat_tables; diff --git a/sql/gcalc_slicescan.cc b/sql/gcalc_slicescan.cc index 68764205302..ba75a1ed827 100644 --- a/sql/gcalc_slicescan.cc +++ b/sql/gcalc_slicescan.cc @@ -993,6 +993,8 @@ void Gcalc_heap::reset() { if (m_n_points) { + if (m_hook) + *m_hook= NULL; free_list(m_first); m_n_points= 0; } diff --git a/sql/handler.cc b/sql/handler.cc index ae63640ae5c..ad1bad59efa 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -1996,6 +1996,7 @@ int ha_recover(HASH *commit_list) for (info.len= MAX_XID_LIST_SIZE ; info.list==0 && info.len > MIN_XID_LIST_SIZE; info.len/=2) { + DBUG_EXECUTE_IF("min_xa_len", info.len = 16;); info.list=(XID *)my_malloc(info.len*sizeof(XID), MYF(0)); } if (!info.list) diff --git a/sql/item.h b/sql/item.h index 466f8d15df8..bd72fed5300 100644 --- a/sql/item.h +++ b/sql/item.h @@ -707,6 +707,45 @@ protected: bool fixed_length, bool set_blob_packlength); Field *create_tmp_field(bool group, TABLE *table, uint convert_int_length); + /* Helper methods, to get an Item value from another Item */ + double val_real_from_item(Item *item) + { + DBUG_ASSERT(fixed == 1); + double value= item->val_real(); + null_value= item->null_value; + return value; + } + longlong val_int_from_item(Item *item) + { + DBUG_ASSERT(fixed == 1); + longlong value= item->val_int(); + null_value= item->null_value; + return value; + } + String *val_str_from_item(Item *item, String *str) + { + DBUG_ASSERT(fixed == 1); + String *res= item->val_str(str); + if (res) + res->set_charset(collation.collation); + if ((null_value= item->null_value)) + res= NULL; + return res; + } + my_decimal *val_decimal_from_item(Item *item, my_decimal *decimal_value) + { + DBUG_ASSERT(fixed == 1); + my_decimal *value= item->val_decimal(decimal_value); + if ((null_value= item->null_value)) + value= NULL; + return value; + } + bool get_date_from_item(Item *item, MYSQL_TIME *ltime, ulonglong fuzzydate) + { + bool rc= item->get_date(ltime, fuzzydate); + null_value= MY_TEST(rc || item->null_value); + return rc; + } /* This method is used if the item was not null but convertion to TIME/DATE/DATETIME failed. We return a zero date if allowed, @@ -2862,6 +2901,10 @@ public: { return result_field->type(); } + CHARSET_INFO *charset_for_protocol(void) const + { + return collation.collation; + } #else const Type_handler *type_handler() const { @@ -4361,6 +4404,12 @@ public: void save_org_in_field(Field *field, fast_field_copier optimizer_data); fast_field_copier setup_fast_field_copier(Field *field) { return (*ref)->setup_fast_field_copier(field); } +#if MARIADB_VERSION_ID < 100300 + CHARSET_INFO *charset_for_protocol(void) const + { + return (*ref)->charset_for_protocol(); + } +#endif enum Item_result result_type () const { return (*ref)->result_type(); } enum_field_types field_type() const { return (*ref)->field_type(); } Field *get_tmp_table_field() diff --git a/sql/item_func.cc b/sql/item_func.cc index 039b4f42f98..33f0b982445 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -2766,6 +2766,8 @@ bool Item_func_min_max::fix_length_and_dec() switch (tmp_cmp_type) { case TIME_RESULT: // At least one temporal argument was found. + if (temporal_type_count < arg_count) + maybe_null= true; // Non-temporal-to-temporal conversion can return NULL collation.set_numeric(); set_handler_by_field_type(temporal_field_type); if (is_temporal_type_with_time(temporal_field_type)) diff --git a/sql/item_func.h b/sql/item_func.h index 41eb019bd6b..cd8e4c08168 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -1234,10 +1234,13 @@ public: name= a->name; name_length= a->name_length; } - double val_real() { return args[0]->val_real(); } - longlong val_int() { return args[0]->val_int(); } - String *val_str(String *str) { return args[0]->val_str(str); } - my_decimal *val_decimal(my_decimal *dec) { return args[0]->val_decimal(dec); } + double val_real() { return val_real_from_item(args[0]); } + longlong val_int() { return val_int_from_item(args[0]); } + String *val_str(String *str) { return val_str_from_item(args[0], str); } + my_decimal *val_decimal(my_decimal *dec) + { return val_decimal_from_item(args[0], dec); } + bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate) + { return get_date_from_item(args[0], ltime, fuzzydate); } const char *func_name() const { return "rollup_const"; } bool const_item() const { return 0; } Item_result result_type() const { return args[0]->result_type(); } diff --git a/sql/sp_head.cc b/sql/sp_head.cc index bb24c3b91bb..c473aec51a1 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -223,6 +223,7 @@ sp_get_flags_for_command(LEX *lex) case SQLCOM_SHOW_EXPLAIN: case SQLCOM_SHOW_FIELDS: case SQLCOM_SHOW_FUNC_CODE: + case SQLCOM_SHOW_GENERIC: case SQLCOM_SHOW_GRANTS: case SQLCOM_SHOW_ENGINE_STATUS: case SQLCOM_SHOW_ENGINE_LOGS: @@ -2896,7 +2897,7 @@ sp_head::show_routine_code(THD *thd) const char *format= "Instruction at position %u has m_ip=%u"; char tmp[sizeof(format) + 2*SP_INSTR_UINT_MAXLEN + 1]; - sprintf(tmp, format, ip, i->m_ip); + my_snprintf(tmp, sizeof(tmp), format, ip, i->m_ip); /* Since this is for debugging purposes only, we don't bother to introduce a special error code for it. diff --git a/sql/sql_class.h b/sql/sql_class.h index 2c5c01161b6..38e55f9c4a9 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -2390,6 +2390,9 @@ public: */ bool create_tmp_table_for_derived; + /* The flag to force reading statistics from EITS tables */ + bool force_read_stats; + bool save_prep_leaf_list; /* container for handler's private per-connection data */ diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 28cf549bfa1..146c4d2d02e 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2926,15 +2926,14 @@ static bool do_execute_sp(THD *thd, sp_head *sp) my_error(ER_SP_BADSELECT, MYF(0), sp->m_qname.str); return 1; } - /* - If SERVER_MORE_RESULTS_EXISTS is not set, - then remember that it should be cleared - */ - bits_to_be_cleared= (~thd->server_status & - SERVER_MORE_RESULTS_EXISTS); - thd->server_status|= SERVER_MORE_RESULTS_EXISTS; } - + /* + If SERVER_MORE_RESULTS_EXISTS is not set, + then remember that it should be cleared + */ + bits_to_be_cleared= (~thd->server_status & + SERVER_MORE_RESULTS_EXISTS); + thd->server_status|= SERVER_MORE_RESULTS_EXISTS; ha_rows select_limit= thd->variables.select_limit; thd->variables.select_limit= HA_POS_ERROR; diff --git a/sql/sql_show.cc b/sql/sql_show.cc index ce0e3bc6265..a29a6871b78 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -4396,6 +4396,7 @@ fill_schema_table_by_open(THD *thd, bool is_show_fields_or_keys, 'only_view_structure()'. */ lex->sql_command= SQLCOM_SHOW_FIELDS; + thd->force_read_stats= get_schema_table_idx(schema_table) == SCH_STATISTICS; result= (thd->open_temporary_tables(table_list) || open_normal_and_derived_tables(thd, table_list, (MYSQL_OPEN_IGNORE_FLUSH | @@ -4403,6 +4404,10 @@ fill_schema_table_by_open(THD *thd, bool is_show_fields_or_keys, (can_deadlock ? MYSQL_OPEN_FAIL_ON_MDL_CONFLICT : 0)), DT_INIT | DT_PREPARE | DT_CREATE)); + + (void) read_statistics_for_tables_if_needed(thd, table_list); + thd->force_read_stats= false; + /* Restore old value of sql_command back as it is being looked at in process_table() function. diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc index 0a51346adb2..3c26f58073d 100644 --- a/sql/sql_statistics.cc +++ b/sql/sql_statistics.cc @@ -2187,7 +2187,10 @@ inline bool statistics_for_command_is_needed(THD *thd) { if (thd->bootstrap || thd->variables.use_stat_tables == NEVER) return FALSE; - + + if (thd->force_read_stats) + return TRUE; + switch(thd->lex->sql_command) { case SQLCOM_SELECT: case SQLCOM_INSERT: @@ -4088,6 +4091,7 @@ bool is_eits_usable(Field *field) partition list of a table. We assume the selecticivity for such columns would be handled during partition pruning. */ + DBUG_ASSERT(field->table->stats_is_read); Column_statistics* col_stats= field->read_stats; return col_stats && !col_stats->no_stat_values_provided() && //(1) field->type() != MYSQL_TYPE_GEOMETRY && //(2) diff --git a/sql/sql_string.h b/sql/sql_string.h index 0065b1424ce..7a1701f6ef3 100644 --- a/sql/sql_string.h +++ b/sql/sql_string.h @@ -705,11 +705,6 @@ public: { length(0); } - StringBuffer(const char *str, size_t length_arg, CHARSET_INFO *cs) - : String(buff, buff_sz, cs) - { - set(str, length_arg, cs); - } }; diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 11ffa684216..80ecd820046 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -302,6 +302,8 @@ int mysql_update(THD *thd, if (lock_tables(thd, table_list, table_count, 0)) DBUG_RETURN(1); + (void) read_statistics_for_tables_if_needed(thd, table_list); + if (table_list->handle_derived(thd->lex, DT_MERGE_FOR_INSERT)) DBUG_RETURN(1); if (table_list->handle_derived(thd->lex, DT_PREPARE)) @@ -1517,6 +1519,7 @@ int mysql_multi_update_prepare(THD *thd) { DBUG_RETURN(TRUE); } + (void) read_statistics_for_tables_if_needed(thd, table_list); /* @todo: downgrade the metadata locks here. */ /* diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc index edbb5d358fa..91647aa2e99 100644 --- a/storage/archive/ha_archive.cc +++ b/storage/archive/ha_archive.cc @@ -1670,7 +1670,6 @@ void ha_archive::update_create_info(HA_CREATE_INFO *create_info) DBUG_VOID_RETURN; } - /* Hints for optimizer, see ha_tina for more information */ @@ -1678,22 +1677,7 @@ int ha_archive::info(uint flag) { DBUG_ENTER("ha_archive::info"); - mysql_mutex_lock(&share->mutex); - if (share->dirty) - { - DBUG_PRINT("ha_archive", ("archive flushing out rows for scan")); - DBUG_ASSERT(share->archive_write_open); - azflush(&(share->archive_write), Z_SYNC_FLUSH); - share->dirty= FALSE; - } - - /* - This should be an accurate number now, though bulk and delayed inserts can - cause the number to be inaccurate. - */ - stats.records= share->rows_recorded; - mysql_mutex_unlock(&share->mutex); - + flush_and_clear_pending_writes(); stats.deleted= 0; DBUG_PRINT("ha_archive", ("Stats rows is %d\n", (int)stats.records)); @@ -1736,6 +1720,38 @@ int ha_archive::info(uint flag) } +int ha_archive::external_lock(THD *thd, int lock_type) +{ + if (lock_type == F_RDLCK) + { + // We are going to read from the table. Flush any pending writes that we + // may have + flush_and_clear_pending_writes(); + } + return 0; +} + + +void ha_archive::flush_and_clear_pending_writes() +{ + mysql_mutex_lock(&share->mutex); + if (share->dirty) + { + DBUG_PRINT("ha_archive", ("archive flushing out rows for scan")); + DBUG_ASSERT(share->archive_write_open); + azflush(&(share->archive_write), Z_SYNC_FLUSH); + share->dirty= FALSE; + } + + /* + This should be an accurate number now, though bulk and delayed inserts can + cause the number to be inaccurate. + */ + stats.records= share->rows_recorded; + mysql_mutex_unlock(&share->mutex); +} + + /* This method tells us that a bulk insert operation is about to occur. We set a flag which will keep write_row from saying that its data is dirty. This in diff --git a/storage/archive/ha_archive.h b/storage/archive/ha_archive.h index 56ff566db8c..a74374a340f 100644 --- a/storage/archive/ha_archive.h +++ b/storage/archive/ha_archive.h @@ -169,5 +169,8 @@ public: int unpack_row(azio_stream *file_to_read, uchar *record); unsigned int pack_row(uchar *record, azio_stream *writer); bool check_if_incompatible_data(HA_CREATE_INFO *info, uint table_changes); + int external_lock(THD *thd, int lock_type); +private: + void flush_and_clear_pending_writes(); }; diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc index e5f1e0dab1d..95f4a205891 100644 --- a/storage/innobase/dict/dict0dict.cc +++ b/storage/innobase/dict/dict0dict.cc @@ -4434,11 +4434,19 @@ dict_create_foreign_constraints_low( } orig = ptr; - ptr = dict_accept(cs, ptr, "TABLE", &success); - - if (!success) { - - goto loop; + for (;;) { + ptr = dict_accept(cs, ptr, "TABLE", &success); + if (success) { + break; + } + ptr = dict_accept(cs, ptr, "ONLINE", &success); + if (success) { + continue; + } + ptr = dict_accept(cs, ptr, "IGNORE", &success); + if (!success) { + goto loop; + } } /* We are doing an ALTER TABLE: scan the table name we are altering */ diff --git a/storage/innobase/include/trx0trx.h b/storage/innobase/include/trx0trx.h index 159dcca2581..6c9223f31be 100644 --- a/storage/innobase/include/trx0trx.h +++ b/storage/innobase/include/trx0trx.h @@ -558,7 +558,7 @@ Check transaction state */ ut_ad(!trx_is_autocommit_non_locking((t))); \ switch ((t)->state) { \ case TRX_STATE_PREPARED: \ - /* fall through */ \ + case TRX_STATE_PREPARED_RECOVERED: \ case TRX_STATE_ACTIVE: \ case TRX_STATE_COMMITTED_IN_MEMORY: \ continue; \ @@ -824,6 +824,7 @@ struct trx_t { TRX_STATE_NOT_STARTED TRX_STATE_ACTIVE TRX_STATE_PREPARED + TRX_STATE_PREPARED_RECOVERED (special case of TRX_STATE_PREPARED) TRX_STATE_COMMITTED_IN_MEMORY (alias below COMMITTED) Valid state transitions are: diff --git a/storage/innobase/include/trx0trx.ic b/storage/innobase/include/trx0trx.ic index dd42c8b8368..61b2f8a7754 100644 --- a/storage/innobase/include/trx0trx.ic +++ b/storage/innobase/include/trx0trx.ic @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2016, 2018, MariaDB Corporation. +Copyright (c) 2016, 2019, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -49,7 +49,7 @@ trx_state_eq( #ifdef UNIV_DEBUG switch (trx->state) { case TRX_STATE_PREPARED: - + case TRX_STATE_PREPARED_RECOVERED: ut_ad(!trx_is_autocommit_non_locking(trx)); return(trx->state == state); diff --git a/storage/innobase/include/trx0types.h b/storage/innobase/include/trx0types.h index de26de44193..3b87c760018 100644 --- a/storage/innobase/include/trx0types.h +++ b/storage/innobase/include/trx0types.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2014, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2018, MariaDB Corporation. +Copyright (c) 2017, 2019, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -65,10 +65,11 @@ enum trx_state_t { TRX_STATE_NOT_STARTED, TRX_STATE_ACTIVE, - - /** Support for 2PC/XA */ + /** XA PREPARE has been executed; only XA COMMIT or XA ROLLBACK + are possible */ TRX_STATE_PREPARED, - + /** XA PREPARE transaction that was returned to ha_recover() */ + TRX_STATE_PREPARED_RECOVERED, TRX_STATE_COMMITTED_IN_MEMORY }; diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc index 1d3e75e9740..f43694b6926 100644 --- a/storage/innobase/lock/lock0lock.cc +++ b/storage/innobase/lock/lock0lock.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2014, 2018, MariaDB Corporation. +Copyright (c) 2014, 2019, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -6807,7 +6807,8 @@ lock_trx_release_locks( { check_trx_state(trx); - if (trx_state_eq(trx, TRX_STATE_PREPARED)) { + if (trx_state_eq(trx, TRX_STATE_PREPARED) + || trx_state_eq(trx, TRX_STATE_PREPARED_RECOVERED)) { mutex_enter(&trx_sys->mutex); diff --git a/storage/innobase/row/row0undo.cc b/storage/innobase/row/row0undo.cc index 3f960235f3e..a78de7c7e80 100644 --- a/storage/innobase/row/row0undo.cc +++ b/storage/innobase/row/row0undo.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, MariaDB Corporation. +Copyright (c) 2017, 2019, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -129,6 +129,7 @@ row_undo_node_create( undo_node_t* undo; ut_ad(trx_state_eq(trx, TRX_STATE_ACTIVE) + || trx_state_eq(trx, TRX_STATE_PREPARED_RECOVERED) || trx_state_eq(trx, TRX_STATE_PREPARED)); ut_ad(parent); diff --git a/storage/innobase/trx/trx0roll.cc b/storage/innobase/trx/trx0roll.cc index 0e277c67453..a592fb47d21 100644 --- a/storage/innobase/trx/trx0roll.cc +++ b/storage/innobase/trx/trx0roll.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2016, 2018, MariaDB Corporation. +Copyright (c) 2016, 2019, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -198,6 +198,7 @@ dberr_t trx_rollback_for_mysql(trx_t* trx) return(trx_rollback_for_mysql_low(trx)); case TRX_STATE_PREPARED: + case TRX_STATE_PREPARED_RECOVERED: ut_ad(!trx_is_autocommit_non_locking(trx)); if (trx->has_logged_persistent()) { /* Change the undo log state back from @@ -294,6 +295,7 @@ trx_rollback_last_sql_stat_for_mysql( return(err); case TRX_STATE_PREPARED: + case TRX_STATE_PREPARED_RECOVERED: case TRX_STATE_COMMITTED_IN_MEMORY: /* The statement rollback is only allowed on an ACTIVE transaction, not a PREPARED or COMMITTED one. */ @@ -467,6 +469,7 @@ trx_rollback_to_savepoint_for_mysql( trx, savep, mysql_binlog_cache_pos)); case TRX_STATE_PREPARED: + case TRX_STATE_PREPARED_RECOVERED: case TRX_STATE_COMMITTED_IN_MEMORY: /* The savepoint rollback is only allowed on an ACTIVE transaction, not a PREPARED or COMMITTED one. */ @@ -744,6 +747,7 @@ fake_prepared: } return(FALSE); case TRX_STATE_PREPARED: + case TRX_STATE_PREPARED_RECOVERED: goto func_exit; case TRX_STATE_NOT_STARTED: break; diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc index e548ffbe62b..91e60571438 100644 --- a/storage/innobase/trx/trx0trx.cc +++ b/storage/innobase/trx/trx0trx.cc @@ -527,6 +527,7 @@ trx_free_prepared( trx_t* trx) /*!< in, own: trx object */ { ut_a(trx_state_eq(trx, TRX_STATE_PREPARED) + || trx_state_eq(trx, TRX_STATE_PREPARED_RECOVERED) || (trx->is_recovered && (trx_state_eq(trx, TRX_STATE_ACTIVE) || trx_state_eq(trx, TRX_STATE_COMMITTED_IN_MEMORY)) @@ -779,9 +780,7 @@ trx_resurrect_insert( /* trx_start_low() is not called with resurrect, so need to initialize start time here.*/ - if (trx->state == TRX_STATE_ACTIVE - || trx->state == TRX_STATE_PREPARED) { - + if (trx->state != TRX_STATE_COMMITTED_IN_MEMORY) { trx->start_time = ut_time(); } @@ -1997,7 +1996,7 @@ trx_commit_or_rollback_prepare( case TRX_STATE_ACTIVE: case TRX_STATE_PREPARED: - + case TRX_STATE_PREPARED_RECOVERED: /* If the trx is in a lock wait state, moves the waiting query thread to the suspended state */ @@ -2108,7 +2107,7 @@ trx_commit_for_mysql( /* fall through */ case TRX_STATE_ACTIVE: case TRX_STATE_PREPARED: - + case TRX_STATE_PREPARED_RECOVERED: trx->op_info = "committing"; if (trx->id != 0) { @@ -2158,6 +2157,7 @@ trx_mark_sql_stat_end( switch (trx->state) { case TRX_STATE_PREPARED: + case TRX_STATE_PREPARED_RECOVERED: case TRX_STATE_COMMITTED_IN_MEMORY: break; case TRX_STATE_NOT_STARTED: @@ -2216,6 +2216,7 @@ trx_print_low( (ulong) difftime(time(NULL), trx->start_time)); goto state_ok; case TRX_STATE_PREPARED: + case TRX_STATE_PREPARED_RECOVERED: fprintf(f, ", ACTIVE (PREPARED) %lu sec", (ulong) difftime(time(NULL), trx->start_time)); goto state_ok; @@ -2353,6 +2354,7 @@ wsrep_trx_print_locking( (ulong) difftime(time(NULL), trx->start_time)); goto state_ok; case TRX_STATE_PREPARED: + case TRX_STATE_PREPARED_RECOVERED: fprintf(f, ", ACTIVE (PREPARED) %lu sec", (ulong) difftime(time(NULL), trx->start_time)); goto state_ok; @@ -2475,6 +2477,7 @@ trx_assert_started( switch (trx->state) { case TRX_STATE_PREPARED: + case TRX_STATE_PREPARED_RECOVERED: return(TRUE); case TRX_STATE_ACTIVE: @@ -2656,7 +2659,7 @@ trx_recover_for_mysql( XID* xid_list, /*!< in/out: prepared transactions */ ulint len) /*!< in: number of slots in xid_list */ { - const trx_t* trx; + trx_t* trx; ulint count = 0; ut_ad(xid_list); @@ -2678,6 +2681,7 @@ trx_recover_for_mysql( trx_sys->mutex. It may change to PREPARED, but not if trx->is_recovered. It may also change to COMMITTED. */ if (trx_state_eq(trx, TRX_STATE_PREPARED)) { + trx->state = TRX_STATE_PREPARED_RECOVERED; xid_list[count] = *trx->xid; if (count == 0) { @@ -2695,11 +2699,22 @@ trx_recover_for_mysql( count++; if (count == len) { - break; + goto partial; } } } + /* After returning the full list, reset the state, because + there will be a second call to recover the transactions. */ + for (trx = UT_LIST_GET_FIRST(trx_sys->rw_trx_list); + trx != NULL; + trx = UT_LIST_GET_NEXT(trx_list, trx)) { + if (trx_state_eq(trx, TRX_STATE_PREPARED_RECOVERED)) { + trx->state = TRX_STATE_PREPARED; + } + } + +partial: trx_sys_mutex_exit(); if (count > 0){ @@ -2739,9 +2754,9 @@ trx_get_trx_by_xid_low( the same */ if (trx->is_recovered - && trx_state_eq(trx, TRX_STATE_PREPARED) - && xid->eq((XID*)trx->xid)) { - + && (trx_state_eq(trx, TRX_STATE_PREPARED) + || trx_state_eq(trx, TRX_STATE_PREPARED_RECOVERED)) + && xid->eq(trx->xid)) { #ifdef WITH_WSREP /* The commit of a prepared recovered Galera transaction needs a valid trx->xid for @@ -2812,6 +2827,7 @@ trx_start_if_not_started_xa_low( } return; case TRX_STATE_PREPARED: + case TRX_STATE_PREPARED_RECOVERED: case TRX_STATE_COMMITTED_IN_MEMORY: break; } @@ -2839,6 +2855,7 @@ trx_start_if_not_started_low( return; case TRX_STATE_PREPARED: + case TRX_STATE_PREPARED_RECOVERED: case TRX_STATE_COMMITTED_IN_MEMORY: break; } @@ -2914,6 +2931,7 @@ trx_start_for_ddl_low( return; case TRX_STATE_PREPARED: + case TRX_STATE_PREPARED_RECOVERED: case TRX_STATE_COMMITTED_IN_MEMORY: break; } diff --git a/storage/maria/ma_test3.c b/storage/maria/ma_test3.c index f81d5363c6b..604c2b676a4 100644 --- a/storage/maria/ma_test3.c +++ b/storage/maria/ma_test3.c @@ -362,7 +362,7 @@ int test_write(MARIA_HA *file,int id,int lock_type) maria_extra(file,HA_EXTRA_WRITE_CACHE,0); } - sprintf((char*) record.id,"%7ld", (long) getpid()); + my_snprintf((char*) record.id, sizeof(record.id), "%7ld", (long) getpid()); strnmov((char*) record.text,"Testing...", sizeof(record.text)); tries=(uint) rnd(100)+10; diff --git a/storage/maria/maria_chk.c b/storage/maria/maria_chk.c index d36b0012372..0eb0495c759 100644 --- a/storage/maria/maria_chk.c +++ b/storage/maria/maria_chk.c @@ -1699,8 +1699,8 @@ static void descript(HA_CHECK *param, register MARIA_HA *info, char *name) null_bit[0]=null_pos[0]=0; if (keyseg->null_bit) { - sprintf(null_bit,"%d",keyseg->null_bit); - sprintf(null_pos,"%ld",(long) keyseg->null_pos+1); + my_snprintf(null_bit, sizeof(null_bit), "%d", keyseg->null_bit); + my_snprintf(null_pos, sizeof(null_pos), "%ld", (long) keyseg->null_pos+1); } printf("%-7ld%-5d%-9s%-10s%-30s\n", (long) keyseg->start+1,keyseg->length, diff --git a/storage/myisam/mi_test3.c b/storage/myisam/mi_test3.c index e05398f7c4a..86a639ad2b0 100644 --- a/storage/myisam/mi_test3.c +++ b/storage/myisam/mi_test3.c @@ -364,7 +364,7 @@ int test_write(MI_INFO *file,int id,int lock_type) mi_extra(file,HA_EXTRA_WRITE_CACHE,0); } - sprintf((char*) record.id,"%7ld",(long) getpid()); + my_snprintf((char*) record.id, sizeof(record.id), "%7ld", (long) getpid()); strnmov((char*) record.text,"Testing...", sizeof(record.text)); tries=(uint) rnd(100)+10; diff --git a/storage/myisam/myisamchk.c b/storage/myisam/myisamchk.c index dcf1d5ccaaf..1cdf6e86885 100644 --- a/storage/myisam/myisamchk.c +++ b/storage/myisam/myisamchk.c @@ -1405,8 +1405,8 @@ static void descript(HA_CHECK *param, register MI_INFO *info, char * name) null_bit[0]=null_pos[0]=0; if (keyseg->null_bit) { - sprintf(null_bit,"%d",keyseg->null_bit); - sprintf(null_pos,"%ld",(long) keyseg->null_pos+1); + my_snprintf(null_bit, sizeof(null_bit), "%d", keyseg->null_bit); + my_snprintf(null_pos, sizeof(null_pos), "%ld", (long) keyseg->null_pos+1); } printf("%-7ld%-5d%-9s%-10s%-30s\n", (long) keyseg->start+1,keyseg->length, diff --git a/storage/perfschema/pfs_events.h b/storage/perfschema/pfs_events.h index 97fb7e08d63..905d6f8590f 100644 --- a/storage/perfschema/pfs_events.h +++ b/storage/perfschema/pfs_events.h @@ -34,14 +34,8 @@ struct PFS_events ulonglong m_event_id; /** END_EVENT_ID. */ ulonglong m_end_event_id; - /** (EVENT_TYPE) */ - enum_event_type m_event_type; /** NESTING_EVENT_ID. */ ulonglong m_nesting_event_id; - /** NESTING_EVENT_TYPE */ - enum_event_type m_nesting_event_type; - /** Instrument metadata. */ - PFS_instr_class *m_class; /** Timer start. This member is populated only if m_class->m_timed is true. @@ -52,8 +46,14 @@ struct PFS_events This member is populated only if m_class->m_timed is true. */ ulonglong m_timer_end; + /** Instrument metadata. */ + PFS_instr_class *m_class; /** Location of the instrumentation in the source code (file name). */ const char *m_source_file; + /** (EVENT_TYPE) */ + enum_event_type m_event_type; + /** NESTING_EVENT_TYPE */ + enum_event_type m_nesting_event_type; /** Location of the instrumentation in the source code (line number). */ uint m_source_line; }; diff --git a/storage/perfschema/pfs_events_waits.h b/storage/perfschema/pfs_events_waits.h index 6a50134ad44..0d4e4c37cae 100644 --- a/storage/perfschema/pfs_events_waits.h +++ b/storage/perfschema/pfs_events_waits.h @@ -55,6 +55,23 @@ enum events_waits_class /** A wait event record. */ struct PFS_events_waits : public PFS_events { + /** Executing thread. */ + PFS_thread *m_thread; + /** Table share, for table operations only. */ + PFS_table_share *m_weak_table_share; + /** File, for file operations only. */ + PFS_file *m_weak_file; + /** Address in memory of the object instance waited on. */ + const void *m_object_instance_addr; + /** Socket, for socket operations only. */ + PFS_socket *m_weak_socket; + /** + Number of bytes read/written. + This member is populated for file READ/WRITE operations only. + */ + size_t m_number_of_bytes; + /** Flags */ + ulong m_flags; /** The type of wait. Readers: @@ -67,34 +84,17 @@ struct PFS_events_waits : public PFS_events - TRUNCATE EVENTS_WAITS_HISTORY_LONG */ events_waits_class m_wait_class; - /** Executing thread. */ - PFS_thread *m_thread; /** Object type */ enum_object_type m_object_type; - /** Table share, for table operations only. */ - PFS_table_share *m_weak_table_share; - /** File, for file operations only. */ - PFS_file *m_weak_file; - /** Socket, for socket operations only. */ - PFS_socket *m_weak_socket; /** For weak pointers, target object version. */ uint32 m_weak_version; - /** Address in memory of the object instance waited on. */ - const void *m_object_instance_addr; /** Operation performed. */ enum_operation_type m_operation; /** - Number of bytes read/written. - This member is populated for file READ/WRITE operations only. - */ - size_t m_number_of_bytes; - /** Index used. This member is populated for TABLE IO operations only. */ uint m_index; - /** Flags */ - ulong m_flags; }; /** TIMED bit in the state flags bitfield. */ diff --git a/storage/xtradb/dict/dict0dict.cc b/storage/xtradb/dict/dict0dict.cc index b587aec5370..344f58decd0 100644 --- a/storage/xtradb/dict/dict0dict.cc +++ b/storage/xtradb/dict/dict0dict.cc @@ -4454,11 +4454,19 @@ dict_create_foreign_constraints_low( } orig = ptr; - ptr = dict_accept(cs, ptr, "TABLE", &success); - - if (!success) { - - goto loop; + for (;;) { + ptr = dict_accept(cs, ptr, "TABLE", &success); + if (success) { + break; + } + ptr = dict_accept(cs, ptr, "ONLINE", &success); + if (success) { + continue; + } + ptr = dict_accept(cs, ptr, "IGNORE", &success); + if (!success) { + goto loop; + } } /* We are doing an ALTER TABLE: scan the table name we are altering */ diff --git a/storage/xtradb/include/trx0trx.h b/storage/xtradb/include/trx0trx.h index 1b490eca2af..4fe10cd6bb2 100644 --- a/storage/xtradb/include/trx0trx.h +++ b/storage/xtradb/include/trx0trx.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2015, 2017, MariaDB Corporation +Copyright (c) 2015, 2019, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -575,7 +575,7 @@ non-locking select */ ut_ad(!trx_is_autocommit_non_locking((t))); \ switch ((t)->state) { \ case TRX_STATE_PREPARED: \ - /* fall through */ \ + case TRX_STATE_PREPARED_RECOVERED: \ case TRX_STATE_ACTIVE: \ case TRX_STATE_COMMITTED_IN_MEMORY: \ continue; \ @@ -765,6 +765,7 @@ struct trx_t{ TRX_STATE_NOT_STARTED TRX_STATE_ACTIVE TRX_STATE_PREPARED + TRX_STATE_PREPARED_RECOVERED (special case of TRX_STATE_PREPARED) TRX_STATE_COMMITTED_IN_MEMORY (alias below COMMITTED) Valid state transitions are: diff --git a/storage/xtradb/include/trx0trx.ic b/storage/xtradb/include/trx0trx.ic index eb7d62d9cad..6b8078a55e8 100644 --- a/storage/xtradb/include/trx0trx.ic +++ b/storage/xtradb/include/trx0trx.ic @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2016, MariaDB Corporation. All Rights Reserved. +Copyright (c) 2016, 2019, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -49,6 +49,7 @@ trx_state_eq( #ifdef UNIV_DEBUG switch (trx->state) { case TRX_STATE_PREPARED: + case TRX_STATE_PREPARED_RECOVERED: ut_ad(!trx_is_autocommit_non_locking(trx)); return(trx->state == state); diff --git a/storage/xtradb/include/trx0types.h b/storage/xtradb/include/trx0types.h index 7ca95131328..a0b398fffa1 100644 --- a/storage/xtradb/include/trx0types.h +++ b/storage/xtradb/include/trx0types.h @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2019, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -48,7 +49,11 @@ enum trx_que_t { enum trx_state_t { TRX_STATE_NOT_STARTED, TRX_STATE_ACTIVE, - TRX_STATE_PREPARED, /* Support for 2PC/XA */ + /** XA PREPARE has been executed; only XA COMMIT or XA ROLLBACK + are possible */ + TRX_STATE_PREPARED, + /** XA PREPARE transaction that was returned to ha_recover() */ + TRX_STATE_PREPARED_RECOVERED, TRX_STATE_COMMITTED_IN_MEMORY }; diff --git a/storage/xtradb/lock/lock0lock.cc b/storage/xtradb/lock/lock0lock.cc index 9daa2cc906f..9c86abf7172 100644 --- a/storage/xtradb/lock/lock0lock.cc +++ b/storage/xtradb/lock/lock0lock.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2014, 2018, MariaDB Corporation. +Copyright (c) 2014, 2019, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -8010,7 +8010,8 @@ lock_trx_release_locks( { assert_trx_in_list(trx); - if (trx_state_eq(trx, TRX_STATE_PREPARED)) { + if (trx_state_eq(trx, TRX_STATE_PREPARED) + || trx_state_eq(trx, TRX_STATE_PREPARED_RECOVERED)) { mutex_enter(&trx_sys->mutex); ut_a(trx_sys->n_prepared_trx > 0); trx_sys->n_prepared_trx--; diff --git a/storage/xtradb/trx/trx0roll.cc b/storage/xtradb/trx/trx0roll.cc index 56b7120fa34..6f393511611 100644 --- a/storage/xtradb/trx/trx0roll.cc +++ b/storage/xtradb/trx/trx0roll.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2016, 2018, MariaDB Corporation. +Copyright (c) 2016, 2019, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -208,6 +208,7 @@ trx_rollback_for_mysql( return(trx_rollback_for_mysql_low(trx)); case TRX_STATE_PREPARED: + case TRX_STATE_PREPARED_RECOVERED: ut_ad(!trx_is_autocommit_non_locking(trx)); return(trx_rollback_for_mysql_low(trx)); @@ -260,6 +261,7 @@ trx_rollback_last_sql_stat_for_mysql( return(err); case TRX_STATE_PREPARED: + case TRX_STATE_PREPARED_RECOVERED: case TRX_STATE_COMMITTED_IN_MEMORY: /* The statement rollback is only allowed on an ACTIVE transaction, not a PREPARED or COMMITTED one. */ @@ -433,6 +435,7 @@ trx_rollback_to_savepoint_for_mysql( return(trx_rollback_to_savepoint_for_mysql_low( trx, savep, mysql_binlog_cache_pos)); case TRX_STATE_PREPARED: + case TRX_STATE_PREPARED_RECOVERED: case TRX_STATE_COMMITTED_IN_MEMORY: /* The savepoint rollback is only allowed on an ACTIVE transaction, not a PREPARED or COMMITTED one. */ @@ -722,6 +725,7 @@ fake_prepared: } return(FALSE); case TRX_STATE_PREPARED: + case TRX_STATE_PREPARED_RECOVERED: goto func_exit; case TRX_STATE_NOT_STARTED: break; diff --git a/storage/xtradb/trx/trx0trx.cc b/storage/xtradb/trx/trx0trx.cc index 17cba81daf3..1044a9321a0 100644 --- a/storage/xtradb/trx/trx0trx.cc +++ b/storage/xtradb/trx/trx0trx.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2015, 2018, MariaDB Corporation. +Copyright (c) 2015, 2019, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -480,6 +480,7 @@ trx_free_prepared( trx_t* trx) /*!< in, own: trx object */ { ut_a(trx_state_eq(trx, TRX_STATE_PREPARED) + || trx_state_eq(trx, TRX_STATE_PREPARED_RECOVERED) || (trx->is_recovered && (trx_state_eq(trx, TRX_STATE_ACTIVE) || trx_state_eq(trx, TRX_STATE_COMMITTED_IN_MEMORY)) @@ -747,8 +748,7 @@ trx_resurrect_insert( /* trx_start_low() is not called with resurrect, so need to initialize start time here.*/ - if (trx->state == TRX_STATE_ACTIVE - || trx->state == TRX_STATE_PREPARED) { + if (trx->state != TRX_STATE_COMMITTED_IN_MEMORY) { trx->start_time = ut_time(); } @@ -1790,6 +1790,7 @@ trx_commit_or_rollback_prepare( /* fall through */ case TRX_STATE_ACTIVE: case TRX_STATE_PREPARED: + case TRX_STATE_PREPARED_RECOVERED: /* If the trx is in a lock wait state, moves the waiting query thread to the suspended state */ @@ -1927,6 +1928,7 @@ trx_commit_for_mysql( /* fall through */ case TRX_STATE_ACTIVE: case TRX_STATE_PREPARED: + case TRX_STATE_PREPARED_RECOVERED: trx->op_info = "committing"; trx_commit(trx); MONITOR_DEC(MONITOR_TRX_ACTIVE); @@ -1983,6 +1985,7 @@ trx_mark_sql_stat_end( switch (trx->state) { case TRX_STATE_PREPARED: + case TRX_STATE_PREPARED_RECOVERED: case TRX_STATE_COMMITTED_IN_MEMORY: break; case TRX_STATE_NOT_STARTED: @@ -2041,6 +2044,7 @@ trx_print_low( (ulong) difftime(time(NULL), trx->start_time)); goto state_ok; case TRX_STATE_PREPARED: + case TRX_STATE_PREPARED_RECOVERED: fprintf(f, ", ACTIVE (PREPARED) %lu sec", (ulong) difftime(time(NULL), trx->start_time)); goto state_ok; @@ -2185,6 +2189,7 @@ wsrep_trx_print_locking( (ulong) difftime(time(NULL), trx->start_time)); goto state_ok; case TRX_STATE_PREPARED: + case TRX_STATE_PREPARED_RECOVERED: fprintf(f, ", ACTIVE (PREPARED) %lu sec", (ulong) difftime(time(NULL), trx->start_time)); goto state_ok; @@ -2313,6 +2318,7 @@ trx_assert_started( switch (trx->state) { case TRX_STATE_PREPARED: + case TRX_STATE_PREPARED_RECOVERED: return(TRUE); case TRX_STATE_ACTIVE: @@ -2478,7 +2484,7 @@ trx_recover_for_mysql( XID* xid_list, /*!< in/out: prepared transactions */ ulint len) /*!< in: number of slots in xid_list */ { - const trx_t* trx; + trx_t* trx; ulint count = 0; ut_ad(xid_list); @@ -2500,6 +2506,7 @@ trx_recover_for_mysql( trx_sys->mutex. It may change to PREPARED, but not if trx->is_recovered. It may also change to COMMITTED. */ if (trx_state_eq(trx, TRX_STATE_PREPARED)) { + trx->state = TRX_STATE_PREPARED_RECOVERED; xid_list[count] = trx->xid; if (count == 0) { @@ -2524,11 +2531,22 @@ trx_recover_for_mysql( count++; if (count == len) { - break; + goto partial; } } } + /* After returning the full list, reset the state, because + there will be a second call to recover the transactions. */ + for (trx = UT_LIST_GET_FIRST(trx_sys->rw_trx_list); + trx != NULL; + trx = UT_LIST_GET_NEXT(trx_list, trx)) { + if (trx_state_eq(trx, TRX_STATE_PREPARED_RECOVERED)) { + trx->state = TRX_STATE_PREPARED; + } + } + +partial: mutex_exit(&trx_sys->mutex); if (count > 0){ @@ -2571,7 +2589,8 @@ trx_get_trx_by_xid_low( the same */ if (trx->is_recovered - && trx_state_eq(trx, TRX_STATE_PREPARED) + && (trx_state_eq(trx, TRX_STATE_PREPARED) + || trx_state_eq(trx, TRX_STATE_PREPARED_RECOVERED)) && !trx->xid.is_null() && xid->gtrid_length == trx->xid.gtrid_length && xid->bqual_length == trx->xid.bqual_length @@ -2651,6 +2670,7 @@ trx_start_if_not_started_xa_low( case TRX_STATE_ACTIVE: return; case TRX_STATE_PREPARED: + case TRX_STATE_PREPARED_RECOVERED: case TRX_STATE_COMMITTED_IN_MEMORY: break; } @@ -2677,6 +2697,7 @@ trx_start_if_not_started_low( case TRX_STATE_ACTIVE: return; case TRX_STATE_PREPARED: + case TRX_STATE_PREPARED_RECOVERED: case TRX_STATE_COMMITTED_IN_MEMORY: break; } @@ -2722,6 +2743,7 @@ trx_start_for_ddl_low( ut_ad(trx->will_lock > 0); return; case TRX_STATE_PREPARED: + case TRX_STATE_PREPARED_RECOVERED: case TRX_STATE_COMMITTED_IN_MEMORY: break; } |