summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2018-05-22 11:47:09 +0200
committerSergei Golubchik <serg@mariadb.org>2018-05-22 11:47:09 +0200
commit4ec8598c1dcb63499bce998142b8e5b8b09b2d30 (patch)
tree23010dcb3489b54b4bc9b26481a4a16a4378914a
parentfe3bf136b6cf83aac5a6e21d3db1c4e821612017 (diff)
parentafe5a51c2df95aa282e4459afeb7f037563def92 (diff)
downloadmariadb-git-4ec8598c1dcb63499bce998142b8e5b8b09b2d30.tar.gz
Merge branch 'github/10.2' into 10.3
-rw-r--r--.gitignore2
-rwxr-xr-xdebian/autobake-deb.sh5
-rw-r--r--extra/mariabackup/backup_mysql.cc15
-rw-r--r--mysql-test/main/create_or_replace.result20
-rw-r--r--mysql-test/main/create_or_replace.test25
-rw-r--r--mysql-test/main/cte_recursive.result30
-rw-r--r--mysql-test/main/cte_recursive.test36
-rw-r--r--mysql-test/main/explain_slowquerylog.result4
-rw-r--r--mysql-test/main/explain_slowquerylog.test6
-rw-r--r--mysql-test/main/grant.result5
-rw-r--r--mysql-test/main/grant.test8
-rw-r--r--mysql-test/main/grant_not_windows.result8
-rw-r--r--mysql-test/main/grant_not_windows.test14
-rw-r--r--mysql-test/main/insert_select.result9
-rw-r--r--mysql-test/main/insert_select.test10
-rw-r--r--mysql-test/main/mysql.test16
-rw-r--r--mysql-test/main/mysql_cp932.test42
-rw-r--r--mysql-test/main/sp.result11
-rw-r--r--mysql-test/main/sp.test15
-rwxr-xr-xmysql-test/mysql-test-run.pl81
-rw-r--r--mysql-test/r/alter_table_errors.result10
-rw-r--r--mysql-test/r/subselect-crash_15755.result317
-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/alter_table_errors.test10
-rw-r--r--mysql-test/t/subselect-crash_15755.test60
-rw-r--r--sql/item.cc8
-rw-r--r--sql/sp_head.cc12
-rw-r--r--sql/sql_base.cc46
-rw-r--r--sql/sql_base.h6
-rw-r--r--sql/sql_class.cc3
-rw-r--r--sql/sql_class.h17
-rw-r--r--sql/sql_cte.cc15
-rw-r--r--sql/sql_delete.cc2
-rw-r--r--sql/sql_insert.cc3
-rw-r--r--sql/sql_lex.cc7
-rw-r--r--sql/sql_lex.h18
-rw-r--r--sql/sql_parse.cc9
-rw-r--r--sql/sql_prepare.cc2
-rw-r--r--sql/sql_select.cc36
-rw-r--r--sql/sql_statistics.cc14
-rw-r--r--sql/sql_table.cc39
-rw-r--r--sql/sql_trigger.cc6
-rw-r--r--sql/sql_union.cc30
-rw-r--r--sql/sql_view.cc4
-rw-r--r--sql/sql_yacc.yy6
-rw-r--r--storage/maria/ha_maria.cc1
-rw-r--r--storage/maria/ma_recovery.c3
-rw-r--r--storage/rocksdb/CMakeLists.txt2
-rw-r--r--storage/rocksdb/ha_rocksdb.cc23
-rw-r--r--storage/rocksdb/ha_rocksdb.h2
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/allow_no_primary_key.result31
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/analyze_table.result26
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/mariadb_port_fixes.result26
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/allow_no_primary_key.test28
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/analyze_table.test26
-rw-r--r--storage/rocksdb/rdb_datadic.cc3
-rw-r--r--storage/tokudb/CMakeLists.txt29
-rw-r--r--storage/tokudb/tokudb.cnf.in (renamed from storage/tokudb/tokudb.cnf)3
-rw-r--r--storage/tokudb/tokudb.conf.in3
62 files changed, 697 insertions, 600 deletions
diff --git a/.gitignore b/.gitignore
index 718befa962d..932c666b74a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -220,6 +220,8 @@ storage/tokudb/PerconaFT/tools/tokudb_load
storage/tokudb/PerconaFT/tools/tokuftdump
storage/tokudb/PerconaFT/tools/tokuft_logprint
storage/tokudb/PerconaFT/xz/
+storage/tokudb/tokudb.cnf
+storage/tokudb/tokudb.conf
strings/conf_to_src
support-files/MySQL-shared-compat.spec
support-files/binary-configure
diff --git a/debian/autobake-deb.sh b/debian/autobake-deb.sh
index f72e1136d83..a52aab35110 100755
--- a/debian/autobake-deb.sh
+++ b/debian/autobake-deb.sh
@@ -128,10 +128,11 @@ UPSTREAM="${MYSQL_VERSION_MAJOR}.${MYSQL_VERSION_MINOR}.${MYSQL_VERSION_PATCH}${
PATCHLEVEL="+maria"
LOGSTRING="MariaDB build"
CODENAME="$(lsb_release -sc)"
+EPOCH="1:"
-dch -b -D ${CODENAME} -v "1:${UPSTREAM}${PATCHLEVEL}~${CODENAME}" "Automatic build with ${LOGSTRING}."
+dch -b -D ${CODENAME} -v "${EPOCH}${UPSTREAM}${PATCHLEVEL}~${CODENAME}" "Automatic build with ${LOGSTRING}."
-echo "Creating package version ${UPSTREAM}${PATCHLEVEL}~${CODENAME} ... "
+echo "Creating package version ${EPOCH}${UPSTREAM}${PATCHLEVEL}~${CODENAME} ... "
# On Travis CI, use -b to build binary only packages as there is no need to
# waste time on generating the source package.
diff --git a/extra/mariabackup/backup_mysql.cc b/extra/mariabackup/backup_mysql.cc
index 71cceadbec4..3517d9136d4 100644
--- a/extra/mariabackup/backup_mysql.cc
+++ b/extra/mariabackup/backup_mysql.cc
@@ -898,16 +898,23 @@ DECLARE_THREAD(kill_mdl_waiters_thread(void *))
break;
MYSQL_RES *result = xb_mysql_query(mysql,
- "SELECT ID, COMMAND FROM INFORMATION_SCHEMA.PROCESSLIST "
+ "SELECT ID, COMMAND, INFO FROM INFORMATION_SCHEMA.PROCESSLIST "
" WHERE State='Waiting for table metadata lock'",
true, true);
while (MYSQL_ROW row = mysql_fetch_row(result))
{
char query[64];
- msg_ts("Killing MDL waiting query '%s' on connection '%s'\n",
- row[1], row[0]);
+
+ if (row[1] && !strcmp(row[1], "Killed"))
+ continue;
+
+ msg_ts("Killing MDL waiting %s ('%s') on connection %s\n",
+ row[1], row[2], row[0]);
snprintf(query, sizeof(query), "KILL QUERY %s", row[0]);
- xb_mysql_query(mysql, query, true);
+ if (mysql_query(mysql, query) && (mysql_errno(mysql) != ER_NO_SUCH_THREAD)) {
+ msg("Error: failed to execute query %s: %s\n", query,mysql_error(mysql));
+ exit(EXIT_FAILURE);
+ }
}
}
diff --git a/mysql-test/main/create_or_replace.result b/mysql-test/main/create_or_replace.result
index e26884f1cbf..0c1bccb861a 100644
--- a/mysql-test/main/create_or_replace.result
+++ b/mysql-test/main/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/main/create_or_replace.test b/mysql-test/main/create_or_replace.test
index 4ef4189694b..3ae882139bc 100644
--- a/mysql-test/main/create_or_replace.test
+++ b/mysql-test/main/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/main/cte_recursive.result b/mysql-test/main/cte_recursive.result
index 19a2e964959..4d1535cacb2 100644
--- a/mysql-test/main/cte_recursive.result
+++ b/mysql-test/main/cte_recursive.result
@@ -3239,6 +3239,36 @@ Parent Child Path
654 987 987,
321 654 987,654,
DROP TABLE t1;
+#
+# MDEV-16212: recursive CTE with global ORDER BY
+#
+set statement max_recursive_iterations = 2 for
+WITH RECURSIVE qn AS (
+SELECT 1 FROM dual UNION ALL
+SELECT 1 FROM qn
+ORDER BY (SELECT * FROM qn))
+SELECT count(*) FROM qn;
+ERROR 42000: This version of MariaDB doesn't yet support 'global ORDER_BY/LIMIT in recursive CTE spec'
+#
+# MDEV-15581: mix of ALL and DISTINCT UNION in recursive CTE
+#
+create table t1(a int);
+insert into t1 values(1),(2);
+insert into t1 values(1),(2);
+set @c=0, @d=0;
+WITH RECURSIVE qn AS
+(
+select 1,0 as col from t1
+union distinct
+select 1,0 from t1
+union all
+select 3, 0*(@c:=@c+1) from qn where @c<1
+union all
+select 3, 0*(@d:=@d+1) from qn where @d<1
+)
+select * from qn;
+ERROR 42000: This version of MariaDB doesn't yet support 'mix of ALL and DISTINCT UNION operations in recursive CTE spec'
+drop table t1;
# Start of 10.3 tests
#
# MDEV-14217 [db crash] Recursive CTE when SELECT includes new field
diff --git a/mysql-test/main/cte_recursive.test b/mysql-test/main/cte_recursive.test
index b0b38a28b34..6f394bd673c 100644
--- a/mysql-test/main/cte_recursive.test
+++ b/mysql-test/main/cte_recursive.test
@@ -2247,6 +2247,42 @@ ORDER BY Path;
DROP TABLE t1;
+--echo #
+--echo # MDEV-16212: recursive CTE with global ORDER BY
+--echo #
+
+--error ER_NOT_SUPPORTED_YET
+set statement max_recursive_iterations = 2 for
+WITH RECURSIVE qn AS (
+SELECT 1 FROM dual UNION ALL
+SELECT 1 FROM qn
+ORDER BY (SELECT * FROM qn))
+SELECT count(*) FROM qn;
+
+--echo #
+--echo # MDEV-15581: mix of ALL and DISTINCT UNION in recursive CTE
+--echo #
+
+create table t1(a int);
+insert into t1 values(1),(2);
+insert into t1 values(1),(2);
+
+set @c=0, @d=0;
+--error ER_NOT_SUPPORTED_YET
+WITH RECURSIVE qn AS
+(
+select 1,0 as col from t1
+union distinct
+select 1,0 from t1
+union all
+select 3, 0*(@c:=@c+1) from qn where @c<1
+union all
+select 3, 0*(@d:=@d+1) from qn where @d<1
+)
+select * from qn;
+
+drop table t1;
+
--echo # Start of 10.3 tests
--echo #
diff --git a/mysql-test/main/explain_slowquerylog.result b/mysql-test/main/explain_slowquerylog.result
index 2b350cf04ff..63da82b5288 100644
--- a/mysql-test/main/explain_slowquerylog.result
+++ b/mysql-test/main/explain_slowquerylog.result
@@ -54,3 +54,7 @@ SELECT 1;
1
SET log_slow_rate_limit=@save1;
SET long_query_time=@save2;
+create table t1 (a int);
+execute immediate "select * from t1 join t1 t2 on (t1.a>5) where exists (select 1)";
+a a
+drop table t1;
diff --git a/mysql-test/main/explain_slowquerylog.test b/mysql-test/main/explain_slowquerylog.test
index 6503a326eb8..ee90fbac4e6 100644
--- a/mysql-test/main/explain_slowquerylog.test
+++ b/mysql-test/main/explain_slowquerylog.test
@@ -61,3 +61,9 @@ SELECT 1;
SET log_slow_rate_limit=@save1;
SET long_query_time=@save2;
+#
+# MDEV-16153 Server crashes in Apc_target::disable, ASAN heap-use-after-free in Explain_query::~Explain_query upon/after EXECUTE IMMEDIATE
+#
+create table t1 (a int);
+execute immediate "select * from t1 join t1 t2 on (t1.a>5) where exists (select 1)";
+drop table t1;
diff --git a/mysql-test/main/grant.result b/mysql-test/main/grant.result
index 22add627144..1d4402185a5 100644
--- a/mysql-test/main/grant.result
+++ b/mysql-test/main/grant.result
@@ -1709,11 +1709,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/main/grant.test b/mysql-test/main/grant.test
index c945e818181..72e427493da 100644
--- a/mysql-test/main/grant.test
+++ b/mysql-test/main/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/main/grant_not_windows.result b/mysql-test/main/grant_not_windows.result
new file mode 100644
index 00000000000..fedfaf984b2
--- /dev/null
+++ b/mysql-test/main/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/main/grant_not_windows.test b/mysql-test/main/grant_not_windows.test
new file mode 100644
index 00000000000..55b09232edc
--- /dev/null
+++ b/mysql-test/main/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/main/insert_select.result b/mysql-test/main/insert_select.result
index 1a3a38b1f35..5094638c92b 100644
--- a/mysql-test/main/insert_select.result
+++ b/mysql-test/main/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 value(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/main/insert_select.test b/mysql-test/main/insert_select.test
index fda89f18d99..0b5cdf95daf 100644
--- a/mysql-test/main/insert_select.test
+++ b/mysql-test/main/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 value(i) as a from t1;
+show create table t2;
+drop table t1, t2;
+
+--echo End of 5.5 tests
diff --git a/mysql-test/main/mysql.test b/mysql-test/main/mysql.test
index 022a24ce25e..01953ba2112 100644
--- a/mysql-test/main/mysql.test
+++ b/mysql-test/main/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/main/mysql_cp932.test b/mysql-test/main/mysql_cp932.test
index 60a129c3805..8fba5750d89 100644
--- a/mysql-test/main/mysql_cp932.test
+++ b/mysql-test/main/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/main/sp.result b/mysql-test/main/sp.result
index f6f34318584..64caf0fd554 100644
--- a/mysql-test/main/sp.result
+++ b/mysql-test/main/sp.result
@@ -8251,6 +8251,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/main/sp.test b/mysql-test/main/sp.test
index 80d541ac77c..cfd6604acce 100644
--- a/mysql-test/main/sp.test
+++ b/mysql-test/main/sp.test
@@ -9749,6 +9749,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/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl
index 3bcbbc44b69..ddb79b925b6 100755
--- a/mysql-test/mysql-test-run.pl
+++ b/mysql-test/mysql-test-run.pl
@@ -653,50 +653,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/alter_table_errors.result b/mysql-test/r/alter_table_errors.result
deleted file mode 100644
index 020a30304d0..00000000000
--- a/mysql-test/r/alter_table_errors.result
+++ /dev/null
@@ -1,10 +0,0 @@
-create table t (a int, v int as (a)) engine=innodb;
-alter table t change column a b tinyint, algorithm=inplace;
-ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: Cannot change column type INPLACE. Try ALGORITHM=COPY
-show create table t;
-Table Create Table
-t CREATE TABLE `t` (
- `a` int(11) DEFAULT NULL,
- `v` int(11) GENERATED ALWAYS AS (`a`) VIRTUAL
-) ENGINE=InnoDB DEFAULT CHARSET=latin1
-drop table t;
diff --git a/mysql-test/r/subselect-crash_15755.result b/mysql-test/r/subselect-crash_15755.result
deleted file mode 100644
index 81b4bd16ab5..00000000000
--- a/mysql-test/r/subselect-crash_15755.result
+++ /dev/null
@@ -1,317 +0,0 @@
-set global innodb_stats_persistent= 1;
-drop table if exists t1;
-Warnings:
-Note 1051 Unknown table 'test.t1'
-create table t1 (
-f1 bigint(20) default 0,
-f2 varchar(50) default '',
-f3 int(10) default 0,
-f4 bigint(20) default 0,
-f5 bigint(20) default 0,
-f6 varchar(50) default '',
-f7 varchar(64) default '',
-f8 varchar(30) default '',
-f9 varchar(30) default '',
-f10 bigint(20) default 0,
-f11 bigint(20) default 0,
-f12 bigint(20) default 0,
-f13 bigint(20) default 0,
-f14 varchar(50) default '',
-f15 varchar(100) default '',
-f16 varchar(30) default '',
-f17 varchar(40) default '',
-f18 varchar(30) default '',
-f19 varchar(10) default '',
-f20 varchar(30) default '',
-f21 int(10) default 0,
-f22 int(10) default 0,
-f23 int(10) default 0,
-f24 int(10) default 0,
-f25 varchar(20) default '',
-f26 varchar(20) default '',
-f27 varchar(100) default '',
-f28 varchar(55) default '',
-f29 varchar(20) default '',
-f30 varchar(100) default '',
-f31 varchar(30) default '',
-f32 varchar(20) default '',
-f33 int(10) default 0,
-f34 int(10) default 0,
-f35 varchar(30) default '',
-f36 varchar(30) default '',
-f37 varchar(30) default '',
-f38 varchar(20) default '',
-f39 tinyint(4) default 0,
-f40 tinyint(4) default 0,
-f41 bigint(20) default 0,
-f42 varchar(50) default '',
-f43 varchar(50) default '',
-f44 varchar(50) default '',
-f45 int(10) default 0,
-f46 tinyint(1) default 0
-) engine=innodb row_format=dynamic;
-insert into t1 () values (),(),(),(),(),(),(),(),(),(),(),(),(),(),(),();
-insert into t1 select * from t1;
-insert into t1 select * from t1;
-insert into t1 select * from t1;
-insert into t1 select * from t1;
-select * from t1 where f2 in (select f2 from t1 group by f2 having count(distinct f3) = 1);
-f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 f13 f14 f15 f16 f17 f18 f19 f20 f21 f22 f23 f24 f25 f26 f27 f28 f29 f30 f31 f32 f33 f34 f35 f36 f37 f38 f39 f40 f41 f42 f43 f44 f45 f46
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
-drop table t1;
-set global innodb_stats_persistent= 0;
diff --git a/mysql-test/suite/innodb/r/innodb_bug54044.result b/mysql-test/suite/innodb/r/innodb_bug54044.result
index 01e8c58f896..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 VALUE(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 655e629b61b..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 VALUE(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/alter_table_errors.test b/mysql-test/t/alter_table_errors.test
deleted file mode 100644
index d9982ac26f4..00000000000
--- a/mysql-test/t/alter_table_errors.test
+++ /dev/null
@@ -1,10 +0,0 @@
---source include/have_innodb.inc
-
-#
-# MDEV-16110 ALTER with ALGORITHM=INPLACE breaks temporary table with virtual columns
-#
-create table t (a int, v int as (a)) engine=innodb;
---error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
-alter table t change column a b tinyint, algorithm=inplace;
-show create table t;
-drop table t;
diff --git a/mysql-test/t/subselect-crash_15755.test b/mysql-test/t/subselect-crash_15755.test
deleted file mode 100644
index 79e259d6337..00000000000
--- a/mysql-test/t/subselect-crash_15755.test
+++ /dev/null
@@ -1,60 +0,0 @@
---source include/have_innodb.inc
-set global innodb_stats_persistent= 1;
-drop table if exists t1;
-create table t1 (
- f1 bigint(20) default 0,
- f2 varchar(50) default '',
- f3 int(10) default 0,
- f4 bigint(20) default 0,
- f5 bigint(20) default 0,
- f6 varchar(50) default '',
- f7 varchar(64) default '',
- f8 varchar(30) default '',
- f9 varchar(30) default '',
- f10 bigint(20) default 0,
- f11 bigint(20) default 0,
- f12 bigint(20) default 0,
- f13 bigint(20) default 0,
- f14 varchar(50) default '',
- f15 varchar(100) default '',
- f16 varchar(30) default '',
- f17 varchar(40) default '',
- f18 varchar(30) default '',
- f19 varchar(10) default '',
- f20 varchar(30) default '',
- f21 int(10) default 0,
- f22 int(10) default 0,
- f23 int(10) default 0,
- f24 int(10) default 0,
- f25 varchar(20) default '',
- f26 varchar(20) default '',
- f27 varchar(100) default '',
- f28 varchar(55) default '',
- f29 varchar(20) default '',
- f30 varchar(100) default '',
- f31 varchar(30) default '',
- f32 varchar(20) default '',
- f33 int(10) default 0,
- f34 int(10) default 0,
- f35 varchar(30) default '',
- f36 varchar(30) default '',
- f37 varchar(30) default '',
- f38 varchar(20) default '',
- f39 tinyint(4) default 0,
- f40 tinyint(4) default 0,
- f41 bigint(20) default 0,
- f42 varchar(50) default '',
- f43 varchar(50) default '',
- f44 varchar(50) default '',
- f45 int(10) default 0,
- f46 tinyint(1) default 0
-) engine=innodb row_format=dynamic;
-
-insert into t1 () values (),(),(),(),(),(),(),(),(),(),(),(),(),(),(),();
-insert into t1 select * from t1;
-insert into t1 select * from t1;
-insert into t1 select * from t1;
-insert into t1 select * from t1;
-select * from t1 where f2 in (select f2 from t1 group by f2 having count(distinct f3) = 1);
-drop table t1;
-set global innodb_stats_persistent= 0;
diff --git a/sql/item.cc b/sql/item.cc
index 69b62b41fe2..8fae773f487 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -9544,10 +9544,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 151023aa24c..ba682beb9c8 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -838,7 +838,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);
@@ -1155,7 +1155,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;
@@ -1262,7 +1262,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.
@@ -1419,7 +1418,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;
@@ -3280,7 +3278,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());
@@ -5164,7 +5162,5 @@ err:
ulong sp_head::sp_cache_version() const
{
- return m_parent ? m_parent->sp_cache_version() :
- m_sp_cache_version;
-
+ return m_parent ? m_parent->sp_cache_version() : m_sp_cache_version;
}
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index b17b2b31ba7..f89fbc59b14 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -951,7 +951,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
@@ -980,9 +981,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;
LEX_CSTRING *d_name, *t_name, *t_alias;
DBUG_ENTER("find_dup_table");
DBUG_PRINT("enter", ("table alias: %s", table->alias.str));
@@ -1015,17 +1016,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->str, t_name->str));
- 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;
}
/*
@@ -1034,21 +1033,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->str, res->alias.str))
- 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 &&
@@ -1060,14 +1067,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())
{
@@ -1099,7 +1109,7 @@ next:
TABLE_LIST*
unique_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list,
- bool check_alias)
+ uint check_flag)
{
TABLE_LIST *dup;
@@ -1131,12 +1141,12 @@ unique_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list,
if (!tmp_parent)
break;
- 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 b85e01032fa..01892c0b938 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);
@@ -267,7 +271,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_CSTRING *a, const LEX_CSTRING *b);
class Open_tables_backup;
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index b58ed52db31..a5f69d63ad0 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -805,7 +805,6 @@ THD::THD(my_thread_id id, bool is_wsrep_applier, bool skip_global_sys_var_lock)
statement_id_counter= 0UL;
// Must be reset to handle error with THD's created for init of mysqld
lex->current_select= 0;
- stmt_lex= 0;
start_utime= utime_after_query= 0;
system_time.start.val= system_time.sec= system_time.sec_part= 0;
utime_after_lock= 0L;
@@ -3845,7 +3844,7 @@ void Statement::set_statement(Statement *stmt)
{
id= stmt->id;
column_usage= stmt->column_usage;
- 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 0ff588a6d38..37e4697e708 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -1103,21 +1103,6 @@ public:
LEX_CSTRING 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.
@@ -4801,7 +4786,7 @@ public:
void set_local_lex(sp_lex_local *sublex)
{
DBUG_ASSERT(lex->sphead);
- lex= stmt_lex= sublex;
+ lex= sublex;
/* Reset part of parser state which needs this. */
m_parser_state->m_yacc.reset_before_substatement();
}
diff --git a/sql/sql_cte.cc b/sql/sql_cte.cc
index c92fb3d97ba..97bbf8f73bd 100644
--- a/sql/sql_cte.cc
+++ b/sql/sql_cte.cc
@@ -682,7 +682,6 @@ void With_element::move_anchors_ahead()
{
st_select_lex *next_sl;
st_select_lex *new_pos= spec->first_select();
- st_select_lex *UNINIT_VAR(last_sl);
new_pos->linkage= UNION_TYPE;
for (st_select_lex *sl= new_pos; sl; sl= next_sl)
{
@@ -690,6 +689,14 @@ void With_element::move_anchors_ahead()
if (is_anchor(sl))
{
sl->move_node(new_pos);
+ if (new_pos == spec->first_select())
+ {
+ enum sub_select_type type= new_pos->linkage;
+ new_pos->linkage= sl->linkage;
+ sl->linkage= type;
+ new_pos->with_all_modifier= sl->with_all_modifier;
+ sl->with_all_modifier= false;
+ }
new_pos= sl->next_select();
}
else if (!sq_rec_ref && no_rec_ref_on_top_level())
@@ -697,10 +704,7 @@ void With_element::move_anchors_ahead()
sq_rec_ref= find_first_sq_rec_ref_in_select(sl);
DBUG_ASSERT(sq_rec_ref != NULL);
}
- last_sl= sl;
}
- if (spec->union_distinct)
- spec->union_distinct= last_sl;
first_recursive= new_pos;
}
@@ -829,8 +833,9 @@ st_select_lex_unit *With_element::clone_parsed_spec(THD *thd,
if (parser_state.init(thd, (char*) unparsed_spec.str, (unsigned int)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 2781bd50d26..3686f866e23 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -1130,7 +1130,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 9cb6a88fd4d..b03cde54abb 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -1583,7 +1583,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 80baf7478a0..47557d562a8 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -652,11 +652,11 @@ void lex_start(THD *thd)
void LEX::start(THD *thd_arg)
{
DBUG_ENTER("LEX::start");
- DBUG_PRINT("info", ("This: %p thd_arg->lex: %p thd_arg->stmt_lex: %p",
- this, thd_arg->lex, thd_arg->stmt_lex));
+ DBUG_PRINT("info", ("This: %p thd_arg->lex: %p", this, thd_arg->lex));
thd= unit.thd= thd_arg;
-
+ stmt_lex= this; // default, should be rewritten for VIEWs And CTEs
+
DBUG_ASSERT(!explain);
context_stack.empty();
@@ -2323,6 +2323,7 @@ void st_select_lex::init_select()
select_limit= 0; /* denotes the default limit = HA_POS_ERROR */
offset_limit= 0; /* denotes the default offset = 0 */
with_sum_func= 0;
+ with_all_modifier= 0;
is_correlated= 0;
cur_pos_in_select_list= UNDEF_POS;
cond_value= having_value= Item::COND_UNDEF;
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index bfb201185b1..a462ba3d252 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -935,7 +935,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.
*/
@@ -1084,6 +1084,7 @@ public:
*/
bool subquery_in_having;
/* TRUE <=> this SELECT is correlated w.r.t. some ancestor select */
+ bool with_all_modifier; /* used for selects in union */
bool is_correlated;
/*
This variable is required to ensure proper work of subqueries and
@@ -2805,6 +2806,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_CSTRING name;
const char *help_arg;
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index cab433d7196..40a5490b908 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -4199,7 +4199,7 @@ mysql_execute_command(THD *thd)
TABLE_LIST *duplicate;
if (unlikely((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);
@@ -7540,8 +7540,9 @@ void THD::reset_for_next_command(bool do_clear_error)
We also assign stmt_lex in lex_start(), but during bootstrap this
code is executed first.
*/
- stmt_lex= &main_lex; stmt_lex->current_select_number= 1;
- DBUG_PRINT("info", ("Lex %p stmt_lex: %p", lex, 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.
@@ -7658,7 +7659,7 @@ mysql_new_select(LEX *lex, bool move_down, SELECT_LEX *select_lex)
{
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 2b5bac87835..d4c96ebc535 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -3911,7 +3911,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))
DBUG_RETURN(TRUE);
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 0f2a3236942..1285835fe7c 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -1396,16 +1396,28 @@ bool JOIN::build_explain()
{
create_explain_query_if_not_exists(thd->lex, thd->mem_root);
have_query_plan= QEP_AVAILABLE;
- if (save_explain_data(thd->lex->explain, false /* can overwrite */,
+
+ /*
+ explain data must be created on the Explain_query::mem_root. Because it's
+ just a memroot, not an arena, explain data must not contain any Items
+ */
+ MEM_ROOT *old_mem_root= thd->mem_root;
+ Item *old_free_list __attribute__((unused))= thd->free_list;
+ thd->mem_root= thd->lex->explain->mem_root;
+ bool res= save_explain_data(thd->lex->explain, false /* can overwrite */,
need_tmp,
!skip_sort_order && !no_order && (order || group_list),
- select_distinct))
+ select_distinct);
+ thd->mem_root= old_mem_root;
+ DBUG_ASSERT(thd->free_list == old_free_list); // no Items were created
+ if (res)
return 1;
+
uint select_nr= select_lex->select_number;
JOIN_TAB *curr_tab= join_tab + exec_join_tab_cnt();
for (uint i= 0; i < aggr_tables; i++, curr_tab++)
{
- if (select_nr == INT_MAX)
+ if (select_nr == INT_MAX)
{
/* this is a fake_select_lex of a union */
select_nr= select_lex->master_unit()->first_select()->select_number;
@@ -1599,7 +1611,11 @@ JOIN::optimize_inner()
/*
The following code will allocate the new items in a permanent
MEMROOT for prepared statements and stored procedures.
+
+ But first we need to ensure that thd->lex->explain is allocated
+ in the execution arena
*/
+ create_explain_query_if_not_exists(thd->lex, thd->mem_root);
Query_arena *arena, backup;
arena= thd->activate_stmt_arena_if_needed(&backup);
@@ -3722,7 +3738,7 @@ bool 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 ||
@@ -24918,9 +24934,9 @@ bool JOIN_TAB::save_explain_data(Explain_table_access *eta,
if (filesort)
{
if (!(eta->pre_join_sort=
- new Explain_aggr_filesort(thd->mem_root,
- thd->lex->analyze_stmt,
- filesort)))
+ new (thd->mem_root) Explain_aggr_filesort(thd->mem_root,
+ thd->lex->analyze_stmt,
+ filesort)))
return 1;
}
@@ -25358,7 +25374,7 @@ bool save_agg_explain_data(JOIN *join, Explain_select *xpl_sel)
{
// Each aggregate means a temp.table
prev_node= node;
- if (!(node= new Explain_aggr_tmp_table))
+ if (!(node= new (thd->mem_root) Explain_aggr_tmp_table))
return 1;
node->child= prev_node;
@@ -25379,7 +25395,7 @@ bool save_agg_explain_data(JOIN *join, Explain_select *xpl_sel)
if (join_tab->distinct)
{
prev_node= node;
- if (!(node= new Explain_aggr_remove_dups))
+ if (!(node= new (thd->mem_root) Explain_aggr_remove_dups))
return 1;
node->child= prev_node;
}
@@ -25387,7 +25403,7 @@ bool save_agg_explain_data(JOIN *join, Explain_select *xpl_sel)
if (join_tab->filesort)
{
Explain_aggr_filesort *eaf =
- new Explain_aggr_filesort(thd->mem_root, is_analyze, join_tab->filesort);
+ new (thd->mem_root) Explain_aggr_filesort(thd->mem_root, is_analyze, join_tab->filesort);
if (!eaf)
return 1;
prev_node= node;
diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc
index 7bb03740bf4..92c019d3f1b 100644
--- a/sql/sql_statistics.cc
+++ b/sql/sql_statistics.cc
@@ -1799,6 +1799,7 @@ private:
public:
bool is_single_comp_pk;
+ bool is_partial_fields_present;
Index_prefix_calc(THD *thd, TABLE *table, KEY *key_info)
: index_table(table), index_info(key_info)
@@ -1810,7 +1811,7 @@ public:
prefixes= 0;
LINT_INIT_STRUCT(calc_state);
- is_single_comp_pk= FALSE;
+ is_partial_fields_present= is_single_comp_pk= FALSE;
uint pk= table->s->primary_key;
if ((uint) (table->key_info - key_info) == pk &&
table->key_info[pk].user_defined_key_parts == 1)
@@ -1832,7 +1833,10 @@ public:
calculating the values of 'avg_frequency' for prefixes.
*/
if (!key_info->key_part[i].field->part_of_key.is_set(keyno))
+ {
+ is_partial_fields_present= TRUE;
break;
+ }
if (!(state->last_prefix=
new (thd->mem_root) Cached_item_field(thd,
@@ -2631,7 +2635,13 @@ int collect_statistics_for_index(THD *thd, TABLE *table, uint index)
DBUG_RETURN(rc);
}
- table->file->ha_start_keyread(index);
+ /*
+ Request "only index read" in case of absence of fields which are
+ partially in the index to avoid problems with partitioning (for example)
+ which want to get whole field value.
+ */
+ if (!index_prefix_calc.is_partial_fields_present)
+ table->file->ha_start_keyread(index);
table->file->ha_index_init(index, TRUE);
rc= table->file->ha_index_first(table->record[0]);
while (rc != HA_ERR_END_OF_FILE)
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 550b11d813e..648e05a4116 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -10060,9 +10060,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);
}
@@ -10115,6 +10113,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;
@@ -10130,15 +10129,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))
+ if (!(copy= new (thd->mem_root) Copy_field[to->s->fields]))
DBUG_RETURN(-1);
- if (!(copy= new (thd->mem_root) 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);
@@ -10149,7 +10156,6 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to,
to->file->extra(HA_EXTRA_PREPARE_FOR_ALTER_TABLE);
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;
@@ -10407,6 +10413,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 (unlikely(mysql_trans_commit_alter_copy_data(thd)))
@@ -10424,10 +10432,19 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to,
*copied= found_count;
*deleted=delete_count;
to->file->ha_release_auto_increment();
- if (unlikely(to->file->ha_external_lock(thd,F_UNLCK)))
- error= 1;
- if (likely(error < 0) && !from->s->tmp_table &&
- unlikely(to->file->extra(HA_EXTRA_PREPARE_FOR_RENAME)))
+
+ 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 &&
+ to->file->extra(HA_EXTRA_PREPARE_FOR_RENAME))
error= 1;
thd_progress_end(thd);
DBUG_RETURN(error > 0 ? -1 : 0);
diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc
index aa222eaad1d..3318faf3f90 100644
--- a/sql/sql_trigger.cc
+++ b/sql/sql_trigger.cc
@@ -1370,12 +1370,12 @@ bool Table_triggers_list::check_n_load(THD *thd, const LEX_CSTRING *db,
List_iterator_fast<LEX_CSTRING> it_connection_cl_name(trigger_list->connection_cl_names);
List_iterator_fast<LEX_CSTRING> 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= thd->db;
thd->reset_db(db);
@@ -1592,7 +1592,6 @@ bool Table_triggers_list::check_n_load(THD *thd, const LEX_CSTRING *db,
}
thd->reset_db(&save_db);
thd->lex= old_lex;
- thd->stmt_lex= old_stmt_lex;
thd->spcont= save_spcont;
thd->variables.sql_mode= save_sql_mode;
@@ -1606,7 +1605,6 @@ bool Table_triggers_list::check_n_load(THD *thd, const LEX_CSTRING *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);
diff --git a/sql/sql_union.cc b/sql/sql_union.cc
index f74c7b5e27a..a1963c33a42 100644
--- a/sql/sql_union.cc
+++ b/sql/sql_union.cc
@@ -834,6 +834,23 @@ bool st_select_lex_unit::prepare(TABLE_LIST *derived_arg,
DBUG_ENTER("st_select_lex_unit::prepare");
DBUG_ASSERT(thd == current_thd);
+ if (is_recursive && (sl= first_sl->next_select()))
+ {
+ SELECT_LEX *next_sl;
+ for ( ; ; sl= next_sl)
+ {
+ next_sl= sl->next_select();
+ if (!next_sl)
+ break;
+ if (next_sl->with_all_modifier != sl->with_all_modifier)
+ {
+ my_error(ER_NOT_SUPPORTED_YET, MYF(0),
+ "mix of ALL and DISTINCT UNION operations in recursive CTE spec");
+ DBUG_RETURN(TRUE);
+ }
+ }
+ }
+
describe= additional_options & SELECT_DESCRIBE;
/*
@@ -927,7 +944,18 @@ bool st_select_lex_unit::prepare(TABLE_LIST *derived_arg,
with_element->rec_result=
new (thd->mem_root) select_union_recursive(thd);
union_result= with_element->rec_result;
- fake_select_lex= NULL;
+ if (fake_select_lex)
+ {
+ if (fake_select_lex->order_list.first ||
+ fake_select_lex->explicit_limit)
+ {
+ my_error(ER_NOT_SUPPORTED_YET, MYF(0),
+ "global ORDER_BY/LIMIT in recursive CTE spec");
+ goto err;
+ }
+ fake_select_lex->cleanup();
+ fake_select_lex= NULL;
+ }
}
if (!(tmp_result= union_result))
goto err; /* purecov: inspected */
diff --git a/sql/sql_view.cc b/sql/sql_view.cc
index 29c61d4abcc..6679334552b 100644
--- a/sql/sql_view.cc
+++ b/sql/sql_view.cc
@@ -1333,6 +1333,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)
{
@@ -1359,8 +1360,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/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 41c05e9df34..c389b09d54c 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -571,11 +571,9 @@ bool LEX::add_select_to_union_list(bool is_union_distinct,
return TRUE;
mysql_init_select(this);
current_select->linkage= type;
+ current_select->with_all_modifier= !is_union_distinct;
if (is_union_distinct) /* UNION DISTINCT - remember position */
- {
- current_select->master_unit()->union_distinct=
- current_select;
- }
+ current_select->master_unit()->union_distinct= current_select;
else
DBUG_ASSERT(type == UNION_TYPE);
return FALSE;
diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc
index 4a241fca941..0442f4d8eae 100644
--- a/storage/maria/ha_maria.cc
+++ b/storage/maria/ha_maria.cc
@@ -2247,6 +2247,7 @@ int ha_maria::end_bulk_insert()
bulk_insert_single_undo ==
BULK_INSERT_SINGLE_UNDO_AND_NO_REPAIR)))
first_error= first_error ? first_error : error;
+ bulk_insert_single_undo= BULK_INSERT_NONE; // Safety
}
DBUG_RETURN(first_error);
}
diff --git a/storage/maria/ma_recovery.c b/storage/maria/ma_recovery.c
index f417275a1b4..38200104538 100644
--- a/storage/maria/ma_recovery.c
+++ b/storage/maria/ma_recovery.c
@@ -3591,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))
diff --git a/storage/rocksdb/CMakeLists.txt b/storage/rocksdb/CMakeLists.txt
index cc4aa2eca4e..f90b07ee380 100644
--- a/storage/rocksdb/CMakeLists.txt
+++ b/storage/rocksdb/CMakeLists.txt
@@ -108,7 +108,7 @@ SET(ROCKSDB_SE_SOURCES
#ADD_DEFINITIONS(-DROCKSDB_PLATFORM_POSIX -DROCKSDB_LIB_IO_POSIX
#)
-MYSQL_ADD_PLUGIN(rocksdb ${ROCKSDB_SE_SOURCES} STORAGE_ENGINE
+MYSQL_ADD_PLUGIN(rocksdb ${ROCKSDB_SE_SOURCES} MODULE_ONLY STORAGE_ENGINE
MODULE_OUTPUT_NAME ha_rocksdb
COMPONENT rocksdb-engine)
diff --git a/storage/rocksdb/ha_rocksdb.cc b/storage/rocksdb/ha_rocksdb.cc
index ab00077c43a..48297aa38f0 100644
--- a/storage/rocksdb/ha_rocksdb.cc
+++ b/storage/rocksdb/ha_rocksdb.cc
@@ -5235,8 +5235,17 @@ int ha_rocksdb::load_hidden_pk_value() {
active_index = m_tbl_def->m_key_count - 1;
const uint8 save_table_status = table->status;
- Rdb_transaction *const tx = get_or_create_tx(table->in_use);
- const bool is_new_snapshot = !tx->has_snapshot();
+ /*
+ We should read the latest committed value in the database.
+ That is, if we have an open transaction with a snapshot, we should not use
+ it as we may get old data. Start a new transaction to read the latest
+ value.
+ */
+ Rdb_transaction *const temp_tx = new Rdb_transaction_impl(table->in_use);
+ temp_tx->start_tx();
+ Rdb_transaction *&tx = get_tx_from_thd(table->in_use);
+ Rdb_transaction *save_tx= tx;
+ tx= temp_tx;
longlong hidden_pk_id = 1;
// Do a lookup.
@@ -5246,9 +5255,8 @@ int ha_rocksdb::load_hidden_pk_value() {
*/
auto err = read_hidden_pk_id_from_rowkey(&hidden_pk_id);
if (err) {
- if (is_new_snapshot) {
- tx->release_snapshot();
- }
+ delete tx;
+ tx= save_tx;
return err;
}
@@ -5260,9 +5268,8 @@ int ha_rocksdb::load_hidden_pk_value() {
!m_tbl_def->m_hidden_pk_val.compare_exchange_weak(old, hidden_pk_id)) {
}
- if (is_new_snapshot) {
- tx->release_snapshot();
- }
+ delete tx;
+ tx= save_tx;
table->status = save_table_status;
active_index = save_active_index;
diff --git a/storage/rocksdb/ha_rocksdb.h b/storage/rocksdb/ha_rocksdb.h
index 171c303ac4a..5bf473a2fb0 100644
--- a/storage/rocksdb/ha_rocksdb.h
+++ b/storage/rocksdb/ha_rocksdb.h
@@ -1473,7 +1473,7 @@ private:
// file name indicating RocksDB data corruption
std::string rdb_corruption_marker_file_name();
-const int MYROCKS_MARIADB_PLUGIN_MATURITY_LEVEL= MariaDB_PLUGIN_MATURITY_GAMMA;
+const int MYROCKS_MARIADB_PLUGIN_MATURITY_LEVEL= MariaDB_PLUGIN_MATURITY_STABLE;
extern bool prevent_myrocks_loading;
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/allow_no_primary_key.result b/storage/rocksdb/mysql-test/rocksdb/r/allow_no_primary_key.result
index 5bffab74917..a8d5c07072c 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/allow_no_primary_key.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/allow_no_primary_key.result
@@ -262,3 +262,34 @@ SELECT * FROM t1;
a b
36 foo
DROP TABLE t1;
+#
+# Issue #834/MDEV-15304 ALTER TABLE table_with_hidden_pk causes Can't
+# write; duplicate key in table error and/or crash
+#
+CREATE TABLE t1 (a INT, KEY(a)) ENGINE=RocksDB;
+INSERT INTO t1 VALUES (1),(1+1);
+create table t2 (a int);
+insert into t2 values (10),(20),(30);
+BEGIN;
+select * from t2;
+a
+10
+20
+30
+connect con1,localhost,root,,;
+connection con1;
+alter table t1 force;
+connection default;
+select * from t1;
+a
+connection con1;
+insert into t1 values (100);
+select * from t1;
+a
+1
+2
+100
+disconnect con1;
+connection default;
+rollback;
+drop table t1,t2;
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/analyze_table.result b/storage/rocksdb/mysql-test/rocksdb/r/analyze_table.result
index ff2973230db..b666a17c81c 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/analyze_table.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/analyze_table.result
@@ -27,3 +27,29 @@ ANALYZE TABLE t1;
Table Op Msg_type Msg_text
test.t1 analyze status OK
DROP TABLE t1;
+#
+# MDEV-12465: Server crashes in my_scan_weight_utf8_bin upon
+# collecting stats for RocksDB table
+#
+CREATE TABLE t1 (
+pk INT,
+f1 CHAR(255),
+f2 TEXT,
+f3 VARCHAR(255),
+f4 TEXT,
+PRIMARY KEY (pk),
+KEY (f4(255))
+) ENGINE=RocksDB
+CHARSET utf8
+COLLATE utf8_bin
+PARTITION BY KEY (pk) PARTITIONS 2;
+INSERT INTO t1 VALUES
+(1,'foo','bar','foo','bar'), (2,'bar','foo','bar','foo');
+ANALYZE TABLE t1 PERSISTENT FOR ALL;
+Table Op Msg_type Msg_text
+test.t1 analyze status Engine-independent statistics collected
+test.t1 analyze Warning Engine-independent statistics are not collected for column 'f2'
+test.t1 analyze Warning Engine-independent statistics are not collected for column 'f4'
+test.t1 analyze status OK
+drop table t1;
+# End of 10.2 tests
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/mariadb_port_fixes.result b/storage/rocksdb/mysql-test/rocksdb/r/mariadb_port_fixes.result
index e9fe026120a..d9e2bf5eea5 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/mariadb_port_fixes.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/mariadb_port_fixes.result
@@ -69,19 +69,19 @@ set global rocksdb_strict_collation_check=@tmp_rscc;
#
select plugin_name, plugin_maturity from information_schema.plugins where plugin_name like '%rocksdb%';
plugin_name plugin_maturity
-ROCKSDB Gamma
-ROCKSDB_CFSTATS Gamma
-ROCKSDB_DBSTATS Gamma
-ROCKSDB_PERF_CONTEXT Gamma
-ROCKSDB_PERF_CONTEXT_GLOBAL Gamma
-ROCKSDB_CF_OPTIONS Gamma
-ROCKSDB_COMPACTION_STATS Gamma
-ROCKSDB_GLOBAL_INFO Gamma
-ROCKSDB_DDL Gamma
-ROCKSDB_INDEX_FILE_MAP Gamma
-ROCKSDB_LOCKS Gamma
-ROCKSDB_TRX Gamma
-ROCKSDB_DEADLOCK Gamma
+ROCKSDB Stable
+ROCKSDB_CFSTATS Stable
+ROCKSDB_DBSTATS Stable
+ROCKSDB_PERF_CONTEXT Stable
+ROCKSDB_PERF_CONTEXT_GLOBAL Stable
+ROCKSDB_CF_OPTIONS Stable
+ROCKSDB_COMPACTION_STATS Stable
+ROCKSDB_GLOBAL_INFO Stable
+ROCKSDB_DDL Stable
+ROCKSDB_INDEX_FILE_MAP Stable
+ROCKSDB_LOCKS Stable
+ROCKSDB_TRX Stable
+ROCKSDB_DEADLOCK Stable
#
# MDEV-12466 : Assertion `thd->transaction.stmt.is_empty() || thd->in_sub_stmt || ...
#
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/allow_no_primary_key.test b/storage/rocksdb/mysql-test/rocksdb/t/allow_no_primary_key.test
index 2a064dc3b00..5f2a37f235a 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/allow_no_primary_key.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/allow_no_primary_key.test
@@ -96,3 +96,31 @@ DELETE FROM t1 WHERE a = 35 AND b = 'foo';
--sorted_result
SELECT * FROM t1;
DROP TABLE t1;
+
+--echo #
+--echo # Issue #834/MDEV-15304 ALTER TABLE table_with_hidden_pk causes Can't
+--echo # write; duplicate key in table error and/or crash
+--echo #
+CREATE TABLE t1 (a INT, KEY(a)) ENGINE=RocksDB;
+INSERT INTO t1 VALUES (1),(1+1);
+create table t2 (a int);
+insert into t2 values (10),(20),(30);
+
+BEGIN;
+select * from t2;
+
+connect (con1,localhost,root,,);
+connection con1;
+alter table t1 force;
+
+connection default;
+select * from t1;
+
+connection con1;
+insert into t1 values (100);
+select * from t1;
+
+disconnect con1;
+connection default;
+rollback;
+drop table t1,t2;
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/analyze_table.test b/storage/rocksdb/mysql-test/rocksdb/t/analyze_table.test
index 10722194121..b24398b1fe2 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/analyze_table.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/analyze_table.test
@@ -1,4 +1,5 @@
--source include/have_rocksdb.inc
+--source include/have_partition.inc
#
# ANALYZE TABLE statements
@@ -29,3 +30,28 @@ INSERT INTO t1 VALUES (5,8),(6,10),(7,11),(8,12);
ANALYZE TABLE t1;
DROP TABLE t1;
+--echo #
+--echo # MDEV-12465: Server crashes in my_scan_weight_utf8_bin upon
+--echo # collecting stats for RocksDB table
+--echo #
+
+CREATE TABLE t1 (
+ pk INT,
+ f1 CHAR(255),
+ f2 TEXT,
+ f3 VARCHAR(255),
+ f4 TEXT,
+ PRIMARY KEY (pk),
+ KEY (f4(255))
+) ENGINE=RocksDB
+ CHARSET utf8
+ COLLATE utf8_bin
+ PARTITION BY KEY (pk) PARTITIONS 2;
+INSERT INTO t1 VALUES
+(1,'foo','bar','foo','bar'), (2,'bar','foo','bar','foo');
+
+ANALYZE TABLE t1 PERSISTENT FOR ALL;
+
+drop table t1;
+
+--echo # End of 10.2 tests
diff --git a/storage/rocksdb/rdb_datadic.cc b/storage/rocksdb/rdb_datadic.cc
index 3ea543c7c42..5664bd901b3 100644
--- a/storage/rocksdb/rdb_datadic.cc
+++ b/storage/rocksdb/rdb_datadic.cc
@@ -4271,6 +4271,9 @@ bool Rdb_ddl_manager::rename(const std::string &from, const std::string &to,
rec->m_auto_incr_val.load(std::memory_order_relaxed);
new_rec->m_key_descr_arr = rec->m_key_descr_arr;
+ new_rec->m_hidden_pk_val =
+ rec->m_hidden_pk_val.load(std::memory_order_relaxed);
+
// so that it's not free'd when deleting the old rec
rec->m_key_descr_arr = nullptr;
diff --git a/storage/tokudb/CMakeLists.txt b/storage/tokudb/CMakeLists.txt
index a0abee09727..16f7ab4ce75 100644
--- a/storage/tokudb/CMakeLists.txt
+++ b/storage/tokudb/CMakeLists.txt
@@ -35,7 +35,7 @@ SET(TOKUDB_SOURCES
tokudb_thread.cc
tokudb_dir_cmd.cc)
MYSQL_ADD_PLUGIN(tokudb ${TOKUDB_SOURCES} STORAGE_ENGINE MODULE_ONLY
- COMPONENT tokudb-engine CONFIG tokudb.cnf)
+ COMPONENT tokudb-engine CONFIG ${CMAKE_CURRENT_BINARY_DIR}/tokudb.cnf)
IF(NOT TARGET tokudb)
RETURN()
@@ -46,6 +46,33 @@ CHECK_JEMALLOC()
IF(NOT LIBJEMALLOC)
MESSAGE(WARNING "TokuDB is enabled, but jemalloc is not. This configuration is not supported")
+ELSEIF(LIBJEMALLOC STREQUAL jemalloc)
+ FIND_LIBRARY(LIBJEMALLOC_SO jemalloc)
+ IF(NOT LIBJEMALLOC_SO)
+ MESSAGE(FATAL_ERROR "jemalloc is present, but cannot be found?")
+ ENDIF()
+ GET_FILENAME_COMPONENT(LIBJEMALLOC_PATH ${LIBJEMALLOC_SO} REALPATH CACHE)
+ENDIF()
+
+IF(LIBJEMALLOC_PATH AND RPM MATCHES fedora28) # TODO check for jemalloc version
+ UNSET(LIBJEMALLOC)
+ GET_DIRECTORY_PROPERTY(V DIRECTORY ${CMAKE_SOURCE_DIR} DEFINITION CPACK_RPM_tokudb-engine_PACKAGE_REQUIRES)
+ SET(CPACK_RPM_tokudb-engine_PACKAGE_REQUIRES "${V} jemalloc" PARENT_SCOPE)
+ SET(systemd_env "Environment=\"LD_PRELOAD=${LIBJEMALLOC_PATH}\"") #"
+ SET(cnf_malloc_lib "malloc-lib=${LIBJEMALLOC_PATH}")
+ELSEIF(LIBJEMALLOC_PATH)
+ SET(systemd_env "#Environment=\"LD_PRELOAD=${LIBJEMALLOC_PATH}\"") #"
+ SET(cnf_malloc_lib "#malloc-lib=${LIBJEMALLOC_PATH}")
+ELSE()
+ SET(systemd_env "#Environment=\"LD_PRELOAD=/path/to/libjemalloc.so\"") #"
+ SET(cnf_malloc_lib "#malloc-lib=/path/to/libjemalloc.so")
+ENDIF()
+CONFIGURE_FILE(tokudb.cnf.in tokudb.cnf @ONLY)
+CONFIGURE_FILE(tokudb.conf.in tokudb.conf @ONLY)
+IF(INSTALL_SYSCONFDIR)
+ INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/tokudb.conf
+ DESTINATION ${INSTALL_SYSCONFDIR}/systemd/system/mariadb.service.d/
+ COMPONENT tokudb-engine)
ENDIF()
MY_CHECK_AND_SET_COMPILER_FLAG("-Wno-vla" DEBUG)
diff --git a/storage/tokudb/tokudb.cnf b/storage/tokudb/tokudb.cnf.in
index 4def635ddf0..de9b5b711ee 100644
--- a/storage/tokudb/tokudb.cnf
+++ b/storage/tokudb/tokudb.cnf.in
@@ -4,3 +4,6 @@
plugin-load-add=ha_tokudb.so
+[mysqld_safe]
+# it might be necessary to uncomment the following line if jemalloc >= 5.0.0
+@cnf_malloc_lib@
diff --git a/storage/tokudb/tokudb.conf.in b/storage/tokudb/tokudb.conf.in
new file mode 100644
index 00000000000..d22f6686d91
--- /dev/null
+++ b/storage/tokudb/tokudb.conf.in
@@ -0,0 +1,3 @@
+[Service]
+# it might be necessary to uncomment the following line if jemalloc >= 5.0.0
+@systemd_env@