1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-08 11:22:35 +03:00

Merge 10.5 into 10.6

This commit is contained in:
Marko Mäkelä
2021-05-26 11:22:40 +03:00
65 changed files with 1544 additions and 344 deletions

View File

@@ -44,7 +44,13 @@ cd ../storage/rocksdb/rocksdb
git submodule update git submodule update
cd ../../maria/libmarias3 cd ../../maria/libmarias3
git submodule update git submodule update
cd ../../.." cd ../../..
cd storage/columnstore/columnstore
git submodule update
cd ../../..
cd wsrep-lib
git submodule update
cd .."
fi fi
commands="$commands commands="$commands
path=`dirname $0` path=`dirname $0`

View File

@@ -32,6 +32,7 @@ Usage: $0 [-h|-n] [configure-options]
-n, --just-print Don't actually run any commands; just print them. -n, --just-print Don't actually run any commands; just print them.
-c, --just-configure Stop after running configure. -c, --just-configure Stop after running configure.
Combined with --just-print shows configure options. 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-configs=xxx Add this to configure options
--extra-flags=xxx Add this C and CXX flags --extra-flags=xxx Add this C and CXX flags
--extra-cflags=xxx Add this to C flags --extra-cflags=xxx Add this to C flags
@@ -71,6 +72,8 @@ parse_options()
just_configure=1;; just_configure=1;;
-n | --just-print | --print) -n | --just-print | --print)
just_print=1;; just_print=1;;
--just-clean)
just_clean=1;;
--verbose) --verbose)
verbose_make=1;; verbose_make=1;;
-h | --help) -h | --help)
@@ -94,6 +97,7 @@ fi
prefix="/usr/local/mysql" prefix="/usr/local/mysql"
just_print= just_print=
just_clean=
just_configure= just_configure=
warning_mode= warning_mode=
maintainer_mode= maintainer_mode=

View File

@@ -123,11 +123,13 @@ FOREACH(_base
ENDIF() ENDIF()
ENDFOREACH() ENDFOREACH()
IF(NOT RPM AND NOT DEB)
FOREACH(tool gtar tar) FOREACH(tool gtar tar)
STRING(TOUPPER ${tool} TOOL) STRING(TOUPPER ${tool} TOOL)
FIND_PROGRAM(${TOOL}_EXECUTABLE ${tool} DOC "path to the executable") FIND_PROGRAM(${TOOL}_EXECUTABLE ${tool} DOC "path to the executable")
MARK_AS_ADVANCED(${TOOL}_EXECUTABLE) MARK_AS_ADVANCED(${TOOL}_EXECUTABLE)
ENDFOREACH() ENDFOREACH()
ENDIF()
FIND_PACKAGE(Git) FIND_PACKAGE(Git)

13
cmake/FindGit.cmake Normal file
View File

@@ -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})

View File

@@ -1,4 +1,9 @@
if(JAVA_AWT_LIBRARY)
set(JNI_FOUND TRUE)
return()
endif()
if(DEFINED JAVA_AWT_LIBRARY) if(DEFINED JAVA_AWT_LIBRARY)
set(JNI_FOUND FALSE)
return() return()
endif() endif()

View File

@@ -1,4 +1,9 @@
if(Java_JAVA_EXECUTABLE)
set(JAVA_FOUND TRUE)
return()
endif()
if(DEFINED Java_JAVA_EXECUTABLE) if(DEFINED Java_JAVA_EXECUTABLE)
set(JAVA_FOUND FALSE)
return() return()
endif() endif()

View File

@@ -84,6 +84,12 @@ ENDIF()
SET(WITH_INNODB_SNAPPY OFF CACHE STRING "") SET(WITH_INNODB_SNAPPY OFF CACHE STRING "")
SET(WITH_NUMA 0 CACHE BOOL "") 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) IF(WIN32)
SET(INSTALL_MYSQLTESTDIR "" CACHE STRING "") SET(INSTALL_MYSQLTESTDIR "" CACHE STRING "")
SET(INSTALL_SQLBENCHDIR "" CACHE STRING "") SET(INSTALL_SQLBENCHDIR "" CACHE STRING "")
@@ -97,7 +103,6 @@ ELSEIF(RPM)
SET(WITH_ZLIB system CACHE STRING "") SET(WITH_ZLIB system CACHE STRING "")
SET(CHECKMODULE /usr/bin/checkmodule CACHE FILEPATH "") SET(CHECKMODULE /usr/bin/checkmodule CACHE FILEPATH "")
SET(SEMODULE_PACKAGE /usr/bin/semodule_package 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(PLUGIN_AUTH_SOCKET YES CACHE STRING "")
SET(WITH_EMBEDDED_SERVER ON CACHE BOOL "") SET(WITH_EMBEDDED_SERVER ON CACHE BOOL "")
# not yet, SLES 12.3 doesn't provide pcre2 # not yet, SLES 12.3 doesn't provide pcre2
@@ -107,7 +112,6 @@ ELSEIF(DEB)
SET(WITH_ZLIB system CACHE STRING "") SET(WITH_ZLIB system CACHE STRING "")
SET(WITH_LIBWRAP ON) SET(WITH_LIBWRAP ON)
SET(HAVE_EMBEDDED_PRIVILEGE_CONTROL ON) SET(HAVE_EMBEDDED_PRIVILEGE_CONTROL ON)
SET(WITH_JEMALLOC "yes" CACHE STRING "")
SET(PLUGIN_AUTH_SOCKET YES CACHE STRING "") SET(PLUGIN_AUTH_SOCKET YES CACHE STRING "")
SET(WITH_EMBEDDED_SERVER ON CACHE BOOL "") SET(WITH_EMBEDDED_SERVER ON CACHE BOOL "")
SET(WITH_PCRE system CACHE STRING "") SET(WITH_PCRE system CACHE STRING "")

View File

@@ -125,8 +125,6 @@ SET(ignored
"%ignore ${CMAKE_INSTALL_PREFIX}/share/man" "%ignore ${CMAKE_INSTALL_PREFIX}/share/man"
"%ignore ${CMAKE_INSTALL_PREFIX}/share/man/man1" "%ignore ${CMAKE_INSTALL_PREFIX}/share/man/man1"
"%ignore ${CMAKE_INSTALL_PREFIX}/share/man/man8" "%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" "%ignore ${CMAKE_INSTALL_PREFIX}/share/pkgconfig"
) )

View File

@@ -15,6 +15,8 @@
# Symbols with information about the CPU. # Symbols with information about the CPU.
IF(NOT DEFINED CPU_LEVEL1_DCACHE_LINESIZE)
IF(CMAKE_SYSTEM_NAME MATCHES "Darwin") IF(CMAKE_SYSTEM_NAME MATCHES "Darwin")
FIND_PROGRAM(SYSCTL sysctl) FIND_PROGRAM(SYSCTL sysctl)
MARK_AS_ADVANCED(SYSCTL) MARK_AS_ADVANCED(SYSCTL)
@@ -37,3 +39,5 @@ ELSE()
) )
ENDIF() ENDIF()
ENDIF() ENDIF()
ENDIF()

View File

@@ -30,7 +30,7 @@ IF(NOT CMAKE_CROSSCOMPILING OR DEFINED CMAKE_CROSSCOMPILING_EMULATOR)
TARGET_LINK_LIBRARIES(factorial dbug) TARGET_LINK_LIBRARIES(factorial dbug)
ENDIF() 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(GROFF groff)
FIND_PROGRAM(NROFF nroff) FIND_PROGRAM(NROFF nroff)
MARK_AS_ADVANCED(GROFF) MARK_AS_ADVANCED(GROFF)

View File

