summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2021-05-26 11:22:40 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2021-05-26 11:22:40 +0300
commit860e754349646fb8ec8e9231a7fc09a5d4b7c247 (patch)
treed66c4b8a3c96e8e0d6e6ad9dfb12cdca750eb754
parent71e1ddda220c2d452351fc6bf240cb0bad6ccf4a (diff)
parent365cd08345ab759308cfcac663a2a5880c0c33cb (diff)
downloadmariadb-git-860e754349646fb8ec8e9231a7fc09a5d4b7c247.tar.gz
Merge 10.5 into 10.6
-rw-r--r--BUILD/FINISH.sh8
-rwxr-xr-xBUILD/SETUP.sh4
-rw-r--r--CMakeLists.txt2
-rw-r--r--cmake/FindGit.cmake13
-rw-r--r--cmake/FindJNI.cmake5
-rw-r--r--cmake/FindJava.cmake5
-rw-r--r--cmake/build_configurations/mysql_release.cmake8
-rw-r--r--cmake/cpack_rpm.cmake2
-rw-r--r--cmake/cpu_info.cmake4
-rw-r--r--dbug/CMakeLists.txt2
-rw-r--r--debian/mariadb-plugin-connect.install4
-rw-r--r--mysql-test/main/cte_nonrecursive.result201
-rw-r--r--mysql-test/main/cte_nonrecursive.test202
-rw-r--r--mysql-test/main/ctype_filename.result41
-rw-r--r--mysql-test/main/ctype_filename.test35
-rw-r--r--mysql-test/main/mysqld--help.result2
-rw-r--r--mysql-test/main/mysqld--help.test2
-rw-r--r--mysql-test/main/subselect4.result21
-rw-r--r--mysql-test/main/subselect4.test27
-rw-r--r--mysql-test/main/trigger-trans.result13
-rw-r--r--mysql-test/main/trigger-trans.test16
-rw-r--r--mysql-test/suite/binlog/r/binlog_admin_cmd_kill.result2
-rw-r--r--mysql-test/suite/binlog/t/binlog_admin_cmd_kill.test5
-rw-r--r--mysql-test/suite/galera/disabled.def4
-rw-r--r--mysql-test/suite/galera/r/MDEV-25562.result16
-rw-r--r--mysql-test/suite/galera/t/MDEV-25562.test23
-rw-r--r--mysql-test/suite/innodb_fts/r/innodb-fts-ddl.result12
-rw-r--r--mysql-test/suite/innodb_fts/r/misc_debug.result13
-rw-r--r--mysql-test/suite/innodb_fts/t/innodb-fts-ddl.opt1
-rw-r--r--mysql-test/suite/innodb_fts/t/innodb-fts-ddl.test19
-rw-r--r--mysql-test/suite/innodb_fts/t/misc_debug.test15
-rw-r--r--mysql-test/suite/perfschema/r/hostcache_ipv4_auth_ed25519.result121
-rw-r--r--mysql-test/suite/perfschema/t/hostcache_ipv4_auth_ed25519.test56
-rw-r--r--mysys/crc32/crc32c.cc4
-rw-r--r--mysys/my_largepage.c6
-rw-r--r--plugin/auth_ed25519/server_ed25519.c6
-rw-r--r--scripts/wsrep_sst_common.sh39
-rw-r--r--sql/item.cc1
-rw-r--r--sql/item_subselect.cc41
-rw-r--r--sql/lock.cc7
-rw-r--r--sql/mysqld.cc2
-rw-r--r--sql/mysqld.h2
-rw-r--r--sql/sp_head.cc3
-rw-r--r--sql/sql_acl.cc5
-rw-r--r--sql/sql_base.cc33
-rw-r--r--sql/sql_class.cc56
-rw-r--r--sql/sql_class.h13
-rw-r--r--sql/sql_cte.cc422
-rw-r--r--sql/sql_cte.h85
-rw-r--r--sql/sql_lex.cc11
-rw-r--r--sql/sql_lex.h26
-rw-r--r--sql/sql_parse.cc17
-rw-r--r--sql/sql_prepare.cc3
-rw-r--r--sql/sql_trigger.cc12
-rw-r--r--sql/sql_view.cc19
-rw-r--r--sql/sql_yacc.yy26
-rw-r--r--sql/table.h37
-rw-r--r--sql/threadpool_generic.cc13
-rw-r--r--storage/connect/CMakeLists.txt4
-rw-r--r--storage/connect/javaconn.cpp14
-rw-r--r--storage/connect/tabjson.cpp1
-rw-r--r--storage/innobase/fts/fts0fts.cc29
-rw-r--r--storage/innobase/handler/ha_innodb.cc26
-rw-r--r--storage/mroonga/vendor/groonga/CMakeLists.txt11
-rw-r--r--support-files/rpm/server-posttrans.sh2
65 files changed, 1540 insertions, 340 deletions
diff --git a/BUILD/FINISH.sh b/BUILD/FINISH.sh
index fd51f2f5dfe..015f973d8a8 100644
--- a/BUILD/FINISH.sh
+++ b/BUILD/FINISH.sh
@@ -44,7 +44,13 @@ cd ../storage/rocksdb/rocksdb
git submodule update
cd ../../maria/libmarias3
git submodule update
-cd ../../.."
+cd ../../..
+cd storage/columnstore/columnstore
+git submodule update
+cd ../../..
+cd wsrep-lib
+git submodule update
+cd .."
fi
commands="$commands
path=`dirname $0`
diff --git a/BUILD/SETUP.sh b/BUILD/SETUP.sh
index bc4c65d5f6b..9cd022f8ad8 100755
--- a/BUILD/SETUP.sh
+++ b/BUILD/SETUP.sh
@@ -32,6 +32,7 @@ Usage: $0 [-h|-n] [configure-options]
-n, --just-print Don't actually run any commands; just print them.
-c, --just-configure Stop after running configure.
Combined with --just-print shows configure options.
+ --just-clean Clean up compilation files and update sub modules
--extra-configs=xxx Add this to configure options
--extra-flags=xxx Add this C and CXX flags
--extra-cflags=xxx Add this to C flags
@@ -71,6 +72,8 @@ parse_options()
just_configure=1;;
-n | --just-print | --print)
just_print=1;;
+ --just-clean)
+ just_clean=1;;
--verbose)
verbose_make=1;;
-h | --help)
@@ -94,6 +97,7 @@ fi
prefix="/usr/local/mysql"
just_print=
+just_clean=
just_configure=
warning_mode=
maintainer_mode=
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7072214ba23..d6cf989711d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -123,11 +123,13 @@ FOREACH(_base
ENDIF()
ENDFOREACH()
+IF(NOT RPM AND NOT DEB)
FOREACH(tool gtar tar)
STRING(TOUPPER ${tool} TOOL)
FIND_PROGRAM(${TOOL}_EXECUTABLE ${tool} DOC "path to the executable")
MARK_AS_ADVANCED(${TOOL}_EXECUTABLE)
ENDFOREACH()
+ENDIF()
FIND_PACKAGE(Git)
diff --git a/cmake/FindGit.cmake b/cmake/FindGit.cmake
new file mode 100644
index 00000000000..8178b614a3e
--- /dev/null
+++ b/cmake/FindGit.cmake
@@ -0,0 +1,13 @@
+if(GIT_EXECUTABLE)
+ set(GIT_FOUND TRUE)
+ return()
+endif()
+if(DEFINED GIT_EXECUTABLE)
+ set(GIT_FOUND FALSE)
+ return()
+endif()
+
+set(orig_CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH})
+unset(CMAKE_MODULE_PATH)
+include(FindGit)
+set(CMAKE_MODULE_PATH ${orig_CMAKE_MODULE_PATH})
diff --git a/cmake/FindJNI.cmake b/cmake/FindJNI.cmake
index fb2f4801a70..12305d7c86d 100644
--- a/cmake/FindJNI.cmake
+++ b/cmake/FindJNI.cmake
@@ -1,4 +1,9 @@
+if(JAVA_AWT_LIBRARY)
+ set(JNI_FOUND TRUE)
+ return()
+endif()
if(DEFINED JAVA_AWT_LIBRARY)
+ set(JNI_FOUND FALSE)
return()
endif()
diff --git a/cmake/FindJava.cmake b/cmake/FindJava.cmake
index 95bbf8682cd..714f56b1f72 100644
--- a/cmake/FindJava.cmake
+++ b/cmake/FindJava.cmake
@@ -1,4 +1,9 @@
+if(Java_JAVA_EXECUTABLE)
+ set(JAVA_FOUND TRUE)
+ return()
+endif()
if(DEFINED Java_JAVA_EXECUTABLE)
+ set(JAVA_FOUND FALSE)
return()
endif()
diff --git a/cmake/build_configurations/mysql_release.cmake b/cmake/build_configurations/mysql_release.cmake
index 520665a2947..82db50ffe7d 100644
--- a/cmake/build_configurations/mysql_release.cmake
+++ b/cmake/build_configurations/mysql_release.cmake
@@ -84,6 +84,12 @@ ENDIF()
SET(WITH_INNODB_SNAPPY OFF CACHE STRING "")
SET(WITH_NUMA 0 CACHE BOOL "")
+SET(CPU_LEVEL1_DCACHE_LINESIZE 0)
+
+IF(NOT EXISTS ${CMAKE_SOURCE_DIR}/.git)
+ SET(GIT_EXECUTABLE GIT_EXECUTABLE-NOTFOUND CACHE FILEPATH "")
+ENDIF()
+
IF(WIN32)
SET(INSTALL_MYSQLTESTDIR "" CACHE STRING "")
SET(INSTALL_SQLBENCHDIR "" CACHE STRING "")
@@ -97,7 +103,6 @@ ELSEIF(RPM)
SET(WITH_ZLIB system CACHE STRING "")
SET(CHECKMODULE /usr/bin/checkmodule CACHE FILEPATH "")
SET(SEMODULE_PACKAGE /usr/bin/semodule_package CACHE FILEPATH "")
- SET(WITH_JEMALLOC "yes" CACHE STRING "")
SET(PLUGIN_AUTH_SOCKET YES CACHE STRING "")
SET(WITH_EMBEDDED_SERVER ON CACHE BOOL "")
# not yet, SLES 12.3 doesn't provide pcre2
@@ -107,7 +112,6 @@ ELSEIF(DEB)
SET(WITH_ZLIB system CACHE STRING "")
SET(WITH_LIBWRAP ON)
SET(HAVE_EMBEDDED_PRIVILEGE_CONTROL ON)
- SET(WITH_JEMALLOC "yes" CACHE STRING "")
SET(PLUGIN_AUTH_SOCKET YES CACHE STRING "")
SET(WITH_EMBEDDED_SERVER ON CACHE BOOL "")
SET(WITH_PCRE system CACHE STRING "")
diff --git a/cmake/cpack_rpm.cmake b/cmake/cpack_rpm.cmake
index 69688833c41..412e5cbf4ef 100644
--- a/cmake/cpack_rpm.cmake
+++ b/cmake/cpack_rpm.cmake
@@ -125,8 +125,6 @@ SET(ignored
"%ignore ${CMAKE_INSTALL_PREFIX}/share/man"
"%ignore ${CMAKE_INSTALL_PREFIX}/share/man/man1"
"%ignore ${CMAKE_INSTALL_PREFIX}/share/man/man8"
- "%ignore ${CMAKE_INSTALL_PREFIX}/share/man/man1*"
- "%ignore ${CMAKE_INSTALL_PREFIX}/share/man/man8*"
"%ignore ${CMAKE_INSTALL_PREFIX}/share/pkgconfig"
)
diff --git a/cmake/cpu_info.cmake b/cmake/cpu_info.cmake
index 1acfad5897f..2abeb5e12c1 100644
--- a/cmake/cpu_info.cmake
+++ b/cmake/cpu_info.cmake
@@ -15,6 +15,8 @@
# Symbols with information about the CPU.
+IF(NOT DEFINED CPU_LEVEL1_DCACHE_LINESIZE)
+
IF(CMAKE_SYSTEM_NAME MATCHES "Darwin")
FIND_PROGRAM(SYSCTL sysctl)
MARK_AS_ADVANCED(SYSCTL)
@@ -37,3 +39,5 @@ ELSE()
)
ENDIF()
ENDIF()
+
+ENDIF()
diff --git a/dbug/CMakeLists.txt b/dbug/CMakeLists.txt
index d45401be290..d938788aded 100644
--- a/dbug/CMakeLists.txt
+++ b/dbug/CMakeLists.txt
@@ -30,7 +30,7 @@ IF(NOT CMAKE_CROSSCOMPILING OR DEFINED CMAKE_CROSSCOMPILING_EMULATOR)
TARGET_LINK_LIBRARIES(factorial dbug)
ENDIF()
-IF(NOT WIN32 AND NOT CMAKE_GENERATOR MATCHES Xcode)
+IF(NOT WIN32 AND NOT CMAKE_GENERATOR MATCHES Xcode AND NOT RPM AND NOT DEB)
FIND_PROGRAM(GROFF groff)
FIND_PROGRAM(NROFF nroff)
MARK_AS_ADVANCED(GROFF)
diff --git a/debian/mariadb-plugin-connect.install b/debian/mariadb-plugin-connect.install
index e2500269438..6cf529163cd 100644
--- a/debian/mariadb-plugin-connect.install
+++ b/debian/mariadb-plugin-connect.install
@@ -1,2 +1,6 @@
etc/mysql/mariadb.conf.d/connect.cnf
usr/lib/mysql/plugin/ha_connect.so
+usr/share/mysql/Mongo2.jar
+usr/share/mysql/Mongo3.jar
+usr/share/mysql/JavaWrappers.jar
+usr/share/mysql/JdbcInterface.jar
diff --git a/mysql-test/main/cte_nonrecursive.result b/mysql-test/main/cte_nonrecursive.result
index 54283f1ccf1..763e51f61cb 100644
--- a/mysql-test/main/cte_nonrecursive.result
+++ b/mysql-test/main/cte_nonrecursive.result
@@ -1763,6 +1763,207 @@ a c
2 1
7 3
drop table t1;
+#
+# MDEV-23886: Stored Function returning the result of a query
+# that uses CTE over a table twice
+#
+create table t1 (c1 int);
+insert into t1 values (1),(2),(6);
+create function f1() returns int return
+( with cte1 as (select c1 from t1)
+select sum(c1) from
+(select * from cte1 union all select * from cte1) dt
+);
+select f1();
+f1()
+18
+create function f2() returns int return
+( with cte1 as (select c1 from t1)
+select sum(s.c1) from cte1 as s, cte1 as t where s.c1=t.c1
+);
+select f2();
+f2()
+9
+create function f3() returns int return
+( with cte1 as (select c1 from t1)
+select
+case
+when exists(select 1 from cte1 where c1 between 1 and 2) then 1
+when exists(select 1 from cte1 where c1 between 5 and 6) then 2
+else 0
+end
+);
+select f3();
+f3()
+1
+create view v1 as (select c1 from t1);
+create function f4() returns int return
+( select sum(c1) from
+(select * from v1 union all select * from v1) dt
+);
+select f4();
+f4()
+18
+create function f5() returns int return
+( select sum(s.c1) from v1 as s, v1 as t where s.c1=t.c1
+);
+select f5();
+f5()
+9
+create view v2(s) as
+with cte1 as (select c1 from t1)
+select sum(c1) from (select * from cte1 union all select * from cte1) dt;
+create function f6() returns int return
+(select s from v2);
+select f6();
+f6()
+18
+create function f7() returns int return
+( select r.s from v2 as r, v2 as t where r.s=t.s
+);
+select f7();
+f7()
+18
+select f5() + f6();
+f5() + f6()
+27
+prepare stmt from "select f5() + f6();";
+execute stmt;
+f5() + f6()
+27
+execute stmt;
+f5() + f6()
+27
+deallocate prepare stmt;
+drop function f1;
+drop function f2;
+drop function f3;
+drop function f4;
+drop function f5;
+drop function f6;
+drop function f7;
+drop view v1;
+drop view v2;
+create table t2 (a int, b int);
+insert into t2
+with cte1 as (select c1 from t1)
+select * from cte1 as s, cte1 as t where s.c1=t.c1 and s.c1 > 5;
+select * from t2;
+a b
+6 6
+create procedure p1()
+begin
+insert into t2
+with cte1 as (select c1 from t1)
+select * from cte1 as s, cte1 as t where s.c1=t.c1 and s.c1 <= 2 and t.c1 >= 2;
+end |
+call p1();
+select * from t2;
+a b
+6 6
+2 2
+drop procedure p1;
+# checking CTE resolution for queries with hanging CTEs
+with
+cte1(a) as (select * from t1 where c1 <= 2),
+cte2(b) as (select * from cte1 where a >= 2),
+cte3 as (select * from cte1,cte2 where cte1.a < cte2.b)
+select * from cte3;
+a b
+1 2
+select * from t2;
+a b
+6 6
+2 2
+with
+cte1(a) as (select * from t1 where c1 <= 2),
+cte2(b) as (select * from cte1 where a >= 2),
+cte3 as (select * from cte1,cte2 where cte1.a < cte2.b)
+select * from t2;
+a b
+6 6
+2 2
+with
+cte1(a) as (select * from t1 where c1 <= 2),
+cte2(b) as (select * from cte1 where c1 >= 2),
+cte3 as (select * from cte1,cte2 where cte1.a < cte2.b)
+select * from t2;
+ERROR 42S22: Unknown column 'c1' in 'where clause'
+with
+cte1(a) as (select * from t1 where c1 <= 2),
+cte2(b) as (select * from cte1 where a >= 2),
+cte3 as (select * from cte1,cte2 where cte1.a < cte2.c1)
+select * from t2;
+ERROR 42S22: Unknown column 'cte2.c1' in 'where clause'
+with
+cte1 as (select * from t1 where c1 <= 2),
+cte2(a,b) as (select * from cte1 as s1, cte1 as s2 where s1.c1=s2.c1)
+select * from cte2;
+a b
+1 1
+2 2
+with
+cte1 as (select * from t1 where c1 <= 2),
+cte2(a,b) as (select * from cte1 as s1, cte1 as s2 where s1.c1=s2.c1)
+select * from t2;
+a b
+6 6
+2 2
+with
+cte1 as (select * from t1 where c1 <= 2),
+cte2(a,b) as (select * from cte1 as s1, cte1 as s2 where s1.c1=c1)
+select * from t2;
+ERROR 23000: Column 'c1' in where clause is ambiguous
+with cte3 as
+( with cte2(a,b) as
+( with cte1 as (select * from t1 where c1 <= 2)
+select * from cte1 as s1, cte1 as s2 where s1.c1=s2.c1)
+select r1.a,r2.b from cte2 as r1, cte2 as r2)
+select * from cte3;
+a b
+1 1
+2 1
+1 2
+2 2
+with cte3 as
+( with cte2(a,b) as
+( with cte1 as (select * from t1 where c1 <= 2)
+select * from cte1 as s1, cte1 as s2 where s1.c1=s2.c1)
+select r1.a,r2.b from cte2 as r1, cte2 as r2)
+select * from t2;
+a b
+6 6
+2 2
+with cte3 as
+( with cte2(a,b) as
+( with cte1 as (select * from t1 where c1 <= 2)
+select * from cte1 as s1, cte1 as s2 where s1.c1=s2.c1)
+select r1.c1,r2.c1 from cte2 as r1, cte2 as r2)
+select * from t2;
+ERROR 42S22: Unknown column 'r1.c1' in 'field list'
+create procedure p1()
+begin
+insert into t2
+with cte1 as (select c1 from t1)
+select * from t1 as s, t1 as t where s.c1=t.c1 and s.c1 <= 2 and t.c1 >= 2;
+end |
+call p1();
+select * from t2;
+a b
+6 6
+2 2
+2 2
+drop procedure p1;
+create procedure p1()
+begin
+insert into t2
+with cte1 as (select a from t1)
+select * from t1 as s, t1 as t where s.c1=t.c1 and s.c1 <= 2 and t.c1 >= 2;
+end |
+call p1();
+ERROR 42S22: Unknown column 'a' in 'field list'
+drop procedure p1;
+drop table t1,t2;
# End of 10.2 tests
#
# MDEV-21673: several references to CTE that uses
diff --git a/mysql-test/main/cte_nonrecursive.test b/mysql-test/main/cte_nonrecursive.test
index a4a1a1784cd..59dae44cb66 100644
--- a/mysql-test/main/cte_nonrecursive.test
+++ b/mysql-test/main/cte_nonrecursive.test
@@ -1273,6 +1273,208 @@ select a, c from cte as r2 where a > 4;
drop table t1;
+--echo #
+--echo # MDEV-23886: Stored Function returning the result of a query
+--echo # that uses CTE over a table twice
+--echo #
+
+create table t1 (c1 int);
+insert into t1 values (1),(2),(6);
+
+create function f1() returns int return
+( with cte1 as (select c1 from t1)
+ select sum(c1) from
+ (select * from cte1 union all select * from cte1) dt
+);
+select f1();
+
+create function f2() returns int return
+( with cte1 as (select c1 from t1)
+ select sum(s.c1) from cte1 as s, cte1 as t where s.c1=t.c1
+);
+select f2();
+
+create function f3() returns int return
+( with cte1 as (select c1 from t1)
+ select
+ case
+ when exists(select 1 from cte1 where c1 between 1 and 2) then 1
+ when exists(select 1 from cte1 where c1 between 5 and 6) then 2
+ else 0
+ end
+);
+select f3();
+
+create view v1 as (select c1 from t1);
+
+create function f4() returns int return
+( select sum(c1) from
+ (select * from v1 union all select * from v1) dt
+);
+select f4();
+
+create function f5() returns int return
+( select sum(s.c1) from v1 as s, v1 as t where s.c1=t.c1
+);
+select f5();
+
+create view v2(s) as
+with cte1 as (select c1 from t1)
+select sum(c1) from (select * from cte1 union all select * from cte1) dt;
+
+create function f6() returns int return
+(select s from v2);
+select f6();
+
+create function f7() returns int return
+( select r.s from v2 as r, v2 as t where r.s=t.s
+);
+select f7();
+
+select f5() + f6();
+
+prepare stmt from "select f5() + f6();";
+execute stmt;
+execute stmt;
+deallocate prepare stmt;
+
+drop function f1;
+drop function f2;
+drop function f3;
+drop function f4;
+drop function f5;
+drop function f6;
+drop function f7;
+
+drop view v1;
+drop view v2;
+
+create table t2 (a int, b int);
+
+insert into t2
+with cte1 as (select c1 from t1)
+select * from cte1 as s, cte1 as t where s.c1=t.c1 and s.c1 > 5;
+
+select * from t2;
+
+delimiter |;
+
+create procedure p1()
+begin
+insert into t2
+with cte1 as (select c1 from t1)
+select * from cte1 as s, cte1 as t where s.c1=t.c1 and s.c1 <= 2 and t.c1 >= 2;
+end |
+
+delimiter ;|
+
+call p1();
+select * from t2;
+
+drop procedure p1;
+
+--echo # checking CTE resolution for queries with hanging CTEs
+
+with
+cte1(a) as (select * from t1 where c1 <= 2),
+cte2(b) as (select * from cte1 where a >= 2),
+cte3 as (select * from cte1,cte2 where cte1.a < cte2.b)
+select * from cte3;
+
+select * from t2;
+
+with
+cte1(a) as (select * from t1 where c1 <= 2),
+cte2(b) as (select * from cte1 where a >= 2),
+cte3 as (select * from cte1,cte2 where cte1.a < cte2.b)
+select * from t2;
+
+--error ER_BAD_FIELD_ERROR
+with
+cte1(a) as (select * from t1 where c1 <= 2),
+cte2(b) as (select * from cte1 where c1 >= 2),
+cte3 as (select * from cte1,cte2 where cte1.a < cte2.b)
+select * from t2;
+
+--error ER_BAD_FIELD_ERROR
+with
+cte1(a) as (select * from t1 where c1 <= 2),
+cte2(b) as (select * from cte1 where a >= 2),
+cte3 as (select * from cte1,cte2 where cte1.a < cte2.c1)
+select * from t2;
+
+with
+cte1 as (select * from t1 where c1 <= 2),
+cte2(a,b) as (select * from cte1 as s1, cte1 as s2 where s1.c1=s2.c1)
+select * from cte2;
+
+with
+cte1 as (select * from t1 where c1 <= 2),
+cte2(a,b) as (select * from cte1 as s1, cte1 as s2 where s1.c1=s2.c1)
+select * from t2;
+
+--error ER_NON_UNIQ_ERROR
+with
+cte1 as (select * from t1 where c1 <= 2),
+cte2(a,b) as (select * from cte1 as s1, cte1 as s2 where s1.c1=c1)
+select * from t2;
+
+with cte3 as
+( with cte2(a,b) as
+ ( with cte1 as (select * from t1 where c1 <= 2)
+ select * from cte1 as s1, cte1 as s2 where s1.c1=s2.c1)
+ select r1.a,r2.b from cte2 as r1, cte2 as r2)
+select * from cte3;
+
+with cte3 as
+( with cte2(a,b) as
+ ( with cte1 as (select * from t1 where c1 <= 2)
+ select * from cte1 as s1, cte1 as s2 where s1.c1=s2.c1)
+ select r1.a,r2.b from cte2 as r1, cte2 as r2)
+select * from t2;
+
+--error ER_BAD_FIELD_ERROR
+with cte3 as
+( with cte2(a,b) as
+ ( with cte1 as (select * from t1 where c1 <= 2)
+ select * from cte1 as s1, cte1 as s2 where s1.c1=s2.c1)
+ select r1.c1,r2.c1 from cte2 as r1, cte2 as r2)
+select * from t2;
+
+delimiter |;
+
+create procedure p1()
+begin
+insert into t2
+with cte1 as (select c1 from t1)
+select * from t1 as s, t1 as t where s.c1=t.c1 and s.c1 <= 2 and t.c1 >= 2;
+end |
+
+delimiter ;|
+
+call p1();
+select * from t2;
+
+drop procedure p1;
+
+delimiter |;
+
+create procedure p1()
+begin
+insert into t2
+with cte1 as (select a from t1)
+select * from t1 as s, t1 as t where s.c1=t.c1 and s.c1 <= 2 and t.c1 >= 2;
+end |
+
+delimiter ;|
+
+--error ER_BAD_FIELD_ERROR
+call p1();
+
+drop procedure p1;
+
+drop table t1,t2;
+
--echo # End of 10.2 tests
--echo #
diff --git a/mysql-test/main/ctype_filename.result b/mysql-test/main/ctype_filename.result
index 2eee5d2888e..739fa979f28 100644
--- a/mysql-test/main/ctype_filename.result
+++ b/mysql-test/main/ctype_filename.result
@@ -22,21 +22,50 @@ SELECT @a:=CONVERT('aя' USING filename) AS `@a`, BINARY @a, REVERSE(@a), HEX(@a
@a BINARY @a REVERSE(@a) HEX(@a) HEX(REVERSE(@a))
aя a@r1 яa 61407231 40723161
#
+# Beginning of 10.2 test.
+#
+# MDEV-25462: Assertion `m_status == DA_ERROR || m_status == DA_OK ||
+# m_status == DA_OK_BULK' failed in Diagnostics_area::message from
+# get_schema_tables_record
+#
+SELECT @@character_set_client, @@character_set_connection, @@character_set_results;
+@@character_set_client @@character_set_connection @@character_set_results
+utf8mb3 utf8mb3 utf8mb3
+SET @old_character_set_client= @@character_set_client;
+SET @old_character_set_connection= @@character_set_connection;
+SET @old_character_set_results= @@character_set_results;
+SET NAMES 'filename';
+ERROR 42000: Variable 'character_set_client' can't be set to the value of 'filename'
+SELECT @@character_set_client, @@character_set_connection, @@character_set_results;
+@@character_set_client @@character_set_connection @@character_set_results
+utf8mb3 utf8mb3 utf8mb3
+CREATE VIEW v2 AS SELECT 1;
+SHOW TABLE STATUS;
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment Max_index_length Temporary
+v2 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL VIEW NULL NULL
+DROP VIEW v2;
+SET @@character_set_client= @old_character_set_client;
+SET @@character_set_connection= @old_character_set_connection;
+SET @@character_set_results= @old_character_set_results;
+#
+# End of 10.2 test
+#
+#
# MDEV-22022 Various mangled SQL statements will crash 10.3 to 10.5 debug builds
#
SET CHARACTER_SET_CLIENT=17;
+ERROR 42000: Variable 'character_set_client' can't be set to the value of '17'
SELECT doc.`Children`.0 FROM t1;
-ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '?Children??0?FROM?t1' at line 1
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '.0 FROM t1' at line 1
SET NAMES latin1;
-#
-# Start of 10.5 tests
-#
+# End of 10.3 tests
#
# MDEV-22043 Special character leads to assertion in my_wc_to_printable_generic on 10.5.2 (debug)
#
SET NAMES filename;
+ERROR 42000: Variable 'character_set_client' can't be set to the value of 'filename'
EXECUTE IMMEDIATE _latin1 0x01;
-ERROR 42000: You@0020have@0020an@0020error@0020in@0020your@0020SQL@0020syntax@003b@0020check@0020the@0020manual@0020that@0020corresponds@0020to@0020your@0020MariaDB@0020server@0020version@0020for@0020the@0020right@0020syntax@0020to@0020use@0020near@0020@0027@005c0001@0027@0020at@0020line@00201
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '\0001' at line 1
SET NAMES utf8;
#
# MDEV-23435 Functions do not convert numbers to character_set_results
@@ -103,6 +132,4 @@ a c
@002d1 @002d1
DROP TABLE t1;
SET NAMES utf8;
-#
# End of 10.5 tests
-#
diff --git a/mysql-test/main/ctype_filename.test b/mysql-test/main/ctype_filename.test
index 17ab71e3985..ba42d1a2807 100644
--- a/mysql-test/main/ctype_filename.test
+++ b/mysql-test/main/ctype_filename.test
@@ -28,25 +28,49 @@ select convert(convert(',' using filename) using binary);
SET NAMES utf8;
SELECT @a:=CONVERT('aя' USING filename) AS `@a`, BINARY @a, REVERSE(@a), HEX(@a), HEX(REVERSE(@a));
+--echo #
+--echo # Beginning of 10.2 test.
+--echo #
+--echo # MDEV-25462: Assertion `m_status == DA_ERROR || m_status == DA_OK ||
+--echo # m_status == DA_OK_BULK' failed in Diagnostics_area::message from
+--echo # get_schema_tables_record
+--echo #
+
+SELECT @@character_set_client, @@character_set_connection, @@character_set_results;
+SET @old_character_set_client= @@character_set_client;
+SET @old_character_set_connection= @@character_set_connection;
+SET @old_character_set_results= @@character_set_results;
+--error ER_WRONG_VALUE_FOR_VAR
+SET NAMES 'filename';
+SELECT @@character_set_client, @@character_set_connection, @@character_set_results;
+CREATE VIEW v2 AS SELECT 1;
+SHOW TABLE STATUS;
+DROP VIEW v2;
+SET @@character_set_client= @old_character_set_client;
+SET @@character_set_connection= @old_character_set_connection;
+SET @@character_set_results= @old_character_set_results;
+
+--echo #
+--echo # End of 10.2 test
+--echo #
--echo #
--echo # MDEV-22022 Various mangled SQL statements will crash 10.3 to 10.5 debug builds
--echo #
+--error ER_WRONG_VALUE_FOR_VAR
SET CHARACTER_SET_CLIENT=17;
--error ER_PARSE_ERROR
SELECT doc.`Children`.0 FROM t1;
SET NAMES latin1;
-
---echo #
---echo # Start of 10.5 tests
---echo #
+--echo # End of 10.3 tests
--echo #
--echo # MDEV-22043 Special character leads to assertion in my_wc_to_printable_generic on 10.5.2 (debug)
--echo #
+--error ER_WRONG_VALUE_FOR_VAR
SET NAMES filename;
--error ER_PARSE_ERROR
EXECUTE IMMEDIATE _latin1 0x01;
@@ -114,7 +138,4 @@ SET NAMES utf8;
--enable_ps_protocol
-
---echo #
--echo # End of 10.5 tests
---echo #
diff --git a/mysql-test/main/mysqld--help.result b/mysql-test/main/mysqld--help.result
index 99d84bb3457..5d014240faa 100644
--- a/mysql-test/main/mysqld--help.result
+++ b/mysql-test/main/mysqld--help.result
@@ -1579,7 +1579,7 @@ lc-messages-dir MYSQL_SHAREDIR/
lc-time-names en_US
local-infile TRUE
lock-wait-timeout 86400
-log-bin (No default value)
+log-bin foo
log-bin-compress FALSE
log-bin-compress-min-len 256
log-bin-index (No default value)
diff --git a/mysql-test/main/mysqld--help.test b/mysql-test/main/mysqld--help.test
index 4405b198951..f918670d319 100644
--- a/mysql-test/main/mysqld--help.test
+++ b/mysql-test/main/mysqld--help.test
@@ -13,7 +13,7 @@
# force symbolic-links=0 (valgrind build has a different default)
#
-exec $MYSQLD_BOOTSTRAP_CMD --symbolic-links=0 --lower-case-table-names=1 --help --verbose > $MYSQL_TMP_DIR/mysqld--help.txt 2>&1;
+exec $MYSQLD_BOOTSTRAP_CMD --symbolic-links=0 --log-bin=foo --lower-case-table-names=1 --help --verbose > $MYSQL_TMP_DIR/mysqld--help.txt 2>&1;
# The inline perl code below will copy $MYSQL_TMP_DIR/mysqld--help.txt
# to output, but filter away some variable stuff (e.g. paths).
diff --git a/mysql-test/main/subselect4.result b/mysql-test/main/subselect4.result
index 7daa0e5be87..78df05f4859 100644
--- a/mysql-test/main/subselect4.result
+++ b/mysql-test/main/subselect4.result
@@ -2721,7 +2721,15 @@ id select_type table type possible_keys key key_len ref rows Extra
SELECT a FROM t1 WHERE (a, a) IN (SELECT 1, 2) AND a = (SELECT MIN(b) FROM t2);
a
DROP TABLE t1,t2;
-# End of 10.2 tests
+#
+# MDEV-22462: Item_in_subselect::create_single_in_to_exists_cond(JOIN *, Item **, Item **): Assertion `false' failed.
+#
+select 1 from dual where 1 in (select 5 from dual where 1);
+1
+create table t1 (a int);
+insert into t1 values (1),(2),(3);
+update t1 set a = 2 where a in (select a from dual where a = a);
+drop table t1;
#
# MDEV-18335: Assertion `!error || error == 137' failed in subselect_rowid_merge_engine::init
#
@@ -2848,6 +2856,17 @@ INSERT INTO t2 VALUES (3),(4);
SELECT 1 IN (SELECT (SELECT a FROM t1) AS x FROM t2 GROUP BY x);
ERROR 21000: Subquery returns more than 1 row
drop table t1,t2;
+#
+# MDEV-25629: Crash in get_sort_by_table() in subquery with order by having outer ref
+#
+CREATE TABLE t1 (i1 int);
+insert into t1 values (1),(2);
+SELECT 1
+FROM (t1 JOIN t1 AS ref_t1 ON
+(t1.i1 > (SELECT ref_t1.i1 AS c0 FROM t1 b ORDER BY -c0)));
+ERROR 21000: Subquery returns more than 1 row
+DROP TABLE t1;
+# End of 10.2 tests
# End of 10.3 tests
#
# MDEV-19134: EXISTS() slower if ORDER BY is defined
diff --git a/mysql-test/main/subselect4.test b/mysql-test/main/subselect4.test
index a1a4108de37..2f65db875f8 100644
--- a/mysql-test/main/subselect4.test
+++ b/mysql-test/main/subselect4.test
@@ -2236,7 +2236,17 @@ SELECT a FROM t1 WHERE (a, a) IN (SELECT 1, 2) AND a = (SELECT MIN(b) FROM t2);
DROP TABLE t1,t2;
---echo # End of 10.2 tests
+--echo #
+--echo # MDEV-22462: Item_in_subselect::create_single_in_to_exists_cond(JOIN *, Item **, Item **): Assertion `false' failed.
+--echo #
+
+select 1 from dual where 1 in (select 5 from dual where 1);
+
+create table t1 (a int);
+insert into t1 values (1),(2),(3);
+
+update t1 set a = 2 where a in (select a from dual where a = a);
+drop table t1;
--echo #
--echo # MDEV-18335: Assertion `!error || error == 137' failed in subselect_rowid_merge_engine::init
@@ -2355,6 +2365,21 @@ INSERT INTO t2 VALUES (3),(4); # Optional, fails either way
SELECT 1 IN (SELECT (SELECT a FROM t1) AS x FROM t2 GROUP BY x);
drop table t1,t2;
+--echo #
+--echo # MDEV-25629: Crash in get_sort_by_table() in subquery with order by having outer ref
+--echo #
+CREATE TABLE t1 (i1 int);
+insert into t1 values (1),(2);
+
+--error ER_SUBQUERY_NO_1_ROW
+SELECT 1
+FROM (t1 JOIN t1 AS ref_t1 ON
+ (t1.i1 > (SELECT ref_t1.i1 AS c0 FROM t1 b ORDER BY -c0)));
+
+DROP TABLE t1;
+
+--echo # End of 10.2 tests
+
--echo # End of 10.3 tests
--echo #
diff --git a/mysql-test/main/trigger-trans.result b/mysql-test/main/trigger-trans.result
index c58c4230a40..24ef9a4291a 100644
--- a/mysql-test/main/trigger-trans.result
+++ b/mysql-test/main/trigger-trans.result
@@ -229,3 +229,16 @@ INSERT INTO t2 (id) VALUES (1);
disconnect con2;
connection default;
DROP TABLE t3, t2, t1;
+#
+# MDEV-25738 Assertion `ticket->m_duration == MDL_EXPLICIT' failed in
+# void MDL_context::release_lock(MDL_ticket*)
+#
+CREATE TABLE t1 (id int(11)) ENGINE=InnoDB;
+SET max_statement_time= 0.001;
+LOCK TABLES t1 WRITE;
+CREATE TRIGGER tr16 AFTER UPDATE ON t1 FOR EACH ROW INSERT INTO t1 VALUES (1);
+DROP TABLE t1;
+SET max_statement_time= default;
+#
+# End of 10.5 tests
+#
diff --git a/mysql-test/main/trigger-trans.test b/mysql-test/main/trigger-trans.test
index 17656c3516e..378da045e0a 100644
--- a/mysql-test/main/trigger-trans.test
+++ b/mysql-test/main/trigger-trans.test
@@ -233,3 +233,19 @@ DROP TABLE t3, t2, t1;
# Wait till we reached the initial number of concurrent sessions
--source include/wait_until_count_sessions.inc
+
+--echo #
+--echo # MDEV-25738 Assertion `ticket->m_duration == MDL_EXPLICIT' failed in
+--echo # void MDL_context::release_lock(MDL_ticket*)
+--echo #
+
+CREATE TABLE t1 (id int(11)) ENGINE=InnoDB;
+SET max_statement_time= 0.001;
+LOCK TABLES t1 WRITE;
+CREATE TRIGGER tr16 AFTER UPDATE ON t1 FOR EACH ROW INSERT INTO t1 VALUES (1);
+DROP TABLE t1;
+SET max_statement_time= default;
+
+--echo #
+--echo # End of 10.5 tests
+--echo #
diff --git a/mysql-test/suite/binlog/r/binlog_admin_cmd_kill.result b/mysql-test/suite/binlog/r/binlog_admin_cmd_kill.result
index a2eb7ee5c0a..d9bfead8dd1 100644
--- a/mysql-test/suite/binlog/r/binlog_admin_cmd_kill.result
+++ b/mysql-test/suite/binlog/r/binlog_admin_cmd_kill.result
@@ -20,7 +20,7 @@ master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (f INT) ENGINE=INNODB
master-bin.000001 # Gtid # # GTID #-#-#
master-bin.000001 # Query # # use `test`; CREATE TABLE t2 (f INT) ENGINE=INNODB
DROP TABLE t1,t2;
-FLUSH LOGS;
+RESET MASTER;
#
# Kill OPTIMIZE command after table modification
#
diff --git a/mysql-test/suite/binlog/t/binlog_admin_cmd_kill.test b/mysql-test/suite/binlog/t/binlog_admin_cmd_kill.test
index 9b248097ae2..e2397f0eab8 100644
--- a/mysql-test/suite/binlog/t/binlog_admin_cmd_kill.test
+++ b/mysql-test/suite/binlog/t/binlog_admin_cmd_kill.test
@@ -56,7 +56,7 @@ SET debug_sync = 'reset';
--source include/show_binlog_events.inc
DROP TABLE t1,t2;
-FLUSH LOGS;
+RESET MASTER;
--echo #
--echo # Kill OPTIMIZE command after table modification
@@ -81,6 +81,9 @@ eval KILL $thd_id;
SET debug_sync = 'reset';
--disconnect con1
+--let $wait_binlog_event= OPTIMIZE
+--source include/wait_for_binlog_event.inc
+
DROP TABLE t1,t2;
let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1);
FLUSH LOGS;
diff --git a/mysql-test/suite/galera/disabled.def b/mysql-test/suite/galera/disabled.def
index 5bc61bc98a1..740abcc9314 100644
--- a/mysql-test/suite/galera/disabled.def
+++ b/mysql-test/suite/galera/disabled.def
@@ -43,11 +43,11 @@ galera_var_notify_cmd : MDEV-21905 Galera test galera_var_notify_cmd causes hang
galera_var_reject_queries : assertion in inline_mysql_socket_send
galera_var_replicate_myisam_on : MDEV-24062 Galera test failure on galera_var_replicate_myisam_on
galera_var_retry_autocommit: MDEV-18181 Galera test failure on galera.galera_var_retry_autocommit
-#galera_wan : MDEV-17259 Test failure on galera.galera_wan
galera_wsrep_provider_unset_set: wsrep_provider is read-only for security reasons
mysql-wsrep#198 : MDEV-24446: galera.mysql-wsrep#198 MTR failed: query 'reap' failed: 2000: Unknown MySQL error
partition : MDEV-19958 Galera test failure on galera.partition
pxc-421: wsrep_provider is read-only for security reasons
query_cache: MDEV-15805 Test failure on galera.query_cache
-#sql_log_bin : MDEV-21491 galera.sql_log_bin
versioning_trx_id: MDEV-18590: galera.versioning_trx_id: Test failure: mysqltest: Result content mismatch
+
+MDEV-25562: MDEV-25562 FIXME: lock wait timeout exceeded
diff --git a/mysql-test/suite/galera/r/MDEV-25562.result b/mysql-test/suite/galera/r/MDEV-25562.result
new file mode 100644
index 00000000000..b0d77af374b
--- /dev/null
+++ b/mysql-test/suite/galera/r/MDEV-25562.result
@@ -0,0 +1,16 @@
+connection node_2;
+connection node_1;
+SET SESSION WSREP_ON=0;
+FLUSH TABLES WITH READ LOCK AND DISABLE CHECKPOINT;
+SET SESSION WSREP_ON=1;
+UNLOCK TABLES;
+SET GLOBAL wsrep_ignore_apply_errors=1;
+CREATE TABLE t1 (a CHAR(1)) engine=innodb;
+CREATE TABLE t1 (a CHAR(1)) engine=innodb;
+ERROR 42S01: Table 't1' already exists
+SHOW PROCEDURE STATUS WHERE db = 'test';
+Db Name Type Definer Modified Created Security_type Comment character_set_client collation_connection Database Collation
+SET GLOBAL read_only=1;
+SET GLOBAL wsrep_ignore_apply_errors=DEFAULT;
+SET GLOBAL read_only=DEFAULT;
+DROP TABLE t1;
diff --git a/mysql-test/suite/galera/t/MDEV-25562.test b/mysql-test/suite/galera/t/MDEV-25562.test
new file mode 100644
index 00000000000..01729936b08
--- /dev/null
+++ b/mysql-test/suite/galera/t/MDEV-25562.test
@@ -0,0 +1,23 @@
+#
+# MDEV-25562 Assertion `pause_seqno_.is_undefined() == false' failed in void wsrep::server_state::resume()
+#
+
+--source include/galera_cluster.inc
+--source include/have_innodb.inc
+
+SET SESSION WSREP_ON=0;
+FLUSH TABLES WITH READ LOCK AND DISABLE CHECKPOINT;
+SET SESSION WSREP_ON=1;
+UNLOCK TABLES;
+
+SET GLOBAL wsrep_ignore_apply_errors=1;
+CREATE TABLE t1 (a CHAR(1)) engine=innodb;
+--error ER_TABLE_EXISTS_ERROR
+CREATE TABLE t1 (a CHAR(1)) engine=innodb;
+SHOW PROCEDURE STATUS WHERE db = 'test';
+SET GLOBAL read_only=1;
+
+SET GLOBAL wsrep_ignore_apply_errors=DEFAULT;
+SET GLOBAL read_only=DEFAULT;
+DROP TABLE t1;
+
diff --git a/mysql-test/suite/innodb_fts/r/innodb-fts-ddl.result b/mysql-test/suite/innodb_fts/r/innodb-fts-ddl.result
index b50bf047265..a64086c9802 100644
--- a/mysql-test/suite/innodb_fts/r/innodb-fts-ddl.result
+++ b/mysql-test/suite/innodb_fts/r/innodb-fts-ddl.result
@@ -264,6 +264,18 @@ t1 CREATE TABLE `t1` (
`f1` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1
DROP TABLE t1;
+#
+# MDEV-25271 Double free of table when inplace alter
+# FTS add index fails
+#
+call mtr.add_suppression("InnoDB: Operating system error number .* in a file operation.");
+call mtr.add_suppression("InnoDB: Error number .* means");
+call mtr.add_suppression("InnoDB: Cannot create file");
+call mtr.add_suppression("InnoDB: Failed to create");
+CREATE TABLE t1(a TEXT, FTS_DOC_ID BIGINT UNSIGNED NOT NULL UNIQUE) ENGINE=InnoDB;
+ALTER TABLE t1 ADD FULLTEXT(a), ALGORITHM=INPLACE;
+ERROR HY000: Got error 11 "Resource temporarily unavailable" from storage engine InnoDB
+DROP TABLE t1;
CREATE TABLE t1 (a VARCHAR(3)) ENGINE=InnoDB;
ALTER TABLE t1 ADD FULLTEXT KEY(a), ADD COLUMN b VARCHAR(3), ADD FULLTEXT KEY(b);
DROP TABLE t1;
diff --git a/mysql-test/suite/innodb_fts/r/misc_debug.result b/mysql-test/suite/innodb_fts/r/misc_debug.result
index 10e3cf8874d..41f8d08ea7d 100644
--- a/mysql-test/suite/innodb_fts/r/misc_debug.result
+++ b/mysql-test/suite/innodb_fts/r/misc_debug.result
@@ -52,3 +52,16 @@ CHECK TABLE t1;
Table Op Msg_type Msg_text
test.t1 check status OK
DROP TABLE t1;
+#
+# MDEV-25663 Double free of transaction during TRUNCATE
+#
+call mtr.add_suppression("InnoDB: \\(Too many concurrent transactions\\)");
+SET DEBUG_DBUG='-d,ib_create_table_fail_too_many_trx';
+CREATE TABLE t1 (b CHAR(12), FULLTEXT KEY(b)) engine=InnoDB;
+SET @save_dbug= @@debug_dbug;
+SET debug_dbug='+d,ib_create_table_fail_too_many_trx';
+TRUNCATE t1;
+ERROR HY000: Got error -1 "Internal error < 0 (Not system error)" from storage engine InnoDB
+SET debug_dbug=@save_dbug;
+DROP TABLE t1;
+# End of 10.3 tests
diff --git a/mysql-test/suite/innodb_fts/t/innodb-fts-ddl.opt b/mysql-test/suite/innodb_fts/t/innodb-fts-ddl.opt
new file mode 100644
index 00000000000..e6ae8d0fe0a
--- /dev/null
+++ b/mysql-test/suite/innodb_fts/t/innodb-fts-ddl.opt
@@ -0,0 +1 @@
+--enable-plugin-innodb-sys-tables
diff --git a/mysql-test/suite/innodb_fts/t/innodb-fts-ddl.test b/mysql-test/suite/innodb_fts/t/innodb-fts-ddl.test
index 7c56811a2d9..78494910b48 100644
--- a/mysql-test/suite/innodb_fts/t/innodb-fts-ddl.test
+++ b/mysql-test/suite/innodb_fts/t/innodb-fts-ddl.test
@@ -319,6 +319,25 @@ ALTER TABLE t1 ADD FTS_DOC_ID INT UNSIGNED NOT NULL, ALGORITHM=INPLACE;
SHOW CREATE TABLE t1;
DROP TABLE t1;
+--echo #
+--echo # MDEV-25271 Double free of table when inplace alter
+--echo # FTS add index fails
+--echo #
+call mtr.add_suppression("InnoDB: Operating system error number .* in a file operation.");
+call mtr.add_suppression("InnoDB: Error number .* means");
+call mtr.add_suppression("InnoDB: Cannot create file");
+call mtr.add_suppression("InnoDB: Failed to create");
+
+let MYSQLD_DATADIR=`select @@datadir`;
+CREATE TABLE t1(a TEXT, FTS_DOC_ID BIGINT UNSIGNED NOT NULL UNIQUE) ENGINE=InnoDB;
+let $fts_aux_file= `select concat('FTS_',right(concat(repeat('0',16), lower(hex(TABLE_ID))),16),'_BEING_DELETED.ibd') FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME='test/t1'`;
+write_file $MYSQLD_DATADIR/test/$fts_aux_file;
+EOF
+--error ER_GET_ERRNO
+ALTER TABLE t1 ADD FULLTEXT(a), ALGORITHM=INPLACE;
+DROP TABLE t1;
+remove_file $MYSQLD_DATADIR/test/$fts_aux_file;
+
# Add more than one FTS index
CREATE TABLE t1 (a VARCHAR(3)) ENGINE=InnoDB;
ALTER TABLE t1 ADD FULLTEXT KEY(a), ADD COLUMN b VARCHAR(3), ADD FULLTEXT KEY(b);
diff --git a/mysql-test/suite/innodb_fts/t/misc_debug.test b/mysql-test/suite/innodb_fts/t/misc_debug.test
index 461e3f1d9d4..90cb84976ce 100644
--- a/mysql-test/suite/innodb_fts/t/misc_debug.test
+++ b/mysql-test/suite/innodb_fts/t/misc_debug.test
@@ -83,3 +83,18 @@ ALTER TABLE t1 ADD bl INT AS (LENGTH(b)) VIRTUAL;
CHECK TABLE t1;
DROP TABLE t1;
--source include/wait_until_count_sessions.inc
+
+--echo #
+--echo # MDEV-25663 Double free of transaction during TRUNCATE
+--echo #
+call mtr.add_suppression("InnoDB: \\(Too many concurrent transactions\\)");
+SET DEBUG_DBUG='-d,ib_create_table_fail_too_many_trx';
+
+CREATE TABLE t1 (b CHAR(12), FULLTEXT KEY(b)) engine=InnoDB;
+SET @save_dbug= @@debug_dbug;
+SET debug_dbug='+d,ib_create_table_fail_too_many_trx';
+--error ER_GET_ERRNO
+TRUNCATE t1;
+SET debug_dbug=@save_dbug;
+DROP TABLE t1;
+--echo # End of 10.3 tests
diff --git a/mysql-test/suite/perfschema/r/hostcache_ipv4_auth_ed25519.result b/mysql-test/suite/perfschema/r/hostcache_ipv4_auth_ed25519.result
new file mode 100644
index 00000000000..6e3d928509c
--- /dev/null
+++ b/mysql-test/suite/perfschema/r/hostcache_ipv4_auth_ed25519.result
@@ -0,0 +1,121 @@
+install soname 'auth_ed25519';
+flush status;
+flush hosts;
+flush user_resources;
+flush privileges;
+select `User`, `Host` from mysql.`user` where `host` like '%\\%%';
+User Host
+select `User`, `Host` from mysql.`user` where `user` like '192.%';
+User Host
+select `User`, `Host` from mysql.`user` where `user` like '2001:%';
+User Host
+select `User`, `Host` from mysql.`user` where `user` like 'santa.claus.%';
+User Host
+create user plug1@'santa.claus.ipv4.example.com'
+ identified with ed25519;
+update mysql.global_priv set priv=json_set(priv, '$.authentication_string', 'foo') where user='plug1';
+flush privileges;
+create user plug2@'santa.claus.ipv4.example.com'
+ identified with ED25519 as 'vubFBzIrapbfHct1/J72dnUryz5VS7lA6XHH8sIx4TI';
+set @saved_dbug = @@global.debug_dbug;
+set global debug_dbug= "+d,vio_peer_addr_fake_ipv4,getnameinfo_fake_ipv4,getaddrinfo_fake_good_ipv4";
+connect(127.0.0.1,plug1,foo,test,PORT,SOCKET);
+connect con1, 127.0.0.1, plug1,foo,,$MASTER_MYPORT;
+ERROR 28000: Access denied for user 'plug1'@'santa.claus.ipv4.example.com' (using password: YES)
+# Dumping performance_schema.host_cache
+IP 192.0.2.4
+HOST santa.claus.ipv4.example.com
+HOST_VALIDATED YES
+SUM_CONNECT_ERRORS 1
+COUNT_HOST_BLOCKED_ERRORS 0
+COUNT_NAMEINFO_TRANSIENT_ERRORS 0
+COUNT_NAMEINFO_PERMANENT_ERRORS 0
+COUNT_FORMAT_ERRORS 0
+COUNT_ADDRINFO_TRANSIENT_ERRORS 0
+COUNT_ADDRINFO_PERMANENT_ERRORS 0
+COUNT_FCRDNS_ERRORS 0
+COUNT_HOST_ACL_ERRORS 0
+COUNT_NO_AUTH_PLUGIN_ERRORS 0
+COUNT_AUTH_PLUGIN_ERRORS 0
+COUNT_HANDSHAKE_ERRORS 1
+COUNT_PROXY_USER_ERRORS 0
+COUNT_PROXY_USER_ACL_ERRORS 0
+COUNT_AUTHENTICATION_ERRORS 0
+COUNT_SSL_ERRORS 0
+COUNT_MAX_USER_CONNECTIONS_ERRORS 0
+COUNT_MAX_USER_CONNECTIONS_PER_HOUR_ERRORS 0
+COUNT_DEFAULT_DATABASE_ERRORS 0
+COUNT_INIT_CONNECT_ERRORS 0
+COUNT_LOCAL_ERRORS 0
+COUNT_UNKNOWN_ERRORS 0
+FIRST_ERROR_SEEN set
+LAST_ERROR_SEEN set
+connect(127.0.0.1,plug2,bar,test,PORT,SOCKET);
+connect con1, 127.0.0.1, plug2,bar,,$MASTER_MYPORT;
+ERROR 28000: Access denied for user 'plug2'@'santa.claus.ipv4.example.com' (using password: YES)
+# Dumping performance_schema.host_cache
+IP 192.0.2.4
+HOST santa.claus.ipv4.example.com
+HOST_VALIDATED YES
+SUM_CONNECT_ERRORS 1
+COUNT_HOST_BLOCKED_ERRORS 0
+COUNT_NAMEINFO_TRANSIENT_ERRORS 0
+COUNT_NAMEINFO_PERMANENT_ERRORS 0
+COUNT_FORMAT_ERRORS 0
+COUNT_ADDRINFO_TRANSIENT_ERRORS 0
+COUNT_ADDRINFO_PERMANENT_ERRORS 0
+COUNT_FCRDNS_ERRORS 0
+COUNT_HOST_ACL_ERRORS 0
+COUNT_NO_AUTH_PLUGIN_ERRORS 0
+COUNT_AUTH_PLUGIN_ERRORS 0
+COUNT_HANDSHAKE_ERRORS 1
+COUNT_PROXY_USER_ERRORS 0
+COUNT_PROXY_USER_ACL_ERRORS 0
+COUNT_AUTHENTICATION_ERRORS 1
+COUNT_SSL_ERRORS 0
+COUNT_MAX_USER_CONNECTIONS_ERRORS 0
+COUNT_MAX_USER_CONNECTIONS_PER_HOUR_ERRORS 0
+COUNT_DEFAULT_DATABASE_ERRORS 0
+COUNT_INIT_CONNECT_ERRORS 0
+COUNT_LOCAL_ERRORS 0
+COUNT_UNKNOWN_ERRORS 0
+FIRST_ERROR_SEEN set
+LAST_ERROR_SEEN set
+connect con1, 127.0.0.1, plug2,foo,,$MASTER_MYPORT;
+select current_user();
+current_user()
+plug2@santa.claus.ipv4.example.com
+disconnect con1;
+connection default;
+# Dumping performance_schema.host_cache
+IP 192.0.2.4
+HOST santa.claus.ipv4.example.com
+HOST_VALIDATED YES
+SUM_CONNECT_ERRORS 0
+COUNT_HOST_BLOCKED_ERRORS 0
+COUNT_NAMEINFO_TRANSIENT_ERRORS 0
+COUNT_NAMEINFO_PERMANENT_ERRORS 0
+COUNT_FORMAT_ERRORS 0
+COUNT_ADDRINFO_TRANSIENT_ERRORS 0
+COUNT_ADDRINFO_PERMANENT_ERRORS 0
+COUNT_FCRDNS_ERRORS 0
+COUNT_HOST_ACL_ERRORS 0
+COUNT_NO_AUTH_PLUGIN_ERRORS 0
+COUNT_AUTH_PLUGIN_ERRORS 0
+COUNT_HANDSHAKE_ERRORS 1
+COUNT_PROXY_USER_ERRORS 0
+COUNT_PROXY_USER_ACL_ERRORS 0
+COUNT_AUTHENTICATION_ERRORS 1
+COUNT_SSL_ERRORS 0
+COUNT_MAX_USER_CONNECTIONS_ERRORS 0
+COUNT_MAX_USER_CONNECTIONS_PER_HOUR_ERRORS 0
+COUNT_DEFAULT_DATABASE_ERRORS 0
+COUNT_INIT_CONNECT_ERRORS 0
+COUNT_LOCAL_ERRORS 0
+COUNT_UNKNOWN_ERRORS 0
+FIRST_ERROR_SEEN set
+LAST_ERROR_SEEN set
+drop user plug1@'santa.claus.ipv4.example.com';
+drop user plug2@'santa.claus.ipv4.example.com';
+set @@global.debug_dbug = @saved_dbug;
+uninstall plugin ed25519;
diff --git a/mysql-test/suite/perfschema/t/hostcache_ipv4_auth_ed25519.test b/mysql-test/suite/perfschema/t/hostcache_ipv4_auth_ed25519.test
new file mode 100644
index 00000000000..4c68d3af51e
--- /dev/null
+++ b/mysql-test/suite/perfschema/t/hostcache_ipv4_auth_ed25519.test
@@ -0,0 +1,56 @@
+#
+# Tests for the performance_schema host_cache.
+#
+# Test authorization with auth plugins.
+# error reporting in:
+# - column COUNT_AUTH_PLUGIN_ERRORS
+# - column COUNT_PROXY_USER_ERRORS
+# - column COUNT_PROXY_USER_ACL_ERRORS
+
+source include/not_embedded.inc;
+source include/have_debug.inc;
+source include/have_perfschema.inc;
+source include/have_plugin_auth.inc;
+source include/have_hostname_cache.inc;
+
+if (!$AUTH_ED25519_SO) {
+ skip No auth_ed25519 plugin;
+}
+install soname 'auth_ed25519';
+
+# Enforce a clean state
+source ../include/wait_for_pfs_thread_count.inc;
+source ../include/hostcache_set_state.inc;
+
+create user plug1@'santa.claus.ipv4.example.com'
+ identified with ed25519;
+update mysql.global_priv set priv=json_set(priv, '$.authentication_string', 'foo') where user='plug1';
+flush privileges;
+
+create user plug2@'santa.claus.ipv4.example.com'
+ identified with ED25519 as 'vubFBzIrapbfHct1/J72dnUryz5VS7lA6XHH8sIx4TI';
+
+set @saved_dbug = @@global.debug_dbug;
+set global debug_dbug= "+d,vio_peer_addr_fake_ipv4,getnameinfo_fake_ipv4,getaddrinfo_fake_good_ipv4";
+
+replace_result $MASTER_MYPORT PORT $MASTER_MYSOCK SOCKET;
+error ER_ACCESS_DENIED_ERROR;
+connect con1, 127.0.0.1, plug1,foo,,$MASTER_MYPORT;
+source ../include/hostcache_dump.inc;
+
+replace_result $MASTER_MYPORT PORT $MASTER_MYSOCK SOCKET;
+error ER_ACCESS_DENIED_ERROR;
+connect con1, 127.0.0.1, plug2,bar,,$MASTER_MYPORT;
+source ../include/hostcache_dump.inc;
+
+connect con1, 127.0.0.1, plug2,foo,,$MASTER_MYPORT;
+select current_user();
+disconnect con1;
+connection default;
+source ../include/hostcache_dump.inc;
+
+drop user plug1@'santa.claus.ipv4.example.com';
+drop user plug2@'santa.claus.ipv4.example.com';
+
+set @@global.debug_dbug = @saved_dbug;
+uninstall plugin ed25519;
diff --git a/mysys/crc32/crc32c.cc b/mysys/crc32/crc32c.cc
index 082d467e7da..b48e744a663 100644
--- a/mysys/crc32/crc32c.cc
+++ b/mysys/crc32/crc32c.cc
@@ -517,12 +517,12 @@ static int arch_ppc_probe(void) {
return arch_ppc_crc32;
}
-#elif _AIX
+#elif defined(_AIX) || defined(__OpenBSD__)
static int arch_ppc_probe(void) {
arch_ppc_crc32 = 0;
#if defined(__powerpc64__)
- // AIX 7.1+ has vector crypto features on all POWER 8+
+ // AIX 7.1+/OpenBSD has vector crypto features on all POWER 8+
arch_ppc_crc32 = 1;
#endif /* __powerpc64__ */
diff --git a/mysys/my_largepage.c b/mysys/my_largepage.c
index c3fc97ffe0a..0fdc4e17a26 100644
--- a/mysys/my_largepage.c
+++ b/mysys/my_largepage.c
@@ -336,8 +336,10 @@ uchar *my_large_malloc(size_t *size, myf my_flags)
# warning "No explicit large page (HUGETLB pages) support in Linux < 3.8"
#endif
#elif defined(MAP_ALIGNED)
- mapflag|= MAP_ALIGNED_SUPER |
- MAP_ALIGNED(my_bit_log2_size_t(large_page_size));
+ mapflag|= MAP_ALIGNED(my_bit_log2_size_t(large_page_size));
+#if defined(MAP_ALIGNED_SUPER)
+ mapflag|= MAP_ALIGNED_SUPER;
+#endif
#endif
aligned_size= MY_ALIGN(*size, (size_t) large_page_size);
}
diff --git a/plugin/auth_ed25519/server_ed25519.c b/plugin/auth_ed25519/server_ed25519.c
index 6fec98c56fc..b789bd34ca4 100644
--- a/plugin/auth_ed25519/server_ed25519.c
+++ b/plugin/auth_ed25519/server_ed25519.c
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2017, MariaDB
+ Copyright (c) 2017, 2021, MariaDB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -42,7 +42,7 @@ static int auth(MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *info)
/* prepare random nonce */
if (my_random_bytes((unsigned char *)nonce, (int)sizeof(nonce)))
- return CR_AUTH_USER_CREDENTIALS;
+ return CR_ERROR; // eh? OpenSSL error
/* send it */
if (vio->write_packet(vio, reply + CRYPTO_BYTES, NONCE_BYTES))
@@ -55,7 +55,7 @@ static int auth(MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *info)
if (crypto_sign_open(reply, CRYPTO_BYTES + NONCE_BYTES,
(unsigned char*)info->auth_string))
- return CR_ERROR;
+ return CR_AUTH_USER_CREDENTIALS; // wrong password provided by the user
return CR_OK;
}
diff --git a/scripts/wsrep_sst_common.sh b/scripts/wsrep_sst_common.sh
index f4ac2e9936d..952a37f75d2 100644
--- a/scripts/wsrep_sst_common.sh
+++ b/scripts/wsrep_sst_common.sh
@@ -875,7 +875,9 @@ get_openssl()
readonly OPENSSL_BINARY
}
+#
# Generate a string equivalent to 16 random bytes
+#
wsrep_gen_secret()
{
get_openssl
@@ -889,16 +891,36 @@ wsrep_gen_secret()
fi
}
+#
+# Checking if the address passed to us is local.
+# If the second parameter is nonzero, then this function
+# does not check for matches with local domain names:
+#
is_local_ip()
{
- [ "$1" = '127.0.0.1' ] && return 0
- [ "$1" = '127.0.0.2' ] && return 0
- [ "$1" = 'localhost' ] && return 0
- [ "$1" = '[::1]' ] && return 0
- [ "$1" = "$(hostname -s)" ] && return 0
- [ "$1" = "$(hostname -f)" ] && return 0
- [ "$1" = "$(hostname -d)" ] && return 0
-
+ # Rapid recognition of the most common cases:
+ [ "$1" = '127.0.0.1' -o \
+ "$1" = '127.0.0.2' -o \
+ "$1" = 'localhost' -o \
+ "$1" = '[::1]' ] && return 0
+ # If the address starts with "127." this is probably a local
+ # address, but we need to clarify what follows this prefix:
+ if [ "${1#127.}" != "$1" ]; then
+ # All 127.0.0.0/8 addresses are local:
+ if echo "$1" | grep -q -E '^127\.[0-9]+\.[0-9]+\.[0-9]+$'; then
+ return 0
+ fi
+ fi
+ # If the second parameter is nonzero, then we will skip
+ # the domain name check:
+ if [ "${2:-0}" -eq 0 ]; then
+ # We consider all the names of a given host to be local addresses:
+ [ "$1" = "$(hostname -s)" -o \
+ "$1" = "$(hostname -f)" -o \
+ "$1" = "$(hostname -d)" ] && return 0
+ fi
+ # Now let's check if the given address is assigned to
+ # one of the network cards:
local ip_util="$(command -v ip)"
if [ -n "$ip_util" ]; then
# ip address show ouput format is " inet[6] <address>/<mask>":
@@ -914,7 +936,6 @@ is_local_ip()
| grep -F " $1 " >/dev/null && return 0
fi
fi
-
return 1
}
diff --git a/sql/item.cc b/sql/item.cc
index b98270022cc..12cbc8f79b6 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -5941,6 +5941,7 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
*/
set_max_sum_func_level(thd, select);
set_field(new_field);
+ depended_from= (*((Item_field**)res))->depended_from;
return 0;
}
else
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index 0cdd9a5fc5c..a87b4687915 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -1870,7 +1870,6 @@ double Item_in_subselect::val_real()
As far as Item_in_subselect called only from Item_in_optimizer this
method should not be used
*/
- DBUG_ASSERT(0);
DBUG_ASSERT(fixed());
if (forced_const)
return value;
@@ -2345,11 +2344,12 @@ Item_in_subselect::create_single_in_to_exists_cond(JOIN *join,
*/
Item *item= (Item*) select_lex->item_list.head();
- if (select_lex->table_list.elements)
+ if (select_lex->table_list.elements ||
+ !(select_lex->master_unit()->is_unit_op()))
{
Item *having= item;
Item *orig_item= item;
-
+
item= func->create(thd, expr, item);
if (!abort_on_null && orig_item->maybe_null())
{
@@ -2393,32 +2393,29 @@ Item_in_subselect::create_single_in_to_exists_cond(JOIN *join,
}
else
{
- if (select_lex->master_unit()->is_unit_op())
- {
- LEX_CSTRING field_name= {STRING_WITH_LEN("<result>") };
- Item *new_having=
- func->create(thd, expr,
- new (thd->mem_root) Item_ref_null_helper(thd,
+ DBUG_ASSERT(select_lex->master_unit()->is_unit_op());
+ LEX_CSTRING field_name= {STRING_WITH_LEN("<result>") };
+ Item *new_having=
+ func->create(thd, expr,
+ new (thd->mem_root) Item_ref_null_helper(thd,
&select_lex->context,
this,
&select_lex->ref_pointer_array[0],
no_matter_name,
field_name));
- if (!abort_on_null && left_expr->maybe_null())
- {
- disable_cond_guard_for_const_null_left_expr(0);
- if (!(new_having= new (thd->mem_root) Item_func_trig_cond(thd, new_having,
- get_cond_guard(0))))
- DBUG_RETURN(true);
- }
-
- new_having->name= in_having_cond;
- if (fix_having(new_having, select_lex))
+ if (!abort_on_null && left_expr->maybe_null())
+ {
+ disable_cond_guard_for_const_null_left_expr(0);
+ if (!(new_having= new (thd->mem_root)
+ Item_func_trig_cond(thd, new_having, get_cond_guard(0))))
DBUG_RETURN(true);
- *having_item= new_having;
}
- else
- DBUG_ASSERT(false);
+
+ new_having->name= in_having_cond;
+ if (fix_having(new_having, select_lex))
+ DBUG_RETURN(true);
+
+ *having_item= new_having;
}
}
diff --git a/sql/lock.cc b/sql/lock.cc
index d62a8d49979..f6cdd40fa0b 100644
--- a/sql/lock.cc
+++ b/sql/lock.cc
@@ -1124,21 +1124,22 @@ void Global_read_lock::unlock_global_read_lock(THD *thd)
thd->mdl_context.release_lock(m_mdl_global_read_lock);
#ifdef WITH_WSREP
- if (m_state == GRL_ACQUIRED_AND_BLOCKS_COMMIT)
+ if (m_state == GRL_ACQUIRED_AND_BLOCKS_COMMIT &&
+ wsrep_locked_seqno != WSREP_SEQNO_UNDEFINED)
{
Wsrep_server_state& server_state= Wsrep_server_state::instance();
if (server_state.state() == Wsrep_server_state::s_donor ||
(WSREP_NNULL(thd) &&
server_state.state() != Wsrep_server_state::s_synced))
{
- /* TODO: maybe redundant here?: */
- wsrep_locked_seqno= WSREP_SEQNO_UNDEFINED;
server_state.resume();
+ wsrep_locked_seqno= WSREP_SEQNO_UNDEFINED;
}
else if (WSREP_NNULL(thd) &&
server_state.state() == Wsrep_server_state::s_synced)
{
server_state.resume_and_resync();
+ wsrep_locked_seqno= WSREP_SEQNO_UNDEFINED;
}
}
#endif /* WITH_WSREP */
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index d32c66891a9..6eba8e11d58 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -4977,7 +4977,7 @@ static int init_server_components()
}
#endif /* WITH_WSREP */
- if (opt_bin_log)
+ if (!opt_help && opt_bin_log)
{
if (mysql_bin_log.open_index_file(opt_binlog_index_name, opt_bin_logname,
TRUE))
diff --git a/sql/mysqld.h b/sql/mysqld.h
index ddfec106b60..768b81d59fc 100644
--- a/sql/mysqld.h
+++ b/sql/mysqld.h
@@ -711,7 +711,7 @@ extern struct st_VioSSLFd * ssl_acceptor_fd;
*/
extern my_bool opt_large_pages;
extern uint opt_large_page_size;
-extern char lc_messages_dir[FN_REFLEN];
+extern MYSQL_PLUGIN_IMPORT char lc_messages_dir[FN_REFLEN];
extern char *lc_messages_dir_ptr, *log_error_file_ptr;
extern MYSQL_PLUGIN_IMPORT char reg_ext[FN_EXTLEN];
extern MYSQL_PLUGIN_IMPORT uint reg_ext_length;
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 0812d61ced8..d1cf5c2d9bd 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -3492,8 +3492,7 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp,
Json_writer_object trace_command(thd);
Json_writer_array trace_command_steps(thd, "steps");
if (open_tables)
- res= check_dependencies_in_with_clauses(m_lex->with_clauses_list) ||
- instr->exec_open_and_lock_tables(thd, m_lex->query_tables);
+ res= instr->exec_open_and_lock_tables(thd, m_lex->query_tables);
if (likely(!res))
{
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index 3a4c83e3139..605723a3b96 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -13909,7 +13909,12 @@ static int server_mpvio_read_packet(MYSQL_PLUGIN_VIO *param, uchar **buf)
done:
if (set_user_salt_if_needed(mpvio->acl_user, mpvio->curr_auth, mpvio->plugin))
+ {
+ ai->thd->clear_error(); // authenticating user should not see these errors
+ my_error(ER_ACCESS_DENIED_ERROR, MYF(0), ai->thd->security_ctx->user,
+ ai->thd->security_ctx->host_or_ip, ER_THD(ai->thd, ER_YES));
goto err;
+ }
ai->user_name= ai->thd->security_ctx->user;
ai->user_name_length= (uint) strlen(ai->user_name);
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 9c07e3de272..5982d8a92e1 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -3591,7 +3591,11 @@ open_and_process_table(THD *thd, TABLE_LIST *tables, uint *counter, uint flags,
if (tables->derived)
{
if (!tables->view)
+ {
+ if (!tables->is_derived())
+ tables->set_derived();
goto end;
+ }
/*
We restore view's name and database wiped out by derived tables
processing and fall back to standard open process in order to
@@ -3601,35 +3605,6 @@ open_and_process_table(THD *thd, TABLE_LIST *tables, uint *counter, uint flags,
tables->db= tables->view_db;
tables->table_name= tables->view_name;
}
- else if (tables->select_lex)
- {
- /*
- Check whether 'tables' refers to a table defined in a with clause.
- If so set the reference to the definition in tables->with.
- */
- if (!tables->with)
- tables->with= tables->select_lex->find_table_def_in_with_clauses(tables);
- /*
- If 'tables' is defined in a with clause set the pointer to the
- specification from its definition in tables->derived.
- */
- if (tables->with)
- {
- if (tables->is_recursive_with_table() &&
- !tables->is_with_table_recursive_reference())
- {
- tables->with->rec_outer_references++;
- With_element *with_elem= tables->with;
- while ((with_elem= with_elem->get_next_mutually_recursive()) !=
- tables->with)
- with_elem->rec_outer_references++;
- }
- if (tables->set_as_with_table(thd, tables->with))
- DBUG_RETURN(1);
- else
- goto end;
- }
- }
if (!tables->derived && is_infoschema_db(&tables->db))
{
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 7d4467c78ca..7c2014fe4b0 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -2804,6 +2804,62 @@ void THD::close_active_vio()
#endif
+/*
+ @brief MySQL parser used for recursive invocations
+
+ @param old_lex The LEX structure in the state when this parser
+ is called recursively
+ @param lex The LEX structure used to parse a new SQL fragment
+ @param str The SQL fragment to parse
+ @param str_len The length of the SQL fragment to parse
+ @param stmt_prepare_mode true <=> when parsing a prepare statement
+
+ @details
+ This function is to be used when parsing of an SQL fragment is
+ needed within one of the grammar rules.
+
+ @notes
+ Currently the function is used only when the specification of a CTE
+ is parsed for the not first and not recursive references of the CTE.
+
+ @retval false On a successful parsing of the fragment
+ @retval true Otherwise
+*/
+
+bool THD::sql_parser(LEX *old_lex, LEX *lex,
+ char *str, uint str_len, bool stmt_prepare_mode)
+{
+ extern int MYSQLparse(THD * thd);
+ extern int ORAparse(THD * thd);
+
+ bool parse_status= false;
+ Parser_state parser_state;
+ Parser_state *old_parser_state= m_parser_state;
+
+ if (parser_state.init(this, str, str_len))
+ return true;
+
+ m_parser_state= &parser_state;
+ parser_state.m_lip.stmt_prepare_mode= stmt_prepare_mode;
+ parser_state.m_lip.multi_statements= false;
+ parser_state.m_lip.m_digest= NULL;
+
+ lex->param_list= old_lex->param_list;
+ lex->sphead= old_lex->sphead;
+ lex->spname= old_lex->spname;
+ lex->spcont= old_lex->spcont;
+ lex->sp_chistics= old_lex->sp_chistics;
+ lex->trg_chistics= old_lex->trg_chistics;
+
+ parse_status= (variables.sql_mode & MODE_ORACLE) ?
+ ORAparse(this) : MYSQLparse(this) != 0;
+
+ m_parser_state= old_parser_state;
+
+ return parse_status;
+}
+
+
struct Item_change_record: public ilink
{
Item **place;
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 2fa50882ebf..3f748c6a206 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -1081,7 +1081,7 @@ mysqld_collation_get_by_name(const char *name, myf utf8_flag,
static inline bool is_supported_parser_charset(CHARSET_INFO *cs)
{
- return MY_TEST(cs->mbminlen == 1);
+ return MY_TEST(cs->mbminlen == 1 && cs->number != 17 /* filename */);
}
/** THD registry */
@@ -4637,14 +4637,11 @@ public:
to resolve all CTE names as we don't need this message to be thrown
for any CTE references.
*/
- if (!lex->with_clauses_list)
+ if (!lex->with_cte_resolution)
{
my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
return TRUE;
}
- /* This will allow to throw an error later for non-CTE references */
- to->str= NULL;
- to->length= 0;
return FALSE;
}
@@ -5398,7 +5395,6 @@ public:
THD_TRANS::EXECUTED_TABLE_ADMIN_CMD));
}
-
uint get_net_wait_timeout()
{
if (in_active_multi_stmt_transaction())
@@ -5449,7 +5445,10 @@ public:
Item *sp_prepare_func_item(Item **it_addr, uint cols= 1);
bool sp_eval_expr(Field *result_field, Item **expr_item_ptr);
- myf get_utf8_flag()
+ bool sql_parser(LEX *old_lex, LEX *lex,
+ char *str, uint str_len, bool stmt_prepare_mode);
+
+ myf get_utf8_flag() const
{
return (variables.old_behavior & OLD_MODE_UTF8_IS_UTF8MB3 ?
MY_UTF8_IS_UTF8MB3 : 0);
diff --git a/sql/sql_cte.cc b/sql/sql_cte.cc
index ad4a37d0fbe..396b3f2c8a9 100644
--- a/sql/sql_cte.cc
+++ b/sql/sql_cte.cc
@@ -84,7 +84,7 @@ void st_select_lex_unit::set_with_clause(With_clause *with_cl)
true on failure
*/
-bool check_dependencies_in_with_clauses(With_clause *with_clauses_list)
+bool LEX::check_dependencies_in_with_clauses()
{
for (With_clause *with_clause= with_clauses_list;
with_clause;
@@ -102,6 +102,201 @@ bool check_dependencies_in_with_clauses(With_clause *with_clauses_list)
/**
@brief
+ Resolve references to CTE in specification of hanging CTE
+
+ @details
+ A CTE to which there are no references in the query is called hanging CTE.
+ Although such CTE is not used for execution its specification must be
+ subject to context analysis. All errors concerning references to
+ non-existing tables or fields occurred in the specification must be
+ reported as well as all other errors caught at the prepare stage.
+ The specification of a hanging CTE might contain references to other
+ CTE outside of the specification and within it if the specification
+ contains a with clause. This function resolves all such references for
+ all hanging CTEs encountered in the processed query.
+
+ @retval
+ false on success
+ true on failure
+*/
+
+bool
+LEX::resolve_references_to_cte_in_hanging_cte()
+{
+ for (With_clause *with_clause= with_clauses_list;
+ with_clause; with_clause= with_clause->next_with_clause)
+ {
+ for (With_element *with_elem= with_clause->with_list.first;
+ with_elem; with_elem= with_elem->next)
+ {
+ if (!with_elem->is_referenced())
+ {
+ TABLE_LIST *first_tbl=
+ with_elem->spec->first_select()->table_list.first;
+ TABLE_LIST **with_elem_end_pos= with_elem->head->tables_pos.end_pos;
+ if (first_tbl && resolve_references_to_cte(first_tbl, with_elem_end_pos))
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+
+/**
+ @brief
+ Resolve table references to CTE from a sub-chain of table references
+
+ @param tables Points to the beginning of the sub-chain
+ @param tables_last Points to the address with the sub-chain barrier
+
+ @details
+ The method resolves tables references to CTE from the chain of
+ table references specified by the parameters 'tables' and 'tables_last'.
+ It resolves the references against the CTE definition occurred in a query
+ or the specification of a CTE whose parsing tree is represented by
+ this LEX structure. The method is always called right after the process
+ of parsing the query or of the specification of a CTE has been finished,
+ thus the chain of table references used in the parsed fragment has been
+ already built. It is assumed that parameters of the method specify a
+ a sub-chain of this chain.
+ If a table reference can be potentially a table reference to a CTE and it
+ has not been resolved yet then the method tries to find the definition
+ of the CTE against which the reference can be resolved. If it succeeds
+ it sets the field TABLE_LIST::with to point to the found definition.
+ It also sets the field TABLE_LIST::derived to point to the specification
+ of the found CTE and sets TABLE::db.str to empty_c_string. This will
+ allow to handle this table reference like a reference to a derived handle.
+ If another table reference has been already resolved against this CTE
+ and this CTE is not recursive then a clone of the CTE specification is
+ constructed using the function With_element::clone_parsed_spec() and
+ TABLE_LIST::derived is set to point to this clone rather than to the
+ original specification.
+ If the method does not find a matched CTE definition in the parsed fragment
+ then in the case when the flag this->only_cte_resolution is set to true
+ it just moves to the resolution of the next table reference from the
+ specified sub-chain while in the case when this->only_cte_resolution is set
+ to false the method additionally sets an mdl request for this table
+ reference.
+
+ @notes
+ The flag this->only_cte_resolution is set to true in the cases when
+ the failure to resolve a table reference as a CTE reference within
+ the fragment associated with this LEX structure does not imply that
+ this table reference cannot be resolved as such at all.
+
+ @retval false On success: no errors reported, no memory allocations failed
+ @retval true Otherwise
+*/
+
+bool LEX::resolve_references_to_cte(TABLE_LIST *tables,
+ TABLE_LIST **tables_last)
+{
+ With_element *with_elem= 0;
+
+ for (TABLE_LIST *tbl= tables; tbl != *tables_last; tbl= tbl->next_global)
+ {
+ if (tbl->derived)
+ continue;
+ if (!tbl->db.str && !tbl->with)
+ tbl->with= tbl->select_lex->find_table_def_in_with_clauses(tbl);
+ if (!tbl->with) // no CTE matches table reference tbl
+ {
+ if (only_cte_resolution)
+ continue;
+ if (!tbl->db.str) // no database specified in table reference tbl
+ {
+ if (!thd->db.str) // no default database is set
+ {
+ my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
+ return true;
+ }
+ if (copy_db_to(&tbl->db))
+ return true;
+ if (!(tbl->table_options & TL_OPTION_ALIAS))
+ MDL_REQUEST_INIT(&tbl->mdl_request, MDL_key::TABLE,
+ tbl->db.str, tbl->table_name.str,
+ tbl->mdl_type, MDL_TRANSACTION);
+ tbl->mdl_request.set_type((tbl->lock_type >= TL_WRITE_ALLOW_WRITE) ?
+ MDL_SHARED_WRITE : MDL_SHARED_READ);
+ }
+ continue;
+ }
+ with_elem= tbl->with;
+ if (tbl->is_recursive_with_table() &&
+ !tbl->is_with_table_recursive_reference())
+ {
+ tbl->with->rec_outer_references++;
+ while ((with_elem= with_elem->get_next_mutually_recursive()) !=
+ tbl->with)
+ with_elem->rec_outer_references++;
+ }
+ if (!with_elem->is_used_in_query || with_elem->is_recursive)
+ {
+ tbl->derived= with_elem->spec;
+ if (tbl->derived != tbl->select_lex->master_unit() &&
+ !with_elem->is_recursive &&
+ !tbl->is_with_table_recursive_reference())
+ {
+ tbl->derived->move_as_slave(tbl->select_lex);
+ }
+ with_elem->is_used_in_query= true;
+ }
+ else
+ {
+ if (!(tbl->derived= tbl->with->clone_parsed_spec(thd->lex, tbl)))
+ return true;
+ }
+ tbl->db.str= empty_c_string;
+ tbl->db.length= 0;
+ tbl->schema_table= 0;
+ if (tbl->derived)
+ {
+ tbl->derived->first_select()->set_linkage(DERIVED_TABLE_TYPE);
+ tbl->select_lex->add_statistics(tbl->derived);
+ }
+ if (tbl->with->is_recursive && tbl->is_with_table_recursive_reference())
+ continue;
+ with_elem->inc_references();
+ }
+ return false;
+}
+
+
+/**
+ @brief
+ Find out dependencies between CTEs, resolve references to them
+
+ @details
+ The function can be called in two modes. With this->with_cte_resolution
+ set to false the function only finds out all dependencies between CTEs
+ used in a query expression with a WITH clause whose parsing has been
+ just finished. Based on these dependencies recursive CTEs are detected.
+ If this->with_cte_resolution is set to true the function additionally
+ resolves all references to CTE occurred in this query expression.
+
+ @retval
+ true on failure
+ false on success
+*/
+
+bool
+LEX::check_cte_dependencies_and_resolve_references()
+{
+ if (check_dependencies_in_with_clauses())
+ return true;
+ if (!with_cte_resolution)
+ return false;
+ if (resolve_references_to_cte(query_tables, query_tables_last))
+ return true;
+ if (resolve_references_to_cte_in_hanging_cte())
+ return true;
+ return false;
+}
+
+
+/**
+ @brief
Check dependencies between tables defined in this with clause
@details
@@ -138,10 +333,11 @@ bool With_clause::check_dependencies()
elem != with_elem;
elem= elem->next)
{
- if (lex_string_cmp(system_charset_info, with_elem->query_name,
- elem->query_name) == 0)
+ if (lex_string_cmp(system_charset_info, with_elem->get_name(),
+ elem->get_name()) == 0)
{
- my_error(ER_DUP_QUERY_NAME, MYF(0), with_elem->query_name->str);
+ my_error(ER_DUP_QUERY_NAME, MYF(0),
+ with_elem->get_name_str());
return true;
}
}
@@ -248,13 +444,12 @@ With_element *With_clause::find_table_def(TABLE_LIST *table,
with_elem != barrier;
with_elem= with_elem->next)
{
- if (my_strcasecmp(system_charset_info, with_elem->query_name->str,
- table->table_name.str) == 0 &&
+ if (my_strcasecmp(system_charset_info, with_elem->get_name_str(),
+ table->table_name.str) == 0 &&
!table->is_fqtn)
{
table->set_derived();
- table->db.str= empty_c_string;
- table->db.length= 0;
+ with_elem->referenced= true;
return with_elem;
}
}
@@ -611,7 +806,7 @@ bool With_clause::check_anchors()
if (elem == with_elem)
{
my_error(ER_RECURSIVE_WITHOUT_ANCHORS, MYF(0),
- with_elem->query_name->str);
+ with_elem->get_name_str());
return true;
}
}
@@ -644,7 +839,7 @@ bool With_clause::check_anchors()
if (elem->work_dep_map & elem->get_elem_map())
{
my_error(ER_UNACCEPTABLE_MUTUAL_RECURSION, MYF(0),
- with_elem->query_name->str);
+ with_elem->get_name_str());
return true;
}
}
@@ -798,7 +993,8 @@ bool With_element::set_unparsed_spec(THD *thd,
@brief
Create a clone of the specification for the given with table
- @param thd The context of the statement containing this with element
+ @param old_lex The LEX structure created for the query or CTE specification
+ where this With_element is defined
@param with_table The reference to the table defined in this element for which
the clone is created.
@@ -808,12 +1004,13 @@ bool With_element::set_unparsed_spec(THD *thd,
this element.
The clone is created when the string with the specification saved in
unparsed_spec is fed into the parser as an input string. The parsing
- this string a unit object representing the specification is build.
+ this string a unit object representing the specification is built.
A chain of all table references occurred in the specification is also
formed.
The method includes the new unit and its sub-unit into hierarchy of
the units of the main query. I also insert the constructed chain of the
table references into the chain of all table references of the main query.
+ The method resolves all references to CTE in the clone.
@note
Clones is created only for not first references to tables defined in
@@ -829,116 +1026,128 @@ bool With_element::set_unparsed_spec(THD *thd,
NULL - otherwise
*/
-st_select_lex_unit *With_element::clone_parsed_spec(THD *thd,
+st_select_lex_unit *With_element::clone_parsed_spec(LEX *old_lex,
TABLE_LIST *with_table)
{
+ THD *thd= old_lex->thd;
LEX *lex;
- st_select_lex_unit *res= NULL;
- Query_arena backup;
- Query_arena *arena= thd->activate_stmt_arena_if_needed(&backup);
- bool has_tmp_tables;
+ st_select_lex_unit *res= NULL;
if (!(lex= (LEX*) new(thd->mem_root) st_lex_local))
- {
- if (arena)
- thd->restore_active_arena(arena, &backup);
return res;
- }
- LEX *old_lex= thd->lex;
thd->lex= lex;
bool parse_status= false;
- Parser_state parser_state;
- TABLE_LIST *spec_tables;
- TABLE_LIST *spec_tables_tail;
st_select_lex *with_select;
char save_end= unparsed_spec.str[unparsed_spec.length];
((char*) &unparsed_spec.str[unparsed_spec.length])[0]= '\0';
- if (parser_state.init(thd, (char*) unparsed_spec.str, (unsigned int)unparsed_spec.length))
- goto err;
- parser_state.m_lip.stmt_prepare_mode= stmt_prepare_mode;
- parser_state.m_lip.multi_statements= false;
- parser_state.m_lip.m_digest= NULL;
lex_start(thd);
lex->clone_spec_offset= unparsed_spec_offset;
- lex->param_list= old_lex->param_list;
- lex->sphead= old_lex->sphead;
- lex->spname= old_lex->spname;
- lex->spcont= old_lex->spcont;
- lex->sp_chistics= old_lex->sp_chistics;
-
- lex->stmt_lex= old_lex;
- parse_status= parse_sql(thd, &parser_state, 0);
+ lex->with_cte_resolution= true;
+
+ /*
+ The specification of a CTE is to be parsed as a regular query.
+ At the very end of the parsing query the function
+ check_cte_dependencies_and_resolve_references() will be called.
+ It will check the dependencies between CTEs that are defined
+ within the query and will resolve CTE references in this query.
+ If a table reference is not resolved as a CTE reference within
+ this query it still can be resolved as a reference to a CTE defined
+ in the same clause as the CTE whose specification is to be parsed
+ or defined in an embedding CTE definition.
+
+ Example:
+ with
+ cte1 as ( ... ),
+ cte2 as ([WITH ...] select ... from cte1 ...)
+ select ... from cte2 as r, ..., cte2 as s ...
+
+ Here the specification of cte2 has be cloned for table reference
+ with alias s1. The specification contains a reference to cte1
+ that is defined outside this specification. If the reference to
+ cte1 cannot be resolved within the specification of cte2 it's
+ not necessarily has to be a reference to a non-CTE table. That's
+ why the flag lex->only_cte_resolution has to be set to true
+ before parsing of the specification of cte2 invoked by this
+ function starts. Otherwise an mdl_lock would be requested for s
+ and this would not be correct.
+ */
+
+ lex->only_cte_resolution= true;
+
+ lex->stmt_lex= old_lex->stmt_lex ? old_lex->stmt_lex : old_lex;
+
+ parse_status= thd->sql_parser(old_lex, lex,
+ (char*) unparsed_spec.str,
+ (unsigned int)unparsed_spec.length,
+ stmt_prepare_mode);
+
((char*) &unparsed_spec.str[unparsed_spec.length])[0]= save_end;
- with_select= lex->first_select_lex();
+ with_select= lex->unit.first_select();
if (parse_status)
goto err;
- if (check_dependencies_in_with_clauses(lex->with_clauses_list))
- goto err;
-
- spec_tables= lex->query_tables;
- spec_tables_tail= 0;
- has_tmp_tables= thd->has_temporary_tables();
- for (TABLE_LIST *tbl= spec_tables;
- tbl;
- tbl= tbl->next_global)
- {
- if (has_tmp_tables && !tbl->derived && !tbl->schema_table &&
- thd->open_temporary_table(tbl))
- goto err;
- spec_tables_tail= tbl;
- }
- if (spec_tables)
+ /*
+ The global chain of TABLE_LIST objects created for the specification that
+ just has been parsed is added to such chain that contains the reference
+ to the CTE whose specification is parsed right after the TABLE_LIST object
+ created for the reference.
+ */
+ if (lex->query_tables)
{
- if (with_table->next_global)
+ head->tables_pos.set_start_pos(&with_table->next_global);
+ head->tables_pos.set_end_pos(lex->query_tables_last);
+ TABLE_LIST *next_tbl= with_table->next_global;
+ if (next_tbl)
{
- spec_tables_tail->next_global= with_table->next_global;
- with_table->next_global->prev_global= &spec_tables_tail->next_global;
+ *(lex->query_tables->prev_global= next_tbl->prev_global)=
+ lex->query_tables;
+ *(next_tbl->prev_global= lex->query_tables_last)= next_tbl;
}
else
{
- old_lex->query_tables_last= &spec_tables_tail->next_global;
+ *(lex->query_tables->prev_global= old_lex->query_tables_last)=
+ lex->query_tables;
+ old_lex->query_tables_last= lex->query_tables_last;
}
- spec_tables->prev_global= &with_table->next_global;
- with_table->next_global= spec_tables;
}
res= &lex->unit;
res->with_element= this;
+ /*
+ The unit of the specification that just has been parsed is included
+ as a slave of the select that contained in its from list the table
+ reference for which the unit has been created.
+ */
lex->unit.include_down(with_table->select_lex);
- lex->unit.set_slave(with_select);
+ lex->unit.set_slave(with_select);
+ lex->unit.cloned_from= spec;
old_lex->all_selects_list=
(st_select_lex*) (lex->all_selects_list->
insert_chain_before(
(st_select_lex_node **) &(old_lex->all_selects_list),
with_select));
- if (check_dependencies_in_with_clauses(lex->with_clauses_list))
- res= NULL;
+
/*
- Resolve references to CTE from the spec_tables list that has not
- been resolved yet.
+ Now all references to the CTE defined outside of the cloned specification
+ has to be resolved. Additionally if old_lex->only_cte_resolution == false
+ for the table references that has not been resolved requests for mdl_locks
+ has to be set.
*/
- for (TABLE_LIST *tbl= spec_tables;
- tbl;
- tbl= tbl->next_global)
+ lex->only_cte_resolution= old_lex->only_cte_resolution;
+ if (lex->resolve_references_to_cte(lex->query_tables,
+ lex->query_tables_last))
{
- if (!tbl->with)
- tbl->with= with_select->find_table_def_in_with_clauses(tbl);
- if (tbl == spec_tables_tail)
- break;
- }
- if (check_table_access(thd, SELECT_ACL, spec_tables, FALSE, UINT_MAX, FALSE))
+ res= NULL;
goto err;
+ }
- lex->sphead= NULL; // in order not to delete lex->sphead
+ lex->sphead= NULL; // in order not to delete lex->sphead
lex_end(lex);
err:
- if (arena)
- thd->restore_active_arena(arena, &backup);
thd->lex= old_lex;
return res;
}
@@ -1145,59 +1354,6 @@ With_element *st_select_lex::find_table_def_in_with_clauses(TABLE_LIST *table)
}
-/**
- @brief
- Set the specifying unit in this reference to a with table
-
- @details
- The method assumes that the given element with_elem defines the table T
- this table reference refers to.
- If this is the first reference to T the method just sets its specification
- in the field 'derived' as the unit that yields T. Otherwise the method
- first creates a clone specification and sets rather this clone in this field.
-
- @retval
- false on success
- true on failure
-*/
-
-bool TABLE_LIST::set_as_with_table(THD *thd, With_element *with_elem)
-{
- if (table)
- {
- /*
- This table was prematurely identified as a temporary table.
- We correct it here, but it's not a nice solution in the case
- when the temporary table with this name is not used anywhere
- else in the query.
- */
- thd->mark_tmp_table_as_free_for_reuse(table);
- table= 0;
- }
- with= with_elem;
- schema_table= NULL;
- if (!with_elem->is_referenced() || with_elem->is_recursive)
- {
- derived= with_elem->spec;
- if (derived != select_lex->master_unit() &&
- !with_elem->is_recursive &&
- !is_with_table_recursive_reference())
- {
- derived->move_as_slave(select_lex);
- }
- }
- else
- {
- if(!(derived= with_elem->clone_parsed_spec(thd, this)))
- return true;
- }
- derived->first_select()->set_linkage(DERIVED_TABLE_TYPE);
- select_lex->add_statistics(derived);
- with_elem->inc_references();
- return false;
-}
-
-
bool TABLE_LIST::is_recursive_with_table()
{
return with && with->is_recursive;
@@ -1297,7 +1453,7 @@ bool st_select_lex::check_unrestricted_recursive(bool only_standard_compliant)
if (only_standard_compliant && with_elem->is_unrestricted())
{
my_error(ER_NOT_STANDARD_COMPLIANT_RECURSIVE,
- MYF(0), with_elem->query_name->str);
+ MYF(0), with_elem->get_name_str());
return true;
}
@@ -1514,7 +1670,7 @@ static void list_strlex_print(THD *thd, String *str, List<Lex_ident_sys> *list)
void With_element::print(THD *thd, String *str, enum_query_type query_type)
{
- str->append(query_name);
+ str->append(get_name());
if (column_list.elements)
{
List_iterator_fast<Lex_ident_sys> li(column_list);
diff --git a/sql/sql_cte.h b/sql/sql_cte.h
index 4c42dd23614..44628df3ff8 100644
--- a/sql/sql_cte.h
+++ b/sql/sql_cte.h
@@ -25,6 +25,39 @@ struct st_unit_ctxt_elem;
/**
+ @class With_element_head
+ @brief Head of the definition of a CTE table
+
+ It contains the name of the CTE and it contains the position of the subchain
+ of table references used in the definition in the global chain of table
+ references used in the query where this definition is encountered.
+*/
+
+class With_element_head : public Sql_alloc
+{
+ /* The name of the defined CTE */
+ LEX_CSTRING *query_name;
+
+public:
+ /*
+ The structure describing the subchain of the table references used in
+ the specification of the defined CTE in the global chain of table
+ references used in the query. The structure is fully defined only
+ after the CTE definition has been parsed.
+ */
+ TABLE_CHAIN tables_pos;
+
+ With_element_head(LEX_CSTRING *name)
+ : query_name(name)
+ {
+ tables_pos.set_start_pos(0);
+ tables_pos.set_end_pos(0);
+ }
+ friend class With_element;
+};
+
+
+/**
@class With_element
@brief Definition of a CTE table
@@ -85,9 +118,22 @@ private:
subqueries and specifications of other with elements).
*/
uint references;
+
+ /*
+ true <=> this With_element is referred in the query in which the
+ element is defined
+ */
+ bool referenced;
+
+ /*
+ true <=> this With_element is needed for the execution of the query
+ in which the element is defined
+ */
+ bool is_used_in_query;
+
/*
Unparsed specification of the query that specifies this element.
- It used to build clones of the specification if they are needed.
+ It's used to build clones of the specification if they are needed.
*/
LEX_CSTRING unparsed_spec;
/* Offset of the specification in the input string */
@@ -101,10 +147,12 @@ private:
public:
/*
- The name of the table introduced by this with elememt. The name
- can be used in FROM lists of the queries in the scope of the element.
+ Contains the name of the defined With element and the position of
+ the subchain of the tables references used by its definition in the
+ global chain of TABLE_LIST objects created for the whole query.
*/
- LEX_CSTRING *query_name;
+ With_element_head *head;
+
/*
Optional list of column names to name the columns of the table introduced
by this with element. It is used in the case when the names are not
@@ -163,18 +211,27 @@ public:
/* List of derived tables containing recursive references to this CTE */
SQL_I_List<TABLE_LIST> derived_with_rec_ref;
- With_element(LEX_CSTRING *name,
+ With_element(With_element_head *h,
List <Lex_ident_sys> list,
st_select_lex_unit *unit)
: next(NULL), base_dep_map(0), derived_dep_map(0),
sq_dep_map(0), work_dep_map(0), mutually_recursive(0),
top_level_dep_map(0), sq_rec_ref(NULL),
next_mutually_recursive(NULL), references(0),
- query_name(name), column_list(list), cycle_list(0), spec(unit),
+ referenced(false), is_used_in_query(false),
+ head(h), column_list(list), cycle_list(0), spec(unit),
is_recursive(false), rec_outer_references(0), with_anchor(false),
level(0), rec_result(NULL)
{ unit->with_element= this; }
+ LEX_CSTRING *get_name() { return head->query_name; }
+ const char *get_name_str() { return get_name()->str; }
+
+ void set_tables_start_pos(TABLE_LIST **pos)
+ { head->tables_pos.set_start_pos(pos); }
+ void set_tables_end_pos(TABLE_LIST **pos)
+ { head->tables_pos.set_end_pos(pos); }
+
bool check_dependencies_in_spec();
void check_dependencies_in_select(st_select_lex *sl, st_unit_ctxt_elem *ctxt,
@@ -201,9 +258,9 @@ public:
bool set_unparsed_spec(THD *thd, const char *spec_start, const char *spec_end,
my_ptrdiff_t spec_offset);
- st_select_lex_unit *clone_parsed_spec(THD *thd, TABLE_LIST *with_table);
+ st_select_lex_unit *clone_parsed_spec(LEX *old_lex, TABLE_LIST *with_table);
- bool is_referenced() { return references != 0; }
+ bool is_referenced() { return referenced; }
void inc_references() { references++; }
@@ -263,6 +320,12 @@ public:
void set_cycle_list(List<Lex_ident_sys> *cycle_list_arg);
friend class With_clause;
+
+ friend
+ bool LEX::resolve_references_to_cte(TABLE_LIST *tables,
+ TABLE_LIST **tables_last);
+ friend
+ bool LEX::resolve_references_to_cte_in_hanging_cte();
};
const uint max_number_of_elements_in_with_clause= sizeof(table_map)*8;
@@ -361,8 +424,10 @@ public:
friend class With_element;
friend
- bool
- check_dependencies_in_with_clauses(With_clause *with_clauses_list);
+ bool LEX::check_dependencies_in_with_clauses();
+
+ friend
+ bool LEX::resolve_references_to_cte_in_hanging_cte();
};
inline
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 05574daf42b..4c4c438564d 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2019, Oracle and/or its affiliates.
- Copyright (c) 2009, 2020, MariaDB Corporation
+ Copyright (c) 2009, 2021, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -1255,6 +1255,8 @@ void LEX::start(THD *thd_arg)
describe= 0;
context_analysis_only= 0;
derived_tables= 0;
+ with_cte_resolution= false;
+ only_cte_resolution= false;
parsing_options.reset();
part_info= 0;
m_sql_cmd= NULL;
@@ -2925,6 +2927,7 @@ void st_select_lex_unit::init_query()
with_wrapped_tvc= 0;
is_view= 0;
describe= 0;
+ cloned_from= 0;
columns_are_renamed= 0;
}
@@ -9079,6 +9082,8 @@ bool LEX::check_main_unit_semantics()
if (unit.set_nest_level(0) ||
unit.check_parameters(first_select_lex()))
return TRUE;
+ if (check_cte_dependencies_and_resolve_references())
+ return TRUE;
return FALSE;
}
@@ -9805,8 +9810,8 @@ bool LEX::main_select_push(bool service)
{
DBUG_ENTER("LEX::main_select_push");
DBUG_PRINT("info", ("service: %u", service));
- current_select_number= 1;
- builtin_select.select_number= 1;
+ current_select_number= ++thd->lex->stmt_lex->current_select_number;
+ builtin_select.select_number= current_select_number;
builtin_select.is_service_select= service;
if (push_select(&builtin_select))
DBUG_RETURN(TRUE);
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 27895af80d8..196d0d80b04 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -895,6 +895,8 @@ public:
With_clause *with_clause;
/* With element where this unit is used as the specification (if any) */
With_element *with_element;
+ /* The unit used as a CTE specification from which this unit is cloned */
+ st_select_lex_unit *cloned_from;
/* thread handler */
THD *thd;
/*
@@ -1563,7 +1565,9 @@ public:
}
With_element *get_with_element()
{
- return master_unit()->with_element;
+ return master_unit()->cloned_from ?
+ master_unit()->cloned_from->with_element :
+ master_unit()->with_element;
}
With_element *find_table_def_in_with_clauses(TABLE_LIST *table);
bool check_unrestricted_recursive(bool only_standard_compliant);
@@ -3357,6 +3361,20 @@ public:
bool parse_vcol_expr:1;
bool analyze_stmt:1; /* TRUE<=> this is "ANALYZE $stmt" */
bool explain_json:1;
+ /*
+ true <=> The parsed fragment requires resolution of references to CTE
+ at the end of parsing. This name resolution process involves searching
+ for possible dependencies between CTE defined in the parsed fragment and
+ detecting possible recursive references.
+ The flag is set to true if the fragment contains CTE definitions.
+ */
+ bool with_cte_resolution:1;
+ /*
+ true <=> only resolution of references to CTE are required in the parsed
+ fragment, no checking of dependencies between CTE is required.
+ This flag is used only when parsing clones of CTE specifications.
+ */
+ bool only_cte_resolution:1;
bool local_file:1;
bool check_exists:1;
bool verbose:1, no_write_to_binlog:1;
@@ -4749,6 +4767,12 @@ public:
const LEX_CSTRING *constraint_name,
Table_ident *ref_table_name,
DDL_options ddl_options);
+ bool check_dependencies_in_with_clauses();
+ bool resolve_references_to_cte_in_hanging_cte();
+ bool check_cte_dependencies_and_resolve_references();
+ bool resolve_references_to_cte(TABLE_LIST *tables,
+ TABLE_LIST **tables_last);
+
};
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 91b8ec138a0..da72bc8e7de 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -3520,9 +3520,6 @@ mysql_execute_command(THD *thd)
thd->get_stmt_da()->opt_clear_warning_info(thd->query_id);
}
- if (check_dependencies_in_with_clauses(thd->lex->with_clauses_list))
- DBUG_RETURN(1);
-
#ifdef HAVE_REPLICATION
if (unlikely(thd->slave_thread))
{
@@ -8212,7 +8209,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
ptr->is_fqtn= TRUE;
ptr->db= table->db;
}
- else if (lex->copy_db_to(&ptr->db))
+ else if (!lex->with_cte_resolution && lex->copy_db_to(&ptr->db))
DBUG_RETURN(0);
else
ptr->is_fqtn= FALSE;
@@ -8227,9 +8224,11 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
if (ptr->db.length && ptr->db.str != any_db.str)
ptr->db.length= my_casedn_str(files_charset_info, (char*) ptr->db.str);
}
-
+
ptr->table_name= table->table;
- ptr->lock_type= lock_type;
+ ptr->lock_type= lock_type;
+ ptr->mdl_type= mdl_type;
+ ptr->table_options= table_options;
ptr->updating= MY_TEST(table_options & TL_OPTION_UPDATING);
/* TODO: remove TL_OPTION_FORCE_INDEX as it looks like it's not used */
ptr->force_index= MY_TEST(table_options & TL_OPTION_FORCE_INDEX);
@@ -8916,8 +8915,10 @@ void st_select_lex::set_lock_for_tables(thr_lock_type lock_type, bool for_update
tables->lock_type= lock_type;
tables->skip_locked= skip_locked;
tables->updating= for_update;
- tables->mdl_request.set_type((lock_type >= TL_FIRST_WRITE) ?
- MDL_SHARED_WRITE : MDL_SHARED_READ);
+
+ if (tables->db.length)
+ tables->mdl_request.set_type((lock_type >= TL_FIRST_WRITE) ?
+ MDL_SHARED_WRITE : MDL_SHARED_READ);
}
DBUG_VOID_RETURN;
}
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index fc75eab564f..1db04c4656f 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -2325,9 +2325,6 @@ static bool check_prepared_statement(Prepared_statement *stmt)
if (tables)
thd->get_stmt_da()->opt_clear_warning_info(thd->query_id);
- if (check_dependencies_in_with_clauses(thd->lex->with_clauses_list))
- goto error;
-
if (sql_command_flags[sql_command] & CF_HA_CLOSE)
mysql_ha_rm_tables(thd, tables);
diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc
index 957fe44d621..474dd413f52 100644
--- a/sql/sql_trigger.cc
+++ b/sql/sql_trigger.cc
@@ -1,6 +1,6 @@
/*
Copyright (c) 2004, 2012, Oracle and/or its affiliates.
- Copyright (c) 2010, 2018, MariaDB
+ Copyright (c) 2010, 2021, MariaDB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -483,7 +483,6 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create)
thd->variables.lock_wait_timeout))
goto end;
-
if (!create)
{
bool if_exists= thd->lex->if_exists();
@@ -599,9 +598,8 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create)
table= tables->table;
#ifdef WITH_WSREP
- if (WSREP(thd) &&
- !wsrep_should_replicate_ddl(thd, table->s->db_type()))
- goto wsrep_error_label;
+ if (WSREP(thd) && !wsrep_should_replicate_ddl(thd, table->s->db_type()))
+ goto end;
#endif
/* Later on we will need it to downgrade the lock */
@@ -725,9 +723,11 @@ end:
thd->mdl_context.release_lock(mdl_request_for_trn.ticket);
DBUG_RETURN(result);
+
#ifdef WITH_WSREP
wsrep_error_label:
- DBUG_RETURN(true);
+ DBUG_ASSERT(result == 1);
+ goto end;
#endif
drop_orphan_trn:
diff --git a/sql/sql_view.cc b/sql/sql_view.cc
index 3fc55552f6b..eb5c1bff200 100644
--- a/sql/sql_view.cc
+++ b/sql/sql_view.cc
@@ -1,5 +1,5 @@
/* Copyright (c) 2004, 2013, Oracle and/or its affiliates.
- Copyright (c) 2011, 2016, MariaDB Corporation
+ Copyright (c) 2011, 2021, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -34,7 +34,6 @@
#include "sp_cache.h"
#include "datadict.h" // dd_frm_is_view()
#include "sql_derived.h"
-#include "sql_cte.h" // check_dependencies_in_with_clauses()
#include "opt_trace.h"
#include "ddl_log.h"
#include "debug.h" // debug_crash_here
@@ -440,12 +439,6 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views,
lex->link_first_table_back(view, link_to_local);
view->open_type= OT_BASE_ONLY;
- if (check_dependencies_in_with_clauses(lex->with_clauses_list))
- {
- res= TRUE;
- goto err_no_relink;
- }
-
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL);
/*
@@ -944,6 +937,13 @@ static int mysql_register_view(THD *thd, DDL_LOG_STATE *ddl_log_state,
LEX *lex= thd->lex;
/*
+ Ensure character set number != 17 (character set = filename) and mbminlen=1
+ because these character sets are not parser friendly, which can give weird
+ sequence in .frm file of view and later give parsing error.
+ */
+ DBUG_ASSERT(thd->charset()->mbminlen == 1 && thd->charset()->number != 17);
+
+ /*
View definition query -- a SELECT statement that fully defines view. It
is generated from the Item-tree built from the original (specified by
the user) query. The idea is that generated query should eliminates all
@@ -1485,9 +1485,6 @@ bool mysql_make_view(THD *thd, TABLE_SHARE *share, TABLE_LIST *table,
TABLE_LIST *tbl;
Security_context *security_ctx= 0;
- if (check_dependencies_in_with_clauses(thd->lex->with_clauses_list))
- goto err;
-
/*
Check rights to run commands which show underlying tables.
In the optimizer trace we would not like to show trace for
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index d1f22006e1d..37cdfc20030 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -294,6 +294,7 @@ void _CONCAT_UNDERSCORED(turn_parser_debug_on,yyparse)()
class sp_head *sphead;
class sp_name *spname;
class sp_variable *spvar;
+ class With_element_head *with_element_head;
class With_clause *with_clause;
class Virtual_column_info *virtual_column;
@@ -1788,7 +1789,7 @@ End SQL_MODE_ORACLE_SPECIFIC */
%type <with_clause> with_clause
-%type <lex_str_ptr> query_name
+%type <with_element_head> with_element_head
%type <ident_sys_list>
comma_separated_ident_list
@@ -2981,7 +2982,11 @@ call:
if (unlikely(Lex->call_statement_start(thd, $2)))
MYSQL_YYABORT;
}
- opt_sp_cparam_list {}
+ opt_sp_cparam_list
+ {
+ if (Lex->check_cte_dependencies_and_resolve_references())
+ MYSQL_YYABORT;
+ }
;
/* CALL parameters */
@@ -3788,6 +3793,8 @@ expr_lex:
$$->sp_lex_in_use= true;
$$->set_item($2);
Lex->pop_select(); //min select
+ if (Lex->check_cte_dependencies_and_resolve_references())
+ MYSQL_YYABORT;
if ($$->sphead->restore_lex(thd))
MYSQL_YYABORT;
}
@@ -12989,6 +12996,8 @@ do:
{
Lex->insert_list= $3;
Lex->pop_select(); //main select
+ if (Lex->check_cte_dependencies_and_resolve_references())
+ MYSQL_YYABORT;
}
;
@@ -15170,6 +15179,7 @@ with_clause:
if (unlikely(with_clause == NULL))
MYSQL_YYABORT;
lex->derived_tables|= DERIVED_WITH;
+ lex->with_cte_resolution= true;
lex->curr_with_clause= with_clause;
with_clause->add_to_list(Lex->with_clauses_list_last_next);
if (lex->current_select &&
@@ -15197,7 +15207,7 @@ with_list:
with_list_element:
- query_name
+ with_element_head
opt_with_column_list
AS '(' query_expression ')' opt_cycle
{
@@ -15215,6 +15225,7 @@ with_list_element:
{
elem->set_cycle_list($7);
}
+ elem->set_tables_end_pos(lex->query_tables_last);
}
;
@@ -15275,12 +15286,15 @@ comma_separated_ident_list:
;
-query_name:
+with_element_head:
ident
{
- $$= (LEX_CSTRING *) thd->memdup(&$1, sizeof(LEX_CSTRING));
- if (unlikely($$ == NULL))
+ LEX_CSTRING *name=
+ (LEX_CSTRING *) thd->memdup(&$1, sizeof(LEX_CSTRING));
+ $$= new (thd->mem_root) With_element_head(name);
+ if (unlikely(name == NULL || $$ == NULL))
MYSQL_YYABORT;
+ $$->tables_pos.set_start_pos(Lex->query_tables_last);
}
;
diff --git a/sql/table.h b/sql/table.h
index 1b8919f4e59..183ade8f1d9 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -2116,6 +2116,29 @@ struct vers_select_conds_t
struct LEX;
class Index_hint;
+
+/*
+ @struct TABLE_CHAIN
+ @brief Subchain of global chain of table references
+
+ The structure contains a pointer to the address of the next_global
+ pointer to the first TABLE_LIST objectof the subchain and the address
+ of the next_global pointer to the element right after the last
+ TABLE_LIST object of the subchain. For an empty subchain both pointers
+ have the same value.
+*/
+
+struct TABLE_CHAIN
+{
+ TABLE_CHAIN() {}
+
+ TABLE_LIST **start_pos;
+ TABLE_LIST ** end_pos;
+
+ void set_start_pos(TABLE_LIST **pos) { start_pos= pos; }
+ void set_end_pos(TABLE_LIST **pos) { end_pos= pos; }
+};
+
struct TABLE_LIST
{
TABLE_LIST() {} /* Remove gcc warning */
@@ -2451,6 +2474,20 @@ struct TABLE_LIST
/* call back function for asking handler about caching in query cache */
qc_engine_callback callback_func;
thr_lock_type lock_type;
+
+ /*
+ Two fields below are set during parsing this table reference in the cases
+ when the table reference can be potentially a reference to a CTE table.
+ In this cases the fact that the reference is a reference to a CTE or not
+ will be ascertained at the very end of parsing of the query when referencies
+ to CTE are resolved. For references to CTE and to derived tables no mdl
+ requests are needed while for other table references they are. If a request
+ is possibly postponed the info that allows to issue this request must be
+ saved in 'mdl_type' and 'table_options'.
+ */
+ enum_mdl_type mdl_type;
+ ulong table_options;
+
uint outer_join; /* Which join type */
uint shared; /* Used in multi-upd */
bool updatable; /* VIEW/TABLE can be updated now */
diff --git a/sql/threadpool_generic.cc b/sql/threadpool_generic.cc
index 19193be0354..e83676179b7 100644
--- a/sql/threadpool_generic.cc
+++ b/sql/threadpool_generic.cc
@@ -234,14 +234,19 @@ static void *native_event_get_userdata(native_event *event)
#elif defined(HAVE_KQUEUE)
/*
- NetBSD is incompatible with other BSDs , last parameter in EV_SET macro
- (udata, user data) needs to be intptr_t, whereas it needs to be void*
- everywhere else.
+ NetBSD prior to 9.99.17 is incompatible with other BSDs, last parameter
+ in EV_SET macro (udata, user data) needs to be intptr_t, whereas it needs
+ to be void* everywhere else.
*/
#ifdef __NetBSD__
+#include <sys/param.h>
+# if !__NetBSD_Prereq__(9,99,17)
#define MY_EV_SET(a, b, c, d, e, f, g) EV_SET(a, b, c, d, e, f, (intptr_t)g)
-#else
+# endif
+#endif
+
+#ifndef MY_EV_SET
#define MY_EV_SET(a, b, c, d, e, f, g) EV_SET(a, b, c, d, e, f, g)
#endif
diff --git a/storage/connect/CMakeLists.txt b/storage/connect/CMakeLists.txt
index 14ab86cf2d8..ebb61bb487b 100644
--- a/storage/connect/CMakeLists.txt
+++ b/storage/connect/CMakeLists.txt
@@ -423,11 +423,11 @@ IF(CONNECT_WITH_JDBC AND JAVA_FOUND AND JNI_FOUND)
INSTALL(FILES
${CMAKE_CURRENT_SOURCE_DIR}/mysql-test/connect/std_data/JavaWrappers.jar
${CMAKE_CURRENT_BINARY_DIR}/JdbcInterface.jar
- DESTINATION ${INSTALL_PLUGINDIR} COMPONENT connect-engine)
+ DESTINATION ${INSTALL_MYSQLSHAREDIR} COMPONENT connect-engine)
IF(CONNECT_WITH_MONGO)
INSTALL(FILES
${CMAKE_CURRENT_SOURCE_DIR}/mysql-test/connect/std_data/Mongo2.jar
${CMAKE_CURRENT_SOURCE_DIR}/mysql-test/connect/std_data/Mongo3.jar
- DESTINATION ${INSTALL_PLUGINDIR} COMPONENT connect-engine)
+ DESTINATION ${INSTALL_MYSQLSHAREDIR} COMPONENT connect-engine)
ENDIF()
ENDIF()
diff --git a/storage/connect/javaconn.cpp b/storage/connect/javaconn.cpp
index eda5d31c80b..03c9ecb9221 100644
--- a/storage/connect/javaconn.cpp
+++ b/storage/connect/javaconn.cpp
@@ -57,8 +57,8 @@ extern "C" HINSTANCE s_hModule; // Saved module handle
extern char *JvmPath; // The connect_jvm_path global variable value
extern char *ClassPath; // The connect_class_path global variable value
-char *GetPluginDir(void);
char *GetJavaWrapper(void); // The connect_java_wrapper variable value
+extern MYSQL_PLUGIN_IMPORT char lc_messages_dir[FN_REFLEN];
/***********************************************************************/
/* Static JAVAConn objects. */
@@ -401,23 +401,23 @@ bool JAVAConn::Open(PGLOBAL g)
} // endif ClassPath
#if 0
- // Java source will be compiled as a jar file installed in the plugin dir
+ // Java source will be compiled as a jar file installed in the mysql share dir
jpop->Append(sep);
- jpop->Append(GetPluginDir());
+ jpop->Append(lc_messages_dir);
jpop->Append("JdbcInterface.jar");
#endif // 0
- // All wrappers are pre-compiled in JavaWrappers.jar in the plugin dir
+ // All wrappers are pre-compiled in JavaWrappers.jar in the mysql share dir
jpop->Append(sep);
- jpop->Append(GetPluginDir());
+ jpop->Append(lc_messages_dir);
jpop->Append("JavaWrappers.jar");
#if defined(MONGO_SUPPORT)
jpop->Append(sep);
- jpop->Append(GetPluginDir());
+ jpop->Append(lc_messages_dir);
jpop->Append("Mongo3.jar");
jpop->Append(sep);
- jpop->Append(GetPluginDir());
+ jpop->Append(lc_messages_dir);
jpop->Append("Mongo2.jar");
#endif // MONGO_SUPPORT
diff --git a/storage/connect/tabjson.cpp b/storage/connect/tabjson.cpp
index e77f10d3209..6ef39391849 100644
--- a/storage/connect/tabjson.cpp
+++ b/storage/connect/tabjson.cpp
@@ -1682,7 +1682,6 @@ PVAL JSONCOL::MakeJson(PGLOBAL g, PJSON jsp, int n)
/***********************************************************************/
PJVAL JSONCOL::GetRowValue(PGLOBAL g, PJSON row, int i)
{
- int n = Nod - 1;
PJVAL val = NULL;
for (; i < Nod && row; i++) {
diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc
index 515abf94060..050c8eb7d23 100644
--- a/storage/innobase/fts/fts0fts.cc
+++ b/storage/innobase/fts/fts0fts.cc
@@ -1750,15 +1750,14 @@ fts_create_one_common_table(
error = row_create_index_for_mysql(index, trx, NULL,
FIL_ENCRYPTION_DEFAULT,
FIL_DEFAULT_ENCRYPTION_KEY);
+ if (error == DB_SUCCESS) {
+ return new_table;
+ }
}
- if (error != DB_SUCCESS) {
- dict_mem_table_free(new_table);
- new_table = NULL;
- ib::warn() << "Failed to create FTS common table "
- << fts_table_name;
- }
- return(new_table);
+ ib::warn() << "Failed to create FTS common table " << fts_table_name;
+ trx->error_state = error;
+ return NULL;
}
/** Creates the common auxiliary tables needed for supporting an FTS index
@@ -1813,7 +1812,8 @@ fts_create_common_tables(
dict_table_t* common_table = fts_create_one_common_table(
trx, table, full_name[i], fts_table.suffix, heap);
- if (common_table == NULL) {
+ if (!common_table) {
+ trx->error_state = DB_SUCCESS;
error = DB_ERROR;
goto func_exit;
}
@@ -1928,16 +1928,15 @@ fts_create_one_index_table(
error = row_create_index_for_mysql(index, trx, NULL,
FIL_ENCRYPTION_DEFAULT,
FIL_DEFAULT_ENCRYPTION_KEY);
- }
- if (error != DB_SUCCESS) {
- dict_mem_table_free(new_table);
- new_table = NULL;
- ib::warn() << "Failed to create FTS index table "
- << table_name;
+ if (error == DB_SUCCESS) {
+ return new_table;
+ }
}
- return(new_table);
+ ib::warn() << "Failed to create FTS index table " << table_name;
+ trx->error_state = error;
+ return NULL;
}
/** Creates the column specific ancillary tables needed for supporting an
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 2b6089c4814..aea5ac42010 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -5966,7 +5966,9 @@ ha_innobase::open(const char* name, int, uint)
/* Index block size in InnoDB: used by MySQL in query optimization */
stats.block_size = static_cast<uint>(srv_page_size);
- if (m_prebuilt->table == NULL
+ const my_bool for_vc_purge = THDVAR(thd, background_thread);
+
+ if (for_vc_purge || !m_prebuilt->table
|| m_prebuilt->table->is_temporary()
|| m_prebuilt->table->persistent_autoinc
|| !m_prebuilt->table->is_readable()) {
@@ -5993,7 +5995,7 @@ ha_innobase::open(const char* name, int, uint)
ut_ad(!m_prebuilt->table
|| table->versioned() == m_prebuilt->table->versioned());
- if (!THDVAR(thd, background_thread)) {
+ if (!for_vc_purge) {
info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST
| HA_STATUS_OPEN);
}
@@ -12956,7 +12958,6 @@ create_table_info_t::create_table_update_dict()
if (m_flags2 & DICT_TF2_FTS) {
if (!innobase_fts_load_stopword(innobase_table, NULL, m_thd)) {
dict_table_close(innobase_table, FALSE, FALSE);
- m_trx->free();
DBUG_RETURN(-1);
}
@@ -13076,7 +13077,8 @@ ha_innobase::create(
DBUG_ASSERT(trx_state_eq(trx, TRX_STATE_NOT_STARTED));
}
- if (int error = info.create_table(own_trx)) {
+ int error = info.create_table(own_trx);
+ if (error) {
/* Drop the being-created table before rollback,
so that rollback can possibly rename back a table
that could have been renamed before the failed creation. */
@@ -13088,22 +13090,18 @@ ha_innobase::create(
}
trx_rollback_for_mysql(trx);
row_mysql_unlock_data_dictionary(trx);
- if (own_trx) {
- trx->free();
- }
- DBUG_RETURN(error);
+ } else {
+ innobase_commit_low(trx);
+ row_mysql_unlock_data_dictionary(trx);
+ ut_ad(!srv_read_only_mode);
+ error = info.create_table_update_dict();
}
- innobase_commit_low(trx);
- row_mysql_unlock_data_dictionary(trx);
-
if (own_trx) {
trx->free();
}
- ut_ad(!srv_read_only_mode);
-
- DBUG_RETURN(info.create_table_update_dict());
+ DBUG_RETURN(error);
}
/** Create a new table to an InnoDB database.
diff --git a/storage/mroonga/vendor/groonga/CMakeLists.txt b/storage/mroonga/vendor/groonga/CMakeLists.txt
index ebb8b6906ec..b6ad3a9e50d 100644
--- a/storage/mroonga/vendor/groonga/CMakeLists.txt
+++ b/storage/mroonga/vendor/groonga/CMakeLists.txt
@@ -588,14 +588,13 @@ else()
set(GRN_WITH_MESSAGE_PACK FALSE)
endif()
-find_program(RUBY NAMES
- "ruby2.3" "ruby23"
- "ruby2.2" "ruby22"
- "ruby2.1" "ruby21"
- "ruby")
-
option(GRN_WITH_MRUBY "use mruby" OFF)
if(GRN_WITH_MRUBY)
+ find_program(RUBY NAMES
+ "ruby2.3" "ruby23"
+ "ruby2.2" "ruby22"
+ "ruby2.1" "ruby21"
+ "ruby")
set(MRUBY_INCLUDE_DIRS
"${CMAKE_CURRENT_SOURCE_DIR}/vendor/mruby-source/include")
set(MRUBY_LIBS mruby)
diff --git a/support-files/rpm/server-posttrans.sh b/support-files/rpm/server-posttrans.sh
index 313274c6140..d91ff65e04f 100644
--- a/support-files/rpm/server-posttrans.sh
+++ b/support-files/rpm/server-posttrans.sh
@@ -3,7 +3,7 @@ if [ -r %{restart_flag} ] ; then
# only restart the server if it was already running
if [ -x /usr/bin/systemctl ] ; then
/usr/bin/systemctl daemon-reload > /dev/null 2>&1
- if [ /usr/bin/systemctl is-active mysql ]; then
+ if /usr/bin/systemctl is-active mysql; then
/usr/bin/systemctl restart mysql > /dev/null 2>&1
else
/usr/bin/systemctl try-restart mariadb.service > /dev/null 2>&1