summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--client/CMakeLists.txt2
-rw-r--r--man/mysql_install_db.119
-rw-r--r--mysql-test/r/gis-precise.result4
-rw-r--r--mysql-test/r/olap.result56
-rw-r--r--mysql-test/r/sp.result16
-rw-r--r--mysql-test/r/stat_tables.result70
-rw-r--r--mysql-test/r/stat_tables_innodb.result70
-rw-r--r--mysql-test/r/type_date.result25
-rw-r--r--mysql-test/r/update_innodb.result24
-rw-r--r--mysql-test/suite/archive/archive_eits.result24
-rw-r--r--mysql-test/suite/archive/archive_eits.test32
-rw-r--r--mysql-test/suite/innodb/r/foreign_key.result10
-rw-r--r--mysql-test/suite/innodb/r/xa_debug.result361
-rw-r--r--mysql-test/suite/innodb/t/foreign_key.test10
-rw-r--r--mysql-test/suite/innodb/t/xa_debug.test45
-rw-r--r--mysql-test/t/gis-precise.test6
-rw-r--r--mysql-test/t/olap.test39
-rw-r--r--mysql-test/t/sp.test9
-rw-r--r--mysql-test/t/stat_tables.test55
-rw-r--r--mysql-test/t/type_date.test14
-rw-r--r--mysql-test/t/update_innodb.test29
-rw-r--r--sql/gcalc_slicescan.cc2
-rw-r--r--sql/handler.cc1
-rw-r--r--sql/item.h49
-rw-r--r--sql/item_func.cc2
-rw-r--r--sql/item_func.h11
-rw-r--r--sql/sp_head.cc3
-rw-r--r--sql/sql_class.h3
-rw-r--r--sql/sql_parse.cc15
-rw-r--r--sql/sql_show.cc5
-rw-r--r--sql/sql_statistics.cc6
-rw-r--r--sql/sql_string.h5
-rw-r--r--sql/sql_update.cc3
-rw-r--r--storage/archive/ha_archive.cc50
-rw-r--r--storage/archive/ha_archive.h3
-rw-r--r--storage/innobase/dict/dict0dict.cc18
-rw-r--r--storage/innobase/include/trx0trx.h3
-rw-r--r--storage/innobase/include/trx0trx.ic4
-rw-r--r--storage/innobase/include/trx0types.h9
-rw-r--r--storage/innobase/lock/lock0lock.cc5
-rw-r--r--storage/innobase/row/row0undo.cc3
-rw-r--r--storage/innobase/trx/trx0roll.cc6
-rw-r--r--storage/innobase/trx/trx0trx.cc38
-rw-r--r--storage/maria/ma_test3.c2
-rw-r--r--storage/maria/maria_chk.c4
-rw-r--r--storage/myisam/mi_test3.c2
-rw-r--r--storage/myisam/myisamchk.c4
-rw-r--r--storage/perfschema/pfs_events.h12
-rw-r--r--storage/perfschema/pfs_events_waits.h34
-rw-r--r--storage/xtradb/dict/dict0dict.cc18
-rw-r--r--storage/xtradb/include/trx0trx.h5
-rw-r--r--storage/xtradb/include/trx0trx.ic3
-rw-r--r--storage/xtradb/include/trx0types.h7
-rw-r--r--storage/xtradb/lock/lock0lock.cc5
-rw-r--r--storage/xtradb/trx/trx0roll.cc6
-rw-r--r--storage/xtradb/trx/trx0trx.cc34
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;
}