@@ -1,2 +1,6 @@
etc/mysql/mariadb.conf.d/connect.cnf etc/mysql/mariadb.conf.d/connect.cnf
usr/lib/mysql/plugin/ha_connect.so 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

View File

@@ -1763,6 +1763,207 @@ a c
2 1 2 1
7 3 7 3
drop table t1; 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 # End of 10.2 tests
# #
# MDEV-21673: several references to CTE that uses # MDEV-21673: several references to CTE that uses

View File

@@ -1273,6 +1273,208 @@ select a, c from cte as r2 where a > 4;
drop table t1; 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 # End of 10.2 tests
--echo # --echo #

View File

@@ -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 BINARY @a REVERSE(@a) HEX(@a) HEX(REVERSE(@a))
aя a@r1 яa 61407231 40723161 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 # MDEV-22022 Various mangled SQL statements will crash 10.3 to 10.5 debug builds
# #
SET CHARACTER_SET_CLIENT=17; 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; 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; SET NAMES latin1;
# # End of 10.3 tests
# Start of 10.5 tests
#
# #
# MDEV-22043 Special character leads to assertion in my_wc_to_printable_generic on 10.5.2 (debug) # MDEV-22043 Special character leads to assertion in my_wc_to_printable_generic on 10.5.2 (debug)
# #
SET NAMES filename; SET NAMES filename;
ERROR 42000: Variable 'character_set_client' can't be set to the value of 'filename'
EXECUTE IMMEDIATE _latin1 0x01; 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; SET NAMES utf8;
# #
# MDEV-23435 Functions do not convert numbers to character_set_results # MDEV-23435 Functions do not convert numbers to character_set_results
@@ -103,6 +132,4 @@ a c
@002d1 @002d1 @002d1 @002d1
DROP TABLE t1; DROP TABLE t1;
SET NAMES utf8; SET NAMES utf8;
#
# End of 10.5 tests # End of 10.5 tests
#

View File

@@ -28,25 +28,49 @@ select convert(convert(',' using filename) using binary);
SET NAMES utf8; SET NAMES utf8;
SELECT @a:=CONVERT('aя' USING filename) AS `@a`, BINARY @a, REVERSE(@a), HEX(@a), HEX(REVERSE(@a)); 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 #
--echo # MDEV-22022 Various mangled SQL statements will crash 10.3 to 10.5 debug builds --echo # MDEV-22022 Various mangled SQL statements will crash 10.3 to 10.5 debug builds
--echo # --echo #
--error ER_WRONG_VALUE_FOR_VAR
SET CHARACTER_SET_CLIENT=17; SET CHARACTER_SET_CLIENT=17;
--error ER_PARSE_ERROR --error ER_PARSE_ERROR
SELECT doc.`Children`.0 FROM t1; SELECT doc.`Children`.0 FROM t1;
SET NAMES latin1; SET NAMES latin1;
--echo # End of 10.3 tests
--echo #
--echo # Start of 10.5 tests
--echo #
--echo # --echo #
--echo # MDEV-22043 Special character leads to assertion in my_wc_to_printable_generic on 10.5.2 (debug) --echo # MDEV-22043 Special character leads to assertion in my_wc_to_printable_generic on 10.5.2 (debug)
--echo # --echo #
--error ER_WRONG_VALUE_FOR_VAR
SET NAMES filename; SET NAMES filename;
--error ER_PARSE_ERROR --error ER_PARSE_ERROR
EXECUTE IMMEDIATE _latin1 0x01; EXECUTE IMMEDIATE _latin1 0x01;
@@ -114,7 +138,4 @@ SET NAMES utf8;
--enable_ps_protocol --enable_ps_protocol
--echo #
--echo # End of 10.5 tests --echo # End of 10.5 tests
--echo #

View File

@@ -1579,7 +1579,7 @@ lc-messages-dir MYSQL_SHAREDIR/
lc-time-names en_US lc-time-names en_US
local-infile TRUE local-infile TRUE
lock-wait-timeout 86400 lock-wait-timeout 86400
log-bin (No default value) log-bin foo
log-bin-compress FALSE log-bin-compress FALSE
log-bin-compress-min-len 256 log-bin-compress-min-len 256
log-bin-index (No default value) log-bin-index (No default value)

View File

@@ -13,7 +13,7 @@
# force symbolic-links=0 (valgrind build has a different default) # 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 # The inline perl code below will copy $MYSQL_TMP_DIR/mysqld--help.txt
# to output, but filter away some variable stuff (e.g. paths). # to output, but filter away some variable stuff (e.g. paths).

View File

@@ -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); SELECT a FROM t1 WHERE (a, a) IN (SELECT 1, 2) AND a = (SELECT MIN(b) FROM t2);
a a
DROP TABLE t1,t2; 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 # 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); SELECT 1 IN (SELECT (SELECT a FROM t1) AS x FROM t2 GROUP BY x);
ERROR 21000: Subquery returns more than 1 row ERROR 21000: Subquery returns more than 1 row
drop table t1,t2; 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 # End of 10.3 tests
# #
# MDEV-19134: EXISTS() slower if ORDER BY is defined # MDEV-19134: EXISTS() slower if ORDER BY is defined

View File

@@ -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; 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 #
--echo # MDEV-18335: Assertion `!error || error == 137' failed in subselect_rowid_merge_engine::init --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); SELECT 1 IN (SELECT (SELECT a FROM t1) AS x FROM t2 GROUP BY x);
drop table t1,t2; 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 # End of 10.3 tests
--echo # --echo #

View File

@@ -229,3 +229,16 @@ INSERT INTO t2 (id) VALUES (1);
disconnect con2; disconnect con2;
connection default; connection default;
DROP TABLE t3, t2, t1; 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
#

View File

@@ -233,3 +233,19 @@ DROP TABLE t3, t2, t1;
# Wait till we reached the initial number of concurrent sessions # Wait till we reached the initial number of concurrent sessions
--source include/wait_until_count_sessions.inc --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 #

View File

@@ -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 # Gtid # # GTID #-#-#
master-bin.000001 # Query # # use `test`; CREATE TABLE t2 (f INT) ENGINE=INNODB master-bin.000001 # Query # # use `test`; CREATE TABLE t2 (f INT) ENGINE=INNODB
DROP TABLE t1,t2; DROP TABLE t1,t2;
FLUSH LOGS; RESET MASTER;
# #
# Kill OPTIMIZE command after table modification # Kill OPTIMIZE command after table modification
# #

View File

@@ -56,7 +56,7 @@ SET debug_sync = 'reset';
--source include/show_binlog_events.inc --source include/show_binlog_events.inc
DROP TABLE t1,t2; DROP TABLE t1,t2;
FLUSH LOGS; RESET MASTER;
--echo # --echo #
--echo # Kill OPTIMIZE command after table modification --echo # Kill OPTIMIZE command after table modification
@@ -81,6 +81,9 @@ eval KILL $thd_id;
SET debug_sync = 'reset'; SET debug_sync = 'reset';
--disconnect con1 --disconnect con1
--let $wait_binlog_event= OPTIMIZE
--source include/wait_for_binlog_event.inc
DROP TABLE t1,t2; DROP TABLE t1,t2;
let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1); let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1);
FLUSH LOGS; FLUSH LOGS;

View File

@@ -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_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_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_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 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 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 partition : MDEV-19958 Galera test failure on galera.partition
pxc-421: wsrep_provider is read-only for security reasons pxc-421: wsrep_provider is read-only for security reasons
query_cache: MDEV-15805 Test failure on galera.query_cache 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 versioning_trx_id: MDEV-18590: galera.versioning_trx_id: Test failure: mysqltest: Result content mismatch
MDEV-25562: MDEV-25562 FIXME: lock wait timeout exceeded

View File

@@ -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;

View File

@@ -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;

View File

