summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2018-05-20 02:07:21 +0200
committerSergei Golubchik <serg@mariadb.org>2018-05-20 20:25:35 +0200
commitff1d10ef9c8595136cc7687aa59e638cf31db332 (patch)
tree1aeb1d16ce75cb40a56d34789f0b2c083e4aa8f6
parent6f530c63cd90a86e3acb5e5e6bf81c6d666025eb (diff)
parent91dfb6141f45aed5cf3fe585d8c5db86f9ddbfe9 (diff)
downloadmariadb-git-ff1d10ef9c8595136cc7687aa59e638cf31db332.tar.gz
Merge branch '10.1' into 10.2
-rwxr-xr-xmysql-test/mysql-test-run.pl81
-rw-r--r--mysql-test/r/create_or_replace.result20
-rw-r--r--mysql-test/r/grant.result5
-rw-r--r--mysql-test/r/grant_not_windows.result8
-rw-r--r--mysql-test/r/insert_select.result9
-rw-r--r--mysql-test/r/sp.result11
-rw-r--r--mysql-test/suite/innodb/r/innodb_bug54044.result6
-rw-r--r--mysql-test/suite/innodb/t/innodb_bug54044.test10
-rw-r--r--mysql-test/suite/maria/alter.result16
-rw-r--r--mysql-test/suite/maria/alter.test17
-rw-r--r--mysql-test/t/create_or_replace.test25
-rw-r--r--mysql-test/t/grant.test8
-rw-r--r--mysql-test/t/grant_not_windows.test14
-rw-r--r--mysql-test/t/insert_select.test10
-rw-r--r--mysql-test/t/mysql.test16
-rw-r--r--mysql-test/t/mysql_cp932.test42
-rw-r--r--mysql-test/t/sp.test15
-rw-r--r--sql/item.cc8
-rw-r--r--sql/sp_head.cc10
-rw-r--r--sql/sql_base.cc46
-rw-r--r--sql/sql_base.h6
-rw-r--r--sql/sql_class.cc2
-rw-r--r--sql/sql_class.h15
-rw-r--r--sql/sql_cte.cc3
-rw-r--r--sql/sql_delete.cc2
-rw-r--r--sql/sql_insert.cc3
-rw-r--r--sql/sql_lex.cc5
-rw-r--r--sql/sql_lex.h17
-rw-r--r--sql/sql_parse.cc9
-rw-r--r--sql/sql_prepare.cc2
-rw-r--r--sql/sql_select.cc2
-rw-r--r--sql/sql_table.cc31
-rw-r--r--sql/sql_trigger.cc6
-rw-r--r--sql/sql_view.cc4
-rw-r--r--storage/maria/ha_maria.cc2
-rw-r--r--storage/maria/ma_recovery.c11
36 files changed, 353 insertions, 144 deletions
diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl
index 4df6998543c..f505f40bedc 100755
--- a/mysql-test/mysql-test-run.pl
+++ b/mysql-test/mysql-test-run.pl
@@ -648,50 +648,59 @@ sub run_test_server ($$$) {
my $worker_savename= basename($worker_savedir);
my $savedir= "$opt_vardir/log/$worker_savename";
+ # Move any core files from e.g. mysqltest
+ foreach my $coref (glob("core*"), glob("*.dmp"))
+ {
+ mtr_report(" - found '$coref', moving it to '$worker_savedir'");
+ move($coref, $worker_savedir);
+ }
+
+ find(
+ {
+ no_chdir => 1,
+ wanted => sub
+ {
+ my $core_file= $File::Find::name;
+ my $core_name= basename($core_file);
+
+ # Name beginning with core, not ending in .gz
+ if (($core_name =~ /^core/ and $core_name !~ /\.gz$/)
+ or (IS_WINDOWS and $core_name =~ /\.dmp$/))
+ {
+ # Ending with .dmp
+ mtr_report(" - found '$core_name'",
+ "($num_saved_cores/$opt_max_save_core)");
+
+ My::CoreDump->show($core_file, $exe_mysqld, $opt_parallel);
+
+ # Limit number of core files saved
+ if ($opt_max_save_core > 0 &&
+ $num_saved_cores >= $opt_max_save_core)
+ {
+ mtr_report(" - deleting it, already saved",
+ "$opt_max_save_core");
+ unlink("$core_file");
+ }
+ else
+ {
+ mtr_compress_file($core_file) unless @opt_cases;
+ ++$num_saved_cores;
+ }
+ }
+ }
+ },
+ $worker_savedir);
+
if ($opt_max_save_datadir > 0 &&
$num_saved_datadir >= $opt_max_save_datadir)
{
mtr_report(" - skipping '$worker_savedir/'");
rmtree($worker_savedir);
}
- else {
+ else
+ {
mtr_report(" - saving '$worker_savedir/' to '$savedir/'");
rename($worker_savedir, $savedir);
- # Move any core files from e.g. mysqltest
- foreach my $coref (glob("core*"), glob("*.dmp"))
- {
- mtr_report(" - found '$coref', moving it to '$savedir'");
- move($coref, $savedir);
- }
- if ($opt_max_save_core > 0) {
- # Limit number of core files saved
- find({ no_chdir => 1,
- wanted => sub {
- my $core_file= $File::Find::name;
- my $core_name= basename($core_file);
-
- # Name beginning with core, not ending in .gz
- if (($core_name =~ /^core/ and $core_name !~ /\.gz$/)
- or (IS_WINDOWS and $core_name =~ /\.dmp$/)){
- # Ending with .dmp
- mtr_report(" - found '$core_name'",
- "($num_saved_cores/$opt_max_save_core)");
-
- My::CoreDump->show($core_file, $exe_mysqld, $opt_parallel);
-
- if ($num_saved_cores >= $opt_max_save_core) {
- mtr_report(" - deleting it, already saved",
- "$opt_max_save_core");
- unlink("$core_file");
- } else {
- mtr_compress_file($core_file) unless @opt_cases;
- }
- ++$num_saved_cores;
- }
- }
- },
- $savedir);
- }
}
resfile_print_test();
$num_saved_datadir++;
diff --git a/mysql-test/r/create_or_replace.result b/mysql-test/r/create_or_replace.result
index e26884f1cbf..0c1bccb861a 100644
--- a/mysql-test/r/create_or_replace.result
+++ b/mysql-test/r/create_or_replace.result
@@ -459,6 +459,26 @@ UNLOCK TABLES;
DROP FUNCTION f1;
DROP TABLE t1;
#
+# MDEV-11129
+# CREATE OR REPLACE TABLE t1 AS SELECT spfunc() crashes if spfunc()
+# references t1
+#
+CREATE OR REPLACE TABLE t1(a INT);
+CREATE FUNCTION f1() RETURNS VARCHAR(16383)
+BEGIN
+INSERT INTO t1 VALUES(1);
+RETURN 'test';
+END;
+$$
+CREATE OR REPLACE TABLE t1 AS SELECT f1();
+ERROR HY000: Table 't1' is specified twice, both as a target for 'CREATE' and as a separate source for data
+LOCK TABLE t1 WRITE;
+CREATE OR REPLACE TABLE t1 AS SELECT f1();
+ERROR HY000: Table 't1' was not locked with LOCK TABLES
+UNLOCK TABLES;
+DROP FUNCTION f1;
+DROP TABLE t1;
+#
# MDEV-11071 - Assertion `thd->transaction.stmt.is_empty()' failed in
# Locked_tables_list::unlock_locked_tables
#
diff --git a/mysql-test/r/grant.result b/mysql-test/r/grant.result
index b250137ebf8..118d1f2134b 100644
--- a/mysql-test/r/grant.result
+++ b/mysql-test/r/grant.result
@@ -1705,11 +1705,6 @@ drop user mysqluser11@localhost;
drop database mysqltest1;
End of 5.0 tests
set names utf8;
-grant select on test.* to юзер_юзер@localhost;
-user()
-юзер_юзер@localhost
-revoke all on test.* from юзер_юзер@localhost;
-drop user юзер_юзер@localhost;
grant select on test.* to очень_длинный_юзер890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890@localhost;
ERROR HY000: String 'очень_длинный_юзер890123456789012345678901234567890123' is too long for user name (should be no longer than 80)
set names default;
diff --git a/mysql-test/r/grant_not_windows.result b/mysql-test/r/grant_not_windows.result
new file mode 100644
index 00000000000..fedfaf984b2
--- /dev/null
+++ b/mysql-test/r/grant_not_windows.result
@@ -0,0 +1,8 @@
+set names utf8;
+create user юзер_юзер@localhost;
+grant select on test.* to юзер_юзер@localhost;
+user()
+юзер_юзер@localhost
+revoke all on test.* from юзер_юзер@localhost;
+drop user юзер_юзер@localhost;
+set names default;
diff --git a/mysql-test/r/insert_select.result b/mysql-test/r/insert_select.result
index 1a3a38b1f35..b86c859d0bd 100644
--- a/mysql-test/r/insert_select.result
+++ b/mysql-test/r/insert_select.result
@@ -856,3 +856,12 @@ INSERT IGNORE INTO t1 SELECT t1.a FROM t1,t1 t2,t1 t3,t1 t4,t1 t5,t1 t6,t1 t7;
SET GLOBAL myisam_data_pointer_size = @old_myisam_data_pointer_size;
DROP TABLE t1;
End of 5.1 tests
+create table t1 (i int);
+create table t2 as select values(i) as a from t1;
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `a` binary(0) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1, t2;
+End of 5.5 tests
diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result
index 537da742032..ad8dc15318e 100644
--- a/mysql-test/r/sp.result
+++ b/mysql-test/r/sp.result
@@ -8250,6 +8250,17 @@ DROP PROCEDURE proc_13;
DROP PROCEDURE proc_select;
DROP TABLE t1, t2;
SET max_sp_recursion_depth=default;
+#
+# MDEV-15347: Valgrind or ASAN errors in mysql_make_view on query
+# from information_schema
+#
+CREATE VIEW v AS SELECT 1;
+CREATE FUNCTION f() RETURNS INT RETURN 1;
+SELECT * FROM INFORMATION_SCHEMA.TABLES JOIN INFORMATION_SCHEMA.PARAMETERS
+UNION
+SELECT * FROM INFORMATION_SCHEMA.TABLES JOIN INFORMATION_SCHEMA.PARAMETERS;
+DROP FUNCTION f;
+DROP VIEW v;
#End of 10.1 tests
#
# MDEV-11081: CURSOR for query with GROUP BY
diff --git a/mysql-test/suite/innodb/r/innodb_bug54044.result b/mysql-test/suite/innodb/r/innodb_bug54044.result
index 0761c7764e6..29b0127f20b 100644
--- a/mysql-test/suite/innodb/r/innodb_bug54044.result
+++ b/mysql-test/suite/innodb/r/innodb_bug54044.result
@@ -16,9 +16,3 @@ tmp CREATE TABLE `tmp` (
`NULL` binary(0) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1
DROP TABLE tmp;
-CREATE TABLE t1 (a VARCHAR(3)) ENGINE=InnoDB;
-INSERT INTO t1 VALUES ('foo'),('bar');
-FLUSH TABLES;
-CREATE TEMPORARY TABLE tmp ENGINE=InnoDB AS SELECT VALUES(a) FROM t1;
-ERROR HY000: Can't create table `test`.`tmp` (errno: 168 "Unknown (generic) error from engine")
-DROP TABLE t1;
diff --git a/mysql-test/suite/innodb/t/innodb_bug54044.test b/mysql-test/suite/innodb/t/innodb_bug54044.test
index 61a09375ae1..cfc6f3c3f0a 100644
--- a/mysql-test/suite/innodb/t/innodb_bug54044.test
+++ b/mysql-test/suite/innodb/t/innodb_bug54044.test
@@ -16,13 +16,3 @@ CREATE TABLE tmp ENGINE = INNODB
AS SELECT COALESCE(NULL, NULL, NULL), GREATEST(NULL, NULL), NULL;
SHOW CREATE TABLE tmp;
DROP TABLE tmp;
-
-# These 'create table' operations should fail because of
-# using NULL datatype
-
-CREATE TABLE t1 (a VARCHAR(3)) ENGINE=InnoDB;
-INSERT INTO t1 VALUES ('foo'),('bar');
-FLUSH TABLES;
---error 1005
-CREATE TEMPORARY TABLE tmp ENGINE=InnoDB AS SELECT VALUES(a) FROM t1;
-DROP TABLE t1;
diff --git a/mysql-test/suite/maria/alter.result b/mysql-test/suite/maria/alter.result
index 1a7daf5a1ee..c63688dddd6 100644
--- a/mysql-test/suite/maria/alter.result
+++ b/mysql-test/suite/maria/alter.result
@@ -31,3 +31,19 @@ pk i
8 88
9 99
DROP TABLE t1;
+CREATE TABLE t1 (f INT) ENGINE=Aria transactional=1;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `f` int(11) DEFAULT NULL
+) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=1
+INSERT INTO t1 VALUES (1),(2);
+ALTER TABLE t1 ORDER BY unknown_column;
+ERROR 42S22: Unknown column 'unknown_column' in 'order clause'
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `f` int(11) DEFAULT NULL
+) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1 TRANSACTIONAL=1
+CREATE TABLE t2 SELECT * FROM t1;
+DROP TABLE t1, t2;
diff --git a/mysql-test/suite/maria/alter.test b/mysql-test/suite/maria/alter.test
index abca4865688..09672cdfa3b 100644
--- a/mysql-test/suite/maria/alter.test
+++ b/mysql-test/suite/maria/alter.test
@@ -25,3 +25,20 @@ INSERT INTO t1 VALUES (2,0),(3,33),(4,0),(5,55),(6,66),(7,0),(8,88),(9,99);
ALTER TABLE t1 ENABLE KEYS;
SELECT * FROM t1 WHERE i = 0 OR pk BETWEEN 6 AND 10;
DROP TABLE t1;
+
+#
+# MDEV-14943
+# Assertion `block->type == PAGECACHE_EMPTY_PAGE || block->type == type ||
+# type == PAGECACHE_LSN_PAGE || type == PAGECACHE_READ_UNKNOWN_PAGE ||
+# block->type == PAGECACHE_READ_UNKNOWN_PAGE' failed in pagecache_read upon
+# CREATE ... SELECT from Aria table
+#
+
+CREATE TABLE t1 (f INT) ENGINE=Aria transactional=1;
+SHOW CREATE TABLE t1;
+INSERT INTO t1 VALUES (1),(2);
+--error ER_BAD_FIELD_ERROR
+ALTER TABLE t1 ORDER BY unknown_column;
+SHOW CREATE TABLE t1;
+CREATE TABLE t2 SELECT * FROM t1;
+DROP TABLE t1, t2;
diff --git a/mysql-test/t/create_or_replace.test b/mysql-test/t/create_or_replace.test
index 4ef4189694b..3ae882139bc 100644
--- a/mysql-test/t/create_or_replace.test
+++ b/mysql-test/t/create_or_replace.test
@@ -398,6 +398,31 @@ DROP FUNCTION f1;
DROP TABLE t1;
--echo #
+--echo # MDEV-11129
+--echo # CREATE OR REPLACE TABLE t1 AS SELECT spfunc() crashes if spfunc()
+--echo # references t1
+--echo #
+
+CREATE OR REPLACE TABLE t1(a INT);
+DELIMITER $$;
+CREATE FUNCTION f1() RETURNS VARCHAR(16383)
+BEGIN
+ INSERT INTO t1 VALUES(1);
+ RETURN 'test';
+END;
+$$
+DELIMITER ;$$
+--error ER_UPDATE_TABLE_USED
+CREATE OR REPLACE TABLE t1 AS SELECT f1();
+LOCK TABLE t1 WRITE;
+--error ER_TABLE_NOT_LOCKED
+CREATE OR REPLACE TABLE t1 AS SELECT f1();
+UNLOCK TABLES;
+
+DROP FUNCTION f1;
+DROP TABLE t1;
+
+--echo #
--echo # MDEV-11071 - Assertion `thd->transaction.stmt.is_empty()' failed in
--echo # Locked_tables_list::unlock_locked_tables
--echo #
diff --git a/mysql-test/t/grant.test b/mysql-test/t/grant.test
index c945e818181..72e427493da 100644
--- a/mysql-test/t/grant.test
+++ b/mysql-test/t/grant.test
@@ -1510,15 +1510,7 @@ drop database mysqltest1;
--echo End of 5.0 tests
-
-#
-# Bug#21432 Database/Table name limited to 64 bytes, not chars, problems with multi-byte
-#
set names utf8;
-grant select on test.* to юзер_юзер@localhost;
---exec $MYSQL --default-character-set=utf8 --user=юзер_юзер -e "select user()"
-revoke all on test.* from юзер_юзер@localhost;
-drop user юзер_юзер@localhost;
--error ER_WRONG_STRING_LENGTH
grant select on test.* to очень_длинный_юзер890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890@localhost;
set names default;
diff --git a/mysql-test/t/grant_not_windows.test b/mysql-test/t/grant_not_windows.test
new file mode 100644
index 00000000000..55b09232edc
--- /dev/null
+++ b/mysql-test/t/grant_not_windows.test
@@ -0,0 +1,14 @@
+ # UTF8 parameters to mysql client do not work on Windows
+--source include/not_windows.inc
+--source include/not_embedded.inc
+
+#
+# Bug#21432 Database/Table name limited to 64 bytes, not chars, problems with multi-byte
+#
+set names utf8;
+create user юзер_юзер@localhost;
+grant select on test.* to юзер_юзер@localhost;
+--exec $MYSQL --default-character-set=utf8 --user=юзер_юзер -e "select user()"
+revoke all on test.* from юзер_юзер@localhost;
+drop user юзер_юзер@localhost;
+set names default;
diff --git a/mysql-test/t/insert_select.test b/mysql-test/t/insert_select.test
index fda89f18d99..27a831fbe3f 100644
--- a/mysql-test/t/insert_select.test
+++ b/mysql-test/t/insert_select.test
@@ -425,3 +425,13 @@ SET GLOBAL myisam_data_pointer_size = @old_myisam_data_pointer_size;
DROP TABLE t1;
--echo End of 5.1 tests
+
+#
+# MDEV-15318 CREATE .. SELECT VALUES produces invalid table structure
+#
+create table t1 (i int);
+create table t2 as select values(i) as a from t1;
+show create table t2;
+drop table t1, t2;
+
+--echo End of 5.5 tests
diff --git a/mysql-test/t/mysql.test b/mysql-test/t/mysql.test
index 300695612fd..fc2ae849aa6 100644
--- a/mysql-test/t/mysql.test
+++ b/mysql-test/t/mysql.test
@@ -53,14 +53,22 @@ drop table t1;
#
# Bug#17939 Wrong table format when using UTF8 strings
-#
---exec $MYSQL --default-character-set=utf8 --table -e "SELECT 'John Doe' as '__tañgè Ñãmé'" 2>&1
---exec $MYSQL --default-character-set=utf8 --table -e "SELECT '__tañgè Ñãmé' as 'John Doe'" 2>&1
+write_file $MYSQL_TMP_DIR/mysql_in;
+SELECT 'John Doe' as '__tañgè Ñãmé';
+SELECT '__tañgè Ñãmé' as 'John Doe';
+EOF
+--exec $MYSQL --default-character-set=utf8 --table < $MYSQL_TMP_DIR/mysql_in 2>&1
+remove_file $MYSQL_TMP_DIR/mysql_in;
#
# Bug#18265 -- mysql client: No longer right-justifies numeric columns
#
---exec $MYSQL -t --default-character-set utf8 test -e "create table t1 (i int, j int, k char(25) charset utf8); insert into t1 (i) values (1); insert into t1 (k) values ('<----------------------->'); insert into t1 (k) values ('<-----'); insert into t1 (k) values ('Τη γλώσσα'); insert into t1 (k) values ('ᛖᚴ ᚷᛖᛏ'); select * from t1; DROP TABLE t1;"
+write_file $MYSQL_TMP_DIR/mysql_in;
+create table t1 (i int, j int, k char(25) charset utf8); insert into t1 (i) values (1); insert into t1 (k) values ('<----------------------->'); insert into t1 (k) values ('<-----'); insert into t1 (k) values ('Τη γλώσσα'); insert into t1 (k) values ('ᛖᚴ ᚷᛖᛏ'); select * from t1; DROP TABLE t1;
+EOF
+--exec $MYSQL -t --default-character-set utf8 test < $MYSQL_TMP_DIR/mysql_in
+remove_file $MYSQL_TMP_DIR/mysql_in;
+
#
# "DESCRIBE" commands may return strange NULLness flags.
diff --git a/mysql-test/t/mysql_cp932.test b/mysql-test/t/mysql_cp932.test
index 60a129c3805..8fba5750d89 100644
--- a/mysql-test/t/mysql_cp932.test
+++ b/mysql-test/t/mysql_cp932.test
@@ -10,13 +10,43 @@
# BUG#16217 - MySQL client misinterprets multi-byte char as escape `\'
#
+let $mysql_in= $MYSQL_TMP_DIR/mysql_in;
+
# new command \C or charset
---exec $MYSQL --default-character-set=utf8 test -e "\C cp932 \g"
---exec $MYSQL --default-character-set=cp932 test -e "charset utf8;"
+write_file $mysql_in;
+\C cp932 \g
+EOF
+--exec $MYSQL --default-character-set=utf8 test < $mysql_in
+remove_file $mysql_in;
+
+write_file $mysql_in;
+charset utf8;
+EOF
+--exec $MYSQL --default-character-set=cp932 test < $mysql_in
+remove_file $mysql_in;
# its usage to switch internally in mysql to requested charset
---exec $MYSQL --default-character-set=utf8 test -e "charset cp932; select '\'; create table t1 (c_cp932 TEXT CHARACTER SET cp932); insert into t1 values('\'); select * from t1; drop table t1;"
---exec $MYSQL --default-character-set=utf8 test -e "charset cp932; select '\'"
---exec $MYSQL --default-character-set=utf8 test -e "/*charset cp932 */; set character_set_client= cp932; select '\'"
---exec $MYSQL --default-character-set=utf8 test -e "/*!\C cp932 */; set character_set_client= cp932; select '\'"
+write_file $mysql_in;
+charset cp932; select '\'; create table t1 (c_cp932 TEXT CHARACTER SET cp932); insert into t1 values('\'); select * from t1; drop table t1;
+EOF
+--exec $MYSQL --default-character-set=utf8 test < $mysql_in
+remove_file $mysql_in;
+
+write_file $mysql_in;
+charset cp932; select '\'
+EOF
+--exec $MYSQL --default-character-set=utf8 test < $mysql_in
+remove_file $mysql_in;
+
+write_file $mysql_in;
+/*charset cp932 */; set character_set_client= cp932; select '\'
+EOF
+--exec $MYSQL --default-character-set=utf8 test < $mysql_in
+remove_file $mysql_in;
+
+write_file $mysql_in;
+/*!\C cp932 */; set character_set_client= cp932; select '\'
+EOF
+--exec $MYSQL --default-character-set=utf8 test < $mysql_in
+remove_file $mysql_in;
diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test
index b7a84bccb47..549d97ad72b 100644
--- a/mysql-test/t/sp.test
+++ b/mysql-test/t/sp.test
@@ -9747,6 +9747,21 @@ DROP TABLE t1, t2;
SET max_sp_recursion_depth=default;
+--echo #
+--echo # MDEV-15347: Valgrind or ASAN errors in mysql_make_view on query
+--echo # from information_schema
+--echo #
+
+CREATE VIEW v AS SELECT 1;
+CREATE FUNCTION f() RETURNS INT RETURN 1;
+--disable_result_log
+SELECT * FROM INFORMATION_SCHEMA.TABLES JOIN INFORMATION_SCHEMA.PARAMETERS
+UNION
+SELECT * FROM INFORMATION_SCHEMA.TABLES JOIN INFORMATION_SCHEMA.PARAMETERS;
+--enable_result_log
+DROP FUNCTION f;
+DROP VIEW v;
+
--echo #End of 10.1 tests
--echo #
diff --git a/sql/item.cc b/sql/item.cc
index 68761293682..f9200ccf56d 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -9153,10 +9153,10 @@ bool Item_insert_value::fix_fields(THD *thd, Item **items)
}
else
{
- Field *tmp_field= field_arg->field;
- /* charset doesn't matter here, it's to avoid sigsegv only */
- tmp_field= new Field_null(0, 0, Field::NONE, field_arg->field->field_name,
- &my_charset_bin);
+ static uchar null_bit=1;
+ /* charset doesn't matter here */
+ Field *tmp_field= new Field_string(0, 0, &null_bit, 1, Field::NONE,
+ field_arg->field->field_name, &my_charset_bin);
if (tmp_field)
{
tmp_field->init(field_arg->field->table);
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 081d8cb9c23..a832aa91004 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -822,7 +822,7 @@ sp_head::~sp_head()
thd->lex->sphead= NULL;
lex_end(thd->lex);
delete thd->lex;
- thd->lex= thd->stmt_lex= lex;
+ thd->lex= lex;
}
my_hash_free(&m_sptabs);
@@ -1129,7 +1129,7 @@ sp_head::execute(THD *thd, bool merge_da_on_success)
backup_arena;
query_id_t old_query_id;
TABLE *old_derived_tables;
- LEX *old_lex, *old_stmt_lex;
+ LEX *old_lex;
Item_change_list old_change_list;
String old_packet;
uint old_server_status;
@@ -1233,7 +1233,6 @@ sp_head::execute(THD *thd, bool merge_da_on_success)
do it in each instruction
*/
old_lex= thd->lex;
- old_stmt_lex= thd->stmt_lex;
/*
We should also save Item tree change list to avoid rollback something
too early in the calling query.
@@ -1383,7 +1382,6 @@ sp_head::execute(THD *thd, bool merge_da_on_success)
DBUG_ASSERT(thd->Item_change_list::is_empty());
old_change_list.move_elements_to(thd);
thd->lex= old_lex;
- thd->stmt_lex= old_stmt_lex;
thd->set_query_id(old_query_id);
DBUG_ASSERT(!thd->derived_tables);
thd->derived_tables= old_derived_tables;
@@ -2220,7 +2218,7 @@ sp_head::reset_lex(THD *thd)
if (sublex == 0)
DBUG_RETURN(TRUE);
- thd->lex= thd->stmt_lex= sublex;
+ thd->lex= sublex;
(void)m_lex.push_front(oldlex);
/* Reset most stuff. */
@@ -2964,7 +2962,7 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp,
We should not save old value since it is saved/restored in
sp_head::execute() when we are entering/leaving routine.
*/
- thd->lex= thd->stmt_lex= m_lex;
+ thd->lex= m_lex;
thd->set_query_id(next_query_id());
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 4ba74804a05..9dfaf82758c 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -943,7 +943,8 @@ TABLE_LIST *find_table_in_list(TABLE_LIST *table,
@param thd thread handle
@param table table which should be checked
@param table_list list of tables
- @param check_alias whether to check tables' aliases
+ @param check_flag whether to check tables' aliases
+ Currently this is only used by INSERT
NOTE: to exclude derived tables from check we use following mechanism:
a) during derived table processing set THD::derived_tables_processing
@@ -972,9 +973,9 @@ TABLE_LIST *find_table_in_list(TABLE_LIST *table,
static
TABLE_LIST* find_dup_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list,
- bool check_alias)
+ uint check_flag)
{
- TABLE_LIST *res;
+ TABLE_LIST *res= 0;
const char *d_name, *t_name, *t_alias;
DBUG_ENTER("find_dup_table");
DBUG_PRINT("enter", ("table alias: %s", table->alias));
@@ -1007,17 +1008,15 @@ TABLE_LIST* find_dup_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list,
retry:
DBUG_PRINT("info", ("real table: %s.%s", d_name, t_name));
- for (TABLE_LIST *tl= table_list;;)
+ for (TABLE_LIST *tl= table_list; tl ; tl= tl->next_global, res= 0)
{
- if (tl &&
- tl->select_lex && tl->select_lex->master_unit() &&
+ if (tl->select_lex && tl->select_lex->master_unit() &&
tl->select_lex->master_unit()->executed)
{
/*
There is no sense to check tables of already executed parts
of the query
*/
- tl= tl->next_global;
continue;
}
/*
@@ -1026,21 +1025,29 @@ retry:
*/
if (! (res= find_table_in_global_list(tl, d_name, t_name)))
break;
+ tl= res; // We can continue search after this table
/* Skip if same underlying table. */
if (res->table && (res->table == table->table))
- goto next;
+ continue;
+
+ if (check_flag & CHECK_DUP_FOR_CREATE)
+ DBUG_RETURN(res);
/* Skip if table alias does not match. */
- if (check_alias)
+ if (check_flag & CHECK_DUP_ALLOW_DIFFERENT_ALIAS)
{
if (my_strcasecmp(table_alias_charset, t_alias, res->alias))
- goto next;
+ continue;
}
/*
- Skip if marked to be excluded (could be a derived table) or if
- entry is a prelocking placeholder.
+ If table is not excluded (could be a derived table) and table is not
+ a prelocking placeholder then we found either a duplicate entry
+ or a table that is part of a derived table (handled below).
+ Examples are:
+ INSERT INTO t1 SELECT * FROM t1;
+ INSERT INTO t1 SELECT * FROM view_containing_t1;
*/
if (res->select_lex &&
!res->select_lex->exclude_from_table_unique_test &&
@@ -1052,14 +1059,17 @@ retry:
processed in derived table or top select of multi-update/multi-delete
(exclude_from_table_unique_test) or prelocking placeholder.
*/
-next:
- tl= res->next_global;
DBUG_PRINT("info",
("found same copy of table or table which we should skip"));
}
if (res && res->belong_to_derived)
{
- /* Try to fix */
+ /*
+ We come here for queries of type:
+ INSERT INTO t1 (SELECT tmp.a FROM (select * FROM t1) as tmp);
+
+ Try to fix by materializing the derived table
+ */
TABLE_LIST *derived= res->belong_to_derived;
if (derived->is_merged_derived() && !derived->derived->is_excluded())
{
@@ -1091,7 +1101,7 @@ next:
TABLE_LIST*
unique_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list,
- bool check_alias)
+ uint check_flag)
{
TABLE_LIST *dup;
@@ -1105,12 +1115,12 @@ unique_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list,
for (child= table->next_global; child && child->parent_l == table;
child= child->next_global)
{
- if ((dup= find_dup_table(thd, child, child->next_global, check_alias)))
+ if ((dup= find_dup_table(thd, child, child->next_global, check_flag)))
break;
}
}
else
- dup= find_dup_table(thd, table, table_list, check_alias);
+ dup= find_dup_table(thd, table, table_list, check_flag);
return dup;
}
/*
diff --git a/sql/sql_base.h b/sql/sql_base.h
index c59a24e4272..914cdcd4512 100644
--- a/sql/sql_base.h
+++ b/sql/sql_base.h
@@ -61,6 +61,10 @@ enum find_item_error_report_type {REPORT_ALL_ERRORS, REPORT_EXCEPT_NOT_FOUND,
IGNORE_ERRORS, REPORT_EXCEPT_NON_UNIQUE,
IGNORE_EXCEPT_NON_UNIQUE};
+/* Flag bits for unique_table() */
+#define CHECK_DUP_ALLOW_DIFFERENT_ALIAS 1
+#define CHECK_DUP_FOR_CREATE 2
+
uint get_table_def_key(const TABLE_LIST *table_list, const char **key);
TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type update,
uint lock_flags);
@@ -262,7 +266,7 @@ bool lock_tables(THD *thd, TABLE_LIST *tables, uint counter, uint flags);
int decide_logging_format(THD *thd, TABLE_LIST *tables);
void close_thread_table(THD *thd, TABLE **table_ptr);
TABLE_LIST *unique_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list,
- bool check_alias);
+ uint check_flag);
bool is_equal(const LEX_STRING *a, const LEX_STRING *b);
class Open_tables_backup;
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 87fe68ed967..23eda5ead77 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -3603,7 +3603,7 @@ void Statement::set_statement(Statement *stmt)
{
id= stmt->id;
mark_used_columns= stmt->mark_used_columns;
- stmt_lex= lex= stmt->lex;
+ lex= stmt->lex;
query_string= stmt->query_string;
}
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 1e866e1da6d..7302881ace2 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -1054,21 +1054,6 @@ public:
LEX_STRING name; /* name for named prepared statements */
LEX *lex; // parse tree descriptor
/*
- LEX which represents current statement (conventional, SP or PS)
-
- For example during view parsing THD::lex will point to the views LEX and
- THD::stmt_lex will point to LEX of the statement where the view will be
- included
-
- Currently it is used to have always correct select numbering inside
- statement (LEX::current_select_number) without storing and restoring a
- global counter which was THD::select_number.
-
- TODO: make some unified statement representation (now SP has different)
- to store such data like LEX::current_select_number.
- */
- LEX *stmt_lex;
- /*
Points to the query associated with this statement. It's const, but
we need to declare it char * because all table handlers are written
in C and need to point to it.
diff --git a/sql/sql_cte.cc b/sql/sql_cte.cc
index fdd6943af93..45f24c3a248 100644
--- a/sql/sql_cte.cc
+++ b/sql/sql_cte.cc
@@ -817,8 +817,9 @@ st_select_lex_unit *With_element::clone_parsed_spec(THD *thd,
if (parser_state.init(thd, unparsed_spec.str, unparsed_spec.length))
goto err;
lex_start(thd);
+ lex->stmt_lex= old_lex;
with_select= &lex->select_lex;
- with_select->select_number= ++thd->stmt_lex->current_select_number;
+ with_select->select_number= ++thd->lex->stmt_lex->current_select_number;
parse_status= parse_sql(thd, &parser_state, 0);
if (parse_status)
goto err;
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index 48509a46ccb..93c7b0580bb 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -951,7 +951,7 @@ multi_delete::initialize_tables(JOIN *join)
TABLE_LIST *tbl= walk->correspondent_table->find_table_for_update();
tables_to_delete_from|= tbl->table->map;
if (delete_while_scanning &&
- unique_table(thd, tbl, join->tables_list, false))
+ unique_table(thd, tbl, join->tables_list, 0))
{
/*
If the table we are going to delete from appears
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index a5f1249c139..c24503677ca 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -1561,7 +1561,8 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
{
Item *fake_conds= 0;
TABLE_LIST *duplicate;
- if ((duplicate= unique_table(thd, table_list, table_list->next_global, 1)))
+ if ((duplicate= unique_table(thd, table_list, table_list->next_global,
+ CHECK_DUP_ALLOW_DIFFERENT_ALIAS)))
{
update_non_unique_table_error(table_list, "INSERT", duplicate);
DBUG_RETURN(TRUE);
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 7c963be695a..750fb75bfb9 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -654,10 +654,11 @@ void lex_start(THD *thd)
{
LEX *lex= thd->lex;
DBUG_ENTER("lex_start");
- DBUG_PRINT("info", ("Lex %p stmt_lex: %p", thd->lex, thd->stmt_lex));
+ DBUG_PRINT("info", ("Lex %p", thd->lex));
lex->thd= lex->unit.thd= thd;
-
+
+ lex->stmt_lex= lex; // default, should be rewritten for VIEWs And CTEs
DBUG_ASSERT(!lex->explain);
lex->context_stack.empty();
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 4acb1e441c1..ed5e423fd5a 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -770,7 +770,7 @@ public:
/*
Point to the LEX in which it was created, used in view subquery detection.
- TODO: make also st_select_lex::parent_stmt_lex (see THD::stmt_lex)
+ TODO: make also st_select_lex::parent_stmt_lex (see LEX::stmt_lex)
and use st_select_lex::parent_lex & st_select_lex::parent_stmt_lex
instead of global (from THD) references where it is possible.
*/
@@ -2553,6 +2553,21 @@ struct LEX: public Query_tables_list
// type information
CHARSET_INFO *charset;
+ /*
+ LEX which represents current statement (conventional, SP or PS)
+
+ For example during view parsing THD::lex will point to the views LEX and
+ lex::stmt_lex will point to LEX of the statement where the view will be
+ included
+
+ Currently it is used to have always correct select numbering inside
+ statement (LEX::current_select_number) without storing and restoring a
+ global counter which was THD::select_number.
+
+ TODO: make some unified statement representation (now SP has different)
+ to store such data like LEX::current_select_number.
+ */
+ LEX *stmt_lex;
LEX_STRING name;
char *help_arg;
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 52aa6bf9381..f4038649745 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -3913,7 +3913,7 @@ mysql_execute_command(THD *thd)
TABLE_LIST *duplicate;
if ((duplicate= unique_table(thd, lex->query_tables,
lex->query_tables->next_global,
- 0)))
+ CHECK_DUP_FOR_CREATE)))
{
update_non_unique_table_error(lex->query_tables, "CREATE",
duplicate);
@@ -7457,8 +7457,9 @@ void THD::reset_for_next_command(bool do_clear_error)
We also assign thd->stmt_lex in lex_start(), but during bootstrap this
code is executed first.
*/
- thd->stmt_lex= &main_lex; thd->stmt_lex->current_select_number= 1;
- DBUG_PRINT("info", ("Lex %p stmt_lex: %p", thd->lex, thd->stmt_lex));
+ DBUG_ASSERT(lex == &main_lex);
+ main_lex.stmt_lex= &main_lex; main_lex.current_select_number= 1;
+ DBUG_PRINT("info", ("Lex and stmt_lex: %p", &main_lex));
/*
Those two lines below are theoretically unneeded as
THD::cleanup_after_query() should take care of this already.
@@ -7575,7 +7576,7 @@ mysql_new_select(LEX *lex, bool move_down)
if (!(select_lex= new (thd->mem_root) SELECT_LEX()))
DBUG_RETURN(1);
- select_lex->select_number= ++thd->stmt_lex->current_select_number;
+ select_lex->select_number= ++thd->lex->stmt_lex->current_select_number;
select_lex->parent_lex= lex; /* Used in init_query. */
select_lex->init_query();
select_lex->init_select();
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index 8a95719069c..d209707fbd7 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -3921,7 +3921,7 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len)
if (! (lex= new (mem_root) st_lex_local))
DBUG_RETURN(TRUE);
- stmt_lex= lex;
+ lex->stmt_lex= lex;
if (set_db(thd->db, thd->db_length))
DBUG_RETURN(TRUE);
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 72096804a24..ee5ba4ade54 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -3313,7 +3313,7 @@ void JOIN::save_explain_data(Explain_query *output, bool can_overwrite,
bool distinct)
{
/*
- If there is SELECT in this statemet with the same number it must be the
+ If there is SELECT in this statement with the same number it must be the
same SELECT
*/
DBUG_ASSERT(select_lex->select_number == UINT_MAX ||
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index b6d46ff82ab..164634f17ca 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -9761,9 +9761,7 @@ bool mysql_trans_prepare_alter_copy_data(THD *thd)
This needs to be done before external_lock.
*/
- if (ha_enable_transaction(thd, FALSE))
- DBUG_RETURN(TRUE);
- DBUG_RETURN(FALSE);
+ DBUG_RETURN(ha_enable_transaction(thd, FALSE) != 0);
}
@@ -9816,6 +9814,7 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to,
List<Item> fields;
List<Item> all_fields;
bool auto_increment_field_copied= 0;
+ bool cleanup_done= 0;
bool init_read_record_done= 0;
sql_mode_t save_sql_mode= thd->variables.sql_mode;
ulonglong prev_insert_id, time_to_report_progress;
@@ -9825,15 +9824,23 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to,
/* Two or 3 stages; Sorting, copying data and update indexes */
thd_progress_init(thd, 2 + MY_TEST(order));
- if (mysql_trans_prepare_alter_copy_data(thd))
- DBUG_RETURN(-1);
-
if (!(copy= new Copy_field[to->s->fields]))
DBUG_RETURN(-1); /* purecov: inspected */
+ if (mysql_trans_prepare_alter_copy_data(thd))
+ {
+ delete [] copy;
+ DBUG_RETURN(-1);
+ }
+
/* We need external lock before we can disable/enable keys */
if (to->file->ha_external_lock(thd, F_WRLCK))
+ {
+ /* Undo call to mysql_trans_prepare_alter_copy_data() */
+ ha_enable_transaction(thd, TRUE);
+ delete [] copy;
DBUG_RETURN(-1);
+ }
alter_table_manage_keys(to, from->file->indexes_are_disabled(), keys_onoff);
@@ -9843,7 +9850,6 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to,
from->file->info(HA_STATUS_VARIABLE);
to->file->ha_start_bulk_insert(from->file->stats.records,
ignore ? 0 : HA_CREATE_UNIQUE_INDEX_BY_SORT);
-
List_iterator<Create_field> it(create);
Create_field *def;
copy_end=copy;
@@ -10067,6 +10073,8 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to,
}
if (!ignore)
to->file->extra(HA_EXTRA_END_ALTER_COPY);
+
+ cleanup_done= 1;
to->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
if (mysql_trans_commit_alter_copy_data(thd))
@@ -10084,6 +10092,15 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to,
*copied= found_count;
*deleted=delete_count;
to->file->ha_release_auto_increment();
+
+ if (!cleanup_done)
+ {
+ /* This happens if we get an error during initialzation of data */
+ DBUG_ASSERT(error);
+ to->file->ha_end_bulk_insert();
+ ha_enable_transaction(thd, TRUE);
+ }
+
if (to->file->ha_external_lock(thd,F_UNLCK))
error=1;
if (error < 0 && !from->s->tmp_table &&
diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc
index 0fefe7d2c52..8f76e7a537e 100644
--- a/sql/sql_trigger.cc
+++ b/sql/sql_trigger.cc
@@ -1358,12 +1358,12 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db,
List_iterator_fast<LEX_STRING> it_connection_cl_name(trigger_list->connection_cl_names);
List_iterator_fast<LEX_STRING> it_db_cl_name(trigger_list->db_cl_names);
List_iterator_fast<ulonglong> it_create_times(trigger_list->create_times);
- LEX *old_lex= thd->lex, *old_stmt_lex= thd->stmt_lex;
+ LEX *old_lex= thd->lex;
LEX lex;
sp_rcontext *save_spcont= thd->spcont;
sql_mode_t save_sql_mode= thd->variables.sql_mode;
- thd->lex= thd->stmt_lex= &lex;
+ thd->lex= &lex;
save_db.str= thd->db;
save_db.length= thd->db_length;
@@ -1581,7 +1581,6 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db,
}
thd->reset_db(save_db.str, save_db.length);
thd->lex= old_lex;
- thd->stmt_lex= old_stmt_lex;
thd->spcont= save_spcont;
thd->variables.sql_mode= save_sql_mode;
@@ -1595,7 +1594,6 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db,
err_with_lex_cleanup:
lex_end(&lex);
thd->lex= old_lex;
- thd->stmt_lex= old_stmt_lex;
thd->spcont= save_spcont;
thd->variables.sql_mode= save_sql_mode;
thd->reset_db(save_db.str, save_db.length);
diff --git a/sql/sql_view.cc b/sql/sql_view.cc
index 024fe53ce83..e3bdde77ee3 100644
--- a/sql/sql_view.cc
+++ b/sql/sql_view.cc
@@ -1323,6 +1323,7 @@ bool mysql_make_view(THD *thd, TABLE_SHARE *share, TABLE_LIST *table,
now Lex placed in statement memory
*/
+
table->view= lex= thd->lex= (LEX*) new(thd->mem_root) st_lex_local;
if (!table->view)
{
@@ -1348,8 +1349,9 @@ bool mysql_make_view(THD *thd, TABLE_SHARE *share, TABLE_LIST *table,
goto end;
lex_start(thd);
+ lex->stmt_lex= old_lex;
view_select= &lex->select_lex;
- view_select->select_number= ++thd->stmt_lex->current_select_number;
+ view_select->select_number= ++thd->lex->stmt_lex->current_select_number;
sql_mode_t saved_mode= thd->variables.sql_mode;
/* switch off modes which can prevent normal parsing of VIEW
diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc
index 16260dcf33a..b4ae46683e4 100644
--- a/storage/maria/ha_maria.cc
+++ b/storage/maria/ha_maria.cc
@@ -1334,6 +1334,7 @@ int ha_maria::check(THD * thd, HA_CHECK_OPT * check_opt)
old_proc_info= thd_proc_info(thd, "Checking status");
thd_progress_init(thd, 3);
error= maria_chk_status(param, file); // Not fatal
+ /* maria_chk_size() will flush the page cache for this file */
if (maria_chk_size(param, file))
error= 1;
if (!error)
@@ -2236,6 +2237,7 @@ end:
_ma_reenable_logging_for_table(file,
bulk_insert_single_undo ==
BULK_INSERT_SINGLE_UNDO_AND_NO_REPAIR);
+ bulk_insert_single_undo= BULK_INSERT_NONE; // Safety
}
DBUG_RETURN(err);
}
diff --git a/storage/maria/ma_recovery.c b/storage/maria/ma_recovery.c
index ad1df75f19e..d9f2f6e77d2 100644
--- a/storage/maria/ma_recovery.c
+++ b/storage/maria/ma_recovery.c
@@ -3520,6 +3520,14 @@ void _ma_tmp_disable_logging_for_table(MARIA_HA *info,
{
MARIA_SHARE *share= info->s;
DBUG_ENTER("_ma_tmp_disable_logging_for_table");
+
+ /*
+ We have to ensure that bitmap is flushed, as it's checking
+ that share->now_transactional is set
+ */
+ if (share->now_transactional && share->data_file_type == BLOCK_RECORD)
+ _ma_bitmap_flush_all(share);
+
if (log_incomplete)
{
uchar log_data[FILEID_STORE_SIZE];
@@ -3583,7 +3591,10 @@ my_bool _ma_reenable_logging_for_table(MARIA_HA *info, my_bool flush_pages)
if (share->now_transactional == share->base.born_transactional ||
!info->switched_transactional)
+ {
+ info->switched_transactional= FALSE;
DBUG_RETURN(0);
+ }
info->switched_transactional= FALSE;
if ((share->now_transactional= share->base.born_transactional))