@@ -264,6 +264,18 @@ t1 CREATE TABLE `t1` (
`f1` int(11) NOT NULL `f1` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ) ENGINE=InnoDB DEFAULT CHARSET=latin1
DROP TABLE t1; 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; CREATE TABLE t1 (a VARCHAR(3)) ENGINE=InnoDB;
ALTER TABLE t1 ADD FULLTEXT KEY(a), ADD COLUMN b VARCHAR(3), ADD FULLTEXT KEY(b); ALTER TABLE t1 ADD FULLTEXT KEY(a), ADD COLUMN b VARCHAR(3), ADD FULLTEXT KEY(b);
DROP TABLE t1; DROP TABLE t1;

View File

@@ -52,3 +52,16 @@ CHECK TABLE t1;
Table Op Msg_type Msg_text Table Op Msg_type Msg_text
test.t1 check status OK test.t1 check status OK
DROP TABLE t1; 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

View File

@@ -0,0 +1 @@
--enable-plugin-innodb-sys-tables

View File

@@ -319,6 +319,25 @@ ALTER TABLE t1 ADD FTS_DOC_ID INT UNSIGNED NOT NULL, ALGORITHM=INPLACE;
SHOW CREATE TABLE t1; SHOW CREATE TABLE t1;
DROP 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 # Add more than one FTS index
CREATE TABLE t1 (a VARCHAR(3)) ENGINE=InnoDB; CREATE TABLE t1 (a VARCHAR(3)) ENGINE=InnoDB;
ALTER TABLE t1 ADD FULLTEXT KEY(a), ADD COLUMN b VARCHAR(3), ADD FULLTEXT KEY(b); ALTER TABLE t1 ADD FULLTEXT KEY(a), ADD COLUMN b VARCHAR(3), ADD FULLTEXT KEY(b);

View File

@@ -83,3 +83,18 @@ ALTER TABLE t1 ADD bl INT AS (LENGTH(b)) VIRTUAL;
CHECK TABLE t1; CHECK TABLE t1;
DROP TABLE t1; DROP TABLE t1;
--source include/wait_until_count_sessions.inc --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

View File

@@ -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;

View File

@@ -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;

View File

@@ -517,12 +517,12 @@ static int arch_ppc_probe(void) {
return arch_ppc_crc32; return arch_ppc_crc32;
} }
#elif _AIX #elif defined(_AIX) || defined(__OpenBSD__)
static int arch_ppc_probe(void) { static int arch_ppc_probe(void) {
arch_ppc_crc32 = 0; arch_ppc_crc32 = 0;
#if defined(__powerpc64__) #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; arch_ppc_crc32 = 1;
#endif /* __powerpc64__ */ #endif /* __powerpc64__ */

View File

@@ -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" # warning "No explicit large page (HUGETLB pages) support in Linux < 3.8"
#endif #endif
#elif defined(MAP_ALIGNED) #elif defined(MAP_ALIGNED)
mapflag|= MAP_ALIGNED_SUPER | mapflag|= MAP_ALIGNED(my_bit_log2_size_t(large_page_size));
MAP_ALIGNED(my_bit_log2_size_t(large_page_size)); #if defined(MAP_ALIGNED_SUPER)
mapflag|= MAP_ALIGNED_SUPER;
#endif
#endif #endif
aligned_size= MY_ALIGN(*size, (size_t) large_page_size); aligned_size= MY_ALIGN(*size, (size_t) large_page_size);
} }

View File

@@ -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 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 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 */ /* prepare random nonce */
if (my_random_bytes((unsigned char *)nonce, (int)sizeof(nonce))) if (my_random_bytes((unsigned char *)nonce, (int)sizeof(nonce)))
return CR_AUTH_USER_CREDENTIALS; return CR_ERROR; // eh? OpenSSL error
/* send it */ /* send it */
if (vio->write_packet(vio, reply + CRYPTO_BYTES, NONCE_BYTES)) 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, if (crypto_sign_open(reply, CRYPTO_BYTES + NONCE_BYTES,
(unsigned char*)info->auth_string)) (unsigned char*)info->auth_string))
return CR_ERROR; return CR_AUTH_USER_CREDENTIALS; // wrong password provided by the user
return CR_OK; return CR_OK;
} }

View File

@@ -875,7 +875,9 @@ get_openssl()
readonly OPENSSL_BINARY readonly OPENSSL_BINARY
} }
#
# Generate a string equivalent to 16 random bytes # Generate a string equivalent to 16 random bytes
#
wsrep_gen_secret() wsrep_gen_secret()
{ {
get_openssl get_openssl
@@ -889,16 +891,36 @@ wsrep_gen_secret()
fi 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() is_local_ip()
{ {
[ "$1" = '127.0.0.1' ] && return 0 # Rapid recognition of the most common cases:
[ "$1" = '127.0.0.2' ] && return 0 [ "$1" = '127.0.0.1' -o \
[ "$1" = 'localhost' ] && return 0 "$1" = '127.0.0.2' -o \
[ "$1" = '[::1]' ] && return 0 "$1" = 'localhost' -o \
[ "$1" = "$(hostname -s)" ] && return 0 "$1" = '[::1]' ] && return 0
[ "$1" = "$(hostname -f)" ] && return 0 # If the address starts with "127." this is probably a local
[ "$1" = "$(hostname -d)" ] && return 0 # 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)" local ip_util="$(command -v ip)"
if [ -n "$ip_util" ]; then if [ -n "$ip_util" ]; then
# ip address show ouput format is " inet[6] <address>/<mask>": # ip address show ouput format is " inet[6] <address>/<mask>":
@@ -914,7 +936,6 @@ is_local_ip()
| grep -F " $1 " >/dev/null && return 0 | grep -F " $1 " >/dev/null && return 0
fi fi
fi fi
return 1 return 1
} }

View File

@@ -5941,6 +5941,7 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
*/ */
set_max_sum_func_level(thd, select); set_max_sum_func_level(thd, select);
set_field(new_field); set_field(new_field);
depended_from= (*((Item_field**)res))->depended_from;
return 0; return 0;
} }
else else

View File

@@ -1870,7 +1870,6 @@ double Item_in_subselect::val_real()
As far as Item_in_subselect called only from Item_in_optimizer this As far as Item_in_subselect called only from Item_in_optimizer this
method should not be used method should not be used
*/ */
DBUG_ASSERT(0);
DBUG_ASSERT(fixed()); DBUG_ASSERT(fixed());
if (forced_const) if (forced_const)
return value; return value;
@@ -2345,7 +2344,8 @@ Item_in_subselect::create_single_in_to_exists_cond(JOIN *join,
*/ */
Item *item= (Item*) select_lex->item_list.head(); 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 *having= item;
Item *orig_item= item; Item *orig_item= item;
@@ -2393,8 +2393,7 @@ Item_in_subselect::create_single_in_to_exists_cond(JOIN *join,
} }
else else
{ {
if (select_lex->master_unit()->is_unit_op()) DBUG_ASSERT(select_lex->master_unit()->is_unit_op());
{
LEX_CSTRING field_name= {STRING_WITH_LEN("<result>") }; LEX_CSTRING field_name= {STRING_WITH_LEN("<result>") };
Item *new_having= Item *new_having=
func->create(thd, expr, func->create(thd, expr,
@@ -2407,19 +2406,17 @@ Item_in_subselect::create_single_in_to_exists_cond(JOIN *join,
if (!abort_on_null && left_expr->maybe_null()) if (!abort_on_null && left_expr->maybe_null())
{ {
disable_cond_guard_for_const_null_left_expr(0); disable_cond_guard_for_const_null_left_expr(0);
if (!(new_having= new (thd->mem_root) Item_func_trig_cond(thd, new_having, if (!(new_having= new (thd->mem_root)
get_cond_guard(0)))) Item_func_trig_cond(thd, new_having, get_cond_guard(0))))
DBUG_RETURN(true); DBUG_RETURN(true);
} }
new_having->name= in_having_cond; new_having->name= in_having_cond;
if (fix_having(new_having, select_lex)) if (fix_having(new_having, select_lex))
DBUG_RETURN(true); DBUG_RETURN(true);
*having_item= new_having; *having_item= new_having;
} }
else
DBUG_ASSERT(false);
}
} }
DBUG_RETURN(false); DBUG_RETURN(false);

View File

@@ -1124,21 +1124,22 @@ void Global_read_lock::unlock_global_read_lock(THD *thd)
thd->mdl_context.release_lock(m_mdl_global_read_lock); thd->mdl_context.release_lock(m_mdl_global_read_lock);
#ifdef WITH_WSREP #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(); Wsrep_server_state& server_state= Wsrep_server_state::instance();
if (server_state.state() == Wsrep_server_state::s_donor || if (server_state.state() == Wsrep_server_state::s_donor ||
(WSREP_NNULL(thd) && (WSREP_NNULL(thd) &&
server_state.state() != Wsrep_server_state::s_synced)) server_state.state() != Wsrep_server_state::s_synced))
{ {
/* TODO: maybe redundant here?: */
wsrep_locked_seqno= WSREP_SEQNO_UNDEFINED;
server_state.resume(); server_state.resume();
wsrep_locked_seqno= WSREP_SEQNO_UNDEFINED;
} }
else if (WSREP_NNULL(thd) && else if (WSREP_NNULL(thd) &&
server_state.state() == Wsrep_server_state::s_synced) server_state.state() == Wsrep_server_state::s_synced)
{ {
server_state.resume_and_resync(); server_state.resume_and_resync();
wsrep_locked_seqno= WSREP_SEQNO_UNDEFINED;
} }
} }
#endif /* WITH_WSREP */ #endif /* WITH_WSREP */

View File

@@ -4977,7 +4977,7 @@ static int init_server_components()
} }
#endif /* WITH_WSREP */ #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, if (mysql_bin_log.open_index_file(opt_binlog_index_name, opt_bin_logname,
TRUE)) TRUE))

View File

@@ -711,7 +711,7 @@ extern struct st_VioSSLFd * ssl_acceptor_fd;
*/ */
extern my_bool opt_large_pages; extern my_bool opt_large_pages;
extern uint opt_large_page_size; 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 char *lc_messages_dir_ptr, *log_error_file_ptr;
extern MYSQL_PLUGIN_IMPORT char reg_ext[FN_EXTLEN]; extern MYSQL_PLUGIN_IMPORT char reg_ext[FN_EXTLEN];
extern MYSQL_PLUGIN_IMPORT uint reg_ext_length; extern MYSQL_PLUGIN_IMPORT uint reg_ext_length;

View File

@@ -3492,8 +3492,7 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp,
Json_writer_object trace_command(thd); Json_writer_object trace_command(thd);
Json_writer_array trace_command_steps(thd, "steps"); Json_writer_array trace_command_steps(thd, "steps");
if (open_tables) if (open_tables)
res= check_dependencies_in_with_clauses(m_lex->with_clauses_list) || res= instr->exec_open_and_lock_tables(thd, m_lex->query_tables);
instr->exec_open_and_lock_tables(thd, m_lex->query_tables);
if (likely(!res)) if (likely(!res))
{ {

View File

@@ -13909,7 +13909,12 @@ static int server_mpvio_read_packet(MYSQL_PLUGIN_VIO *param, uchar **buf)
done: done:
if (set_user_salt_if_needed(mpvio->acl_user, mpvio->curr_auth, mpvio->plugin)) 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; goto err;
}
ai->user_name= ai->thd->security_ctx->user; ai->user_name= ai->thd->security_ctx->user;
ai->user_name_length= (uint) strlen(ai->user_name); ai->user_name_length= (uint) strlen(ai->user_name);

View File

@@ -3591,7 +3591,11 @@ open_and_process_table(THD *thd, TABLE_LIST *tables, uint *counter, uint flags,
if (tables->derived) if (tables->derived)
{ {
if (!tables->view) if (!tables->view)
{
if (!tables->is_derived())
tables->set_derived();
goto end; goto end;
}
/* /*
We restore view's name and database wiped out by derived tables We restore view's name and database wiped out by derived tables
processing and fall back to standard open process in order to 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->db= tables->view_db;
tables->table_name= tables->view_name; 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)) if (!tables->derived && is_infoschema_db(&tables->db))
{ {

View File

@@ -2804,6 +2804,62 @@ void THD::close_active_vio()
#endif #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 struct Item_change_record: public ilink
{ {
Item **place; Item **place;

View File

@@ -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) 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 */ /** THD registry */
@@ -4637,14 +4637,11 @@ public:
to resolve all CTE names as we don't need this message to be thrown to resolve all CTE names as we don't need this message to be thrown
for any CTE references. 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)); my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
return TRUE; return TRUE;
} }
/* This will allow to throw an error later for non-CTE references */
to->str= NULL;
to->length= 0;
return FALSE; return FALSE;
} }
@@ -5398,7 +5395,6 @@ public:
THD_TRANS::EXECUTED_TABLE_ADMIN_CMD)); THD_TRANS::EXECUTED_TABLE_ADMIN_CMD));
} }
uint get_net_wait_timeout() uint get_net_wait_timeout()
{ {
if (in_active_multi_stmt_transaction()) if (in_active_multi_stmt_transaction())
@@ -5449,7 +5445,10 @@ public:
Item *sp_prepare_func_item(Item **it_addr, uint cols= 1); Item *sp_prepare_func_item(Item **it_addr, uint cols= 1);
bool sp_eval_expr(Field *result_field, Item **expr_item_ptr); 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 ? return (variables.old_behavior & OLD_MODE_UTF8_IS_UTF8MB3 ?
MY_UTF8_IS_UTF8MB3 : 0); MY_UTF8_IS_UTF8MB3 : 0);

View File

@@ -84,7 +84,7 @@ void st_select_lex_unit::set_with_clause(With_clause *with_cl)
true on failure 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; for (With_clause *with_clause= with_clauses_list;
with_clause; with_clause;
@@ -100,6 +100,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 @brief
Check dependencies between tables defined in this with clause Check dependencies between tables defined in this with clause
@@ -138,10 +333,11 @@ bool With_clause::check_dependencies()
elem != with_elem; elem != with_elem;
elem= elem->next) elem= elem->next)
{ {
if (lex_string_cmp(system_charset_info, with_elem->query_name, if (lex_string_cmp(system_charset_info, with_elem->get_name(),
elem->query_name) == 0) 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; return true;
} }
} }
@@ -248,13 +444,12 @@ With_element *With_clause::find_table_def(TABLE_LIST *table,
with_elem != barrier; with_elem != barrier;
with_elem= with_elem->next) with_elem= with_elem->next)
{ {
if (my_strcasecmp(system_charset_info, with_elem->query_name->str, if (my_strcasecmp(system_charset_info, with_elem->get_name_str(),
table->table_name.str) == 0 && table->table_name.str) == 0 &&
!table->is_fqtn) !table->is_fqtn)
{ {
table->set_derived(); table->set_derived();
table->db.str= empty_c_string; with_elem->referenced= true;
table->db.length= 0;
return with_elem; return with_elem;
} }
} }
@@ -611,7 +806,7 @@ bool With_clause::check_anchors()
if (elem == with_elem) if (elem == with_elem)
{ {
my_error(ER_RECURSIVE_WITHOUT_ANCHORS, MYF(0), my_error(ER_RECURSIVE_WITHOUT_ANCHORS, MYF(0),
with_elem->query_name->str); with_elem->get_name_str());
return true; return true;
} }
} }
@@ -644,7 +839,7 @@ bool With_clause::check_anchors()
if (elem->work_dep_map & elem->get_elem_map()) if (elem->work_dep_map & elem->get_elem_map())
{ {
my_error(ER_UNACCEPTABLE_MUTUAL_RECURSION, MYF(0), my_error(ER_UNACCEPTABLE_MUTUAL_RECURSION, MYF(0),
with_elem->query_name->str); with_elem->get_name_str());
return true; return true;
} }
} }
@@ -798,7 +993,8 @@ bool With_element::set_unparsed_spec(THD *thd,
@brief @brief
Create a clone of the specification for the given with table 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 @param with_table The reference to the table defined in this element for which
the clone is created. the clone is created.
@@ -808,12 +1004,13 @@ bool With_element::set_unparsed_spec(THD *thd,
this element. this element.
The clone is created when the string with the specification saved in 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 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 A chain of all table references occurred in the specification is also
formed. formed.
The method includes the new unit and its sub-unit into hierarchy of 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 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. table references into the chain of all table references of the main query.
The method resolves all references to CTE in the clone.
@note @note
Clones is created only for not first references to tables defined in 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 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) TABLE_LIST *with_table)
{ {
THD *thd= old_lex->thd;
LEX *lex; LEX *lex;
st_select_lex_unit *res= NULL; st_select_lex_unit *res= NULL;
Query_arena backup;
Query_arena *arena= thd->activate_stmt_arena_if_needed(&backup);
bool has_tmp_tables;
if (!(lex= (LEX*) new(thd->mem_root) st_lex_local)) if (!(lex= (LEX*) new(thd->mem_root) st_lex_local))
{
if (arena)
thd->restore_active_arena(arena, &backup);
return res; return res;
}
LEX *old_lex= thd->lex;
thd->lex= lex; thd->lex= lex;
bool parse_status= false; bool parse_status= false;
Parser_state parser_state;
TABLE_LIST *spec_tables;
TABLE_LIST *spec_tables_tail;
st_select_lex *with_select; st_select_lex *with_select;
char save_end= unparsed_spec.str[unparsed_spec.length]; char save_end= unparsed_spec.str[unparsed_spec.length];
((char*) &unparsed_spec.str[unparsed_spec.length])[0]= '\0'; ((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_start(thd);
lex->clone_spec_offset= unparsed_spec_offset; lex->clone_spec_offset= unparsed_spec_offset;
lex->param_list= old_lex->param_list; lex->with_cte_resolution= true;
lex->sphead= old_lex->sphead;
lex->spname= old_lex->spname; /*
lex->spcont= old_lex->spcont; The specification of a CTE is to be parsed as a regular query.
lex->sp_chistics= old_lex->sp_chistics; 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);
lex->stmt_lex= old_lex;
parse_status= parse_sql(thd, &parser_state, 0);
((char*) &unparsed_spec.str[unparsed_spec.length])[0]= save_end; ((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) if (parse_status)
goto err; goto err;
if (check_dependencies_in_with_clauses(lex->with_clauses_list)) /*
goto err; 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
spec_tables= lex->query_tables; to the CTE whose specification is parsed right after the TABLE_LIST object
spec_tables_tail= 0; created for the reference.
has_tmp_tables= thd->has_temporary_tables(); */
for (TABLE_LIST *tbl= spec_tables; if (lex->query_tables)
tbl;
tbl= tbl->next_global)
{ {
if (has_tmp_tables && !tbl->derived && !tbl->schema_table && head->tables_pos.set_start_pos(&with_table->next_global);
thd->open_temporary_table(tbl)) head->tables_pos.set_end_pos(lex->query_tables_last);
goto err; TABLE_LIST *next_tbl= with_table->next_global;
spec_tables_tail= tbl; if (next_tbl)
}
if (spec_tables)
{ {
if (with_table->next_global) *(lex->query_tables->prev_global= next_tbl->prev_global)=
{ lex->query_tables;
spec_tables_tail->next_global= with_table->next_global; *(next_tbl->prev_global= lex->query_tables_last)= next_tbl;
with_table->next_global->prev_global= &spec_tables_tail->next_global;
} }
else 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= &lex->unit;
res->with_element= this; 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.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= old_lex->all_selects_list=
(st_select_lex*) (lex->all_selects_list-> (st_select_lex*) (lex->all_selects_list->
insert_chain_before( insert_chain_before(
(st_select_lex_node **) &(old_lex->all_selects_list), (st_select_lex_node **) &(old_lex->all_selects_list),
with_select)); 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 Now all references to the CTE defined outside of the cloned specification
been resolved yet. 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; lex->only_cte_resolution= old_lex->only_cte_resolution;
tbl; if (lex->resolve_references_to_cte(lex->query_tables,
tbl= tbl->next_global) lex->query_tables_last))
{ {
if (!tbl->with) res= NULL;
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))
goto err; 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); lex_end(lex);
err: err:
if (arena)
thd->restore_active_arena(arena, &backup);
thd->lex= old_lex; thd->lex= old_lex;
return res; 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() bool TABLE_LIST::is_recursive_with_table()
{ {
return with && with->is_recursive; 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()) if (only_standard_compliant && with_elem->is_unrestricted())
{ {
my_error(ER_NOT_STANDARD_COMPLIANT_RECURSIVE, my_error(ER_NOT_STANDARD_COMPLIANT_RECURSIVE,
MYF(0), with_elem->query_name->str); MYF(0), with_elem->get_name_str());
return true; 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) 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) if (column_list.elements)
{ {
List_iterator_fast<Lex_ident_sys> li(column_list); List_iterator_fast<Lex_ident_sys> li(column_list);

View File

@@ -24,6 +24,39 @@ class select_unit;
struct st_unit_ctxt_elem; 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 @class With_element
@brief Definition of a CTE table @brief Definition of a CTE table
@@ -85,9 +118,22 @@ private:
subqueries and specifications of other with elements). subqueries and specifications of other with elements).
*/ */
uint references; 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. 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; LEX_CSTRING unparsed_spec;
/* Offset of the specification in the input string */ /* Offset of the specification in the input string */
@@ -101,10 +147,12 @@ private:
public: public:
/* /*
The name of the table introduced by this with elememt. The name Contains the name of the defined With element and the position of
can be used in FROM lists of the queries in the scope of the element. 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 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 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 */ /* List of derived tables containing recursive references to this CTE */
SQL_I_List<TABLE_LIST> derived_with_rec_ref; 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, List <Lex_ident_sys> list,
st_select_lex_unit *unit) st_select_lex_unit *unit)
: next(NULL), base_dep_map(0), derived_dep_map(0), : next(NULL), base_dep_map(0), derived_dep_map(0),
sq_dep_map(0), work_dep_map(0), mutually_recursive(0), sq_dep_map(0), work_dep_map(0), mutually_recursive(0),
top_level_dep_map(0), sq_rec_ref(NULL), top_level_dep_map(0), sq_rec_ref(NULL),
next_mutually_recursive(NULL), references(0), 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), is_recursive(false), rec_outer_references(0), with_anchor(false),
level(0), rec_result(NULL) level(0), rec_result(NULL)
{ unit->with_element= this; } { 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(); bool check_dependencies_in_spec();
void check_dependencies_in_select(st_select_lex *sl, st_unit_ctxt_elem *ctxt, 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, bool set_unparsed_spec(THD *thd, const char *spec_start, const char *spec_end,
my_ptrdiff_t spec_offset); 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++; } void inc_references() { references++; }
@@ -263,6 +320,12 @@ public:
void set_cycle_list(List<Lex_ident_sys> *cycle_list_arg); void set_cycle_list(List<Lex_ident_sys> *cycle_list_arg);
friend class With_clause; 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; const uint max_number_of_elements_in_with_clause= sizeof(table_map)*8;
@@ -361,8 +424,10 @@ public:
friend class With_element; friend class With_element;
friend friend
bool bool LEX::check_dependencies_in_with_clauses();
check_dependencies_in_with_clauses(With_clause *with_clauses_list);
friend
bool LEX::resolve_references_to_cte_in_hanging_cte();
}; };
inline inline

View File

@@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2019, Oracle and/or its affiliates. /* 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 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 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; describe= 0;
context_analysis_only= 0; context_analysis_only= 0;
derived_tables= 0; derived_tables= 0;
with_cte_resolution= false;
only_cte_resolution= false;
parsing_options.reset(); parsing_options.reset();
part_info= 0; part_info= 0;
m_sql_cmd= NULL; m_sql_cmd= NULL;
@@ -2925,6 +2927,7 @@ void st_select_lex_unit::init_query()
with_wrapped_tvc= 0; with_wrapped_tvc= 0;
is_view= 0; is_view= 0;
describe= 0; describe= 0;
cloned_from= 0;
columns_are_renamed= 0; columns_are_renamed= 0;
} }
@@ -9079,6 +9082,8 @@ bool LEX::check_main_unit_semantics()
if (unit.set_nest_level(0) || if (unit.set_nest_level(0) ||
unit.check_parameters(first_select_lex())) unit.check_parameters(first_select_lex()))
return TRUE; return TRUE;
if (check_cte_dependencies_and_resolve_references())
return TRUE;
return FALSE; return FALSE;
} }
@@ -9805,8 +9810,8 @@ bool LEX::main_select_push(bool service)
{ {
DBUG_ENTER("LEX::main_select_push"); DBUG_ENTER("LEX::main_select_push");
DBUG_PRINT("info", ("service: %u", service)); DBUG_PRINT("info", ("service: %u", service));
current_select_number= 1; current_select_number= ++thd->lex->stmt_lex->current_select_number;
builtin_select.select_number= 1; builtin_select.select_number= current_select_number;
builtin_select.is_service_select= service; builtin_select.is_service_select= service;
if (push_select(&builtin_select)) if (push_select(&builtin_select))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);

View File

@@ -895,6 +895,8 @@ public:
With_clause *with_clause; With_clause *with_clause;
/* With element where this unit is used as the specification (if any) */ /* With element where this unit is used as the specification (if any) */
With_element *with_element; 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 */ /* thread handler */
THD *thd; THD *thd;
/* /*
@@ -1563,7 +1565,9 @@ public:
} }
With_element *get_with_element() 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); With_element *find_table_def_in_with_clauses(TABLE_LIST *table);
bool check_unrestricted_recursive(bool only_standard_compliant); bool check_unrestricted_recursive(bool only_standard_compliant);
@@ -3357,6 +3361,20 @@ public:
bool parse_vcol_expr:1; bool parse_vcol_expr:1;
bool analyze_stmt:1; /* TRUE<=> this is "ANALYZE $stmt" */ bool analyze_stmt:1; /* TRUE<=> this is "ANALYZE $stmt" */
bool explain_json:1; 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 local_file:1;
bool check_exists:1; bool check_exists:1;
bool verbose:1, no_write_to_binlog:1; bool verbose:1, no_write_to_binlog:1;
@@ -4749,6 +4767,12 @@ public:
const LEX_CSTRING *constraint_name, const LEX_CSTRING *constraint_name,
Table_ident *ref_table_name, Table_ident *ref_table_name,
DDL_options ddl_options); 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);
}; };

View File

@@ -3520,9 +3520,6 @@ mysql_execute_command(THD *thd)
thd->get_stmt_da()->opt_clear_warning_info(thd->query_id); 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 #ifdef HAVE_REPLICATION
if (unlikely(thd->slave_thread)) 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->is_fqtn= TRUE;
ptr->db= table->db; 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); DBUG_RETURN(0);
else else
ptr->is_fqtn= FALSE; ptr->is_fqtn= FALSE;
@@ -8230,6 +8227,8 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
ptr->table_name= table->table; 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); ptr->updating= MY_TEST(table_options & TL_OPTION_UPDATING);
/* TODO: remove TL_OPTION_FORCE_INDEX as it looks like it's not used */ /* 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); ptr->force_index= MY_TEST(table_options & TL_OPTION_FORCE_INDEX);
@@ -8916,6 +8915,8 @@ void st_select_lex::set_lock_for_tables(thr_lock_type lock_type, bool for_update
tables->lock_type= lock_type; tables->lock_type= lock_type;
tables->skip_locked= skip_locked; tables->skip_locked= skip_locked;
tables->updating= for_update; tables->updating= for_update;
if (tables->db.length)
tables->mdl_request.set_type((lock_type >= TL_FIRST_WRITE) ? tables->mdl_request.set_type((lock_type >= TL_FIRST_WRITE) ?
MDL_SHARED_WRITE : MDL_SHARED_READ); MDL_SHARED_WRITE : MDL_SHARED_READ);
} }

View File

@@ -2325,9 +2325,6 @@ static bool check_prepared_statement(Prepared_statement *stmt)
if (tables) if (tables)
thd->get_stmt_da()->opt_clear_warning_info(thd->query_id); 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) if (sql_command_flags[sql_command] & CF_HA_CLOSE)
mysql_ha_rm_tables(thd, tables); mysql_ha_rm_tables(thd, tables);

View File

@@ -1,6 +1,6 @@
/* /*
Copyright (c) 2004, 2012, Oracle and/or its affiliates. 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 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 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)) thd->variables.lock_wait_timeout))
goto end; goto end;
if (!create) if (!create)
{ {
bool if_exists= thd->lex->if_exists(); 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; table= tables->table;
#ifdef WITH_WSREP #ifdef WITH_WSREP
if (WSREP(thd) && if (WSREP(thd) && !wsrep_should_replicate_ddl(thd, table->s->db_type()))
!wsrep_should_replicate_ddl(thd, table->s->db_type())) goto end;
goto wsrep_error_label;
#endif #endif
/* Later on we will need it to downgrade the lock */ /* 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); thd->mdl_context.release_lock(mdl_request_for_trn.ticket);
DBUG_RETURN(result); DBUG_RETURN(result);
#ifdef WITH_WSREP #ifdef WITH_WSREP
wsrep_error_label: wsrep_error_label:
DBUG_RETURN(true); DBUG_ASSERT(result == 1);
goto end;
#endif #endif
drop_orphan_trn: drop_orphan_trn:

View File

@@ -1,5 +1,5 @@
/* Copyright (c) 2004, 2013, Oracle and/or its affiliates. /* 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 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 it under the terms of the GNU General Public License as published by
@@ -34,7 +34,6 @@
#include "sp_cache.h" #include "sp_cache.h"
#include "datadict.h" // dd_frm_is_view() #include "datadict.h" // dd_frm_is_view()
#include "sql_derived.h" #include "sql_derived.h"
#include "sql_cte.h" // check_dependencies_in_with_clauses()
#include "opt_trace.h" #include "opt_trace.h"
#include "ddl_log.h" #include "ddl_log.h"
#include "debug.h" // debug_crash_here #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); lex->link_first_table_back(view, link_to_local);
view->open_type= OT_BASE_ONLY; 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); WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL);
/* /*
@@ -943,6 +936,13 @@ static int mysql_register_view(THD *thd, DDL_LOG_STATE *ddl_log_state,
{ {
LEX *lex= thd->lex; 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 View definition query -- a SELECT statement that fully defines view. It
is generated from the Item-tree built from the original (specified by is generated from the Item-tree built from the original (specified by
@@ -1485,9 +1485,6 @@ bool mysql_make_view(THD *thd, TABLE_SHARE *share, TABLE_LIST *table,
TABLE_LIST *tbl; TABLE_LIST *tbl;
Security_context *security_ctx= 0; 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. Check rights to run commands which show underlying tables.
In the optimizer trace we would not like to show trace for In the optimizer trace we would not like to show trace for

View File

@@ -294,6 +294,7 @@ void _CONCAT_UNDERSCORED(turn_parser_debug_on,yyparse)()
class sp_head *sphead; class sp_head *sphead;
class sp_name *spname; class sp_name *spname;
class sp_variable *spvar; class sp_variable *spvar;
class With_element_head *with_element_head;
class With_clause *with_clause; class With_clause *with_clause;
class Virtual_column_info *virtual_column; class Virtual_column_info *virtual_column;
@@ -1788,7 +1789,7 @@ End SQL_MODE_ORACLE_SPECIFIC */
%type <with_clause> with_clause %type <with_clause> with_clause
%type <lex_str_ptr> query_name %type <with_element_head> with_element_head
%type <ident_sys_list> %type <ident_sys_list>
comma_separated_ident_list comma_separated_ident_list
@@ -2981,7 +2982,11 @@ call:
if (unlikely(Lex->call_statement_start(thd, $2))) if (unlikely(Lex->call_statement_start(thd, $2)))
MYSQL_YYABORT; MYSQL_YYABORT;
} }
opt_sp_cparam_list {} opt_sp_cparam_list
{
if (Lex->check_cte_dependencies_and_resolve_references())
MYSQL_YYABORT;
}
; ;
/* CALL parameters */ /* CALL parameters */
@@ -3788,6 +3793,8 @@ expr_lex:
$$->sp_lex_in_use= true; $$->sp_lex_in_use= true;
$$->set_item($2); $$->set_item($2);
Lex->pop_select(); //min select Lex->pop_select(); //min select
if (Lex->check_cte_dependencies_and_resolve_references())
MYSQL_YYABORT;
if ($$->sphead->restore_lex(thd)) if ($$->sphead->restore_lex(thd))
MYSQL_YYABORT; MYSQL_YYABORT;
} }
@@ -12989,6 +12996,8 @@ do:
{ {
Lex->insert_list= $3; Lex->insert_list= $3;
Lex->pop_select(); //main select 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)) if (unlikely(with_clause == NULL))
MYSQL_YYABORT; MYSQL_YYABORT;
lex->derived_tables|= DERIVED_WITH; lex->derived_tables|= DERIVED_WITH;
lex->with_cte_resolution= true;
lex->curr_with_clause= with_clause; lex->curr_with_clause= with_clause;
with_clause->add_to_list(Lex->with_clauses_list_last_next); with_clause->add_to_list(Lex->with_clauses_list_last_next);
if (lex->current_select && if (lex->current_select &&
@@ -15197,7 +15207,7 @@ with_list:
with_list_element: with_list_element:
query_name with_element_head
opt_with_column_list opt_with_column_list
AS '(' query_expression ')' opt_cycle AS '(' query_expression ')' opt_cycle
{ {
@@ -15215,6 +15225,7 @@ with_list_element:
{ {
elem->set_cycle_list($7); 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 ident
{ {
$$= (LEX_CSTRING *) thd->memdup(&$1, sizeof(LEX_CSTRING)); LEX_CSTRING *name=
if (unlikely($$ == NULL)) (LEX_CSTRING *) thd->memdup(&$1, sizeof(LEX_CSTRING));
$$= new (thd->mem_root) With_element_head(name);
if (unlikely(name == NULL || $$ == NULL))
MYSQL_YYABORT; MYSQL_YYABORT;
$$->tables_pos.set_start_pos(Lex->query_tables_last);
} }
; ;

View File

@@ -2116,6 +2116,29 @@ struct vers_select_conds_t
struct LEX; struct LEX;
class Index_hint; 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 struct TABLE_LIST
{ {
TABLE_LIST() {} /* Remove gcc warning */ TABLE_LIST() {} /* Remove gcc warning */
@@ -2451,6 +2474,20 @@ struct TABLE_LIST
/* call back function for asking handler about caching in query cache */ /* call back function for asking handler about caching in query cache */
qc_engine_callback callback_func; qc_engine_callback callback_func;
thr_lock_type lock_type; 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 outer_join; /* Which join type */
uint shared; /* Used in multi-upd */ uint shared; /* Used in multi-upd */
bool updatable; /* VIEW/TABLE can be updated now */ bool updatable; /* VIEW/TABLE can be updated now */

View File

@@ -234,14 +234,19 @@ static void *native_event_get_userdata(native_event *event)
#elif defined(HAVE_KQUEUE) #elif defined(HAVE_KQUEUE)
/* /*
NetBSD is incompatible with other BSDs , last parameter in EV_SET macro NetBSD prior to 9.99.17 is incompatible with other BSDs, last parameter
(udata, user data) needs to be intptr_t, whereas it needs to be void* in EV_SET macro (udata, user data) needs to be intptr_t, whereas it needs
everywhere else. to be void* everywhere else.
*/ */
#ifdef __NetBSD__ #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) #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) #define MY_EV_SET(a, b, c, d, e, f, g) EV_SET(a, b, c, d, e, f, g)
#endif #endif

View File

@@ -423,11 +423,11 @@ IF(CONNECT_WITH_JDBC AND JAVA_FOUND AND JNI_FOUND)
INSTALL(FILES INSTALL(FILES
${CMAKE_CURRENT_SOURCE_DIR}/mysql-test/connect/std_data/JavaWrappers.jar ${CMAKE_CURRENT_SOURCE_DIR}/mysql-test/connect/std_data/JavaWrappers.jar
${CMAKE_CURRENT_BINARY_DIR}/JdbcInterface.jar ${CMAKE_CURRENT_BINARY_DIR}/JdbcInterface.jar
DESTINATION ${INSTALL_PLUGINDIR} COMPONENT connect-engine) DESTINATION ${INSTALL_MYSQLSHAREDIR} COMPONENT connect-engine)
IF(CONNECT_WITH_MONGO) IF(CONNECT_WITH_MONGO)
INSTALL(FILES INSTALL(FILES
${CMAKE_CURRENT_SOURCE_DIR}/mysql-test/connect/std_data/Mongo2.jar ${CMAKE_CURRENT_SOURCE_DIR}/mysql-test/connect/std_data/Mongo2.jar
${CMAKE_CURRENT_SOURCE_DIR}/mysql-test/connect/std_data/Mongo3.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()
ENDIF() ENDIF()

View File

@@ -57,8 +57,8 @@ extern "C" HINSTANCE s_hModule; // Saved module handle
extern char *JvmPath; // The connect_jvm_path global variable value extern char *JvmPath; // The connect_jvm_path global variable value
extern char *ClassPath; // The connect_class_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 char *GetJavaWrapper(void); // The connect_java_wrapper variable value
extern MYSQL_PLUGIN_IMPORT char lc_messages_dir[FN_REFLEN];
/***********************************************************************/ /***********************************************************************/
/* Static JAVAConn objects. */ /* Static JAVAConn objects. */
@@ -401,23 +401,23 @@ bool JAVAConn::Open(PGLOBAL g)
} // endif ClassPath } // endif ClassPath
#if 0 #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(sep);
jpop->Append(GetPluginDir()); jpop->Append(lc_messages_dir);
jpop->Append("JdbcInterface.jar"); jpop->Append("JdbcInterface.jar");
#endif // 0 #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(sep);
jpop->Append(GetPluginDir()); jpop->Append(lc_messages_dir);
jpop->Append("JavaWrappers.jar"); jpop->Append("JavaWrappers.jar");
#if defined(MONGO_SUPPORT) #if defined(MONGO_SUPPORT)
jpop->Append(sep); jpop->Append(sep);
jpop->Append(GetPluginDir()); jpop->Append(lc_messages_dir);
jpop->Append("Mongo3.jar"); jpop->Append("Mongo3.jar");
jpop->Append(sep); jpop->Append(sep);
jpop->Append(GetPluginDir()); jpop->Append(lc_messages_dir);
jpop->Append("Mongo2.jar"); jpop->Append("Mongo2.jar");
#endif // MONGO_SUPPORT #endif // MONGO_SUPPORT

View File

@@ -1682,7 +1682,6 @@ PVAL JSONCOL::MakeJson(PGLOBAL g, PJSON jsp, int n)
/***********************************************************************/ /***********************************************************************/
PJVAL JSONCOL::GetRowValue(PGLOBAL g, PJSON row, int i) PJVAL JSONCOL::GetRowValue(PGLOBAL g, PJSON row, int i)
{ {
int n = Nod - 1;
PJVAL val = NULL; PJVAL val = NULL;
for (; i < Nod && row; i++) { for (; i < Nod && row; i++) {

View File

@@ -1750,15 +1750,14 @@ fts_create_one_common_table(
error = row_create_index_for_mysql(index, trx, NULL, error = row_create_index_for_mysql(index, trx, NULL,
FIL_ENCRYPTION_DEFAULT, FIL_ENCRYPTION_DEFAULT,
FIL_DEFAULT_ENCRYPTION_KEY); FIL_DEFAULT_ENCRYPTION_KEY);
if (error == DB_SUCCESS) {
return new_table;
}
} }
if (error != DB_SUCCESS) { ib::warn() << "Failed to create FTS common table " << fts_table_name;
dict_mem_table_free(new_table); trx->error_state = error;
new_table = NULL; return NULL;
ib::warn() << "Failed to create FTS common table "
<< fts_table_name;
}
return(new_table);
} }
/** Creates the common auxiliary tables needed for supporting an FTS index /** 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( dict_table_t* common_table = fts_create_one_common_table(
trx, table, full_name[i], fts_table.suffix, heap); trx, table, full_name[i], fts_table.suffix, heap);
if (common_table == NULL) { if (!common_table) {
trx->error_state = DB_SUCCESS;
error = DB_ERROR; error = DB_ERROR;
goto func_exit; goto func_exit;
} }
@@ -1928,16 +1928,15 @@ fts_create_one_index_table(
error = row_create_index_for_mysql(index, trx, NULL, error = row_create_index_for_mysql(index, trx, NULL,
FIL_ENCRYPTION_DEFAULT, FIL_ENCRYPTION_DEFAULT,
FIL_DEFAULT_ENCRYPTION_KEY); FIL_DEFAULT_ENCRYPTION_KEY);
if (error == DB_SUCCESS) {
return new_table;
}
} }
if (error != DB_SUCCESS) { ib::warn() << "Failed to create FTS index table " << table_name;
dict_mem_table_free(new_table); trx->error_state = error;
new_table = NULL; return NULL;
ib::warn() << "Failed to create FTS index table "
<< table_name;
}
return(new_table);
} }
/** Creates the column specific ancillary tables needed for supporting an /** Creates the column specific ancillary tables needed for supporting an

View File

@@ -5966,7 +5966,9 @@ ha_innobase::open(const char* name, int, uint)
/* Index block size in InnoDB: used by MySQL in query optimization */ /* Index block size in InnoDB: used by MySQL in query optimization */
stats.block_size = static_cast<uint>(srv_page_size); 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->is_temporary()
|| m_prebuilt->table->persistent_autoinc || m_prebuilt->table->persistent_autoinc
|| !m_prebuilt->table->is_readable()) { || !m_prebuilt->table->is_readable()) {
@@ -5993,7 +5995,7 @@ ha_innobase::open(const char* name, int, uint)
ut_ad(!m_prebuilt->table ut_ad(!m_prebuilt->table
|| table->versioned() == m_prebuilt->table->versioned()); || 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 info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST
| HA_STATUS_OPEN); | HA_STATUS_OPEN);
} }
@@ -12956,7 +12958,6 @@ create_table_info_t::create_table_update_dict()
if (m_flags2 & DICT_TF2_FTS) { if (m_flags2 & DICT_TF2_FTS) {
if (!innobase_fts_load_stopword(innobase_table, NULL, m_thd)) { if (!innobase_fts_load_stopword(innobase_table, NULL, m_thd)) {
dict_table_close(innobase_table, FALSE, FALSE); dict_table_close(innobase_table, FALSE, FALSE);
m_trx->free();
DBUG_RETURN(-1); DBUG_RETURN(-1);
} }
@@ -13076,7 +13077,8 @@ ha_innobase::create(
DBUG_ASSERT(trx_state_eq(trx, TRX_STATE_NOT_STARTED)); 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, /* Drop the being-created table before rollback,
so that rollback can possibly rename back a table so that rollback can possibly rename back a table
that could have been renamed before the failed creation. */ that could have been renamed before the failed creation. */
@@ -13088,22 +13090,18 @@ ha_innobase::create(
} }
trx_rollback_for_mysql(trx); trx_rollback_for_mysql(trx);
row_mysql_unlock_data_dictionary(trx); row_mysql_unlock_data_dictionary(trx);
if (own_trx) { } else {
trx->free();
}
DBUG_RETURN(error);
}
innobase_commit_low(trx); innobase_commit_low(trx);
row_mysql_unlock_data_dictionary(trx); row_mysql_unlock_data_dictionary(trx);
ut_ad(!srv_read_only_mode);
error = info.create_table_update_dict();
}
if (own_trx) { if (own_trx) {
trx->free(); trx->free();
} }
ut_ad(!srv_read_only_mode); DBUG_RETURN(error);
DBUG_RETURN(info.create_table_update_dict());
} }
/** Create a new table to an InnoDB database. /** Create a new table to an InnoDB database.

View File

@@ -588,14 +588,13 @@ else()
set(GRN_WITH_MESSAGE_PACK FALSE) set(GRN_WITH_MESSAGE_PACK FALSE)
endif() endif()
find_program(RUBY NAMES option(GRN_WITH_MRUBY "use mruby" OFF)
if(GRN_WITH_MRUBY)
find_program(RUBY NAMES
"ruby2.3" "ruby23" "ruby2.3" "ruby23"
"ruby2.2" "ruby22" "ruby2.2" "ruby22"
"ruby2.1" "ruby21" "ruby2.1" "ruby21"
"ruby") "ruby")
option(GRN_WITH_MRUBY "use mruby" OFF)
if(GRN_WITH_MRUBY)
set(MRUBY_INCLUDE_DIRS set(MRUBY_INCLUDE_DIRS
"${CMAKE_CURRENT_SOURCE_DIR}/vendor/mruby-source/include") "${CMAKE_CURRENT_SOURCE_DIR}/vendor/mruby-source/include")
set(MRUBY_LIBS mruby) set(MRUBY_LIBS mruby)

View File

@@ -3,7 +3,7 @@ if [ -r %{restart_flag} ] ; then
# only restart the server if it was already running # only restart the server if it was already running
if [ -x /usr/bin/systemctl ] ; then if [ -x /usr/bin/systemctl ] ; then
/usr/bin/systemctl daemon-reload > /dev/null 2>&1 /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 /usr/bin/systemctl restart mysql > /dev/null 2>&1
else else
/usr/bin/systemctl try-restart mariadb.service > /dev/null 2>&1 /usr/bin/systemctl try-restart mariadb.service > /dev/null 2>&1